1 /************************************************************************* 2 * D bindings for ODE * 3 * * 4 * C header port by Daniel "q66" Kolesa <quaker66@gmail.com> * 5 * * 6 * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 * * 9 * This library is free software; you can redistribute it and/or * 10 * modify it under the terms of EITHER: * 11 * (1) The GNU Lesser General Public License as published by the Free * 12 * Software Foundation; either version 2.1 of the License, or (at * 13 * your option) any later version. The text of the GNU Lesser * 14 * General Public License is included with this library in the * 15 * file LICENSE.TXT. * 16 * (2) The BSD-style license that is included with this library in * 17 * the file LICENSE-BSD.TXT. * 18 * * 19 * This library is distributed in the hope that it will be useful, * 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 * * 24 *************************************************************************/ 25 26 module deimos.ode.collision; 27 28 private 29 { 30 import deimos.ode.common; 31 import deimos.ode.collision_space; 32 import deimos.ode.contact; 33 34 import deimos.ode.odeinit; 35 } 36 37 extern (C): 38 nothrow: 39 40 41 /** 42 * @defgroup collide Collision Detection 43 * 44 * ODE has two main components: a dynamics simulation engine and a collision 45 * detection engine. The collision engine is given information about the 46 * shape of each body. At each time step it figures out which bodies touch 47 * each other and passes the resulting contact point information to the user. 48 * The user in turn creates contact joints between bodies. 49 * 50 * Using ODE's collision detection is optional - an alternative collision 51 * detection system can be used as long as it can supply the right kinds of 52 * contact information. 53 */ 54 55 56 /* ************************************************************************ */ 57 /* general functions */ 58 59 /** 60 * @brief Destroy a geom, removing it from any space. 61 * 62 * Destroy a geom, removing it from any space it is in first. This one 63 * function destroys a geom of any type, but to create a geom you must call 64 * a creation function for that type. 65 * 66 * When a space is destroyed, if its cleanup mode is 1 (the default) then all 67 * the geoms in that space are automatically destroyed as well. 68 * 69 * @param geom the geom to be destroyed. 70 * @ingroup collide 71 */ 72 void dGeomDestroy(dGeomID geom); 73 74 75 /** 76 * @brief Set the user-defined data pointer stored in the geom. 77 * 78 * @param geom the geom to hold the data 79 * @param data the data pointer to be stored 80 * @ingroup collide 81 */ 82 void dGeomSetData(dGeomID geom, void* data); 83 84 85 /** 86 * @brief Get the user-defined data pointer stored in the geom. 87 * 88 * @param geom the geom containing the data 89 * @ingroup collide 90 */ 91 void* dGeomGetData(dGeomID geom); 92 93 94 /** 95 * @brief Set the body associated with a placeable geom. 96 * 97 * Setting a body on a geom automatically combines the position vector and 98 * rotation matrix of the body and geom, so that setting the position or 99 * orientation of one will set the value for both objects. Setting a body 100 * ID of zero gives the geom its own position and rotation, independent 101 * from any body. If the geom was previously connected to a body then its 102 * new independent position/rotation is set to the current position/rotation 103 * of the body. 104 * 105 * Calling these functions on a non-placeable geom results in a runtime 106 * error in the debug build of ODE. 107 * 108 * @param geom the geom to connect 109 * @param body the body to attach to the geom 110 * @ingroup collide 111 */ 112 void dGeomSetBody(dGeomID geom, dBodyID gbody); 113 114 115 /** 116 * @brief Get the body associated with a placeable geom. 117 * @param geom the geom to query. 118 * @sa dGeomSetBody 119 * @ingroup collide 120 */ 121 dBodyID dGeomGetBody(dGeomID geom); 122 123 124 /** 125 * @brief Set the position vector of a placeable geom. 126 * 127 * If the geom is attached to a body, the body's position will also be changed. 128 * Calling this function on a non-placeable geom results in a runtime error in 129 * the debug build of ODE. 130 * 131 * @param geom the geom to set. 132 * @param x the new X coordinate. 133 * @param y the new Y coordinate. 134 * @param z the new Z coordinate. 135 * @sa dBodySetPosition 136 * @ingroup collide 137 */ 138 void dGeomSetPosition(dGeomID geom, dReal x, dReal y, dReal z); 139 140 141 /** 142 * @brief Set the rotation matrix of a placeable geom. 143 * 144 * If the geom is attached to a body, the body's rotation will also be changed. 145 * Calling this function on a non-placeable geom results in a runtime error in 146 * the debug build of ODE. 147 * 148 * @param geom the geom to set. 149 * @param R the new rotation matrix. 150 * @sa dBodySetRotation 151 * @ingroup collide 152 */ 153 void dGeomSetRotation(dGeomID geom, in dMatrix3 R); 154 155 156 /** 157 * @brief Set the rotation of a placeable geom. 158 * 159 * If the geom is attached to a body, the body's rotation will also be changed. 160 * 161 * Calling this function on a non-placeable geom results in a runtime error in 162 * the debug build of ODE. 163 * 164 * @param geom the geom to set. 165 * @param Q the new rotation. 166 * @sa dBodySetQuaternion 167 * @ingroup collide 168 */ 169 void dGeomSetQuaternion(dGeomID geom, in dQuaternion Q); 170 171 172 /** 173 * @brief Get the position vector of a placeable geom. 174 * 175 * If the geom is attached to a body, the body's position will be returned. 176 * 177 * Calling this function on a non-placeable geom results in a runtime error in 178 * the debug build of ODE. 179 * 180 * @param geom the geom to query. 181 * @returns A pointer to the geom's position vector. 182 * @remarks The returned value is a pointer to the geom's internal 183 * data structure. It is valid until any changes are made 184 * to the geom. 185 * @sa dBodyGetPosition 186 * @ingroup collide 187 */ 188 const(dReal)* dGeomGetPosition(dGeomID geom); 189 190 191 /** 192 * @brief Copy the position of a geom into a vector. 193 * @ingroup collide 194 * @param geom the geom to query 195 * @param pos a copy of the geom position 196 * @sa dGeomGetPosition 197 */ 198 void dGeomCopyPosition(dGeomID geom, dVector3 pos); 199 200 201 /** 202 * @brief Get the rotation matrix of a placeable geom. 203 * 204 * If the geom is attached to a body, the body's rotation will be returned. 205 * 206 * Calling this function on a non-placeable geom results in a runtime error in 207 * the debug build of ODE. 208 * 209 * @param geom the geom to query. 210 * @returns A pointer to the geom's rotation matrix. 211 * @remarks The returned value is a pointer to the geom's internal 212 * data structure. It is valid until any changes are made 213 * to the geom. 214 * @sa dBodyGetRotation 215 * @ingroup collide 216 */ 217 const(dReal)* dGeomGetRotation(dGeomID geom); 218 219 220 /** 221 * @brief Get the rotation matrix of a placeable geom. 222 * 223 * If the geom is attached to a body, the body's rotation will be returned. 224 * 225 * Calling this function on a non-placeable geom results in a runtime error in 226 * the debug build of ODE. 227 * 228 * @param geom the geom to query. 229 * @param R a copy of the geom rotation 230 * @sa dGeomGetRotation 231 * @ingroup collide 232 */ 233 void dGeomCopyRotation(dGeomID geom, dMatrix3 R); 234 235 236 /** 237 * @brief Get the rotation quaternion of a placeable geom. 238 * 239 * If the geom is attached to a body, the body's quaternion will be returned. 240 * 241 * Calling this function on a non-placeable geom results in a runtime error in 242 * the debug build of ODE. 243 * 244 * @param geom the geom to query. 245 * @param result a copy of the rotation quaternion. 246 * @sa dBodyGetQuaternion 247 * @ingroup collide 248 */ 249 void dGeomGetQuaternion(dGeomID geom, dQuaternion result); 250 251 252 /** 253 * @brief Return the axis-aligned bounding box. 254 * 255 * Return in aabb an axis aligned bounding box that surrounds the given geom. 256 * The aabb array has elements (minx, maxx, miny, maxy, minz, maxz). If the 257 * geom is a space, a bounding box that surrounds all contained geoms is 258 * returned. 259 * 260 * This function may return a pre-computed cached bounding box, if it can 261 * determine that the geom has not moved since the last time the bounding 262 * box was computed. 263 * 264 * @param geom the geom to query 265 * @param aabb the returned bounding box 266 * @ingroup collide 267 */ 268 void dGeomGetAABB(dGeomID geom, ref dReal[6] aabb); 269 270 271 /** 272 * @brief Determing if a geom is a space. 273 * @param geom the geom to query 274 * @returns Non-zero if the geom is a space, zero otherwise. 275 * @ingroup collide 276 */ 277 int dGeomIsSpace(dGeomID geom); 278 279 280 /** 281 * @brief Query for the space containing a particular geom. 282 * @param geom the geom to query 283 * @returns The space that contains the geom, or NULL if the geom is 284 * not contained by a space. 285 * @ingroup collide 286 */ 287 dSpaceID dGeomGetSpace(dGeomID); 288 289 290 /** 291 * @brief Given a geom, this returns its class. 292 * 293 * The ODE classes are: 294 * @li dSphereClass 295 * @li dBoxClass 296 * @li dCylinderClass 297 * @li dPlaneClass 298 * @li dRayClass 299 * @li dConvexClass 300 * @li dGeomTransformClass 301 * @li dTriMeshClass 302 * @li dSimpleSpaceClass 303 * @li dHashSpaceClass 304 * @li dQuadTreeSpaceClass 305 * @li dFirstUserClass 306 * @li dLastUserClass 307 * 308 * User-defined class will return their own number. 309 * 310 * @param geom the geom to query 311 * @returns The geom class ID. 312 * @ingroup collide 313 */ 314 int dGeomGetClass(dGeomID geom); 315 316 317 /** 318 * @brief Set the "category" bitfield for the given geom. 319 * 320 * The category bitfield is used by spaces to govern which geoms will 321 * interact with each other. The bitfield is guaranteed to be at least 322 * 32 bits wide. The default category values for newly created geoms 323 * have all bits set. 324 * 325 * @param geom the geom to set 326 * @param bits the new bitfield value 327 * @ingroup collide 328 */ 329 void dGeomSetCategoryBits(dGeomID geom, c_ulong bits); 330 331 332 /** 333 * @brief Set the "collide" bitfield for the given geom. 334 * 335 * The collide bitfield is used by spaces to govern which geoms will 336 * interact with each other. The bitfield is guaranteed to be at least 337 * 32 bits wide. The default category values for newly created geoms 338 * have all bits set. 339 * 340 * @param geom the geom to set 341 * @param bits the new bitfield value 342 * @ingroup collide 343 */ 344 void dGeomSetCollideBits(dGeomID geom, c_ulong bits); 345 346 347 /** 348 * @brief Get the "category" bitfield for the given geom. 349 * 350 * @param geom the geom to set 351 * @param bits the new bitfield value 352 * @sa dGeomSetCategoryBits 353 * @ingroup collide 354 */ 355 c_ulong dGeomGetCategoryBits(dGeomID); 356 357 358 /** 359 * @brief Get the "collide" bitfield for the given geom. 360 * 361 * @param geom the geom to set 362 * @param bits the new bitfield value 363 * @sa dGeomSetCollideBits 364 * @ingroup collide 365 */ 366 c_ulong dGeomGetCollideBits(dGeomID); 367 368 369 /** 370 * @brief Enable a geom. 371 * 372 * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, 373 * although they can still be members of a space. New geoms are created in 374 * the enabled state. 375 * 376 * @param geom the geom to enable 377 * @sa dGeomDisable 378 * @sa dGeomIsEnabled 379 * @ingroup collide 380 */ 381 void dGeomEnable(dGeomID geom); 382 383 384 /** 385 * @brief Disable a geom. 386 * 387 * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, 388 * although they can still be members of a space. New geoms are created in 389 * the enabled state. 390 * 391 * @param geom the geom to disable 392 * @sa dGeomDisable 393 * @sa dGeomIsEnabled 394 * @ingroup collide 395 */ 396 void dGeomDisable(dGeomID geom); 397 398 399 /** 400 * @brief Check to see if a geom is enabled. 401 * 402 * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, 403 * although they can still be members of a space. New geoms are created in 404 * the enabled state. 405 * 406 * @param geom the geom to query 407 * @returns Non-zero if the geom is enabled, zero otherwise. 408 * @sa dGeomDisable 409 * @sa dGeomIsEnabled 410 * @ingroup collide 411 */ 412 int dGeomIsEnabled(dGeomID geom); 413 414 enum 415 { 416 dGeomCommonControlClass = 0, 417 dGeomColliderControlClass = 1 418 } 419 420 enum 421 { 422 dGeomCommonAnyControlCode = 0, 423 424 dGeomColliderSetMergeSphereContactsControlCode = 1, 425 dGeomColliderGetMergeSphereContactsControlCode = 2 426 } 427 428 enum 429 { 430 dGeomColliderMergeContactsValue__Default = 0, // Used with Set... to restore default value 431 dGeomColliderMergeContactsValue_None = 1, 432 dGeomColliderMergeContactsValue_Normals = 2, 433 dGeomColliderMergeContactsValue_Full = 3 434 } 435 436 /** 437 * @brief Execute low level control operation for geometry. 438 * 439 * The variable the dataSize points to must be initialized before the call. 440 * If the size does not match the one expected for the control class/code function 441 * changes it to the size expected and returns failure. This implies the function 442 * can be called with NULL data and zero size to test if control class/code is supported 443 * and obtain required data size for it. 444 * 445 * dGeomCommonAnyControlCode applies to any control class and returns success if 446 * at least one control code is available for the given class with given geom. 447 * 448 * Currently there are the folliwing control classes supported: 449 * @li dGeomColliderControlClass 450 * 451 * For dGeomColliderControlClass there are the following codes available: 452 * @li dGeomColliderSetMergeSphereContactsControlCode (arg of type int, dGeomColliderMergeContactsValue_*) 453 * @li dGeomColliderGetMergeSphereContactsControlCode (arg of type int, dGeomColliderMergeContactsValue_*) 454 * 455 * @param geom the geom to control 456 * @param controlClass the control class 457 * @param controlCode the control code for the class 458 * @param dataValue the control argument pointer 459 * @param dataSize the control argument size provided or expected 460 * @returns Boolean execution status 461 * @ingroup collide 462 */ 463 int dGeomLowLevelControl(dGeomID geom, int controlClass, int controlCode, void* dataValue, int* dataSize); 464 465 466 /** 467 * @brief Get world position of a relative point on geom. 468 * 469 * Calling this function on a non-placeable geom results in the same point being 470 * returned. 471 * 472 * @ingroup collide 473 * @param result will contain the result. 474 */ 475 void dGeomGetRelPointPos(dGeomID geom, dReal px, dReal py, dReal pz, dVector3 result); 476 477 /** 478 * @brief takes a point in global coordinates and returns 479 * the point's position in geom-relative coordinates. 480 * 481 * Calling this function on a non-placeable geom results in the same point being 482 * returned. 483 * 484 * @remarks 485 * This is the inverse of dGeomGetRelPointPos() 486 * @ingroup collide 487 * @param result will contain the result. 488 */ 489 void dGeomGetPosRelPoint(dGeomID geom, dReal px, dReal py, dReal pz, dVector3 result); 490 491 /** 492 * @brief Convert from geom-local to world coordinates. 493 * 494 * Calling this function on a non-placeable geom results in the same vector being 495 * returned. 496 * 497 * @ingroup collide 498 * @param result will contain the result. 499 */ 500 void dGeomVectorToWorld(dGeomID geom, dReal px, dReal py, dReal pz, dVector3 result); 501 502 /** 503 * @brief Convert from world to geom-local coordinates. 504 * 505 * Calling this function on a non-placeable geom results in the same vector being 506 * returned. 507 * 508 * @ingroup collide 509 * @param result will contain the result. 510 */ 511 void dGeomVectorFromWorld(dGeomID geom, dReal px, dReal py, dReal pz, dVector3 result); 512 513 514 /* ************************************************************************ */ 515 /* geom offset from body */ 516 517 /** 518 * @brief Set the local offset position of a geom from its body. 519 * 520 * Sets the geom's positional offset in local coordinates. 521 * After this call, the geom will be at a new position determined from the 522 * body's position and the offset. 523 * The geom must be attached to a body. 524 * If the geom did not have an offset, it is automatically created. 525 * 526 * @param geom the geom to set. 527 * @param x the new X coordinate. 528 * @param y the new Y coordinate. 529 * @param z the new Z coordinate. 530 * @ingroup collide 531 */ 532 void dGeomSetOffsetPosition(dGeomID geom, dReal x, dReal y, dReal z); 533 534 535 /** 536 * @brief Set the local offset rotation matrix of a geom from its body. 537 * 538 * Sets the geom's rotational offset in local coordinates. 539 * After this call, the geom will be at a new position determined from the 540 * body's position and the offset. 541 * The geom must be attached to a body. 542 * If the geom did not have an offset, it is automatically created. 543 * 544 * @param geom the geom to set. 545 * @param R the new rotation matrix. 546 * @ingroup collide 547 */ 548 void dGeomSetOffsetRotation(dGeomID geom, in dMatrix3 R); 549 550 551 /** 552 * @brief Set the local offset rotation of a geom from its body. 553 * 554 * Sets the geom's rotational offset in local coordinates. 555 * After this call, the geom will be at a new position determined from the 556 * body's position and the offset. 557 * The geom must be attached to a body. 558 * If the geom did not have an offset, it is automatically created. 559 * 560 * @param geom the geom to set. 561 * @param Q the new rotation. 562 * @ingroup collide 563 */ 564 void dGeomSetOffsetQuaternion(dGeomID geom, in dQuaternion Q); 565 566 567 /** 568 * @brief Set the offset position of a geom from its body. 569 * 570 * Sets the geom's positional offset to move it to the new world 571 * coordinates. 572 * After this call, the geom will be at the world position passed in, 573 * and the offset will be the difference from the current body position. 574 * The geom must be attached to a body. 575 * If the geom did not have an offset, it is automatically created. 576 * 577 * @param geom the geom to set. 578 * @param x the new X coordinate. 579 * @param y the new Y coordinate. 580 * @param z the new Z coordinate. 581 * @ingroup collide 582 */ 583 void dGeomSetOffsetWorldPosition(dGeomID geom, dReal x, dReal y, dReal z); 584 585 586 /** 587 * @brief Set the offset rotation of a geom from its body. 588 * 589 * Sets the geom's rotational offset to orient it to the new world 590 * rotation matrix. 591 * After this call, the geom will be at the world orientation passed in, 592 * and the offset will be the difference from the current body orientation. 593 * The geom must be attached to a body. 594 * If the geom did not have an offset, it is automatically created. 595 * 596 * @param geom the geom to set. 597 * @param R the new rotation matrix. 598 * @ingroup collide 599 */ 600 void dGeomSetOffsetWorldRotation(dGeomID geom, in dMatrix3 R); 601 602 603 /** 604 * @brief Set the offset rotation of a geom from its body. 605 * 606 * Sets the geom's rotational offset to orient it to the new world 607 * rotation matrix. 608 * After this call, the geom will be at the world orientation passed in, 609 * and the offset will be the difference from the current body orientation. 610 * The geom must be attached to a body. 611 * If the geom did not have an offset, it is automatically created. 612 * 613 * @param geom the geom to set. 614 * @param Q the new rotation. 615 * @ingroup collide 616 */ 617 void dGeomSetOffsetWorldQuaternion(dGeomID geom, in dQuaternion); 618 619 620 /** 621 * @brief Clear any offset from the geom. 622 * 623 * If the geom has an offset, it is eliminated and the geom is 624 * repositioned at the body's position. If the geom has no offset, 625 * this function does nothing. 626 * This is more efficient than calling dGeomSetOffsetPosition(zero) 627 * and dGeomSetOffsetRotation(identiy), because this function actually 628 * eliminates the offset, rather than leaving it as the identity transform. 629 * 630 * @param geom the geom to have its offset destroyed. 631 * @ingroup collide 632 */ 633 void dGeomClearOffset(dGeomID geom); 634 635 636 /** 637 * @brief Check to see whether the geom has an offset. 638 * 639 * This function will return non-zero if the offset has been created. 640 * Note that there is a difference between a geom with no offset, 641 * and a geom with an offset that is the identity transform. 642 * In the latter case, although the observed behaviour is identical, 643 * there is a unnecessary computation involved because the geom will 644 * be applying the transform whenever it needs to recalculate its world 645 * position. 646 * 647 * @param geom the geom to query. 648 * @returns Non-zero if the geom has an offset, zero otherwise. 649 * @ingroup collide 650 */ 651 int dGeomIsOffset(dGeomID geom); 652 653 654 /** 655 * @brief Get the offset position vector of a geom. 656 * 657 * Returns the positional offset of the geom in local coordinates. 658 * If the geom has no offset, this function returns the zero vector. 659 * 660 * @param geom the geom to query. 661 * @returns A pointer to the geom's offset vector. 662 * @remarks The returned value is a pointer to the geom's internal 663 * data structure. It is valid until any changes are made 664 * to the geom. 665 * @ingroup collide 666 */ 667 const(dReal)* dGeomGetOffsetPosition(dGeomID geom); 668 669 670 /** 671 * @brief Copy the offset position vector of a geom. 672 * 673 * Returns the positional offset of the geom in local coordinates. 674 * If the geom has no offset, this function returns the zero vector. 675 * 676 * @param geom the geom to query. 677 * @param pos returns the offset position 678 * @ingroup collide 679 */ 680 void dGeomCopyOffsetPosition(dGeomID geom, dVector3 pos); 681 682 683 /** 684 * @brief Get the offset rotation matrix of a geom. 685 * 686 * Returns the rotational offset of the geom in local coordinates. 687 * If the geom has no offset, this function returns the identity 688 * matrix. 689 * 690 * @param geom the geom to query. 691 * @returns A pointer to the geom's offset rotation matrix. 692 * @remarks The returned value is a pointer to the geom's internal 693 * data structure. It is valid until any changes are made 694 * to the geom. 695 * @ingroup collide 696 */ 697 const(dReal)* dGeomGetOffsetRotation(dGeomID geom); 698 699 700 /** 701 * @brief Copy the offset rotation matrix of a geom. 702 * 703 * Returns the rotational offset of the geom in local coordinates. 704 * If the geom has no offset, this function returns the identity 705 * matrix. 706 * 707 * @param geom the geom to query. 708 * @param R returns the rotation matrix. 709 * @ingroup collide 710 */ 711 void dGeomCopyOffsetRotation(dGeomID geom, dMatrix3 R); 712 713 714 /** 715 * @brief Get the offset rotation quaternion of a geom. 716 * 717 * Returns the rotation offset of the geom as a quaternion. 718 * If the geom has no offset, the identity quaternion is returned. 719 * 720 * @param geom the geom to query. 721 * @param result a copy of the rotation quaternion. 722 * @ingroup collide 723 */ 724 void dGeomGetOffsetQuaternion(dGeomID geom, dQuaternion result); 725 726 727 /* ************************************************************************ */ 728 /* collision detection */ 729 730 /* 731 * Just generate any contacts (disables any contact refining). 732 */ 733 enum CONTACTS_UNIMPORTANT = 0x80000000; 734 735 /** 736 * 737 * @brief Given two geoms o1 and o2 that potentially intersect, 738 * generate contact information for them. 739 * 740 * Internally, this just calls the correct class-specific collision 741 * functions for o1 and o2. 742 * 743 * @param o1 The first geom to test. 744 * @param o2 The second geom to test. 745 * 746 * @param flags The flags specify how contacts should be generated if 747 * the geoms touch. The lower 16 bits of flags is an integer that 748 * specifies the maximum number of contact points to generate. You must 749 * ask for at least one contact. 750 * Additionally, following bits may be set: 751 * CONTACTS_UNIMPORTANT -- just generate any contacts (skip contact refining). 752 * All other bits in flags must be set to zero. In the future the other bits 753 * may be used to select from different contact generation strategies. 754 * 755 * @param contact Points to an array of dContactGeom structures. The array 756 * must be able to hold at least the maximum number of contacts. These 757 * dContactGeom structures may be embedded within larger structures in the 758 * array -- the skip parameter is the byte offset from one dContactGeom to 759 * the next in the array. If skip is sizeof(dContactGeom) then contact 760 * points to a normal (C-style) array. It is an error for skip to be smaller 761 * than sizeof(dContactGeom). 762 * 763 * @returns If the geoms intersect, this function returns the number of contact 764 * points generated (and updates the contact array), otherwise it returns 0 765 * (and the contact array is not touched). 766 * 767 * @remarks If a space is passed as o1 or o2 then this function will collide 768 * all objects contained in o1 with all objects contained in o2, and return 769 * the resulting contact points. This method for colliding spaces with geoms 770 * (or spaces with spaces) provides no user control over the individual 771 * collisions. To get that control, use dSpaceCollide or dSpaceCollide2 instead. 772 * 773 * @remarks If o1 and o2 are the same geom then this function will do nothing 774 * and return 0. Technically speaking an object intersects with itself, but it 775 * is not useful to find contact points in this case. 776 * 777 * @remarks This function does not care if o1 and o2 are in the same space or not 778 * (or indeed if they are in any space at all). 779 * 780 * @ingroup collide 781 */ 782 int dCollide(dGeomID o1, dGeomID o2, int flags, dContactGeom* contact, int skip); 783 784 /** 785 * @brief Determines which pairs of geoms in a space may potentially intersect, 786 * and calls the callback function for each candidate pair. 787 * 788 * @param space The space to test. 789 * 790 * @param data Passed from dSpaceCollide directly to the callback 791 * function. Its meaning is user defined. The o1 and o2 arguments are the 792 * geoms that may be near each other. 793 * 794 * @param callback A callback function is of type @ref dNearCallback. 795 * 796 * @remarks Other spaces that are contained within the colliding space are 797 * not treated specially, i.e. they are not recursed into. The callback 798 * function may be passed these contained spaces as one or both geom 799 * arguments. 800 * 801 * @remarks dSpaceCollide() is guaranteed to pass all intersecting geom 802 * pairs to the callback function, but may also pass close but 803 * non-intersecting pairs. The number of these calls depends on the 804 * internal algorithms used by the space. Thus you should not expect 805 * that dCollide will return contacts for every pair passed to the 806 * callback. 807 * 808 * @sa dSpaceCollide2 809 * @ingroup collide 810 */ 811 void dSpaceCollide(dSpaceID space, void* data, dNearCallback* callback); 812 813 814 /** 815 * @brief Determines which geoms from one space may potentially intersect with 816 * geoms from another space, and calls the callback function for each candidate 817 * pair. 818 * 819 * @param space1 The first space to test. 820 * 821 * @param space2 The second space to test. 822 * 823 * @param data Passed from dSpaceCollide directly to the callback 824 * function. Its meaning is user defined. The o1 and o2 arguments are the 825 * geoms that may be near each other. 826 * 827 * @param callback A callback function is of type @ref dNearCallback. 828 * 829 * @remarks This function can also test a single non-space geom against a 830 * space. This function is useful when there is a collision hierarchy, i.e. 831 * when there are spaces that contain other spaces. 832 * 833 * @remarks Other spaces that are contained within the colliding space are 834 * not treated specially, i.e. they are not recursed into. The callback 835 * function may be passed these contained spaces as one or both geom 836 * arguments. 837 * 838 * @remarks Sublevel value of space affects how the spaces are iterated. 839 * Both spaces are recursed only if their sublevels match. Otherwise, only 840 * the space with greater sublevel is recursed and the one with lesser sublevel 841 * is used as a geom itself. 842 * 843 * @remarks dSpaceCollide2() is guaranteed to pass all intersecting geom 844 * pairs to the callback function, but may also pass close but 845 * non-intersecting pairs. The number of these calls depends on the 846 * internal algorithms used by the space. Thus you should not expect 847 * that dCollide will return contacts for every pair passed to the 848 * callback. 849 * 850 * @sa dSpaceCollide 851 * @sa dSpaceSetSublevel 852 * @ingroup collide 853 */ 854 void dSpaceCollide2(dGeomID space1, dGeomID space2, void* data, dNearCallback* callback); 855 856 857 /* ************************************************************************ */ 858 /* standard classes */ 859 860 /* the maximum number of user classes that are supported */ 861 enum dMaxUserClasses = 4; 862 863 /* class numbers - each geometry object needs a unique number */ 864 enum 865 { 866 dSphereClass = 0, 867 dBoxClass, 868 dCapsuleClass, 869 dCylinderClass, 870 dPlaneClass, 871 dRayClass, 872 dConvexClass, 873 dGeomTransformClass, 874 dTriMeshClass, 875 dHeightFieldClass, 876 877 dFirstSpaceClass, 878 dSimpleSpaceClass = dFirstSpaceClass, 879 dHashSpaceClass, 880 dSweepAndPruneSpaceClass, // SAP 881 dQuadTreeClass, 882 dLastSpaceClass = dQuadTreeClass, 883 884 dFirstUserClass, 885 dLastUserClass = dFirstUserClass + dMaxUserClasses - 1, 886 dGeomNumClasses 887 } 888 889 890 /** 891 * @defgroup collide_sphere Sphere Class 892 * @ingroup collide 893 */ 894 895 /** 896 * @brief Create a sphere geom of the given radius, and return its ID. 897 * 898 * @param space a space to contain the new geom. May be null. 899 * @param radius the radius of the sphere. 900 * 901 * @returns A new sphere geom. 902 * 903 * @remarks The point of reference for a sphere is its center. 904 * 905 * @sa dGeomDestroy 906 * @sa dGeomSphereSetRadius 907 * @ingroup collide_sphere 908 */ 909 dGeomID dCreateSphere(dSpaceID space, dReal radius); 910 911 912 /** 913 * @brief Set the radius of a sphere geom. 914 * 915 * @param sphere the sphere to set. 916 * @param radius the new radius. 917 * 918 * @sa dGeomSphereGetRadius 919 * @ingroup collide_sphere 920 */ 921 void dGeomSphereSetRadius(dGeomID sphere, dReal radius); 922 923 924 /** 925 * @brief Retrieves the radius of a sphere geom. 926 * 927 * @param sphere the sphere to query. 928 * 929 * @sa dGeomSphereSetRadius 930 * @ingroup collide_sphere 931 */ 932 dReal dGeomSphereGetRadius(dGeomID sphere); 933 934 935 /** 936 * @brief Calculate the depth of the a given point within a sphere. 937 * 938 * @param sphere the sphere to query. 939 * @param x the X coordinate of the point. 940 * @param y the Y coordinate of the point. 941 * @param z the Z coordinate of the point. 942 * 943 * @returns The depth of the point. Points inside the sphere will have a 944 * positive depth, points outside it will have a negative depth, and points 945 * on the surface will have a depth of zero. 946 * 947 * @ingroup collide_sphere 948 */ 949 dReal dGeomSpherePointDepth(dGeomID sphere, dReal x, dReal y, dReal z); 950 951 952 //--> Convex Functions 953 dGeomID dCreateConvex( 954 dSpaceID space, dReal* _planes, uint _planecount, dReal* _points, 955 uint _pointcount, uint* _polygons 956 ); 957 958 void dGeomSetConvex( 959 dGeomID g, dReal* _planes, uint _count, dReal* _points, 960 uint _pointcount, uint* _polygons 961 ); 962 //<-- Convex Functions 963 964 /** 965 * @defgroup collide_box Box Class 966 * @ingroup collide 967 */ 968 969 /** 970 * @brief Create a box geom with the provided side lengths. 971 * 972 * @param space a space to contain the new geom. May be null. 973 * @param lx the length of the box along the X axis 974 * @param ly the length of the box along the Y axis 975 * @param lz the length of the box along the Z axis 976 * 977 * @returns A new box geom. 978 * 979 * @remarks The point of reference for a box is its center. 980 * 981 * @sa dGeomDestroy 982 * @sa dGeomBoxSetLengths 983 * @ingroup collide_box 984 */ 985 dGeomID dCreateBox(dSpaceID space, dReal lx, dReal ly, dReal lz); 986 987 988 /** 989 * @brief Set the side lengths of the given box. 990 * 991 * @param box the box to set 992 * @param lx the length of the box along the X axis 993 * @param ly the length of the box along the Y axis 994 * @param lz the length of the box along the Z axis 995 * 996 * @sa dGeomBoxGetLengths 997 * @ingroup collide_box 998 */ 999 void dGeomBoxSetLengths(dGeomID box, dReal lx, dReal ly, dReal lz); 1000 1001 1002 /** 1003 * @brief Get the side lengths of a box. 1004 * 1005 * @param box the box to query 1006 * @param result the returned side lengths 1007 * 1008 * @sa dGeomBoxSetLengths 1009 * @ingroup collide_box 1010 */ 1011 void dGeomBoxGetLengths(dGeomID box, dVector3 result); 1012 1013 1014 /** 1015 * @brief Return the depth of a point in a box. 1016 * 1017 * @param box the box to query 1018 * @param x the X coordinate of the point to test. 1019 * @param y the Y coordinate of the point to test. 1020 * @param z the Z coordinate of the point to test. 1021 * 1022 * @returns The depth of the point. Points inside the box will have a 1023 * positive depth, points outside it will have a negative depth, and points 1024 * on the surface will have a depth of zero. 1025 */ 1026 dReal dGeomBoxPointDepth(dGeomID box, dReal x, dReal y, dReal z); 1027 1028 1029 dGeomID dCreatePlane(dSpaceID space, dReal a, dReal b, dReal c, dReal d); 1030 void dGeomPlaneSetParams(dGeomID plane, dReal a, dReal b, dReal c, dReal d); 1031 void dGeomPlaneGetParams(dGeomID plane, dVector4 result); 1032 dReal dGeomPlanePointDepth(dGeomID plane, dReal x, dReal y, dReal z); 1033 1034 dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length); 1035 void dGeomCapsuleSetParams (dGeomID ccylinder, dReal radius, dReal length); 1036 void dGeomCapsuleGetParams (dGeomID ccylinder, dReal* radius, dReal* length); 1037 dReal dGeomCapsulePointDepth (dGeomID ccylinder, dReal x, dReal y, dReal z); 1038 1039 // For now we want to have a backwards compatible C-API, note: C++ API is not. 1040 alias dCreateCapsule dCreateCCylinder; 1041 alias dGeomCapsuleSetParams dGeomCCylinderSetParams; 1042 alias dGeomCapsuleGetParams dGeomCCylinderGetParams; 1043 alias dGeomCapsulePointDepth dGeomCCylinderPointDepth; 1044 alias dCapsuleClass dCCylinderClass; 1045 1046 dGeomID dCreateCylinder(dSpaceID space, dReal radius, dReal length); 1047 void dGeomCylinderSetParams(dGeomID cylinder, dReal radius, dReal length); 1048 void dGeomCylinderGetParams(dGeomID cylinder, dReal* radius, dReal* length); 1049 1050 dGeomID dCreateRay(dSpaceID space, dReal length); 1051 void dGeomRaySetLength(dGeomID ray, dReal length); 1052 dReal dGeomRayGetLength(dGeomID ray); 1053 void dGeomRaySet(dGeomID ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz); 1054 void dGeomRayGet(dGeomID ray, dVector3 start, dVector3 dir); 1055 1056 /* 1057 * Set/get ray flags that influence ray collision detection. 1058 * These flags are currently only noticed by the trimesh collider, because 1059 * they can make a major differences there. 1060 */ 1061 void dGeomRaySetParams(dGeomID g, int FirstContact, int BackfaceCull); 1062 void dGeomRayGetParams(dGeomID g, int* FirstContact, int* BackfaceCull); 1063 void dGeomRaySetClosestHit(dGeomID g, int closestHit); 1064 int dGeomRayGetClosestHit(dGeomID g); 1065 1066 public import deimos.ode.collision_trimesh; 1067 1068 dGeomID dCreateGeomTransform(dSpaceID space); 1069 void dGeomTransformSetGeom(dGeomID g, dGeomID obj); 1070 dGeomID dGeomTransformGetGeom(dGeomID g); 1071 void dGeomTransformSetCleanup(dGeomID g, int mode); 1072 int dGeomTransformGetCleanup(dGeomID g); 1073 void dGeomTransformSetInfo(dGeomID g, int mode); 1074 int dGeomTransformGetInfo(dGeomID g); 1075 1076 /* ************************************************************************ */ 1077 /* heightfield functions */ 1078 1079 // Data storage for heightfield data. 1080 struct dxHeightfieldData; 1081 alias dxHeightfieldData* dHeightfieldDataID; 1082 1083 /** 1084 * @brief Callback prototype 1085 * 1086 * Used by the callback heightfield data type to sample a height for a 1087 * given cell position. 1088 * 1089 * @param p_user_data User data specified when creating the dHeightfieldDataID 1090 * @param x The index of a sample in the local x axis. It is a value 1091 * in the range zero to ( nWidthSamples - 1 ). 1092 * @param x The index of a sample in the local z axis. It is a value 1093 * in the range zero to ( nDepthSamples - 1 ). 1094 * 1095 * @return The sample height which is then scaled and offset using the 1096 * values specified when the heightfield data was created. 1097 * 1098 * @ingroup collide 1099 */ 1100 alias dReal function(void* p_user_data, int x, int z) dHeightfieldGetHeight; 1101 1102 /** 1103 * @brief Creates a heightfield geom. 1104 * 1105 * Uses the information in the given dHeightfieldDataID to construct 1106 * a geom representing a heightfield in a collision space. 1107 * 1108 * @param space The space to add the geom to. 1109 * @param data The dHeightfieldDataID created by dGeomHeightfieldDataCreate and 1110 * setup by dGeomHeightfieldDataBuildCallback, dGeomHeightfieldDataBuildByte, 1111 * dGeomHeightfieldDataBuildShort or dGeomHeightfieldDataBuildFloat. 1112 * @param bPlaceable If non-zero this geom can be transformed in the world using the 1113 * usual functions such as dGeomSetPosition and dGeomSetRotation. If the geom is 1114 * not set as placeable, then it uses a fixed orientation where the global y axis 1115 * represents the dynamic 'height' of the heightfield. 1116 * 1117 * @return A geom id to reference this geom in other calls. 1118 * 1119 * @ingroup collide 1120 */ 1121 dGeomID dCreateHeightfield(dSpaceID space, dHeightfieldDataID data, int bPlaceable); 1122 1123 /** 1124 * @brief Creates a new empty dHeightfieldDataID. 1125 * 1126 * Allocates a new dHeightfieldDataID and returns it. You must call 1127 * dGeomHeightfieldDataDestroy to destroy it after the geom has been removed. 1128 * The dHeightfieldDataID value is used when specifying a data format type. 1129 * 1130 * @return A dHeightfieldDataID for use with dGeomHeightfieldDataBuildCallback, 1131 * dGeomHeightfieldDataBuildByte, dGeomHeightfieldDataBuildShort or 1132 * dGeomHeightfieldDataBuildFloat. 1133 * @ingroup collide 1134 */ 1135 dHeightfieldDataID dGeomHeightfieldDataCreate(); 1136 1137 /** 1138 * @brief Destroys a dHeightfieldDataID. 1139 * 1140 * Deallocates a given dHeightfieldDataID and all managed resources. 1141 * 1142 * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate 1143 * @ingroup collide 1144 */ 1145 void dGeomHeightfieldDataDestroy(dHeightfieldDataID d); 1146 1147 /** 1148 * @brief Configures a dHeightfieldDataID to use a callback to 1149 * retrieve height data. 1150 * 1151 * Before a dHeightfieldDataID can be used by a geom it must be 1152 * configured to specify the format of the height data. 1153 * This call specifies that the heightfield data is computed by 1154 * the user and it should use the given callback when determining 1155 * the height of a given element of it's shape. 1156 * 1157 * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate 1158 * 1159 * @param width Specifies the total 'width' of the heightfield along 1160 * the geom's local x axis. 1161 * @param depth Specifies the total 'depth' of the heightfield along 1162 * the geom's local z axis. 1163 * 1164 * @param widthSamples Specifies the number of vertices to sample 1165 * along the width of the heightfield. Each vertex has a corresponding 1166 * height value which forms the overall shape. 1167 * Naturally this value must be at least two or more. 1168 * @param depthSamples Specifies the number of vertices to sample 1169 * along the depth of the heightfield. 1170 * 1171 * @param scale A uniform scale applied to all raw height data. 1172 * @param offset An offset applied to the scaled height data. 1173 * 1174 * @param thickness A value subtracted from the lowest height 1175 * value which in effect adds an additional cuboid to the base of the 1176 * heightfield. This is used to prevent geoms from looping under the 1177 * desired terrain and not registering as a collision. Note that the 1178 * thickness is not affected by the scale or offset parameters. 1179 * 1180 * @param bWrap If non-zero the heightfield will infinitely tile in both 1181 * directions along the local x and z axes. If zero the heightfield is 1182 * bounded from zero to width in the local x axis, and zero to depth in 1183 * the local z axis. 1184 * 1185 * @ingroup collide 1186 */ 1187 void dGeomHeightfieldDataBuildCallback( 1188 dHeightfieldDataID d, void* pUserData, dHeightfieldGetHeight pCallback, 1189 dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, 1190 dReal offset, dReal thickness, int bWrap 1191 ); 1192 1193 /** 1194 * @brief Configures a dHeightfieldDataID to use height data in byte format. 1195 * 1196 * Before a dHeightfieldDataID can be used by a geom it must be 1197 * configured to specify the format of the height data. 1198 * This call specifies that the heightfield data is stored as a rectangular 1199 * array of bytes (8 bit unsigned) representing the height at each sample point. 1200 * 1201 * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate 1202 * 1203 * @param pHeightData A pointer to the height data. 1204 * @param bCopyHeightData When non-zero the height data is copied to an 1205 * internal store. When zero the height data is accessed by reference and 1206 * so must persist throughout the lifetime of the heightfield. 1207 * 1208 * @param width Specifies the total 'width' of the heightfield along 1209 * the geom's local x axis. 1210 * @param depth Specifies the total 'depth' of the heightfield along 1211 * the geom's local z axis. 1212 * 1213 * @param widthSamples Specifies the number of vertices to sample 1214 * along the width of the heightfield. Each vertex has a corresponding 1215 * height value which forms the overall shape. 1216 * Naturally this value must be at least two or more. 1217 * @param depthSamples Specifies the number of vertices to sample 1218 * along the depth of the heightfield. 1219 * 1220 * @param scale A uniform scale applied to all raw height data. 1221 * @param offset An offset applied to the scaled height data. 1222 * 1223 * @param thickness A value subtracted from the lowest height 1224 * value which in effect adds an additional cuboid to the base of the 1225 * heightfield. This is used to prevent geoms from looping under the 1226 * desired terrain and not registering as a collision. Note that the 1227 * thickness is not affected by the scale or offset parameters. 1228 * 1229 * @param bWrap If non-zero the heightfield will infinitely tile in both 1230 * directions along the local x and z axes. If zero the heightfield is 1231 * bounded from zero to width in the local x axis, and zero to depth in 1232 * the local z axis. 1233 * 1234 * @ingroup collide 1235 */ 1236 void dGeomHeightfieldDataBuildByte( 1237 dHeightfieldDataID d, in ubyte* pHeightData, int bCopyHeightData, 1238 dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, 1239 dReal offset, dReal thickness, int bWrap 1240 ); 1241 1242 /** 1243 * @brief Configures a dHeightfieldDataID to use height data in short format. 1244 * 1245 * Before a dHeightfieldDataID can be used by a geom it must be 1246 * configured to specify the format of the height data. 1247 * This call specifies that the heightfield data is stored as a rectangular 1248 * array of shorts (16 bit signed) representing the height at each sample point. 1249 * 1250 * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate 1251 * 1252 * @param pHeightData A pointer to the height data. 1253 * @param bCopyHeightData When non-zero the height data is copied to an 1254 * internal store. When zero the height data is accessed by reference and 1255 * so must persist throughout the lifetime of the heightfield. 1256 * 1257 * @param width Specifies the total 'width' of the heightfield along 1258 * the geom's local x axis. 1259 * @param depth Specifies the total 'depth' of the heightfield along 1260 * the geom's local z axis. 1261 * 1262 * @param widthSamples Specifies the number of vertices to sample 1263 * along the width of the heightfield. Each vertex has a corresponding 1264 * height value which forms the overall shape. 1265 * Naturally this value must be at least two or more. 1266 * @param depthSamples Specifies the number of vertices to sample 1267 * along the depth of the heightfield. 1268 * 1269 * @param scale A uniform scale applied to all raw height data. 1270 * @param offset An offset applied to the scaled height data. 1271 * 1272 * @param thickness A value subtracted from the lowest height 1273 * value which in effect adds an additional cuboid to the base of the 1274 * heightfield. This is used to prevent geoms from looping under the 1275 * desired terrain and not registering as a collision. Note that the 1276 * thickness is not affected by the scale or offset parameters. 1277 * 1278 * @param bWrap If non-zero the heightfield will infinitely tile in both 1279 * directions along the local x and z axes. If zero the heightfield is 1280 * bounded from zero to width in the local x axis, and zero to depth in 1281 * the local z axis. 1282 * 1283 * @ingroup collide 1284 */ 1285 void dGeomHeightfieldDataBuildShort( 1286 dHeightfieldDataID d, in short* pHeightData, int bCopyHeightData, 1287 dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, 1288 dReal offset, dReal thickness, int bWrap 1289 ); 1290 1291 /** 1292 * @brief Configures a dHeightfieldDataID to use height data in 1293 * single precision floating point format. 1294 * 1295 * Before a dHeightfieldDataID can be used by a geom it must be 1296 * configured to specify the format of the height data. 1297 * This call specifies that the heightfield data is stored as a rectangular 1298 * array of single precision floats representing the height at each 1299 * sample point. 1300 * 1301 * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate 1302 * 1303 * @param pHeightData A pointer to the height data. 1304 * @param bCopyHeightData When non-zero the height data is copied to an 1305 * internal store. When zero the height data is accessed by reference and 1306 * so must persist throughout the lifetime of the heightfield. 1307 * 1308 * @param width Specifies the total 'width' of the heightfield along 1309 * the geom's local x axis. 1310 * @param depth Specifies the total 'depth' of the heightfield along 1311 * the geom's local z axis. 1312 * 1313 * @param widthSamples Specifies the number of vertices to sample 1314 * along the width of the heightfield. Each vertex has a corresponding 1315 * height value which forms the overall shape. 1316 * Naturally this value must be at least two or more. 1317 * @param depthSamples Specifies the number of vertices to sample 1318 * along the depth of the heightfield. 1319 * 1320 * @param scale A uniform scale applied to all raw height data. 1321 * @param offset An offset applied to the scaled height data. 1322 * 1323 * @param thickness A value subtracted from the lowest height 1324 * value which in effect adds an additional cuboid to the base of the 1325 * heightfield. This is used to prevent geoms from looping under the 1326 * desired terrain and not registering as a collision. Note that the 1327 * thickness is not affected by the scale or offset parameters. 1328 * 1329 * @param bWrap If non-zero the heightfield will infinitely tile in both 1330 * directions along the local x and z axes. If zero the heightfield is 1331 * bounded from zero to width in the local x axis, and zero to depth in 1332 * the local z axis. 1333 * 1334 * @ingroup collide 1335 */ 1336 void dGeomHeightfieldDataBuildSingle( 1337 dHeightfieldDataID d, in float* pHeightData, int bCopyHeightData, 1338 dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, 1339 dReal offset, dReal thickness, int bWrap 1340 ); 1341 1342 /** 1343 * @brief Configures a dHeightfieldDataID to use height data in 1344 * double precision floating point format. 1345 * 1346 * Before a dHeightfieldDataID can be used by a geom it must be 1347 * configured to specify the format of the height data. 1348 * This call specifies that the heightfield data is stored as a rectangular 1349 * array of double precision floats representing the height at each 1350 * sample point. 1351 * 1352 * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate 1353 * 1354 * @param pHeightData A pointer to the height data. 1355 * @param bCopyHeightData When non-zero the height data is copied to an 1356 * internal store. When zero the height data is accessed by reference and 1357 * so must persist throughout the lifetime of the heightfield. 1358 * 1359 * @param width Specifies the total 'width' of the heightfield along 1360 * the geom's local x axis. 1361 * @param depth Specifies the total 'depth' of the heightfield along 1362 * the geom's local z axis. 1363 * 1364 * @param widthSamples Specifies the number of vertices to sample 1365 * along the width of the heightfield. Each vertex has a corresponding 1366 * height value which forms the overall shape. 1367 * Naturally this value must be at least two or more. 1368 * @param depthSamples Specifies the number of vertices to sample 1369 * along the depth of the heightfield. 1370 * 1371 * @param scale A uniform scale applied to all raw height data. 1372 * @param offset An offset applied to the scaled height data. 1373 * 1374 * @param thickness A value subtracted from the lowest height 1375 * value which in effect adds an additional cuboid to the base of the 1376 * heightfield. This is used to prevent geoms from looping under the 1377 * desired terrain and not registering as a collision. Note that the 1378 * thickness is not affected by the scale or offset parameters. 1379 * 1380 * @param bWrap If non-zero the heightfield will infinitely tile in both 1381 * directions along the local x and z axes. If zero the heightfield is 1382 * bounded from zero to width in the local x axis, and zero to depth in 1383 * the local z axis. 1384 * 1385 * @ingroup collide 1386 */ 1387 void dGeomHeightfieldDataBuildDouble( 1388 dHeightfieldDataID d, in double* pHeightData, int bCopyHeightData, 1389 dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, 1390 dReal offset, dReal thickness, int bWrap 1391 ); 1392 1393 /** 1394 * @brief Manually set the minimum and maximum height bounds. 1395 * 1396 * This call allows you to set explicit min / max values after initial 1397 * creation typically for callback heightfields which default to +/- infinity, 1398 * or those whose data has changed. This must be set prior to binding with a 1399 * geom, as the the AABB is not recomputed after it's first generation. 1400 * 1401 * @remarks The minimum and maximum values are used to compute the AABB 1402 * for the heightfield which is used for early rejection of collisions. 1403 * A close fit will yield a more efficient collision check. 1404 * 1405 * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate 1406 * @param min_height The new minimum height value. Scale, offset and thickness is then applied. 1407 * @param max_height The new maximum height value. Scale and offset is then applied. 1408 * @ingroup collide 1409 */ 1410 void dGeomHeightfieldDataSetBounds(dHeightfieldDataID d, dReal minHeight, dReal maxHeight); 1411 1412 1413 /** 1414 * @brief Assigns a dHeightfieldDataID to a heightfield geom. 1415 * 1416 * Associates the given dHeightfieldDataID with a heightfield geom. 1417 * This is done without affecting the GEOM_PLACEABLE flag. 1418 * 1419 * @param g A geom created by dCreateHeightfield 1420 * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate 1421 * @ingroup collide 1422 */ 1423 void dGeomHeightfieldSetHeightfieldData(dGeomID g, dHeightfieldDataID d); 1424 1425 1426 /** 1427 * @brief Gets the dHeightfieldDataID bound to a heightfield geom. 1428 * 1429 * Returns the dHeightfieldDataID associated with a heightfield geom. 1430 * 1431 * @param g A geom created by dCreateHeightfield 1432 * @return The dHeightfieldDataID which may be NULL if none was assigned. 1433 * @ingroup collide 1434 */ 1435 dHeightfieldDataID dGeomHeightfieldGetHeightfieldData(dGeomID g); 1436 1437 1438 1439 /* ************************************************************************ */ 1440 /* utility functions */ 1441 1442 void dClosestLineSegmentPoints( 1443 in dVector3 a1, in dVector3 a2, 1444 in dVector3 b1, in dVector3 b2, 1445 dVector3 cp1, dVector3 cp2 1446 ); 1447 1448 int dBoxTouchesBox( 1449 in dVector3 _p1, in dMatrix3 R1, in dVector3 side1, in dVector3 _p2, 1450 in dMatrix3 R2, in dVector3 side2 1451 ); 1452 1453 // The meaning of flags parameter is the same as in dCollide() 1454 int dBoxBox( 1455 in dVector3 p1, in dMatrix3 R1, in dVector3 side1, in dVector3 p2, 1456 in dMatrix3 R2, in dVector3 side2, dVector3 normal, dReal* depth, 1457 int* return_code, int flags, dContactGeom* contact, int skip 1458 ); 1459 1460 void dInfiniteAABB(dGeomID geom, ref dReal[6] aabb); 1461 1462 1463 /* ************************************************************************ */ 1464 /* custom classes */ 1465 1466 alias void function(dGeomID, ref dReal[6] aabb) dGetAABBFn; 1467 alias int function( 1468 dGeomID o1, dGeomID o2, int flags, dContactGeom* contact, int skip 1469 ) dColliderFn; 1470 alias dColliderFn function(int num) dGetColliderFnFn; 1471 alias void function(dGeomID o) dGeomDtorFn; 1472 alias int function(dGeomID o1, dGeomID o2, ref dReal[6] aabb) dAABBTestFn; 1473 1474 struct dGeomClass 1475 { 1476 int bytes; 1477 dGetColliderFnFn collider; 1478 dGetAABBFn aabb; 1479 dAABBTestFn aabb_test; 1480 dGeomDtorFn dtor; 1481 } 1482 1483 int dCreateGeomClass(in dGeomClass* classptr); 1484 void* dGeomGetClassData(dGeomID); 1485 dGeomID dCreateGeom(int classnum); 1486 1487 /** 1488 * @brief Sets a custom collider function for two geom classes. 1489 * 1490 * @param i The first geom class handled by this collider 1491 * @param j The second geom class handled by this collider 1492 * @param fn The collider function to use to determine collisions. 1493 * @ingroup collide 1494 */ 1495 void dSetColliderOverride (int i, int j, dColliderFn* fn);