|
From: <jas...@us...> - 2006-06-09 14:43:01
|
Revision: 983 Author: jason379 Date: 2006-06-09 07:42:54 -0700 (Fri, 09 Jun 2006) ViewCVS: http://svn.sourceforge.net/opende/?rev=983&view=rev Log Message: ----------- Clean up support files for 0.6 release Modified Paths: -------------- trunk/README.txt trunk/ode/doc/main.dox Added Paths: ----------- trunk/INSTALL.txt Removed Paths: ------------- trunk/INSTALL trunk/ode/doc/ode.doc Deleted: trunk/INSTALL =================================================================== --- trunk/INSTALL 2006-06-07 21:31:50 UTC (rev 982) +++ trunk/INSTALL 2006-06-09 14:42:54 UTC (rev 983) @@ -1,104 +0,0 @@ - -ODE NOW HAS AUTOTOOLS SUPPORT!!!! - -if you want to build ODE with autotools follow these steps, if not skip ahead: - -(0) if you are building from CVS you must bootstrap the process first - by running: - - $ sh autogen.sh - - you may see some "underquoted definition" warnings depending on your - platform, these are (for now) harmless warnings regarding scripts - from other m4 installed packages. - -(1) The default build process builds ODE with single precision, with trimesh - support, and debug enabled if this is what you want, simply run: - - $ ./configure - - Double precision is enabled with the argument --enable-double-precision - opcode support is disabled with the --disable-opcode argument. - To disable the gyroscopic term, which may improve stability, use - --disable-gyroscopic - A release build is enabled with --enable-release. - So, if you want to build ODE without trimesh support, you would run: - - $ ./configure --disable-opcode - - if you want to build ODE without trimesh support and double precision: - - $ ./configure --enable-double-precision --disable-opcode - - etc, each of these arguments are independent of each other. - In addition the option --with-arch= allows the user to pass the - -march flag to GCC, in order to tune the library for a particular - architecture, the argument --with-arch= takes are the ones listed on the - this page for -mtune: - http://gcc.gnu.org/onlinedocs/gcc-3.4.1/gcc/i386-and-x86-64-Options.html#i386%20and%20x86-64%20Options - Note that the link points to posible values for Intel processors, - but other processors are also supported, check the page for your particular - processor to see what parameters can be passed to -march in your case. - -(2) Run: - - $ make - -(3) To install the library run: - - $ make install - -(4) Test your build: - Note, you may have to set your LD_LIBRARY_PATH if $prefix/lib is not in it. - - $ cd ode/test ; ./test_boxstack - -Autotools Notes: - -1. Automake 1.8.x or higher is required in order to build ODE - using autotools, some Linux distributions (Debian) may install - by default a lower version even if there are packages for higher versions, - make sure you have the correct one. -2. Currently because of the nuisances of the Windows DLL system shared - libraries are disabled, so autotools will build a static library only, - on non Windows systems, you can get a shared library by adding the - argument --enable-shared to the configure script. -3. the autotools build process creates and installs a 'ode-config' script - similar to that of gtk, useful for passing cflags and libs to your projects, - run ode-config from a command prompt to find out how it works. -4. The initial autotools build support was written by - Rodrigo Hernandez (kwizatz at aeongames.com) feel free to contact me, - if you have any questions regarging the ODE autotools scripts. - - -And here are the steps to build ODE without autotools: - -(0) if you're using Microsoft's Visual C++ compiler, you have the option - of using the workspace and project files in the VC6 subdirectory, - or you can follow the instructions below. - -(1) get the GNU 'make' tool. many unix platforms come with this, although - sometimes it is called 'gmake'. a version of GNU make for windows - is available at: http://q12.org/ode/bin/make.exe - -(2) edit the settings in the file config/user-settings. the list of supported - platforms is given in that file. - -(3) run 'make' to configure and build ODE and the graphical test programs. - to build parts of ODE the make targets are: - - make configure create configuration file include/ode/config.h - make ode-lib build the core ODE library - make drawstuff-lib build the OpenGL-based graphics library - make ode-test build some ODE tests (they need drawstuff) - make drawstuff-test build a test app for the drawstuff library - - all of these targets will do an implicit 'make configure'. if the - configurator screws up then you can edit the settings directly in - include/ode/config.h. - -(4) to install the ODE library onto your system you should copy the 'lib' and - 'include' directories to a suitable place, e.g. on unix: - - include/ode --> /usr/local/include/ode - lib/libode.a --> /usr/local/lib/libode.a Copied: trunk/INSTALL.txt (from rev 982, trunk/INSTALL) =================================================================== --- trunk/INSTALL.txt (rev 0) +++ trunk/INSTALL.txt 2006-06-09 14:42:54 UTC (rev 983) @@ -0,0 +1,84 @@ +As of version 0.6, ODE has two new build systems, one for Visual Studio +and another just about everything else. + +1. Building with Visual Studio +2. Building with Autotools (Linux, OS X, etc.) + + +1. BUILDING WITH VISUAL STUDIO (version 6.0 and up) + + If you downloaded the source code from Subversion you must first copy + the file build/config-default.h to include/ode/config.h. If you + downloaded a source code package from SourceForge this has already + been done for you. + + The directory ode/build contains project files for all supported versions + of Visual Studio. Open the appropriate solution for your version, build, + and go! + + Single-precision math is used by default. If you would like to switch to + doubles instead, edit ode/include/ode/config.h and replace + + #define dSINGLE 1 + + with the line + + #define dDOUBLE 1 + + and the rebuild everything. + + Note that we are considering dropping support for Visual Studio 6.0. Now + that Visual Studio 2005 C++ Express is available for free there does not + seem to be any good reason to put up with 6.0's foibles. + + +2. BUILDING WITH AUTOTOOLS (Linux, OS X, etc.) + + If you downloaded the source code from Subversion you must bootstrap the + process by running the command: + + $ sh autogen.sh + + If you downloaded a source code package from SourceForge this has + already been done for you. You may see some "underquoted definition" + warnings depending on your platform, these are (for now) harmless + warnings regarding scripts from other m4 installed packages. + + Run the configure script to autodetect your build environment. + + $ ./configure + + By default this will build ODE as a static library with single-precision + math, trimesh support, and debug symbols enabled. You can modify these + defaults by passing additional parameters to configure. For a full list + of available options, type + + $ ./configure --help + + Some of the more popular options are + + --enable-double-precision enable double-precision math + --disable-opcode disables the OPCODE-based trimesh support + --enable-release builds an optimized library + --enabled-shared builds a shared library + + Once configure has run successfully, build and install ODE: + + $ make + $ make install + + The latter command will also create an `ode-config` script which you can + use to pass cflags and ldflags to your projects. run `ode-config` from a + command prompt to find out how it works. + + In addition the option `--with-arch=` allows the user to pass the -march + flag to GCC, in order to tune the library for a particular architecture. + The arguments for --with-arch are listed on this page for -mtune: + + http://gcc.gnu.org/onlinedocs/gcc-3.4.1/gcc/i386-and-x86-64-Options.html#i386%20and%20x86-64%20Options + + Note that the link points to posible values for Intel processors, but + other processors are also supported, check the page for your particular + processor to see what parameters can be passed to -march in your case. + + Modified: trunk/README.txt =================================================================== --- trunk/README.txt 2006-06-07 21:31:50 UTC (rev 982) +++ trunk/README.txt 2006-06-09 14:42:54 UTC (rev 983) @@ -1,4 +1,4 @@ -The Open Dynamics Engine (ODE), Copyright (C) 2001-2004 Russell L. Smith. +The Open Dynamics Engine (ODE), Copyright (C) 2001-2006 Russell L. Smith. ------------------------------------------------------------------------- ODE is a free, industrial quality library for simulating articulated @@ -22,9 +22,11 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files LICENSE.TXT and LICENSE-BSD.TXT for more details. - * Installation instructions are in the INSTALL file + * Installation instructions are in the INSTALL file - * The ODE web pages are at http://ode.org/ + * The ODE web pages are at http://ode.org/ - * The ODE documentation is in the file ode/doc/ode.html, or you - can view it on the web at http://ode.org/ + * An online manual is at http://opende.sf.net/wiki/index.php/Manual + + * API documentation is in the file ode/docs/index.html, or you + can view it on the web at http://opende.sf.net/docs/index.html Modified: trunk/ode/doc/main.dox =================================================================== --- trunk/ode/doc/main.dox 2006-06-07 21:31:50 UTC (rev 982) +++ trunk/ode/doc/main.dox 2006-06-09 14:42:54 UTC (rev 983) @@ -12,5 +12,11 @@ to ODE, please see the <a href="http://opende.sourceforge.net/wiki/index.php/Manual"> Online Handbook</a>. +<h2>Important: this document is not yet complete!</h2> + +We are still working on getting the full API documentated. In the meantime, +please refer to the <a href="http://opende.sourceforge.net/wiki/index.php/Manual"> +Online Handbook</a> + */ Deleted: trunk/ode/doc/ode.doc =================================================================== --- trunk/ode/doc/ode.doc 2006-06-07 21:31:50 UTC (rev 982) +++ trunk/ode/doc/ode.doc 2006-06-09 14:42:54 UTC (rev 983) @@ -1,4859 +0,0 @@ -######################################################################### -# # -# Open Dynamics Engine, Copyright (C) 2001-2004 Russell L. Smith. # -# All rights reserved. Email: ru...@q1... Web: www.q12.org # -# # -# This library is free software; you can redistribute it and/or # -# modify it under the terms of EITHER: # -# (1) The GNU Lesser General Public License as published by the Free # -# Software Foundation; either version 2.1 of the License, or (at # -# your option) any later version. The text of the GNU Lesser # -# General Public License is included with this library in the # -# file LICENSE.TXT. # -# (2) The BSD-style license that is included with this library in # -# the file LICENSE-BSD.TXT. # -# # -# This library is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files # -# LICENSE.TXT and LICENSE-BSD.TXT for more details. # -# # -######################################################################### - -@title{Open Dynamics Engine} -@subtitle{v0.5 User Guide} -@author{Russell Smith} -@copyright{This document is Copyright @C 2001-2004 Russell Smith.} - -############################################################################# -@chapter{Introduction} - -The Open Dynamics Engine (ODE) is a free, industrial quality library for -simulating articulated rigid body dynamics. -For example, it is good for simulating ground vehicles, legged creatures, -and moving objects in VR environments. -It is fast, flexible and robust, and it has built-in collision detection. -ODE is being developed by @link{http://www.q12.org}{Russell Smith} -with help from several -@link{http://opende.sourceforge.net/community.html}{contributors}. - -If ``rigid body simulation'' does not make much sense to you, check out -@link{http://opende.sourceforge.net/slides/slides.html}{What is a Physics -SDK?}. - -This is the user guide for ODE version 0.5. -Despite the low version number, ODE is reasonably mature and stable. - - -@section{Features} - -ODE is good for simulating @emph{articulated} rigid body structures. -An articulated structure is created when rigid bodies of various shapes are -connected together with joints of various kinds. -Examples are ground vehicles (where the wheels are connected to the chassis), -legged creatures (where the legs are connected to the body), or stacks of -objects. - -ODE is designed to be used in interactive or real-time simulation. -It is particularly good for simulating moving objects in changeable -virtual reality environments. -This is because it is fast, robust and stable, and the user has complete -freedom to change the structure of the system even while the simulation -is running. - -ODE uses a highly stable integrator, so that the simulation errors should -not grow out of control. -The physical meaning of this is that the simulated system should not -"explode" for no reason (believe me, this happens a lot with other simulators -if you are not careful). -ODE emphasizes speed and stability over physical accuracy. - -ODE has @emph{hard} contacts. This means that a special non-penetration -constraint is used whenever two bodies collide. -The alternative, used in many other simulators, is to use virtual springs to -represent contacts. -This is difficult to do right and extremely error-prone. - -ODE has a built-in collision detection system. -However you can ignore it and do your own collision detection if you want to. -The current collision primitives are sphere, box, capped cylinder, plane, -ray, and triangular mesh - more collision objects will come later. -ODE's collision system provides fast identification of potentially -intersecting objects, through the concept of ``spaces''. - -Here are the features: -@list{ -@* Rigid bodies with arbitrary mass distribution. -@* Joint types: ball-and-socket, hinge, slider (prismatic), - hinge-2, fixed, angular motor, universal. -@* Collision primitives: sphere, box, capped cylinder, plane, - ray, and triangular mesh. -@* Collision spaces: Quad tree, hash space, and simple. -@* Simulation method: The equations of motion are derived from a - Lagrange multiplier velocity based model due to Trinkle/Stewart and - Anitescu/Potra. -@* A first order integrator is being used. It's fast, but not accurate - enough for quantitative engineering yet. Higher order integrators - will come later. -@* Choice of time stepping methods: either the standard ``big matrix'' - method or the newer iterative QuickStep method can be used. -@* Contact and friction model: This is based on the Dantzig LCP solver - described by Baraff, although ODE implements a faster approximation - to the Coloumb friction model. -@* Has a native C interface (even though ODE is mostly written in C++). -@* Has a C++ interface built on top of the C one. -@* Many unit tests, and more being written all the time. -@* Platform specific optimizations. -@* Other stuff I forgot to mention... -} - - -@section{ODE's License} - -ODE is Copyright @C 2001-2004 Russell L. Smith. -All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of EITHER: -@numlist{ -@* The @link{http://www.opensource.org/licenses/lgpl-license.html}{GNU - Lesser General Public License} as published by the Free Software - Foundation; either version 2.1 of the License, or (at your option) - any later version. The text of the GNU Lesser General Public License - is included with this library in the file @c{LICENSE.TXT}. -@* The @link{http://opende.sourceforge.net/ode-license.html}{BSD-style - license} that is included with this library in - the file @c{LICENSE-BSD.TXT}. -} -This library is distributed in the hope that it will be useful, -but @emph{WITHOUT ANY WARRANTY}; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files -@c{LICENSE.TXT} and @c{LICENSE-BSD.TXT} for more details. - - -@section{The ODE Community} - -Do you have questions or comments about ODE? -Think you can help? Please @link{http://q12.org/mailman/listinfo/ode}{write to -the ODE mailing list}. - -############################################################################# -@chapter{How to Install and Use ODE} - -@section{Installing ODE} - -@b{Step 1:} -Unpack the ODE archive. - -@b{Steps 2-4 (alternate):} -If you're on windows and using MSVC, you can use the workspace and project -files in the VC6 subdirectory of the distribution. - -@b{Step 2:} -Get the GNU @c{make} tool. Many Unix platforms come with this, although -sometimes it is called @c{gmake}. A version of GNU make for windows is -available @link{http://q12.org/ode/bin/make.exe}{here}. - -@b{Step 3:} -Edit the settings in the file @c{config/user-settings}. -The list of supported platforms is given in that file. - -@b{Step 4:} -Run GNU @c{make} to configure and build ODE and the graphical test programs. -The configuration process creates the file @c{include/ode/config.h}. - -@b{Step 5:} -To install the ODE library onto your system you should copy the @c{lib/} and -@c{include/} directories to a suitable place, e.g. on Unix: -@list{ -@* @c{include/ode/ --> /usr/local/include/ode/} -@* @c{lib/libode.a --> /usr/local/lib/libode.a} -} - - -@subsection{Building and Running ODE Tests on MacOS X} - -ODE uses XWindows and OpenGL to render the scene being simulated. -In order to build the example you will need to install Apple X11 -server and the X11SDK (as well as the normal developer tools). - -These are available from Apple. As of writing this can be found at: -@link{http://www.apple.com/macosx/x11}{http://www.apple.com/macosx/x11}. -NOTE: there is a tiny link at the bottom right of the page for the SDK - -Once the software is installed follow the normal build instructions. - -Since ODE uses X11 you need to run the X11 server (which you should -have installed, it's in the Applications Folder). - -If you run the test app in the XTerm that the X11 server opens by -default then they should run fine. If however you run them from a MacOS X -Terminal then you need to define the environment variable DISPLAY. If -DISPLAY is not defined then you will get a message saying: -"cannot open X11 display". - -For example to run the boxstack test you would type -@[ - cd ode/test - DISPLAY=:0.0 ./test_boxstack.exe -@] -You can define this environment variable in your shell startup scripts -(for example in ~/.bashrc if you are using bash) - - -@section{Using ODE} - -The best way to understand how to use ODE is to look at the test/example -programs that come with it. Note the following things: -@list{ -@* Source files that use ODE only need to include a single header file: -@[ - #include <ode/ode.h> -@] - The @c{ode} directory in this statement is actually the - @c{include/ode} directory of the ODE distribution. - This header file will include others in the @c{ode} directory, - so you need to set the include path of your compiler, - e.g. in linux -@[ - gcc -c -I /home/username/ode/include myprogram.cpp -@] - -@* When ODE is used with the @func{dWorldStep()} function, heavy use is made - of the stack for storing temporary values. - For very large systems several megabytes of stack can be used. - If you experience unexplained out-of-memory errors or data - corruption, especially on Windows, try increasing the stack size, or - switching to @func{dWorldQuickStep()}. -} - -############################################################################# -@chapter{Concepts} - -@section{Background} - -[Here is where I will write some background information about rigid body -dynamics and simulation. -But in the meantime, please refer to Baraff's excellent -@link{http://www.cs.cmu.edu/~baraff/sigcourse/index.html}{SIGGRAPH tutorial}]. - - -@section{Rigid bodies} - -A rigid body has various properties from the point of view of the simulation. -Some properties change over time: -@list{ -@* Position vector (x,y,z) of the body's point of reference. - Currently the point of reference must correspond to the body's - center of mass. -@* Linear velocity of the point of reference, a vector (vx,vy,vz). -@* Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or - a 3x3 rotation matrix. -@* Angular velocity vector (wx,wy,wz) which describes how the orientation - changes over time. - -} -Other body properties are usually constant over time: -@list{ -@* Mass of the body. -@* Position of the center of mass with respect to the point of reference. - In the current implementation the center of mass and the point of - reference must coincide. -@* Inertia matrix. This is a 3x3 matrix that describes how the body's - mass is distributed around the center of mass. -} -Conceptually each body has an x-y-z coordinate frame embedded in it, that moves -and rotates with the body, as shown in @fig{body}. - - @figure{body}{The body coordinate frame.}{3in} - -The origin of this coordinate frame is the body's point of reference. -Some values in ODE (vectors, matrices etc) are relative to the body -coordinate frame, and others are relative to the global coordinate frame. - -Note that the @emph{shape} of a rigid body is not a dynamical property -(except insofar as it influences the various mass properties). -It is only @emph{collision detection} that cares about the detailed shape of -the body. - - -@subsection{Islands and Disabled Bodies} - -Bodies are connected to each other with joints. -An ``island'' of bodies is a group that can not be pulled apart - in other -words each body is connected somehow to every other body in the island. - -Each island in the world is treated separately when the simulation step is -taken. -This is useful to know: if there are @m{N} similar islands in the -simulation then the step computation time will be @m{O(N)}. - -Each body can be enabled or disabled. -Disabled bodies are effectively ``turned off'' and are not updated during a -simulation step. -Disabling bodies is an effective way to save computation time when it is known -that the bodies are motionless or otherwise irrelevant to the simulation. - -If there are any enabled bodies in an island then every body in the island -will be enabled at the next simulation step. -Thus to effectively disable an island of bodies, @emph{every} body in the -island must be disabled. -If a disabled island is touched by another enabled body then the entire -island will be enabled, as a contact joint will join the enabled body to -the island. - - -@section{Integration} - -The process of simulating the rigid body system through time is called -integration. -Each integration step advances the current time by a given step size, -adjusting the state of all the rigid bodies for the new time value. -There are two main issues to consider when working with any integrator: -@list{ -@* How accurate is it? That is, how closely does the behavior of the - simulated system match what would happen in real life? -@* How stable is it? That is, will calculation errors ever cause - completely non-physical behavior of the simulated system? - (e.g. causing the system to "explode" for no reason). -} -ODE's current integrator is very stable, but not particularly accurate -unless the step size is small. -For most uses of ODE this is not a problem -- ODE's behavior still looks -perfectly physical in almost all cases. -However ODE should not be used for quantitative engineering until this accuracy -issue has been addressed in a future release. - - -@section{Force accumulators} - -Between each integrator step the user can call functions to apply forces -to the rigid body. -These forces are added to "force accumulators" in the rigid body object. -When the next integrator step happens, the sum of all the applied forces -will be used to push the body around. -The forces accumulators are set to zero after each integrator step. - - -@section{Joints and constraints} - -In real life a joint is something like a hinge, that is used to connect two -objects. -In ODE a joint is very similar: It is a relationship that is enforced between -two bodies so that they can only have certain positions and orientations -relative to each other. -This relationship is called a @emph{constraint} -- the words @emph{joint} and -@emph{constraint} are often used interchangeably. -@Fig{joints} shows three different constraint types. - - @figure{joints}{Three different constraint types.}{5in} - -The first is a ball and socket joint that constraints the ``ball'' of one -body to be in the same location as the ``socket'' of another body. -The second is a hinge joint that constraints the two parts of the -hinge to be in the same location and to line up along the hinge axle. -The third is a slider joint that constraints the ``piston'' and ``socket'' -to line up, and additionally constraints the two bodies to have the same -orientation. - -Each time the integrator takes a step all the joints are allowed to apply -@emph{constraint forces} to the bodies they affect. -These forces are calculated such that the bodies move in such a way to -preserve all the joint relationships. - -Each joint has a number of parameters controlling its geometry. -An example is the position of the ball-and-socket point for a ball-and-socket -joint. -The functions to set joint parameters all take @emph{global} coordinates, -not body-relative coordinates. -A consequence of this is that the rigid bodies that a joint connects must be -positioned correctly @emph{before} the joint is attached. - - -@section{Joint groups} - -A joint group is a special container that holds joints in a world. -Joints can be added to a group, and then when those joints are no -longer needed the entire group of joints can be very quickly destroyed -with one function call. -However, individual joints in a group can not be destroyed before the entire -group is emptied. - -This is most useful with contact joints, which are added and remove from -the world in groups every time step. - - -@section{Joint error and the error reduction parameter (ERP)} - -When a joint attaches two bodies, those bodies are required to have certain -positions and orientations relative to each other. -However, it is possible for the bodies to be in positions where the joint -constraints are not met. -This ``joint error'' can happen in two ways: -@numlist{ -@* If the user sets the position/orientation of one body without correctly - setting the position/orientation of the other body. -@* During the simulation, errors can creep in that result in the bodies - drifting away from their required positions. -} -@Fig{ball-and-socket-bad} shows an example of error in a ball and socket -joint (where the ball and socket do not line up). - - @figure{ball-and-socket-bad}{An example of error in a ball and socket joint.}{3in} - -There is a mechanism to reduce joint error: during each simulation step each -joint applies a special force to bring its bodies back into correct alignment. -This force is controlled by the @emph{error reduction parameter} (ERP), -which has a value between 0 and 1. - -The ERP specifies what proportion of the joint error will be -fixed during the next simulation step. -If ERP=0 then no correcting force is applied and the bodies will eventually -drift apart as the simulation proceeds. -If ERP=1 then the simulation will attempt to fix all joint error during the -next time step. -However, setting ERP=1 is not recommended, as the joint error will not be -completely fixed due to various internal approximations. -A value of ERP=0.1 to 0.8 is recommended (0.2 is the default). - -A global ERP value can be set that affects most joints in the simulation. -However some joints have local ERP values that control various aspects of -the joint. - - -@section{Soft constraint and constraint force mixing (CFM)} - -Most constraints are by nature ``hard''. -This means that the constraints represent conditions that are never violated. -For example, the ball must always be in the socket, and the two parts of the -hinge must always be lined up. -In practice constraints can be violated by unintentional introduction of -errors into the system, but the error reduction parameter can be set to -correct these errors. - -Not all constraints are hard. -Some ``soft'' constraints are designed to be violated. -For example, the contact constraint that prevents colliding objects from -penetrating is hard by default, so it acts as though the colliding surfaces -are made of steel. -But it can be made into a soft constraint to simulate softer materials, -thereby allowing some natural penetration of the two objects when they are -forced together. - -There are two parameters that control the distinction between hard and soft -constraints. The first is the error reduction parameter (ERP) that has already -been introduced. -The second is the constraint force mixing (CFM) value, that is described below. - - -@subsection{Constraint Force Mixing (CFM)} - -What follows is a somewhat technical description of the meaning of CFM. -If you just want to know how it is used in practice then skip to the next -section. - -Traditionally the constraint equation for every joint has the form - - @eqn{J * v = c} - -where @m{v} is a velocity vector for the bodies involved, @m{J} is a -``Jacobian'' matrix with one row for every degree of freedom the joint -removes from the system, and @m{c} is a right hand side vector. -At the next time step, a vector @m{lambda} is calculated (of the same -size as @m{c}) such that the forces applied to the bodies to preserve the -joint constraint are - - @eqn{force = J^T * @sym{lambda}} - -ODE adds a new twist. -ODE's constraint equation has the form - - @eqn{J * v = c + CFM * @sym{lambda}} - -where @m{CFM} is a square diagonal matrix. -@m{CFM} mixes the resulting constraint force in with the constraint that -produces it. -A nonzero (positive) value of @m{CFM} allows the original constraint -equation to be violated by an amount proportional to CFM times the restoring -force @m{@sym{lambda}} that is needed to enforce the constraint. -Solving for @m{@sym{lambda}} gives - - @eqn{(J M^{-1} J^T + CFM/h) @sym{lambda} = c/h} - -Thus @m{CFM} simply adds to the diagonal of the original system matrix. -Using a positive value of @m{CFM} has the additional benefit of taking the -system away from any singularity and thus improving the factorizer accuracy. - - -@subsection{How To Use ERP and CFM} - -ERP and CFM can be independently set in many joints. They can be set in -contact joints, in joint limits and various other places, to control the -spongyness and springyness of the joint (or joint limit). - -If CFM is set to zero, the constraint will be hard. -If CFM is set to a positive value, it will be possible to violate the -constraint by ``pushing on it'' (for example, for contact constraints by -forcing the two contacting objects together). -In other words the constraint will be soft, and the softness will increase -as CFM increases. -What is actually happening here is that the constraint is allowed to be -violated by an amount proportional to CFM times the restoring force that is -needed to enforce the constraint. -Note that setting CFM to a negative value can have undesirable bad effects, -such as instability. Don't do it. - -By adjusting the values of ERP and CFM, you can achieve various effects. -For example you can simulate springy constraints, where the two bodies -oscillate as though connected by springs. -Or you can simulate more spongy constraints, without the oscillation. -In fact, ERP and CFM can be selected to have the same effect as any -desired spring and damper constants. -If you have a spring constant @m{k_p} and damping constant @m{k_d}, -then the corresponding ODE constants are: - - @eqn{ERP = h k_p / (h k_p + k_d)} - @eqn{CFM = 1 / (h k_p + k_d)} - -where @m{h} is the stepsize. -These values will give the same effect as a spring-and-damper system simulated -with implicit first order integration. - -Increasing CFM, especially the global CFM, can reduce the numerical errors -in the simulation. If the system is near-singular, then this can markedly -increase stability. -In fact, if the system is mis-behaving, one of the first things to try is -to increase the global CFM. - - -@section{Collision handling} - -[There is a lot that needs to be written about collision handling.] - -Collisions between bodies or between bodies and the static environment are -handled as follows: -@numlist{ -@* Before each simulation step, the user calls collision detection - functions to determine what is touching what. - These functions return a list of contact points. - Each contact point specifies a position in space, a surface normal - vector, and a penetration depth. - -@* A special contact joint is created for each contact point. - The contact joint is given extra information about the contact, - for example the friction present at the contact surface, how bouncy - or soft it is, and various other properties. - -@* The contact joints are put in a joint "group", which allows them to be - added to and removed from the system very quickly. - The simulation speed goes down as the number of contacts goes up, - so various strategies can be used to limit the number of contact - points. - -@* A simulation step is taken. - -@* All contact joints are removed from the system. -} -Note that the built-in collision functions do not have to be used - -other collision detection libraries can be used as long as they provide -the right kinds of contact point information. - - -@section{Typical simulation code} - -A typical simulation will proceed like this: -@numlist{ -@* Create a dynamics world. -@* Create bodies in the dynamics world. -@* Set the state (position etc) of all bodies. -@* Create joints in the dynamics world. -@* Attach the joints to the bodies. -@* Set the parameters of all joints. -@* Create a collision world and collision geometry objects, as - necessary. -@* Create a joint group to hold the contact joints. -@* Loop: @numlist{ - @* Apply forces to the bodies as necessary. - @* Adjust the joint parameters as necessary. - @* Call collision detection. - @* Create a contact joint for every collision point, and put it - in the contact joint group. - @* Take a simulation step. - @* Remove all joints in the contact joint group. - } -@* Destroy the dynamics and collision worlds. -} - - -@section{Physics model} - -The various methods and approximations that are used in ODE are discussed -here. - -@subsection{Friction Approximation} - -[We really need more pictures here.] - -The Coulomb friction model is a simple, but effective way to model friction -at contact points. -It is a simple relationship between the normal and tangential forces present -at a contact point (see the contact joint section for a description of these -forces). The rule is: - - @eqn{| f_T | <= @sym{mu} * | f_N |} - -where @m{f_N} and @m{f_T} are the normal and tangential force vectors -respectively, and @m{@sym{mu}} is the friction coefficient (typically a number -around 1.0). -This equation defines a "friction cone" - imagine a cone with @m{f_N} as the -axis and the contact point as the vertex. -If the total friction force vector is within the cone then the contact is in -"sticking mode", and the friction force is enough to prevent the contacting -surfaces from moving with respect to each other. -If the force vector is on the surface of the cone then the contact is in -"sliding mode", and the friction force is typically not large enough to -prevent the contacting surfaces from sliding. -The parameter @m{@sym{mu}} thus specifies the maximum ratio of tangential to normal -force. - -ODE's friction models are approximations to the friction cone, for reasons of -efficiency. There are currently two approximations to chose from: -@numlist{ -@* The meaning of @m{@sym{mu}} is changed so that it specifies the - maximum friction (tangential) force that can be present at a contact, - in either of the tangential friction directions. - This is rather non physical because it is independent of the normal - force, but it can be useful and it is the computationally cheapest - option. Note that in this case @m{@sym{mu}} is a force limit an must be - chosen appropriate to the simulation. -@* The friction cone is approximated by a friction pyramid aligned with - the first and second friction directions [I really need a picture - here]. - A further approximation is made: first ODE computes the normal forces - assuming that all the contacts are frictionless. Then it computes the - maximum limits @m{f_m} for the friction (tangential) forces from - - @eqn{f_m = @sym{mu} * | f_N |} - - and then proceeds to solve for the entire system with these fixed - limits (in a manner similar to approximation 1 above). - This differs from a true friction pyramid in that the "effective" - @m{@sym{mu}} is not quite fixed. - This approximation is easier to use as @m{@sym{mu}} is a unit-less ratio - the same as the normal Coloumb friction coefficient, and thus can be - set to a constant value around 1.0 without regard for the specific - simulation. -} - -############################################################################# -@chapter{Data Types and Conventions} - -@section{The basic data types} - -The ODE library can be built to use either single or double precision floating -point numbers. -Single precision is faster and uses less memory, but the simulation will -have more numerical error that can result in visible problems. -You will get less accuracy and stability with single precision. - -[must describe what factors influence accuracy and stability]. - -The floating point data type is @c{dReal}. -Other commonly used types are @c{dVector3}, @c{dVector4}, @c{dMatrix3}, -@c{dMatrix4}, @c{dQuaternion}. - - -@section{Objects and IDs} - -There are various kinds of object that can be created: -@list{ -@* dWorld - a dynamics world. -@* dSpace - a collision space. -@* dBody - a rigid body. -@* dGeom - geometry (for collision). -@* dJoint - a joint -@* dJointGroup - a group of joints. -} -Functions that deal with these objects take and return object IDs. -The object ID types are @c{dWorldID}, @c{dBodyID}, etc. - - -@section{Argument conventions} - -All 3-vectors (x,y,z) supplied to ``set'' functions are given as individual -x,y,z arguments. - -All 3-vector result arguments to get() function are pointers to arrays of -@c{dReal}. - -Larger vectors are always supplied and returned as pointers to arrays of -@c{dReal}. - -All coordinates are in the global frame except where otherwise specified. - - -@section{C versus C++} - -The ODE library is written in C++, but its public interface is made of simple -C functions, not classes. Why is this? -@list{ -@* Using a C interface only is simpler - the features of C++ features do - not help much for ODE. -@* It prevents C++ mangling and runtime-support problems across multiple - compilers. -@* The user doesn't have to be familiar with C++ quirks to use ODE. -} - - -@section{Debugging} - -The ODE library can be compiled in "debugging" or "release" mode. -Debugging mode is slower, but function arguments are checked and many -run-time tests are done to ensure internal consistency. -Release mode is faster, but no checking is done. - -############################################################################# -@chapter{World} - -The world object is a container for rigid bodies and joints. -Objects in different worlds can not interact, for example rigid bodies from -two different worlds can not collide. - -All the objects in a world exist at the same point in time, thus one reason -to use separate worlds is to simulate systems at different rates. - -Most applications will only need one world. - - -@funcdef{ -dWorldID dWorldCreate(); -}{ -Create a new, empty world and return its ID number. -} - - -@funcdef{ -void dWorldDestroy (dWorldID); -}{ -Destroy a world and everything in it. This includes all bodies, and all -joints that are not part of a joint group. -Joints that are part of a joint group will be deactivated, and can be -destroyed by calling, for example, @func{dJointGroupEmpty()}. -} - - -@funcdef{ -void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z); -void dWorldGetGravity (dWorldID, dVector3 gravity); -}{ -Set and get the world's global gravity vector. The units are m/s/s, so Earth's -gravity vector would be (0,0,-9.81), assuming that +z is up. -The default is no gravity, i.e. (0,0,0). -} - - -@funcdef{ -void dWorldSetERP (dWorldID, dReal erp); -dReal dWorldGetERP (dWorldID); -}{ -Set and get the global ERP value, that controls how much error correction is -performed in each time step. -Typical values are in the range 0.1--0.8. -The default is 0.2. -} - - -@funcdef{ -void dWorldSetCFM (dWorldID, dReal cfm); -dReal dWorldGetCFM (dWorldID); -}{ -Set and get the global CFM (constraint force mixing) value. -Typical values are in the range @m{10^{-9}} -- 1. -The default is @m{10^{-5}} if single precision is being used, or @m{10^{-10}} if double -precision is being used. -} - - -@funcdef{ -void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable); -int dWorldGetAutoDisableFlag (dWorldID); -void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold); -dReal dWorldGetAutoDisableLinearThreshold (dWorldID); -void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold); -dReal dWorldGetAutoDisableAngularThreshold (dWorldID); -void dWorldSetAutoDisableSteps (dWorldID, int steps); -int dWorldGetAutoDisableSteps (dWorldID); -void dWorldSetAutoDisableTime (dWorldID, dReal time); -dReal dWorldGetAutoDisableTime (dWorldID); -}{ -Set and get the default auto-disable parameters for newly created bodies. -See @secref{Automatic Enabling and Disabling} for a description of the auto-disable feature. -The default parameters are: -@list{ -@* AutoDisableFlag = disabled -@* AutoDisableLinearThreshold = 0.01 -@* AutoDisableAngularThreshold = 0.01 -@* AutoDisableSteps = 10 -@* AutoDisableTime = 0 -} -} - - -@funcdef{ -void dWorldImpulseToForce (dWorldID, dReal stepsize, - dReal ix, dReal iy, dReal iz, dVector3 force); -}{ -If you want to apply a linear or angular impulse to a rigid body, -instead of a force or a torque, then you can use this function to convert -the desired impulse into a force/torque vector before calling the -@c{dBodyAdd...} function. - -This function is given the desired impulse as (@arg{ix},@arg{iy},@arg{iz}) -and puts the force vector in @arg{force}. -The current algorithm simply scales the impulse by 1/@arg{stepsize}, -where @arg{stepsize} is the step size for the @emph{next} step that will -be taken. - -This function is given a @c{dWorldID} because, in the future, the force -computation may depend on integrator parameters that are set as -properties of the world. -} - - -@funcdef{ -void dCloseODE(); -}{ -This deallocates some extra memory used by ODE that can not be deallocated -using the normal destroy functions, e.g. @func{dWorldDestroy()}. -You can use this function at the end of your application to prevent -memory leak checkers from complaining about ODE. -} - - -@section{Stepping Functions} - -@funcdef{ -void dWorldStep (dWorldID, dReal stepsize); -}{ -Step the world. -This uses a "big matrix" method that takes time on the order of @m{m^3} -and memory on the order of @m{m^2}, where @m{m} is the total number of constraint rows. - -For large systems this will use a lot of memory and can be very slow, -but this is currently the most accurate method. -} - - -@funcdef{ -void dWorldQuickStep (dWorldID, dReal stepsize); -}{ -Step the world. -This uses an iterative method that takes time on the order of @m{m*N} -and memory on the order of @m{m}, where @m{m} is the total number of constraint rows -and @m{N} is the number of iterations. - -For large systems this is a lot faster than @func{dWorldStep()}, -but it is less accurate. - -QuickStep is great for stacks of objects especially when the auto-disable feature -is used as well. -However, it has poor accuracy for near-singular systems. -Near-singular systems can occur when using high-friction contacts, motors, -or certain articulated structures. For example, a robot with multiple legs -sitting on the ground may be near-singular. - -There are ways to help overcome QuickStep's inaccuracy problems: -@list{ -@* Increase CFM. -@* Reduce the number of contacts in your system (e.g. use the minimum - number of contacts for the feet of a robot or creature). -@* Don't use excessive friction in the contacts. -@* Use contact slip if appropriate -@* Avoid kinematic loops (however, kinematic loops are inevitable in - legged creatures). -@* Don't use excessive motor strength. -@* Use force-based motors instead of velocity-based motors. -} -Increasing the number of QuickStep iterations may help a little bit, but -it is not going to help much if your system is really near singular. - -} - - -@funcdef{ -void dWorldSetQuickStepNumIterations (dWorldID, int num); -int dWorldGetQuickStepNumIterations (dWorldID); -}{ -Set and get the number of iterations that the QuickStep method performs per step. -More iterations will give a more accurate solution, but will take longer to compute. -The default is 20 iterations. -} - - -@section{Contact Parameters} - -@funcdef{ -void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel); -dReal dWorldGetContactMaxCorrectingVel (dWorldID); -}{ -Set and get the maximum correcting velocity that contacts are allowed to generate. -The default value is infinity (i.e. no limit). -Reducing this value can help prevent "popping" of deeply embedded objects. -} - - -@funcdef{ -void dWorldSetContactSurfaceLayer (dWorldID, dReal depth); -dReal dWorldGetContactSurfaceLayer (dWorldID); -}{ -Set and get the depth of the surface layer around all geometry objects. -Contacts are allowed to sink into the surface layer up to the given -depth before coming to rest. -The default value is zero. -Increasing this to some small value (e.g. 0.001) can help prevent jittering problems -due to contacts being repeatedly made and broken. -} - -############################################################################# -@chapter{Rigid Body Functions} - -@section{Creating and Destroying Bodies} - -@funcdef{ -dBodyID dBodyCreate (dWorldID); -}{ -Create a body in the given world with default mass parameters at -position (0,0,0). -Return its ID. -} - - -@funcdef{ -void dBodyDestroy (dBodyID); -}{ -Destroy a body. -All joints that are attached to this body will be put into limbo -(i.e. unattached and not affecting the simulation, but they will NOT be -deleted). -} - - -@section{Position and orientation} - -@funcdef{ -void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z); -void dBodySetRotation (dBodyID, const dMatrix3 R); -void dBodySetQuaternion (dBodyID, const dQuaternion q); -void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z); -void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z); -const dReal * dBodyGetPosition (dBodyID); -const dReal * dBodyGetRotation (dBodyID); -const dReal * dBodyGetQuaternion (dBodyID); -const dReal * dBodyGetLinearVel (dBodyID); -const dReal * dBodyGetAngularVel (dBodyID); -}{ -These functions set and get the position, rotation, linear and angular -velocity of the body. -After setting a group of bodies, the outcome of the simulation is undefined -if the new configuration is inconsistent with the joints/constraints that are -present. -When getting, the returned values are pointers to internal data structures, -so the vectors are valid until any changes are made to the rigid body system -structure. - -Hmmm. @c{dBodyGetRotation} returns a 4x3 rotation matrix. -} - - - -@section{Mass and force} - -@funcdef{ -void dBodySetMass (dBodyID, const dMass *mass); -void dBodyGetMass (dBodyID, dMass *mass); -}{ -Set/get the mass of the body (see the mass functions). -} - - -@funcdef{ -void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); -void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); -void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz); -void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz); -void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz); -void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz); -void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz); -void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz); -}{ -Add forces to bodies (absolute or relative coordinates). -The forces are accumulated on to each body, and the accumulators are zeroed -after each time step. - -The ...@c{RelForce} and ...@c{RelTorque} functions take force vectors that are -relative to the body's own frame of reference. - -The ...@c{ForceAtPos} and ...@c{ForceAtRelPos} functions take an extra -position vector (in global or body-relative coordinates respectively) -that specifies the point at which the force is applied. -All other functions apply the force at the center of mass. -} - - -@funcdef{ -const dReal * dBodyGetForce (dBodyID); -const dReal * dBodyGetTorque (dBodyID); -}{ -Return the current accumulated force and torque vector. -The returned pointers point to an array of 3 @c{dReal}s. -The returned values are pointers to internal data structures, so the vectors -are only valid until any changes are made to the rigid body system. -} - - -@funcdef{ -void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z); -void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z); -}{ -Set the body force and torque accumulation vectors. -This is mostly useful to zero the force and torque for deactivated bodies -before they are reactivated, in the case where the force-adding functions -were called on them while they were deactivated. -} - - -@section{Utility} - -@funcdef{ -void dBodyGetRelPointPos (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyGetRelPointVel (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyGetPointVel (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -}{ -Utility functions that take a point on a body (@arg{px},@arg{py},@arg{pz}) and -return that point's position or velocity in global coordinates -(in @arg{result}). -The @c{dBodyGetRelPointXXX} functions are given the point in body -relative coordinates, and the @c{dBodyGetPointVel} function is given -the point in global coordinates. -} - - -@funcdef{ -void dBodyGetPosRelPoint (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -}{ -This is the inverse of @func{dBodyGetRelPointPos()}. -It takes a point in global coordinates (@arg{x},@arg{y},@arg{z}) and returns -the point's position in body-relative coordinates (@arg{result}). -} - - -@funcdef{ -void dBodyVectorToWorld (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyVectorFromWorld (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -}{ -Given a vector expressed in the body (or world) coordinate system -(@arg{x},@arg{y},@arg{z}), rotate it to the world (or body) coordinate system -(@arg{result}). -} - - -@section{Automatic Enabling and Disabling} - -Every body can be enabled or disabled. -Enabled bodies participate in the simulation, while -disabled bodies are turned off and do not get updated during a simulation step. -New bodies are always created in the enabled state. - -A disabled body that is connected through a joint to an enabled body will -be automatically re-enabled at the next simulation step. - -Disabled bodies do not consume CPU time, therefore to speed up the simulation -bodies should be disabled when they come to rest. -This can be done automatically with the auto-disable feature. - -If a body has its auto-disable flag turned on, it will automatically disable itself -when -@numlist{ -@* It has been idle for a given number of simulation steps. -@* It has also been idle for a given amount of simulation time. -} -A body is considered to be idle when the magnitudes of both its linear velocity -and angular velocity are below given thresholds. - -Thus, every body has five auto-disable parameters: an enabled flag, a idle step count, -an idle time, and linear/angular velocity thresholds. -Newly created bodies get these parameters from world. - -The following functions set and get the enable/disable parameters of a body. - - -@funcdef{ -void dBodyEnable (dBodyID); -void dBodyDisable (dBodyID); -}{ -Manually enable and disable a body. -Note that a disabled body that is connected through a joint to an enabled body will -be automatically re-enabled at the next simulation step. -} - - -@funcdef{ -int dBodyIsEnabled (dBodyID); -}{ -Return 1 if a body is currently enabled or 0 if it is disabled. -} - - -@funcdef{ -void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable); -int dBodyGetAutoDisableFlag (dBodyID); -}{ -Set and get the auto-disable flag of a body. -If the @arg{do_auto_disable} is nonzero the body will be automatically disabled when -it has been idle for long enough. -} - -@funcdef{ -void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_threshold); -dReal dBodyGetAutoDisableLinearThreshold (dBodyID); -}{ -Set and get a body's linear velocity threshold for automatic disabling. -The body's linear velocity magnitude must be less than this threshold for it -to be considered idle. -Set the threshold to @c{dInfinity} to prevent the linear velocity from being considered. -} - -@funcdef{ -void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_threshold); -dReal dBodyGetAutoDisableAngularThreshold (dBodyID); -}{ -Set and get a body's angular velocity threshold for automatic disabling. -The body's linear angular magnitude must be less than this threshold for it -to be considered idle. -Set the threshold to @c{dInfinity} to prevent the angular velocity from being considered. -} - -@funcdef{ -void dBodySetAutoDisableSteps (dBodyID, int steps); -int dBodyGetAutoDisableSteps (dBodyID); -}{ -Set and get the number of simulation steps that a body must be idle before it -is automatically disabled. -Set this to zero to disable consideration of the number of steps. -} - -@funcdef{ -void dBodySetAutoDisableTime (dBodyID, dReal time); -dReal dBodyGetAutoDisableTime (dBodyID); -}{ -Set and get the amount of simulation time that a body must be idle before it -is automatically disabled. -Set this to zero to disable consideration of the amount of simulation time. -} - -@funcdef{ -void dBodySetAutoDisableDefaults (dBodyID); -}{ -Set the auto-disable parameters of the body to the default parameters that have -been set on the world. -} - - -@section{Miscellaneous Body Functions} - -@funcdef{ -void dBodySetData (dBodyID, void *data); -void *dBodyGetData (dBodyID); -}{ -Get and set the body's user-data pointer. -} - - -@funcdef{ -void dBodySetFiniteRotationMode (dBodyID, int mode); -}{ -This function controls the way a body's orientation is updated at each time -step. The @arg{mode} argument can be: -@list{ -@* 0: An ``infinitesimal'' orientation update is used. - This is fast to compute, but it can occasionally cause inaccuracies - for bodies that are rotating at high speed, especially when those - bodies are joined to other bodies. - This is the default for every new body that is created. -@* 1: A ``finite'' orientation update is used. - This is more costly to compute, but will be more accurate for high - speed rotations. - Note however that high speed rotations can result in many types of - error in a simulation, and this mode will only fix one of those - sources of error. -} -} - - -@funcdef{ -int dBodyGetFiniteRotationMode (dBodyID); -}{ -Return the current finite rotation mode of a body (0 or 1). -} - - -@funcdef{ -void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z); -}{ -This sets the finite rotation axis for a body. -This is axis only has meaning when the finite rotation mode is set -(see @func{dBodySetFiniteRotationMode()}). - -If this axis is zero (0,0,0), full finite rotations are performed on the body. - -If this axis is nonzero, the body is rotated by performing a partial finite -rotation along the axis direction followed by an infinitesimal rotation along -an orthogonal direction. - -This can be useful to alleviate certain sources of error caused by quickly -spinning bodies. For example, if a car wheel is rotating at high speed -you can call this function with the wheel's hinge axis as the argument to -try and improve its behavior. -} - - -@funcdef{ -void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result); -}{ -Return the current finite rotation axis of a body. -} - - -@funcdef{ -int dBodyGetNumJoints (dBodyID b); -}{ -Return the number of joints that are attached to this body. -} - - -@funcdef{ -dJointID dBodyGetJoint (dBodyID, int index); -}{ -Return a joint attached to this body, given by @arg{index}. -Valid indexes are 0 to @m{n-1} where @m{n} is the value returned by -@func{dBodyGetNumJoints()}. -} - - -@funcdef{ -void dBodySetGravityMode (dBodyID b, int mode); -int dBodyGetGravityMode (dBodyID b); -}{ -Set/get whether the body is influenced by the world's gravity or not. -If @arg{mode} is nonzero it is, if @arg{mode} is zero, it isn't. -Newly created bodies are always influenced by the world's gravity. -} - -############################################################################# -@chapter{Joint Types and Joint Functions} - -@section{Creating and Destroying Joints} - -@funcdef{ -dJointID dJointCreateBall (dWorldID, dJointGroupID); -dJointID dJointCreateHinge (dWorldID, dJointGroupID); -dJointID dJointCreateSlider (dWorldID, dJointGroupID); -dJointID dJointCreateContact (dWorldID, dJointGroupID, - const dContact *); -dJointID dJointCreateUniversal (dWorldID, dJointGroupID); -dJointID dJointCreateHinge2 (dWorldID, dJointGroupID); -dJointID dJointCreateFixed (dWorldID, dJointGroupID); -dJointID dJointCreateAMotor (dWorldID, dJointGroupID); -dJointID dJointCreateLMotor (dWorldID, dJointGroupID); -}{ -Create a new joint of a given type. -The joint is initially in "limbo" (i.e. it has no effect on the simulation) -because it does not connect to any bodies. -The joint group ID is 0 to allocate the joint normally. -If it is nonzero the joint is allocated in the given joint group. -The contact joint will be initialized with the given @c{dContact} -structure. -} - - -@funcdef{ -void dJointDestroy (dJointID); -}{ -Destroy a joint, disconnecting it from its attached bodies and removing -it from the world. -However, if the joint is a member of a group then this function has no -effect - to destroy that joint the group must be emptied or destroyed. -} - - -@funcdef{ -dJointGroupID dJointGroupCreate (int max_size); -}{ -Create a joint group. -The @arg{max_size} argument is now unused and should be set to 0. -It is kept for backwards compatibility. -} - - -@funcdef{ -void dJointGroupDestroy (dJointGroupID); -}{ -Destroy a joint group. All joints in the joint group will be destroyed. -} - - -@funcdef{ -void dJointGroupEmpty (dJointGroupID); -}{ -Empty a joint group. All joints in the joint group will be destroyed, -but the joint group itself will not be destroyed. -} - - -@section{Miscellaneous Joint Functions} - -@funcdef{ -void dJointAttach (dJointID, dBodyID body1, dBodyID body2); -}{ -Attach the j... [truncated message content] |