1 /************************************************************************* 2 * * 3 * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * 4 * All rights reserved. Email: russ@q12.org Web: www.q12.org * 5 * * 6 * This library is free software; you can redistribute it and/or * 7 * modify it under the terms of EITHER: * 8 * (1) The GNU Lesser General Public License as published by the Free * 9 * Software Foundation; either version 2.1 of the License, or (at * 10 * your option) any later version. The text of the GNU Lesser * 11 * General Public License is included with this library in the * 12 * file LICENSE.TXT. * 13 * (2) The BSD-style license that is included with this library in * 14 * the file LICENSE-BSD.TXT. * 15 * * 16 * This library is distributed in the hope that it will be useful, * 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 19 * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 20 * * 21 *************************************************************************/ 22 23 #ifndef _ODE_OBJECTS_H_ 24 #define _ODE_OBJECTS_H_ 25 26 #include <ode/common.h> 27 #include <ode/mass.h> 28 #include <ode/contact.h> 29 #include <ode/threading.h> 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 /** 36 * @defgroup world World 37 * 38 * The world object is a container for rigid bodies and joints. Objects in 39 * different worlds can not interact, for example rigid bodies from two 40 * different worlds can not collide. 41 * 42 * All the objects in a world exist at the same point in time, thus one 43 * reason to use separate worlds is to simulate systems at different rates. 44 * Most applications will only need one world. 45 */ 46 47 /** 48 * @brief Create a new, empty world and return its ID number. 49 * @return an identifier 50 * @ingroup world 51 */ 52 ODE_API dWorldID dWorldCreate(void); 53 54 55 /** 56 * @brief Destroy a world and everything in it. 57 * 58 * This includes all bodies, and all joints that are not part of a joint 59 * group. Joints that are part of a joint group will be deactivated, and 60 * can be destroyed by calling, for example, dJointGroupEmpty(). 61 * @ingroup world 62 * @param world the identifier for the world the be destroyed. 63 */ 64 ODE_API void dWorldDestroy (dWorldID world); 65 66 67 /** 68 * @brief Set the world's global gravity vector. 69 * 70 * The units are m/s^2, so Earth's gravity vector would be (0,0,-9.81), 71 * assuming that +z is up. The default is no gravity, i.e. (0,0,0). 72 * 73 * @ingroup world 74 */ 75 ODE_API void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z); 76 77 78 /** 79 * @brief Get the gravity vector for a given world. 80 * @ingroup world 81 */ 82 ODE_API void dWorldGetGravity (dWorldID, dVector3 gravity); 83 84 85 /** 86 * @brief Set the global ERP value, that controls how much error 87 * correction is performed in each time step. 88 * @ingroup world 89 * @param dWorldID the identifier of the world. 90 * @param erp Typical values are in the range 0.1--0.8. The default is 0.2. 91 */ 92 ODE_API void dWorldSetERP (dWorldID, dReal erp); 93 94 /** 95 * @brief Get the error reduction parameter. 96 * @ingroup world 97 * @return ERP value 98 */ 99 ODE_API dReal dWorldGetERP (dWorldID); 100 101 102 /** 103 * @brief Set the global CFM (constraint force mixing) value. 104 * @ingroup world 105 * @param cfm Typical values are in the range @m{10^{-9}} -- 1. 106 * The default is 10^-5 if single precision is being used, or 10^-10 107 * if double precision is being used. 108 */ 109 ODE_API void dWorldSetCFM (dWorldID, dReal cfm); 110 111 /** 112 * @brief Get the constraint force mixing value. 113 * @ingroup world 114 * @return CFM value 115 */ 116 ODE_API dReal dWorldGetCFM (dWorldID); 117 118 119 #define dWORLDSTEP_THREADCOUNT_UNLIMITED 0U 120 121 /** 122 * @brief Set maximum threads to be used for island stepping 123 * 124 * The actual number of threads that is going to be used will be the minimum 125 * of this limit and number of threads in the threading pool. By default 126 * there is no limit (@c dWORLDSTEP_THREADCOUNT_UNLIMITED). 127 * 128 * @warning 129 * WARNING! Running island stepping in multiple threads requires allocating 130 * individual stepping memory buffer for each of those threads. The size of buffers 131 * allocated is the size needed to handle the largest island in the world. 132 * 133 * Note: Setting a limit for island stepping does not affect threading at lower 134 * levels in stepper functions. The sub-calls scheduled from them can be executed 135 * in as many threads as there are available in the pool. 136 * 137 * @param w The world affected 138 * @param count Thread count limit value for island stepping 139 * @ingroup world 140 * @see dWorldGetStepIslandsProcessingMaxThreadCount 141 */ 142 ODE_API void dWorldSetStepIslandsProcessingMaxThreadCount(dWorldID w, unsigned count); 143 /** 144 * @brief Get maximum threads that are allowed to be used for island stepping. 145 * 146 * Please read commentaries to @c dWorldSetStepIslandsProcessingMaxThreadCount for 147 * important information regarding the value returned. 148 * 149 * @param w The world queried 150 * @returns Current thread count limit value for island stepping 151 * @ingroup world 152 * @see dWorldSetStepIslandsProcessingMaxThreadCount 153 */ 154 ODE_API unsigned dWorldGetStepIslandsProcessingMaxThreadCount(dWorldID w); 155 156 /** 157 * @brief Set the world to use shared working memory along with another world. 158 * 159 * The worlds allocate working memory internally for simulation stepping. This 160 * memory is cached among the calls to @c dWordStep and @c dWorldQuickStep. 161 * Similarly, several worlds can be set up to share this memory caches thus 162 * reducing overall memory usage by cost of making worlds inappropriate for 163 * simultaneous simulation in multiple threads. 164 * 165 * If null value is passed for @a from_world parameter the world is detached from 166 * sharing and returns to defaults for working memory, reservation policy and 167 * memory manager as if just created. This can also be used to enable use of shared 168 * memory for a world that has already had working memory allocated privately. 169 * Normally using shared memory after a world has its private working memory allocated 170 * is prohibited. 171 * 172 * Allocation policy used can only increase world's internal reserved memory size 173 * and never decreases it. @c dWorldCleanupWorkingMemory can be used to release 174 * working memory for a world in case if number of objects/joint decreases 175 * significantly in it. 176 * 177 * With sharing working memory worlds also automatically share memory reservation 178 * policy and memory manager. Thus, these parameters need to be customized for 179 * initial world to be used as sharing source only. 180 * 181 * If worlds share working memory they must also use compatible threading implementations 182 * (i.e. it is illegal for one world to perform stepping with self-threaded implementation 183 * when the other world is assigned a multi-threaded implementation). 184 * For more information read section about threading approaches in ODE. 185 * 186 * Failure result status means a memory allocation failure. 187 * 188 * @param w The world to use the shared memory with. 189 * @param from_world Null or the world the shared memory is to be used from. 190 * @returns 1 for success and 0 for failure. 191 * 192 * @ingroup world 193 * @see dWorldCleanupWorkingMemory 194 * @see dWorldSetStepMemoryReservationPolicy 195 * @see dWorldSetStepMemoryManager 196 */ 197 ODE_API int dWorldUseSharedWorkingMemory(dWorldID w, dWorldID from_world/*=NULL*/); 198 199 /** 200 * @brief Release internal working memory allocated for world 201 * 202 * The worlds allocate working memory internally for simulation stepping. This 203 * function can be used to free world's internal memory cache in case if number of 204 * objects/joints in the world decreases significantly. By default, internal 205 * allocation policy is used to only increase cache size as necessary and never 206 * decrease it. 207 * 208 * If a world shares its working memory with other worlds the cache deletion 209 * affects all the linked worlds. However the shared status itself remains intact. 210 * 211 * The function call does affect neither memory reservation policy nor memory manager. 212 * 213 * @param w The world to release working memory for. 214 * 215 * @ingroup world 216 * @see dWorldUseSharedWorkingMemory 217 * @see dWorldSetStepMemoryReservationPolicy 218 * @see dWorldSetStepMemoryManager 219 */ 220 ODE_API void dWorldCleanupWorkingMemory(dWorldID w); 221 222 223 #define dWORLDSTEP_RESERVEFACTOR_DEFAULT 1.2f 224 #define dWORLDSTEP_RESERVESIZE_DEFAULT 65536U 225 226 /** 227 * @struct dWorldStepReserveInfo 228 * @brief Memory reservation policy descriptor structure for world stepping functions. 229 * 230 * @c struct_size should be assigned the size of the structure. 231 * 232 * @c reserve_factor is a quotient that is multiplied by required memory size 233 * to allocate extra reserve whenever reallocation is needed. 234 * 235 * @c reserve_minimum is a minimum size that is checked against whenever reallocation 236 * is needed to allocate expected working memory minimum at once without extra 237 * reallocations as number of bodies/joints grows. 238 * 239 * @ingroup world 240 * @see dWorldSetStepMemoryReservationPolicy 241 */ 242 typedef struct 243 { 244 unsigned struct_size; 245 float reserve_factor; /* Use float as precision does not matter here*/ 246 unsigned reserve_minimum; 247 248 } dWorldStepReserveInfo; 249 250 /** 251 * @brief Set memory reservation policy for world to be used with simulation stepping functions 252 * 253 * The function allows to customize reservation policy to be used for internal 254 * memory which is allocated to aid simulation for a world. By default, values 255 * of @c dWORLDSTEP_RESERVEFACTOR_DEFAULT and @c dWORLDSTEP_RESERVESIZE_DEFAULT 256 * are used. 257 * 258 * Passing @a policyinfo argument as NULL results in reservation policy being 259 * reset to defaults as if the world has been just created. The content of 260 * @a policyinfo structure is copied internally and does not need to remain valid 261 * after the call returns. 262 * 263 * If the world uses working memory sharing, changing memory reservation policy 264 * affects all the worlds linked together. 265 * 266 * Failure result status means a memory allocation failure. 267 * 268 * @param w The world to change memory reservation policy for. 269 * @param policyinfo Null or a pointer to policy descriptor structure. 270 * @returns 1 for success and 0 for failure. 271 * 272 * @ingroup world 273 * @see dWorldUseSharedWorkingMemory 274 */ 275 ODE_API int dWorldSetStepMemoryReservationPolicy(dWorldID w, const dWorldStepReserveInfo *policyinfo/*=NULL*/); 276 277 /** 278 * @struct dWorldStepMemoryFunctionsInfo 279 * @brief World stepping memory manager descriptor structure 280 * 281 * This structure is intended to define the functions of memory manager to be used 282 * with world stepping functions. 283 * 284 * @c struct_size should be assigned the size of the structure 285 * 286 * @c alloc_block is a function to allocate memory block of given size. 287 * 288 * @c shrink_block is a function to shrink existing memory block to a smaller size. 289 * It must preserve the contents of block head while shrinking. The new block size 290 * is guaranteed to be always less than the existing one. 291 * 292 * @c free_block is a function to delete existing memory block. 293 * 294 * @ingroup init 295 * @see dWorldSetStepMemoryManager 296 */ 297 typedef struct 298 { 299 unsigned struct_size; 300 void *(*alloc_block)(size_t block_size); 301 void *(*shrink_block)(void *block_pointer, size_t block_current_size, size_t block_smaller_size); 302 void (*free_block)(void *block_pointer, size_t block_current_size); 303 304 } dWorldStepMemoryFunctionsInfo; 305 306 /** 307 * @brief Set memory manager for world to be used with simulation stepping functions 308 * 309 * The function allows to customize memory manager to be used for internal 310 * memory allocation during simulation for a world. By default, @c dAlloc/@c dRealloc/@c dFree 311 * based memory manager is used. 312 * 313 * Passing @a memfuncs argument as NULL results in memory manager being 314 * reset to default one as if the world has been just created. The content of 315 * @a memfuncs structure is copied internally and does not need to remain valid 316 * after the call returns. 317 * 318 * If the world uses working memory sharing, changing memory manager 319 * affects all the worlds linked together. 320 * 321 * Failure result status means a memory allocation failure. 322 * 323 * @param w The world to change memory reservation policy for. 324 * @param memfuncs Null or a pointer to memory manager descriptor structure. 325 * @returns 1 for success and 0 for failure. 326 * 327 * @ingroup world 328 * @see dWorldUseSharedWorkingMemory 329 */ 330 ODE_API int dWorldSetStepMemoryManager(dWorldID w, const dWorldStepMemoryFunctionsInfo *memfuncs); 331 332 /** 333 * @brief Assign threading implementation to be used for [quick]stepping the world. 334 * 335 * @warning It is not recommended to assign the same threading implementation to 336 * different worlds if they are going to be called in parallel. In particular this 337 * makes resources preallocation for threaded calls to lose its sense. 338 * Built-in threading implementation is likely to crash if misused this way. 339 * 340 * @param w The world to change threading implementation for. 341 * @param functions_info Pointer to threading functions structure 342 * @param threading_impl ID of threading implementation object 343 * 344 * @ingroup world 345 */ 346 ODE_API void dWorldSetStepThreadingImplementation(dWorldID w, const dThreadingFunctionsInfo *functions_info, dThreadingImplementationID threading_impl); 347 348 /** 349 * @brief Step the world. 350 * 351 * This uses a "big matrix" method that takes time on the order of m^3 352 * and memory on the order of m^2, where m is the total number of constraint 353 * rows. For large systems this will use a lot of memory and can be very slow, 354 * but this is currently the most accurate method. 355 * 356 * Failure result status means that the memory allocation has failed for operation. 357 * In such a case all the objects remain in unchanged state and simulation can be 358 * retried as soon as more memory is available. 359 * 360 * @param w The world to be stepped 361 * @param stepsize The number of seconds that the simulation has to advance. 362 * @returns 1 for success and 0 for failure 363 * 364 * @ingroup world 365 */ 366 ODE_API int dWorldStep (dWorldID w, dReal stepsize); 367 368 /** 369 * @brief Quick-step the world. 370 * 371 * This uses an iterative method that takes time on the order of m*N 372 * and memory on the order of m, where m is the total number of constraint 373 * rows N is the number of iterations. 374 * For large systems this is a lot faster than dWorldStep(), 375 * but it is less accurate. 376 * 377 * QuickStep is great for stacks of objects especially when the 378 * auto-disable feature is used as well. 379 * However, it has poor accuracy for near-singular systems. 380 * Near-singular systems can occur when using high-friction contacts, motors, 381 * or certain articulated structures. For example, a robot with multiple legs 382 * sitting on the ground may be near-singular. 383 * 384 * There are ways to help overcome QuickStep's inaccuracy problems: 385 * 386 * \li Increase CFM. 387 * \li Reduce the number of contacts in your system (e.g. use the minimum 388 * number of contacts for the feet of a robot or creature). 389 * \li Don't use excessive friction in the contacts. 390 * \li Use contact slip if appropriate 391 * \li Avoid kinematic loops (however, kinematic loops are inevitable in 392 * legged creatures). 393 * \li Don't use excessive motor strength. 394 * \liUse force-based motors instead of velocity-based motors. 395 * 396 * Increasing the number of QuickStep iterations may help a little bit, but 397 * it is not going to help much if your system is really near singular. 398 * 399 * Failure result status means that the memory allocation has failed for operation. 400 * In such a case all the objects remain in unchanged state and simulation can be 401 * retried as soon as more memory is available. 402 * 403 * @param w The world to be stepped 404 * @param stepsize The number of seconds that the simulation has to advance. 405 * @returns 1 for success and 0 for failure 406 * 407 * @ingroup world 408 */ 409 ODE_API int dWorldQuickStep (dWorldID w, dReal stepsize); 410 411 412 /** 413 * @brief Converts an impulse to a force. 414 * @ingroup world 415 * @remarks 416 * If you want to apply a linear or angular impulse to a rigid body, 417 * instead of a force or a torque, then you can use this function to convert 418 * the desired impulse into a force/torque vector before calling the 419 * BodyAdd... function. 420 * The current algorithm simply scales the impulse by 1/stepsize, 421 * where stepsize is the step size for the next step that will be taken. 422 * This function is given a dWorldID because, in the future, the force 423 * computation may depend on integrator parameters that are set as 424 * properties of the world. 425 */ 426 ODE_API void dWorldImpulseToForce 427 ( 428 dWorldID, dReal stepsize, 429 dReal ix, dReal iy, dReal iz, dVector3 force 430 ); 431 432 433 /** 434 * @brief Set the number of iterations that the QuickStep method performs per 435 * step. 436 * @ingroup world 437 * @remarks 438 * More iterations will give a more accurate solution, but will take 439 * longer to compute. 440 * @param num The default is 20 iterations. 441 */ 442 ODE_API void dWorldSetQuickStepNumIterations (dWorldID, int num); 443 444 445 /** 446 * @brief Get the number of iterations that the QuickStep method performs per 447 * step. 448 * @ingroup world 449 * @return nr of iterations 450 */ 451 ODE_API int dWorldGetQuickStepNumIterations (dWorldID); 452 453 /** 454 * @brief Set the SOR over-relaxation parameter 455 * @ingroup world 456 * @param over_relaxation value to use by SOR 457 */ 458 ODE_API void dWorldSetQuickStepW (dWorldID, dReal over_relaxation); 459 460 /** 461 * @brief Get the SOR over-relaxation parameter 462 * @ingroup world 463 * @returns the over-relaxation setting 464 */ 465 ODE_API dReal dWorldGetQuickStepW (dWorldID); 466 467 /* World contact parameter functions */ 468 469 /** 470 * @brief Set the maximum correcting velocity that contacts are allowed 471 * to generate. 472 * @ingroup world 473 * @param vel The default value is infinity (i.e. no limit). 474 * @remarks 475 * Reducing this value can help prevent "popping" of deeply embedded objects. 476 */ 477 ODE_API void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel); 478 479 /** 480 * @brief Get the maximum correcting velocity that contacts are allowed 481 * to generated. 482 * @ingroup world 483 */ 484 ODE_API dReal dWorldGetContactMaxCorrectingVel (dWorldID); 485 486 /** 487 * @brief Set the depth of the surface layer around all geometry objects. 488 * @ingroup world 489 * @remarks 490 * Contacts are allowed to sink into the surface layer up to the given 491 * depth before coming to rest. 492 * @param depth The default value is zero. 493 * @remarks 494 * Increasing this to some small value (e.g. 0.001) can help prevent 495 * jittering problems due to contacts being repeatedly made and broken. 496 */ 497 ODE_API void dWorldSetContactSurfaceLayer (dWorldID, dReal depth); 498 499 /** 500 * @brief Get the depth of the surface layer around all geometry objects. 501 * @ingroup world 502 * @returns the depth 503 */ 504 ODE_API dReal dWorldGetContactSurfaceLayer (dWorldID); 505 506 507 /** 508 * @defgroup disable Automatic Enabling and Disabling 509 * @ingroup world bodies 510 * 511 * Every body can be enabled or disabled. Enabled bodies participate in the 512 * simulation, while disabled bodies are turned off and do not get updated 513 * during a simulation step. New bodies are always created in the enabled state. 514 * 515 * A disabled body that is connected through a joint to an enabled body will be 516 * automatically re-enabled at the next simulation step. 517 * 518 * Disabled bodies do not consume CPU time, therefore to speed up the simulation 519 * bodies should be disabled when they come to rest. This can be done automatically 520 * with the auto-disable feature. 521 * 522 * If a body has its auto-disable flag turned on, it will automatically disable 523 * itself when 524 * @li It has been idle for a given number of simulation steps. 525 * @li It has also been idle for a given amount of simulation time. 526 * 527 * A body is considered to be idle when the magnitudes of both its 528 * linear average velocity and angular average velocity are below given thresholds. 529 * The sample size for the average defaults to one and can be disabled by setting 530 * to zero with 531 * 532 * Thus, every body has six auto-disable parameters: an enabled flag, a idle step 533 * count, an idle time, linear/angular average velocity thresholds, and the 534 * average samples count. 535 * 536 * Newly created bodies get these parameters from world. 537 */ 538 539 /** 540 * @brief Get auto disable linear threshold for newly created bodies. 541 * @ingroup disable 542 * @return the threshold 543 */ 544 ODE_API dReal dWorldGetAutoDisableLinearThreshold (dWorldID); 545 546 /** 547 * @brief Set auto disable linear threshold for newly created bodies. 548 * @param linear_threshold default is 0.01 549 * @ingroup disable 550 */ 551 ODE_API void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold); 552 553 /** 554 * @brief Get auto disable angular threshold for newly created bodies. 555 * @ingroup disable 556 * @return the threshold 557 */ 558 ODE_API dReal dWorldGetAutoDisableAngularThreshold (dWorldID); 559 560 /** 561 * @brief Set auto disable angular threshold for newly created bodies. 562 * @param linear_threshold default is 0.01 563 * @ingroup disable 564 */ 565 ODE_API void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold); 566 567 /** 568 * @brief Get auto disable linear average threshold for newly created bodies. 569 * @ingroup disable 570 * @return the threshold 571 */ 572 ODE_API dReal dWorldGetAutoDisableLinearAverageThreshold (dWorldID); 573 574 /** 575 * @brief Set auto disable linear average threshold for newly created bodies. 576 * @param linear_average_threshold default is 0.01 577 * @ingroup disable 578 */ 579 ODE_API void dWorldSetAutoDisableLinearAverageThreshold (dWorldID, dReal linear_average_threshold); 580 581 /** 582 * @brief Get auto disable angular average threshold for newly created bodies. 583 * @ingroup disable 584 * @return the threshold 585 */ 586 ODE_API dReal dWorldGetAutoDisableAngularAverageThreshold (dWorldID); 587 588 /** 589 * @brief Set auto disable angular average threshold for newly created bodies. 590 * @param linear_average_threshold default is 0.01 591 * @ingroup disable 592 */ 593 ODE_API void dWorldSetAutoDisableAngularAverageThreshold (dWorldID, dReal angular_average_threshold); 594 595 /** 596 * @brief Get auto disable sample count for newly created bodies. 597 * @ingroup disable 598 * @return number of samples used 599 */ 600 ODE_API int dWorldGetAutoDisableAverageSamplesCount (dWorldID); 601 602 /** 603 * @brief Set auto disable average sample count for newly created bodies. 604 * @ingroup disable 605 * @param average_samples_count Default is 1, meaning only instantaneous velocity is used. 606 * Set to zero to disable sampling and thus prevent any body from auto-disabling. 607 */ 608 ODE_API void dWorldSetAutoDisableAverageSamplesCount (dWorldID, unsigned int average_samples_count ); 609 610 /** 611 * @brief Get auto disable steps for newly created bodies. 612 * @ingroup disable 613 * @return nr of steps 614 */ 615 ODE_API int dWorldGetAutoDisableSteps (dWorldID); 616 617 /** 618 * @brief Set auto disable steps for newly created bodies. 619 * @ingroup disable 620 * @param steps default is 10 621 */ 622 ODE_API void dWorldSetAutoDisableSteps (dWorldID, int steps); 623 624 /** 625 * @brief Get auto disable time for newly created bodies. 626 * @ingroup disable 627 * @return nr of seconds 628 */ 629 ODE_API dReal dWorldGetAutoDisableTime (dWorldID); 630 631 /** 632 * @brief Set auto disable time for newly created bodies. 633 * @ingroup disable 634 * @param time default is 0 seconds 635 */ 636 ODE_API void dWorldSetAutoDisableTime (dWorldID, dReal time); 637 638 /** 639 * @brief Get auto disable flag for newly created bodies. 640 * @ingroup disable 641 * @return 0 or 1 642 */ 643 ODE_API int dWorldGetAutoDisableFlag (dWorldID); 644 645 /** 646 * @brief Set auto disable flag for newly created bodies. 647 * @ingroup disable 648 * @param do_auto_disable default is false. 649 */ 650 ODE_API void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable); 651 652 653 /** 654 * @defgroup damping Damping 655 * @ingroup bodies world 656 * 657 * Damping serves two purposes: reduce simulation instability, and to allow 658 * the bodies to come to rest (and possibly auto-disabling them). 659 * 660 * Bodies are constructed using the world's current damping parameters. Setting 661 * the scales to 0 disables the damping. 662 * 663 * Here is how it is done: after every time step linear and angular 664 * velocities are tested against the corresponding thresholds. If they 665 * are above, they are multiplied by (1 - scale). So a negative scale value 666 * will actually increase the speed, and values greater than one will 667 * make the object oscillate every step; both can make the simulation unstable. 668 * 669 * To disable damping just set the damping scale to zero. 670 * 671 * You can also limit the maximum angular velocity. In contrast to the damping 672 * functions, the angular velocity is affected before the body is moved. 673 * This means that it will introduce errors in joints that are forcing the body 674 * to rotate too fast. Some bodies have naturally high angular velocities 675 * (like cars' wheels), so you may want to give them a very high (like the default, 676 * dInfinity) limit. 677 * 678 * @note The velocities are damped after the stepper function has moved the 679 * object. Otherwise the damping could introduce errors in joints. First the 680 * joint constraints are processed by the stepper (moving the body), then 681 * the damping is applied. 682 * 683 * @note The damping happens right after the moved callback is called; this way 684 * it still possible use the exact velocities the body has acquired during the 685 * step. You can even use the callback to create your own customized damping. 686 */ 687 688 /** 689 * @brief Get the world's linear damping threshold. 690 * @ingroup damping 691 */ 692 ODE_API dReal dWorldGetLinearDampingThreshold (dWorldID w); 693 694 /** 695 * @brief Set the world's linear damping threshold. 696 * @param threshold The damping won't be applied if the linear speed is 697 * below this threshold. Default is 0.01. 698 * @ingroup damping 699 */ 700 ODE_API void dWorldSetLinearDampingThreshold(dWorldID w, dReal threshold); 701 702 /** 703 * @brief Get the world's angular damping threshold. 704 * @ingroup damping 705 */ 706 ODE_API dReal dWorldGetAngularDampingThreshold (dWorldID w); 707 708 /** 709 * @brief Set the world's angular damping threshold. 710 * @param threshold The damping won't be applied if the angular speed is 711 * below this threshold. Default is 0.01. 712 * @ingroup damping 713 */ 714 ODE_API void dWorldSetAngularDampingThreshold(dWorldID w, dReal threshold); 715 716 /** 717 * @brief Get the world's linear damping scale. 718 * @ingroup damping 719 */ 720 ODE_API dReal dWorldGetLinearDamping (dWorldID w); 721 722 /** 723 * @brief Set the world's linear damping scale. 724 * @param scale The linear damping scale that is to be applied to bodies. 725 * Default is 0 (no damping). Should be in the interval [0, 1]. 726 * @ingroup damping 727 */ 728 ODE_API void dWorldSetLinearDamping (dWorldID w, dReal scale); 729 730 /** 731 * @brief Get the world's angular damping scale. 732 * @ingroup damping 733 */ 734 ODE_API dReal dWorldGetAngularDamping (dWorldID w); 735 736 /** 737 * @brief Set the world's angular damping scale. 738 * @param scale The angular damping scale that is to be applied to bodies. 739 * Default is 0 (no damping). Should be in the interval [0, 1]. 740 * @ingroup damping 741 */ 742 ODE_API void dWorldSetAngularDamping(dWorldID w, dReal scale); 743 744 /** 745 * @brief Convenience function to set body linear and angular scales. 746 * @param linear_scale The linear damping scale that is to be applied to bodies. 747 * @param angular_scale The angular damping scale that is to be applied to bodies. 748 * @ingroup damping 749 */ 750 ODE_API void dWorldSetDamping(dWorldID w, 751 dReal linear_scale, 752 dReal angular_scale); 753 754 /** 755 * @brief Get the default maximum angular speed. 756 * @ingroup damping 757 * @sa dBodyGetMaxAngularSpeed() 758 */ 759 ODE_API dReal dWorldGetMaxAngularSpeed (dWorldID w); 760 761 762 /** 763 * @brief Set the default maximum angular speed for new bodies. 764 * @ingroup damping 765 * @sa dBodySetMaxAngularSpeed() 766 */ 767 ODE_API void dWorldSetMaxAngularSpeed (dWorldID w, dReal max_speed); 768 769 770 771 /** 772 * @defgroup bodies Rigid Bodies 773 * 774 * A rigid body has various properties from the point of view of the 775 * simulation. Some properties change over time: 776 * 777 * @li Position vector (x,y,z) of the body's point of reference. 778 * Currently the point of reference must correspond to the body's center of mass. 779 * @li Linear velocity of the point of reference, a vector (vx,vy,vz). 780 * @li Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or 781 * a 3x3 rotation matrix. 782 * @li Angular velocity vector (wx,wy,wz) which describes how the orientation 783 * changes over time. 784 * 785 * Other body properties are usually constant over time: 786 * 787 * @li Mass of the body. 788 * @li Position of the center of mass with respect to the point of reference. 789 * In the current implementation the center of mass and the point of 790 * reference must coincide. 791 * @li Inertia matrix. This is a 3x3 matrix that describes how the body's mass 792 * is distributed around the center of mass. Conceptually each body has an 793 * x-y-z coordinate frame embedded in it that moves and rotates with the body. 794 * 795 * The origin of this coordinate frame is the body's point of reference. Some values 796 * in ODE (vectors, matrices etc) are relative to the body coordinate frame, and others 797 * are relative to the global coordinate frame. 798 * 799 * Note that the shape of a rigid body is not a dynamical property (except insofar as 800 * it influences the various mass properties). It is only collision detection that cares 801 * about the detailed shape of the body. 802 */ 803 804 805 /** 806 * @brief Get auto disable linear average threshold. 807 * @ingroup bodies disable 808 * @return the threshold 809 */ 810 ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID); 811 812 /** 813 * @brief Set auto disable linear average threshold. 814 * @ingroup bodies disable 815 * @return the threshold 816 */ 817 ODE_API void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_average_threshold); 818 819 /** 820 * @brief Get auto disable angular average threshold. 821 * @ingroup bodies disable 822 * @return the threshold 823 */ 824 ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID); 825 826 /** 827 * @brief Set auto disable angular average threshold. 828 * @ingroup bodies disable 829 * @return the threshold 830 */ 831 ODE_API void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_average_threshold); 832 833 /** 834 * @brief Get auto disable average size (samples count). 835 * @ingroup bodies disable 836 * @return the nr of steps/size. 837 */ 838 ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID); 839 840 /** 841 * @brief Set auto disable average buffer size (average steps). 842 * @ingroup bodies disable 843 * @param average_samples_count the nr of samples to review. 844 */ 845 ODE_API void dBodySetAutoDisableAverageSamplesCount (dBodyID, unsigned int average_samples_count); 846 847 848 /** 849 * @brief Get auto steps a body must be thought of as idle to disable 850 * @ingroup bodies disable 851 * @return the nr of steps 852 */ 853 ODE_API int dBodyGetAutoDisableSteps (dBodyID); 854 855 /** 856 * @brief Set auto disable steps. 857 * @ingroup bodies disable 858 * @param steps the nr of steps. 859 */ 860 ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps); 861 862 /** 863 * @brief Get auto disable time. 864 * @ingroup bodies disable 865 * @return nr of seconds 866 */ 867 ODE_API dReal dBodyGetAutoDisableTime (dBodyID); 868 869 /** 870 * @brief Set auto disable time. 871 * @ingroup bodies disable 872 * @param time nr of seconds. 873 */ 874 ODE_API void dBodySetAutoDisableTime (dBodyID, dReal time); 875 876 /** 877 * @brief Get auto disable flag. 878 * @ingroup bodies disable 879 * @return 0 or 1 880 */ 881 ODE_API int dBodyGetAutoDisableFlag (dBodyID); 882 883 /** 884 * @brief Set auto disable flag. 885 * @ingroup bodies disable 886 * @param do_auto_disable 0 or 1 887 */ 888 ODE_API void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable); 889 890 /** 891 * @brief Set auto disable defaults. 892 * @remarks 893 * Set the values for the body to those set as default for the world. 894 * @ingroup bodies disable 895 */ 896 ODE_API void dBodySetAutoDisableDefaults (dBodyID); 897 898 899 /** 900 * @brief Retrieves the world attached to te given body. 901 * @remarks 902 * 903 * @ingroup bodies 904 */ 905 ODE_API dWorldID dBodyGetWorld (dBodyID); 906 907 /** 908 * @brief Create a body in given world. 909 * @remarks 910 * Default mass parameters are at position (0,0,0). 911 * @ingroup bodies 912 */ 913 ODE_API dBodyID dBodyCreate (dWorldID); 914 915 /** 916 * @brief Destroy a body. 917 * @remarks 918 * All joints that are attached to this body will be put into limbo: 919 * i.e. unattached and not affecting the simulation, but they will NOT be 920 * deleted. 921 * @ingroup bodies 922 */ 923 ODE_API void dBodyDestroy (dBodyID); 924 925 /** 926 * @brief Set the body's user-data pointer. 927 * @ingroup bodies 928 * @param data arbitraty pointer 929 */ 930 ODE_API void dBodySetData (dBodyID, void *data); 931 932 /** 933 * @brief Get the body's user-data pointer. 934 * @ingroup bodies 935 * @return a pointer to the user's data. 936 */ 937 ODE_API void *dBodyGetData (dBodyID); 938 939 /** 940 * @brief Set position of a body. 941 * @remarks 942 * After setting, the outcome of the simulation is undefined 943 * if the new configuration is inconsistent with the joints/constraints 944 * that are present. 945 * @ingroup bodies 946 */ 947 ODE_API void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z); 948 949 /** 950 * @brief Set the orientation of a body. 951 * @ingroup bodies 952 * @remarks 953 * After setting, the outcome of the simulation is undefined 954 * if the new configuration is inconsistent with the joints/constraints 955 * that are present. 956 */ 957 ODE_API void dBodySetRotation (dBodyID, const dMatrix3 R); 958 959 /** 960 * @brief Set the orientation of a body. 961 * @ingroup bodies 962 * @remarks 963 * After setting, the outcome of the simulation is undefined 964 * if the new configuration is inconsistent with the joints/constraints 965 * that are present. 966 */ 967 ODE_API void dBodySetQuaternion (dBodyID, const dQuaternion q); 968 969 /** 970 * @brief Set the linear velocity of a body. 971 * @ingroup bodies 972 */ 973 ODE_API void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z); 974 975 /** 976 * @brief Set the angular velocity of a body. 977 * @ingroup bodies 978 */ 979 ODE_API void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z); 980 981 /** 982 * @brief Get the position of a body. 983 * @ingroup bodies 984 * @remarks 985 * When getting, the returned values are pointers to internal data structures, 986 * so the vectors are valid until any changes are made to the rigid body 987 * system structure. 988 * @sa dBodyCopyPosition 989 */ 990 ODE_API const dReal * dBodyGetPosition (dBodyID); 991 992 993 /** 994 * @brief Copy the position of a body into a vector. 995 * @ingroup bodies 996 * @param body the body to query 997 * @param pos a copy of the body position 998 * @sa dBodyGetPosition 999 */ 1000 ODE_API void dBodyCopyPosition (dBodyID body, dVector3 pos); 1001 1002 1003 /** 1004 * @brief Get the rotation of a body. 1005 * @ingroup bodies 1006 * @return pointer to a 4x3 rotation matrix. 1007 */ 1008 ODE_API const dReal * dBodyGetRotation (dBodyID); 1009 1010 1011 /** 1012 * @brief Copy the rotation of a body. 1013 * @ingroup bodies 1014 * @param body the body to query 1015 * @param R a copy of the rotation matrix 1016 * @sa dBodyGetRotation 1017 */ 1018 ODE_API void dBodyCopyRotation (dBodyID, dMatrix3 R); 1019 1020 1021 /** 1022 * @brief Get the rotation of a body. 1023 * @ingroup bodies 1024 * @return pointer to 4 scalars that represent the quaternion. 1025 */ 1026 ODE_API const dReal * dBodyGetQuaternion (dBodyID); 1027 1028 1029 /** 1030 * @brief Copy the orientation of a body into a quaternion. 1031 * @ingroup bodies 1032 * @param body the body to query 1033 * @param quat a copy of the orientation quaternion 1034 * @sa dBodyGetQuaternion 1035 */ 1036 ODE_API void dBodyCopyQuaternion(dBodyID body, dQuaternion quat); 1037 1038 1039 /** 1040 * @brief Get the linear velocity of a body. 1041 * @ingroup bodies 1042 */ 1043 ODE_API const dReal * dBodyGetLinearVel (dBodyID); 1044 1045 /** 1046 * @brief Get the angular velocity of a body. 1047 * @ingroup bodies 1048 */ 1049 ODE_API const dReal * dBodyGetAngularVel (dBodyID); 1050 1051 /** 1052 * @brief Set the mass of a body. 1053 * @ingroup bodies 1054 */ 1055 ODE_API void dBodySetMass (dBodyID, const dMass *mass); 1056 1057 /** 1058 * @brief Get the mass of a body. 1059 * @ingroup bodies 1060 */ 1061 ODE_API void dBodyGetMass (dBodyID, dMass *mass); 1062 1063 /** 1064 * @brief Add force at centre of mass of body in absolute coordinates. 1065 * @ingroup bodies 1066 */ 1067 ODE_API void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); 1068 1069 /** 1070 * @brief Add torque at centre of mass of body in absolute coordinates. 1071 * @ingroup bodies 1072 */ 1073 ODE_API void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); 1074 1075 /** 1076 * @brief Add force at centre of mass of body in coordinates relative to body. 1077 * @ingroup bodies 1078 */ 1079 ODE_API void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz); 1080 1081 /** 1082 * @brief Add torque at centre of mass of body in coordinates relative to body. 1083 * @ingroup bodies 1084 */ 1085 ODE_API void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz); 1086 1087 /** 1088 * @brief Add force at specified point in body in global coordinates. 1089 * @ingroup bodies 1090 */ 1091 ODE_API void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, 1092 dReal px, dReal py, dReal pz); 1093 /** 1094 * @brief Add force at specified point in body in local coordinates. 1095 * @ingroup bodies 1096 */ 1097 ODE_API void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, 1098 dReal px, dReal py, dReal pz); 1099 /** 1100 * @brief Add force at specified point in body in global coordinates. 1101 * @ingroup bodies 1102 */ 1103 ODE_API void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, 1104 dReal px, dReal py, dReal pz); 1105 /** 1106 * @brief Add force at specified point in body in local coordinates. 1107 * @ingroup bodies 1108 */ 1109 ODE_API void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, 1110 dReal px, dReal py, dReal pz); 1111 1112 /** 1113 * @brief Return the current accumulated force vector. 1114 * @return points to an array of 3 reals. 1115 * @remarks 1116 * The returned values are pointers to internal data structures, so 1117 * the vectors are only valid until any changes are made to the rigid 1118 * body system. 1119 * @ingroup bodies 1120 */ 1121 ODE_API const dReal * dBodyGetForce (dBodyID); 1122 1123 /** 1124 * @brief Return the current accumulated torque vector. 1125 * @return points to an array of 3 reals. 1126 * @remarks 1127 * The returned values are pointers to internal data structures, so 1128 * the vectors are only valid until any changes are made to the rigid 1129 * body system. 1130 * @ingroup bodies 1131 */ 1132 ODE_API const dReal * dBodyGetTorque (dBodyID); 1133 1134 /** 1135 * @brief Set the body force accumulation vector. 1136 * @remarks 1137 * This is mostly useful to zero the force and torque for deactivated bodies 1138 * before they are reactivated, in the case where the force-adding functions 1139 * were called on them while they were deactivated. 1140 * @ingroup bodies 1141 */ 1142 ODE_API void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z); 1143 1144 /** 1145 * @brief Set the body torque accumulation vector. 1146 * @remarks 1147 * This is mostly useful to zero the force and torque for deactivated bodies 1148 * before they are reactivated, in the case where the force-adding functions 1149 * were called on them while they were deactivated. 1150 * @ingroup bodies 1151 */ 1152 ODE_API void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z); 1153 1154 /** 1155 * @brief Get world position of a relative point on body. 1156 * @ingroup bodies 1157 * @param result will contain the result. 1158 */ 1159 ODE_API void dBodyGetRelPointPos 1160 ( 1161 dBodyID, dReal px, dReal py, dReal pz, 1162 dVector3 result 1163 ); 1164 1165 /** 1166 * @brief Get velocity vector in global coords of a relative point on body. 1167 * @ingroup bodies 1168 * @param result will contain the result. 1169 */ 1170 ODE_API void dBodyGetRelPointVel 1171 ( 1172 dBodyID, dReal px, dReal py, dReal pz, 1173 dVector3 result 1174 ); 1175 1176 /** 1177 * @brief Get velocity vector in global coords of a globally 1178 * specified point on a body. 1179 * @ingroup bodies 1180 * @param result will contain the result. 1181 */ 1182 ODE_API void dBodyGetPointVel 1183 ( 1184 dBodyID, dReal px, dReal py, dReal pz, 1185 dVector3 result 1186 ); 1187 1188 /** 1189 * @brief takes a point in global coordinates and returns 1190 * the point's position in body-relative coordinates. 1191 * @remarks 1192 * This is the inverse of dBodyGetRelPointPos() 1193 * @ingroup bodies 1194 * @param result will contain the result. 1195 */ 1196 ODE_API void dBodyGetPosRelPoint 1197 ( 1198 dBodyID, dReal px, dReal py, dReal pz, 1199 dVector3 result 1200 ); 1201 1202 /** 1203 * @brief Convert from local to world coordinates. 1204 * @ingroup bodies 1205 * @param result will contain the result. 1206 */ 1207 ODE_API void dBodyVectorToWorld 1208 ( 1209 dBodyID, dReal px, dReal py, dReal pz, 1210 dVector3 result 1211 ); 1212 1213 /** 1214 * @brief Convert from world to local coordinates. 1215 * @ingroup bodies 1216 * @param result will contain the result. 1217 */ 1218 ODE_API void dBodyVectorFromWorld 1219 ( 1220 dBodyID, dReal px, dReal py, dReal pz, 1221 dVector3 result 1222 ); 1223 1224 /** 1225 * @brief controls the way a body's orientation is updated at each timestep. 1226 * @ingroup bodies 1227 * @param mode can be 0 or 1: 1228 * \li 0: An ``infinitesimal'' orientation update is used. 1229 * This is fast to compute, but it can occasionally cause inaccuracies 1230 * for bodies that are rotating at high speed, especially when those 1231 * bodies are joined to other bodies. 1232 * This is the default for every new body that is created. 1233 * \li 1: A ``finite'' orientation update is used. 1234 * This is more costly to compute, but will be more accurate for high 1235 * speed rotations. 1236 * @remarks 1237 * Note however that high speed rotations can result in many types of 1238 * error in a simulation, and the finite mode will only fix one of those 1239 * sources of error. 1240 */ 1241 ODE_API void dBodySetFiniteRotationMode (dBodyID, int mode); 1242 1243 /** 1244 * @brief sets the finite rotation axis for a body. 1245 * @ingroup bodies 1246 * @remarks 1247 * This is axis only has meaning when the finite rotation mode is set 1248 * If this axis is zero (0,0,0), full finite rotations are performed on 1249 * the body. 1250 * If this axis is nonzero, the body is rotated by performing a partial finite 1251 * rotation along the axis direction followed by an infinitesimal rotation 1252 * along an orthogonal direction. 1253 * @remarks 1254 * This can be useful to alleviate certain sources of error caused by quickly 1255 * spinning bodies. For example, if a car wheel is rotating at high speed 1256 * you can call this function with the wheel's hinge axis as the argument to 1257 * try and improve its behavior. 1258 */ 1259 ODE_API void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z); 1260 1261 /** 1262 * @brief Get the way a body's orientation is updated each timestep. 1263 * @ingroup bodies 1264 * @return the mode 0 (infitesimal) or 1 (finite). 1265 */ 1266 ODE_API int dBodyGetFiniteRotationMode (dBodyID); 1267 1268 /** 1269 * @brief Get the finite rotation axis. 1270 * @param result will contain the axis. 1271 * @ingroup bodies 1272 */ 1273 ODE_API void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result); 1274 1275 /** 1276 * @brief Get the number of joints that are attached to this body. 1277 * @ingroup bodies 1278 * @return nr of joints 1279 */ 1280 ODE_API int dBodyGetNumJoints (dBodyID b); 1281 1282 /** 1283 * @brief Return a joint attached to this body, given by index. 1284 * @ingroup bodies 1285 * @param index valid range is 0 to n-1 where n is the value returned by 1286 * dBodyGetNumJoints(). 1287 */ 1288 ODE_API dJointID dBodyGetJoint (dBodyID, int index); 1289 1290 1291 1292 1293 /** 1294 * @brief Set rigid body to dynamic state (default). 1295 * @param dBodyID identification of body. 1296 * @ingroup bodies 1297 */ 1298 ODE_API void dBodySetDynamic (dBodyID); 1299 1300 /** 1301 * @brief Set rigid body to kinematic state. 1302 * When in kinematic state the body isn't simulated as a dynamic 1303 * body (it's "unstoppable", doesn't respond to forces), 1304 * but can still affect dynamic bodies (e.g. in joints). 1305 * Kinematic bodies can be controlled by position and velocity. 1306 * @note A kinematic body has infinite mass. If you set its mass 1307 * to something else, it loses the kinematic state and behaves 1308 * as a normal dynamic body. 1309 * @param dBodyID identification of body. 1310 * @ingroup bodies 1311 */ 1312 ODE_API void dBodySetKinematic (dBodyID); 1313 1314 /** 1315 * @brief Check wether a body is in kinematic state. 1316 * @ingroup bodies 1317 * @return 1 if a body is kinematic or 0 if it is dynamic. 1318 */ 1319 ODE_API int dBodyIsKinematic (dBodyID); 1320 1321 /** 1322 * @brief Manually enable a body. 1323 * @param dBodyID identification of body. 1324 * @ingroup bodies 1325 */ 1326 ODE_API void dBodyEnable (dBodyID); 1327 1328 /** 1329 * @brief Manually disable a body. 1330 * @ingroup bodies 1331 * @remarks 1332 * A disabled body that is connected through a joint to an enabled body will 1333 * be automatically re-enabled at the next simulation step. 1334 */ 1335 ODE_API void dBodyDisable (dBodyID); 1336 1337 /** 1338 * @brief Check wether a body is enabled. 1339 * @ingroup bodies 1340 * @return 1 if a body is currently enabled or 0 if it is disabled. 1341 */ 1342 ODE_API int dBodyIsEnabled (dBodyID); 1343 1344 /** 1345 * @brief Set whether the body is influenced by the world's gravity or not. 1346 * @ingroup bodies 1347 * @param mode when nonzero gravity affects this body. 1348 * @remarks 1349 * Newly created bodies are always influenced by the world's gravity. 1350 */ 1351 ODE_API void dBodySetGravityMode (dBodyID b, int mode); 1352 1353 /** 1354 * @brief Get whether the body is influenced by the world's gravity or not. 1355 * @ingroup bodies 1356 * @return nonzero means gravity affects this body. 1357 */ 1358 ODE_API int dBodyGetGravityMode (dBodyID b); 1359 1360 /** 1361 * @brief Set the 'moved' callback of a body. 1362 * 1363 * Whenever a body has its position or rotation changed during the 1364 * timestep, the callback will be called (with body as the argument). 1365 * Use it to know which body may need an update in an external 1366 * structure (like a 3D engine). 1367 * 1368 * @param b the body that needs to be watched. 1369 * @param callback the callback to be invoked when the body moves. Set to zero 1370 * to disable. 1371 * @ingroup bodies 1372 */ 1373 ODE_API void dBodySetMovedCallback(dBodyID b, void (*callback)(dBodyID)); 1374 1375 1376 /** 1377 * @brief Return the first geom associated with the body. 1378 * 1379 * You can traverse through the geoms by repeatedly calling 1380 * dBodyGetNextGeom(). 1381 * 1382 * @return the first geom attached to this body, or 0. 1383 * @ingroup bodies 1384 */ 1385 ODE_API dGeomID dBodyGetFirstGeom (dBodyID b); 1386 1387 1388 /** 1389 * @brief returns the next geom associated with the same body. 1390 * @param g a geom attached to some body. 1391 * @return the next geom attached to the same body, or 0. 1392 * @sa dBodyGetFirstGeom 1393 * @ingroup bodies 1394 */ 1395 ODE_API dGeomID dBodyGetNextGeom (dGeomID g); 1396 1397 1398 /** 1399 * @brief Resets the damping settings to the current world's settings. 1400 * @ingroup bodies damping 1401 */ 1402 ODE_API void dBodySetDampingDefaults(dBodyID b); 1403 1404 /** 1405 * @brief Get the body's linear damping scale. 1406 * @ingroup bodies damping 1407 */ 1408 ODE_API dReal dBodyGetLinearDamping (dBodyID b); 1409 1410 /** 1411 * @brief Set the body's linear damping scale. 1412 * @param scale The linear damping scale. Should be in the interval [0, 1]. 1413 * @ingroup bodies damping 1414 * @remarks From now on the body will not use the world's linear damping 1415 * scale until dBodySetDampingDefaults() is called. 1416 * @sa dBodySetDampingDefaults() 1417 */ 1418 ODE_API void dBodySetLinearDamping(dBodyID b, dReal scale); 1419 1420 /** 1421 * @brief Get the body's angular damping scale. 1422 * @ingroup bodies damping 1423 * @remarks If the body's angular damping scale was not set, this function 1424 * returns the world's angular damping scale. 1425 */ 1426 ODE_API dReal dBodyGetAngularDamping (dBodyID b); 1427 1428 /** 1429 * @brief Set the body's angular damping scale. 1430 * @param scale The angular damping scale. Should be in the interval [0, 1]. 1431 * @ingroup bodies damping 1432 * @remarks From now on the body will not use the world's angular damping 1433 * scale until dBodyResetAngularDamping() is called. 1434 * @sa dBodyResetAngularDamping() 1435 */ 1436 ODE_API void dBodySetAngularDamping(dBodyID b, dReal scale); 1437 1438 /** 1439 * @brief Convenience function to set linear and angular scales at once. 1440 * @param linear_scale The linear damping scale. Should be in the interval [0, 1]. 1441 * @param angular_scale The angular damping scale. Should be in the interval [0, 1]. 1442 * @ingroup bodies damping 1443 * @sa dBodySetLinearDamping() dBodySetAngularDamping() 1444 */ 1445 ODE_API void dBodySetDamping(dBodyID b, dReal linear_scale, dReal angular_scale); 1446 1447 /** 1448 * @brief Get the body's linear damping threshold. 1449 * @ingroup bodies damping 1450 */ 1451 ODE_API dReal dBodyGetLinearDampingThreshold (dBodyID b); 1452 1453 /** 1454 * @brief Set the body's linear damping threshold. 1455 * @param threshold The linear threshold to be used. Damping 1456 * is only applied if the linear speed is above this limit. 1457 * @ingroup bodies damping 1458 */ 1459 ODE_API void dBodySetLinearDampingThreshold(dBodyID b, dReal threshold); 1460 1461 /** 1462 * @brief Get the body's angular damping threshold. 1463 * @ingroup bodies damping 1464 */ 1465 ODE_API dReal dBodyGetAngularDampingThreshold (dBodyID b); 1466 1467 /** 1468 * @brief Set the body's angular damping threshold. 1469 * @param threshold The angular threshold to be used. Damping is 1470 * only used if the angular speed is above this limit. 1471 * @ingroup bodies damping 1472 */ 1473 ODE_API void dBodySetAngularDampingThreshold(dBodyID b, dReal threshold); 1474 1475 /** 1476 * @brief Get the body's maximum angular speed. 1477 * @ingroup damping bodies 1478 * @sa dWorldGetMaxAngularSpeed() 1479 */ 1480 ODE_API dReal dBodyGetMaxAngularSpeed (dBodyID b); 1481 1482 /** 1483 * @brief Set the body's maximum angular speed. 1484 * @ingroup damping bodies 1485 * @sa dWorldSetMaxAngularSpeed() dBodyResetMaxAngularSpeed() 1486 * The default value is dInfinity, but it's a good idea to limit 1487 * it at less than 500 if the body has the gyroscopic term 1488 * enabled. 1489 */ 1490 ODE_API void dBodySetMaxAngularSpeed(dBodyID b, dReal max_speed); 1491 1492 1493 1494 /** 1495 * @brief Get the body's gyroscopic state. 1496 * 1497 * @return nonzero if gyroscopic term computation is enabled (default), 1498 * zero otherwise. 1499 * @ingroup bodies 1500 */ 1501 ODE_API int dBodyGetGyroscopicMode(dBodyID b); 1502 1503 1504 /** 1505 * @brief Enable/disable the body's gyroscopic term. 1506 * 1507 * Disabling the gyroscopic term of a body usually improves 1508 * stability. It also helps turning spining objects, like cars' 1509 * wheels. 1510 * 1511 * @param enabled nonzero (default) to enable gyroscopic term, 0 1512 * to disable. 1513 * @ingroup bodies 1514 */ 1515 ODE_API void dBodySetGyroscopicMode(dBodyID b, int enabled); 1516 1517 1518 1519 1520 /** 1521 * @defgroup joints Joints 1522 * 1523 * In real life a joint is something like a hinge, that is used to connect two 1524 * objects. 1525 * In ODE a joint is very similar: It is a relationship that is enforced between 1526 * two bodies so that they can only have certain positions and orientations 1527 * relative to each other. 1528 * This relationship is called a constraint -- the words joint and 1529 * constraint are often used interchangeably. 1530 * 1531 * A joint has a set of parameters that can be set. These include: 1532 * 1533 * 1534 * \li dParamLoStop Low stop angle or position. Setting this to 1535 * -dInfinity (the default value) turns off the low stop. 1536 * For rotational joints, this stop must be greater than -pi to be 1537 * effective. 1538 * \li dParamHiStop High stop angle or position. Setting this to 1539 * dInfinity (the default value) turns off the high stop. 1540 * For rotational joints, this stop must be less than pi to be 1541 * effective. 1542 * If the high stop is less than the low stop then both stops will 1543 * be ineffective. 1544 * \li dParamVel Desired motor velocity (this will be an angular or 1545 * linear velocity). 1546 * \li dParamFMax The maximum force or torque that the motor will use to 1547 * achieve the desired velocity. 1548 * This must always be greater than or equal to zero. 1549 * Setting this to zero (the default value) turns off the motor. 1550 * \li dParamFudgeFactor The current joint stop/motor implementation has 1551 * a small problem: 1552 * when the joint is at one stop and the motor is set to move it away 1553 * from the stop, too much force may be applied for one time step, 1554 * causing a ``jumping'' motion. 1555 * This fudge factor is used to scale this excess force. 1556 * It should have a value between zero and one (the default value). 1557 * If the jumping motion is too visible in a joint, the value can be 1558 * reduced. 1559 * Making this value too small can prevent the motor from being able to 1560 * move the joint away from a stop. 1561 * \li dParamBounce The bouncyness of the stops. 1562 * This is a restitution parameter in the range 0..1. 1563 * 0 means the stops are not bouncy at all, 1 means maximum bouncyness. 1564 * \li dParamCFM The constraint force mixing (CFM) value used when not 1565 * at a stop. 1566 * \li dParamStopERP The error reduction parameter (ERP) used by the 1567 * stops. 1568 * \li dParamStopCFM The constraint force mixing (CFM) value used by the 1569 * stops. Together with the ERP value this can be used to get spongy or 1570 * soft stops. 1571 * Note that this is intended for unpowered joints, it does not really 1572 * work as expected when a powered joint reaches its limit. 1573 * \li dParamSuspensionERP Suspension error reduction parameter (ERP). 1574 * Currently this is only implemented on the hinge-2 joint. 1575 * \li dParamSuspensionCFM Suspension constraint force mixing (CFM) value. 1576 * Currently this is only implemented on the hinge-2 joint. 1577 * 1578 * If a particular parameter is not implemented by a given joint, setting it 1579 * will have no effect. 1580 * These parameter names can be optionally followed by a digit (2 or 3) 1581 * to indicate the second or third set of parameters, e.g. for the second axis 1582 * in a hinge-2 joint, or the third axis in an AMotor joint. 1583 */ 1584 1585 1586 /** 1587 * @brief Create a new joint of the ball type. 1588 * @ingroup joints 1589 * @remarks 1590 * The joint is initially in "limbo" (i.e. it has no effect on the simulation) 1591 * because it does not connect to any bodies. 1592 * @param dJointGroupID set to 0 to allocate the joint normally. 1593 * If it is nonzero the joint is allocated in the given joint group. 1594 */ 1595 ODE_API dJointID dJointCreateBall (dWorldID, dJointGroupID); 1596 1597 /** 1598 * @brief Create a new joint of the hinge type. 1599 * @ingroup joints 1600 * @param dJointGroupID set to 0 to allocate the joint normally. 1601 * If it is nonzero the joint is allocated in the given joint group. 1602 */ 1603 ODE_API dJointID dJointCreateHinge (dWorldID, dJointGroupID); 1604 1605 /** 1606 * @brief Create a new joint of the slider type. 1607 * @ingroup joints 1608 * @param dJointGroupID set to 0 to allocate the joint normally. 1609 * If it is nonzero the joint is allocated in the given joint group. 1610 */ 1611 ODE_API dJointID dJointCreateSlider (dWorldID, dJointGroupID); 1612 1613 /** 1614 * @brief Create a new joint of the contact type. 1615 * @ingroup joints 1616 * @param dJointGroupID set to 0 to allocate the joint normally. 1617 * If it is nonzero the joint is allocated in the given joint group. 1618 */ 1619 ODE_API dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *); 1620 1621 /** 1622 * @brief Create a new joint of the hinge2 type. 1623 * @ingroup joints 1624 * @param dJointGroupID set to 0 to allocate the joint normally. 1625 * If it is nonzero the joint is allocated in the given joint group. 1626 */ 1627 ODE_API dJointID dJointCreateHinge2 (dWorldID, dJointGroupID); 1628 1629 /** 1630 * @brief Create a new joint of the universal type. 1631 * @ingroup joints 1632 * @param dJointGroupID set to 0 to allocate the joint normally. 1633 * If it is nonzero the joint is allocated in the given joint group. 1634 */ 1635 ODE_API dJointID dJointCreateUniversal (dWorldID, dJointGroupID); 1636 1637 /** 1638 * @brief Create a new joint of the PR (Prismatic and Rotoide) type. 1639 * @ingroup joints 1640 * @param dJointGroupID set to 0 to allocate the joint normally. 1641 * If it is nonzero the joint is allocated in the given joint group. 1642 */ 1643 ODE_API dJointID dJointCreatePR (dWorldID, dJointGroupID); 1644 1645 /** 1646 * @brief Create a new joint of the PU (Prismatic and Universal) type. 1647 * @ingroup joints 1648 * @param dJointGroupID set to 0 to allocate the joint normally. 1649 * If it is nonzero the joint is allocated in the given joint group. 1650 */ 1651 ODE_API dJointID dJointCreatePU (dWorldID, dJointGroupID); 1652 1653 /** 1654 * @brief Create a new joint of the Piston type. 1655 * @ingroup joints 1656 * @param dJointGroupID set to 0 to allocate the joint normally. 1657 * If it is nonzero the joint is allocated in the given 1658 * joint group. 1659 */ 1660 ODE_API dJointID dJointCreatePiston (dWorldID, dJointGroupID); 1661 1662 /** 1663 * @brief Create a new joint of the fixed type. 1664 * @ingroup joints 1665 * @param dJointGroupID set to 0 to allocate the joint normally. 1666 * If it is nonzero the joint is allocated in the given joint group. 1667 */ 1668 ODE_API dJointID dJointCreateFixed (dWorldID, dJointGroupID); 1669 1670 ODE_API dJointID dJointCreateNull (dWorldID, dJointGroupID); 1671 1672 /** 1673 * @brief Create a new joint of the A-motor type. 1674 * @ingroup joints 1675 * @param dJointGroupID set to 0 to allocate the joint normally. 1676 * If it is nonzero the joint is allocated in the given joint group. 1677 */ 1678 ODE_API dJointID dJointCreateAMotor (dWorldID, dJointGroupID); 1679 1680 /** 1681 * @brief Create a new joint of the L-motor type. 1682 * @ingroup joints 1683 * @param dJointGroupID set to 0 to allocate the joint normally. 1684 * If it is nonzero the joint is allocated in the given joint group. 1685 */ 1686 ODE_API dJointID dJointCreateLMotor (dWorldID, dJointGroupID); 1687 1688 /** 1689 * @brief Create a new joint of the plane-2d type. 1690 * @ingroup joints 1691 * @param dJointGroupID set to 0 to allocate the joint normally. 1692 * If it is nonzero the joint is allocated in the given joint group. 1693 */ 1694 ODE_API dJointID dJointCreatePlane2D (dWorldID, dJointGroupID); 1695 1696 /** 1697 * @brief Create a new joint of the double ball type. 1698 * @ingroup joints 1699 * @param dJointGroupID set to 0 to allocate the joint normally. 1700 * If it is nonzero the joint is allocated in the given joint group. 1701 */ 1702 ODE_API dJointID dJointCreateDBall (dWorldID, dJointGroupID); 1703 1704 /** 1705 * @brief Create a new joint of the double hinge type. 1706 * @ingroup joints 1707 * @param dJointGroupID set to 0 to allocate the joint normally. 1708 * If it is nonzero the joint is allocated in the given joint group. 1709 */ 1710 ODE_API dJointID dJointCreateDHinge (dWorldID, dJointGroupID); 1711 1712 /** 1713 * @brief Create a new joint of the Transmission type. 1714 * @ingroup joints 1715 * @param dJointGroupID set to 0 to allocate the joint normally. 1716 * If it is nonzero the joint is allocated in the given joint group. 1717 */ 1718 ODE_API dJointID dJointCreateTransmission (dWorldID, dJointGroupID); 1719 1720 1721 /** 1722 * @brief Destroy a joint. 1723 * @ingroup joints 1724 * 1725 * disconnects it from its attached bodies and removing it from the world. 1726 * However, if the joint is a member of a group then this function has no 1727 * effect - to destroy that joint the group must be emptied or destroyed. 1728 */ 1729 ODE_API void dJointDestroy (dJointID); 1730 1731 1732 /** 1733 * @brief Create a joint group 1734 * @ingroup joints 1735 * @param max_size deprecated. Set to 0. 1736 */ 1737 ODE_API dJointGroupID dJointGroupCreate (int max_size); 1738 1739 /** 1740 * @brief Destroy a joint group. 1741 * @ingroup joints 1742 * 1743 * All joints in the joint group will be destroyed. 1744 */ 1745 ODE_API void dJointGroupDestroy (dJointGroupID); 1746 1747 /** 1748 * @brief Empty a joint group. 1749 * @ingroup joints 1750 * 1751 * All joints in the joint group will be destroyed, 1752 * but the joint group itself will not be destroyed. 1753 */ 1754 ODE_API void dJointGroupEmpty (dJointGroupID); 1755 1756 /** 1757 * @brief Return the number of bodies attached to the joint 1758 * @ingroup joints 1759 */ 1760 ODE_API int dJointGetNumBodies(dJointID); 1761 1762 /** 1763 * @brief Attach the joint to some new bodies. 1764 * @ingroup joints 1765 * 1766 * If the joint is already attached, it will be detached from the old bodies 1767 * first. 1768 * To attach this joint to only one body, set body1 or body2 to zero - a zero 1769 * body refers to the static environment. 1770 * Setting both bodies to zero puts the joint into "limbo", i.e. it will 1771 * have no effect on the simulation. 1772 * @remarks 1773 * Some joints, like hinge-2 need to be attached to two bodies to work. 1774 */ 1775 ODE_API void dJointAttach (dJointID, dBodyID body1, dBodyID body2); 1776 1777 /** 1778 * @brief Manually enable a joint. 1779 * @param dJointID identification of joint. 1780 * @ingroup joints 1781 */ 1782 ODE_API void dJointEnable (dJointID); 1783 1784 /** 1785 * @brief Manually disable a joint. 1786 * @ingroup joints 1787 * @remarks 1788 * A disabled joint will not affect the simulation, but will maintain the anchors and 1789 * axes so it can be enabled later. 1790 */ 1791 ODE_API void dJointDisable (dJointID); 1792 1793 /** 1794 * @brief Check wether a joint is enabled. 1795 * @ingroup joints 1796 * @return 1 if a joint is currently enabled or 0 if it is disabled. 1797 */ 1798 ODE_API int dJointIsEnabled (dJointID); 1799 1800 /** 1801 * @brief Set the user-data pointer 1802 * @ingroup joints 1803 */ 1804 ODE_API void dJointSetData (dJointID, void *data); 1805 1806 /** 1807 * @brief Get the user-data pointer 1808 * @ingroup joints 1809 */ 1810 ODE_API void *dJointGetData (dJointID); 1811 1812 /** 1813 * @brief Get the type of the joint 1814 * @ingroup joints 1815 * @return the type, being one of these: 1816 * \li dJointTypeBall 1817 * \li dJointTypeHinge 1818 * \li dJointTypeSlider 1819 * \li dJointTypeContact 1820 * \li dJointTypeUniversal 1821 * \li dJointTypeHinge2 1822 * \li dJointTypeFixed 1823 * \li dJointTypeNull 1824 * \li dJointTypeAMotor 1825 * \li dJointTypeLMotor 1826 * \li dJointTypePlane2D 1827 * \li dJointTypePR 1828 * \li dJointTypePU 1829 * \li dJointTypePiston 1830 */ 1831 ODE_API dJointType dJointGetType (dJointID); 1832 1833 /** 1834 * @brief Return the bodies that this joint connects. 1835 * @ingroup joints 1836 * @param index return the first (0) or second (1) body. 1837 * @remarks 1838 * If one of these returned body IDs is zero, the joint connects the other body 1839 * to the static environment. 1840 * If both body IDs are zero, the joint is in ``limbo'' and has no effect on 1841 * the simulation. 1842 */ 1843 ODE_API dBodyID dJointGetBody (dJointID, int index); 1844 1845 /** 1846 * @brief Sets the datastructure that is to receive the feedback. 1847 * 1848 * The feedback can be used by the user, so that it is known how 1849 * much force an individual joint exerts. 1850 * @ingroup joints 1851 */ 1852 ODE_API void dJointSetFeedback (dJointID, dJointFeedback *); 1853 1854 /** 1855 * @brief Gets the datastructure that is to receive the feedback. 1856 * @ingroup joints 1857 */ 1858 ODE_API dJointFeedback *dJointGetFeedback (dJointID); 1859 1860 /** 1861 * @brief Set the joint anchor point. 1862 * @ingroup joints 1863 * 1864 * The joint will try to keep this point on each body 1865 * together. The input is specified in world coordinates. 1866 */ 1867 ODE_API void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z); 1868 1869 /** 1870 * @brief Set the joint anchor point. 1871 * @ingroup joints 1872 */ 1873 ODE_API void dJointSetBallAnchor2 (dJointID, dReal x, dReal y, dReal z); 1874 1875 /** 1876 * @brief Param setting for Ball joints 1877 * @ingroup joints 1878 */ 1879 ODE_API void dJointSetBallParam (dJointID, int parameter, dReal value); 1880 1881 /** 1882 * @brief Set hinge anchor parameter. 1883 * @ingroup joints 1884 */ 1885 ODE_API void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z); 1886 1887 ODE_API void dJointSetHingeAnchorDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); 1888 1889 /** 1890 * @brief Set hinge axis. 1891 * @ingroup joints 1892 */ 1893 ODE_API void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z); 1894 1895 /** 1896 * @brief Set the Hinge axis as if the 2 bodies were already at angle appart. 1897 * @ingroup joints 1898 * 1899 * This function initialize the Axis and the relative orientation of each body 1900 * as if body1 was rotated around the axis by the angle value. \br 1901 * Ex: 1902 * <PRE> 1903 * dJointSetHingeAxis(jId, 1, 0, 0); 1904 * // If you request the position you will have: dJointGetHingeAngle(jId) == 0 1905 * dJointSetHingeAxisDelta(jId, 1, 0, 0, 0.23); 1906 * // If you request the position you will have: dJointGetHingeAngle(jId) == 0.23 1907 * </PRE> 1908 1909 * @param j The Hinge joint ID for which the axis will be set 1910 * @param x The X component of the axis in world frame 1911 * @param y The Y component of the axis in world frame 1912 * @param z The Z component of the axis in world frame 1913 * @param angle The angle for the offset of the relative orientation. 1914 * As if body1 was rotated by angle when the Axis was set (see below). 1915 * The rotation is around the new Hinge axis. 1916 * 1917 * @note Usually the function dJointSetHingeAxis set the current position of body1 1918 * and body2 as the zero angle position. This function set the current position 1919 * as the if the 2 bodies where \b angle appart. 1920 * @warning Calling dJointSetHingeAnchor or dJointSetHingeAxis will reset the "zero" 1921 * angle position. 1922 */ 1923 ODE_API void dJointSetHingeAxisOffset (dJointID j, dReal x, dReal y, dReal z, dReal angle); 1924 1925 /** 1926 * @brief set joint parameter 1927 * @ingroup joints 1928 */ 1929 ODE_API void dJointSetHingeParam (dJointID, int parameter, dReal value); 1930 1931 /** 1932 * @brief Applies the torque about the hinge axis. 1933 * 1934 * That is, it applies a torque with specified magnitude in the direction 1935 * of the hinge axis, to body 1, and with the same magnitude but in opposite 1936 * direction to body 2. This function is just a wrapper for dBodyAddTorque()} 1937 * @ingroup joints 1938 */ 1939 ODE_API void dJointAddHingeTorque(dJointID joint, dReal torque); 1940 1941 /** 1942 * @brief set the joint axis 1943 * @ingroup joints 1944 */ 1945 ODE_API void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z); 1946 1947 /** 1948 * @ingroup joints 1949 */ 1950 ODE_API void dJointSetSliderAxisDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); 1951 1952 /** 1953 * @brief set joint parameter 1954 * @ingroup joints 1955 */ 1956 ODE_API void dJointSetSliderParam (dJointID, int parameter, dReal value); 1957 1958 /** 1959 * @brief Applies the given force in the slider's direction. 1960 * 1961 * That is, it applies a force with specified magnitude, in the direction of 1962 * slider's axis, to body1, and with the same magnitude but opposite 1963 * direction to body2. This function is just a wrapper for dBodyAddForce(). 1964 * @ingroup joints 1965 */ 1966 ODE_API void dJointAddSliderForce(dJointID joint, dReal force); 1967 1968 /** 1969 * @brief set anchor 1970 * @ingroup joints 1971 */ 1972 ODE_API void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z); 1973 1974 /** 1975 * @brief set axis 1976 * @ingroup joints 1977 */ 1978 ODE_API void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z); 1979 1980 /** 1981 * @brief set axis 1982 * @ingroup joints 1983 */ 1984 ODE_API void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z); 1985 1986 /** 1987 * @brief set joint parameter 1988 * @ingroup joints 1989 */ 1990 ODE_API void dJointSetHinge2Param (dJointID, int parameter, dReal value); 1991 1992 /** 1993 * @brief Applies torque1 about the hinge2's axis 1, torque2 about the 1994 * hinge2's axis 2. 1995 * @remarks This function is just a wrapper for dBodyAddTorque(). 1996 * @ingroup joints 1997 */ 1998 ODE_API void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2); 1999 2000 /** 2001 * @brief set anchor 2002 * @ingroup joints 2003 */ 2004 ODE_API void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z); 2005 2006 /** 2007 * @brief set axis 2008 * @ingroup joints 2009 */ 2010 ODE_API void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z); 2011 2012 /** 2013 * @brief Set the Universal axis1 as if the 2 bodies were already at 2014 * offset1 and offset2 appart with respect to axis1 and axis2. 2015 * @ingroup joints 2016 * 2017 * This function initialize the axis1 and the relative orientation of 2018 * each body as if body1 was rotated around the new axis1 by the offset1 2019 * value and as if body2 was rotated around the axis2 by offset2. \br 2020 * Ex: 2021 * <PRE> 2022 * dJointSetHuniversalAxis1(jId, 1, 0, 0); 2023 * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0 2024 * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0 2025 * dJointSetHuniversalAxis1Offset(jId, 1, 0, 0, 0.2, 0.17); 2026 * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2 2027 * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17 2028 * </PRE> 2029 * 2030 * @param j The Hinge joint ID for which the axis will be set 2031 * @param x The X component of the axis in world frame 2032 * @param y The Y component of the axis in world frame 2033 * @param z The Z component of the axis in world frame 2034 * @param angle The angle for the offset of the relative orientation. 2035 * As if body1 was rotated by angle when the Axis was set (see below). 2036 * The rotation is around the new Hinge axis. 2037 * 2038 * @note Usually the function dJointSetHingeAxis set the current position of body1 2039 * and body2 as the zero angle position. This function set the current position 2040 * as the if the 2 bodies where \b offsets appart. 2041 * 2042 * @note Any previous offsets are erased. 2043 * 2044 * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, 2045 * dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset 2046 * will reset the "zero" angle position. 2047 */ 2048 ODE_API void dJointSetUniversalAxis1Offset (dJointID, dReal x, dReal y, dReal z, 2049 dReal offset1, dReal offset2); 2050 2051 /** 2052 * @brief set axis 2053 * @ingroup joints 2054 */ 2055 ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z); 2056 2057 /** 2058 * @brief Set the Universal axis2 as if the 2 bodies were already at 2059 * offset1 and offset2 appart with respect to axis1 and axis2. 2060 * @ingroup joints 2061 * 2062 * This function initialize the axis2 and the relative orientation of 2063 * each body as if body1 was rotated around the axis1 by the offset1 2064 * value and as if body2 was rotated around the new axis2 by offset2. \br 2065 * Ex: 2066 * <PRE> 2067 * dJointSetHuniversalAxis2(jId, 0, 1, 0); 2068 * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0 2069 * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0 2070 * dJointSetHuniversalAxis2Offset(jId, 0, 1, 0, 0.2, 0.17); 2071 * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2 2072 * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17 2073 * </PRE> 2074 2075 * @param j The Hinge joint ID for which the axis will be set 2076 * @param x The X component of the axis in world frame 2077 * @param y The Y component of the axis in world frame 2078 * @param z The Z component of the axis in world frame 2079 * @param angle The angle for the offset of the relative orientation. 2080 * As if body1 was rotated by angle when the Axis was set (see below). 2081 * The rotation is around the new Hinge axis. 2082 * 2083 * @note Usually the function dJointSetHingeAxis set the current position of body1 2084 * and body2 as the zero angle position. This function set the current position 2085 * as the if the 2 bodies where \b offsets appart. 2086 * 2087 * @note Any previous offsets are erased. 2088 * 2089 * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, 2090 * dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset 2091 * will reset the "zero" angle position. 2092 */ 2093 2094 2095 ODE_API void dJointSetUniversalAxis2Offset (dJointID, dReal x, dReal y, dReal z, 2096 dReal offset1, dReal offset2); 2097 2098 /** 2099 * @brief set joint parameter 2100 * @ingroup joints 2101 */ 2102 ODE_API void dJointSetUniversalParam (dJointID, int parameter, dReal value); 2103 2104 /** 2105 * @brief Applies torque1 about the universal's axis 1, torque2 about the 2106 * universal's axis 2. 2107 * @remarks This function is just a wrapper for dBodyAddTorque(). 2108 * @ingroup joints 2109 */ 2110 ODE_API void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2); 2111 2112 2113 /** 2114 * @brief set anchor 2115 * @ingroup joints 2116 */ 2117 ODE_API void dJointSetPRAnchor (dJointID, dReal x, dReal y, dReal z); 2118 2119 /** 2120 * @brief set the axis for the prismatic articulation 2121 * @ingroup joints 2122 */ 2123 ODE_API void dJointSetPRAxis1 (dJointID, dReal x, dReal y, dReal z); 2124 2125 /** 2126 * @brief set the axis for the rotoide articulation 2127 * @ingroup joints 2128 */ 2129 ODE_API void dJointSetPRAxis2 (dJointID, dReal x, dReal y, dReal z); 2130 2131 /** 2132 * @brief set joint parameter 2133 * @ingroup joints 2134 * 2135 * @note parameterX where X equal 2 refer to parameter for the rotoide articulation 2136 */ 2137 ODE_API void dJointSetPRParam (dJointID, int parameter, dReal value); 2138 2139 /** 2140 * @brief Applies the torque about the rotoide axis of the PR joint 2141 * 2142 * That is, it applies a torque with specified magnitude in the direction 2143 * of the rotoide axis, to body 1, and with the same magnitude but in opposite 2144 * direction to body 2. This function is just a wrapper for dBodyAddTorque()} 2145 * @ingroup joints 2146 */ 2147 ODE_API void dJointAddPRTorque (dJointID j, dReal torque); 2148 2149 2150 /** 2151 * @brief set anchor 2152 * @ingroup joints 2153 */ 2154 ODE_API void dJointSetPUAnchor (dJointID, dReal x, dReal y, dReal z); 2155 2156 /** 2157 * @brief set anchor 2158 * @ingroup joints 2159 */ 2160 ODE_API_DEPRECATED ODE_API void dJointSetPUAnchorDelta (dJointID, dReal x, dReal y, dReal z, 2161 dReal dx, dReal dy, dReal dz); 2162 2163 /** 2164 * @brief Set the PU anchor as if the 2 bodies were already at [dx, dy, dz] appart. 2165 * @ingroup joints 2166 * 2167 * This function initialize the anchor and the relative position of each body 2168 * as if the position between body1 and body2 was already the projection of [dx, dy, dz] 2169 * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the 2170 * axis is set). 2171 * Ex: 2172 * <PRE> 2173 * dReal offset = 3; 2174 * dVector3 axis; 2175 * dJointGetPUAxis(jId, axis); 2176 * dJointSetPUAnchor(jId, 0, 0, 0); 2177 * // If you request the position you will have: dJointGetPUPosition(jId) == 0 2178 * dJointSetPUAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset); 2179 * // If you request the position you will have: dJointGetPUPosition(jId) == offset 2180 * </PRE> 2181 * @param j The PU joint for which the anchor point will be set 2182 * @param x The X position of the anchor point in world frame 2183 * @param y The Y position of the anchor point in world frame 2184 * @param z The Z position of the anchor point in world frame 2185 * @param dx A delta to be substracted to the X position as if the anchor was set 2186 * when body1 was at current_position[X] - dx 2187 * @param dx A delta to be substracted to the Y position as if the anchor was set 2188 * when body1 was at current_position[Y] - dy 2189 * @param dx A delta to be substracted to the Z position as if the anchor was set 2190 * when body1 was at current_position[Z] - dz 2191 */ 2192 ODE_API void dJointSetPUAnchorOffset (dJointID, dReal x, dReal y, dReal z, 2193 dReal dx, dReal dy, dReal dz); 2194 2195 /** 2196 * @brief set the axis for the first axis or the universal articulation 2197 * @ingroup joints 2198 */ 2199 ODE_API void dJointSetPUAxis1 (dJointID, dReal x, dReal y, dReal z); 2200 2201 /** 2202 * @brief set the axis for the second axis or the universal articulation 2203 * @ingroup joints 2204 */ 2205 ODE_API void dJointSetPUAxis2 (dJointID, dReal x, dReal y, dReal z); 2206 2207 /** 2208 * @brief set the axis for the prismatic articulation 2209 * @ingroup joints 2210 */ 2211 ODE_API void dJointSetPUAxis3 (dJointID, dReal x, dReal y, dReal z); 2212 2213 /** 2214 * @brief set the axis for the prismatic articulation 2215 * @ingroup joints 2216 * @note This function was added for convenience it is the same as 2217 * dJointSetPUAxis3 2218 */ 2219 ODE_API void dJointSetPUAxisP (dJointID id, dReal x, dReal y, dReal z); 2220 2221 2222 2223 /** 2224 * @brief set joint parameter 2225 * @ingroup joints 2226 * 2227 * @note parameterX where X equal 2 refer to parameter for second axis of the 2228 * universal articulation 2229 * @note parameterX where X equal 3 refer to parameter for prismatic 2230 * articulation 2231 */ 2232 ODE_API void dJointSetPUParam (dJointID, int parameter, dReal value); 2233 2234 /** 2235 * @brief Applies the torque about the rotoide axis of the PU joint 2236 * 2237 * That is, it applies a torque with specified magnitude in the direction 2238 * of the rotoide axis, to body 1, and with the same magnitude but in opposite 2239 * direction to body 2. This function is just a wrapper for dBodyAddTorque()} 2240 * @ingroup joints 2241 */ 2242 ODE_API void dJointAddPUTorque (dJointID j, dReal torque); 2243 2244 2245 2246 2247 /** 2248 * @brief set the joint anchor 2249 * @ingroup joints 2250 */ 2251 ODE_API void dJointSetPistonAnchor (dJointID, dReal x, dReal y, dReal z); 2252 2253 /** 2254 * @brief Set the Piston anchor as if the 2 bodies were already at [dx,dy, dz] appart. 2255 * @ingroup joints 2256 * 2257 * This function initialize the anchor and the relative position of each body 2258 * as if the position between body1 and body2 was already the projection of [dx, dy, dz] 2259 * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the 2260 * axis is set). 2261 * Ex: 2262 * <PRE> 2263 * dReal offset = 3; 2264 * dVector3 axis; 2265 * dJointGetPistonAxis(jId, axis); 2266 * dJointSetPistonAnchor(jId, 0, 0, 0); 2267 * // If you request the position you will have: dJointGetPistonPosition(jId) == 0 2268 * dJointSetPistonAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset); 2269 * // If you request the position you will have: dJointGetPistonPosition(jId) == offset 2270 * </PRE> 2271 * @param j The Piston joint for which the anchor point will be set 2272 * @param x The X position of the anchor point in world frame 2273 * @param y The Y position of the anchor point in world frame 2274 * @param z The Z position of the anchor point in world frame 2275 * @param dx A delta to be substracted to the X position as if the anchor was set 2276 * when body1 was at current_position[X] - dx 2277 * @param dx A delta to be substracted to the Y position as if the anchor was set 2278 * when body1 was at current_position[Y] - dy 2279 * @param dx A delta to be substracted to the Z position as if the anchor was set 2280 * when body1 was at current_position[Z] - dz 2281 */ 2282 ODE_API void dJointSetPistonAnchorOffset(dJointID j, dReal x, dReal y, dReal z, 2283 dReal dx, dReal dy, dReal dz); 2284 2285 /** 2286 * @brief set the joint axis 2287 * @ingroup joints 2288 */ 2289 ODE_API void dJointSetPistonAxis (dJointID, dReal x, dReal y, dReal z); 2290 2291 /** 2292 * This function set prismatic axis of the joint and also set the position 2293 * of the joint. 2294 * 2295 * @ingroup joints 2296 * @param j The joint affected by this function 2297 * @param x The x component of the axis 2298 * @param y The y component of the axis 2299 * @param z The z component of the axis 2300 * @param dx The Initial position of the prismatic join in the x direction 2301 * @param dy The Initial position of the prismatic join in the y direction 2302 * @param dz The Initial position of the prismatic join in the z direction 2303 */ 2304 ODE_API_DEPRECATED ODE_API void dJointSetPistonAxisDelta (dJointID j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); 2305 2306 /** 2307 * @brief set joint parameter 2308 * @ingroup joints 2309 */ 2310 ODE_API void dJointSetPistonParam (dJointID, int parameter, dReal value); 2311 2312 /** 2313 * @brief Applies the given force in the slider's direction. 2314 * 2315 * That is, it applies a force with specified magnitude, in the direction of 2316 * prismatic's axis, to body1, and with the same magnitude but opposite 2317 * direction to body2. This function is just a wrapper for dBodyAddForce(). 2318 * @ingroup joints 2319 */ 2320 ODE_API void dJointAddPistonForce (dJointID joint, dReal force); 2321 2322 2323 /** 2324 * @brief Call this on the fixed joint after it has been attached to 2325 * remember the current desired relative offset and desired relative 2326 * rotation between the bodies. 2327 * @ingroup joints 2328 */ 2329 ODE_API void dJointSetFixed (dJointID); 2330 2331 /* 2332 * @brief Sets joint parameter 2333 * 2334 * @ingroup joints 2335 */ 2336 ODE_API void dJointSetFixedParam (dJointID, int parameter, dReal value); 2337 2338 /** 2339 * @brief set the nr of axes 2340 * @param num 0..3 2341 * @ingroup joints 2342 */ 2343 ODE_API void dJointSetAMotorNumAxes (dJointID, int num); 2344 2345 /** 2346 * @brief set axis 2347 * @ingroup joints 2348 */ 2349 ODE_API void dJointSetAMotorAxis (dJointID, int anum, int rel, 2350 dReal x, dReal y, dReal z); 2351 2352 /** 2353 * @brief Tell the AMotor what the current angle is along axis anum. 2354 * 2355 * This function should only be called in dAMotorUser mode, because in this 2356 * mode the AMotor has no other way of knowing the joint angles. 2357 * The angle information is needed if stops have been set along the axis, 2358 * but it is not needed for axis motors. 2359 * @ingroup joints 2360 */ 2361 ODE_API void dJointSetAMotorAngle (dJointID, int anum, dReal angle); 2362 2363 /** 2364 * @brief set joint parameter 2365 * @ingroup joints 2366 */ 2367 ODE_API void dJointSetAMotorParam (dJointID, int parameter, dReal value); 2368 2369 /** 2370 * @brief set mode 2371 * @ingroup joints 2372 */ 2373 ODE_API void dJointSetAMotorMode (dJointID, int mode); 2374 2375 /** 2376 * @brief Applies torque0 about the AMotor's axis 0, torque1 about the 2377 * AMotor's axis 1, and torque2 about the AMotor's axis 2. 2378 * @remarks 2379 * If the motor has fewer than three axes, the higher torques are ignored. 2380 * This function is just a wrapper for dBodyAddTorque(). 2381 * @ingroup joints 2382 */ 2383 ODE_API void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3); 2384 2385 /** 2386 * @brief Set the number of axes that will be controlled by the LMotor. 2387 * @param num can range from 0 (which effectively deactivates the joint) to 3. 2388 * @ingroup joints 2389 */ 2390 ODE_API void dJointSetLMotorNumAxes (dJointID, int num); 2391 2392 /** 2393 * @brief Set the AMotor axes. 2394 * @param anum selects the axis to change (0,1 or 2). 2395 * @param rel Each axis can have one of three ``relative orientation'' modes 2396 * \li 0: The axis is anchored to the global frame. 2397 * \li 1: The axis is anchored to the first body. 2398 * \li 2: The axis is anchored to the second body. 2399 * @remarks The axis vector is always specified in global coordinates 2400 * regardless of the setting of rel. 2401 * @ingroup joints 2402 */ 2403 ODE_API void dJointSetLMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z); 2404 2405 /** 2406 * @brief set joint parameter 2407 * @ingroup joints 2408 */ 2409 ODE_API void dJointSetLMotorParam (dJointID, int parameter, dReal value); 2410 2411 /** 2412 * @ingroup joints 2413 */ 2414 ODE_API void dJointSetPlane2DXParam (dJointID, int parameter, dReal value); 2415 2416 /** 2417 * @ingroup joints 2418 */ 2419 2420 ODE_API void dJointSetPlane2DYParam (dJointID, int parameter, dReal value); 2421 2422 /** 2423 * @ingroup joints 2424 */ 2425 ODE_API void dJointSetPlane2DAngleParam (dJointID, int parameter, dReal value); 2426 2427 /** 2428 * @brief Get the joint anchor point, in world coordinates. 2429 * 2430 * This returns the point on body 1. If the joint is perfectly satisfied, 2431 * this will be the same as the point on body 2. 2432 */ 2433 ODE_API void dJointGetBallAnchor (dJointID, dVector3 result); 2434 2435 /** 2436 * @brief Get the joint anchor point, in world coordinates. 2437 * 2438 * This returns the point on body 2. You can think of a ball and socket 2439 * joint as trying to keep the result of dJointGetBallAnchor() and 2440 * dJointGetBallAnchor2() the same. If the joint is perfectly satisfied, 2441 * this function will return the same value as dJointGetBallAnchor() to 2442 * within roundoff errors. dJointGetBallAnchor2() can be used, along with 2443 * dJointGetBallAnchor(), to see how far the joint has come apart. 2444 */ 2445 ODE_API void dJointGetBallAnchor2 (dJointID, dVector3 result); 2446 2447 /** 2448 * @brief get joint parameter 2449 * @ingroup joints 2450 */ 2451 ODE_API dReal dJointGetBallParam (dJointID, int parameter); 2452 2453 /** 2454 * @brief Get the hinge anchor point, in world coordinates. 2455 * 2456 * This returns the point on body 1. If the joint is perfectly satisfied, 2457 * this will be the same as the point on body 2. 2458 * @ingroup joints 2459 */ 2460 ODE_API void dJointGetHingeAnchor (dJointID, dVector3 result); 2461 2462 /** 2463 * @brief Get the joint anchor point, in world coordinates. 2464 * @return The point on body 2. If the joint is perfectly satisfied, 2465 * this will return the same value as dJointGetHingeAnchor(). 2466 * If not, this value will be slightly different. 2467 * This can be used, for example, to see how far the joint has come apart. 2468 * @ingroup joints 2469 */ 2470 ODE_API void dJointGetHingeAnchor2 (dJointID, dVector3 result); 2471 2472 /** 2473 * @brief get axis 2474 * @ingroup joints 2475 */ 2476 ODE_API void dJointGetHingeAxis (dJointID, dVector3 result); 2477 2478 /** 2479 * @brief get joint parameter 2480 * @ingroup joints 2481 */ 2482 ODE_API dReal dJointGetHingeParam (dJointID, int parameter); 2483 2484 /** 2485 * @brief Get the hinge angle. 2486 * 2487 * The angle is measured between the two bodies, or between the body and 2488 * the static environment. 2489 * The angle will be between -pi..pi. 2490 * Give the relative rotation with respect to the Hinge axis of Body 1 with 2491 * respect to Body 2. 2492 * When the hinge anchor or axis is set, the current position of the attached 2493 * bodies is examined and that position will be the zero angle. 2494 * @ingroup joints 2495 */ 2496 ODE_API dReal dJointGetHingeAngle (dJointID); 2497 2498 /** 2499 * @brief Get the hinge angle time derivative. 2500 * @ingroup joints 2501 */ 2502 ODE_API dReal dJointGetHingeAngleRate (dJointID); 2503 2504 /** 2505 * @brief Get the slider linear position (i.e. the slider's extension) 2506 * 2507 * When the axis is set, the current position of the attached bodies is 2508 * examined and that position will be the zero position. 2509 2510 * The position is the distance, with respect to the zero position, 2511 * along the slider axis of body 1 with respect to 2512 * body 2. (A NULL body is replaced by the world). 2513 * @ingroup joints 2514 */ 2515 ODE_API dReal dJointGetSliderPosition (dJointID); 2516 2517 /** 2518 * @brief Get the slider linear position's time derivative. 2519 * @ingroup joints 2520 */ 2521 ODE_API dReal dJointGetSliderPositionRate (dJointID); 2522 2523 /** 2524 * @brief Get the slider axis 2525 * @ingroup joints 2526 */ 2527 ODE_API void dJointGetSliderAxis (dJointID, dVector3 result); 2528 2529 /** 2530 * @brief get joint parameter 2531 * @ingroup joints 2532 */ 2533 ODE_API dReal dJointGetSliderParam (dJointID, int parameter); 2534 2535 /** 2536 * @brief Get the joint anchor point, in world coordinates. 2537 * @return the point on body 1. If the joint is perfectly satisfied, 2538 * this will be the same as the point on body 2. 2539 * @ingroup joints 2540 */ 2541 ODE_API void dJointGetHinge2Anchor (dJointID, dVector3 result); 2542 2543 /** 2544 * @brief Get the joint anchor point, in world coordinates. 2545 * This returns the point on body 2. If the joint is perfectly satisfied, 2546 * this will return the same value as dJointGetHinge2Anchor. 2547 * If not, this value will be slightly different. 2548 * This can be used, for example, to see how far the joint has come apart. 2549 * @ingroup joints 2550 */ 2551 ODE_API void dJointGetHinge2Anchor2 (dJointID, dVector3 result); 2552 2553 /** 2554 * @brief Get joint axis 2555 * @ingroup joints 2556 */ 2557 ODE_API void dJointGetHinge2Axis1 (dJointID, dVector3 result); 2558 2559 /** 2560 * @brief Get joint axis 2561 * @ingroup joints 2562 */ 2563 ODE_API void dJointGetHinge2Axis2 (dJointID, dVector3 result); 2564 2565 /** 2566 * @brief get joint parameter 2567 * @ingroup joints 2568 */ 2569 ODE_API dReal dJointGetHinge2Param (dJointID, int parameter); 2570 2571 /** 2572 * @brief Get angle 2573 * @ingroup joints 2574 */ 2575 ODE_API dReal dJointGetHinge2Angle1 (dJointID); 2576 2577 /** 2578 * @brief Get time derivative of angle 2579 * @ingroup joints 2580 */ 2581 ODE_API dReal dJointGetHinge2Angle1Rate (dJointID); 2582 2583 /** 2584 * @brief Get time derivative of angle 2585 * @ingroup joints 2586 */ 2587 ODE_API dReal dJointGetHinge2Angle2Rate (dJointID); 2588 2589 /** 2590 * @brief Get the joint anchor point, in world coordinates. 2591 * @return the point on body 1. If the joint is perfectly satisfied, 2592 * this will be the same as the point on body 2. 2593 * @ingroup joints 2594 */ 2595 ODE_API void dJointGetUniversalAnchor (dJointID, dVector3 result); 2596 2597 /** 2598 * @brief Get the joint anchor point, in world coordinates. 2599 * @return This returns the point on body 2. 2600 * @remarks 2601 * You can think of the ball and socket part of a universal joint as 2602 * trying to keep the result of dJointGetBallAnchor() and 2603 * dJointGetBallAnchor2() the same. If the joint is 2604 * perfectly satisfied, this function will return the same value 2605 * as dJointGetUniversalAnchor() to within roundoff errors. 2606 * dJointGetUniversalAnchor2() can be used, along with 2607 * dJointGetUniversalAnchor(), to see how far the joint has come apart. 2608 * @ingroup joints 2609 */ 2610 ODE_API void dJointGetUniversalAnchor2 (dJointID, dVector3 result); 2611 2612 /** 2613 * @brief Get axis 2614 * @ingroup joints 2615 */ 2616 ODE_API void dJointGetUniversalAxis1 (dJointID, dVector3 result); 2617 2618 /** 2619 * @brief Get axis 2620 * @ingroup joints 2621 */ 2622 ODE_API void dJointGetUniversalAxis2 (dJointID, dVector3 result); 2623 2624 2625 /** 2626 * @brief get joint parameter 2627 * @ingroup joints 2628 */ 2629 ODE_API dReal dJointGetUniversalParam (dJointID, int parameter); 2630 2631 /** 2632 * @brief Get both angles at the same time. 2633 * @ingroup joints 2634 * 2635 * @param joint The universal joint for which we want to calculate the angles 2636 * @param angle1 The angle between the body1 and the axis 1 2637 * @param angle2 The angle between the body2 and the axis 2 2638 * 2639 * @note This function combine getUniversalAngle1 and getUniversalAngle2 together 2640 * and try to avoid redundant calculation 2641 */ 2642 ODE_API void dJointGetUniversalAngles (dJointID, dReal *angle1, dReal *angle2); 2643 2644 /** 2645 * @brief Get angle 2646 * @ingroup joints 2647 */ 2648 ODE_API dReal dJointGetUniversalAngle1 (dJointID); 2649 2650 /** 2651 * @brief Get angle 2652 * @ingroup joints 2653 */ 2654 ODE_API dReal dJointGetUniversalAngle2 (dJointID); 2655 2656 /** 2657 * @brief Get time derivative of angle 2658 * @ingroup joints 2659 */ 2660 ODE_API dReal dJointGetUniversalAngle1Rate (dJointID); 2661 2662 /** 2663 * @brief Get time derivative of angle 2664 * @ingroup joints 2665 */ 2666 ODE_API dReal dJointGetUniversalAngle2Rate (dJointID); 2667 2668 2669 2670 /** 2671 * @brief Get the joint anchor point, in world coordinates. 2672 * @return the point on body 1. If the joint is perfectly satisfied, 2673 * this will be the same as the point on body 2. 2674 * @ingroup joints 2675 */ 2676 ODE_API void dJointGetPRAnchor (dJointID, dVector3 result); 2677 2678 /** 2679 * @brief Get the PR linear position (i.e. the prismatic's extension) 2680 * 2681 * When the axis is set, the current position of the attached bodies is 2682 * examined and that position will be the zero position. 2683 * 2684 * The position is the "oriented" length between the 2685 * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)] 2686 * 2687 * @ingroup joints 2688 */ 2689 ODE_API dReal dJointGetPRPosition (dJointID); 2690 2691 /** 2692 * @brief Get the PR linear position's time derivative 2693 * 2694 * @ingroup joints 2695 */ 2696 ODE_API dReal dJointGetPRPositionRate (dJointID); 2697 2698 2699 /** 2700 * @brief Get the PR angular position (i.e. the twist between the 2 bodies) 2701 * 2702 * When the axis is set, the current position of the attached bodies is 2703 * examined and that position will be the zero position. 2704 * @ingroup joints 2705 */ 2706 ODE_API dReal dJointGetPRAngle (dJointID); 2707 2708 /** 2709 * @brief Get the PR angular position's time derivative 2710 * 2711 * @ingroup joints 2712 */ 2713 ODE_API dReal dJointGetPRAngleRate (dJointID); 2714 2715 2716 /** 2717 * @brief Get the prismatic axis 2718 * @ingroup joints 2719 */ 2720 ODE_API void dJointGetPRAxis1 (dJointID, dVector3 result); 2721 2722 /** 2723 * @brief Get the Rotoide axis 2724 * @ingroup joints 2725 */ 2726 ODE_API void dJointGetPRAxis2 (dJointID, dVector3 result); 2727 2728 /** 2729 * @brief get joint parameter 2730 * @ingroup joints 2731 */ 2732 ODE_API dReal dJointGetPRParam (dJointID, int parameter); 2733 2734 2735 2736 /** 2737 * @brief Get the joint anchor point, in world coordinates. 2738 * @return the point on body 1. If the joint is perfectly satisfied, 2739 * this will be the same as the point on body 2. 2740 * @ingroup joints 2741 */ 2742 ODE_API void dJointGetPUAnchor (dJointID, dVector3 result); 2743 2744 /** 2745 * @brief Get the PU linear position (i.e. the prismatic's extension) 2746 * 2747 * When the axis is set, the current position of the attached bodies is 2748 * examined and that position will be the zero position. 2749 * 2750 * The position is the "oriented" length between the 2751 * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)] 2752 * 2753 * @ingroup joints 2754 */ 2755 ODE_API dReal dJointGetPUPosition (dJointID); 2756 2757 /** 2758 * @brief Get the PR linear position's time derivative 2759 * 2760 * @ingroup joints 2761 */ 2762 ODE_API dReal dJointGetPUPositionRate (dJointID); 2763 2764 /** 2765 * @brief Get the first axis of the universal component of the joint 2766 * @ingroup joints 2767 */ 2768 ODE_API void dJointGetPUAxis1 (dJointID, dVector3 result); 2769 2770 /** 2771 * @brief Get the second axis of the Universal component of the joint 2772 * @ingroup joints 2773 */ 2774 ODE_API void dJointGetPUAxis2 (dJointID, dVector3 result); 2775 2776 /** 2777 * @brief Get the prismatic axis 2778 * @ingroup joints 2779 */ 2780 ODE_API void dJointGetPUAxis3 (dJointID, dVector3 result); 2781 2782 /** 2783 * @brief Get the prismatic axis 2784 * @ingroup joints 2785 * 2786 * @note This function was added for convenience it is the same as 2787 * dJointGetPUAxis3 2788 */ 2789 ODE_API void dJointGetPUAxisP (dJointID id, dVector3 result); 2790 2791 2792 2793 2794 /** 2795 * @brief Get both angles at the same time. 2796 * @ingroup joints 2797 * 2798 * @param joint The Prismatic universal joint for which we want to calculate the angles 2799 * @param angle1 The angle between the body1 and the axis 1 2800 * @param angle2 The angle between the body2 and the axis 2 2801 * 2802 * @note This function combine dJointGetPUAngle1 and dJointGetPUAngle2 together 2803 * and try to avoid redundant calculation 2804 */ 2805 ODE_API void dJointGetPUAngles (dJointID, dReal *angle1, dReal *angle2); 2806 2807 /** 2808 * @brief Get angle 2809 * @ingroup joints 2810 */ 2811 ODE_API dReal dJointGetPUAngle1 (dJointID); 2812 2813 /** 2814 * @brief * @brief Get time derivative of angle1 2815 * 2816 * @ingroup joints 2817 */ 2818 ODE_API dReal dJointGetPUAngle1Rate (dJointID); 2819 2820 2821 /** 2822 * @brief Get angle 2823 * @ingroup joints 2824 */ 2825 ODE_API dReal dJointGetPUAngle2 (dJointID); 2826 2827 /** 2828 * @brief * @brief Get time derivative of angle2 2829 * 2830 * @ingroup joints 2831 */ 2832 ODE_API dReal dJointGetPUAngle2Rate (dJointID); 2833 2834 /** 2835 * @brief get joint parameter 2836 * @ingroup joints 2837 */ 2838 ODE_API dReal dJointGetPUParam (dJointID, int parameter); 2839 2840 2841 2842 2843 2844 /** 2845 * @brief Get the Piston linear position (i.e. the piston's extension) 2846 * 2847 * When the axis is set, the current position of the attached bodies is 2848 * examined and that position will be the zero position. 2849 * @ingroup joints 2850 */ 2851 ODE_API dReal dJointGetPistonPosition (dJointID); 2852 2853 /** 2854 * @brief Get the piston linear position's time derivative. 2855 * @ingroup joints 2856 */ 2857 ODE_API dReal dJointGetPistonPositionRate (dJointID); 2858 2859 /** 2860 * @brief Get the Piston angular position (i.e. the twist between the 2 bodies) 2861 * 2862 * When the axis is set, the current position of the attached bodies is 2863 * examined and that position will be the zero position. 2864 * @ingroup joints 2865 */ 2866 ODE_API dReal dJointGetPistonAngle (dJointID); 2867 2868 /** 2869 * @brief Get the piston angular position's time derivative. 2870 * @ingroup joints 2871 */ 2872 ODE_API dReal dJointGetPistonAngleRate (dJointID); 2873 2874 2875 /** 2876 * @brief Get the joint anchor 2877 * 2878 * This returns the point on body 1. If the joint is perfectly satisfied, 2879 * this will be the same as the point on body 2 in direction perpendicular 2880 * to the prismatic axis. 2881 * 2882 * @ingroup joints 2883 */ 2884 ODE_API void dJointGetPistonAnchor (dJointID, dVector3 result); 2885 2886 /** 2887 * @brief Get the joint anchor w.r.t. body 2 2888 * 2889 * This returns the point on body 2. You can think of a Piston 2890 * joint as trying to keep the result of dJointGetPistonAnchor() and 2891 * dJointGetPistonAnchor2() the same in the direction perpendicular to the 2892 * pirsmatic axis. If the joint is perfectly satisfied, 2893 * this function will return the same value as dJointGetPistonAnchor() to 2894 * within roundoff errors. dJointGetPistonAnchor2() can be used, along with 2895 * dJointGetPistonAnchor(), to see how far the joint has come apart. 2896 * 2897 * @ingroup joints 2898 */ 2899 ODE_API void dJointGetPistonAnchor2 (dJointID, dVector3 result); 2900 2901 /** 2902 * @brief Get the prismatic axis (This is also the rotoide axis. 2903 * @ingroup joints 2904 */ 2905 ODE_API void dJointGetPistonAxis (dJointID, dVector3 result); 2906 2907 /** 2908 * @brief get joint parameter 2909 * @ingroup joints 2910 */ 2911 ODE_API dReal dJointGetPistonParam (dJointID, int parameter); 2912 2913 2914 /** 2915 * @brief Get the number of angular axes that will be controlled by the 2916 * AMotor. 2917 * @param num can range from 0 (which effectively deactivates the 2918 * joint) to 3. 2919 * This is automatically set to 3 in dAMotorEuler mode. 2920 * @ingroup joints 2921 */ 2922 ODE_API int dJointGetAMotorNumAxes (dJointID); 2923 2924 /** 2925 * @brief Get the AMotor axes. 2926 * @param anum selects the axis to change (0,1 or 2). 2927 * @param rel Each axis can have one of three ``relative orientation'' modes. 2928 * \li 0: The axis is anchored to the global frame. 2929 * \li 1: The axis is anchored to the first body. 2930 * \li 2: The axis is anchored to the second body. 2931 * @ingroup joints 2932 */ 2933 ODE_API void dJointGetAMotorAxis (dJointID, int anum, dVector3 result); 2934 2935 /** 2936 * @brief Get axis 2937 * @remarks 2938 * The axis vector is always specified in global coordinates regardless 2939 * of the setting of rel. 2940 * There are two GetAMotorAxis functions, one to return the axis and one to 2941 * return the relative mode. 2942 * 2943 * For dAMotorEuler mode: 2944 * \li Only axes 0 and 2 need to be set. Axis 1 will be determined 2945 automatically at each time step. 2946 * \li Axes 0 and 2 must be perpendicular to each other. 2947 * \li Axis 0 must be anchored to the first body, axis 2 must be anchored 2948 to the second body. 2949 * @ingroup joints 2950 */ 2951 ODE_API int dJointGetAMotorAxisRel (dJointID, int anum); 2952 2953 /** 2954 * @brief Get the current angle for axis. 2955 * @remarks 2956 * In dAMotorUser mode this is simply the value that was set with 2957 * dJointSetAMotorAngle(). 2958 * In dAMotorEuler mode this is the corresponding euler angle. 2959 * @ingroup joints 2960 */ 2961 ODE_API dReal dJointGetAMotorAngle (dJointID, int anum); 2962 2963 /** 2964 * @brief Get the current angle rate for axis anum. 2965 * @remarks 2966 * In dAMotorUser mode this is always zero, as not enough information is 2967 * available. 2968 * In dAMotorEuler mode this is the corresponding euler angle rate. 2969 * @ingroup joints 2970 */ 2971 ODE_API dReal dJointGetAMotorAngleRate (dJointID, int anum); 2972 2973 /** 2974 * @brief get joint parameter 2975 * @ingroup joints 2976 */ 2977 ODE_API dReal dJointGetAMotorParam (dJointID, int parameter); 2978 2979 /** 2980 * @brief Get the angular motor mode. 2981 * @param mode must be one of the following constants: 2982 * \li dAMotorUser The AMotor axes and joint angle settings are entirely 2983 * controlled by the user. This is the default mode. 2984 * \li dAMotorEuler Euler angles are automatically computed. 2985 * The axis a1 is also automatically computed. 2986 * The AMotor axes must be set correctly when in this mode, 2987 * as described below. 2988 * When this mode is initially set the current relative orientations 2989 * of the bodies will correspond to all euler angles at zero. 2990 * @ingroup joints 2991 */ 2992 ODE_API int dJointGetAMotorMode (dJointID); 2993 2994 /** 2995 * @brief Get nr of axes. 2996 * @ingroup joints 2997 */ 2998 ODE_API int dJointGetLMotorNumAxes (dJointID); 2999 3000 /** 3001 * @brief Get axis. 3002 * @ingroup joints 3003 */ 3004 ODE_API void dJointGetLMotorAxis (dJointID, int anum, dVector3 result); 3005 3006 /** 3007 * @brief get joint parameter 3008 * @ingroup joints 3009 */ 3010 ODE_API dReal dJointGetLMotorParam (dJointID, int parameter); 3011 3012 /** 3013 * @brief get joint parameter 3014 * @ingroup joints 3015 */ 3016 ODE_API dReal dJointGetFixedParam (dJointID, int parameter); 3017 3018 3019 /** 3020 * @brief get the contact point of the first wheel of the Transmission joint. 3021 * @ingroup joints 3022 */ 3023 ODE_API void dJointGetTransmissionContactPoint1(dJointID, dVector3 result); 3024 3025 /** 3026 * @brief get contact point of the second wheel of the Transmission joint. 3027 * @ingroup joints 3028 */ 3029 ODE_API void dJointGetTransmissionContactPoint2(dJointID, dVector3 result); 3030 3031 /** 3032 * @brief set the first axis for the Transmission joint 3033 * @remarks This is the axis around which the first body is allowed to 3034 * revolve and is attached to it. It is given in global coordinates 3035 * and can only be set explicitly in intersecting-axes mode. For the 3036 * parallel-axes and chain modes which share one common axis of 3037 * revolution for both gears dJointSetTransmissionAxis should be used. 3038 * @ingroup joints 3039 */ 3040 ODE_API void dJointSetTransmissionAxis1(dJointID, dReal x, dReal y, dReal z); 3041 3042 /** 3043 * @brief get first axis for the Transmission joint 3044 * @remarks In parallel-axes and chain mode the common axis with 3045 * respect to the first body is returned. If the joint constraint is 3046 * satisfied it should be the same as the axis return with 3047 * dJointGetTransmissionAxis2 or dJointGetTransmissionAxis. 3048 * @ingroup joints 3049 */ 3050 ODE_API void dJointGetTransmissionAxis1(dJointID, dVector3 result); 3051 3052 /** 3053 * @brief set second axis for the Transmission joint 3054 * @remarks This is the axis around which the second body is allowed 3055 * to revolve and is attached to it. It is given in global 3056 * coordinates and can only be set explicitly in intersecting-axes 3057 * mode. For the parallel-axes and chain modes which share one common 3058 * axis of revolution for both gears dJointSetTransmissionAxis should 3059 * be used. 3060 * @ingroup joints 3061 */ 3062 ODE_API void dJointSetTransmissionAxis2(dJointID, dReal x, dReal y, dReal z); 3063 3064 /** 3065 * @brief get second axis for the Transmission joint 3066 * @remarks In parallel-axes and chain mode the common axis with 3067 * respect to the second body is returned. If the joint constraint is 3068 * satisfied it should be the same as the axis return with 3069 * dJointGetTransmissionAxis1 or dJointGetTransmissionAxis. 3070 * @ingroup joints 3071 */ 3072 ODE_API void dJointGetTransmissionAxis2(dJointID, dVector3 result); 3073 3074 /** 3075 * @brief set the first anchor for the Transmission joint 3076 * @remarks This is the point of attachment of the wheel on the 3077 * first body. It is given in global coordinates. 3078 * @ingroup joints 3079 */ 3080 ODE_API void dJointSetTransmissionAnchor1(dJointID, dReal x, dReal y, dReal z); 3081 3082 /** 3083 * @brief get the first anchor of the Transmission joint 3084 * @ingroup joints 3085 */ 3086 ODE_API void dJointGetTransmissionAnchor1(dJointID, dVector3 result); 3087 3088 /** 3089 * @brief set the second anchor for the Transmission joint 3090 * @remarks This is the point of attachment of the wheel on the 3091 * second body. It is given in global coordinates. 3092 * @ingroup joints 3093 */ 3094 ODE_API void dJointSetTransmissionAnchor2(dJointID, dReal x, dReal y, dReal z); 3095 3096 /** 3097 * @brief get the second anchor for the Transmission joint 3098 * @ingroup joints 3099 */ 3100 ODE_API void dJointGetTransmissionAnchor2(dJointID, dVector3 result); 3101 3102 /** 3103 * @brief set a Transmission joint parameter 3104 * @ingroup joints 3105 */ 3106 ODE_API void dJointSetTransmissionParam(dJointID, int parameter, dReal value); 3107 3108 /** 3109 * @brief get a Transmission joint parameter 3110 * @ingroup joints 3111 */ 3112 ODE_API dReal dJointGetTransmissionParam(dJointID, int parameter); 3113 3114 /** 3115 * @brief set the Transmission joint mode 3116 * @remarks The mode can be one of dTransmissionParallelAxes, 3117 * dTransmissionIntersectingAxes and dTransmissionChainDrive simulating a 3118 * set of parallel-axes gears, intersecting-axes beveled gears or 3119 * chain and sprockets respectively. 3120 * @ingroup joints 3121 */ 3122 ODE_API void dJointSetTransmissionMode( dJointID j, int mode ); 3123 3124 /** 3125 * @brief get the Transmission joint mode 3126 * @ingroup joints 3127 */ 3128 ODE_API int dJointGetTransmissionMode( dJointID j ); 3129 3130 /** 3131 * @brief set the Transmission ratio 3132 * @remarks This is the ratio of the angular speed of the first gear 3133 * to that of the second gear. It can only be set explicitly in 3134 * parallel-axes mode. In intersecting-axes mode the ratio is defined 3135 * implicitly by the initial configuration of the wheels and in chain 3136 * mode it is defined implicitly be the wheel radii. 3137 * @ingroup joints 3138 */ 3139 ODE_API void dJointSetTransmissionRatio( dJointID j, dReal ratio ); 3140 3141 /** 3142 * @brief get the Transmission joint ratio 3143 * @ingroup joints 3144 */ 3145 ODE_API dReal dJointGetTransmissionRatio( dJointID j ); 3146 3147 /** 3148 * @brief set the common axis for both wheels of the Transmission joint 3149 * @remarks This sets the common axis of revolution for both wheels 3150 * and should only be used in parallel-axes or chain mode. For 3151 * intersecting-axes mode where each wheel axis needs to be specified 3152 * individually dJointSetTransmissionAxis1 and 3153 * dJointSetTransmissionAxis2 should be used. The axis is given in 3154 * global coordinates 3155 * @ingroup joints 3156 */ 3157 ODE_API void dJointSetTransmissionAxis( dJointID j, dReal x, dReal y, dReal z ); 3158 3159 /** 3160 * @brief get the common axis for both wheels of the Transmission joint 3161 * @ingroup joints 3162 */ 3163 ODE_API void dJointGetTransmissionAxis( dJointID j, dVector3 result ); 3164 3165 /** 3166 * @brief get the phase, that is the traversed angle for the first 3167 * wheel of the Transmission joint 3168 * @ingroup joints 3169 */ 3170 ODE_API dReal dJointGetTransmissionAngle1( dJointID j ); 3171 3172 /** 3173 * @brief get the phase, that is the traversed angle for the second 3174 * wheel of the Transmission joint 3175 * @ingroup joints 3176 */ 3177 ODE_API dReal dJointGetTransmissionAngle2( dJointID j ); 3178 3179 /** 3180 * @brief get the radius of the first wheel of the Transmission joint 3181 * @ingroup joints 3182 */ 3183 ODE_API dReal dJointGetTransmissionRadius1( dJointID j ); 3184 3185 /** 3186 * @brief get the radius of the second wheel of the Transmission joint 3187 * @ingroup joints 3188 */ 3189 ODE_API dReal dJointGetTransmissionRadius2( dJointID j ); 3190 3191 /** 3192 * @brief set the radius of the first wheel of the Transmission joint 3193 * @remarks The wheel radii can only be set explicitly in chain mode. 3194 * In the other modes they're defined implicitly by the initial 3195 * configuration and ratio of the wheels. 3196 * @ingroup joints 3197 */ 3198 ODE_API void dJointSetTransmissionRadius1( dJointID j, dReal radius ); 3199 3200 /** 3201 * @brief set the radius of the second wheel of the Transmission joint 3202 * @remarks The wheel radii can only be set explicitly in chain mode. 3203 * In the other modes they're defined implicitly by the initial 3204 * configuration and ratio of the wheels. 3205 * @ingroup joints 3206 */ 3207 ODE_API void dJointSetTransmissionRadius2( dJointID j, dReal radius ); 3208 3209 /** 3210 * @brief get the backlash of the Transmission joint 3211 * @ingroup joints 3212 */ 3213 ODE_API dReal dJointGetTransmissionBacklash( dJointID j ); 3214 3215 /** 3216 * @brief set the backlash of the Transmission joint 3217 * @remarks Backlash is the clearance in the mesh of the wheels of the 3218 * transmission and is defined as the maximum distance that the 3219 * geometric contact point can travel without any actual contact or 3220 * transfer of power between the wheels. This can be converted in 3221 * degrees of revolution for each wheel by dividing by the wheel's 3222 * radius. To further illustrate this consider the situation where a 3223 * wheel of radius r_1 is driving another wheel of radius r_2 and 3224 * there is an amount of backlash equal to b in their mesh. If the 3225 * driving wheel were to instantaneously stop there would be no 3226 * contact and hence the driven wheel would continue to turn for 3227 * another b / r_2 radians until all the backlash in the mesh was take 3228 * up and contact restored with the relationship of driving and driven 3229 * wheel reversed. The backlash is therefore given in untis of 3230 * length. 3231 * @ingroup joints 3232 */ 3233 ODE_API void dJointSetTransmissionBacklash( dJointID j, dReal backlash ); 3234 3235 /** 3236 * @brief set anchor1 for double ball joint 3237 * @ingroup joints 3238 */ 3239 ODE_API void dJointSetDBallAnchor1(dJointID, dReal x, dReal y, dReal z); 3240 3241 /** 3242 * @brief set anchor2 for double ball joint 3243 * @ingroup joints 3244 */ 3245 ODE_API void dJointSetDBallAnchor2(dJointID, dReal x, dReal y, dReal z); 3246 3247 /** 3248 * @brief get anchor1 from double ball joint 3249 * @ingroup joints 3250 */ 3251 ODE_API void dJointGetDBallAnchor1(dJointID, dVector3 result); 3252 3253 /** 3254 * @brief get anchor2 from double ball joint 3255 * @ingroup joints 3256 */ 3257 ODE_API void dJointGetDBallAnchor2(dJointID, dVector3 result); 3258 3259 /** 3260 * @brief get the set distance from double ball joint 3261 * @ingroup joints 3262 */ 3263 ODE_API dReal dJointGetDBallDistance(dJointID); 3264 3265 /** 3266 * @brief set double ball joint parameter 3267 * @ingroup joints 3268 */ 3269 ODE_API void dJointSetDBallParam(dJointID, int parameter, dReal value); 3270 3271 /** 3272 * @brief get double ball joint parameter 3273 * @ingroup joints 3274 */ 3275 ODE_API dReal dJointGetDBallParam(dJointID, int parameter); 3276 3277 /** 3278 * @brief set axis for double hinge joint 3279 * @ingroup joints 3280 */ 3281 ODE_API void dJointSetDHingeAxis(dJointID, dReal x, dReal y, dReal z); 3282 3283 /** 3284 * @brief get axis for double hinge joint 3285 * @ingroup joints 3286 */ 3287 ODE_API void dJointGetDHingeAxis(dJointID, dVector3 result); 3288 3289 /** 3290 * @brief set anchor1 for double hinge joint 3291 * @ingroup joints 3292 */ 3293 ODE_API void dJointSetDHingeAnchor1(dJointID, dReal x, dReal y, dReal z); 3294 3295 /** 3296 * @brief set anchor2 for double hinge joint 3297 * @ingroup joints 3298 */ 3299 ODE_API void dJointSetDHingeAnchor2(dJointID, dReal x, dReal y, dReal z); 3300 3301 /** 3302 * @brief get anchor1 from double hinge joint 3303 * @ingroup joints 3304 */ 3305 ODE_API void dJointGetDHingeAnchor1(dJointID, dVector3 result); 3306 3307 /** 3308 * @brief get anchor2 from double hinge joint 3309 * @ingroup joints 3310 */ 3311 ODE_API void dJointGetDHingeAnchor2(dJointID, dVector3 result); 3312 3313 /** 3314 * @brief get the set distance from double hinge joint 3315 * @ingroup joints 3316 */ 3317 ODE_API dReal dJointGetDHingeDistance(dJointID); 3318 3319 /** 3320 * @brief set double hinge joint parameter 3321 * @ingroup joints 3322 */ 3323 ODE_API void dJointSetDHingeParam(dJointID, int parameter, dReal value); 3324 3325 /** 3326 * @brief get double hinge joint parameter 3327 * @ingroup joints 3328 */ 3329 ODE_API dReal dJointGetDHingeParam(dJointID, int parameter); 3330 3331 3332 3333 3334 /** 3335 * @ingroup joints 3336 */ 3337 ODE_API dJointID dConnectingJoint (dBodyID, dBodyID); 3338 3339 /** 3340 * @ingroup joints 3341 */ 3342 ODE_API int dConnectingJointList (dBodyID, dBodyID, dJointID*); 3343 3344 /** 3345 * @brief Utility function 3346 * @return 1 if the two bodies are connected together by 3347 * a joint, otherwise return 0. 3348 * @ingroup joints 3349 */ 3350 ODE_API int dAreConnected (dBodyID, dBodyID); 3351 3352 /** 3353 * @brief Utility function 3354 * @return 1 if the two bodies are connected together by 3355 * a joint that does not have type @arg{joint_type}, otherwise return 0. 3356 * @param body1 A body to check. 3357 * @param body2 A body to check. 3358 * @param joint_type is a dJointTypeXXX constant. 3359 * This is useful for deciding whether to add contact joints between two bodies: 3360 * if they are already connected by non-contact joints then it may not be 3361 * appropriate to add contacts, however it is okay to add more contact between- 3362 * bodies that already have contacts. 3363 * @ingroup joints 3364 */ 3365 ODE_API int dAreConnectedExcluding (dBodyID body1, dBodyID body2, int joint_type); 3366 3367 3368 #ifdef __cplusplus 3369 } 3370 #endif 3371 3372 #endif 3373