Dropped Newton in favour of ODE which was simple to build and get running on both windows and linux

dev
Shariq Shah 8 years ago
parent ac12a48b8a
commit 9b8bc3f241
  1. 14
      README.md
  2. 14
      assets/config.cfg
  3. 11
      assets/ground.ent
  4. 15
      assets/keybindings.cfg
  5. 19
      assets/light.ent
  6. 15
      assets/player.ent
  7. 272
      assets/test.symtres
  8. 26
      build/genie.lua
  9. 1316
      include/common/newton/Newton.h
  10. 1526
      include/linux/ode/collision.h
  11. 182
      include/linux/ode/collision_space.h
  12. 316
      include/linux/ode/collision_trimesh.h
  13. 568
      include/linux/ode/common.h
  14. 40
      include/linux/ode/compatibility.h
  15. 110
      include/linux/ode/contact.h
  16. 229
      include/linux/ode/cooperative.h
  17. 63
      include/linux/ode/error.h
  18. 40
      include/linux/ode/export-dif.h
  19. 144
      include/linux/ode/mass.h
  20. 200
      include/linux/ode/matrix.h
  21. 291
      include/linux/ode/matrix_coop.h
  22. 59
      include/linux/ode/memory.h
  23. 86
      include/linux/ode/misc.h
  24. 3396
      include/linux/ode/objects.h
  25. 56
      include/linux/ode/ode.h
  26. 215
      include/linux/ode/odeconfig.h
  27. 1355
      include/linux/ode/odecpp.h
  28. 467
      include/linux/ode/odecpp_collision.h
  29. 236
      include/linux/ode/odeinit.h
  30. 545
      include/linux/ode/odemath.h
  31. 162
      include/linux/ode/odemath_legacy.h
  32. 16
      include/linux/ode/precision.h
  33. 70
      include/linux/ode/rotation.h
  34. 412
      include/linux/ode/threading.h
  35. 292
      include/linux/ode/threading_impl.h
  36. 76
      include/linux/ode/timer.h
  37. 6
      include/linux/ode/version.h
  38. 1526
      include/windows/ode/collision.h
  39. 182
      include/windows/ode/collision_space.h
  40. 316
      include/windows/ode/collision_trimesh.h
  41. 568
      include/windows/ode/common.h
  42. 40
      include/windows/ode/compatibility.h
  43. 110
      include/windows/ode/contact.h
  44. 229
      include/windows/ode/cooperative.h
  45. 63
      include/windows/ode/error.h
  46. 40
      include/windows/ode/export-dif.h
  47. 144
      include/windows/ode/mass.h
  48. 200
      include/windows/ode/matrix.h
  49. 291
      include/windows/ode/matrix_coop.h
  50. 59
      include/windows/ode/memory.h
  51. 86
      include/windows/ode/misc.h
  52. 3396
      include/windows/ode/objects.h
  53. 56
      include/windows/ode/ode.h
  54. 215
      include/windows/ode/odeconfig.h
  55. 1355
      include/windows/ode/odecpp.h
  56. 467
      include/windows/ode/odecpp_collision.h
  57. 236
      include/windows/ode/odeinit.h
  58. 545
      include/windows/ode/odemath.h
  59. 162
      include/windows/ode/odemath_legacy.h
  60. 16
      include/windows/ode/precision.h
  61. 70
      include/windows/ode/rotation.h
  62. 412
      include/windows/ode/threading.h
  63. 292
      include/windows/ode/threading_impl.h
  64. 76
      include/windows/ode/timer.h
  65. 6
      include/windows/ode/version.h
  66. BIN
      lib/linux/ode/libode.so
  67. 2
      lib/linux/sdl2/libSDL2-2.0.so.0
  68. 1
      lib/linux/sdl2/libSDL2.so
  69. BIN
      lib/linux/sdl2/libSDL2.so
  70. BIN
      lib/windows/newton/newton.dll
  71. BIN
      lib/windows/newton/newton.exp
  72. BIN
      lib/windows/newton/newton.lib
  73. BIN
      lib/windows/newton/newton_d.dll
  74. BIN
      lib/windows/newton/newton_d.exp
  75. BIN
      lib/windows/newton/newton_d.lib
  76. BIN
      lib/windows/newton/newton_d.pdb
  77. BIN
      lib/windows/ode/ode_double.dll
  78. BIN
      lib/windows/ode/ode_double.lib
  79. BIN
      lib/windows/ode/ode_doubled.dll
  80. BIN
      lib/windows/ode/ode_doubled.lib
  81. BIN
      lib/windows/ode/ode_doubled.pdb
  82. 19
      src/common/common.h
  83. 15
      src/game/main.c
  84. 176
      src/game/physics.c
  85. 21
      src/game/physics.h
  86. 36
      src/libsymmetry/game.c

@ -155,7 +155,19 @@
- ## TODO
- Complete Newton integration
- Trimesh support
- Debug physics mesh drawing
- Serializing/Deserializing physics data
- Proper physics time-step and speed
- Storing entity reference/id in rigidbody
- Storing rigidbody in entity
- Expose complete physics api with forces/joints etc
- Complete ODE integration
- Test physics code on linux
- Terrain rendering using heightfields
- Re-order lib folder for linux by putting all libraries in one folder
- Figure out a better way for handling libs on linux, current method DOES NOT work on other computers
- Fix 30fps bug on windows
- Add fallback shader
- Implement Game States
- Store Materials in new format supported by parser

@ -1,14 +0,0 @@
msaa_levels: 4
debug_draw_color : 1.000, 0.000, 0.000, 1.000
render_width : 1024
fog_density : 0.0020
render_height : 600
fog_mode : 2
fog_color : 0.500, 0.200, 0.200
fog_max_dist : 150.0000
msaa_enabled : true
fog_start_dist : 20.0000
debug_draw_enabled : false
debug_draw_mode : 0
ambient_light : 0.100, 0.100, 0.100
video_driver_linux : 1

@ -1,11 +0,0 @@
name: Ground
type: 5
is_listener: false
renderable: true
parent: ROOT
position: 0.00000 -5.00000 0.00000
scale: 400.00000 2.00000 400.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh

@ -1,15 +0,0 @@
Move_Forward : Left Ctrl-E, W, Left Alt-Left Shift-Up
Move_Backward : S, Down, S, Down
Move_Left : A, Left
Move_Right : D, Right
Move_Up : Q
Move_Down : E
Sprint : Left Shift
Turn_Left : J
Turn_Right : L
Turn_Up : I
Turn_Down : K
Editor_Toggle : F1
Window_Fullscreen : F11
Window_Maximize : F12
Reload_Game_Lib : F5

@ -1,19 +0,0 @@
name: Light_Ent
type: 4
is_listener: false
renderable: false
parent: ROOT
position: 7.00000 1.00000 82.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
light_type: 0
outer_angle: 0.52360
inner_angle: 0.34907
falloff: 1.50000
radius: 40
intensity: 2.00000
depth_bias: 0.00050
valid: true
cast_shadow: false
pcf_enabled: false
color: 0.00000 1.0000 0.000

@ -1,15 +0,0 @@
name: player
type: 2
is_listener: 1
renderable: 0
parent: ROOT
position: 10.00000 5.00000 100.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
ortho: 0
resizeable: 1
fov: 60.00000
nearz: 0.10000
farz: 1000.00000
render_texture: 1

@ -1,272 +0,0 @@
Entity
{
name: ROOT
type: 2
is_listener: false
renderable: false
parent: NONE
position: 0.00000 0.00000 0.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
}
Entity
{
name: player
type: 3
is_listener: false
renderable: false
parent: ROOT
position: 10.00000 5.00000 100.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
ortho: false
resizeable: true
fov: 60.00000
nearz: 0.10000
farz: 1000.00000
clear_color: 0.30000 0.60000 0.90000 1.00000
has_fbo: true
fbo_height: 768
fbo_width: 1024
fbo_has_render_tex: true
fbo_has_depth_tex: true
}
Entity
{
name: Model_Entity
type: 5
is_listener: false
renderable: true
parent: ROOT
position: 0.00000 0.00000 -5.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Ground
type: 5
is_listener: false
renderable: true
parent: ROOT
position: 0.00000 -5.00000 0.00000
scale: 400.00000 2.00000 400.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Light_Ent
type: 4
is_listener: false
renderable: false
parent: ROOT
position: 20.00000 0.00000 60.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
light_type: 1
outer_angle: 0.52360
inner_angle: 0.34907
falloff: 1.50000
radius: 20
intensity: 1.00000
depth_bias: 0.00050
valid: true
cast_shadow: false
pcf_enabled: false
color: 1.00000 0.12500 0.33333
}
Entity
{
name: Light_Ent
type: 4
is_listener: false
renderable: false
parent: ROOT
position: 60.00000 0.00000 40.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
light_type: 1
outer_angle: 0.52360
inner_angle: 0.34907
falloff: 1.50000
radius: 20
intensity: 1.00000
depth_bias: 0.00050
valid: true
cast_shadow: false
pcf_enabled: false
color: 0.33333 0.20000 0.50000
}
Entity
{
name: Light_Ent
type: 4
is_listener: false
renderable: false
parent: ROOT
position: 20.00000 0.00000 20.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
light_type: 1
outer_angle: 0.52360
inner_angle: 0.34907
falloff: 1.50000
radius: 20
intensity: 1.00000
depth_bias: 0.00050
valid: true
cast_shadow: false
pcf_enabled: false
color: 1.00000 0.14286 1.00000
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 6.00000 0.00000 8.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 8.00000 0.00000 3.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 6.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 7.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 6.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 3.00000 0.00000 2.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 2.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 10.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 6.00000 0.00000 4.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 2.00000 0.00000 6.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}

@ -6,14 +6,14 @@ solution "Symmetry"
configuration {"linux"}
postbuildcommands {"ln -fs " .. os.getcwd() .. "/../assets debug/assets"}
postbuildcommands {"ln -fs " .. os.getcwd() .. "/../assets release/assets"}
buildoptions {"-Wall", "-std=c99", "`pkg-config --cflags-only-I sdl2`"}
buildoptions {"-Wall", "-std=c99"}
configuration {"windows", "vs2017"}
defines {"_CRT_SECURE_NO_WARNINGS"}
flags {"NoIncrementalLink", "NoEditAndContinue"}
local windowsPlatform = string.gsub(os.getenv("WindowsSDKVersion") or "10.0.16299.0", "\\", "")
local action = premake.action.current()
if(action ~= nil) then
if(action ~= nil and _ACTION == "vs2017") then
action.vstudio.windowsTargetPlatformVersion = windowsPlatform
action.vstudio.windowsTargetPlatformMinVersion = windowsPlatform
end
@ -66,46 +66,48 @@ solution "Symmetry"
defines {"GAME"}
configuration "linux"
includedirs {"../include/linux/sdl2/", "../include/common/soloud/"}
libdirs {"../lib/linux/sdl2/", "../lib/linux/soloud/"}
links {"SDL2", "m"}
includedirs {"../include/linux/sdl2/", "../include/common/soloud/", "../include/linux/"}
libdirs {"../lib/linux/sdl2/", "../lib/linux/soloud/", "../lib/linux/ode/"}
links {"SDL2", "m", "ode", "pthread"}
configuration {"windows", "vs2017"}
includedirs {"../include/windows/sdl2/", "../include/common/soloud/", "../include/common/newton/"}
libdirs {"../lib/windows/sdl2/", "../lib/windows/soloud/", "../lib/windows/newton/"}
includedirs {"../include/windows/sdl2/", "../include/common/soloud/", "../include/windows/"}
libdirs {"../lib/windows/sdl2/", "../lib/windows/soloud/", "../lib/windows/ode/"}
links {"SDL2"}
configuration "Debug"
links {"soloud_x64_d", "newton_d"}
links {"soloud_x64_d"}
configuration "Release"
links {"soloud_x64", "newton"}
links {"soloud_x64"}
configuration {"windows", "Release", "vs2017"}
postbuildcommands
{
"copy ..\\..\\lib\\windows\\sdl2\\SDL2.dll release\\ /Y",
"copy ..\\..\\lib\\windows\\soloud\\soloud_x64.dll release\\ /Y",
"copy ..\\..\\lib\\windows\\newton\\newton.dll release\\ /Y",
"copy ..\\..\\lib\\windows\\ode\\ode_double.dll release\\ /Y",
"xcopy ..\\..\\assets ..\\..\\bin\\assets /s /e /h /i /y /d",
"copy release\\Symmetry.exe ..\\..\\bin\\ /Y",
"copy release\\libSymmetry.dll ..\\..\\bin\\ /Y",
"copy release\\SDL2.dll ..\\..\\bin\\ /Y",
"copy release\\soloud_x64.dll ..\\..\\bin\\ /Y",
"copy release\\newton.dll ..\\..\\bin\\ /Y",
"copy release\\ode_double.dll ..\\..\\bin\\ /Y",
"rmdir release\\assets",
"mklink /D release\\assets ..\\..\\..\\assets"
}
links {"ode_double"}
configuration {"windows", "Debug", "vs2017"}
postbuildcommands
{
"copy ..\\..\\lib\\windows\\sdl2\\SDL2.dll debug\\ /Y",
"copy ..\\..\\lib\\windows\\soloud\\soloud_x64_d.dll debug\\ /Y",
"copy ..\\..\\lib\\windows\\newton\\newton_d.dll debug\\ /Y",
"copy ..\\..\\lib\\windows\\ode\\ode_doubled.dll debug\\ /Y",
"rmdir debug\\assets",
"mklink /D debug\\assets ..\\..\\..\\assets"
}
links {"ode_doubled"}
-------------------------
-- libSymmetry
-------------------------

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,182 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_COLLISION_SPACE_H_
#define _ODE_COLLISION_SPACE_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
struct dContactGeom;
/**
* @brief User callback for geom-geom collision testing.
*
* @param data The user data object, as passed to dSpaceCollide.
* @param o1 The first geom being tested.
* @param o2 The second geom being test.
*
* @remarks The callback function can call dCollide on o1 and o2 to generate
* contact points between each pair. Then these contact points may be added
* to the simulation as contact joints. The user's callback function can of
* course chose not to call dCollide for any pair, e.g. if the user decides
* that those pairs should not interact.
*
* @ingroup collide
*/
typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2);
ODE_API dSpaceID dSimpleSpaceCreate (dSpaceID space);
ODE_API dSpaceID dHashSpaceCreate (dSpaceID space);
ODE_API dSpaceID dQuadTreeSpaceCreate (dSpaceID space, const dVector3 Center, const dVector3 Extents, int Depth);
/* SAP */
/* Order XZY or ZXY usually works best, if your Y is up. */
#define dSAP_AXES_XYZ ((0)|(1<<2)|(2<<4))
#define dSAP_AXES_XZY ((0)|(2<<2)|(1<<4))
#define dSAP_AXES_YXZ ((1)|(0<<2)|(2<<4))
#define dSAP_AXES_YZX ((1)|(2<<2)|(0<<4))
#define dSAP_AXES_ZXY ((2)|(0<<2)|(1<<4))
#define dSAP_AXES_ZYX ((2)|(1<<2)|(0<<4))
ODE_API dSpaceID dSweepAndPruneSpaceCreate( dSpaceID space, int axisorder );
ODE_API void dSpaceDestroy (dSpaceID);
ODE_API void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel);
ODE_API void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel);
ODE_API void dSpaceSetCleanup (dSpaceID space, int mode);
ODE_API int dSpaceGetCleanup (dSpaceID space);
/**
* @brief Sets sublevel value for a space.
*
* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided
* with another space. If sublevels of both spaces match, the function iterates
* geometries of both spaces and collides them with each other. If sublevel of one
* space is greater than the sublevel of another one, only the geometries of the
* space with greater sublevel are iterated, another space is passed into
* collision callback as a geometry itself. By default all the spaces are assigned
* zero sublevel.
*
* @note
* The space sublevel @e IS @e NOT automatically updated when one space is inserted
* into another or removed from one. It is a client's responsibility to update sublevel
* value if necessary.
*
* @param space the space to modify
* @param sublevel the sublevel value to be assigned
* @ingroup collide
* @see dSpaceGetSublevel
* @see dSpaceCollide2
*/
ODE_API void dSpaceSetSublevel (dSpaceID space, int sublevel);
/**
* @brief Gets sublevel value of a space.
*
* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided
* with another space. See @c dSpaceSetSublevel for more details.
*
* @param space the space to query
* @returns the sublevel value of the space
* @ingroup collide
* @see dSpaceSetSublevel
* @see dSpaceCollide2
*/
ODE_API int dSpaceGetSublevel (dSpaceID space);
/**
* @brief Sets manual cleanup flag for a space.
*
* Manual cleanup flag marks a space as eligible for manual thread data cleanup.
* This function should be called for every space object right after creation in
* case if ODE has been initialized with @c dInitFlagManualThreadCleanup flag.
*
* Failure to set manual cleanup flag for a space may lead to some resources
* remaining leaked until the program exit.
*
* @param space the space to modify
* @param mode 1 for manual cleanup mode and 0 for default cleanup mode
* @ingroup collide
* @see dSpaceGetManualCleanup
* @see dInitODE2
*/
ODE_API void dSpaceSetManualCleanup (dSpaceID space, int mode);
/**
* @brief Get manual cleanup flag of a space.
*
* Manual cleanup flag marks a space space as eligible for manual thread data cleanup.
* See @c dSpaceSetManualCleanup for more details.
*
* @param space the space to query
* @returns 1 for manual cleanup mode and 0 for default cleanup mode of the space
* @ingroup collide
* @see dSpaceSetManualCleanup
* @see dInitODE2
*/
ODE_API int dSpaceGetManualCleanup (dSpaceID space);
ODE_API void dSpaceAdd (dSpaceID, dGeomID);
ODE_API void dSpaceRemove (dSpaceID, dGeomID);
ODE_API int dSpaceQuery (dSpaceID, dGeomID);
ODE_API void dSpaceClean (dSpaceID);
ODE_API int dSpaceGetNumGeoms (dSpaceID);
ODE_API dGeomID dSpaceGetGeom (dSpaceID, int i);
/**
* @brief Given a space, this returns its class.
*
* The ODE classes are:
* @li dSimpleSpaceClass
* @li dHashSpaceClass
* @li dSweepAndPruneSpaceClass
* @li dQuadTreeSpaceClass
* @li dFirstUserClass
* @li dLastUserClass
*
* The class id not defined by the user should be between
* dFirstSpaceClass and dLastSpaceClass.
*
* User-defined class will return their own number.
*
* @param space the space to query
* @returns The space class ID.
* @ingroup collide
*/
ODE_API int dSpaceGetClass(dSpaceID space);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,316 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/*
* TriMesh code by Erwin de Vries.
*
* Trimesh data.
* This is where the actual vertexdata (pointers), and BV tree is stored.
* Vertices should be single precision!
* This should be more sophisticated, so that the user can easyly implement
* another collision library, but this is a lot of work, and also costs some
* performance because some data has to be copied.
*/
#ifndef _ODE_COLLISION_TRIMESH_H_
#define _ODE_COLLISION_TRIMESH_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Data storage for triangle meshes.
*/
struct dxTriMeshData;
typedef struct dxTriMeshData* dTriMeshDataID;
typedef enum
{
dMTV__MIN,
dMTV_FIRST = dMTV__MIN,
dMTV_SECOND,
dMTV_THIRD,
dMTV__MAX,
} dMeshTriangleVertex;
/*
* These don't make much sense now, but they will later when we add more
* features.
*/
ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void);
ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g);
/*
* The values of data_id that can be used with dGeomTriMeshDataSet/dGeomTriMeshDataGet
*/
enum
{
dTRIMESHDATA__MIN,
dTRIMESHDATA_FACE_NORMALS = dTRIMESHDATA__MIN,
dTRIMESHDATA_USE_FLAGS,
dTRIMESHDATA__MAX,
#ifndef TRIMESH_FACE_NORMALS // Define this name during the header inclusion if you need it for something else
// Included for backward compatibility -- please use the corrected name above. Sorry.
TRIMESH_FACE_NORMALS = dTRIMESHDATA_FACE_NORMALS,
#endif
};
/*
* The flags of the dTRIMESHDATA_USE_FLAGS data elements
*/
enum
{
dMESHDATAUSE_EDGE1 = 0x01,
dMESHDATAUSE_EDGE2 = 0x02,
dMESHDATAUSE_EDGE3 = 0x04,
dMESHDATAUSE_VERTEX1 = 0x08,
dMESHDATAUSE_VERTEX2 = 0x10,
dMESHDATAUSE_VERTEX3 = 0x20,
};
/*
* Set and get the TriMeshData additional data
* Note: The data is NOT COPIED on assignment
*/
ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void *in_data);
ODE_API void *dGeomTriMeshDataGet(dTriMeshDataID g, int data_id);
ODE_API void *dGeomTriMeshDataGet2(dTriMeshDataID g, int data_id, dsizeint *pout_size/*=NULL*/);
/**
* We need to set the last transform after each time step for
* accurate collision response. These functions get and set that transform.
* It is stored per geom instance, rather than per dTriMeshDataID.
*/
ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, const dMatrix4 last_trans );
ODE_API const dReal* dGeomTriMeshGetLastTransform( dGeomID g );
/*
* Build a TriMesh data object with single precision vertex data.
*/
ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g,
const void* Vertices, int VertexStride, int VertexCount,
const void* Indices, int IndexCount, int TriStride);
/* same again with a normals array (used as trimesh-trimesh optimization) */
ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g,
const void* Vertices, int VertexStride, int VertexCount,
const void* Indices, int IndexCount, int TriStride,
const void* Normals);
/*
* Build a TriMesh data object with double precision vertex data.
*/
ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g,
const void* Vertices, int VertexStride, int VertexCount,
const void* Indices, int IndexCount, int TriStride);
/* same again with a normals array (used as trimesh-trimesh optimization) */
ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g,
const void* Vertices, int VertexStride, int VertexCount,
const void* Indices, int IndexCount, int TriStride,
const void* Normals);
/*
* Simple build. Single/double precision based on dSINGLE/dDOUBLE!
*/
ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g,
const dReal* Vertices, int VertexCount,
const dTriIndex* Indices, int IndexCount);
/* same again with a normals array (used as trimesh-trimesh optimization) */
ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g,
const dReal* Vertices, int VertexCount,
const dTriIndex* Indices, int IndexCount,
const int* Normals);
/*
* Data preprocessing build request flags.
*/
enum
{
dTRIDATAPREPROCESS_BUILD__MIN,
dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES = dTRIDATAPREPROCESS_BUILD__MIN, // Used to optimize OPCODE trimesh-capsule collisions; allocates 1 byte per triangle; no extra data associated
dTRIDATAPREPROCESS_BUILD_FACE_ANGLES, // Used to aid trimesh-convex collisions; memory requirements depend on extra data
dTRIDATAPREPROCESS_BUILD__MAX,
};
/*
* Data preprocessing extra values for dTRIDATAPREPROCESS_BUILD_FACE_ANGLES.
*/
enum
{
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN,
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE = dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN, // Build angles for convex edges only and store as bytes; allocates 3 bytes per triangle; stores angles (0..180] in 1/254 fractions leaving two values for the flat and all the concaves
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_ALL, // Build angles for all the edges and store in bytes; allocates 3 bytes per triangle; stores angles [-180..0) and (0..180] in 1/127 fractions plus a value for the flat angle
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_WORD_ALL, // Build angles for all the edges and store in words; allocates 6 bytes per triangle; stores angles [-180..0) and (0..180] in 1/32767 fractions plus a value for the flat angle
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX,
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__DEFAULT = dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE, // The default value assumed if the extra data is not provided
};
/*
* Pre-process the trimesh data according to the request flags.
*
* buildRequestFlags is a bitmask of 1U << dTRIDATAPREPROCESS_BUILD_...
* It is allowed to call the function multiple times provided the bitmasks are different each time.
*
* requestExtraData is an optional pointer to array of extra parameters per bitmask bits
* (only the elements indexed by positions of raised bits are examined;
* defaults are assumed if the pointer is NULL)
*
* The function returns a boolean status the only failure reason being insufficient memory.
*/
ODE_API int dGeomTriMeshDataPreprocess2(dTriMeshDataID g, unsigned int buildRequestFlags, const dintptr *requestExtraData/*=NULL | const dintptr (*)[dTRIDATAPREPROCESS_BUILD__MAX]*/);
/*
* Obsolete. Equivalent to calling dGeomTriMeshDataPreprocess2(g, (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES), NULL)
*/
ODE_API int dGeomTriMeshDataPreprocess(dTriMeshDataID g);
/*
* Get and set the internal preprocessed trimesh data buffer (see the enumerated type above), for loading and saving
* These functions are deprecated. Use dGeomTriMeshDataSet/dGeomTriMeshDataGet2 with dTRIMESHDATA_USE_FLAGS instead.
*/
ODE_API_DEPRECATED ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen);
ODE_API_DEPRECATED ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf);
/*
* Per triangle callback. Allows the user to say if he wants a collision with
* a particular triangle.
*/
typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex);
ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback);
ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g);
/*
* Per object callback. Allows the user to get the list of triangles in 1
* shot. Maybe we should remove this one.
*/
typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount);
ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback);
ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g);
/*
* Ray callback.
* Allows the user to say if a ray collides with a triangle on barycentric
* coords. The user can for example sample a texture with alpha transparency
* to determine if a collision should occur.
*/
typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v);
ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback);
ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g);
/*
* Triangle merging callback.
* Allows the user to generate a fake triangle index for a new contact generated
* from merging of two other contacts. That index could later be used by the
* user to determine attributes of original triangles used as sources for a
* merged contact.
*/
typedef int dTriTriMergeCallback(dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex);
ODE_API void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback);
ODE_API dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g);
/*
* Trimesh class
* Construction. Callbacks are optional.
*/
ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback);
ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data);
ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g);
/* enable/disable/check temporal coherence*/
ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable);
ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass);
/*
* Clears the internal temporal coherence caches. When a geom has its
* collision checked with a trimesh once, data is stored inside the trimesh.
* With large worlds with lots of seperate objects this list could get huge.
* We should be able to do this automagically.
*/
ODE_API void dGeomTriMeshClearTCCache(dGeomID g);
/*
* returns the TriMeshDataID
*/
ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g);
/*
* Gets a triangle.
*/
ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2);
/*
* Gets the point on the requested triangle and the given barycentric
* coordinates.
*/
ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out);
/*
This is how the strided data works:
struct StridedVertex{
dVector3 Vertex;
// Userdata
};
int VertexStride = sizeof(StridedVertex);
struct StridedTri{
int Indices[3];
// Userdata
};
int TriStride = sizeof(StridedTri);
*/
ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g);
ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g);
#ifdef __cplusplus
}
#endif
#endif /* _ODE_COLLISION_TRIMESH_H_ */

@ -0,0 +1,568 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_COMMON_H_
#define _ODE_COMMON_H_
#include <ode/odeconfig.h>
#include <ode/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/* configuration stuff */
/* constants */
/* pi and 1/sqrt(2) are defined here if necessary because they don't get
* defined in <math.h> on some platforms (like MS-Windows)
*/
#ifndef M_PI
#define M_PI REAL(3.1415926535897932384626433832795029)
#endif
#ifndef M_PI_2
#define M_PI_2 REAL(1.5707963267948966192313216916398)
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
#endif
/* floating point data type, vector, matrix and quaternion types */
#if defined(dSINGLE)
typedef float dReal;
#ifdef dDOUBLE
#error You can only #define dSINGLE or dDOUBLE, not both.
#endif /* dDOUBLE */
#elif defined(dDOUBLE)
typedef double dReal;
#else
#error You must #define dSINGLE or dDOUBLE
#endif
/* Detect if we've got both trimesh engines enabled. */
#if dTRIMESH_ENABLED
#if dTRIMESH_OPCODE && dTRIMESH_GIMPACT
#error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both.
#endif
#endif /* dTRIMESH_ENABLED */
/*
* Define a type for indices, either 16 or 32 bit, based on build option
* TODO: Currently GIMPACT only supports 32 bit indices.
*/
#if dTRIMESH_16BIT_INDICES
#if dTRIMESH_GIMPACT
typedef duint32 dTriIndex;
#else /* dTRIMESH_GIMPACT */
typedef duint16 dTriIndex;
#endif /* dTRIMESH_GIMPACT */
#else /* dTRIMESH_16BIT_INDICES */
typedef duint32 dTriIndex;
#endif /* dTRIMESH_16BIT_INDICES */
/* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
* (used to compute matrix leading dimensions)
*/
#define dPAD(a) (((a) > 1) ? (((a) + 3) & (int)(~3)) : (a))
typedef enum {
dSA__MIN,
dSA_X = dSA__MIN,
dSA_Y,
dSA_Z,
dSA__MAX,
} dSpaceAxis;
typedef enum {
dMD__MIN,
dMD_LINEAR = dMD__MIN,
dMD_ANGULAR,
dMD__MAX,
} dMotionDynamics;
typedef enum {
dDA__MIN,
dDA__L_MIN = dDA__MIN + dMD_LINEAR * dSA__MAX,
dDA_LX = dDA__L_MIN + dSA_X,
dDA_LY = dDA__L_MIN + dSA_Y,
dDA_LZ = dDA__L_MIN + dSA_Z,
dDA__L_MAX = dDA__L_MIN + dSA__MAX,
dDA__A_MIN = dDA__MIN + dMD_ANGULAR * dSA__MAX,
dDA_AX = dDA__A_MIN + dSA_X,
dDA_AY = dDA__A_MIN + dSA_Y,
dDA_AZ = dDA__A_MIN + dSA_Z,
dDA__A_MAX = dDA__A_MIN + dSA__MAX,
dDA__MAX = dDA__MIN + dMD__MAX * dSA__MAX,
} dDynamicsAxis;
typedef enum {
dV3E__MIN,
dV3E__AXES_MIN = dV3E__MIN,
dV3E_X = dV3E__AXES_MIN + dSA_X,
dV3E_Y = dV3E__AXES_MIN + dSA_Y,
dV3E_Z = dV3E__AXES_MIN + dSA_Z,
dV3E__AXES_MAX = dV3E__AXES_MIN + dSA__MAX,
dV3E_PAD = dV3E__AXES_MAX,
dV3E__MAX,
dV3E__AXES_COUNT = dV3E__AXES_MAX - dV3E__AXES_MIN,
} dVec3Element;
typedef enum {
dV4E__MIN,
dV4E_X = dV4E__MIN + dSA_X,
dV4E_Y = dV4E__MIN + dSA_Y,
dV4E_Z = dV4E__MIN + dSA_Z,
dV4E_O = dV4E__MIN + dSA__MAX,
dV4E__MAX,
} dVec4Element;
typedef enum {
dM3E__MIN,
dM3E__X_MIN = dM3E__MIN + dSA_X * dV3E__MAX,
dM3E__X_AXES_MIN = dM3E__X_MIN + dV3E__AXES_MIN,
dM3E_XX = dM3E__X_MIN + dV3E_X,
dM3E_XY = dM3E__X_MIN + dV3E_Y,
dM3E_XZ = dM3E__X_MIN + dV3E_Z,
dM3E__X_AXES_MAX = dM3E__X_MIN + dV3E__AXES_MAX,
dM3E_XPAD = dM3E__X_MIN + dV3E_PAD,
dM3E__X_MAX = dM3E__X_MIN + dV3E__MAX,
dM3E__Y_MIN = dM3E__MIN + dSA_Y * dV3E__MAX,
dM3E__Y_AXES_MIN = dM3E__Y_MIN + dV3E__AXES_MIN,
dM3E_YX = dM3E__Y_MIN + dV3E_X,
dM3E_YY = dM3E__Y_MIN + dV3E_Y,
dM3E_YZ = dM3E__Y_MIN + dV3E_Z,
dM3E__Y_AXES_MAX = dM3E__Y_MIN + dV3E__AXES_MAX,
dM3E_YPAD = dM3E__Y_MIN + dV3E_PAD,
dM3E__Y_MAX = dM3E__Y_MIN + dV3E__MAX,
dM3E__Z_MIN = dM3E__MIN + dSA_Z * dV3E__MAX,
dM3E__Z_AXES_MIN = dM3E__Z_MIN + dV3E__AXES_MIN,
dM3E_ZX = dM3E__Z_MIN + dV3E_X,
dM3E_ZY = dM3E__Z_MIN + dV3E_Y,
dM3E_ZZ = dM3E__Z_MIN + dV3E_Z,
dM3E__Z_AXES_MAX = dM3E__Z_MIN + dV3E__AXES_MAX,
dM3E_ZPAD = dM3E__Z_MIN + dV3E_PAD,
dM3E__Z_MAX = dM3E__Z_MIN + dV3E__MAX,
dM3E__MAX = dM3E__MIN + dSA__MAX * dV3E__MAX,
} dMat3Element;
typedef enum {
dM4E__MIN,
dM4E__X_MIN = dM4E__MIN + dV4E_X * dV4E__MAX,
dM4E_XX = dM4E__X_MIN + dV4E_X,
dM4E_XY = dM4E__X_MIN + dV4E_Y,
dM4E_XZ = dM4E__X_MIN + dV4E_Z,
dM4E_XO = dM4E__X_MIN + dV4E_O,
dM4E__X_MAX = dM4E__X_MIN + dV4E__MAX,
dM4E__Y_MIN = dM4E__MIN + dV4E_Y * dV4E__MAX,
dM4E_YX = dM4E__Y_MIN + dV4E_X,
dM4E_YY = dM4E__Y_MIN + dV4E_Y,
dM4E_YZ = dM4E__Y_MIN + dV4E_Z,
dM4E_YO = dM4E__Y_MIN + dV4E_O,
dM4E__Y_MAX = dM4E__Y_MIN + dV4E__MAX,
dM4E__Z_MIN = dM4E__MIN + dV4E_Z * dV4E__MAX,
dM4E_ZX = dM4E__Z_MIN + dV4E_X,
dM4E_ZY = dM4E__Z_MIN + dV4E_Y,
dM4E_ZZ = dM4E__Z_MIN + dV4E_Z,
dM4E_ZO = dM4E__Z_MIN + dV4E_O,
dM4E__Z_MAX = dM4E__Z_MIN + dV4E__MAX,
dM4E__O_MIN = dM4E__MIN + dV4E_O * dV4E__MAX,
dM4E_OX = dM4E__O_MIN + dV4E_X,
dM4E_OY = dM4E__O_MIN + dV4E_Y,
dM4E_OZ = dM4E__O_MIN + dV4E_Z,
dM4E_OO = dM4E__O_MIN + dV4E_O,
dM4E__O_MAX = dM4E__O_MIN + dV4E__MAX,
dM4E__MAX = dM4E__MIN + dV4E__MAX * dV4E__MAX,
} dMat4Element;
typedef enum {
dQUE__MIN,
dQUE_R = dQUE__MIN,
dQUE__AXIS_MIN,
dQUE_I = dQUE__AXIS_MIN + dSA_X,
dQUE_J = dQUE__AXIS_MIN + dSA_Y,
dQUE_K = dQUE__AXIS_MIN + dSA_Z,
dQUE__AXIS_MAX = dQUE__AXIS_MIN + dSA__MAX,
dQUE__MAX = dQUE__AXIS_MAX,
} dQuatElement;
/* these types are mainly just used in headers */
typedef dReal dVector3[dV3E__MAX];
typedef dReal dVector4[dV4E__MAX];
typedef dReal dMatrix3[dM3E__MAX];
typedef dReal dMatrix4[dM4E__MAX];
typedef dReal dMatrix6[(dMD__MAX * dV3E__MAX) * (dMD__MAX * dSA__MAX)];
typedef dReal dQuaternion[dQUE__MAX];
/* precision dependent scalar math functions */
#if defined(dSINGLE)
#define REAL(x) (x##f) /* form a constant */
#define dRecip(x) ((1.0f/(x))) /* reciprocal */
#define dSqrt(x) (sqrtf(x)) /* square root */
#define dRecipSqrt(x) ((1.0f/sqrtf(x))) /* reciprocal square root */
#define dSin(x) (sinf(x)) /* sine */
#define dCos(x) (cosf(x)) /* cosine */
#define dFabs(x) (fabsf(x)) /* absolute value */
#define dAtan2(y,x) (atan2f(y,x)) /* arc tangent with 2 args */
#define dAsin(x) (asinf(x))
#define dAcos(x) (acosf(x))
#define dFMod(a,b) (fmodf(a,b)) /* modulo */
#define dFloor(x) floorf(x) /* floor */
#define dCeil(x) ceilf(x) /* ceil */
#define dCopySign(a,b) _ode_copysignf(a, b) /* copy value sign */
#define dNextAfter(x, y) _ode_nextafterf(x, y) /* next value after */
#ifdef HAVE___ISNANF
#define dIsNan(x) (__isnanf(x))
#elif defined(HAVE__ISNANF)
#define dIsNan(x) (_isnanf(x))
#elif defined(HAVE_ISNANF)
#define dIsNan(x) (isnanf(x))
#else
/*
fall back to _isnan which is the VC way,
this may seem redundant since we already checked
for _isnan before, but if isnan is detected by
configure but is not found during compilation
we should always make sure we check for __isnanf,
_isnanf and isnanf in that order before falling
back to a default
*/
#define dIsNan(x) (_isnan(x))
#endif
#elif defined(dDOUBLE)
#define REAL(x) (x)
#define dRecip(x) (1.0/(x))
#define dSqrt(x) sqrt(x)
#define dRecipSqrt(x) (1.0/sqrt(x))
#define dSin(x) sin(x)
#define dCos(x) cos(x)
#define dFabs(x) fabs(x)
#define dAtan2(y,x) atan2((y),(x))
#define dAsin(x) asin(x)
#define dAcos(x) acos(x)
#define dFMod(a,b) (fmod((a),(b)))
#define dFloor(x) floor(x)
#define dCeil(x) ceil(x)
#define dCopySign(a,b) _ode_copysign(a, b)
#define dNextAfter(x, y) _ode_nextafter(x, y)
#ifdef HAVE___ISNAN
#define dIsNan(x) (__isnan(x))
#elif defined(HAVE__ISNAN)
#define dIsNan(x) (_isnan(x))
#elif defined(HAVE_ISNAN)
#define dIsNan(x) (isnan(x))
#else
#define dIsNan(x) (_isnan(x))
#endif
#else
#error You must #define dSINGLE or dDOUBLE
#endif
ODE_PURE_INLINE dReal dMin(dReal x, dReal y) { return x <= y ? x : y; }
ODE_PURE_INLINE dReal dMax(dReal x, dReal y) { return x <= y ? y : x; }
/* internal object types (all prefixed with `dx') */
struct dxWorld; /* dynamics world */
struct dxSpace; /* collision space */
struct dxBody; /* rigid body (dynamics object) */
struct dxGeom; /* geometry (collision object) */
struct dxJoint; /* joint */
struct dxJointGroup;/* joint group */
typedef struct dxWorld *dWorldID;
typedef struct dxSpace *dSpaceID;
typedef struct dxBody *dBodyID;
typedef struct dxGeom *dGeomID;
typedef struct dxJoint *dJointID;
typedef struct dxJointGroup *dJointGroupID;
/* error numbers */
enum {
d_ERR_UNKNOWN = 0, /* unknown error */
d_ERR_IASSERT, /* internal assertion failed */
d_ERR_UASSERT, /* user assertion failed */
d_ERR_LCP /* user assertion failed */
};
/* joint type numbers */
typedef enum {
dJointTypeNone = 0, /* or "unknown" */
dJointTypeBall,
dJointTypeHinge,
dJointTypeSlider,
dJointTypeContact,
dJointTypeUniversal,
dJointTypeHinge2,
dJointTypeFixed,
dJointTypeNull,
dJointTypeAMotor,
dJointTypeLMotor,
dJointTypePlane2D,
dJointTypePR,
dJointTypePU,
dJointTypePiston,
dJointTypeDBall,
dJointTypeDHinge,
dJointTypeTransmission,
} dJointType;
/* an alternative way of setting joint parameters, using joint parameter
* structures and member constants. we don't actually do this yet.
*/
/*
typedef struct dLimot {
int mode;
dReal lostop, histop;
dReal vel, fmax;
dReal fudge_factor;
dReal bounce, soft;
dReal suspension_erp, suspension_cfm;
} dLimot;
enum {
dLimotLoStop = 0x0001,
dLimotHiStop = 0x0002,
dLimotVel = 0x0004,
dLimotFMax = 0x0008,
dLimotFudgeFactor = 0x0010,
dLimotBounce = 0x0020,
dLimotSoft = 0x0040
};
*/
/* standard joint parameter names. why are these here? - because we don't want
* to include all the joint function definitions in joint.cpp. hmmmm.
* MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
* which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
* paste between these two.
*/
#define D_ALL_PARAM_NAMES(start) \
/* parameters for limits and motors */ \
dParamLoStop = start, \
dParamHiStop, \
dParamVel, \
dParamLoVel, \
dParamHiVel, \
dParamFMax, \
dParamFudgeFactor, \
dParamBounce, \
dParamCFM, \
dParamStopERP, \
dParamStopCFM, \
/* parameters for suspension */ \
dParamSuspensionERP, \
dParamSuspensionCFM, \
dParamERP, \
/*
* \enum D_ALL_PARAM_NAMES_X
*
* \var dParamGroup This is the starting value of the different group
* (i.e. dParamGroup1, dParamGroup2, dParamGroup3)
* It also helps in the use of parameter
* (dParamGroup2 | dParamFMax) == dParamFMax2
*/
#define D_ALL_PARAM_NAMES_X(start,x) \
dParamGroup ## x = start, \
/* parameters for limits and motors */ \
dParamLoStop ## x = start, \
dParamHiStop ## x, \
dParamVel ## x, \
dParamLoVel ## x, \
dParamHiVel ## x, \
dParamFMax ## x, \
dParamFudgeFactor ## x, \
dParamBounce ## x, \
dParamCFM ## x, \
dParamStopERP ## x, \
dParamStopCFM ## x, \
/* parameters for suspension */ \
dParamSuspensionERP ## x, \
dParamSuspensionCFM ## x, \
dParamERP ## x,
enum {
D_ALL_PARAM_NAMES(0)
dParamsInGroup, /* < Number of parameter in a group */
D_ALL_PARAM_NAMES_X(0x000,1)
D_ALL_PARAM_NAMES_X(0x100,2)
D_ALL_PARAM_NAMES_X(0x200,3)
/* add a multiple of this constant to the basic parameter numbers to get
* the parameters for the second, third etc axes.
*/
dParamGroup=0x100
};
/* angular motor mode numbers */
enum {
dAMotorUser = 0,
dAMotorEuler = 1
};
/* transmission joint mode numbers */
enum {
dTransmissionParallelAxes = 0,
dTransmissionIntersectingAxes = 1,
dTransmissionChainDrive = 2
};
/* joint force feedback information */
typedef struct dJointFeedback {
dVector3 f1; /* force applied to body 1 */
dVector3 t1; /* torque applied to body 1 */
dVector3 f2; /* force applied to body 2 */
dVector3 t2; /* torque applied to body 2 */
} dJointFeedback;
/* private functions that must be implemented by the collision library:
* (1) indicate that a geom has moved, (2) get the next geom in a body list.
* these functions are called whenever the position of geoms connected to a
* body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or
* when the ODE step function updates the body state.
*/
void dGeomMoved (dGeomID);
dGeomID dGeomGetBodyNext (dGeomID);
/**
* dGetConfiguration returns the specific ODE build configuration as
* a string of tokens. The string can be parsed in a similar way to
* the OpenGL extension mechanism, the naming convention should be
* familiar too. The following extensions are reported:
*
* ODE
* ODE_single_precision
* ODE_double_precision
* ODE_EXT_no_debug
* ODE_EXT_trimesh
* ODE_EXT_opcode
* ODE_EXT_gimpact
* ODE_OPC_16bit_indices
* ODE_OPC_new_collider
* ODE_EXT_mt_collisions
* ODE_EXT_threading
* ODE_THR_builtin_impl
*/
ODE_API const char* dGetConfiguration (void);
/**
* Helper to check for a token in the ODE configuration string.
* Caution, this function is case sensitive.
*
* @param token A configuration token, see dGetConfiguration for details
*
* @return 1 if exact token is present, 0 if not present
*/
ODE_API int dCheckConfiguration( const char* token );
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,40 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_COMPATIBILITY_H_
#define _ODE_COMPATIBILITY_H_
/*
* ODE's backward compatibility system ensures that as ODE's API
* evolves, user code will not break.
*/
/*
* These new rotation function names are more consistent with the
* rest of the API.
*/
#define dQtoR(q,R) dRfromQ((R),(q))
#define dRtoQ(R,q) dQfromR((q),(R))
#define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q))
#endif

@ -0,0 +1,110 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_CONTACT_H_
#define _ODE_CONTACT_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
dContactMu2 = 0x001, /**< Use axis dependent friction */
dContactAxisDep = 0x001, /**< Same as above */
dContactFDir1 = 0x002, /**< Use FDir for the first friction value */
dContactBounce = 0x004, /**< Restore collision energy anti-parallel to the normal */
dContactSoftERP = 0x008, /**< Don't use global erp for penetration reduction */
dContactSoftCFM = 0x010, /**< Don't use global cfm for penetration constraint */
dContactMotion1 = 0x020, /**< Use a non-zero target velocity for the constraint */
dContactMotion2 = 0x040,
dContactMotionN = 0x080,
dContactSlip1 = 0x100, /**< Force-dependent slip. */
dContactSlip2 = 0x200,
dContactRolling = 0x400, /**< Rolling/Angular friction */
dContactApprox0 = 0x0000,
dContactApprox1_1 = 0x1000,
dContactApprox1_2 = 0x2000,
dContactApprox1_N = 0x4000, /**< For rolling friction */
dContactApprox1 = 0x7000
};
typedef struct dSurfaceParameters {
/* must always be defined */
int mode;
dReal mu;
/* only defined if the corresponding flag is set in mode */
dReal mu2;
dReal rho; /**< Rolling friction */
dReal rho2;
dReal rhoN; /**< Spinning friction */
dReal bounce; /**< Coefficient of restitution */
dReal bounce_vel; /**< Bouncing threshold */
dReal soft_erp;
dReal soft_cfm;
dReal motion1,motion2,motionN;
dReal slip1,slip2;
} dSurfaceParameters;
/**
* @brief Describe the contact point between two geoms.
*
* If two bodies touch, or if a body touches a static feature in its
* environment, the contact is represented by one or more "contact
* points", described by dContactGeom.
*
* The convention is that if body 1 is moved along the normal vector by
* a distance depth (or equivalently if body 2 is moved the same distance
* in the opposite direction) then the contact depth will be reduced to
* zero. This means that the normal vector points "in" to body 1.
*
* @ingroup collide
*/
typedef struct dContactGeom {
dVector3 pos; /*< contact position*/
dVector3 normal; /*< normal vector*/
dReal depth; /*< penetration depth*/
dGeomID g1,g2; /*< the colliding geoms*/
int side1,side2; /*< (to be documented)*/
} dContactGeom;
/* contact info used by contact joint */
typedef struct dContact {
dSurfaceParameters surface;
dContactGeom geom;
dVector3 fdir1;
} dContact;
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,229 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_COOPERATIVE_H_
#define _ODE_COOPERATIVE_H_
#include <ode/common.h>
#include <ode/threading.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup coop Cooperative Algorithms
*
* Algorithms implemented as multiple threads doing work cooperatively.
*/
struct dxCooperative;
struct dxResourceRequirements;
struct dxResourceContainer;
/**
* @brief A container for cooperative algorithms shared context
*
* The Cooperative is a container for cooperative algorithms shared context.
* At present it contains threading object (either a real one or a defaulted
* self-threading).
*
* Cooperative use in functions performing computations must be serialized. That is,
* functions referring to a single instance of Cooperative object must not be called in
* parallel.
*/
typedef struct dxCooperative *dCooperativeID;
/**
* @brief A container for resource requirements information
*
* The ResourceRequirements object is a container for descriptive information
* regarding what resources (memory, synchronization objects, etc.) need to be
* allocated for particular computations. The object can be used for accumulating
* resource requirement maxima over multiple functions and then allocating resources
* that would suffice for any of those function calls.
*
* ResourceRequirements objects maintain relations to Cooperative objects since
* amounts of resources that could be required can depend on characteristics of
* shared context, e.g. on maximal number of threads in the threading object.
*
* @ingroup coop
* @see dCooperativeID
* @see dResourceContainerID
*/
typedef struct dxResourceRequirements *dResourceRequirementsID;
/**
* @brief A container for algorithm allocated resources
*
* The ResourceContainer object can contain resources allocated according to information
* in a ResourceRequirements. The resources inherit link to the threading object
* from the requirements they are allocated according to.
*
* @ingroup coop
* @see dResourceRequirementsID
* @see dCooperativeID
*/
typedef struct dxResourceContainer *dResourceContainerID;
/**
* @brief Creates a Cooperative object related to the specified threading.
*
* NULL's are allowed for the threading. In this case the default (global) self-threading
* object will be used.
*
* Use @c dCooperativeDestroy to destroy the object. The Cooperative object must exist
* until after all the objects referencing it are destroyed.
*
* @param functionInfo The threading functions to use
* @param threadingImpl The threading implementation object to use
* @returns The Cooperative object instance or NULL if allocation fails.
* @ingroup coop
* @see dCooperativeDestroy
*/
ODE_API dCooperativeID dCooperativeCreate(const dThreadingFunctionsInfo *functionInfo/*=NULL*/, dThreadingImplementationID threadingImpl/*=NULL*/);
/**
* @brief Destroys Cooperative object.
*
* The Cooperative object can only be destroyed after all the objects referencing it.
*
* @param cooperative A Cooperative object to be deleted (NULL is allowed)
* @ingroup coop
* @see dCooperativeCreate
*/
ODE_API void dCooperativeDestroy(dCooperativeID cooperative);
/**
* @brief Creates a ResourceRequirements object related to a Cooperative.
*
* The object is purely descriptive and does not contain any resources by itself.
* The actual resources are allocated by means of ResourceContainer object.
*
* The object is created with empty requirements. It can be then used to accumulate
* requirements for one or more function calls and can be cloned or merged with others.
* The actual requirements information is added to the object by computation related
* functions.
*
* Use @c dResourceRequirementsDestroy to delete the object when it is no longer needed.
*
* @param cooperative A Cooperative object to be used
* @returns The ResourceRequirements object instance or NULL if allocation fails
* @ingroup coop
* @see dResourceRequirementsDestroy
* @see dResourceRequirementsClone
* @see dResourceRequirementsMergeIn
* @see dCooperativeCreate
* @see dResourceContainerAcquire
*/
ODE_API dResourceRequirementsID dResourceRequirementsCreate(dCooperativeID cooperative);
/**
* @brief Destroys ResourceRequirements object.
*
* The ResourceRequirements object can be destroyed at any time with no regards
* to other objects' lifetime.
*
* @param requirements A ResourceRequirements object to be deleted (NULL is allowed)
* @ingroup coop
* @see dResourceRequirementsCreate
*/
ODE_API void dResourceRequirementsDestroy(dResourceRequirementsID requirements);
/**
* @brief Clones ResourceRequirements object.
*
* The function creates a copy of the ResourceRequirements object with all the
* contents and the relation to Cooperative matching. The object passed in
* the parameter is not changed.
*
* The object created with the function must later be destroyed with @c dResourceRequirementsDestroy.
*
* @param requirements A ResourceRequirements object to be cloned
* @returns A handle to the new object or NULL if allocation fails
* @ingroup coop
* @see dResourceRequirementsCreate
* @see dResourceRequirementsDestroy
* @see dResourceRequirementsMergeIn
*/
ODE_API dResourceRequirementsID dResourceRequirementsClone(/*const */dResourceRequirementsID requirements);
/**
* @brief Merges one ResourceRequirements object into another ResourceRequirements object.
*
* The function updates @a summaryRequirements requirements to be also sufficient
* for the purposes @a extraRequirements could be used for. The @a extraRequirements
* object is not changed. The both objects should normally have had been created
* with the same Cooperative object.
*
* @param summaryRequirements A ResourceRequirements object to be changed
* @param extraRequirements A ResourceRequirements the requirements to be taken from
* @ingroup coop
* @see dResourceRequirementsCreate
* @see dResourceRequirementsDestroy
* @see dResourceRequirementsClone
*/
ODE_API void dResourceRequirementsMergeIn(dResourceRequirementsID summaryRequirements, /*const */dResourceRequirementsID extraRequirements);
/**
* @brief Allocates resources as specified in ResourceRequirements object.
*
* The ResourceContainer object can be used in cooperative computation algorithms.
*
* The same @a requirements object can be passed to many resource allocations
* (with or without modifications) and can be deleted immediately, without waiting
* for the ResourceContainer object destruction.
*
* Use @c dResourceContainerDestroy to delete the object and release the resources
* when they are no longer needed.
*
* @param requirements The ResourceRequirements object to allocate resources according to
* @returns A ResourceContainer object instance with the resources allocated or NULL if allocation fails
* @ingroup coop
* @see dResourceContainerDestroy
* @see dResourceRequirementsCreate
*/
ODE_API dResourceContainerID dResourceContainerAcquire(/*const */dResourceRequirementsID requirements);
/**
* @brief Destroys ResourceContainer object and releases resources allocated in it.
*
* @param resources A ResourceContainer object to be deleted (NULL is allowed)
* @ingroup coop
* @see dResourceContainerAcquire
*/
ODE_API void dResourceContainerDestroy(dResourceContainerID resources);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef _ODE_COOPERATIVE_H_

@ -0,0 +1,63 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* this comes from the `reuse' library. copy any changes back to the source */
#ifndef _ODE_ERROR_H_
#define _ODE_ERROR_H_
#include <ode/odeconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
/* all user defined error functions have this type. error and debug functions
* should not return.
*/
typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
/* set a new error, debug or warning handler. if fn is 0, the default handlers
* are used.
*/
ODE_API void dSetErrorHandler (dMessageFunction *fn);
ODE_API void dSetDebugHandler (dMessageFunction *fn);
ODE_API void dSetMessageHandler (dMessageFunction *fn);
/* return the current error, debug or warning handler. if the return value is
* 0, the default handlers are in place.
*/
ODE_API dMessageFunction *dGetErrorHandler(void);
ODE_API dMessageFunction *dGetDebugHandler(void);
ODE_API dMessageFunction *dGetMessageHandler(void);
/* generate a fatal error, debug trap or a message. */
ODE_API void ODE_NORETURN dError (int num, const char *msg, ...);
ODE_API void ODE_NORETURN dDebug (int num, const char *msg, ...);
ODE_API void dMessage (int num, const char *msg, ...);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,40 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_EXPORT_DIF_
#define _ODE_EXPORT_DIF_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
ODE_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,144 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_MASS_H_
#define _ODE_MASS_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
struct dMass;
typedef struct dMass dMass;
/**
* Check if a mass structure has valid value.
* The function check if the mass and innertia matrix are positive definits
*
* @param m A mass structure to check
*
* @return 1 if both codition are met
*/
ODE_API int dMassCheck(const dMass *m);
ODE_API void dMassSetZero (dMass *);
ODE_API void dMassSetParameters (dMass *, dReal themass,
dReal cgx, dReal cgy, dReal cgz,
dReal I11, dReal I22, dReal I33,
dReal I12, dReal I13, dReal I23);
ODE_API void dMassSetSphere (dMass *, dReal density, dReal radius);
ODE_API void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius);
ODE_API void dMassSetCapsule (dMass *, dReal density, int direction,
dReal radius, dReal length);
ODE_API void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction,
dReal radius, dReal length);
ODE_API void dMassSetCylinder (dMass *, dReal density, int direction,
dReal radius, dReal length);
ODE_API void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction,
dReal radius, dReal length);
ODE_API void dMassSetBox (dMass *, dReal density,
dReal lx, dReal ly, dReal lz);
ODE_API void dMassSetBoxTotal (dMass *, dReal total_mass,
dReal lx, dReal ly, dReal lz);
ODE_API void dMassSetTrimesh (dMass *, dReal density, dGeomID g);
ODE_API void dMassSetTrimeshTotal (dMass *m, dReal total_mass, dGeomID g);
ODE_API void dMassAdjust (dMass *, dReal newmass);
ODE_API void dMassTranslate (dMass *, dReal x, dReal y, dReal z);
ODE_API void dMassRotate (dMass *, const dMatrix3 R);
ODE_API void dMassAdd (dMass *a, const dMass *b);
/* Backwards compatible API */
ODE_API_DEPRECATED ODE_API void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e);
ODE_API_DEPRECATED ODE_API void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e);
struct dMass {
dReal mass;
dVector3 c;
dMatrix3 I;
#ifdef __cplusplus
dMass()
{ dMassSetZero (this); }
void setZero()
{ dMassSetZero (this); }
void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz,
dReal I11, dReal I22, dReal I33,
dReal I12, dReal I13, dReal I23)
{ dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); }
void setSphere (dReal density, dReal radius)
{ dMassSetSphere (this,density,radius); }
void setSphereTotal (dReal total, dReal radius)
{ dMassSetSphereTotal (this,total,radius); }
void setCapsule (dReal density, int direction, dReal radius, dReal length)
{ dMassSetCapsule (this,density,direction,radius,length); }
void setCapsuleTotal (dReal total, int direction, dReal radius, dReal length)
{ dMassSetCapsule (this,total,direction,radius,length); }
void setCylinder(dReal density, int direction, dReal radius, dReal length)
{ dMassSetCylinder (this,density,direction,radius,length); }
void setCylinderTotal(dReal total, int direction, dReal radius, dReal length)
{ dMassSetCylinderTotal (this,total,direction,radius,length); }
void setBox (dReal density, dReal lx, dReal ly, dReal lz)
{ dMassSetBox (this,density,lx,ly,lz); }
void setBoxTotal (dReal total, dReal lx, dReal ly, dReal lz)
{ dMassSetBoxTotal (this,total,lx,ly,lz); }
void setTrimesh(dReal density, dGeomID g)
{ dMassSetTrimesh (this, density, g); }
void setTrimeshTotal(dReal total, dGeomID g)
{ dMassSetTrimeshTotal (this, total, g); }
void adjust (dReal newmass)
{ dMassAdjust (this,newmass); }
void translate (dReal x, dReal y, dReal z)
{ dMassTranslate (this,x,y,z); }
void rotate (const dMatrix3 R)
{ dMassRotate (this,R); }
void add (const dMass *b)
{ dMassAdd (this,b); }
#endif
};
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,200 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* optimized and unoptimized vector and matrix functions */
#ifndef _ODE_MATRIX_H_
#define _ODE_MATRIX_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/* set a vector/matrix of size n to all zeros, or to a specific value. */
ODE_API void dSetZero (dReal *a, int n);
ODE_API void dSetValue (dReal *a, int n, dReal value);
/* get the dot product of two n*1 vectors. if n <= 0 then
* zero will be returned (in which case a and b need not be valid).
*/
ODE_API dReal dDot (const dReal *a, const dReal *b, int n);
/* get the dot products of (a0,b), (a1,b), etc and return them in outsum.
* all vectors are n*1. if n <= 0 then zeroes will be returned (in which case
* the input vectors need not be valid). this function is somewhat faster
* than calling dDot() for all of the combinations separately.
*/
/* NOT INCLUDED in the library for now.
void dMultidot2 (const dReal *a0, const dReal *a1,
const dReal *b, dReal *outsum, int n);
*/
/* matrix multiplication. all matrices are stored in standard row format.
* the digit refers to the argument that is transposed:
* 0: A = B * C (sizes: A:p*r B:p*q C:q*r)
* 1: A = B' * C (sizes: A:p*r B:q*p C:q*r)
* 2: A = B * C' (sizes: A:p*r B:p*q C:r*q)
* case 1,2 are equivalent to saying that the operation is A=B*C but
* B or C are stored in standard column format.
*/
ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
/* do an in-place cholesky decomposition on the lower triangle of the n*n
* symmetric matrix A (which is stored by rows). the resulting lower triangle
* will be such that L*L'=A. return 1 on success and 0 on failure (on failure
* the matrix is not positive definite).
*/
ODE_API int dFactorCholesky (dReal *A, int n);
/* solve for x: L*L'*x = b, and put the result back into x.
* L is size n*n, b is size n*1. only the lower triangle of L is considered.
*/
ODE_API void dSolveCholesky (const dReal *L, dReal *b, int n);
/* compute the inverse of the n*n positive definite matrix A and put it in
* Ainv. this is not especially fast. this returns 1 on success (A was
* positive definite) or 0 on failure (not PD).
*/
ODE_API int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n);
/* check whether an n*n matrix A is positive definite, return 1/0 (yes/no).
* positive definite means that x'*A*x > 0 for any x. this performs a
* cholesky decomposition of A. if the decomposition fails then the matrix
* is not positive definite. A is stored by rows. A is not altered.
*/
ODE_API int dIsPositiveDefinite (const dReal *A, int n);
/* factorize a matrix A into L*D*L', where L is lower triangular with ones on
* the diagonal, and D is diagonal.
* A is an n*n matrix stored by rows, with a leading dimension of n rounded
* up to 4. L is written into the strict lower triangle of A (the ones are not
* written) and the reciprocal of the diagonal elements of D are written into
* d.
*/
ODE_API void dFactorLDLT (dReal *A, dReal *d, int n, int nskip);
/* solve L*x=b, where L is n*n lower triangular with ones on the diagonal,
* and x,b are n*1. b is overwritten with x.
* the leading dimension of L is `nskip'.
*/
ODE_API void dSolveL1 (const dReal *L, dReal *b, int n, int nskip);
/* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal,
* and x,b are n*1. b is overwritten with x.
* the leading dimension of L is `nskip'.
*/
ODE_API void dSolveL1T (const dReal *L, dReal *b, int n, int nskip);
/* in matlab syntax: a(1:n) = a(1:n) .* d(1:n)
*/
ODE_API void dScaleVector (dReal *a, const dReal *d, int n);
/* The function is an alias for @c dScaleVector.
* It has been deprecated because of a wrong naming schema used.
*/
ODE_API_DEPRECATED ODE_API void dVectorScale (dReal *a, const dReal *d, int n);
/* given `L', a n*n lower triangular matrix with ones on the diagonal,
* and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix
* D, solve L*D*L'*x=b where x,b are n*1. x overwrites b.
* the leading dimension of L is `nskip'.
*/
ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
/* given an L*D*L' factorization of an n*n matrix A, return the updated
* factorization L2*D2*L2' of A plus the following "top left" matrix:
*
* [ b a' ] <-- b is a[0]
* [ a 0 ] <-- a is a[1..n-1]
*
* - L has size n*n, its leading dimension is nskip. L is lower triangular
* with ones on the diagonal. only the lower triangle of L is referenced.
* - d has size n. d contains the reciprocal diagonal elements of D.
* - a has size n.
* the result is written into L, except that the left column of L and d[0]
* are not actually modified. see ldltaddTL.m for further comments.
*/
ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip);
/* given an L*D*L' factorization of a permuted matrix A, produce a new
* factorization for row and column `r' removed.
* - A has size n1*n1, its leading dimension in nskip. A is symmetric and
* positive definite. only the lower triangle of A is referenced.
* A itself may actually be an array of row pointers.
* - L has size n2*n2, its leading dimension in nskip. L is lower triangular
* with ones on the diagonal. only the lower triangle of L is referenced.
* - d has size n2. d contains the reciprocal diagonal elements of D.
* - p is a permutation vector. it contains n2 indexes into A. each index
* must be in the range 0..n1-1.
* - r is the row/column of L to remove.
* the new L will be written within the old L, i.e. will have the same leading
* dimension. the last row and column of L, and the last element of d, are
* undefined on exit.
*
* a fast O(n^2) algorithm is used. see ldltremove.m for further comments.
*/
ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
int n1, int n2, int r, int nskip);
/* given an n*n matrix A (with leading dimension nskip), remove the r'th row
* and column by moving elements. the new matrix will have the same leading
* dimension. the last row and column of A are untouched on exit.
*/
ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,291 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_MATRIX_COOP_H_
#define _ODE_MATRIX_COOP_H_
#include <ode/common.h>
#include <ode/cooperative.h>
#include <ode/threading.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup matrix_coop Matrix Cooperative Algorithms
*
* Cooperative algorithms operating on matrices and vectors.
*
* @ingroup coop
*/
/**
* @brief Estimates resource requirements for a @c dCooperativelyFactorLDLT call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelyFactorLDLT with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalRowCount Maximal value of rowCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelyFactorLDLT
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelyFactorLDLTResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
/**
* @brief Cooperatively factorizes a matrix `A' into L*D*L'
*
* The function factorizes a matrix `A' into L*D*L', where `L' is lower triangular with ones on
* the diagonal, and `D' is diagonal.
* @a A is a rowCount*rowCount matrix stored by rows, with a leading dimension of @a rowCount rounded
* up at least to 4 elements. `L; is written into the strict lower triangle of @a A
* (the ones are not written) and the reciprocal of the diagonal elements of `D' are written into @a d.
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelyFactorLDLTResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param A The `A' matrix
* @param d The `d' vector
* @param rowCount The row count in @a A and @a d
* @param rowskip The actual number of elements to be added to skip to next row in @a A
* @ingroup matrix_coop
* @see dEstimateCooperativelyFactorLDLTResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelySolveLDLT
*/
ODE_API void dCooperativelyFactorLDLT(dResourceContainerID resources, unsigned allowedThreadCount,
dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip);
/**
* @brief Estimates resource requirements for a @c dCooperativelySolveLDLT call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelySolveLDLT with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalRowCount Maximal value of rowCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelySolveLDLT
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelySolveLDLTResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
/**
* @brief Cooperatively solves L*D*L'*x=b
*
* Given `L', a rowCount*rowCount lower triangular matrix with ones on the diagonal,
* and `d', a rowCount*1 vector of the reciprocal diagonal elements of a rowCount*rowCount matrix
* D, the function solves L*D*L'*x=b where `x' and `b' are rowCount*1.
* The leading dimension of @a L is @a rowSkip. The resulting vector `x' overwrites @a b.
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelySolveLDLTResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param L The `L' matrix
* @param d The `d' vector
* @param b The `b' vector; also the result is stored here
* @param rowCount The row count in @a L, @a d and @a b
* @param rowskip The actual number of elements to be added to skip to next row in @a L
* @ingroup matrix_coop
* @see dEstimateCooperativelySolveLDLTResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelyFactorLDLT
*/
ODE_API void dCooperativelySolveLDLT(dResourceContainerID resources, unsigned allowedThreadCount,
const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip);
/**
* @brief Estimates resource requirements for a @c dCooperativelySolveL1Straight call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelySolveL1Straight with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalRowCount Maximal value of rowCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelySolveL1Straight
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelySolveL1StraightResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
/**
* @brief Cooperatively solves L*x=b
*
* The function solves L*x=b, where `L' is rowCount*rowCount lower triangular with ones on the diagonal,
* and `x', `b' are rowCount*1. The leading dimension of @a L is @a rowSkip.
* @a b is overwritten with `x'.
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelySolveL1StraightResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param L The `L' matrix
* @param b The `b' vector; also the result is stored here
* @param rowCount The row count in @a L and @a b
* @param rowskip The actual number of elements to be added to skip to next row in @a L
* @ingroup matrix_coop
* @see dEstimateCooperativelySolveL1StraightResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelyFactorLDLT
*/
ODE_API void dCooperativelySolveL1Straight(dResourceContainerID resources, unsigned allowedThreadCount,
const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip);
/**
* @brief Estimates resource requirements for a @c dCooperativelySolveL1Transposed call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelySolveL1Transposed with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalRowCount Maximal value of rowCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelySolveL1Transposed
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelySolveL1TransposedResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
/**
* @brief Cooperatively solves L'*x=b
*
* The function solves L'*x=b, where `L' is rowCount*rowCount lower triangular with ones on the diagonal,
* and `x', b are rowCount*1. The leading dimension of @a L is @a rowSkip.
* @a b is overwritten with `x'.
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelySolveL1TransposedResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param L The `L' matrix
* @param b The `b' vector; also the result is stored here
* @param rowCount The row count in @a L and @a b
* @param rowskip The actual number of elements to be added to skip to next row in @a L
* @ingroup matrix_coop
* @see dEstimateCooperativelySolveL1TransposedResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelyFactorLDLT
*/
ODE_API void dCooperativelySolveL1Transposed(dResourceContainerID resources, unsigned allowedThreadCount,
const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip);
/**
* @brief Estimates resource requirements for a @c dCooperativelyScaleVector call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelyScaleVector with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalElementCount Maximal value of elementCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelyScaleVector
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelyScaleVectorResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalElementCount);
/**
* @brief Multiplies elements of one vector by corresponding element of another one
*
* In matlab syntax, the operation performed is: dataVector(1:elementCount) = dataVector(1:elementCount) .* scaleVector(1:elementCount)
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelyScaleVectorResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param dataVector The vector to be scaled in place
* @param scaleVector The scale vector
* @param elementCount The number of elements in @a dataVector and @a scaleVector
* @ingroup matrix_coop
* @see dEstimateCooperativelyScaleVectorResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelyFactorLDLT
*/
ODE_API void dCooperativelyScaleVector(dResourceContainerID resources, unsigned allowedThreadCount,
dReal *dataVector, const dReal *scaleVector, unsigned elementCount);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef _ODE_MATRIX_COOP_H_

@ -0,0 +1,59 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* this comes from the `reuse' library. copy any changes back to the source */
#ifndef _ODE_MEMORY_H_
#define _ODE_MEMORY_H_
#include <ode/odeconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
/* function types to allocate and free memory */
typedef void * dAllocFunction (dsizeint size);
typedef void * dReallocFunction (void *ptr, dsizeint oldsize, dsizeint newsize);
typedef void dFreeFunction (void *ptr, dsizeint size);
/* set new memory management functions. if fn is 0, the default handlers are
* used. */
ODE_API void dSetAllocHandler (dAllocFunction *fn);
ODE_API void dSetReallocHandler (dReallocFunction *fn);
ODE_API void dSetFreeHandler (dFreeFunction *fn);
/* get current memory management functions */
ODE_API dAllocFunction *dGetAllocHandler (void);
ODE_API dReallocFunction *dGetReallocHandler (void);
ODE_API dFreeFunction *dGetFreeHandler (void);
/* allocate and free memory. */
ODE_API void * dAlloc (dsizeint size);
ODE_API void * dRealloc (void *ptr, dsizeint oldsize, dsizeint newsize);
ODE_API void dFree (void *ptr, dsizeint size);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,86 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* miscellaneous math functions. these are mostly useful for testing */
#ifndef _ODE_MISC_H_
#define _ODE_MISC_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/* return 1 if the random number generator is working. */
ODE_API int dTestRand(void);
/* return next 32 bit random number. this uses a not-very-random linear
* congruential method.
*/
ODE_API unsigned long dRand(void);
/* get and set the current random number seed. */
ODE_API unsigned long dRandGetSeed(void);
ODE_API void dRandSetSeed (unsigned long s);
/* return a random integer between 0..n-1. the distribution will get worse
* as n approaches 2^32.
*/
ODE_API int dRandInt (int n);
/* return a random real number between 0..1 */
ODE_API dReal dRandReal(void);
/* print out a matrix */
ODE_API void dPrintMatrix (const dReal *A, int n, int m, const char *fmt, FILE *f);
/* make a random vector with entries between +/- range. A has n elements. */
ODE_API void dMakeRandomVector (dReal *A, int n, dReal range);
/* make a random matrix with entries between +/- range. A has size n*m. */
ODE_API void dMakeRandomMatrix (dReal *A, int n, int m, dReal range);
/* clear the upper triangle of a square matrix */
ODE_API void dClearUpperTriangle (dReal *A, int n);
/* return the maximum element difference between the two n*m matrices */
ODE_API dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m);
/* return the maximum element difference between the lower triangle of two
* n*n matrices */
ODE_API dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
static inline void dPrintMatrix (const dReal *A, int n, int m, const char *fmt="%10.4f ") { dPrintMatrix(A, n, m, fmt, stdout); }
#endif
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,56 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ODE_H_
#define _ODE_ODE_H_
/* include *everything* here */
#include <ode/odeconfig.h>
#include <ode/compatibility.h>
#include <ode/common.h>
#include <ode/odeinit.h>
#include <ode/contact.h>
#include <ode/error.h>
#include <ode/memory.h>
#include <ode/odemath.h>
#include <ode/matrix.h>
#include <ode/matrix_coop.h>
#include <ode/timer.h>
#include <ode/rotation.h>
#include <ode/mass.h>
#include <ode/misc.h>
#include <ode/objects.h>
#include <ode/collision_space.h>
#include <ode/collision.h>
#include <ode/threading.h>
#include <ode/threading_impl.h>
#include <ode/cooperative.h>
#include <ode/export-dif.h>
#include <ode/version.h>
#ifdef __cplusplus
# include <ode/odecpp.h>
# include <ode/odecpp_collision.h>
#endif
#endif

@ -0,0 +1,215 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ODECONFIG_H_
#define _ODE_ODECONFIG_H_
/* Pull in the standard headers */
#include <stddef.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <float.h>
#include <ode/precision.h>
#if defined(ODE_DLL) || defined(ODE_LIB)
#define __ODE__
#endif
/* Define a DLL export symbol for those platforms that need it */
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(_WIN32))
#if defined(ODE_DLL)
#define ODE_API __declspec(dllexport)
#elif !defined(ODE_LIB)
#define ODE_DLL_API __declspec(dllimport)
#endif
#endif
#if !defined(ODE_API)
#define ODE_API
#endif
#if defined(_MSC_VER)
# define ODE_API_DEPRECATED __declspec(deprecated)
#elif defined (__GNUC__) && ( (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) )
# define ODE_API_DEPRECATED __attribute__((__deprecated__))
#else
# define ODE_API_DEPRECATED
#endif
#define ODE_PURE_INLINE static __inline
#define ODE_INLINE __inline
#if defined(__cplusplus)
#define ODE_EXTERN_C extern "C"
#else
#define ODE_EXTERN_C
#endif
#if defined(__GNUC__)
#define ODE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define ODE_NORETURN __declspec(noreturn)
#else // #if !defined(_MSC_VER)
#define ODE_NORETURN
#endif // #if !defined(__GNUC__)
/* Well-defined common data types...need to define for 64 bit systems */
#if defined(__aarch64__)
#include <stdint.h>
typedef int64_t dint64;
typedef uint64_t duint64;
typedef int32_t dint32;
typedef uint32_t duint32;
typedef int16_t dint16;
typedef uint16_t duint16;
typedef int8_t dint8;
typedef uint8_t duint8;
typedef intptr_t dintptr;
typedef uintptr_t duintptr;
typedef ptrdiff_t ddiffint;
typedef size_t dsizeint;
#elif defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__)
#define X86_64_SYSTEM 1
#if defined(_MSC_VER)
typedef __int64 dint64;
typedef unsigned __int64 duint64;
#else
#if defined(_LP64)
typedef long dint64;
typedef unsigned long duint64;
#else
typedef long long dint64;
typedef unsigned long long duint64;
#endif
#endif
typedef int dint32;
typedef unsigned int duint32;
typedef short dint16;
typedef unsigned short duint16;
typedef signed char dint8;
typedef unsigned char duint8;
typedef dint64 dintptr;
typedef duint64 duintptr;
typedef dint64 ddiffint;
typedef duint64 dsizeint;
#else
#if defined(_MSC_VER)
typedef __int64 dint64;
typedef unsigned __int64 duint64;
#else
typedef long long dint64;
typedef unsigned long long duint64;
#endif
typedef int dint32;
typedef unsigned int duint32;
typedef short dint16;
typedef unsigned short duint16;
typedef signed char dint8;
typedef unsigned char duint8;
typedef dint32 dintptr;
typedef duint32 duintptr;
typedef dint32 ddiffint;
typedef duint32 dsizeint;
#endif
/* Define the dInfinity macro */
#ifdef INFINITY
#ifdef dSINGLE
#define dInfinity ((float)INFINITY)
#else
#define dInfinity ((double)INFINITY)
#endif
#elif defined(HUGE_VAL)
#ifdef dSINGLE
#ifdef HUGE_VALF
#define dInfinity HUGE_VALF
#else
#define dInfinity ((float)HUGE_VAL)
#endif
#else
#define dInfinity HUGE_VAL
#endif
#else
#ifdef dSINGLE
#define dInfinity ((float)(1.0/0.0))
#else
#define dInfinity (1.0/0.0)
#endif
#endif
/* Define the dNaN macro */
#if defined(NAN)
#define dNaN NAN
#elif defined(__GNUC__)
#define dNaN ({ union { duint32 m_ui; float m_f; } un; un.m_ui = 0x7FC00000; un.m_f; })
#elif defined(__cplusplus)
union _dNaNUnion
{
_dNaNUnion(): m_ui(0x7FC00000) {}
duint32 m_ui;
float m_f;
};
#define dNaN (_dNaNUnion().m_f)
#else
#ifdef dSINGLE
#define dNaN ((float)(dInfinity - dInfinity))
#else
#define dNaN (dInfinity - dInfinity)
#endif
#endif
/* Visual C does not define these functions */
#if defined(_MSC_VER)
#define _ode_copysignf(x, y) ((float)_copysign(x, y))
#define _ode_copysign(x, y) _copysign(x, y)
#define _ode_nextafterf(x, y) _nextafterf(x, y)
#define _ode_nextafter(x, y) _nextafter(x, y)
#if !defined(_WIN64) && defined(dSINGLE)
#define _ODE__NEXTAFTERF_REQUIRED
ODE_EXTERN_C float _nextafterf(float x, float y);
#endif
#else
#define _ode_copysignf(x, y) copysignf(x, y)
#define _ode_copysign(x, y) copysign(x, y)
#define _ode_nextafterf(x, y) nextafterf(x, y)
#define _ode_nextafter(x, y) nextafter(x, y)
#endif
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,467 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* C++ interface for new collision API */
#ifndef _ODE_ODECPP_COLLISION_H_
#define _ODE_ODECPP_COLLISION_H_
#ifdef __cplusplus
//#include <ode/error.h>
//namespace ode {
class dGeom {
// intentionally undefined, don't use these
dGeom (dGeom &);
void operator= (dGeom &);
protected:
dGeomID _id;
dGeom()
{ _id = 0; }
public:
~dGeom()
{ if (_id) dGeomDestroy (_id); }
dGeomID id() const
{ return _id; }
operator dGeomID() const
{ return _id; }
void destroy() {
if (_id) dGeomDestroy (_id);
_id = 0;
}
int getClass() const
{ return dGeomGetClass (_id); }
dSpaceID getSpace() const
{ return dGeomGetSpace (_id); }
void setData (void *data)
{ dGeomSetData (_id,data); }
void *getData() const
{ return dGeomGetData (_id); }
void setBody (dBodyID b)
{ dGeomSetBody (_id,b); }
dBodyID getBody() const
{ return dGeomGetBody (_id); }
void setPosition (dReal x, dReal y, dReal z)
{ dGeomSetPosition (_id,x,y,z); }
const dReal * getPosition() const
{ return dGeomGetPosition (_id); }
void setRotation (const dMatrix3 R)
{ dGeomSetRotation (_id,R); }
const dReal * getRotation() const
{ return dGeomGetRotation (_id); }
void setQuaternion (const dQuaternion quat)
{ dGeomSetQuaternion (_id,quat); }
void getQuaternion (dQuaternion quat) const
{ dGeomGetQuaternion (_id,quat); }
void getAABB (dReal aabb[6]) const
{ dGeomGetAABB (_id, aabb); }
int isSpace()
{ return dGeomIsSpace (_id); }
void setCategoryBits (unsigned long bits)
{ dGeomSetCategoryBits (_id, bits); }
void setCollideBits (unsigned long bits)
{ dGeomSetCollideBits (_id, bits); }
unsigned long getCategoryBits()
{ return dGeomGetCategoryBits (_id); }
unsigned long getCollideBits()
{ return dGeomGetCollideBits (_id); }
void enable()
{ dGeomEnable (_id); }
void disable()
{ dGeomDisable (_id); }
int isEnabled()
{ return dGeomIsEnabled (_id); }
void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
{ dGeomGetRelPointPos (_id, px, py, pz, result); }
void getRelPointPos (const dVector3 p, dVector3 result) const
{ getRelPointPos (p[0], p[1], p[2], result); }
void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
{ dGeomGetPosRelPoint (_id, px, py, pz, result); }
void getPosRelPoint (const dVector3 p, dVector3 result) const
{ getPosRelPoint (p[0], p[1], p[2], result); }
void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
{ dGeomVectorToWorld (_id, px, py, pz, result); }
void vectorToWorld (const dVector3 p, dVector3 result) const
{ vectorToWorld (p[0], p[1], p[2], result); }
void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
{ dGeomVectorFromWorld (_id, px, py, pz, result); }
void vectorFromWorld (const dVector3 p, dVector3 result) const
{ vectorFromWorld (p[0], p[1], p[2], result); }
void collide2 (dGeomID g, void *data, dNearCallback *callback)
{ dSpaceCollide2 (_id,g,data,callback); }
};
class dSpace : public dGeom {
// intentionally undefined, don't use these
dSpace (dSpace &);
void operator= (dSpace &);
protected:
// the default constructor is protected so that you
// can't instance this class. you must instance one
// of its subclasses instead.
dSpace () { _id = 0; }
public:
dSpaceID id() const
{ return (dSpaceID) _id; }
operator dSpaceID() const
{ return (dSpaceID) _id; }
void setCleanup (int mode)
{ dSpaceSetCleanup (id(), mode); }
int getCleanup()
{ return dSpaceGetCleanup (id()); }
void add (dGeomID x)
{ dSpaceAdd (id(), x); }
void remove (dGeomID x)
{ dSpaceRemove (id(), x); }
int query (dGeomID x)
{ return dSpaceQuery (id(),x); }
int getNumGeoms()
{ return dSpaceGetNumGeoms (id()); }
dGeomID getGeom (int i)
{ return dSpaceGetGeom (id(),i); }
void collide (void *data, dNearCallback *callback)
{ dSpaceCollide (id(),data,callback); }
};
class dSimpleSpace : public dSpace {
// intentionally undefined, don't use these
dSimpleSpace (dSimpleSpace &);
void operator= (dSimpleSpace &);
public:
dSimpleSpace ()
{ _id = (dGeomID) dSimpleSpaceCreate (0); }
dSimpleSpace (dSpace &space)
{ _id = (dGeomID) dSimpleSpaceCreate (space.id()); }
dSimpleSpace (dSpaceID space)
{ _id = (dGeomID) dSimpleSpaceCreate (space); }
};
class dHashSpace : public dSpace {
// intentionally undefined, don't use these
dHashSpace (dHashSpace &);
void operator= (dHashSpace &);
public:
dHashSpace ()
{ _id = (dGeomID) dHashSpaceCreate (0); }
dHashSpace (dSpace &space)
{ _id = (dGeomID) dHashSpaceCreate (space.id()); }
dHashSpace (dSpaceID space)
{ _id = (dGeomID) dHashSpaceCreate (space); }
void setLevels (int minlevel, int maxlevel)
{ dHashSpaceSetLevels (id(),minlevel,maxlevel); }
};
class dQuadTreeSpace : public dSpace {
// intentionally undefined, don't use these
dQuadTreeSpace (dQuadTreeSpace &);
void operator= (dQuadTreeSpace &);
public:
dQuadTreeSpace (const dVector3 center, const dVector3 extents, int depth)
{ _id = (dGeomID) dQuadTreeSpaceCreate (0,center,extents,depth); }
dQuadTreeSpace (dSpace &space, const dVector3 center, const dVector3 extents, int depth)
{ _id = (dGeomID) dQuadTreeSpaceCreate (space.id(),center,extents,depth); }
dQuadTreeSpace (dSpaceID space, const dVector3 center, const dVector3 extents, int depth)
{ _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); }
};
class dSphere : public dGeom {
// intentionally undefined, don't use these
dSphere (dSphere &);
void operator= (dSphere &);
public:
dSphere () { }
dSphere (dReal radius)
{ _id = dCreateSphere (0, radius); }
dSphere (dSpace &space, dReal radius)
{ _id = dCreateSphere (space.id(), radius); }
dSphere (dSpaceID space, dReal radius)
{ _id = dCreateSphere (space, radius); }
void create (dSpaceID space, dReal radius) {
if (_id) dGeomDestroy (_id);
_id = dCreateSphere (space, radius);
}
void setRadius (dReal radius)
{ dGeomSphereSetRadius (_id, radius); }
dReal getRadius() const
{ return dGeomSphereGetRadius (_id); }
};
class dBox : public dGeom {
// intentionally undefined, don't use these
dBox (dBox &);
void operator= (dBox &);
public:
dBox () { }
dBox (dReal lx, dReal ly, dReal lz)
{ _id = dCreateBox (0,lx,ly,lz); }
dBox (dSpace &space, dReal lx, dReal ly, dReal lz)
{ _id = dCreateBox (space,lx,ly,lz); }
dBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
{ _id = dCreateBox (space,lx,ly,lz); }
void create (dSpaceID space, dReal lx, dReal ly, dReal lz) {
if (_id) dGeomDestroy (_id);
_id = dCreateBox (space,lx,ly,lz);
}
void setLengths (dReal lx, dReal ly, dReal lz)
{ dGeomBoxSetLengths (_id, lx, ly, lz); }
void getLengths (dVector3 result) const
{ dGeomBoxGetLengths (_id,result); }
};
class dPlane : public dGeom {
// intentionally undefined, don't use these
dPlane (dPlane &);
void operator= (dPlane &);
public:
dPlane() { }
dPlane (dReal a, dReal b, dReal c, dReal d)
{ _id = dCreatePlane (0,a,b,c,d); }
dPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d)
{ _id = dCreatePlane (space.id(),a,b,c,d); }
dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d)
{ _id = dCreatePlane (space,a,b,c,d); }
void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) {
if (_id) dGeomDestroy (_id);
_id = dCreatePlane (space,a,b,c,d);
}
void setParams (dReal a, dReal b, dReal c, dReal d)
{ dGeomPlaneSetParams (_id, a, b, c, d); }
void getParams (dVector4 result) const
{ dGeomPlaneGetParams (_id,result); }
};
class dCapsule : public dGeom {
// intentionally undefined, don't use these
dCapsule (dCapsule &);
void operator= (dCapsule &);
public:
dCapsule() { }
dCapsule (dReal radius, dReal length)
{ _id = dCreateCapsule (0,radius,length); }
dCapsule (dSpace &space, dReal radius, dReal length)
{ _id = dCreateCapsule (space.id(),radius,length); }
dCapsule (dSpaceID space, dReal radius, dReal length)
{ _id = dCreateCapsule (space,radius,length); }
void create (dSpaceID space, dReal radius, dReal length) {
if (_id) dGeomDestroy (_id);
_id = dCreateCapsule (space,radius,length);
}
void setParams (dReal radius, dReal length)
{ dGeomCapsuleSetParams (_id, radius, length); }
void getParams (dReal *radius, dReal *length) const
{ dGeomCapsuleGetParams (_id,radius,length); }
};
class dCylinder : public dGeom {
// intentionally undefined, don't use these
dCylinder (dCylinder &);
void operator= (dCylinder &);
public:
dCylinder() { }
dCylinder (dReal radius, dReal length)
{ _id = dCreateCylinder (0,radius,length); }
dCylinder (dSpace &space, dReal radius, dReal length)
{ _id = dCreateCylinder (space.id(),radius,length); }
dCylinder (dSpaceID space, dReal radius, dReal length)
{ _id = dCreateCylinder (space,radius,length); }
void create (dSpaceID space, dReal radius, dReal length) {
if (_id) dGeomDestroy (_id);
_id = dCreateCylinder (space,radius,length);
}
void setParams (dReal radius, dReal length)
{ dGeomCylinderSetParams (_id, radius, length); }
void getParams (dReal *radius, dReal *length) const
{ dGeomCylinderGetParams (_id,radius,length); }
};
class dRay : public dGeom {
// intentionally undefined, don't use these
dRay (dRay &);
void operator= (dRay &);
public:
dRay() { }
dRay (dReal length)
{ _id = dCreateRay (0,length); }
dRay (dSpace &space, dReal length)
{ _id = dCreateRay (space.id(),length); }
dRay (dSpaceID space, dReal length)
{ _id = dCreateRay (space,length); }
void create (dSpaceID space, dReal length) {
if (_id) dGeomDestroy (_id);
_id = dCreateRay (space,length);
}
void setLength (dReal length)
{ dGeomRaySetLength (_id, length); }
dReal getLength()
{ return dGeomRayGetLength (_id); }
void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz)
{ dGeomRaySet (_id, px, py, pz, dx, dy, dz); }
void get (dVector3 start, dVector3 dir)
{ dGeomRayGet (_id, start, dir); }
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4996 )
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
ODE_API_DEPRECATED
void setParams (int firstContact, int backfaceCull)
{ dGeomRaySetParams (_id, firstContact, backfaceCull); }
ODE_API_DEPRECATED
void getParams (int *firstContact, int *backfaceCull)
{ dGeomRayGetParams (_id, firstContact, backfaceCull); }
#ifdef WIN32
#pragma warning( pop )
#else
#pragma GCC diagnostic pop
#endif
void setBackfaceCull (int backfaceCull)
{ dGeomRaySetBackfaceCull (_id, backfaceCull); }
int getBackfaceCull()
{ return dGeomRayGetBackfaceCull (_id); }
void setFirstContact (int firstContact)
{ dGeomRaySetFirstContact (_id, firstContact); }
int getFirstContact()
{ return dGeomRayGetFirstContact (_id); }
void setClosestHit (int closestHit)
{ dGeomRaySetClosestHit (_id, closestHit); }
int getClosestHit()
{ return dGeomRayGetClosestHit (_id); }
};
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4996 )
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
class ODE_API_DEPRECATED dGeomTransform : public dGeom {
// intentionally undefined, don't use these
dGeomTransform (dGeomTransform &);
void operator= (dGeomTransform &);
public:
dGeomTransform() { }
dGeomTransform (dSpace &space)
{ _id = dCreateGeomTransform (space.id()); }
dGeomTransform (dSpaceID space)
{ _id = dCreateGeomTransform (space); }
void create (dSpaceID space=0) {
if (_id) dGeomDestroy (_id);
_id = dCreateGeomTransform (space);
}
void setGeom (dGeomID geom)
{ dGeomTransformSetGeom (_id, geom); }
dGeomID getGeom() const
{ return dGeomTransformGetGeom (_id); }
void setCleanup (int mode)
{ dGeomTransformSetCleanup (_id,mode); }
int getCleanup ()
{ return dGeomTransformGetCleanup (_id); }
void setInfo (int mode)
{ dGeomTransformSetInfo (_id,mode); }
int getInfo()
{ return dGeomTransformGetInfo (_id); }
};
#ifdef WIN32
#pragma warning( pop )
#else
#pragma GCC diagnostic pop
#endif
//}
#endif
#endif

@ -0,0 +1,236 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* Library initialization/finalization functions. */
#ifndef _ODE_ODEINIT_H_
#define _ODE_ODEINIT_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ************************************************************************ */
/* Library initialization */
/**
* @defgroup init Library Initialization
*
* Library initialization functions prepare ODE internal data structures for use
* and release allocated resources after ODE is not needed any more.
*/
/**
* @brief Library initialization flags.
*
* These flags define ODE library initialization options.
*
* @c dInitFlagManualThreadCleanup indicates that resources allocated in TLS for threads
* using ODE are to be cleared by library client with explicit call to @c dCleanupODEAllDataForThread.
* If this flag is not specified the automatic resource tracking algorithm is used.
*
* With automatic resource tracking, On Windows, memory allocated for a thread may
* remain not freed for some time after the thread exits. The resources may be
* released when one of other threads calls @c dAllocateODEDataForThread. Ultimately,
* the resources are released when library is closed with @c dCloseODE. On other
* operating systems resources are always released by the thread itself on its exit
* or on library closure with @c dCloseODE.
*
* With manual thread data cleanup mode every collision space object must be
* explicitly switched to manual cleanup mode with @c dSpaceSetManualCleanup
* after creation. See description of the function for more details.
*
* If @c dInitFlagManualThreadCleanup was not specified during initialization,
* calls to @c dCleanupODEAllDataForThread are not allowed.
*
* @see dInitODE2
* @see dAllocateODEDataForThread
* @see dSpaceSetManualCleanup
* @see dCloseODE
* @ingroup init
*/
enum dInitODEFlags {
dInitFlagManualThreadCleanup = 0x00000001 /*@< Thread local data is to be cleared explicitly on @c dCleanupODEAllDataForThread function call*/
};
/**
* @brief Initializes ODE library.
*
* @c dInitODE is obsolete. @c dInitODE2 is to be used for library initialization.
*
* A call to @c dInitODE is equal to the following initialization sequence
* @code
* dInitODE2(0);
* dAllocateODEDataForThread(dAllocateMaskAll);
* @endcode
*
* @see dInitODE2
* @see dAllocateODEDataForThread
* @ingroup init
*/
ODE_API void dInitODE(void);
/**
* @brief Initializes ODE library.
* @param uiInitFlags Initialization options bitmask
* @return A nonzero if initialization succeeded and zero otherwise.
*
* This function must be called to initialize ODE library before first use. If
* initialization succeeds the function may not be called again until library is
* closed with a call to @c dCloseODE.
*
* The @a uiInitFlags parameter specifies initialization options to be used. These
* can be combination of zero or more @c dInitODEFlags flags.
*
* @note
* If @c dInitFlagManualThreadCleanup flag is used for initialization,
* @c dSpaceSetManualCleanup must be called to set manual cleanup mode for every
* space object right after creation. Failure to do so may lead to resource leaks.
*
* @see dInitODEFlags
* @see dCloseODE
* @see dSpaceSetManualCleanup
* @ingroup init
*/
ODE_API int dInitODE2(unsigned int uiInitFlags/*=0*/);
/**
* @brief ODE data allocation flags.
*
* These flags are used to indicate which data is to be pre-allocated in call to
* @c dAllocateODEDataForThread.
*
* @c dAllocateFlagBasicData tells to allocate the basic data set required for
* normal library operation. This flag is equal to zero and is always implicitly
* included.
*
* @c dAllocateFlagCollisionData tells that collision detection data is to be allocated.
* Collision detection functions may not be called if the data has not be allocated
* in advance. If collision detection is not going to be used, it is not necessary
* to specify this flag.
*
* @c dAllocateMaskAll is a mask that can be used for for allocating all possible
* data in cases when it is not known what exactly features of ODE will be used.
* The mask may not be used in combination with other flags. It is guaranteed to
* include all the current and future legal allocation flags. However, mature
* applications should use explicit flags they need rather than allocating everything.
*
* @see dAllocateODEDataForThread
* @ingroup init
*/
enum dAllocateODEDataFlags {
dAllocateFlagBasicData = 0, /*@< Allocate basic data required for library to operate*/
dAllocateFlagCollisionData = 0x00000001, /*@< Allocate data for collision detection*/
dAllocateMaskAll = ~0 /*@< Allocate all the possible data that is currently defined or will be defined in the future.*/
};
/**
* @brief Allocate thread local data to allow the thread calling ODE.
* @param uiAllocateFlags Allocation options bitmask.
* @return A nonzero if allocation succeeded and zero otherwise.
*
* The function is required to be called for every thread that is going to use
* ODE. This function allocates the data that is required for accessing ODE from
* current thread along with optional data required for particular ODE subsystems.
*
* @a uiAllocateFlags parameter can contain zero or more flags from @c dAllocateODEDataFlags
* enumerated type. Multiple calls with different allocation flags are allowed.
* The flags that are already allocated are ignored in subsequent calls. If zero
* is passed as the parameter, it means to only allocate the set of most important
* data the library can not operate without.
*
* If the function returns failure status it means that none of the requested
* data has been allocated. The client may retry allocation attempt with the same
* flags when more system resources are available.
*
* @see dAllocateODEDataFlags
* @see dCleanupODEAllDataForThread
* @ingroup init
*/
ODE_API int dAllocateODEDataForThread(unsigned int uiAllocateFlags);
/**
* @brief Free thread local data that was allocated for current thread.
*
* If library was initialized with @c dInitFlagManualThreadCleanup flag the function
* is required to be called on exit of every thread that was calling @c dAllocateODEDataForThread.
* Failure to call @c dCleanupODEAllDataForThread may result in some resources remaining
* not freed until program exit. The function may also be called when ODE is still
* being used to release resources allocated for all the current subsystems and
* possibly proceed with data pre-allocation for other subsystems.
*
* The function can safely be called several times in a row. The function can be
* called without prior invocation of @c dAllocateODEDataForThread. The function
* may not be called before ODE is initialized with @c dInitODE2 or after library
* has been closed with @c dCloseODE. A call to @c dCloseODE implicitly releases
* all the thread local resources that might be allocated for all the threads that
* were using ODE.
*
* If library was initialized without @c dInitFlagManualThreadCleanup flag
* @c dCleanupODEAllDataForThread must not be called.
*
* @see dAllocateODEDataForThread
* @see dInitODE2
* @see dCloseODE
* @ingroup init
*/
ODE_API void dCleanupODEAllDataForThread();
/**
* @brief Close ODE after it is not needed any more.
*
* The function is required to be called when program does not need ODE features any more.
* The call to @c dCloseODE releases all the resources allocated for library
* including all the thread local data that might be allocated for all the threads
* that were using ODE.
*
* @c dCloseODE is a paired function for @c dInitODE2 and must only be called
* after successful library initialization.
*
* @note Important!
* Make sure that all the threads that were using ODE have already terminated
* before calling @c dCloseODE. In particular it is not allowed to call
* @c dCleanupODEAllDataForThread after @c dCloseODE.
*
* @see dInitODE2
* @see dCleanupODEAllDataForThread
* @ingroup init
*/
ODE_API void dCloseODE(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _ODE_ODEINIT_H_ */

@ -0,0 +1,545 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ODEMATH_H_
#define _ODE_ODEMATH_H_
#include <ode/common.h>
/*
* macro to access elements i,j in an NxM matrix A, independent of the
* matrix storage convention.
*/
#define dACCESS33(A,i,j) ((A)[(i)*4+(j)])
/*
* Macro to test for valid floating point values
*/
#define dVALIDVEC3(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2])))
#define dVALIDVEC4(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3])))
#define dVALIDMAT3(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11])))
#define dVALIDMAT4(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]) || dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) ))
ODE_PURE_INLINE void dZeroVector3(dVector3 res)
{
res[dV3E_X] = REAL(0.0);
res[dV3E_Y] = REAL(0.0);
res[dV3E_Z] = REAL(0.0);
}
ODE_PURE_INLINE void dAssignVector3(dVector3 res, dReal x, dReal y, dReal z)
{
res[dV3E_X] = x;
res[dV3E_Y] = y;
res[dV3E_Z] = z;
}
ODE_PURE_INLINE void dZeroMatrix3(dMatrix3 res)
{
res[dM3E_XX] = REAL(0.0); res[dM3E_XY] = REAL(0.0); res[dM3E_XZ] = REAL(0.0);
res[dM3E_YX] = REAL(0.0); res[dM3E_YY] = REAL(0.0); res[dM3E_YZ] = REAL(0.0);
res[dM3E_ZX] = REAL(0.0); res[dM3E_ZY] = REAL(0.0); res[dM3E_ZZ] = REAL(0.0);
}
ODE_PURE_INLINE void dZeroMatrix4(dMatrix4 res)
{
res[dM4E_XX] = REAL(0.0); res[dM4E_XY] = REAL(0.0); res[dM4E_XZ] = REAL(0.0); res[dM4E_XO] = REAL(0.0);
res[dM4E_YX] = REAL(0.0); res[dM4E_YY] = REAL(0.0); res[dM4E_YZ] = REAL(0.0); res[dM4E_YO] = REAL(0.0);
res[dM4E_ZX] = REAL(0.0); res[dM4E_ZY] = REAL(0.0); res[dM4E_ZZ] = REAL(0.0); res[dM4E_ZO] = REAL(0.0);
res[dM4E_OX] = REAL(0.0); res[dM4E_OY] = REAL(0.0); res[dM4E_OZ] = REAL(0.0); res[dM4E_OO] = REAL(0.0);
}
/* Some vector math */
ODE_PURE_INLINE void dAddVectors3(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = a[0] + b[0];
const dReal res_1 = a[1] + b[1];
const dReal res_2 = a[2] + b[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dSubtractVectors3(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = a[0] - b[0];
const dReal res_1 = a[1] - b[1];
const dReal res_2 = a[2] - b[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dAddVectorScaledVector3(dReal *res, const dReal *a, const dReal *b, dReal b_scale)
{
const dReal res_0 = a[0] + b_scale * b[0];
const dReal res_1 = a[1] + b_scale * b[1];
const dReal res_2 = a[2] + b_scale * b[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dAddScaledVectors3(dReal *res, const dReal *a, const dReal *b, dReal a_scale, dReal b_scale)
{
const dReal res_0 = a_scale * a[0] + b_scale * b[0];
const dReal res_1 = a_scale * a[1] + b_scale * b[1];
const dReal res_2 = a_scale * a[2] + b_scale * b[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dAddThreeScaledVectors3(dReal *res, const dReal *a, const dReal *b, const dReal *c, dReal a_scale, dReal b_scale, dReal c_scale)
{
const dReal res_0 = a_scale * a[0] + b_scale * b[0] + c_scale * c[0];
const dReal res_1 = a_scale * a[1] + b_scale * b[1] + c_scale * c[1];
const dReal res_2 = a_scale * a[2] + b_scale * b[2] + c_scale * c[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dScaleVector3(dReal *res, dReal nScale)
{
res[0] *= nScale ;
res[1] *= nScale ;
res[2] *= nScale ;
}
ODE_PURE_INLINE void dNegateVector3(dReal *res)
{
res[0] = -res[0];
res[1] = -res[1];
res[2] = -res[2];
}
ODE_PURE_INLINE void dCopyVector3(dReal *res, const dReal *a)
{
const dReal res_0 = a[0];
const dReal res_1 = a[1];
const dReal res_2 = a[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dCopyScaledVector3(dReal *res, const dReal *a, dReal nScale)
{
const dReal res_0 = a[0] * nScale;
const dReal res_1 = a[1] * nScale;
const dReal res_2 = a[2] * nScale;
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dCopyNegatedVector3(dReal *res, const dReal *a)
{
const dReal res_0 = -a[0];
const dReal res_1 = -a[1];
const dReal res_2 = -a[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dCopyVector4(dReal *res, const dReal *a)
{
const dReal res_0 = a[0];
const dReal res_1 = a[1];
const dReal res_2 = a[2];
const dReal res_3 = a[3];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3;
}
ODE_PURE_INLINE void dCopyMatrix4x4(dReal *res, const dReal *a)
{
dCopyVector4(res + 0, a + 0);
dCopyVector4(res + 4, a + 4);
dCopyVector4(res + 8, a + 8);
}
ODE_PURE_INLINE void dCopyMatrix4x3(dReal *res, const dReal *a)
{
dCopyVector3(res + 0, a + 0);
dCopyVector3(res + 4, a + 4);
dCopyVector3(res + 8, a + 8);
}
ODE_PURE_INLINE void dGetMatrixColumn3(dReal *res, const dReal *a, unsigned n)
{
const dReal res_0 = a[n + 0];
const dReal res_1 = a[n + 4];
const dReal res_2 = a[n + 8];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE dReal dCalcVectorLength3(const dReal *a)
{
return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
}
ODE_PURE_INLINE dReal dCalcVectorLengthSquare3(const dReal *a)
{
return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
}
ODE_PURE_INLINE dReal dCalcPointDepth3(const dReal *test_p, const dReal *plane_p, const dReal *plane_n)
{
return (plane_p[0] - test_p[0]) * plane_n[0] + (plane_p[1] - test_p[1]) * plane_n[1] + (plane_p[2] - test_p[2]) * plane_n[2];
}
/*
* 3-way dot product. _dCalcVectorDot3 means that elements of `a' and `b' are spaced
* step_a and step_b indexes apart respectively. dCalcVectorDot3() means dDot311.
*/
ODE_PURE_INLINE dReal _dCalcVectorDot3(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b)
{
return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b];
}
ODE_PURE_INLINE dReal dCalcVectorDot3 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,1); }
ODE_PURE_INLINE dReal dCalcVectorDot3_13 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,3); }
ODE_PURE_INLINE dReal dCalcVectorDot3_31 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,1); }
ODE_PURE_INLINE dReal dCalcVectorDot3_33 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,3); }
ODE_PURE_INLINE dReal dCalcVectorDot3_14 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,4); }
ODE_PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); }
ODE_PURE_INLINE dReal dCalcVectorDot3_44 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,4); }
/*
* cross product, set res = a x b. _dCalcVectorCross3 means that elements of `res', `a'
* and `b' are spaced step_res, step_a and step_b indexes apart respectively.
* dCalcVectorCross3() means dCross3111.
*/
ODE_PURE_INLINE void _dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b, unsigned step_res, unsigned step_a, unsigned step_b)
{
const dReal res_0 = a[ step_a]*b[2*step_b] - a[2*step_a]*b[ step_b];
const dReal res_1 = a[2*step_a]*b[ 0] - a[ 0]*b[2*step_b];
const dReal res_2 = a[ 0]*b[ step_b] - a[ step_a]*b[ 0];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[ 0] = res_0;
res[ step_res] = res_1;
res[2*step_res] = res_2;
}
ODE_PURE_INLINE void dCalcVectorCross3 (dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); }
ODE_PURE_INLINE void dCalcVectorCross3_141(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_144(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); }
ODE_PURE_INLINE void dCalcVectorCross3_411(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_414(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); }
ODE_PURE_INLINE void dCalcVectorCross3_441(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_444(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); }
ODE_PURE_INLINE void dAddVectorCross3(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dCalcVectorCross3(tmp, a, b);
dAddVectors3(res, res, tmp);
}
ODE_PURE_INLINE void dSubtractVectorCross3(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dCalcVectorCross3(tmp, a, b);
dSubtractVectors3(res, res, tmp);
}
/*
* set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
* A is stored by rows, and has `skip' elements per row. the matrix is
* assumed to be already zero, so this does not write zero elements!
* if (plus,minus) is (+,-) then a positive version will be written.
* if (plus,minus) is (-,+) then a negative version will be written.
*/
ODE_PURE_INLINE void dSetCrossMatrixPlus(dReal *res, const dReal *a, unsigned skip)
{
const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2];
res[1] = -a_2;
res[2] = +a_1;
res[skip+0] = +a_2;
res[skip+2] = -a_0;
res[2*skip+0] = -a_1;
res[2*skip+1] = +a_0;
}
ODE_PURE_INLINE void dSetCrossMatrixMinus(dReal *res, const dReal *a, unsigned skip)
{
const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2];
res[1] = +a_2;
res[2] = -a_1;
res[skip+0] = -a_2;
res[skip+2] = +a_0;
res[2*skip+0] = +a_1;
res[2*skip+1] = -a_0;
}
/*
* compute the distance between two 3D-vectors
*/
ODE_PURE_INLINE dReal dCalcPointsDistance3(const dReal *a, const dReal *b)
{
dReal res;
dReal tmp[3];
dSubtractVectors3(tmp, a, b);
res = dCalcVectorLength3(tmp);
return res;
}
/*
* special case matrix multiplication, with operator selection
*/
ODE_PURE_INLINE void dMultiplyHelper0_331(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot3(a, b);
const dReal res_1 = dCalcVectorDot3(a + 4, b);
const dReal res_2 = dCalcVectorDot3(a + 8, b);
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dMultiplyHelper1_331(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot3_41(a, b);
const dReal res_1 = dCalcVectorDot3_41(a + 1, b);
const dReal res_2 = dCalcVectorDot3_41(a + 2, b);
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dMultiplyHelper0_133(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper1_331(res, b, a);
}
ODE_PURE_INLINE void dMultiplyHelper1_133(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot3_44(a, b);
const dReal res_1 = dCalcVectorDot3_44(a + 1, b);
const dReal res_2 = dCalcVectorDot3_44(a + 2, b);
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
/*
Note: NEVER call any of these functions/macros with the same variable for A and C,
it is not equivalent to A*=B.
*/
ODE_PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_331(res, a, b);
}
ODE_PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper1_331(res, a, b);
}
ODE_PURE_INLINE void dMultiply0_133(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_133(res, a, b);
}
ODE_PURE_INLINE void dMultiply0_333(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_133(res + 0, a + 0, b);
dMultiplyHelper0_133(res + 4, a + 4, b);
dMultiplyHelper0_133(res + 8, a + 8, b);
}
ODE_PURE_INLINE void dMultiply1_333(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper1_133(res + 0, b, a + 0);
dMultiplyHelper1_133(res + 4, b, a + 1);
dMultiplyHelper1_133(res + 8, b, a + 2);
}
ODE_PURE_INLINE void dMultiply2_333(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_331(res + 0, b, a + 0);
dMultiplyHelper0_331(res + 4, b, a + 4);
dMultiplyHelper0_331(res + 8, b, a + 8);
}
ODE_PURE_INLINE void dMultiplyAdd0_331(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper0_331(tmp, a, b);
dAddVectors3(res, res, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd1_331(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper1_331(tmp, a, b);
dAddVectors3(res, res, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd0_133(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper0_133(tmp, a, b);
dAddVectors3(res, res, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd0_333(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper0_133(tmp, a + 0, b);
dAddVectors3(res+ 0, res + 0, tmp);
dMultiplyHelper0_133(tmp, a + 4, b);
dAddVectors3(res + 4, res + 4, tmp);
dMultiplyHelper0_133(tmp, a + 8, b);
dAddVectors3(res + 8, res + 8, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd1_333(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper1_133(tmp, b, a + 0);
dAddVectors3(res + 0, res + 0, tmp);
dMultiplyHelper1_133(tmp, b, a + 1);
dAddVectors3(res + 4, res + 4, tmp);
dMultiplyHelper1_133(tmp, b, a + 2);
dAddVectors3(res + 8, res + 8, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd2_333(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper0_331(tmp, b, a + 0);
dAddVectors3(res + 0, res + 0, tmp);
dMultiplyHelper0_331(tmp, b, a + 4);
dAddVectors3(res + 4, res + 4, tmp);
dMultiplyHelper0_331(tmp, b, a + 8);
dAddVectors3(res + 8, res + 8, tmp);
}
ODE_PURE_INLINE dReal dCalcMatrix3Det( const dReal* mat )
{
dReal det;
det = mat[0] * ( mat[5]*mat[10] - mat[9]*mat[6] )
- mat[1] * ( mat[4]*mat[10] - mat[8]*mat[6] )
+ mat[2] * ( mat[4]*mat[9] - mat[8]*mat[5] );
return( det );
}
/**
Closed form matrix inversion, copied from
collision_util.h for use in the stepper.
Returns the determinant.
returns 0 and does nothing
if the matrix is singular.
*/
ODE_PURE_INLINE dReal dInvertMatrix3(dReal *dst, const dReal *ma)
{
dReal det;
dReal detRecip;
det = dCalcMatrix3Det( ma );
/* Setting an arbitrary non-zero threshold
for the determinant doesn't do anyone
any favors. The condition number is the
important thing. If all the eigen-values
of the matrix are small, so is the
determinant, but it can still be well
conditioned.
A single extremely large eigen-value could
push the determinant over threshold, but
produce a very unstable result if the other
eigen-values are small. So we just say that
the determinant must be non-zero and trust the
caller to provide well-conditioned matrices.
*/
if ( det == 0 )
{
return 0;
}
detRecip = dRecip(det);
dst[0] = ( ma[5]*ma[10] - ma[6]*ma[9] ) * detRecip;
dst[1] = ( ma[9]*ma[2] - ma[1]*ma[10] ) * detRecip;
dst[2] = ( ma[1]*ma[6] - ma[5]*ma[2] ) * detRecip;
dst[4] = ( ma[6]*ma[8] - ma[4]*ma[10] ) * detRecip;
dst[5] = ( ma[0]*ma[10] - ma[8]*ma[2] ) * detRecip;
dst[6] = ( ma[4]*ma[2] - ma[0]*ma[6] ) * detRecip;
dst[8] = ( ma[4]*ma[9] - ma[8]*ma[5] ) * detRecip;
dst[9] = ( ma[8]*ma[1] - ma[0]*ma[9] ) * detRecip;
dst[10] = ( ma[0]*ma[5] - ma[1]*ma[4] ) * detRecip;
return det;
}
/* Include legacy macros here */
#include <ode/odemath_legacy.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* normalize 3x1 and 4x1 vectors (i.e. scale them to unit length)
*/
/* For DLL export*/
ODE_API int dSafeNormalize3 (dVector3 a);
ODE_API int dSafeNormalize4 (dVector4 a);
ODE_API void dNormalize3 (dVector3 a); /* Potentially asserts on zero vec*/
ODE_API void dNormalize4 (dVector4 a); /* Potentially asserts on zero vec*/
/*
* given a unit length "normal" vector n, generate vectors p and q vectors
* that are an orthonormal basis for the plane space perpendicular to n.
* i.e. this makes p,q such that n,p,q are all perpendicular to each other.
* q will equal n x p. if n is not unit length then p will be unit length but
* q wont be.
*/
ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
/* Makes sure the matrix is a proper rotation, returns a boolean status */
ODE_API int dOrthogonalizeR(dMatrix3 m);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,162 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ODEMATH_LEGACY_H_
#define _ODE_ODEMATH_LEGACY_H_
/*
* These macros are not used any more inside of ODE
* They are kept for backward compatibility with external code that
* might still be using them.
*/
/*
* General purpose vector operations with other vectors or constants.
*/
#define dOP(a,op,b,c) do { \
(a)[0] = ((b)[0]) op ((c)[0]); \
(a)[1] = ((b)[1]) op ((c)[1]); \
(a)[2] = ((b)[2]) op ((c)[2]); \
} while (0)
#define dOPC(a,op,b,c) do { \
(a)[0] = ((b)[0]) op (c); \
(a)[1] = ((b)[1]) op (c); \
(a)[2] = ((b)[2]) op (c); \
} while (0)
#define dOPE(a,op,b) do {\
(a)[0] op ((b)[0]); \
(a)[1] op ((b)[1]); \
(a)[2] op ((b)[2]); \
} while (0)
#define dOPEC(a,op,c) do { \
(a)[0] op (c); \
(a)[1] op (c); \
(a)[2] op (c); \
} while (0)
/* Define an equation with operators
* For example this function can be used to replace
* <PRE>
* for (int i=0; i<3; ++i)
* a[i] += b[i] + c[i];
* </PRE>
*/
#define dOPE2(a,op1,b,op2,c) do { \
(a)[0] op1 ((b)[0]) op2 ((c)[0]); \
(a)[1] op1 ((b)[1]) op2 ((c)[1]); \
(a)[2] op1 ((b)[2]) op2 ((c)[2]); \
} while (0)
#define dLENGTHSQUARED(a) dCalcVectorLengthSquare3(a)
#define dLENGTH(a) dCalcVectorLength3(a)
#define dDISTANCE(a, b) dCalcPointsDistance3(a, b)
#define dDOT(a, b) dCalcVectorDot3(a, b)
#define dDOT13(a, b) dCalcVectorDot3_13(a, b)
#define dDOT31(a, b) dCalcVectorDot3_31(a, b)
#define dDOT33(a, b) dCalcVectorDot3_33(a, b)
#define dDOT14(a, b) dCalcVectorDot3_14(a, b)
#define dDOT41(a, b) dCalcVectorDot3_41(a, b)
#define dDOT44(a, b) dCalcVectorDot3_44(a, b)
/*
* cross product, set a = b x c. dCROSSpqr means that elements of `a', `b'
* and `c' are spaced p, q and r indexes apart respectively.
* dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
* +=, -= etc to get other effects.
*/
#define dCROSS(a,op,b,c) \
do { \
(a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
(a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
(a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \
} while(0)
#define dCROSSpqr(a,op,b,c,p,q,r) \
do { \
(a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \
(a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \
(a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \
} while(0)
#define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4)
#define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1)
#define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4)
#define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1)
#define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4)
#define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1)
#define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4)
/*
* set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
* A is stored by rows, and has `skip' elements per row. the matrix is
* assumed to be already zero, so this does not write zero elements!
* if (plus,minus) is (+,-) then a positive version will be written.
* if (plus,minus) is (-,+) then a negative version will be written.
*/
#define dCROSSMAT(A,a,skip,plus,minus) \
do { \
(A)[1] = minus (a)[2]; \
(A)[2] = plus (a)[1]; \
(A)[(skip)+0] = plus (a)[2]; \
(A)[(skip)+2] = minus (a)[0]; \
(A)[2*(skip)+0] = minus (a)[1]; \
(A)[2*(skip)+1] = plus (a)[0]; \
} while(0)
/*
Note: NEVER call any of these functions/macros with the same variable for A and C,
it is not equivalent to A*=B.
*/
#define dMULTIPLY0_331(A, B, C) dMultiply0_331(A, B, C)
#define dMULTIPLY1_331(A, B, C) dMultiply1_331(A, B, C)
#define dMULTIPLY0_133(A, B, C) dMultiply0_133(A, B, C)
#define dMULTIPLY0_333(A, B, C) dMultiply0_333(A, B, C)
#define dMULTIPLY1_333(A, B, C) dMultiply1_333(A, B, C)
#define dMULTIPLY2_333(A, B, C) dMultiply2_333(A, B, C)
#define dMULTIPLYADD0_331(A, B, C) dMultiplyAdd0_331(A, B, C)
#define dMULTIPLYADD1_331(A, B, C) dMultiplyAdd1_331(A, B, C)
#define dMULTIPLYADD0_133(A, B, C) dMultiplyAdd0_133(A, B, C)
#define dMULTIPLYADD0_333(A, B, C) dMultiplyAdd0_333(A, B, C)
#define dMULTIPLYADD1_333(A, B, C) dMultiplyAdd1_333(A, B, C)
#define dMULTIPLYADD2_333(A, B, C) dMultiplyAdd2_333(A, B, C)
/*
* These macros are not used any more inside of ODE
* They are kept for backward compatibility with external code that
* might still be using them.
*/
#endif /* #ifndef _ODE_ODEMATH_LEGACY_H_ */

@ -0,0 +1,16 @@
#ifndef _ODE_PRECISION_H_
#define _ODE_PRECISION_H_
/* Define dSINGLE for single precision, dDOUBLE for double precision,
* but never both!
*/
#if defined(dIDESINGLE)
#define dSINGLE
#elif defined(dIDEDOUBLE)
#define dDOUBLE
#else
#define dDOUBLE
#endif
#endif

@ -0,0 +1,70 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ROTATION_H_
#define _ODE_ROTATION_H_
#include <ode/common.h>
#include <ode/compatibility.h>
#ifdef __cplusplus
extern "C" {
#endif
ODE_API void dRSetIdentity (dMatrix3 R);
ODE_API void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
dReal angle);
ODE_API void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi);
ODE_API void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
dReal bx, dReal by, dReal bz);
ODE_API void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az);
ODE_API void dQSetIdentity (dQuaternion q);
ODE_API void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
dReal angle);
/* Quaternion multiplication, analogous to the matrix multiplication routines. */
/* qa = rotate by qc, then qb */
ODE_API void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
/* qa = rotate by qc, then by inverse of qb */
ODE_API void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
/* qa = rotate by inverse of qc, then by qb */
ODE_API void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
/* qa = rotate by inverse of qc, then by inverse of qb */
ODE_API void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
ODE_API void dRfromQ (dMatrix3 R, const dQuaternion q);
ODE_API void dQfromR (dQuaternion q, const dMatrix3 R);
ODE_API void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,412 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* Threading support header file. *
* Copyright (C) 2011-2012 Oleh Derevenko. All rights reserved. *
* e-mail: odar@eleks.com (change all "a" to "e") *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/*
* ODE threading support interfaces
*/
#ifndef _ODE_THREADING_H_
#define _ODE_THREADING_H_
#include <ode/odeconfig.h>
// Include <time.h> since time_t is used and it is not available by default in some OSes
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
struct dxThreadingImplementation;
typedef struct dxThreadingImplementation *dThreadingImplementationID;
typedef unsigned dmutexindex_t;
struct dxMutexGroup;
typedef struct dxMutexGroup *dMutexGroupID;
#define dTHREADING_THREAD_COUNT_UNLIMITED 0U
/**
* @brief Allocates a group of muteces.
*
* The Mutex allocated do not need to support recursive locking.
*
* The Mutex names are provided to aid in debugging and thread state tracking.
*
* @param impl Threading implementation ID
* @param Mutex_count Number of Mutex to create
* @Mutex_names_ptr Pointer to optional Mutex names array to be associated with individual Mutex
* @returns MutexGroup ID or NULL if error occurred.
*
* @ingroup threading
* @see dMutexGroupFreeFunction
* @see dMutexGroupMutexLockFunction
* @see dMutexGroupMutexUnlockFunction
*/
typedef dMutexGroupID dMutexGroupAllocFunction (dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/);
/**
* @brief Deletes a group of muteces.
*
* @param impl Threading implementation ID
* @param mutex_group Mutex group to deallocate
*
* @ingroup threading
* @see dMutexGroupAllocFunction
* @see dMutexGroupMutexLockFunction
* @see dMutexGroupMutexUnlockFunction
*/
typedef void dMutexGroupFreeFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group);
/**
* @brief Locks a mutex in a group of muteces.
*
* The function is to block execution until requested mutex can be locked.
*
* Note: Mutex provided may not support recursive locking. Calling this function
* while mutex is already locked by current thread will result in unpredictable behavior.
*
* @param impl Threading implementation ID
* @param mutex_group Mutex group to use for locking
* @param mutex_index The index of mutex to be locked (0..Mutex_count - 1)
*
* @ingroup threading
* @see dMutexGroupAllocFunction
* @see dMutexGroupFreeFunction
* @see dMutexGroupMutexUnlockFunction
*/
typedef void dMutexGroupMutexLockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
/**
* @brief Attempts to lock a mutex in a group of muteces.
*
* The function is to lock the requested mutex if it is unoccupied or
* immediately return failure if mutex is already locked by other thread.
*
* Note: Mutex provided may not support recursive locking. Calling this function
* while mutex is already locked by current thread will result in unpredictable behavior.
*
* @param impl Threading implementation ID
* @param mutex_group Mutex group to use for locking
* @param mutex_index The index of mutex to be locked (0..Mutex_count - 1)
* @returns 1 for success (mutex is locked) and 0 for failure (mutex is not locked)
*
* @ingroup threading
* @see dMutexGroupAllocFunction
* @see dMutexGroupFreeFunction
* @see dMutexGroupMutexLockFunction
* @see dMutexGroupMutexUnlockFunction
*/
/* typedef int dMutexGroupMutexTryLockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);*/
/**
* @brief Unlocks a mutex in a group of muteces.
*
* The function is to unlock the given mutex provided it had been locked before.
*
* @param impl Threading implementation ID
* @param mutex_group Mutex group to use for unlocking
* @param mutex_index The index of mutex to be unlocked (0..Mutex_count - 1)
*
* @ingroup threading
* @see dMutexGroupAllocFunction
* @see dMutexGroupFreeFunction
* @see dMutexGroupMutexLockFunction
*/
typedef void dMutexGroupMutexUnlockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
struct dxCallReleasee;
typedef struct dxCallReleasee *dCallReleaseeID;
struct dxCallWait;
typedef struct dxCallWait *dCallWaitID;
typedef dsizeint ddependencycount_t;
typedef ddiffint ddependencychange_t;
typedef dsizeint dcallindex_t;
typedef int dThreadedCallFunction(void *call_context, dcallindex_t instance_index,
dCallReleaseeID this_releasee);
typedef struct dxThreadedWaitTime
{
time_t wait_sec;
unsigned long wait_nsec;
} dThreadedWaitTime;
/**
* @brief Allocates a Wait ID that can be used to wait for a call.
*
* @param impl Threading implementation ID
* @returns Wait ID or NULL if error occurred
*
* @ingroup threading
* @see dThreadedCallWaitResetFunction
* @see dThreadedCallWaitFreeFunction
* @see dThreadedCallPostFunction
* @see dThreadedCallWaitFunction
*/
typedef dCallWaitID dThreadedCallWaitAllocFunction(dThreadingImplementationID impl);
/**
* @brief Resets a Wait ID so that it could be used to wait for another call.
*
* @param impl Threading implementation ID
* @param call_wait Wait ID to reset
*
* @ingroup threading
* @see dThreadedCallWaitAllocFunction
* @see dThreadedCallWaitFreeFunction
* @see dThreadedCallPostFunction
* @see dThreadedCallWaitFunction
*/
typedef void dThreadedCallWaitResetFunction(dThreadingImplementationID impl, dCallWaitID call_wait);
/**
* @brief Frees a Wait ID.
*
* @param impl Threading implementation ID
* @param call_wait Wait ID to delete
*
* @ingroup threading
* @see dThreadedCallWaitAllocFunction
* @see dThreadedCallPostFunction
* @see dThreadedCallWaitFunction
*/
typedef void dThreadedCallWaitFreeFunction(dThreadingImplementationID impl, dCallWaitID call_wait);
/**
* @brief Post a function to be called in another thread.
*
* A call is scheduled to be executed asynchronously.
*
* A @a out_summary_fault variable can be provided for call to accumulate any
* possible faults from its execution and execution of any possible sub-calls.
* This variable gets result that @a call_func returns. Also, if dependent calls
* are executed after the call already exits, the variable is also going to be
* updated with results of all those calls before control is released to master.
*
* @a out_post_releasee parameter receives a value of @c dCallReleaseeID that can
* later be used for @a dependent_releasee while scheduling sub-calls to make
* current call depend on them. The value is only returned if @a dependencies_count
* is not zero (i.e. if any dependencies are expected at all). The call is not going
* to start until all its dependencies complete.
*
* In case if number of dependencies is unknown in advance 1 can be passed on call
* scheduling. Then @c dThreadedCallDependenciesCountAlterFunction can be used to
* add one more extra dependencies before scheduling each subcall. And then, after
* all sub-calls had been scheduled, @c dThreadedCallDependenciesCountAlterFunction
* can be used again to subtract initial extra dependency from total number.
* Adding one dependency in advance is necessary to obtain releasee ID and to make
* sure the call will not start and will not terminate before all sub-calls are scheduled.
*
* Extra dependencies can also be added from the call itself after it has already
* been started (with parameter received in @c dThreadedCallFunction).
* In that case those dependencies will start immediately or after call returns
* but the call's master will not be released/notified until all additional
* dependencies complete. This can be used to schedule sub-calls from a call and
* then pass own job to another sub-call dependent on those initial sub-calls.
*
* By using @ call_wait it is possible to assign a Wait ID that can later
* be passed into @c dThreadedCallWaitFunction to wait for call completion.
*
* If @a call_name is available (and it should!) the string must remain valid until
* after call completion. In most cases this should be a static string literal.
*
* Since the function is an analogue of normal method call it is not supposed to fail.
* Any complications with resource allocation on call scheduling should be
* anticipated, avoided and worked around by implementation.
*
* @param impl Threading implementation ID
* @param out_summary_fault Optional pointer to variable to be set to 1 if function
* call (or any sub-call) fails internally, or 0 if all calls return success
* @param out_post_releasee Optional pointer to variable to receive releasee ID
* associated with the call
* @param dependencies_count Number of dependencies that are going to reference
* this call as dependent releasee
* @param dependent_releasee Optional releasee ID to reference with this call
* @param call_wait Optional Wait ID that can later be used to wait for the call
* @param call_func Pointer to function to be called
* @param call_context Context parameter to be passed into the call
* @param instance_index Index parameter to be passed into the call
* @param call_name Optional name to be associated with the call (for debugging and state tracking)
*
* @ingroup threading
* @see dThreadedCallWaitFunction
* @see dThreadedCallDependenciesCountAlterFunction
* @see dThreadingImplResourcesForCallsPreallocateFunction
*/
typedef void dThreadedCallPostFunction(dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
dCallWaitID call_wait/*=NULL*/,
dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
const char *call_name/*=NULL*/);
/**
* @brief Add or remove extra dependencies from call that has been scheduled
* or is in process of execution.
*
* Extra dependencies can be added to a call if exact number of sub-calls is
* not known in advance at the moment the call is scheduled. Also, some dependencies
* can be removed if sub-calls were planned but then dropped.
*
* In case if total dependency count of a call reaches zero by result of invoking
* this function, the call is free to start executing immediately.
*
* After the call execution had been started, any additional dependencies can only
* be added from the call function itself!
*
* @param impl Threading implementation ID
* @param target_releasee ID of releasee to apply dependencies count change to
* @param dependencies_count_change Number of dependencies to add or remove
*
* @ingroup threading
* @see dThreadedCallPostFunction
*/
typedef void dThreadedCallDependenciesCountAlterFunction(dThreadingImplementationID impl, dCallReleaseeID target_releasee,
ddependencychange_t dependencies_count_change);
/**
* @brief Wait for a posted call to complete.
*
* Function blocks until a call identified by @a call_wait completes or
* timeout elapses.
*
* IT IS ILLEGAL TO INVOKE THIS FUNCTION FROM WITHIN A THREADED CALL!
* This is because doing so will block a physical thread and will require
* increasing worker thread count to avoid starvation. Use call dependencies
* if it is necessary make sure sub-calls have been completed instead!
*
* If @a timeout_time_ptr is NULL, the function waits without time limit. If @a timeout_time_ptr
* points to zero value, the function only checks status and does not block.
*
* If @a wait_name is available (and it should!) the string must remain valid for
* the duration of wait. In most cases this should be a static string literal.
*
* Function is not expected to return failures caused by system call faults as
* those are hardly ever possible to be handled in this case anyway. In event of
* system call fault the function is supposed to terminate application.
*
* @param impl Threading implementation ID
* @param out_wait_status Optional pointer to variable to receive 1 if waiting succeeded
* or 0 in case of timeout
* @param call_wait Wait ID that had been passed to scheduling a call that needs to be waited for
* @param timeout_time_ptr Optional pointer to time specification the wait must not
* last longer than (pass NULL for infinite timeout)
* @param wait_name Optional name to be associated with the wait (for debugging and state tracking)
*
* @ingroup threading
* @see dThreadedCallPostFunction
*/
typedef void dThreadedCallWaitFunction(dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
const char *wait_name/*=NULL*/);
/**
* @brief Retrieve number of active threads that serve the implementation.
*
* @param impl Threading implementation ID
* @returns Number of active threads
*
* @ingroup threading
*/
typedef unsigned dThreadingImplThreadCountRetrieveFunction(dThreadingImplementationID impl);
/**
* @brief Preallocate resources to handle posted calls.
*
* The function is intended to make sure enough resources is preallocated for the
* implementation to be able to handle posted calls. Then @c max_simultaneous_calls_estimate
* is an estimate of how many posted calls can potentially be active or scheduled
* at the same time. The value is usually derived from the way the calls are posted
* in library code and dependencies between them.
*
* @warning While working on an implementation be prepared that the estimate provided
* yet rarely but theoretically can be exceeded due to unpredictability of thread execution.
*
* This function is normally going to be invoked by library each time it is entered
* from outside to do the job but before any threaded calls are going to be posted.
*
* @param impl Threading implementation ID
* @param max_simultaneous_calls_estimate An estimated number of calls that can be posted simultaneously
* @returns 1 or 0 to indicate success or failure
*
* @ingroup threading
* @see dThreadedCallPostFunction
*/
typedef int dThreadingImplResourcesForCallsPreallocateFunction(dThreadingImplementationID impl,
ddependencycount_t max_simultaneous_calls_estimate);
/**
* @brief An interface structure with function pointers to be provided by threading implementation.
*/
typedef struct dxThreadingFunctionsInfo
{
unsigned struct_size;
dMutexGroupAllocFunction *alloc_mutex_group;
dMutexGroupFreeFunction *free_mutex_group;
dMutexGroupMutexLockFunction *lock_group_mutex;
dMutexGroupMutexUnlockFunction *unlock_group_mutex;
dThreadedCallWaitAllocFunction *alloc_call_wait;
dThreadedCallWaitResetFunction *reset_call_wait;
dThreadedCallWaitFreeFunction *free_call_wait;
dThreadedCallPostFunction *post_call;
dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count;
dThreadedCallWaitFunction *wait_call;
dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count;
dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls;
/*
* Beware of Jon Watte's anger if you dare to uncomment this!
* May cryptic text below be you a warning!
* Стародавні легенди розказують, що кожного сміливця, хто наважиться порушити табу
* і відкрити заборонений код, спіткає страшне прокляття і він відразу почне робити
* одні лиш помилки.
*
* dMutexGroupMutexTryLockFunction *trylock_group_mutex;
*/
} dThreadingFunctionsInfo;
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _ODE_THREADING_H_ */

@ -0,0 +1,292 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* Builtin ODE threading implementation header. *
* Copyright (C) 2011-2012 Oleh Derevenko. All rights reserved. *
* e-mail: odar@eleks.com (change all "a" to "e") *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/*
* A threading implementation built into ODE for those who does not care to
* or can't implement an own one.
*/
#ifndef _ODE_THREADING_IMPL_H_
#define _ODE_THREADING_IMPL_H_
#include <ode/odeconfig.h>
#include <ode/threading.h>
#ifdef __cplusplus
extern "C" {
#endif
struct dxThreadingThreadPool;
typedef struct dxThreadingThreadPool *dThreadingThreadPoolID;
/**
* @brief Allocates built-in self-threaded threading implementation object.
*
* A self-threaded implementation is a type of implementation that performs
* processing of posted calls by means of caller thread itself. This type of
* implementation does not need thread pool to serve it.
*
* Note that since May 9th, 2017 (rev. #2066) the Self-Threaded implementation
* returns 0 rather than 1 as available thread count to distinguish from
* thread pools with just one thread in them.
*
* The processing is arranged in a way to prevent call stack depth growth
* as more and more nested calls are posted.
*
* Note that it is not necessary to create and assign a self-threaded
* implementation to a world, as there is a global one used by default
* if no implementation is explicitly assigned. You should only assign
* each world an individual threading implementation instance if simulations
* need to be run in parallel in multiple threads for the worlds.
*
* @returns ID of object allocated or NULL on failure
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingFreeImplementation
*/
ODE_API dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation();
/**
* @brief Allocates built-in multi-threaded threading implementation object.
*
* A multi-threaded implementation is a type of implementation that has to be
* served with a thread pool. The thread pool can be either the built-in ODE object
* or set of external threads that dedicate themselves to this purpose and stay
* in ODE until implementation releases them.
*
* @returns ID of object allocated or NULL on failure
*
* @ingroup threading
* @see dThreadingThreadPoolServeMultiThreadedImplementation
* @see dExternalThreadingServeMultiThreadedImplementation
* @see dThreadingFreeImplementation
*/
ODE_API dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation();
/**
* @brief Retrieves the functions record of a built-in threading implementation.
*
* The implementation can be the one allocated by ODE (from @c dThreadingAllocateMultiThreadedImplementation).
* Do not use this function with self-made custom implementations -
* they should be bundled with their own set of functions.
*
* @param impl Threading implementation ID
* @returns Pointer to associated functions structure
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
*/
ODE_API const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl);
/**
* @brief Requests a built-in implementation to release threads serving it.
*
* The function unblocks threads employed in implementation serving and lets them
* return to from where they originate. It's the responsibility of external code
* to make sure all the calls to ODE that might be dependent on given threading
* implementation object had already returned before this call is made. If threading
* implementation is still processing some posted calls while this function is
* invoked the behavior is implementation dependent.
*
* This call is to be used to request the threads to be released before waiting
* for them in host pool or before waiting for them to exit. Implementation object
* must not be destroyed before it is known that all the serving threads have already
* returned from it. If implementation needs to be reused after this function is called
* and all the threads have exited from it a call to @c dThreadingImplementationCleanupForRestart
* must be made to restore internal state of the object.
*
* If this function is called for self-threaded built-in threading implementation
* the call has no effect.
*
* @param impl Threading implementation ID
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationCleanupForRestart
*/
ODE_API void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl);
/**
* @brief Restores built-in implementation's state to let it be reused after shutdown.
*
* If a multi-threaded built-in implementation needs to be reused after a call
* to @c dThreadingImplementationShutdownProcessing this call is to be made to
* restore object's internal state. After that the implementation can be served again.
*
* If this function is called for self-threaded built-in threading implementation
* the call has no effect.
*
* @param impl Threading implementation ID
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationShutdownProcessing
*/
ODE_API void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl);
/**
* @brief Deletes an instance of built-in threading implementation.
*
* @warning A care must be taken to make sure the implementation is unassigned
* from all the objects it was assigned to and that there are no more threads
* serving it before attempting to call this function.
*
* @param impl Threading implementation ID
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
*/
ODE_API void dThreadingFreeImplementation(dThreadingImplementationID impl);
typedef void (dThreadReadyToServeCallback)(void *callback_context);
/**
* @brief An entry point for external threads that would like to serve a built-in
* threading implementation object.
*
* A thread that calls this function remains blocked in ODE and serves implementation
* object @p impl until being released with @c dThreadingImplementationShutdownProcessing call.
* This function can be used to provide external threads instead of ODE's built-in
* thread pools.
*
* The optional callback @readiness_callback is called after the thread has reached
* and has registered within the implementation. The implementation should not
* be used until all dedicated threads register within it as otherwise it will not
* have accurate view of the execution resources available.
*
* @param impl Threading implementation ID
* @param readiness_callback Optional readiness callback to be called after thread enters the implementation
* @param callback_context A value to be passed as parameter to readiness callback
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationShutdownProcessing
*/
ODE_API void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl,
dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/);
/**
* @brief Creates an instance of built-in thread pool object that can be used to serve
* multi-threaded threading implementations.
*
* The threads allocated inherit priority of caller thread. Their affinity is not
* explicitly adjusted and gets the value the system assigns by default. Threads
* have their stack memory fully committed immediately on start. On POSIX platforms
* threads are started with all the possible signals blocked. Threads execute
* calls to @c dAllocateODEDataForThread with @p ode_data_allocate_flags
* on initialization.
*
* On POSIX platforms this function must be called with signals masked
* or other measures must be taken to prevent reception of signals by calling thread
* for the duration of the call.
*
* @param thread_count Number of threads to start in pool
* @param stack_size Size of stack to be used for every thread or 0 for system default value
* @param ode_data_allocate_flags Flags to be passed to @c dAllocateODEDataForThread on behalf of each thread
* @returns ID of object allocated or NULL on failure
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationShutdownProcessing
* @see dThreadingFreeThreadPool
*/
ODE_API dThreadingThreadPoolID dThreadingAllocateThreadPool(unsigned thread_count,
dsizeint stack_size, unsigned int ode_data_allocate_flags, void *reserved/*=NULL*/);
/**
* @brief Commands an instance of built-in thread pool to serve a built-in multi-threaded
* threading implementation.
*
* A pool can only serve one threading implementation at a time.
* Call @c dThreadingImplementationShutdownProcessing to release pool threads
* from implementation serving and make them idle. Pool threads must be released
* from any implementations before pool is attempted to be deleted.
*
* This function waits for threads to register within implementation before returning.
* So, after the function call exits the implementation can be used immediately.
*
* @param pool Thread pool ID to serve the implementation
* @param impl Implementation ID of implementation to be served
*
* @ingroup threading
* @see dThreadingAllocateThreadPool
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationShutdownProcessing
*/
ODE_API void dThreadingThreadPoolServeMultiThreadedImplementation(dThreadingThreadPoolID pool, dThreadingImplementationID impl);
/**
* @brief Waits until all pool threads are released from threading implementation
* they might be serving.
*
* The function can be used after a call to @c dThreadingImplementationShutdownProcessing
* to make sure all the threads have already been released by threading implementation
* and it can be deleted or it can be cleaned up for restart and served by another pool
* or this pool's threads can be used to serve another threading implementation.
*
* Note that is it not necessary to call this function before pool destruction
* since @c dThreadingFreeThreadPool performs similar wait operation implicitly on its own.
*
* It is OK to call this function even if pool was not serving any threading implementation
* in which case the call exits immediately with minimal delay.
*
* @param pool Thread pool ID to wait for
*
* @ingroup threading
* @see dThreadingAllocateThreadPool
* @see dThreadingImplementationShutdownProcessing
* @see dThreadingFreeThreadPool
*/
ODE_API void dThreadingThreadPoolWaitIdleState(dThreadingThreadPoolID pool);
/**
* @brief Deletes a built-in thread pool instance.
*
* The pool threads must be released from any implementations they might be serving
* before this function is called. Otherwise the call is going to block
* and wait until pool's threads return.
*
* @param pool Thread pool ID to delete
*
* @ingroup threading
* @see dThreadingAllocateThreadPool
* @see dThreadingImplementationShutdownProcessing
*/
ODE_API void dThreadingFreeThreadPool(dThreadingThreadPoolID pool);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _ODE_THREADING_IMPL_H_ */

@ -0,0 +1,76 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_TIMER_H_
#define _ODE_TIMER_H_
#include <ode/odeconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
/* stop watch objects */
typedef struct dStopwatch {
double time; /* total clock count */
unsigned long cc[2]; /* clock count since last `start' */
} dStopwatch;
ODE_API void dStopwatchReset (dStopwatch *);
ODE_API void dStopwatchStart (dStopwatch *);
ODE_API void dStopwatchStop (dStopwatch *);
ODE_API double dStopwatchTime (dStopwatch *); /* returns total time in secs */
/* code timers */
ODE_API void dTimerStart (const char *description); /* pass a static string here */
ODE_API void dTimerNow (const char *description); /* pass a static string here */
ODE_API void dTimerEnd(void);
/* print out a timer report. if `average' is nonzero, print out the average
* time for each slot (this is only meaningful if the same start-now-end
* calls are being made repeatedly.
*/
ODE_API void dTimerReport (FILE *fout, int average);
/* resolution */
/* returns the timer ticks per second implied by the timing hardware or API.
* the actual timer resolution may not be this great.
*/
ODE_API double dTimerTicksPerSecond(void);
/* returns an estimate of the actual timer resolution, in seconds. this may
* be greater than 1/ticks_per_second.
*/
ODE_API double dTimerResolution(void);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,6 @@
#ifndef _ODE_VERSION_H_
#define _ODE_VERSION_H_
#define dODE_VERSION "0.15"
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,182 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_COLLISION_SPACE_H_
#define _ODE_COLLISION_SPACE_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
struct dContactGeom;
/**
* @brief User callback for geom-geom collision testing.
*
* @param data The user data object, as passed to dSpaceCollide.
* @param o1 The first geom being tested.
* @param o2 The second geom being test.
*
* @remarks The callback function can call dCollide on o1 and o2 to generate
* contact points between each pair. Then these contact points may be added
* to the simulation as contact joints. The user's callback function can of
* course chose not to call dCollide for any pair, e.g. if the user decides
* that those pairs should not interact.
*
* @ingroup collide
*/
typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2);
ODE_API dSpaceID dSimpleSpaceCreate (dSpaceID space);
ODE_API dSpaceID dHashSpaceCreate (dSpaceID space);
ODE_API dSpaceID dQuadTreeSpaceCreate (dSpaceID space, const dVector3 Center, const dVector3 Extents, int Depth);
/* SAP */
/* Order XZY or ZXY usually works best, if your Y is up. */
#define dSAP_AXES_XYZ ((0)|(1<<2)|(2<<4))
#define dSAP_AXES_XZY ((0)|(2<<2)|(1<<4))
#define dSAP_AXES_YXZ ((1)|(0<<2)|(2<<4))
#define dSAP_AXES_YZX ((1)|(2<<2)|(0<<4))
#define dSAP_AXES_ZXY ((2)|(0<<2)|(1<<4))
#define dSAP_AXES_ZYX ((2)|(1<<2)|(0<<4))
ODE_API dSpaceID dSweepAndPruneSpaceCreate( dSpaceID space, int axisorder );
ODE_API void dSpaceDestroy (dSpaceID);
ODE_API void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel);
ODE_API void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel);
ODE_API void dSpaceSetCleanup (dSpaceID space, int mode);
ODE_API int dSpaceGetCleanup (dSpaceID space);
/**
* @brief Sets sublevel value for a space.
*
* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided
* with another space. If sublevels of both spaces match, the function iterates
* geometries of both spaces and collides them with each other. If sublevel of one
* space is greater than the sublevel of another one, only the geometries of the
* space with greater sublevel are iterated, another space is passed into
* collision callback as a geometry itself. By default all the spaces are assigned
* zero sublevel.
*
* @note
* The space sublevel @e IS @e NOT automatically updated when one space is inserted
* into another or removed from one. It is a client's responsibility to update sublevel
* value if necessary.
*
* @param space the space to modify
* @param sublevel the sublevel value to be assigned
* @ingroup collide
* @see dSpaceGetSublevel
* @see dSpaceCollide2
*/
ODE_API void dSpaceSetSublevel (dSpaceID space, int sublevel);
/**
* @brief Gets sublevel value of a space.
*
* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided
* with another space. See @c dSpaceSetSublevel for more details.
*
* @param space the space to query
* @returns the sublevel value of the space
* @ingroup collide
* @see dSpaceSetSublevel
* @see dSpaceCollide2
*/
ODE_API int dSpaceGetSublevel (dSpaceID space);
/**
* @brief Sets manual cleanup flag for a space.
*
* Manual cleanup flag marks a space as eligible for manual thread data cleanup.
* This function should be called for every space object right after creation in
* case if ODE has been initialized with @c dInitFlagManualThreadCleanup flag.
*
* Failure to set manual cleanup flag for a space may lead to some resources
* remaining leaked until the program exit.
*
* @param space the space to modify
* @param mode 1 for manual cleanup mode and 0 for default cleanup mode
* @ingroup collide
* @see dSpaceGetManualCleanup
* @see dInitODE2
*/
ODE_API void dSpaceSetManualCleanup (dSpaceID space, int mode);
/**
* @brief Get manual cleanup flag of a space.
*
* Manual cleanup flag marks a space space as eligible for manual thread data cleanup.
* See @c dSpaceSetManualCleanup for more details.
*
* @param space the space to query
* @returns 1 for manual cleanup mode and 0 for default cleanup mode of the space
* @ingroup collide
* @see dSpaceSetManualCleanup
* @see dInitODE2
*/
ODE_API int dSpaceGetManualCleanup (dSpaceID space);
ODE_API void dSpaceAdd (dSpaceID, dGeomID);
ODE_API void dSpaceRemove (dSpaceID, dGeomID);
ODE_API int dSpaceQuery (dSpaceID, dGeomID);
ODE_API void dSpaceClean (dSpaceID);
ODE_API int dSpaceGetNumGeoms (dSpaceID);
ODE_API dGeomID dSpaceGetGeom (dSpaceID, int i);
/**
* @brief Given a space, this returns its class.
*
* The ODE classes are:
* @li dSimpleSpaceClass
* @li dHashSpaceClass
* @li dSweepAndPruneSpaceClass
* @li dQuadTreeSpaceClass
* @li dFirstUserClass
* @li dLastUserClass
*
* The class id not defined by the user should be between
* dFirstSpaceClass and dLastSpaceClass.
*
* User-defined class will return their own number.
*
* @param space the space to query
* @returns The space class ID.
* @ingroup collide
*/
ODE_API int dSpaceGetClass(dSpaceID space);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,316 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/*
* TriMesh code by Erwin de Vries.
*
* Trimesh data.
* This is where the actual vertexdata (pointers), and BV tree is stored.
* Vertices should be single precision!
* This should be more sophisticated, so that the user can easyly implement
* another collision library, but this is a lot of work, and also costs some
* performance because some data has to be copied.
*/
#ifndef _ODE_COLLISION_TRIMESH_H_
#define _ODE_COLLISION_TRIMESH_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Data storage for triangle meshes.
*/
struct dxTriMeshData;
typedef struct dxTriMeshData* dTriMeshDataID;
typedef enum
{
dMTV__MIN,
dMTV_FIRST = dMTV__MIN,
dMTV_SECOND,
dMTV_THIRD,
dMTV__MAX,
} dMeshTriangleVertex;
/*
* These don't make much sense now, but they will later when we add more
* features.
*/
ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void);
ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g);
/*
* The values of data_id that can be used with dGeomTriMeshDataSet/dGeomTriMeshDataGet
*/
enum
{
dTRIMESHDATA__MIN,
dTRIMESHDATA_FACE_NORMALS = dTRIMESHDATA__MIN,
dTRIMESHDATA_USE_FLAGS,
dTRIMESHDATA__MAX,
#ifndef TRIMESH_FACE_NORMALS // Define this name during the header inclusion if you need it for something else
// Included for backward compatibility -- please use the corrected name above. Sorry.
TRIMESH_FACE_NORMALS = dTRIMESHDATA_FACE_NORMALS,
#endif
};
/*
* The flags of the dTRIMESHDATA_USE_FLAGS data elements
*/
enum
{
dMESHDATAUSE_EDGE1 = 0x01,
dMESHDATAUSE_EDGE2 = 0x02,
dMESHDATAUSE_EDGE3 = 0x04,
dMESHDATAUSE_VERTEX1 = 0x08,
dMESHDATAUSE_VERTEX2 = 0x10,
dMESHDATAUSE_VERTEX3 = 0x20,
};
/*
* Set and get the TriMeshData additional data
* Note: The data is NOT COPIED on assignment
*/
ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void *in_data);
ODE_API void *dGeomTriMeshDataGet(dTriMeshDataID g, int data_id);
ODE_API void *dGeomTriMeshDataGet2(dTriMeshDataID g, int data_id, dsizeint *pout_size/*=NULL*/);
/**
* We need to set the last transform after each time step for
* accurate collision response. These functions get and set that transform.
* It is stored per geom instance, rather than per dTriMeshDataID.
*/
ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, const dMatrix4 last_trans );
ODE_API const dReal* dGeomTriMeshGetLastTransform( dGeomID g );
/*
* Build a TriMesh data object with single precision vertex data.
*/
ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g,
const void* Vertices, int VertexStride, int VertexCount,
const void* Indices, int IndexCount, int TriStride);
/* same again with a normals array (used as trimesh-trimesh optimization) */
ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g,
const void* Vertices, int VertexStride, int VertexCount,
const void* Indices, int IndexCount, int TriStride,
const void* Normals);
/*
* Build a TriMesh data object with double precision vertex data.
*/
ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g,
const void* Vertices, int VertexStride, int VertexCount,
const void* Indices, int IndexCount, int TriStride);
/* same again with a normals array (used as trimesh-trimesh optimization) */
ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g,
const void* Vertices, int VertexStride, int VertexCount,
const void* Indices, int IndexCount, int TriStride,
const void* Normals);
/*
* Simple build. Single/double precision based on dSINGLE/dDOUBLE!
*/
ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g,
const dReal* Vertices, int VertexCount,
const dTriIndex* Indices, int IndexCount);
/* same again with a normals array (used as trimesh-trimesh optimization) */
ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g,
const dReal* Vertices, int VertexCount,
const dTriIndex* Indices, int IndexCount,
const int* Normals);
/*
* Data preprocessing build request flags.
*/
enum
{
dTRIDATAPREPROCESS_BUILD__MIN,
dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES = dTRIDATAPREPROCESS_BUILD__MIN, // Used to optimize OPCODE trimesh-capsule collisions; allocates 1 byte per triangle; no extra data associated
dTRIDATAPREPROCESS_BUILD_FACE_ANGLES, // Used to aid trimesh-convex collisions; memory requirements depend on extra data
dTRIDATAPREPROCESS_BUILD__MAX,
};
/*
* Data preprocessing extra values for dTRIDATAPREPROCESS_BUILD_FACE_ANGLES.
*/
enum
{
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN,
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE = dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN, // Build angles for convex edges only and store as bytes; allocates 3 bytes per triangle; stores angles (0..180] in 1/254 fractions leaving two values for the flat and all the concaves
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_ALL, // Build angles for all the edges and store in bytes; allocates 3 bytes per triangle; stores angles [-180..0) and (0..180] in 1/127 fractions plus a value for the flat angle
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_WORD_ALL, // Build angles for all the edges and store in words; allocates 6 bytes per triangle; stores angles [-180..0) and (0..180] in 1/32767 fractions plus a value for the flat angle
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX,
dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__DEFAULT = dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE, // The default value assumed if the extra data is not provided
};
/*
* Pre-process the trimesh data according to the request flags.
*
* buildRequestFlags is a bitmask of 1U << dTRIDATAPREPROCESS_BUILD_...
* It is allowed to call the function multiple times provided the bitmasks are different each time.
*
* requestExtraData is an optional pointer to array of extra parameters per bitmask bits
* (only the elements indexed by positions of raised bits are examined;
* defaults are assumed if the pointer is NULL)
*
* The function returns a boolean status the only failure reason being insufficient memory.
*/
ODE_API int dGeomTriMeshDataPreprocess2(dTriMeshDataID g, unsigned int buildRequestFlags, const dintptr *requestExtraData/*=NULL | const dintptr (*)[dTRIDATAPREPROCESS_BUILD__MAX]*/);
/*
* Obsolete. Equivalent to calling dGeomTriMeshDataPreprocess2(g, (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES), NULL)
*/
ODE_API int dGeomTriMeshDataPreprocess(dTriMeshDataID g);
/*
* Get and set the internal preprocessed trimesh data buffer (see the enumerated type above), for loading and saving
* These functions are deprecated. Use dGeomTriMeshDataSet/dGeomTriMeshDataGet2 with dTRIMESHDATA_USE_FLAGS instead.
*/
ODE_API_DEPRECATED ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen);
ODE_API_DEPRECATED ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf);
/*
* Per triangle callback. Allows the user to say if he wants a collision with
* a particular triangle.
*/
typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex);
ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback);
ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g);
/*
* Per object callback. Allows the user to get the list of triangles in 1
* shot. Maybe we should remove this one.
*/
typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount);
ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback);
ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g);
/*
* Ray callback.
* Allows the user to say if a ray collides with a triangle on barycentric
* coords. The user can for example sample a texture with alpha transparency
* to determine if a collision should occur.
*/
typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v);
ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback);
ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g);
/*
* Triangle merging callback.
* Allows the user to generate a fake triangle index for a new contact generated
* from merging of two other contacts. That index could later be used by the
* user to determine attributes of original triangles used as sources for a
* merged contact.
*/
typedef int dTriTriMergeCallback(dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex);
ODE_API void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback);
ODE_API dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g);
/*
* Trimesh class
* Construction. Callbacks are optional.
*/
ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback);
ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data);
ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g);
/* enable/disable/check temporal coherence*/
ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable);
ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass);
/*
* Clears the internal temporal coherence caches. When a geom has its
* collision checked with a trimesh once, data is stored inside the trimesh.
* With large worlds with lots of seperate objects this list could get huge.
* We should be able to do this automagically.
*/
ODE_API void dGeomTriMeshClearTCCache(dGeomID g);
/*
* returns the TriMeshDataID
*/
ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g);
/*
* Gets a triangle.
*/
ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2);
/*
* Gets the point on the requested triangle and the given barycentric
* coordinates.
*/
ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out);
/*
This is how the strided data works:
struct StridedVertex{
dVector3 Vertex;
// Userdata
};
int VertexStride = sizeof(StridedVertex);
struct StridedTri{
int Indices[3];
// Userdata
};
int TriStride = sizeof(StridedTri);
*/
ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g);
ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g);
#ifdef __cplusplus
}
#endif
#endif /* _ODE_COLLISION_TRIMESH_H_ */

@ -0,0 +1,568 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_COMMON_H_
#define _ODE_COMMON_H_
#include <ode/odeconfig.h>
#include <ode/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/* configuration stuff */
/* constants */
/* pi and 1/sqrt(2) are defined here if necessary because they don't get
* defined in <math.h> on some platforms (like MS-Windows)
*/
#ifndef M_PI
#define M_PI REAL(3.1415926535897932384626433832795029)
#endif
#ifndef M_PI_2
#define M_PI_2 REAL(1.5707963267948966192313216916398)
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
#endif
/* floating point data type, vector, matrix and quaternion types */
#if defined(dSINGLE)
typedef float dReal;
#ifdef dDOUBLE
#error You can only #define dSINGLE or dDOUBLE, not both.
#endif /* dDOUBLE */
#elif defined(dDOUBLE)
typedef double dReal;
#else
#error You must #define dSINGLE or dDOUBLE
#endif
/* Detect if we've got both trimesh engines enabled. */
#if dTRIMESH_ENABLED
#if dTRIMESH_OPCODE && dTRIMESH_GIMPACT
#error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both.
#endif
#endif /* dTRIMESH_ENABLED */
/*
* Define a type for indices, either 16 or 32 bit, based on build option
* TODO: Currently GIMPACT only supports 32 bit indices.
*/
#if dTRIMESH_16BIT_INDICES
#if dTRIMESH_GIMPACT
typedef duint32 dTriIndex;
#else /* dTRIMESH_GIMPACT */
typedef duint16 dTriIndex;
#endif /* dTRIMESH_GIMPACT */
#else /* dTRIMESH_16BIT_INDICES */
typedef duint32 dTriIndex;
#endif /* dTRIMESH_16BIT_INDICES */
/* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
* (used to compute matrix leading dimensions)
*/
#define dPAD(a) (((a) > 1) ? (((a) + 3) & (int)(~3)) : (a))
typedef enum {
dSA__MIN,
dSA_X = dSA__MIN,
dSA_Y,
dSA_Z,
dSA__MAX,
} dSpaceAxis;
typedef enum {
dMD__MIN,
dMD_LINEAR = dMD__MIN,
dMD_ANGULAR,
dMD__MAX,
} dMotionDynamics;
typedef enum {
dDA__MIN,
dDA__L_MIN = dDA__MIN + dMD_LINEAR * dSA__MAX,
dDA_LX = dDA__L_MIN + dSA_X,
dDA_LY = dDA__L_MIN + dSA_Y,
dDA_LZ = dDA__L_MIN + dSA_Z,
dDA__L_MAX = dDA__L_MIN + dSA__MAX,
dDA__A_MIN = dDA__MIN + dMD_ANGULAR * dSA__MAX,
dDA_AX = dDA__A_MIN + dSA_X,
dDA_AY = dDA__A_MIN + dSA_Y,
dDA_AZ = dDA__A_MIN + dSA_Z,
dDA__A_MAX = dDA__A_MIN + dSA__MAX,
dDA__MAX = dDA__MIN + dMD__MAX * dSA__MAX,
} dDynamicsAxis;
typedef enum {
dV3E__MIN,
dV3E__AXES_MIN = dV3E__MIN,
dV3E_X = dV3E__AXES_MIN + dSA_X,
dV3E_Y = dV3E__AXES_MIN + dSA_Y,
dV3E_Z = dV3E__AXES_MIN + dSA_Z,
dV3E__AXES_MAX = dV3E__AXES_MIN + dSA__MAX,
dV3E_PAD = dV3E__AXES_MAX,
dV3E__MAX,
dV3E__AXES_COUNT = dV3E__AXES_MAX - dV3E__AXES_MIN,
} dVec3Element;
typedef enum {
dV4E__MIN,
dV4E_X = dV4E__MIN + dSA_X,
dV4E_Y = dV4E__MIN + dSA_Y,
dV4E_Z = dV4E__MIN + dSA_Z,
dV4E_O = dV4E__MIN + dSA__MAX,
dV4E__MAX,
} dVec4Element;
typedef enum {
dM3E__MIN,
dM3E__X_MIN = dM3E__MIN + dSA_X * dV3E__MAX,
dM3E__X_AXES_MIN = dM3E__X_MIN + dV3E__AXES_MIN,
dM3E_XX = dM3E__X_MIN + dV3E_X,
dM3E_XY = dM3E__X_MIN + dV3E_Y,
dM3E_XZ = dM3E__X_MIN + dV3E_Z,
dM3E__X_AXES_MAX = dM3E__X_MIN + dV3E__AXES_MAX,
dM3E_XPAD = dM3E__X_MIN + dV3E_PAD,
dM3E__X_MAX = dM3E__X_MIN + dV3E__MAX,
dM3E__Y_MIN = dM3E__MIN + dSA_Y * dV3E__MAX,
dM3E__Y_AXES_MIN = dM3E__Y_MIN + dV3E__AXES_MIN,
dM3E_YX = dM3E__Y_MIN + dV3E_X,
dM3E_YY = dM3E__Y_MIN + dV3E_Y,
dM3E_YZ = dM3E__Y_MIN + dV3E_Z,
dM3E__Y_AXES_MAX = dM3E__Y_MIN + dV3E__AXES_MAX,
dM3E_YPAD = dM3E__Y_MIN + dV3E_PAD,
dM3E__Y_MAX = dM3E__Y_MIN + dV3E__MAX,
dM3E__Z_MIN = dM3E__MIN + dSA_Z * dV3E__MAX,
dM3E__Z_AXES_MIN = dM3E__Z_MIN + dV3E__AXES_MIN,
dM3E_ZX = dM3E__Z_MIN + dV3E_X,
dM3E_ZY = dM3E__Z_MIN + dV3E_Y,
dM3E_ZZ = dM3E__Z_MIN + dV3E_Z,
dM3E__Z_AXES_MAX = dM3E__Z_MIN + dV3E__AXES_MAX,
dM3E_ZPAD = dM3E__Z_MIN + dV3E_PAD,
dM3E__Z_MAX = dM3E__Z_MIN + dV3E__MAX,
dM3E__MAX = dM3E__MIN + dSA__MAX * dV3E__MAX,
} dMat3Element;
typedef enum {
dM4E__MIN,
dM4E__X_MIN = dM4E__MIN + dV4E_X * dV4E__MAX,
dM4E_XX = dM4E__X_MIN + dV4E_X,
dM4E_XY = dM4E__X_MIN + dV4E_Y,
dM4E_XZ = dM4E__X_MIN + dV4E_Z,
dM4E_XO = dM4E__X_MIN + dV4E_O,
dM4E__X_MAX = dM4E__X_MIN + dV4E__MAX,
dM4E__Y_MIN = dM4E__MIN + dV4E_Y * dV4E__MAX,
dM4E_YX = dM4E__Y_MIN + dV4E_X,
dM4E_YY = dM4E__Y_MIN + dV4E_Y,
dM4E_YZ = dM4E__Y_MIN + dV4E_Z,
dM4E_YO = dM4E__Y_MIN + dV4E_O,
dM4E__Y_MAX = dM4E__Y_MIN + dV4E__MAX,
dM4E__Z_MIN = dM4E__MIN + dV4E_Z * dV4E__MAX,
dM4E_ZX = dM4E__Z_MIN + dV4E_X,
dM4E_ZY = dM4E__Z_MIN + dV4E_Y,
dM4E_ZZ = dM4E__Z_MIN + dV4E_Z,
dM4E_ZO = dM4E__Z_MIN + dV4E_O,
dM4E__Z_MAX = dM4E__Z_MIN + dV4E__MAX,
dM4E__O_MIN = dM4E__MIN + dV4E_O * dV4E__MAX,
dM4E_OX = dM4E__O_MIN + dV4E_X,
dM4E_OY = dM4E__O_MIN + dV4E_Y,
dM4E_OZ = dM4E__O_MIN + dV4E_Z,
dM4E_OO = dM4E__O_MIN + dV4E_O,
dM4E__O_MAX = dM4E__O_MIN + dV4E__MAX,
dM4E__MAX = dM4E__MIN + dV4E__MAX * dV4E__MAX,
} dMat4Element;
typedef enum {
dQUE__MIN,
dQUE_R = dQUE__MIN,
dQUE__AXIS_MIN,
dQUE_I = dQUE__AXIS_MIN + dSA_X,
dQUE_J = dQUE__AXIS_MIN + dSA_Y,
dQUE_K = dQUE__AXIS_MIN + dSA_Z,
dQUE__AXIS_MAX = dQUE__AXIS_MIN + dSA__MAX,
dQUE__MAX = dQUE__AXIS_MAX,
} dQuatElement;
/* these types are mainly just used in headers */
typedef dReal dVector3[dV3E__MAX];
typedef dReal dVector4[dV4E__MAX];
typedef dReal dMatrix3[dM3E__MAX];
typedef dReal dMatrix4[dM4E__MAX];
typedef dReal dMatrix6[(dMD__MAX * dV3E__MAX) * (dMD__MAX * dSA__MAX)];
typedef dReal dQuaternion[dQUE__MAX];
/* precision dependent scalar math functions */
#if defined(dSINGLE)
#define REAL(x) (x##f) /* form a constant */
#define dRecip(x) ((1.0f/(x))) /* reciprocal */
#define dSqrt(x) (sqrtf(x)) /* square root */
#define dRecipSqrt(x) ((1.0f/sqrtf(x))) /* reciprocal square root */
#define dSin(x) (sinf(x)) /* sine */
#define dCos(x) (cosf(x)) /* cosine */
#define dFabs(x) (fabsf(x)) /* absolute value */
#define dAtan2(y,x) (atan2f(y,x)) /* arc tangent with 2 args */
#define dAsin(x) (asinf(x))
#define dAcos(x) (acosf(x))
#define dFMod(a,b) (fmodf(a,b)) /* modulo */
#define dFloor(x) floorf(x) /* floor */
#define dCeil(x) ceilf(x) /* ceil */
#define dCopySign(a,b) _ode_copysignf(a, b) /* copy value sign */
#define dNextAfter(x, y) _ode_nextafterf(x, y) /* next value after */
#ifdef HAVE___ISNANF
#define dIsNan(x) (__isnanf(x))
#elif defined(HAVE__ISNANF)
#define dIsNan(x) (_isnanf(x))
#elif defined(HAVE_ISNANF)
#define dIsNan(x) (isnanf(x))
#else
/*
fall back to _isnan which is the VC way,
this may seem redundant since we already checked
for _isnan before, but if isnan is detected by
configure but is not found during compilation
we should always make sure we check for __isnanf,
_isnanf and isnanf in that order before falling
back to a default
*/
#define dIsNan(x) (_isnan(x))
#endif
#elif defined(dDOUBLE)
#define REAL(x) (x)
#define dRecip(x) (1.0/(x))
#define dSqrt(x) sqrt(x)
#define dRecipSqrt(x) (1.0/sqrt(x))
#define dSin(x) sin(x)
#define dCos(x) cos(x)
#define dFabs(x) fabs(x)
#define dAtan2(y,x) atan2((y),(x))
#define dAsin(x) asin(x)
#define dAcos(x) acos(x)
#define dFMod(a,b) (fmod((a),(b)))
#define dFloor(x) floor(x)
#define dCeil(x) ceil(x)
#define dCopySign(a,b) _ode_copysign(a, b)
#define dNextAfter(x, y) _ode_nextafter(x, y)
#ifdef HAVE___ISNAN
#define dIsNan(x) (__isnan(x))
#elif defined(HAVE__ISNAN)
#define dIsNan(x) (_isnan(x))
#elif defined(HAVE_ISNAN)
#define dIsNan(x) (isnan(x))
#else
#define dIsNan(x) (_isnan(x))
#endif
#else
#error You must #define dSINGLE or dDOUBLE
#endif
ODE_PURE_INLINE dReal dMin(dReal x, dReal y) { return x <= y ? x : y; }
ODE_PURE_INLINE dReal dMax(dReal x, dReal y) { return x <= y ? y : x; }
/* internal object types (all prefixed with `dx') */
struct dxWorld; /* dynamics world */
struct dxSpace; /* collision space */
struct dxBody; /* rigid body (dynamics object) */
struct dxGeom; /* geometry (collision object) */
struct dxJoint; /* joint */
struct dxJointGroup;/* joint group */
typedef struct dxWorld *dWorldID;
typedef struct dxSpace *dSpaceID;
typedef struct dxBody *dBodyID;
typedef struct dxGeom *dGeomID;
typedef struct dxJoint *dJointID;
typedef struct dxJointGroup *dJointGroupID;
/* error numbers */
enum {
d_ERR_UNKNOWN = 0, /* unknown error */
d_ERR_IASSERT, /* internal assertion failed */
d_ERR_UASSERT, /* user assertion failed */
d_ERR_LCP /* user assertion failed */
};
/* joint type numbers */
typedef enum {
dJointTypeNone = 0, /* or "unknown" */
dJointTypeBall,
dJointTypeHinge,
dJointTypeSlider,
dJointTypeContact,
dJointTypeUniversal,
dJointTypeHinge2,
dJointTypeFixed,
dJointTypeNull,
dJointTypeAMotor,
dJointTypeLMotor,
dJointTypePlane2D,
dJointTypePR,
dJointTypePU,
dJointTypePiston,
dJointTypeDBall,
dJointTypeDHinge,
dJointTypeTransmission,
} dJointType;
/* an alternative way of setting joint parameters, using joint parameter
* structures and member constants. we don't actually do this yet.
*/
/*
typedef struct dLimot {
int mode;
dReal lostop, histop;
dReal vel, fmax;
dReal fudge_factor;
dReal bounce, soft;
dReal suspension_erp, suspension_cfm;
} dLimot;
enum {
dLimotLoStop = 0x0001,
dLimotHiStop = 0x0002,
dLimotVel = 0x0004,
dLimotFMax = 0x0008,
dLimotFudgeFactor = 0x0010,
dLimotBounce = 0x0020,
dLimotSoft = 0x0040
};
*/
/* standard joint parameter names. why are these here? - because we don't want
* to include all the joint function definitions in joint.cpp. hmmmm.
* MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
* which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
* paste between these two.
*/
#define D_ALL_PARAM_NAMES(start) \
/* parameters for limits and motors */ \
dParamLoStop = start, \
dParamHiStop, \
dParamVel, \
dParamLoVel, \
dParamHiVel, \
dParamFMax, \
dParamFudgeFactor, \
dParamBounce, \
dParamCFM, \
dParamStopERP, \
dParamStopCFM, \
/* parameters for suspension */ \
dParamSuspensionERP, \
dParamSuspensionCFM, \
dParamERP, \
/*
* \enum D_ALL_PARAM_NAMES_X
*
* \var dParamGroup This is the starting value of the different group
* (i.e. dParamGroup1, dParamGroup2, dParamGroup3)
* It also helps in the use of parameter
* (dParamGroup2 | dParamFMax) == dParamFMax2
*/
#define D_ALL_PARAM_NAMES_X(start,x) \
dParamGroup ## x = start, \
/* parameters for limits and motors */ \
dParamLoStop ## x = start, \
dParamHiStop ## x, \
dParamVel ## x, \
dParamLoVel ## x, \
dParamHiVel ## x, \
dParamFMax ## x, \
dParamFudgeFactor ## x, \
dParamBounce ## x, \
dParamCFM ## x, \
dParamStopERP ## x, \
dParamStopCFM ## x, \
/* parameters for suspension */ \
dParamSuspensionERP ## x, \
dParamSuspensionCFM ## x, \
dParamERP ## x,
enum {
D_ALL_PARAM_NAMES(0)
dParamsInGroup, /* < Number of parameter in a group */
D_ALL_PARAM_NAMES_X(0x000,1)
D_ALL_PARAM_NAMES_X(0x100,2)
D_ALL_PARAM_NAMES_X(0x200,3)
/* add a multiple of this constant to the basic parameter numbers to get
* the parameters for the second, third etc axes.
*/
dParamGroup=0x100
};
/* angular motor mode numbers */
enum {
dAMotorUser = 0,
dAMotorEuler = 1
};
/* transmission joint mode numbers */
enum {
dTransmissionParallelAxes = 0,
dTransmissionIntersectingAxes = 1,
dTransmissionChainDrive = 2
};
/* joint force feedback information */
typedef struct dJointFeedback {
dVector3 f1; /* force applied to body 1 */
dVector3 t1; /* torque applied to body 1 */
dVector3 f2; /* force applied to body 2 */
dVector3 t2; /* torque applied to body 2 */
} dJointFeedback;
/* private functions that must be implemented by the collision library:
* (1) indicate that a geom has moved, (2) get the next geom in a body list.
* these functions are called whenever the position of geoms connected to a
* body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or
* when the ODE step function updates the body state.
*/
void dGeomMoved (dGeomID);
dGeomID dGeomGetBodyNext (dGeomID);
/**
* dGetConfiguration returns the specific ODE build configuration as
* a string of tokens. The string can be parsed in a similar way to
* the OpenGL extension mechanism, the naming convention should be
* familiar too. The following extensions are reported:
*
* ODE
* ODE_single_precision
* ODE_double_precision
* ODE_EXT_no_debug
* ODE_EXT_trimesh
* ODE_EXT_opcode
* ODE_EXT_gimpact
* ODE_OPC_16bit_indices
* ODE_OPC_new_collider
* ODE_EXT_mt_collisions
* ODE_EXT_threading
* ODE_THR_builtin_impl
*/
ODE_API const char* dGetConfiguration (void);
/**
* Helper to check for a token in the ODE configuration string.
* Caution, this function is case sensitive.
*
* @param token A configuration token, see dGetConfiguration for details
*
* @return 1 if exact token is present, 0 if not present
*/
ODE_API int dCheckConfiguration( const char* token );
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,40 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_COMPATIBILITY_H_
#define _ODE_COMPATIBILITY_H_
/*
* ODE's backward compatibility system ensures that as ODE's API
* evolves, user code will not break.
*/
/*
* These new rotation function names are more consistent with the
* rest of the API.
*/
#define dQtoR(q,R) dRfromQ((R),(q))
#define dRtoQ(R,q) dQfromR((q),(R))
#define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q))
#endif

@ -0,0 +1,110 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_CONTACT_H_
#define _ODE_CONTACT_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
dContactMu2 = 0x001, /**< Use axis dependent friction */
dContactAxisDep = 0x001, /**< Same as above */
dContactFDir1 = 0x002, /**< Use FDir for the first friction value */
dContactBounce = 0x004, /**< Restore collision energy anti-parallel to the normal */
dContactSoftERP = 0x008, /**< Don't use global erp for penetration reduction */
dContactSoftCFM = 0x010, /**< Don't use global cfm for penetration constraint */
dContactMotion1 = 0x020, /**< Use a non-zero target velocity for the constraint */
dContactMotion2 = 0x040,
dContactMotionN = 0x080,
dContactSlip1 = 0x100, /**< Force-dependent slip. */
dContactSlip2 = 0x200,
dContactRolling = 0x400, /**< Rolling/Angular friction */
dContactApprox0 = 0x0000,
dContactApprox1_1 = 0x1000,
dContactApprox1_2 = 0x2000,
dContactApprox1_N = 0x4000, /**< For rolling friction */
dContactApprox1 = 0x7000
};
typedef struct dSurfaceParameters {
/* must always be defined */
int mode;
dReal mu;
/* only defined if the corresponding flag is set in mode */
dReal mu2;
dReal rho; /**< Rolling friction */
dReal rho2;
dReal rhoN; /**< Spinning friction */
dReal bounce; /**< Coefficient of restitution */
dReal bounce_vel; /**< Bouncing threshold */
dReal soft_erp;
dReal soft_cfm;
dReal motion1,motion2,motionN;
dReal slip1,slip2;
} dSurfaceParameters;
/**
* @brief Describe the contact point between two geoms.
*
* If two bodies touch, or if a body touches a static feature in its
* environment, the contact is represented by one or more "contact
* points", described by dContactGeom.
*
* The convention is that if body 1 is moved along the normal vector by
* a distance depth (or equivalently if body 2 is moved the same distance
* in the opposite direction) then the contact depth will be reduced to
* zero. This means that the normal vector points "in" to body 1.
*
* @ingroup collide
*/
typedef struct dContactGeom {
dVector3 pos; /*< contact position*/
dVector3 normal; /*< normal vector*/
dReal depth; /*< penetration depth*/
dGeomID g1,g2; /*< the colliding geoms*/
int side1,side2; /*< (to be documented)*/
} dContactGeom;
/* contact info used by contact joint */
typedef struct dContact {
dSurfaceParameters surface;
dContactGeom geom;
dVector3 fdir1;
} dContact;
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,229 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_COOPERATIVE_H_
#define _ODE_COOPERATIVE_H_
#include <ode/common.h>
#include <ode/threading.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup coop Cooperative Algorithms
*
* Algorithms implemented as multiple threads doing work cooperatively.
*/
struct dxCooperative;
struct dxResourceRequirements;
struct dxResourceContainer;
/**
* @brief A container for cooperative algorithms shared context
*
* The Cooperative is a container for cooperative algorithms shared context.
* At present it contains threading object (either a real one or a defaulted
* self-threading).
*
* Cooperative use in functions performing computations must be serialized. That is,
* functions referring to a single instance of Cooperative object must not be called in
* parallel.
*/
typedef struct dxCooperative *dCooperativeID;
/**
* @brief A container for resource requirements information
*
* The ResourceRequirements object is a container for descriptive information
* regarding what resources (memory, synchronization objects, etc.) need to be
* allocated for particular computations. The object can be used for accumulating
* resource requirement maxima over multiple functions and then allocating resources
* that would suffice for any of those function calls.
*
* ResourceRequirements objects maintain relations to Cooperative objects since
* amounts of resources that could be required can depend on characteristics of
* shared context, e.g. on maximal number of threads in the threading object.
*
* @ingroup coop
* @see dCooperativeID
* @see dResourceContainerID
*/
typedef struct dxResourceRequirements *dResourceRequirementsID;
/**
* @brief A container for algorithm allocated resources
*
* The ResourceContainer object can contain resources allocated according to information
* in a ResourceRequirements. The resources inherit link to the threading object
* from the requirements they are allocated according to.
*
* @ingroup coop
* @see dResourceRequirementsID
* @see dCooperativeID
*/
typedef struct dxResourceContainer *dResourceContainerID;
/**
* @brief Creates a Cooperative object related to the specified threading.
*
* NULL's are allowed for the threading. In this case the default (global) self-threading
* object will be used.
*
* Use @c dCooperativeDestroy to destroy the object. The Cooperative object must exist
* until after all the objects referencing it are destroyed.
*
* @param functionInfo The threading functions to use
* @param threadingImpl The threading implementation object to use
* @returns The Cooperative object instance or NULL if allocation fails.
* @ingroup coop
* @see dCooperativeDestroy
*/
ODE_API dCooperativeID dCooperativeCreate(const dThreadingFunctionsInfo *functionInfo/*=NULL*/, dThreadingImplementationID threadingImpl/*=NULL*/);
/**
* @brief Destroys Cooperative object.
*
* The Cooperative object can only be destroyed after all the objects referencing it.
*
* @param cooperative A Cooperative object to be deleted (NULL is allowed)
* @ingroup coop
* @see dCooperativeCreate
*/
ODE_API void dCooperativeDestroy(dCooperativeID cooperative);
/**
* @brief Creates a ResourceRequirements object related to a Cooperative.
*
* The object is purely descriptive and does not contain any resources by itself.
* The actual resources are allocated by means of ResourceContainer object.
*
* The object is created with empty requirements. It can be then used to accumulate
* requirements for one or more function calls and can be cloned or merged with others.
* The actual requirements information is added to the object by computation related
* functions.
*
* Use @c dResourceRequirementsDestroy to delete the object when it is no longer needed.
*
* @param cooperative A Cooperative object to be used
* @returns The ResourceRequirements object instance or NULL if allocation fails
* @ingroup coop
* @see dResourceRequirementsDestroy
* @see dResourceRequirementsClone
* @see dResourceRequirementsMergeIn
* @see dCooperativeCreate
* @see dResourceContainerAcquire
*/
ODE_API dResourceRequirementsID dResourceRequirementsCreate(dCooperativeID cooperative);
/**
* @brief Destroys ResourceRequirements object.
*
* The ResourceRequirements object can be destroyed at any time with no regards
* to other objects' lifetime.
*
* @param requirements A ResourceRequirements object to be deleted (NULL is allowed)
* @ingroup coop
* @see dResourceRequirementsCreate
*/
ODE_API void dResourceRequirementsDestroy(dResourceRequirementsID requirements);
/**
* @brief Clones ResourceRequirements object.
*
* The function creates a copy of the ResourceRequirements object with all the
* contents and the relation to Cooperative matching. The object passed in
* the parameter is not changed.
*
* The object created with the function must later be destroyed with @c dResourceRequirementsDestroy.
*
* @param requirements A ResourceRequirements object to be cloned
* @returns A handle to the new object or NULL if allocation fails
* @ingroup coop
* @see dResourceRequirementsCreate
* @see dResourceRequirementsDestroy
* @see dResourceRequirementsMergeIn
*/
ODE_API dResourceRequirementsID dResourceRequirementsClone(/*const */dResourceRequirementsID requirements);
/**
* @brief Merges one ResourceRequirements object into another ResourceRequirements object.
*
* The function updates @a summaryRequirements requirements to be also sufficient
* for the purposes @a extraRequirements could be used for. The @a extraRequirements
* object is not changed. The both objects should normally have had been created
* with the same Cooperative object.
*
* @param summaryRequirements A ResourceRequirements object to be changed
* @param extraRequirements A ResourceRequirements the requirements to be taken from
* @ingroup coop
* @see dResourceRequirementsCreate
* @see dResourceRequirementsDestroy
* @see dResourceRequirementsClone
*/
ODE_API void dResourceRequirementsMergeIn(dResourceRequirementsID summaryRequirements, /*const */dResourceRequirementsID extraRequirements);
/**
* @brief Allocates resources as specified in ResourceRequirements object.
*
* The ResourceContainer object can be used in cooperative computation algorithms.
*
* The same @a requirements object can be passed to many resource allocations
* (with or without modifications) and can be deleted immediately, without waiting
* for the ResourceContainer object destruction.
*
* Use @c dResourceContainerDestroy to delete the object and release the resources
* when they are no longer needed.
*
* @param requirements The ResourceRequirements object to allocate resources according to
* @returns A ResourceContainer object instance with the resources allocated or NULL if allocation fails
* @ingroup coop
* @see dResourceContainerDestroy
* @see dResourceRequirementsCreate
*/
ODE_API dResourceContainerID dResourceContainerAcquire(/*const */dResourceRequirementsID requirements);
/**
* @brief Destroys ResourceContainer object and releases resources allocated in it.
*
* @param resources A ResourceContainer object to be deleted (NULL is allowed)
* @ingroup coop
* @see dResourceContainerAcquire
*/
ODE_API void dResourceContainerDestroy(dResourceContainerID resources);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef _ODE_COOPERATIVE_H_

@ -0,0 +1,63 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* this comes from the `reuse' library. copy any changes back to the source */
#ifndef _ODE_ERROR_H_
#define _ODE_ERROR_H_
#include <ode/odeconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
/* all user defined error functions have this type. error and debug functions
* should not return.
*/
typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
/* set a new error, debug or warning handler. if fn is 0, the default handlers
* are used.
*/
ODE_API void dSetErrorHandler (dMessageFunction *fn);
ODE_API void dSetDebugHandler (dMessageFunction *fn);
ODE_API void dSetMessageHandler (dMessageFunction *fn);
/* return the current error, debug or warning handler. if the return value is
* 0, the default handlers are in place.
*/
ODE_API dMessageFunction *dGetErrorHandler(void);
ODE_API dMessageFunction *dGetDebugHandler(void);
ODE_API dMessageFunction *dGetMessageHandler(void);
/* generate a fatal error, debug trap or a message. */
ODE_API void ODE_NORETURN dError (int num, const char *msg, ...);
ODE_API void ODE_NORETURN dDebug (int num, const char *msg, ...);
ODE_API void dMessage (int num, const char *msg, ...);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,40 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_EXPORT_DIF_
#define _ODE_EXPORT_DIF_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
ODE_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,144 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_MASS_H_
#define _ODE_MASS_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
struct dMass;
typedef struct dMass dMass;
/**
* Check if a mass structure has valid value.
* The function check if the mass and innertia matrix are positive definits
*
* @param m A mass structure to check
*
* @return 1 if both codition are met
*/
ODE_API int dMassCheck(const dMass *m);
ODE_API void dMassSetZero (dMass *);
ODE_API void dMassSetParameters (dMass *, dReal themass,
dReal cgx, dReal cgy, dReal cgz,
dReal I11, dReal I22, dReal I33,
dReal I12, dReal I13, dReal I23);
ODE_API void dMassSetSphere (dMass *, dReal density, dReal radius);
ODE_API void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius);
ODE_API void dMassSetCapsule (dMass *, dReal density, int direction,
dReal radius, dReal length);
ODE_API void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction,
dReal radius, dReal length);
ODE_API void dMassSetCylinder (dMass *, dReal density, int direction,
dReal radius, dReal length);
ODE_API void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction,
dReal radius, dReal length);
ODE_API void dMassSetBox (dMass *, dReal density,
dReal lx, dReal ly, dReal lz);
ODE_API void dMassSetBoxTotal (dMass *, dReal total_mass,
dReal lx, dReal ly, dReal lz);
ODE_API void dMassSetTrimesh (dMass *, dReal density, dGeomID g);
ODE_API void dMassSetTrimeshTotal (dMass *m, dReal total_mass, dGeomID g);
ODE_API void dMassAdjust (dMass *, dReal newmass);
ODE_API void dMassTranslate (dMass *, dReal x, dReal y, dReal z);
ODE_API void dMassRotate (dMass *, const dMatrix3 R);
ODE_API void dMassAdd (dMass *a, const dMass *b);
/* Backwards compatible API */
ODE_API_DEPRECATED ODE_API void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e);
ODE_API_DEPRECATED ODE_API void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e);
struct dMass {
dReal mass;
dVector3 c;
dMatrix3 I;
#ifdef __cplusplus
dMass()
{ dMassSetZero (this); }
void setZero()
{ dMassSetZero (this); }
void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz,
dReal I11, dReal I22, dReal I33,
dReal I12, dReal I13, dReal I23)
{ dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); }
void setSphere (dReal density, dReal radius)
{ dMassSetSphere (this,density,radius); }
void setSphereTotal (dReal total, dReal radius)
{ dMassSetSphereTotal (this,total,radius); }
void setCapsule (dReal density, int direction, dReal radius, dReal length)
{ dMassSetCapsule (this,density,direction,radius,length); }
void setCapsuleTotal (dReal total, int direction, dReal radius, dReal length)
{ dMassSetCapsule (this,total,direction,radius,length); }
void setCylinder(dReal density, int direction, dReal radius, dReal length)
{ dMassSetCylinder (this,density,direction,radius,length); }
void setCylinderTotal(dReal total, int direction, dReal radius, dReal length)
{ dMassSetCylinderTotal (this,total,direction,radius,length); }
void setBox (dReal density, dReal lx, dReal ly, dReal lz)
{ dMassSetBox (this,density,lx,ly,lz); }
void setBoxTotal (dReal total, dReal lx, dReal ly, dReal lz)
{ dMassSetBoxTotal (this,total,lx,ly,lz); }
void setTrimesh(dReal density, dGeomID g)
{ dMassSetTrimesh (this, density, g); }
void setTrimeshTotal(dReal total, dGeomID g)
{ dMassSetTrimeshTotal (this, total, g); }
void adjust (dReal newmass)
{ dMassAdjust (this,newmass); }
void translate (dReal x, dReal y, dReal z)
{ dMassTranslate (this,x,y,z); }
void rotate (const dMatrix3 R)
{ dMassRotate (this,R); }
void add (const dMass *b)
{ dMassAdd (this,b); }
#endif
};
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,200 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* optimized and unoptimized vector and matrix functions */
#ifndef _ODE_MATRIX_H_
#define _ODE_MATRIX_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/* set a vector/matrix of size n to all zeros, or to a specific value. */
ODE_API void dSetZero (dReal *a, int n);
ODE_API void dSetValue (dReal *a, int n, dReal value);
/* get the dot product of two n*1 vectors. if n <= 0 then
* zero will be returned (in which case a and b need not be valid).
*/
ODE_API dReal dDot (const dReal *a, const dReal *b, int n);
/* get the dot products of (a0,b), (a1,b), etc and return them in outsum.
* all vectors are n*1. if n <= 0 then zeroes will be returned (in which case
* the input vectors need not be valid). this function is somewhat faster
* than calling dDot() for all of the combinations separately.
*/
/* NOT INCLUDED in the library for now.
void dMultidot2 (const dReal *a0, const dReal *a1,
const dReal *b, dReal *outsum, int n);
*/
/* matrix multiplication. all matrices are stored in standard row format.
* the digit refers to the argument that is transposed:
* 0: A = B * C (sizes: A:p*r B:p*q C:q*r)
* 1: A = B' * C (sizes: A:p*r B:q*p C:q*r)
* 2: A = B * C' (sizes: A:p*r B:p*q C:r*q)
* case 1,2 are equivalent to saying that the operation is A=B*C but
* B or C are stored in standard column format.
*/
ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
/* do an in-place cholesky decomposition on the lower triangle of the n*n
* symmetric matrix A (which is stored by rows). the resulting lower triangle
* will be such that L*L'=A. return 1 on success and 0 on failure (on failure
* the matrix is not positive definite).
*/
ODE_API int dFactorCholesky (dReal *A, int n);
/* solve for x: L*L'*x = b, and put the result back into x.
* L is size n*n, b is size n*1. only the lower triangle of L is considered.
*/
ODE_API void dSolveCholesky (const dReal *L, dReal *b, int n);
/* compute the inverse of the n*n positive definite matrix A and put it in
* Ainv. this is not especially fast. this returns 1 on success (A was
* positive definite) or 0 on failure (not PD).
*/
ODE_API int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n);
/* check whether an n*n matrix A is positive definite, return 1/0 (yes/no).
* positive definite means that x'*A*x > 0 for any x. this performs a
* cholesky decomposition of A. if the decomposition fails then the matrix
* is not positive definite. A is stored by rows. A is not altered.
*/
ODE_API int dIsPositiveDefinite (const dReal *A, int n);
/* factorize a matrix A into L*D*L', where L is lower triangular with ones on
* the diagonal, and D is diagonal.
* A is an n*n matrix stored by rows, with a leading dimension of n rounded
* up to 4. L is written into the strict lower triangle of A (the ones are not
* written) and the reciprocal of the diagonal elements of D are written into
* d.
*/
ODE_API void dFactorLDLT (dReal *A, dReal *d, int n, int nskip);
/* solve L*x=b, where L is n*n lower triangular with ones on the diagonal,
* and x,b are n*1. b is overwritten with x.
* the leading dimension of L is `nskip'.
*/
ODE_API void dSolveL1 (const dReal *L, dReal *b, int n, int nskip);
/* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal,
* and x,b are n*1. b is overwritten with x.
* the leading dimension of L is `nskip'.
*/
ODE_API void dSolveL1T (const dReal *L, dReal *b, int n, int nskip);
/* in matlab syntax: a(1:n) = a(1:n) .* d(1:n)
*/
ODE_API void dScaleVector (dReal *a, const dReal *d, int n);
/* The function is an alias for @c dScaleVector.
* It has been deprecated because of a wrong naming schema used.
*/
ODE_API_DEPRECATED ODE_API void dVectorScale (dReal *a, const dReal *d, int n);
/* given `L', a n*n lower triangular matrix with ones on the diagonal,
* and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix
* D, solve L*D*L'*x=b where x,b are n*1. x overwrites b.
* the leading dimension of L is `nskip'.
*/
ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
/* given an L*D*L' factorization of an n*n matrix A, return the updated
* factorization L2*D2*L2' of A plus the following "top left" matrix:
*
* [ b a' ] <-- b is a[0]
* [ a 0 ] <-- a is a[1..n-1]
*
* - L has size n*n, its leading dimension is nskip. L is lower triangular
* with ones on the diagonal. only the lower triangle of L is referenced.
* - d has size n. d contains the reciprocal diagonal elements of D.
* - a has size n.
* the result is written into L, except that the left column of L and d[0]
* are not actually modified. see ldltaddTL.m for further comments.
*/
ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip);
/* given an L*D*L' factorization of a permuted matrix A, produce a new
* factorization for row and column `r' removed.
* - A has size n1*n1, its leading dimension in nskip. A is symmetric and
* positive definite. only the lower triangle of A is referenced.
* A itself may actually be an array of row pointers.
* - L has size n2*n2, its leading dimension in nskip. L is lower triangular
* with ones on the diagonal. only the lower triangle of L is referenced.
* - d has size n2. d contains the reciprocal diagonal elements of D.
* - p is a permutation vector. it contains n2 indexes into A. each index
* must be in the range 0..n1-1.
* - r is the row/column of L to remove.
* the new L will be written within the old L, i.e. will have the same leading
* dimension. the last row and column of L, and the last element of d, are
* undefined on exit.
*
* a fast O(n^2) algorithm is used. see ldltremove.m for further comments.
*/
ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
int n1, int n2, int r, int nskip);
/* given an n*n matrix A (with leading dimension nskip), remove the r'th row
* and column by moving elements. the new matrix will have the same leading
* dimension. the last row and column of A are untouched on exit.
*/
ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,291 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_MATRIX_COOP_H_
#define _ODE_MATRIX_COOP_H_
#include <ode/common.h>
#include <ode/cooperative.h>
#include <ode/threading.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup matrix_coop Matrix Cooperative Algorithms
*
* Cooperative algorithms operating on matrices and vectors.
*
* @ingroup coop
*/
/**
* @brief Estimates resource requirements for a @c dCooperativelyFactorLDLT call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelyFactorLDLT with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalRowCount Maximal value of rowCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelyFactorLDLT
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelyFactorLDLTResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
/**
* @brief Cooperatively factorizes a matrix `A' into L*D*L'
*
* The function factorizes a matrix `A' into L*D*L', where `L' is lower triangular with ones on
* the diagonal, and `D' is diagonal.
* @a A is a rowCount*rowCount matrix stored by rows, with a leading dimension of @a rowCount rounded
* up at least to 4 elements. `L; is written into the strict lower triangle of @a A
* (the ones are not written) and the reciprocal of the diagonal elements of `D' are written into @a d.
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelyFactorLDLTResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param A The `A' matrix
* @param d The `d' vector
* @param rowCount The row count in @a A and @a d
* @param rowskip The actual number of elements to be added to skip to next row in @a A
* @ingroup matrix_coop
* @see dEstimateCooperativelyFactorLDLTResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelySolveLDLT
*/
ODE_API void dCooperativelyFactorLDLT(dResourceContainerID resources, unsigned allowedThreadCount,
dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip);
/**
* @brief Estimates resource requirements for a @c dCooperativelySolveLDLT call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelySolveLDLT with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalRowCount Maximal value of rowCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelySolveLDLT
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelySolveLDLTResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
/**
* @brief Cooperatively solves L*D*L'*x=b
*
* Given `L', a rowCount*rowCount lower triangular matrix with ones on the diagonal,
* and `d', a rowCount*1 vector of the reciprocal diagonal elements of a rowCount*rowCount matrix
* D, the function solves L*D*L'*x=b where `x' and `b' are rowCount*1.
* The leading dimension of @a L is @a rowSkip. The resulting vector `x' overwrites @a b.
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelySolveLDLTResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param L The `L' matrix
* @param d The `d' vector
* @param b The `b' vector; also the result is stored here
* @param rowCount The row count in @a L, @a d and @a b
* @param rowskip The actual number of elements to be added to skip to next row in @a L
* @ingroup matrix_coop
* @see dEstimateCooperativelySolveLDLTResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelyFactorLDLT
*/
ODE_API void dCooperativelySolveLDLT(dResourceContainerID resources, unsigned allowedThreadCount,
const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip);
/**
* @brief Estimates resource requirements for a @c dCooperativelySolveL1Straight call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelySolveL1Straight with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalRowCount Maximal value of rowCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelySolveL1Straight
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelySolveL1StraightResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
/**
* @brief Cooperatively solves L*x=b
*
* The function solves L*x=b, where `L' is rowCount*rowCount lower triangular with ones on the diagonal,
* and `x', `b' are rowCount*1. The leading dimension of @a L is @a rowSkip.
* @a b is overwritten with `x'.
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelySolveL1StraightResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param L The `L' matrix
* @param b The `b' vector; also the result is stored here
* @param rowCount The row count in @a L and @a b
* @param rowskip The actual number of elements to be added to skip to next row in @a L
* @ingroup matrix_coop
* @see dEstimateCooperativelySolveL1StraightResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelyFactorLDLT
*/
ODE_API void dCooperativelySolveL1Straight(dResourceContainerID resources, unsigned allowedThreadCount,
const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip);
/**
* @brief Estimates resource requirements for a @c dCooperativelySolveL1Transposed call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelySolveL1Transposed with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalRowCount Maximal value of rowCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelySolveL1Transposed
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelySolveL1TransposedResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalRowCount);
/**
* @brief Cooperatively solves L'*x=b
*
* The function solves L'*x=b, where `L' is rowCount*rowCount lower triangular with ones on the diagonal,
* and `x', b are rowCount*1. The leading dimension of @a L is @a rowSkip.
* @a b is overwritten with `x'.
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelySolveL1TransposedResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param L The `L' matrix
* @param b The `b' vector; also the result is stored here
* @param rowCount The row count in @a L and @a b
* @param rowskip The actual number of elements to be added to skip to next row in @a L
* @ingroup matrix_coop
* @see dEstimateCooperativelySolveL1TransposedResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelyFactorLDLT
*/
ODE_API void dCooperativelySolveL1Transposed(dResourceContainerID resources, unsigned allowedThreadCount,
const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip);
/**
* @brief Estimates resource requirements for a @c dCooperativelyScaleVector call
*
* The function updates the contents of @a requirements to also suffice for calling
* @c dCooperativelyScaleVector with the given parameters.
*
* Note: The requirements that could have already been in the @a requirements parameter
* are never decreased.
*
* @param requirements The ResourceRequirements object to update
* @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used
* @param maximalElementCount Maximal value of elementCount parameter that is going to be used
* @ingroup matrix_coop
* @see dCooperativelyScaleVector
* @see dResourceRequirementsCreate
*/
ODE_API void dEstimateCooperativelyScaleVectorResourceRequirements(dResourceRequirementsID requirements,
unsigned maximalAllowedThreadCount, unsigned maximalElementCount);
/**
* @brief Multiplies elements of one vector by corresponding element of another one
*
* In matlab syntax, the operation performed is: dataVector(1:elementCount) = dataVector(1:elementCount) .* scaleVector(1:elementCount)
*
* The @a resources must have had been allocated from a ResourceRequirements object
* estimated in @c dEstimateCooperativelyScaleVectorResourceRequirements.
*
* The operation is performed cooperatively by up to @a allowedThreadCount threads
* from thread pool available in @a resources. The threading must must not be simultaneously
* used (via other @c dResourceContainerID instances) in other calls that employ its features.
*
* @param resources The resources allocated for the function
* @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters)
* @param dataVector The vector to be scaled in place
* @param scaleVector The scale vector
* @param elementCount The number of elements in @a dataVector and @a scaleVector
* @ingroup matrix_coop
* @see dEstimateCooperativelyScaleVectorResourceRequirements
* @see dResourceContainerAcquire
* @see dCooperativelyFactorLDLT
*/
ODE_API void dCooperativelyScaleVector(dResourceContainerID resources, unsigned allowedThreadCount,
dReal *dataVector, const dReal *scaleVector, unsigned elementCount);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef _ODE_MATRIX_COOP_H_

@ -0,0 +1,59 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* this comes from the `reuse' library. copy any changes back to the source */
#ifndef _ODE_MEMORY_H_
#define _ODE_MEMORY_H_
#include <ode/odeconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
/* function types to allocate and free memory */
typedef void * dAllocFunction (dsizeint size);
typedef void * dReallocFunction (void *ptr, dsizeint oldsize, dsizeint newsize);
typedef void dFreeFunction (void *ptr, dsizeint size);
/* set new memory management functions. if fn is 0, the default handlers are
* used. */
ODE_API void dSetAllocHandler (dAllocFunction *fn);
ODE_API void dSetReallocHandler (dReallocFunction *fn);
ODE_API void dSetFreeHandler (dFreeFunction *fn);
/* get current memory management functions */
ODE_API dAllocFunction *dGetAllocHandler (void);
ODE_API dReallocFunction *dGetReallocHandler (void);
ODE_API dFreeFunction *dGetFreeHandler (void);
/* allocate and free memory. */
ODE_API void * dAlloc (dsizeint size);
ODE_API void * dRealloc (void *ptr, dsizeint oldsize, dsizeint newsize);
ODE_API void dFree (void *ptr, dsizeint size);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,86 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* miscellaneous math functions. these are mostly useful for testing */
#ifndef _ODE_MISC_H_
#define _ODE_MISC_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/* return 1 if the random number generator is working. */
ODE_API int dTestRand(void);
/* return next 32 bit random number. this uses a not-very-random linear
* congruential method.
*/
ODE_API unsigned long dRand(void);
/* get and set the current random number seed. */
ODE_API unsigned long dRandGetSeed(void);
ODE_API void dRandSetSeed (unsigned long s);
/* return a random integer between 0..n-1. the distribution will get worse
* as n approaches 2^32.
*/
ODE_API int dRandInt (int n);
/* return a random real number between 0..1 */
ODE_API dReal dRandReal(void);
/* print out a matrix */
ODE_API void dPrintMatrix (const dReal *A, int n, int m, const char *fmt, FILE *f);
/* make a random vector with entries between +/- range. A has n elements. */
ODE_API void dMakeRandomVector (dReal *A, int n, dReal range);
/* make a random matrix with entries between +/- range. A has size n*m. */
ODE_API void dMakeRandomMatrix (dReal *A, int n, int m, dReal range);
/* clear the upper triangle of a square matrix */
ODE_API void dClearUpperTriangle (dReal *A, int n);
/* return the maximum element difference between the two n*m matrices */
ODE_API dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m);
/* return the maximum element difference between the lower triangle of two
* n*n matrices */
ODE_API dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
static inline void dPrintMatrix (const dReal *A, int n, int m, const char *fmt="%10.4f ") { dPrintMatrix(A, n, m, fmt, stdout); }
#endif
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,56 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ODE_H_
#define _ODE_ODE_H_
/* include *everything* here */
#include <ode/odeconfig.h>
#include <ode/compatibility.h>
#include <ode/common.h>
#include <ode/odeinit.h>
#include <ode/contact.h>
#include <ode/error.h>
#include <ode/memory.h>
#include <ode/odemath.h>
#include <ode/matrix.h>
#include <ode/matrix_coop.h>
#include <ode/timer.h>
#include <ode/rotation.h>
#include <ode/mass.h>
#include <ode/misc.h>
#include <ode/objects.h>
#include <ode/collision_space.h>
#include <ode/collision.h>
#include <ode/threading.h>
#include <ode/threading_impl.h>
#include <ode/cooperative.h>
#include <ode/export-dif.h>
#include <ode/version.h>
#ifdef __cplusplus
# include <ode/odecpp.h>
# include <ode/odecpp_collision.h>
#endif
#endif

@ -0,0 +1,215 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ODECONFIG_H_
#define _ODE_ODECONFIG_H_
/* Pull in the standard headers */
#include <stddef.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <float.h>
#include <ode/precision.h>
#if defined(ODE_DLL) || defined(ODE_LIB)
#define __ODE__
#endif
/* Define a DLL export symbol for those platforms that need it */
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(_WIN32))
#if defined(ODE_DLL)
#define ODE_API __declspec(dllexport)
#elif !defined(ODE_LIB)
#define ODE_DLL_API __declspec(dllimport)
#endif
#endif
#if !defined(ODE_API)
#define ODE_API
#endif
#if defined(_MSC_VER)
# define ODE_API_DEPRECATED __declspec(deprecated)
#elif defined (__GNUC__) && ( (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) )
# define ODE_API_DEPRECATED __attribute__((__deprecated__))
#else
# define ODE_API_DEPRECATED
#endif
#define ODE_PURE_INLINE static __inline
#define ODE_INLINE __inline
#if defined(__cplusplus)
#define ODE_EXTERN_C extern "C"
#else
#define ODE_EXTERN_C
#endif
#if defined(__GNUC__)
#define ODE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define ODE_NORETURN __declspec(noreturn)
#else // #if !defined(_MSC_VER)
#define ODE_NORETURN
#endif // #if !defined(__GNUC__)
/* Well-defined common data types...need to define for 64 bit systems */
#if defined(__aarch64__)
#include <stdint.h>
typedef int64_t dint64;
typedef uint64_t duint64;
typedef int32_t dint32;
typedef uint32_t duint32;
typedef int16_t dint16;
typedef uint16_t duint16;
typedef int8_t dint8;
typedef uint8_t duint8;
typedef intptr_t dintptr;
typedef uintptr_t duintptr;
typedef ptrdiff_t ddiffint;
typedef size_t dsizeint;
#elif defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__)
#define X86_64_SYSTEM 1
#if defined(_MSC_VER)
typedef __int64 dint64;
typedef unsigned __int64 duint64;
#else
#if defined(_LP64)
typedef long dint64;
typedef unsigned long duint64;
#else
typedef long long dint64;
typedef unsigned long long duint64;
#endif
#endif
typedef int dint32;
typedef unsigned int duint32;
typedef short dint16;
typedef unsigned short duint16;
typedef signed char dint8;
typedef unsigned char duint8;
typedef dint64 dintptr;
typedef duint64 duintptr;
typedef dint64 ddiffint;
typedef duint64 dsizeint;
#else
#if defined(_MSC_VER)
typedef __int64 dint64;
typedef unsigned __int64 duint64;
#else
typedef long long dint64;
typedef unsigned long long duint64;
#endif
typedef int dint32;
typedef unsigned int duint32;
typedef short dint16;
typedef unsigned short duint16;
typedef signed char dint8;
typedef unsigned char duint8;
typedef dint32 dintptr;
typedef duint32 duintptr;
typedef dint32 ddiffint;
typedef duint32 dsizeint;
#endif
/* Define the dInfinity macro */
#ifdef INFINITY
#ifdef dSINGLE
#define dInfinity ((float)INFINITY)
#else
#define dInfinity ((double)INFINITY)
#endif
#elif defined(HUGE_VAL)
#ifdef dSINGLE
#ifdef HUGE_VALF
#define dInfinity HUGE_VALF
#else
#define dInfinity ((float)HUGE_VAL)
#endif
#else
#define dInfinity HUGE_VAL
#endif
#else
#ifdef dSINGLE
#define dInfinity ((float)(1.0/0.0))
#else
#define dInfinity (1.0/0.0)
#endif
#endif
/* Define the dNaN macro */
#if defined(NAN)
#define dNaN NAN
#elif defined(__GNUC__)
#define dNaN ({ union { duint32 m_ui; float m_f; } un; un.m_ui = 0x7FC00000; un.m_f; })
#elif defined(__cplusplus)
union _dNaNUnion
{
_dNaNUnion(): m_ui(0x7FC00000) {}
duint32 m_ui;
float m_f;
};
#define dNaN (_dNaNUnion().m_f)
#else
#ifdef dSINGLE
#define dNaN ((float)(dInfinity - dInfinity))
#else
#define dNaN (dInfinity - dInfinity)
#endif
#endif
/* Visual C does not define these functions */
#if defined(_MSC_VER)
#define _ode_copysignf(x, y) ((float)_copysign(x, y))
#define _ode_copysign(x, y) _copysign(x, y)
#define _ode_nextafterf(x, y) _nextafterf(x, y)
#define _ode_nextafter(x, y) _nextafter(x, y)
#if !defined(_WIN64) && defined(dSINGLE)
#define _ODE__NEXTAFTERF_REQUIRED
ODE_EXTERN_C float _nextafterf(float x, float y);
#endif
#else
#define _ode_copysignf(x, y) copysignf(x, y)
#define _ode_copysign(x, y) copysign(x, y)
#define _ode_nextafterf(x, y) nextafterf(x, y)
#define _ode_nextafter(x, y) nextafter(x, y)
#endif
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,467 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* C++ interface for new collision API */
#ifndef _ODE_ODECPP_COLLISION_H_
#define _ODE_ODECPP_COLLISION_H_
#ifdef __cplusplus
//#include <ode/error.h>
//namespace ode {
class dGeom {
// intentionally undefined, don't use these
dGeom (dGeom &);
void operator= (dGeom &);
protected:
dGeomID _id;
dGeom()
{ _id = 0; }
public:
~dGeom()
{ if (_id) dGeomDestroy (_id); }
dGeomID id() const
{ return _id; }
operator dGeomID() const
{ return _id; }
void destroy() {
if (_id) dGeomDestroy (_id);
_id = 0;
}
int getClass() const
{ return dGeomGetClass (_id); }
dSpaceID getSpace() const
{ return dGeomGetSpace (_id); }
void setData (void *data)
{ dGeomSetData (_id,data); }
void *getData() const
{ return dGeomGetData (_id); }
void setBody (dBodyID b)
{ dGeomSetBody (_id,b); }
dBodyID getBody() const
{ return dGeomGetBody (_id); }
void setPosition (dReal x, dReal y, dReal z)
{ dGeomSetPosition (_id,x,y,z); }
const dReal * getPosition() const
{ return dGeomGetPosition (_id); }
void setRotation (const dMatrix3 R)
{ dGeomSetRotation (_id,R); }
const dReal * getRotation() const
{ return dGeomGetRotation (_id); }
void setQuaternion (const dQuaternion quat)
{ dGeomSetQuaternion (_id,quat); }
void getQuaternion (dQuaternion quat) const
{ dGeomGetQuaternion (_id,quat); }
void getAABB (dReal aabb[6]) const
{ dGeomGetAABB (_id, aabb); }
int isSpace()
{ return dGeomIsSpace (_id); }
void setCategoryBits (unsigned long bits)
{ dGeomSetCategoryBits (_id, bits); }
void setCollideBits (unsigned long bits)
{ dGeomSetCollideBits (_id, bits); }
unsigned long getCategoryBits()
{ return dGeomGetCategoryBits (_id); }
unsigned long getCollideBits()
{ return dGeomGetCollideBits (_id); }
void enable()
{ dGeomEnable (_id); }
void disable()
{ dGeomDisable (_id); }
int isEnabled()
{ return dGeomIsEnabled (_id); }
void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
{ dGeomGetRelPointPos (_id, px, py, pz, result); }
void getRelPointPos (const dVector3 p, dVector3 result) const
{ getRelPointPos (p[0], p[1], p[2], result); }
void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
{ dGeomGetPosRelPoint (_id, px, py, pz, result); }
void getPosRelPoint (const dVector3 p, dVector3 result) const
{ getPosRelPoint (p[0], p[1], p[2], result); }
void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
{ dGeomVectorToWorld (_id, px, py, pz, result); }
void vectorToWorld (const dVector3 p, dVector3 result) const
{ vectorToWorld (p[0], p[1], p[2], result); }
void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
{ dGeomVectorFromWorld (_id, px, py, pz, result); }
void vectorFromWorld (const dVector3 p, dVector3 result) const
{ vectorFromWorld (p[0], p[1], p[2], result); }
void collide2 (dGeomID g, void *data, dNearCallback *callback)
{ dSpaceCollide2 (_id,g,data,callback); }
};
class dSpace : public dGeom {
// intentionally undefined, don't use these
dSpace (dSpace &);
void operator= (dSpace &);
protected:
// the default constructor is protected so that you
// can't instance this class. you must instance one
// of its subclasses instead.
dSpace () { _id = 0; }
public:
dSpaceID id() const
{ return (dSpaceID) _id; }
operator dSpaceID() const
{ return (dSpaceID) _id; }
void setCleanup (int mode)
{ dSpaceSetCleanup (id(), mode); }
int getCleanup()
{ return dSpaceGetCleanup (id()); }
void add (dGeomID x)
{ dSpaceAdd (id(), x); }
void remove (dGeomID x)
{ dSpaceRemove (id(), x); }
int query (dGeomID x)
{ return dSpaceQuery (id(),x); }
int getNumGeoms()
{ return dSpaceGetNumGeoms (id()); }
dGeomID getGeom (int i)
{ return dSpaceGetGeom (id(),i); }
void collide (void *data, dNearCallback *callback)
{ dSpaceCollide (id(),data,callback); }
};
class dSimpleSpace : public dSpace {
// intentionally undefined, don't use these
dSimpleSpace (dSimpleSpace &);
void operator= (dSimpleSpace &);
public:
dSimpleSpace ()
{ _id = (dGeomID) dSimpleSpaceCreate (0); }
dSimpleSpace (dSpace &space)
{ _id = (dGeomID) dSimpleSpaceCreate (space.id()); }
dSimpleSpace (dSpaceID space)
{ _id = (dGeomID) dSimpleSpaceCreate (space); }
};
class dHashSpace : public dSpace {
// intentionally undefined, don't use these
dHashSpace (dHashSpace &);
void operator= (dHashSpace &);
public:
dHashSpace ()
{ _id = (dGeomID) dHashSpaceCreate (0); }
dHashSpace (dSpace &space)
{ _id = (dGeomID) dHashSpaceCreate (space.id()); }
dHashSpace (dSpaceID space)
{ _id = (dGeomID) dHashSpaceCreate (space); }
void setLevels (int minlevel, int maxlevel)
{ dHashSpaceSetLevels (id(),minlevel,maxlevel); }
};
class dQuadTreeSpace : public dSpace {
// intentionally undefined, don't use these
dQuadTreeSpace (dQuadTreeSpace &);
void operator= (dQuadTreeSpace &);
public:
dQuadTreeSpace (const dVector3 center, const dVector3 extents, int depth)
{ _id = (dGeomID) dQuadTreeSpaceCreate (0,center,extents,depth); }
dQuadTreeSpace (dSpace &space, const dVector3 center, const dVector3 extents, int depth)
{ _id = (dGeomID) dQuadTreeSpaceCreate (space.id(),center,extents,depth); }
dQuadTreeSpace (dSpaceID space, const dVector3 center, const dVector3 extents, int depth)
{ _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); }
};
class dSphere : public dGeom {
// intentionally undefined, don't use these
dSphere (dSphere &);
void operator= (dSphere &);
public:
dSphere () { }
dSphere (dReal radius)
{ _id = dCreateSphere (0, radius); }
dSphere (dSpace &space, dReal radius)
{ _id = dCreateSphere (space.id(), radius); }
dSphere (dSpaceID space, dReal radius)
{ _id = dCreateSphere (space, radius); }
void create (dSpaceID space, dReal radius) {
if (_id) dGeomDestroy (_id);
_id = dCreateSphere (space, radius);
}
void setRadius (dReal radius)
{ dGeomSphereSetRadius (_id, radius); }
dReal getRadius() const
{ return dGeomSphereGetRadius (_id); }
};
class dBox : public dGeom {
// intentionally undefined, don't use these
dBox (dBox &);
void operator= (dBox &);
public:
dBox () { }
dBox (dReal lx, dReal ly, dReal lz)
{ _id = dCreateBox (0,lx,ly,lz); }
dBox (dSpace &space, dReal lx, dReal ly, dReal lz)
{ _id = dCreateBox (space,lx,ly,lz); }
dBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
{ _id = dCreateBox (space,lx,ly,lz); }
void create (dSpaceID space, dReal lx, dReal ly, dReal lz) {
if (_id) dGeomDestroy (_id);
_id = dCreateBox (space,lx,ly,lz);
}
void setLengths (dReal lx, dReal ly, dReal lz)
{ dGeomBoxSetLengths (_id, lx, ly, lz); }
void getLengths (dVector3 result) const
{ dGeomBoxGetLengths (_id,result); }
};
class dPlane : public dGeom {
// intentionally undefined, don't use these
dPlane (dPlane &);
void operator= (dPlane &);
public:
dPlane() { }
dPlane (dReal a, dReal b, dReal c, dReal d)
{ _id = dCreatePlane (0,a,b,c,d); }
dPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d)
{ _id = dCreatePlane (space.id(),a,b,c,d); }
dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d)
{ _id = dCreatePlane (space,a,b,c,d); }
void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) {
if (_id) dGeomDestroy (_id);
_id = dCreatePlane (space,a,b,c,d);
}
void setParams (dReal a, dReal b, dReal c, dReal d)
{ dGeomPlaneSetParams (_id, a, b, c, d); }
void getParams (dVector4 result) const
{ dGeomPlaneGetParams (_id,result); }
};
class dCapsule : public dGeom {
// intentionally undefined, don't use these
dCapsule (dCapsule &);
void operator= (dCapsule &);
public:
dCapsule() { }
dCapsule (dReal radius, dReal length)
{ _id = dCreateCapsule (0,radius,length); }
dCapsule (dSpace &space, dReal radius, dReal length)
{ _id = dCreateCapsule (space.id(),radius,length); }
dCapsule (dSpaceID space, dReal radius, dReal length)
{ _id = dCreateCapsule (space,radius,length); }
void create (dSpaceID space, dReal radius, dReal length) {
if (_id) dGeomDestroy (_id);
_id = dCreateCapsule (space,radius,length);
}
void setParams (dReal radius, dReal length)
{ dGeomCapsuleSetParams (_id, radius, length); }
void getParams (dReal *radius, dReal *length) const
{ dGeomCapsuleGetParams (_id,radius,length); }
};
class dCylinder : public dGeom {
// intentionally undefined, don't use these
dCylinder (dCylinder &);
void operator= (dCylinder &);
public:
dCylinder() { }
dCylinder (dReal radius, dReal length)
{ _id = dCreateCylinder (0,radius,length); }
dCylinder (dSpace &space, dReal radius, dReal length)
{ _id = dCreateCylinder (space.id(),radius,length); }
dCylinder (dSpaceID space, dReal radius, dReal length)
{ _id = dCreateCylinder (space,radius,length); }
void create (dSpaceID space, dReal radius, dReal length) {
if (_id) dGeomDestroy (_id);
_id = dCreateCylinder (space,radius,length);
}
void setParams (dReal radius, dReal length)
{ dGeomCylinderSetParams (_id, radius, length); }
void getParams (dReal *radius, dReal *length) const
{ dGeomCylinderGetParams (_id,radius,length); }
};
class dRay : public dGeom {
// intentionally undefined, don't use these
dRay (dRay &);
void operator= (dRay &);
public:
dRay() { }
dRay (dReal length)
{ _id = dCreateRay (0,length); }
dRay (dSpace &space, dReal length)
{ _id = dCreateRay (space.id(),length); }
dRay (dSpaceID space, dReal length)
{ _id = dCreateRay (space,length); }
void create (dSpaceID space, dReal length) {
if (_id) dGeomDestroy (_id);
_id = dCreateRay (space,length);
}
void setLength (dReal length)
{ dGeomRaySetLength (_id, length); }
dReal getLength()
{ return dGeomRayGetLength (_id); }
void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz)
{ dGeomRaySet (_id, px, py, pz, dx, dy, dz); }
void get (dVector3 start, dVector3 dir)
{ dGeomRayGet (_id, start, dir); }
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4996 )
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
ODE_API_DEPRECATED
void setParams (int firstContact, int backfaceCull)
{ dGeomRaySetParams (_id, firstContact, backfaceCull); }
ODE_API_DEPRECATED
void getParams (int *firstContact, int *backfaceCull)
{ dGeomRayGetParams (_id, firstContact, backfaceCull); }
#ifdef WIN32
#pragma warning( pop )
#else
#pragma GCC diagnostic pop
#endif
void setBackfaceCull (int backfaceCull)
{ dGeomRaySetBackfaceCull (_id, backfaceCull); }
int getBackfaceCull()
{ return dGeomRayGetBackfaceCull (_id); }
void setFirstContact (int firstContact)
{ dGeomRaySetFirstContact (_id, firstContact); }
int getFirstContact()
{ return dGeomRayGetFirstContact (_id); }
void setClosestHit (int closestHit)
{ dGeomRaySetClosestHit (_id, closestHit); }
int getClosestHit()
{ return dGeomRayGetClosestHit (_id); }
};
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4996 )
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
class ODE_API_DEPRECATED dGeomTransform : public dGeom {
// intentionally undefined, don't use these
dGeomTransform (dGeomTransform &);
void operator= (dGeomTransform &);
public:
dGeomTransform() { }
dGeomTransform (dSpace &space)
{ _id = dCreateGeomTransform (space.id()); }
dGeomTransform (dSpaceID space)
{ _id = dCreateGeomTransform (space); }
void create (dSpaceID space=0) {
if (_id) dGeomDestroy (_id);
_id = dCreateGeomTransform (space);
}
void setGeom (dGeomID geom)
{ dGeomTransformSetGeom (_id, geom); }
dGeomID getGeom() const
{ return dGeomTransformGetGeom (_id); }
void setCleanup (int mode)
{ dGeomTransformSetCleanup (_id,mode); }
int getCleanup ()
{ return dGeomTransformGetCleanup (_id); }
void setInfo (int mode)
{ dGeomTransformSetInfo (_id,mode); }
int getInfo()
{ return dGeomTransformGetInfo (_id); }
};
#ifdef WIN32
#pragma warning( pop )
#else
#pragma GCC diagnostic pop
#endif
//}
#endif
#endif

@ -0,0 +1,236 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/* Library initialization/finalization functions. */
#ifndef _ODE_ODEINIT_H_
#define _ODE_ODEINIT_H_
#include <ode/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ************************************************************************ */
/* Library initialization */
/**
* @defgroup init Library Initialization
*
* Library initialization functions prepare ODE internal data structures for use
* and release allocated resources after ODE is not needed any more.
*/
/**
* @brief Library initialization flags.
*
* These flags define ODE library initialization options.
*
* @c dInitFlagManualThreadCleanup indicates that resources allocated in TLS for threads
* using ODE are to be cleared by library client with explicit call to @c dCleanupODEAllDataForThread.
* If this flag is not specified the automatic resource tracking algorithm is used.
*
* With automatic resource tracking, On Windows, memory allocated for a thread may
* remain not freed for some time after the thread exits. The resources may be
* released when one of other threads calls @c dAllocateODEDataForThread. Ultimately,
* the resources are released when library is closed with @c dCloseODE. On other
* operating systems resources are always released by the thread itself on its exit
* or on library closure with @c dCloseODE.
*
* With manual thread data cleanup mode every collision space object must be
* explicitly switched to manual cleanup mode with @c dSpaceSetManualCleanup
* after creation. See description of the function for more details.
*
* If @c dInitFlagManualThreadCleanup was not specified during initialization,
* calls to @c dCleanupODEAllDataForThread are not allowed.
*
* @see dInitODE2
* @see dAllocateODEDataForThread
* @see dSpaceSetManualCleanup
* @see dCloseODE
* @ingroup init
*/
enum dInitODEFlags {
dInitFlagManualThreadCleanup = 0x00000001 /*@< Thread local data is to be cleared explicitly on @c dCleanupODEAllDataForThread function call*/
};
/**
* @brief Initializes ODE library.
*
* @c dInitODE is obsolete. @c dInitODE2 is to be used for library initialization.
*
* A call to @c dInitODE is equal to the following initialization sequence
* @code
* dInitODE2(0);
* dAllocateODEDataForThread(dAllocateMaskAll);
* @endcode
*
* @see dInitODE2
* @see dAllocateODEDataForThread
* @ingroup init
*/
ODE_API void dInitODE(void);
/**
* @brief Initializes ODE library.
* @param uiInitFlags Initialization options bitmask
* @return A nonzero if initialization succeeded and zero otherwise.
*
* This function must be called to initialize ODE library before first use. If
* initialization succeeds the function may not be called again until library is
* closed with a call to @c dCloseODE.
*
* The @a uiInitFlags parameter specifies initialization options to be used. These
* can be combination of zero or more @c dInitODEFlags flags.
*
* @note
* If @c dInitFlagManualThreadCleanup flag is used for initialization,
* @c dSpaceSetManualCleanup must be called to set manual cleanup mode for every
* space object right after creation. Failure to do so may lead to resource leaks.
*
* @see dInitODEFlags
* @see dCloseODE
* @see dSpaceSetManualCleanup
* @ingroup init
*/
ODE_API int dInitODE2(unsigned int uiInitFlags/*=0*/);
/**
* @brief ODE data allocation flags.
*
* These flags are used to indicate which data is to be pre-allocated in call to
* @c dAllocateODEDataForThread.
*
* @c dAllocateFlagBasicData tells to allocate the basic data set required for
* normal library operation. This flag is equal to zero and is always implicitly
* included.
*
* @c dAllocateFlagCollisionData tells that collision detection data is to be allocated.
* Collision detection functions may not be called if the data has not be allocated
* in advance. If collision detection is not going to be used, it is not necessary
* to specify this flag.
*
* @c dAllocateMaskAll is a mask that can be used for for allocating all possible
* data in cases when it is not known what exactly features of ODE will be used.
* The mask may not be used in combination with other flags. It is guaranteed to
* include all the current and future legal allocation flags. However, mature
* applications should use explicit flags they need rather than allocating everything.
*
* @see dAllocateODEDataForThread
* @ingroup init
*/
enum dAllocateODEDataFlags {
dAllocateFlagBasicData = 0, /*@< Allocate basic data required for library to operate*/
dAllocateFlagCollisionData = 0x00000001, /*@< Allocate data for collision detection*/
dAllocateMaskAll = ~0 /*@< Allocate all the possible data that is currently defined or will be defined in the future.*/
};
/**
* @brief Allocate thread local data to allow the thread calling ODE.
* @param uiAllocateFlags Allocation options bitmask.
* @return A nonzero if allocation succeeded and zero otherwise.
*
* The function is required to be called for every thread that is going to use
* ODE. This function allocates the data that is required for accessing ODE from
* current thread along with optional data required for particular ODE subsystems.
*
* @a uiAllocateFlags parameter can contain zero or more flags from @c dAllocateODEDataFlags
* enumerated type. Multiple calls with different allocation flags are allowed.
* The flags that are already allocated are ignored in subsequent calls. If zero
* is passed as the parameter, it means to only allocate the set of most important
* data the library can not operate without.
*
* If the function returns failure status it means that none of the requested
* data has been allocated. The client may retry allocation attempt with the same
* flags when more system resources are available.
*
* @see dAllocateODEDataFlags
* @see dCleanupODEAllDataForThread
* @ingroup init
*/
ODE_API int dAllocateODEDataForThread(unsigned int uiAllocateFlags);
/**
* @brief Free thread local data that was allocated for current thread.
*
* If library was initialized with @c dInitFlagManualThreadCleanup flag the function
* is required to be called on exit of every thread that was calling @c dAllocateODEDataForThread.
* Failure to call @c dCleanupODEAllDataForThread may result in some resources remaining
* not freed until program exit. The function may also be called when ODE is still
* being used to release resources allocated for all the current subsystems and
* possibly proceed with data pre-allocation for other subsystems.
*
* The function can safely be called several times in a row. The function can be
* called without prior invocation of @c dAllocateODEDataForThread. The function
* may not be called before ODE is initialized with @c dInitODE2 or after library
* has been closed with @c dCloseODE. A call to @c dCloseODE implicitly releases
* all the thread local resources that might be allocated for all the threads that
* were using ODE.
*
* If library was initialized without @c dInitFlagManualThreadCleanup flag
* @c dCleanupODEAllDataForThread must not be called.
*
* @see dAllocateODEDataForThread
* @see dInitODE2
* @see dCloseODE
* @ingroup init
*/
ODE_API void dCleanupODEAllDataForThread();
/**
* @brief Close ODE after it is not needed any more.
*
* The function is required to be called when program does not need ODE features any more.
* The call to @c dCloseODE releases all the resources allocated for library
* including all the thread local data that might be allocated for all the threads
* that were using ODE.
*
* @c dCloseODE is a paired function for @c dInitODE2 and must only be called
* after successful library initialization.
*
* @note Important!
* Make sure that all the threads that were using ODE have already terminated
* before calling @c dCloseODE. In particular it is not allowed to call
* @c dCleanupODEAllDataForThread after @c dCloseODE.
*
* @see dInitODE2
* @see dCleanupODEAllDataForThread
* @ingroup init
*/
ODE_API void dCloseODE(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _ODE_ODEINIT_H_ */

@ -0,0 +1,545 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ODEMATH_H_
#define _ODE_ODEMATH_H_
#include <ode/common.h>
/*
* macro to access elements i,j in an NxM matrix A, independent of the
* matrix storage convention.
*/
#define dACCESS33(A,i,j) ((A)[(i)*4+(j)])
/*
* Macro to test for valid floating point values
*/
#define dVALIDVEC3(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2])))
#define dVALIDVEC4(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3])))
#define dVALIDMAT3(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11])))
#define dVALIDMAT4(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]) || dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) ))
ODE_PURE_INLINE void dZeroVector3(dVector3 res)
{
res[dV3E_X] = REAL(0.0);
res[dV3E_Y] = REAL(0.0);
res[dV3E_Z] = REAL(0.0);
}
ODE_PURE_INLINE void dAssignVector3(dVector3 res, dReal x, dReal y, dReal z)
{
res[dV3E_X] = x;
res[dV3E_Y] = y;
res[dV3E_Z] = z;
}
ODE_PURE_INLINE void dZeroMatrix3(dMatrix3 res)
{
res[dM3E_XX] = REAL(0.0); res[dM3E_XY] = REAL(0.0); res[dM3E_XZ] = REAL(0.0);
res[dM3E_YX] = REAL(0.0); res[dM3E_YY] = REAL(0.0); res[dM3E_YZ] = REAL(0.0);
res[dM3E_ZX] = REAL(0.0); res[dM3E_ZY] = REAL(0.0); res[dM3E_ZZ] = REAL(0.0);
}
ODE_PURE_INLINE void dZeroMatrix4(dMatrix4 res)
{
res[dM4E_XX] = REAL(0.0); res[dM4E_XY] = REAL(0.0); res[dM4E_XZ] = REAL(0.0); res[dM4E_XO] = REAL(0.0);
res[dM4E_YX] = REAL(0.0); res[dM4E_YY] = REAL(0.0); res[dM4E_YZ] = REAL(0.0); res[dM4E_YO] = REAL(0.0);
res[dM4E_ZX] = REAL(0.0); res[dM4E_ZY] = REAL(0.0); res[dM4E_ZZ] = REAL(0.0); res[dM4E_ZO] = REAL(0.0);
res[dM4E_OX] = REAL(0.0); res[dM4E_OY] = REAL(0.0); res[dM4E_OZ] = REAL(0.0); res[dM4E_OO] = REAL(0.0);
}
/* Some vector math */
ODE_PURE_INLINE void dAddVectors3(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = a[0] + b[0];
const dReal res_1 = a[1] + b[1];
const dReal res_2 = a[2] + b[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dSubtractVectors3(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = a[0] - b[0];
const dReal res_1 = a[1] - b[1];
const dReal res_2 = a[2] - b[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dAddVectorScaledVector3(dReal *res, const dReal *a, const dReal *b, dReal b_scale)
{
const dReal res_0 = a[0] + b_scale * b[0];
const dReal res_1 = a[1] + b_scale * b[1];
const dReal res_2 = a[2] + b_scale * b[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dAddScaledVectors3(dReal *res, const dReal *a, const dReal *b, dReal a_scale, dReal b_scale)
{
const dReal res_0 = a_scale * a[0] + b_scale * b[0];
const dReal res_1 = a_scale * a[1] + b_scale * b[1];
const dReal res_2 = a_scale * a[2] + b_scale * b[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dAddThreeScaledVectors3(dReal *res, const dReal *a, const dReal *b, const dReal *c, dReal a_scale, dReal b_scale, dReal c_scale)
{
const dReal res_0 = a_scale * a[0] + b_scale * b[0] + c_scale * c[0];
const dReal res_1 = a_scale * a[1] + b_scale * b[1] + c_scale * c[1];
const dReal res_2 = a_scale * a[2] + b_scale * b[2] + c_scale * c[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dScaleVector3(dReal *res, dReal nScale)
{
res[0] *= nScale ;
res[1] *= nScale ;
res[2] *= nScale ;
}
ODE_PURE_INLINE void dNegateVector3(dReal *res)
{
res[0] = -res[0];
res[1] = -res[1];
res[2] = -res[2];
}
ODE_PURE_INLINE void dCopyVector3(dReal *res, const dReal *a)
{
const dReal res_0 = a[0];
const dReal res_1 = a[1];
const dReal res_2 = a[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dCopyScaledVector3(dReal *res, const dReal *a, dReal nScale)
{
const dReal res_0 = a[0] * nScale;
const dReal res_1 = a[1] * nScale;
const dReal res_2 = a[2] * nScale;
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dCopyNegatedVector3(dReal *res, const dReal *a)
{
const dReal res_0 = -a[0];
const dReal res_1 = -a[1];
const dReal res_2 = -a[2];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dCopyVector4(dReal *res, const dReal *a)
{
const dReal res_0 = a[0];
const dReal res_1 = a[1];
const dReal res_2 = a[2];
const dReal res_3 = a[3];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3;
}
ODE_PURE_INLINE void dCopyMatrix4x4(dReal *res, const dReal *a)
{
dCopyVector4(res + 0, a + 0);
dCopyVector4(res + 4, a + 4);
dCopyVector4(res + 8, a + 8);
}
ODE_PURE_INLINE void dCopyMatrix4x3(dReal *res, const dReal *a)
{
dCopyVector3(res + 0, a + 0);
dCopyVector3(res + 4, a + 4);
dCopyVector3(res + 8, a + 8);
}
ODE_PURE_INLINE void dGetMatrixColumn3(dReal *res, const dReal *a, unsigned n)
{
const dReal res_0 = a[n + 0];
const dReal res_1 = a[n + 4];
const dReal res_2 = a[n + 8];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE dReal dCalcVectorLength3(const dReal *a)
{
return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
}
ODE_PURE_INLINE dReal dCalcVectorLengthSquare3(const dReal *a)
{
return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
}
ODE_PURE_INLINE dReal dCalcPointDepth3(const dReal *test_p, const dReal *plane_p, const dReal *plane_n)
{
return (plane_p[0] - test_p[0]) * plane_n[0] + (plane_p[1] - test_p[1]) * plane_n[1] + (plane_p[2] - test_p[2]) * plane_n[2];
}
/*
* 3-way dot product. _dCalcVectorDot3 means that elements of `a' and `b' are spaced
* step_a and step_b indexes apart respectively. dCalcVectorDot3() means dDot311.
*/
ODE_PURE_INLINE dReal _dCalcVectorDot3(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b)
{
return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b];
}
ODE_PURE_INLINE dReal dCalcVectorDot3 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,1); }
ODE_PURE_INLINE dReal dCalcVectorDot3_13 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,3); }
ODE_PURE_INLINE dReal dCalcVectorDot3_31 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,1); }
ODE_PURE_INLINE dReal dCalcVectorDot3_33 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,3); }
ODE_PURE_INLINE dReal dCalcVectorDot3_14 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,4); }
ODE_PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); }
ODE_PURE_INLINE dReal dCalcVectorDot3_44 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,4); }
/*
* cross product, set res = a x b. _dCalcVectorCross3 means that elements of `res', `a'
* and `b' are spaced step_res, step_a and step_b indexes apart respectively.
* dCalcVectorCross3() means dCross3111.
*/
ODE_PURE_INLINE void _dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b, unsigned step_res, unsigned step_a, unsigned step_b)
{
const dReal res_0 = a[ step_a]*b[2*step_b] - a[2*step_a]*b[ step_b];
const dReal res_1 = a[2*step_a]*b[ 0] - a[ 0]*b[2*step_b];
const dReal res_2 = a[ 0]*b[ step_b] - a[ step_a]*b[ 0];
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[ 0] = res_0;
res[ step_res] = res_1;
res[2*step_res] = res_2;
}
ODE_PURE_INLINE void dCalcVectorCross3 (dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); }
ODE_PURE_INLINE void dCalcVectorCross3_141(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_144(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); }
ODE_PURE_INLINE void dCalcVectorCross3_411(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_414(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); }
ODE_PURE_INLINE void dCalcVectorCross3_441(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_444(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); }
ODE_PURE_INLINE void dAddVectorCross3(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dCalcVectorCross3(tmp, a, b);
dAddVectors3(res, res, tmp);
}
ODE_PURE_INLINE void dSubtractVectorCross3(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dCalcVectorCross3(tmp, a, b);
dSubtractVectors3(res, res, tmp);
}
/*
* set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
* A is stored by rows, and has `skip' elements per row. the matrix is
* assumed to be already zero, so this does not write zero elements!
* if (plus,minus) is (+,-) then a positive version will be written.
* if (plus,minus) is (-,+) then a negative version will be written.
*/
ODE_PURE_INLINE void dSetCrossMatrixPlus(dReal *res, const dReal *a, unsigned skip)
{
const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2];
res[1] = -a_2;
res[2] = +a_1;
res[skip+0] = +a_2;
res[skip+2] = -a_0;
res[2*skip+0] = -a_1;
res[2*skip+1] = +a_0;
}
ODE_PURE_INLINE void dSetCrossMatrixMinus(dReal *res, const dReal *a, unsigned skip)
{
const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2];
res[1] = +a_2;
res[2] = -a_1;
res[skip+0] = -a_2;
res[skip+2] = +a_0;
res[2*skip+0] = +a_1;
res[2*skip+1] = -a_0;
}
/*
* compute the distance between two 3D-vectors
*/
ODE_PURE_INLINE dReal dCalcPointsDistance3(const dReal *a, const dReal *b)
{
dReal res;
dReal tmp[3];
dSubtractVectors3(tmp, a, b);
res = dCalcVectorLength3(tmp);
return res;
}
/*
* special case matrix multiplication, with operator selection
*/
ODE_PURE_INLINE void dMultiplyHelper0_331(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot3(a, b);
const dReal res_1 = dCalcVectorDot3(a + 4, b);
const dReal res_2 = dCalcVectorDot3(a + 8, b);
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dMultiplyHelper1_331(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot3_41(a, b);
const dReal res_1 = dCalcVectorDot3_41(a + 1, b);
const dReal res_2 = dCalcVectorDot3_41(a + 2, b);
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
ODE_PURE_INLINE void dMultiplyHelper0_133(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper1_331(res, b, a);
}
ODE_PURE_INLINE void dMultiplyHelper1_133(dReal *res, const dReal *a, const dReal *b)
{
const dReal res_0 = dCalcVectorDot3_44(a, b);
const dReal res_1 = dCalcVectorDot3_44(a + 1, b);
const dReal res_2 = dCalcVectorDot3_44(a + 2, b);
/* Only assign after all the calculations are over to avoid incurring memory aliasing*/
res[0] = res_0; res[1] = res_1; res[2] = res_2;
}
/*
Note: NEVER call any of these functions/macros with the same variable for A and C,
it is not equivalent to A*=B.
*/
ODE_PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_331(res, a, b);
}
ODE_PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper1_331(res, a, b);
}
ODE_PURE_INLINE void dMultiply0_133(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_133(res, a, b);
}
ODE_PURE_INLINE void dMultiply0_333(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_133(res + 0, a + 0, b);
dMultiplyHelper0_133(res + 4, a + 4, b);
dMultiplyHelper0_133(res + 8, a + 8, b);
}
ODE_PURE_INLINE void dMultiply1_333(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper1_133(res + 0, b, a + 0);
dMultiplyHelper1_133(res + 4, b, a + 1);
dMultiplyHelper1_133(res + 8, b, a + 2);
}
ODE_PURE_INLINE void dMultiply2_333(dReal *res, const dReal *a, const dReal *b)
{
dMultiplyHelper0_331(res + 0, b, a + 0);
dMultiplyHelper0_331(res + 4, b, a + 4);
dMultiplyHelper0_331(res + 8, b, a + 8);
}
ODE_PURE_INLINE void dMultiplyAdd0_331(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper0_331(tmp, a, b);
dAddVectors3(res, res, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd1_331(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper1_331(tmp, a, b);
dAddVectors3(res, res, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd0_133(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper0_133(tmp, a, b);
dAddVectors3(res, res, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd0_333(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper0_133(tmp, a + 0, b);
dAddVectors3(res+ 0, res + 0, tmp);
dMultiplyHelper0_133(tmp, a + 4, b);
dAddVectors3(res + 4, res + 4, tmp);
dMultiplyHelper0_133(tmp, a + 8, b);
dAddVectors3(res + 8, res + 8, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd1_333(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper1_133(tmp, b, a + 0);
dAddVectors3(res + 0, res + 0, tmp);
dMultiplyHelper1_133(tmp, b, a + 1);
dAddVectors3(res + 4, res + 4, tmp);
dMultiplyHelper1_133(tmp, b, a + 2);
dAddVectors3(res + 8, res + 8, tmp);
}
ODE_PURE_INLINE void dMultiplyAdd2_333(dReal *res, const dReal *a, const dReal *b)
{
dReal tmp[3];
dMultiplyHelper0_331(tmp, b, a + 0);
dAddVectors3(res + 0, res + 0, tmp);
dMultiplyHelper0_331(tmp, b, a + 4);
dAddVectors3(res + 4, res + 4, tmp);
dMultiplyHelper0_331(tmp, b, a + 8);
dAddVectors3(res + 8, res + 8, tmp);
}
ODE_PURE_INLINE dReal dCalcMatrix3Det( const dReal* mat )
{
dReal det;
det = mat[0] * ( mat[5]*mat[10] - mat[9]*mat[6] )
- mat[1] * ( mat[4]*mat[10] - mat[8]*mat[6] )
+ mat[2] * ( mat[4]*mat[9] - mat[8]*mat[5] );
return( det );
}
/**
Closed form matrix inversion, copied from
collision_util.h for use in the stepper.
Returns the determinant.
returns 0 and does nothing
if the matrix is singular.
*/
ODE_PURE_INLINE dReal dInvertMatrix3(dReal *dst, const dReal *ma)
{
dReal det;
dReal detRecip;
det = dCalcMatrix3Det( ma );
/* Setting an arbitrary non-zero threshold
for the determinant doesn't do anyone
any favors. The condition number is the
important thing. If all the eigen-values
of the matrix are small, so is the
determinant, but it can still be well
conditioned.
A single extremely large eigen-value could
push the determinant over threshold, but
produce a very unstable result if the other
eigen-values are small. So we just say that
the determinant must be non-zero and trust the
caller to provide well-conditioned matrices.
*/
if ( det == 0 )
{
return 0;
}
detRecip = dRecip(det);
dst[0] = ( ma[5]*ma[10] - ma[6]*ma[9] ) * detRecip;
dst[1] = ( ma[9]*ma[2] - ma[1]*ma[10] ) * detRecip;
dst[2] = ( ma[1]*ma[6] - ma[5]*ma[2] ) * detRecip;
dst[4] = ( ma[6]*ma[8] - ma[4]*ma[10] ) * detRecip;
dst[5] = ( ma[0]*ma[10] - ma[8]*ma[2] ) * detRecip;
dst[6] = ( ma[4]*ma[2] - ma[0]*ma[6] ) * detRecip;
dst[8] = ( ma[4]*ma[9] - ma[8]*ma[5] ) * detRecip;
dst[9] = ( ma[8]*ma[1] - ma[0]*ma[9] ) * detRecip;
dst[10] = ( ma[0]*ma[5] - ma[1]*ma[4] ) * detRecip;
return det;
}
/* Include legacy macros here */
#include <ode/odemath_legacy.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* normalize 3x1 and 4x1 vectors (i.e. scale them to unit length)
*/
/* For DLL export*/
ODE_API int dSafeNormalize3 (dVector3 a);
ODE_API int dSafeNormalize4 (dVector4 a);
ODE_API void dNormalize3 (dVector3 a); /* Potentially asserts on zero vec*/
ODE_API void dNormalize4 (dVector4 a); /* Potentially asserts on zero vec*/
/*
* given a unit length "normal" vector n, generate vectors p and q vectors
* that are an orthonormal basis for the plane space perpendicular to n.
* i.e. this makes p,q such that n,p,q are all perpendicular to each other.
* q will equal n x p. if n is not unit length then p will be unit length but
* q wont be.
*/
ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
/* Makes sure the matrix is a proper rotation, returns a boolean status */
ODE_API int dOrthogonalizeR(dMatrix3 m);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,162 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ODEMATH_LEGACY_H_
#define _ODE_ODEMATH_LEGACY_H_
/*
* These macros are not used any more inside of ODE
* They are kept for backward compatibility with external code that
* might still be using them.
*/
/*
* General purpose vector operations with other vectors or constants.
*/
#define dOP(a,op,b,c) do { \
(a)[0] = ((b)[0]) op ((c)[0]); \
(a)[1] = ((b)[1]) op ((c)[1]); \
(a)[2] = ((b)[2]) op ((c)[2]); \
} while (0)
#define dOPC(a,op,b,c) do { \
(a)[0] = ((b)[0]) op (c); \
(a)[1] = ((b)[1]) op (c); \
(a)[2] = ((b)[2]) op (c); \
} while (0)
#define dOPE(a,op,b) do {\
(a)[0] op ((b)[0]); \
(a)[1] op ((b)[1]); \
(a)[2] op ((b)[2]); \
} while (0)
#define dOPEC(a,op,c) do { \
(a)[0] op (c); \
(a)[1] op (c); \
(a)[2] op (c); \
} while (0)
/* Define an equation with operators
* For example this function can be used to replace
* <PRE>
* for (int i=0; i<3; ++i)
* a[i] += b[i] + c[i];
* </PRE>
*/
#define dOPE2(a,op1,b,op2,c) do { \
(a)[0] op1 ((b)[0]) op2 ((c)[0]); \
(a)[1] op1 ((b)[1]) op2 ((c)[1]); \
(a)[2] op1 ((b)[2]) op2 ((c)[2]); \
} while (0)
#define dLENGTHSQUARED(a) dCalcVectorLengthSquare3(a)
#define dLENGTH(a) dCalcVectorLength3(a)
#define dDISTANCE(a, b) dCalcPointsDistance3(a, b)
#define dDOT(a, b) dCalcVectorDot3(a, b)
#define dDOT13(a, b) dCalcVectorDot3_13(a, b)
#define dDOT31(a, b) dCalcVectorDot3_31(a, b)
#define dDOT33(a, b) dCalcVectorDot3_33(a, b)
#define dDOT14(a, b) dCalcVectorDot3_14(a, b)
#define dDOT41(a, b) dCalcVectorDot3_41(a, b)
#define dDOT44(a, b) dCalcVectorDot3_44(a, b)
/*
* cross product, set a = b x c. dCROSSpqr means that elements of `a', `b'
* and `c' are spaced p, q and r indexes apart respectively.
* dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
* +=, -= etc to get other effects.
*/
#define dCROSS(a,op,b,c) \
do { \
(a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
(a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
(a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \
} while(0)
#define dCROSSpqr(a,op,b,c,p,q,r) \
do { \
(a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \
(a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \
(a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \
} while(0)
#define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4)
#define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1)
#define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4)
#define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1)
#define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4)
#define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1)
#define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4)
/*
* set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
* A is stored by rows, and has `skip' elements per row. the matrix is
* assumed to be already zero, so this does not write zero elements!
* if (plus,minus) is (+,-) then a positive version will be written.
* if (plus,minus) is (-,+) then a negative version will be written.
*/
#define dCROSSMAT(A,a,skip,plus,minus) \
do { \
(A)[1] = minus (a)[2]; \
(A)[2] = plus (a)[1]; \
(A)[(skip)+0] = plus (a)[2]; \
(A)[(skip)+2] = minus (a)[0]; \
(A)[2*(skip)+0] = minus (a)[1]; \
(A)[2*(skip)+1] = plus (a)[0]; \
} while(0)
/*
Note: NEVER call any of these functions/macros with the same variable for A and C,
it is not equivalent to A*=B.
*/
#define dMULTIPLY0_331(A, B, C) dMultiply0_331(A, B, C)
#define dMULTIPLY1_331(A, B, C) dMultiply1_331(A, B, C)
#define dMULTIPLY0_133(A, B, C) dMultiply0_133(A, B, C)
#define dMULTIPLY0_333(A, B, C) dMultiply0_333(A, B, C)
#define dMULTIPLY1_333(A, B, C) dMultiply1_333(A, B, C)
#define dMULTIPLY2_333(A, B, C) dMultiply2_333(A, B, C)
#define dMULTIPLYADD0_331(A, B, C) dMultiplyAdd0_331(A, B, C)
#define dMULTIPLYADD1_331(A, B, C) dMultiplyAdd1_331(A, B, C)
#define dMULTIPLYADD0_133(A, B, C) dMultiplyAdd0_133(A, B, C)
#define dMULTIPLYADD0_333(A, B, C) dMultiplyAdd0_333(A, B, C)
#define dMULTIPLYADD1_333(A, B, C) dMultiplyAdd1_333(A, B, C)
#define dMULTIPLYADD2_333(A, B, C) dMultiplyAdd2_333(A, B, C)
/*
* These macros are not used any more inside of ODE
* They are kept for backward compatibility with external code that
* might still be using them.
*/
#endif /* #ifndef _ODE_ODEMATH_LEGACY_H_ */

@ -0,0 +1,16 @@
#ifndef _ODE_PRECISION_H_
#define _ODE_PRECISION_H_
/* Define dSINGLE for single precision, dDOUBLE for double precision,
* but never both!
*/
#if defined(dIDESINGLE)
#define dSINGLE
#elif defined(dIDEDOUBLE)
#define dDOUBLE
#else
#define dDOUBLE
#endif
#endif

@ -0,0 +1,70 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_ROTATION_H_
#define _ODE_ROTATION_H_
#include <ode/common.h>
#include <ode/compatibility.h>
#ifdef __cplusplus
extern "C" {
#endif
ODE_API void dRSetIdentity (dMatrix3 R);
ODE_API void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
dReal angle);
ODE_API void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi);
ODE_API void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
dReal bx, dReal by, dReal bz);
ODE_API void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az);
ODE_API void dQSetIdentity (dQuaternion q);
ODE_API void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
dReal angle);
/* Quaternion multiplication, analogous to the matrix multiplication routines. */
/* qa = rotate by qc, then qb */
ODE_API void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
/* qa = rotate by qc, then by inverse of qb */
ODE_API void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
/* qa = rotate by inverse of qc, then by qb */
ODE_API void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
/* qa = rotate by inverse of qc, then by inverse of qb */
ODE_API void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
ODE_API void dRfromQ (dMatrix3 R, const dQuaternion q);
ODE_API void dQfromR (dQuaternion q, const dMatrix3 R);
ODE_API void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,412 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* Threading support header file. *
* Copyright (C) 2011-2012 Oleh Derevenko. All rights reserved. *
* e-mail: odar@eleks.com (change all "a" to "e") *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/*
* ODE threading support interfaces
*/
#ifndef _ODE_THREADING_H_
#define _ODE_THREADING_H_
#include <ode/odeconfig.h>
// Include <time.h> since time_t is used and it is not available by default in some OSes
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
struct dxThreadingImplementation;
typedef struct dxThreadingImplementation *dThreadingImplementationID;
typedef unsigned dmutexindex_t;
struct dxMutexGroup;
typedef struct dxMutexGroup *dMutexGroupID;
#define dTHREADING_THREAD_COUNT_UNLIMITED 0U
/**
* @brief Allocates a group of muteces.
*
* The Mutex allocated do not need to support recursive locking.
*
* The Mutex names are provided to aid in debugging and thread state tracking.
*
* @param impl Threading implementation ID
* @param Mutex_count Number of Mutex to create
* @Mutex_names_ptr Pointer to optional Mutex names array to be associated with individual Mutex
* @returns MutexGroup ID or NULL if error occurred.
*
* @ingroup threading
* @see dMutexGroupFreeFunction
* @see dMutexGroupMutexLockFunction
* @see dMutexGroupMutexUnlockFunction
*/
typedef dMutexGroupID dMutexGroupAllocFunction (dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/);
/**
* @brief Deletes a group of muteces.
*
* @param impl Threading implementation ID
* @param mutex_group Mutex group to deallocate
*
* @ingroup threading
* @see dMutexGroupAllocFunction
* @see dMutexGroupMutexLockFunction
* @see dMutexGroupMutexUnlockFunction
*/
typedef void dMutexGroupFreeFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group);
/**
* @brief Locks a mutex in a group of muteces.
*
* The function is to block execution until requested mutex can be locked.
*
* Note: Mutex provided may not support recursive locking. Calling this function
* while mutex is already locked by current thread will result in unpredictable behavior.
*
* @param impl Threading implementation ID
* @param mutex_group Mutex group to use for locking
* @param mutex_index The index of mutex to be locked (0..Mutex_count - 1)
*
* @ingroup threading
* @see dMutexGroupAllocFunction
* @see dMutexGroupFreeFunction
* @see dMutexGroupMutexUnlockFunction
*/
typedef void dMutexGroupMutexLockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
/**
* @brief Attempts to lock a mutex in a group of muteces.
*
* The function is to lock the requested mutex if it is unoccupied or
* immediately return failure if mutex is already locked by other thread.
*
* Note: Mutex provided may not support recursive locking. Calling this function
* while mutex is already locked by current thread will result in unpredictable behavior.
*
* @param impl Threading implementation ID
* @param mutex_group Mutex group to use for locking
* @param mutex_index The index of mutex to be locked (0..Mutex_count - 1)
* @returns 1 for success (mutex is locked) and 0 for failure (mutex is not locked)
*
* @ingroup threading
* @see dMutexGroupAllocFunction
* @see dMutexGroupFreeFunction
* @see dMutexGroupMutexLockFunction
* @see dMutexGroupMutexUnlockFunction
*/
/* typedef int dMutexGroupMutexTryLockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);*/
/**
* @brief Unlocks a mutex in a group of muteces.
*
* The function is to unlock the given mutex provided it had been locked before.
*
* @param impl Threading implementation ID
* @param mutex_group Mutex group to use for unlocking
* @param mutex_index The index of mutex to be unlocked (0..Mutex_count - 1)
*
* @ingroup threading
* @see dMutexGroupAllocFunction
* @see dMutexGroupFreeFunction
* @see dMutexGroupMutexLockFunction
*/
typedef void dMutexGroupMutexUnlockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
struct dxCallReleasee;
typedef struct dxCallReleasee *dCallReleaseeID;
struct dxCallWait;
typedef struct dxCallWait *dCallWaitID;
typedef dsizeint ddependencycount_t;
typedef ddiffint ddependencychange_t;
typedef dsizeint dcallindex_t;
typedef int dThreadedCallFunction(void *call_context, dcallindex_t instance_index,
dCallReleaseeID this_releasee);
typedef struct dxThreadedWaitTime
{
time_t wait_sec;
unsigned long wait_nsec;
} dThreadedWaitTime;
/**
* @brief Allocates a Wait ID that can be used to wait for a call.
*
* @param impl Threading implementation ID
* @returns Wait ID or NULL if error occurred
*
* @ingroup threading
* @see dThreadedCallWaitResetFunction
* @see dThreadedCallWaitFreeFunction
* @see dThreadedCallPostFunction
* @see dThreadedCallWaitFunction
*/
typedef dCallWaitID dThreadedCallWaitAllocFunction(dThreadingImplementationID impl);
/**
* @brief Resets a Wait ID so that it could be used to wait for another call.
*
* @param impl Threading implementation ID
* @param call_wait Wait ID to reset
*
* @ingroup threading
* @see dThreadedCallWaitAllocFunction
* @see dThreadedCallWaitFreeFunction
* @see dThreadedCallPostFunction
* @see dThreadedCallWaitFunction
*/
typedef void dThreadedCallWaitResetFunction(dThreadingImplementationID impl, dCallWaitID call_wait);
/**
* @brief Frees a Wait ID.
*
* @param impl Threading implementation ID
* @param call_wait Wait ID to delete
*
* @ingroup threading
* @see dThreadedCallWaitAllocFunction
* @see dThreadedCallPostFunction
* @see dThreadedCallWaitFunction
*/
typedef void dThreadedCallWaitFreeFunction(dThreadingImplementationID impl, dCallWaitID call_wait);
/**
* @brief Post a function to be called in another thread.
*
* A call is scheduled to be executed asynchronously.
*
* A @a out_summary_fault variable can be provided for call to accumulate any
* possible faults from its execution and execution of any possible sub-calls.
* This variable gets result that @a call_func returns. Also, if dependent calls
* are executed after the call already exits, the variable is also going to be
* updated with results of all those calls before control is released to master.
*
* @a out_post_releasee parameter receives a value of @c dCallReleaseeID that can
* later be used for @a dependent_releasee while scheduling sub-calls to make
* current call depend on them. The value is only returned if @a dependencies_count
* is not zero (i.e. if any dependencies are expected at all). The call is not going
* to start until all its dependencies complete.
*
* In case if number of dependencies is unknown in advance 1 can be passed on call
* scheduling. Then @c dThreadedCallDependenciesCountAlterFunction can be used to
* add one more extra dependencies before scheduling each subcall. And then, after
* all sub-calls had been scheduled, @c dThreadedCallDependenciesCountAlterFunction
* can be used again to subtract initial extra dependency from total number.
* Adding one dependency in advance is necessary to obtain releasee ID and to make
* sure the call will not start and will not terminate before all sub-calls are scheduled.
*
* Extra dependencies can also be added from the call itself after it has already
* been started (with parameter received in @c dThreadedCallFunction).
* In that case those dependencies will start immediately or after call returns
* but the call's master will not be released/notified until all additional
* dependencies complete. This can be used to schedule sub-calls from a call and
* then pass own job to another sub-call dependent on those initial sub-calls.
*
* By using @ call_wait it is possible to assign a Wait ID that can later
* be passed into @c dThreadedCallWaitFunction to wait for call completion.
*
* If @a call_name is available (and it should!) the string must remain valid until
* after call completion. In most cases this should be a static string literal.
*
* Since the function is an analogue of normal method call it is not supposed to fail.
* Any complications with resource allocation on call scheduling should be
* anticipated, avoided and worked around by implementation.
*
* @param impl Threading implementation ID
* @param out_summary_fault Optional pointer to variable to be set to 1 if function
* call (or any sub-call) fails internally, or 0 if all calls return success
* @param out_post_releasee Optional pointer to variable to receive releasee ID
* associated with the call
* @param dependencies_count Number of dependencies that are going to reference
* this call as dependent releasee
* @param dependent_releasee Optional releasee ID to reference with this call
* @param call_wait Optional Wait ID that can later be used to wait for the call
* @param call_func Pointer to function to be called
* @param call_context Context parameter to be passed into the call
* @param instance_index Index parameter to be passed into the call
* @param call_name Optional name to be associated with the call (for debugging and state tracking)
*
* @ingroup threading
* @see dThreadedCallWaitFunction
* @see dThreadedCallDependenciesCountAlterFunction
* @see dThreadingImplResourcesForCallsPreallocateFunction
*/
typedef void dThreadedCallPostFunction(dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
dCallWaitID call_wait/*=NULL*/,
dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
const char *call_name/*=NULL*/);
/**
* @brief Add or remove extra dependencies from call that has been scheduled
* or is in process of execution.
*
* Extra dependencies can be added to a call if exact number of sub-calls is
* not known in advance at the moment the call is scheduled. Also, some dependencies
* can be removed if sub-calls were planned but then dropped.
*
* In case if total dependency count of a call reaches zero by result of invoking
* this function, the call is free to start executing immediately.
*
* After the call execution had been started, any additional dependencies can only
* be added from the call function itself!
*
* @param impl Threading implementation ID
* @param target_releasee ID of releasee to apply dependencies count change to
* @param dependencies_count_change Number of dependencies to add or remove
*
* @ingroup threading
* @see dThreadedCallPostFunction
*/
typedef void dThreadedCallDependenciesCountAlterFunction(dThreadingImplementationID impl, dCallReleaseeID target_releasee,
ddependencychange_t dependencies_count_change);
/**
* @brief Wait for a posted call to complete.
*
* Function blocks until a call identified by @a call_wait completes or
* timeout elapses.
*
* IT IS ILLEGAL TO INVOKE THIS FUNCTION FROM WITHIN A THREADED CALL!
* This is because doing so will block a physical thread and will require
* increasing worker thread count to avoid starvation. Use call dependencies
* if it is necessary make sure sub-calls have been completed instead!
*
* If @a timeout_time_ptr is NULL, the function waits without time limit. If @a timeout_time_ptr
* points to zero value, the function only checks status and does not block.
*
* If @a wait_name is available (and it should!) the string must remain valid for
* the duration of wait. In most cases this should be a static string literal.
*
* Function is not expected to return failures caused by system call faults as
* those are hardly ever possible to be handled in this case anyway. In event of
* system call fault the function is supposed to terminate application.
*
* @param impl Threading implementation ID
* @param out_wait_status Optional pointer to variable to receive 1 if waiting succeeded
* or 0 in case of timeout
* @param call_wait Wait ID that had been passed to scheduling a call that needs to be waited for
* @param timeout_time_ptr Optional pointer to time specification the wait must not
* last longer than (pass NULL for infinite timeout)
* @param wait_name Optional name to be associated with the wait (for debugging and state tracking)
*
* @ingroup threading
* @see dThreadedCallPostFunction
*/
typedef void dThreadedCallWaitFunction(dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
const char *wait_name/*=NULL*/);
/**
* @brief Retrieve number of active threads that serve the implementation.
*
* @param impl Threading implementation ID
* @returns Number of active threads
*
* @ingroup threading
*/
typedef unsigned dThreadingImplThreadCountRetrieveFunction(dThreadingImplementationID impl);
/**
* @brief Preallocate resources to handle posted calls.
*
* The function is intended to make sure enough resources is preallocated for the
* implementation to be able to handle posted calls. Then @c max_simultaneous_calls_estimate
* is an estimate of how many posted calls can potentially be active or scheduled
* at the same time. The value is usually derived from the way the calls are posted
* in library code and dependencies between them.
*
* @warning While working on an implementation be prepared that the estimate provided
* yet rarely but theoretically can be exceeded due to unpredictability of thread execution.
*
* This function is normally going to be invoked by library each time it is entered
* from outside to do the job but before any threaded calls are going to be posted.
*
* @param impl Threading implementation ID
* @param max_simultaneous_calls_estimate An estimated number of calls that can be posted simultaneously
* @returns 1 or 0 to indicate success or failure
*
* @ingroup threading
* @see dThreadedCallPostFunction
*/
typedef int dThreadingImplResourcesForCallsPreallocateFunction(dThreadingImplementationID impl,
ddependencycount_t max_simultaneous_calls_estimate);
/**
* @brief An interface structure with function pointers to be provided by threading implementation.
*/
typedef struct dxThreadingFunctionsInfo
{
unsigned struct_size;
dMutexGroupAllocFunction *alloc_mutex_group;
dMutexGroupFreeFunction *free_mutex_group;
dMutexGroupMutexLockFunction *lock_group_mutex;
dMutexGroupMutexUnlockFunction *unlock_group_mutex;
dThreadedCallWaitAllocFunction *alloc_call_wait;
dThreadedCallWaitResetFunction *reset_call_wait;
dThreadedCallWaitFreeFunction *free_call_wait;
dThreadedCallPostFunction *post_call;
dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count;
dThreadedCallWaitFunction *wait_call;
dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count;
dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls;
/*
* Beware of Jon Watte's anger if you dare to uncomment this!
* May cryptic text below be you a warning!
* Стародавні легенди розказують, що кожного сміливця, хто наважиться порушити табу
* і відкрити заборонений код, спіткає страшне прокляття і він відразу почне робити
* одні лиш помилки.
*
* dMutexGroupMutexTryLockFunction *trylock_group_mutex;
*/
} dThreadingFunctionsInfo;
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _ODE_THREADING_H_ */

@ -0,0 +1,292 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* Builtin ODE threading implementation header. *
* Copyright (C) 2011-2012 Oleh Derevenko. All rights reserved. *
* e-mail: odar@eleks.com (change all "a" to "e") *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
/*
* A threading implementation built into ODE for those who does not care to
* or can't implement an own one.
*/
#ifndef _ODE_THREADING_IMPL_H_
#define _ODE_THREADING_IMPL_H_
#include <ode/odeconfig.h>
#include <ode/threading.h>
#ifdef __cplusplus
extern "C" {
#endif
struct dxThreadingThreadPool;
typedef struct dxThreadingThreadPool *dThreadingThreadPoolID;
/**
* @brief Allocates built-in self-threaded threading implementation object.
*
* A self-threaded implementation is a type of implementation that performs
* processing of posted calls by means of caller thread itself. This type of
* implementation does not need thread pool to serve it.
*
* Note that since May 9th, 2017 (rev. #2066) the Self-Threaded implementation
* returns 0 rather than 1 as available thread count to distinguish from
* thread pools with just one thread in them.
*
* The processing is arranged in a way to prevent call stack depth growth
* as more and more nested calls are posted.
*
* Note that it is not necessary to create and assign a self-threaded
* implementation to a world, as there is a global one used by default
* if no implementation is explicitly assigned. You should only assign
* each world an individual threading implementation instance if simulations
* need to be run in parallel in multiple threads for the worlds.
*
* @returns ID of object allocated or NULL on failure
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingFreeImplementation
*/
ODE_API dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation();
/**
* @brief Allocates built-in multi-threaded threading implementation object.
*
* A multi-threaded implementation is a type of implementation that has to be
* served with a thread pool. The thread pool can be either the built-in ODE object
* or set of external threads that dedicate themselves to this purpose and stay
* in ODE until implementation releases them.
*
* @returns ID of object allocated or NULL on failure
*
* @ingroup threading
* @see dThreadingThreadPoolServeMultiThreadedImplementation
* @see dExternalThreadingServeMultiThreadedImplementation
* @see dThreadingFreeImplementation
*/
ODE_API dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation();
/**
* @brief Retrieves the functions record of a built-in threading implementation.
*
* The implementation can be the one allocated by ODE (from @c dThreadingAllocateMultiThreadedImplementation).
* Do not use this function with self-made custom implementations -
* they should be bundled with their own set of functions.
*
* @param impl Threading implementation ID
* @returns Pointer to associated functions structure
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
*/
ODE_API const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl);
/**
* @brief Requests a built-in implementation to release threads serving it.
*
* The function unblocks threads employed in implementation serving and lets them
* return to from where they originate. It's the responsibility of external code
* to make sure all the calls to ODE that might be dependent on given threading
* implementation object had already returned before this call is made. If threading
* implementation is still processing some posted calls while this function is
* invoked the behavior is implementation dependent.
*
* This call is to be used to request the threads to be released before waiting
* for them in host pool or before waiting for them to exit. Implementation object
* must not be destroyed before it is known that all the serving threads have already
* returned from it. If implementation needs to be reused after this function is called
* and all the threads have exited from it a call to @c dThreadingImplementationCleanupForRestart
* must be made to restore internal state of the object.
*
* If this function is called for self-threaded built-in threading implementation
* the call has no effect.
*
* @param impl Threading implementation ID
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationCleanupForRestart
*/
ODE_API void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl);
/**
* @brief Restores built-in implementation's state to let it be reused after shutdown.
*
* If a multi-threaded built-in implementation needs to be reused after a call
* to @c dThreadingImplementationShutdownProcessing this call is to be made to
* restore object's internal state. After that the implementation can be served again.
*
* If this function is called for self-threaded built-in threading implementation
* the call has no effect.
*
* @param impl Threading implementation ID
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationShutdownProcessing
*/
ODE_API void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl);
/**
* @brief Deletes an instance of built-in threading implementation.
*
* @warning A care must be taken to make sure the implementation is unassigned
* from all the objects it was assigned to and that there are no more threads
* serving it before attempting to call this function.
*
* @param impl Threading implementation ID
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
*/
ODE_API void dThreadingFreeImplementation(dThreadingImplementationID impl);
typedef void (dThreadReadyToServeCallback)(void *callback_context);
/**
* @brief An entry point for external threads that would like to serve a built-in
* threading implementation object.
*
* A thread that calls this function remains blocked in ODE and serves implementation
* object @p impl until being released with @c dThreadingImplementationShutdownProcessing call.
* This function can be used to provide external threads instead of ODE's built-in
* thread pools.
*
* The optional callback @readiness_callback is called after the thread has reached
* and has registered within the implementation. The implementation should not
* be used until all dedicated threads register within it as otherwise it will not
* have accurate view of the execution resources available.
*
* @param impl Threading implementation ID
* @param readiness_callback Optional readiness callback to be called after thread enters the implementation
* @param callback_context A value to be passed as parameter to readiness callback
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationShutdownProcessing
*/
ODE_API void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl,
dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/);
/**
* @brief Creates an instance of built-in thread pool object that can be used to serve
* multi-threaded threading implementations.
*
* The threads allocated inherit priority of caller thread. Their affinity is not
* explicitly adjusted and gets the value the system assigns by default. Threads
* have their stack memory fully committed immediately on start. On POSIX platforms
* threads are started with all the possible signals blocked. Threads execute
* calls to @c dAllocateODEDataForThread with @p ode_data_allocate_flags
* on initialization.
*
* On POSIX platforms this function must be called with signals masked
* or other measures must be taken to prevent reception of signals by calling thread
* for the duration of the call.
*
* @param thread_count Number of threads to start in pool
* @param stack_size Size of stack to be used for every thread or 0 for system default value
* @param ode_data_allocate_flags Flags to be passed to @c dAllocateODEDataForThread on behalf of each thread
* @returns ID of object allocated or NULL on failure
*
* @ingroup threading
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationShutdownProcessing
* @see dThreadingFreeThreadPool
*/
ODE_API dThreadingThreadPoolID dThreadingAllocateThreadPool(unsigned thread_count,
dsizeint stack_size, unsigned int ode_data_allocate_flags, void *reserved/*=NULL*/);
/**
* @brief Commands an instance of built-in thread pool to serve a built-in multi-threaded
* threading implementation.
*
* A pool can only serve one threading implementation at a time.
* Call @c dThreadingImplementationShutdownProcessing to release pool threads
* from implementation serving and make them idle. Pool threads must be released
* from any implementations before pool is attempted to be deleted.
*
* This function waits for threads to register within implementation before returning.
* So, after the function call exits the implementation can be used immediately.
*
* @param pool Thread pool ID to serve the implementation
* @param impl Implementation ID of implementation to be served
*
* @ingroup threading
* @see dThreadingAllocateThreadPool
* @see dThreadingAllocateMultiThreadedImplementation
* @see dThreadingImplementationShutdownProcessing
*/
ODE_API void dThreadingThreadPoolServeMultiThreadedImplementation(dThreadingThreadPoolID pool, dThreadingImplementationID impl);
/**
* @brief Waits until all pool threads are released from threading implementation
* they might be serving.
*
* The function can be used after a call to @c dThreadingImplementationShutdownProcessing
* to make sure all the threads have already been released by threading implementation
* and it can be deleted or it can be cleaned up for restart and served by another pool
* or this pool's threads can be used to serve another threading implementation.
*
* Note that is it not necessary to call this function before pool destruction
* since @c dThreadingFreeThreadPool performs similar wait operation implicitly on its own.
*
* It is OK to call this function even if pool was not serving any threading implementation
* in which case the call exits immediately with minimal delay.
*
* @param pool Thread pool ID to wait for
*
* @ingroup threading
* @see dThreadingAllocateThreadPool
* @see dThreadingImplementationShutdownProcessing
* @see dThreadingFreeThreadPool
*/
ODE_API void dThreadingThreadPoolWaitIdleState(dThreadingThreadPoolID pool);
/**
* @brief Deletes a built-in thread pool instance.
*
* The pool threads must be released from any implementations they might be serving
* before this function is called. Otherwise the call is going to block
* and wait until pool's threads return.
*
* @param pool Thread pool ID to delete
*
* @ingroup threading
* @see dThreadingAllocateThreadPool
* @see dThreadingImplementationShutdownProcessing
*/
ODE_API void dThreadingFreeThreadPool(dThreadingThreadPoolID pool);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _ODE_THREADING_IMPL_H_ */

@ -0,0 +1,76 @@
/*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************/
#ifndef _ODE_TIMER_H_
#define _ODE_TIMER_H_
#include <ode/odeconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
/* stop watch objects */
typedef struct dStopwatch {
double time; /* total clock count */
unsigned long cc[2]; /* clock count since last `start' */
} dStopwatch;
ODE_API void dStopwatchReset (dStopwatch *);
ODE_API void dStopwatchStart (dStopwatch *);
ODE_API void dStopwatchStop (dStopwatch *);
ODE_API double dStopwatchTime (dStopwatch *); /* returns total time in secs */
/* code timers */
ODE_API void dTimerStart (const char *description); /* pass a static string here */
ODE_API void dTimerNow (const char *description); /* pass a static string here */
ODE_API void dTimerEnd(void);
/* print out a timer report. if `average' is nonzero, print out the average
* time for each slot (this is only meaningful if the same start-now-end
* calls are being made repeatedly.
*/
ODE_API void dTimerReport (FILE *fout, int average);
/* resolution */
/* returns the timer ticks per second implied by the timing hardware or API.
* the actual timer resolution may not be this great.
*/
ODE_API double dTimerTicksPerSecond(void);
/* returns an estimate of the actual timer resolution, in seconds. this may
* be greater than 1/ticks_per_second.
*/
ODE_API double dTimerResolution(void);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,6 @@
#ifndef _ODE_VERSION_H_
#define _ODE_VERSION_H_
#define dODE_VERSION "0.15.2"
#endif

Binary file not shown.

@ -1 +1 @@
libSDL2-2.0.so.0.7.0
libSDL2.so

@ -1 +0,0 @@
libSDL2-2.0.so.0.7.0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -17,6 +17,10 @@ struct Window;
struct Hashmap;
struct Sound_Source_Buffer;
//Physics Decls
typedef void* Rigidbody;
typedef void (*RigidbodyMoveCB)(Rigidbody);
// Function Pointer decls
typedef void (*Keyboard_Event_Func) (int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt);
typedef void (*Mousebutton_Event_Func) (int button, int state, int x, int y, int8 num_clicks);
@ -49,8 +53,19 @@ enum Sound_Attenuation_Type
struct Physics_Api
{
void(*init)(void);
void(*cleanup)(void);
void (*init)(void);
void (*cleanup)(void);
void (*step)(float);
void (*gravity_set)(float x, float y, float z);
void (*gravity_get)(float* x, float* y, float* z);
void (*body_position_set)(Rigidbody body, float x, float y, float z);
void (*body_position_get)(Rigidbody body, float* x, float* y, float* z);
void (*body_rotation_set)(Rigidbody body, float x, float y, float z, float w);
void (*body_rotation_get)(Rigidbody body, float* x, float* y, float* z, float* w);
Rigidbody (*plane_create)(float a, float b, float c, float d);
Rigidbody (*box_create)(float length, float width, float height);
void (*body_set_moved_callback)(Rigidbody body, RigidbodyMoveCB callback);
void (*body_kinematic_set)(Rigidbody body);
};
struct Sound_Api

@ -122,8 +122,19 @@ int main(int argc, char** args)
},
.physics =
{
.init = &physics_init,
.cleanup = &physics_cleanup
.init = &physics_init,
.cleanup = &physics_cleanup,
.step = &physics_step,
.gravity_set = &physics_gravity_set,
.gravity_get = &physics_gravity_get,
.body_position_set = &physics_body_position_set,
.body_position_get = &physics_body_position_get,
.body_rotation_set = &physics_body_rotation_set,
.body_rotation_get = &physics_body_rotation_get,
.body_kinematic_set = &physics_body_kinematic_set,
.body_set_moved_callback = &physics_body_set_moved_callback,
.plane_create = &physics_plane_create,
.box_create = &physics_box_create
}
};

@ -1,27 +1,191 @@
#include "physics.h"
#include "../common/log.h"
#include <Newton.h>
#include <ode/ode.h>
#include <assert.h>
static NewtonWorld* newton_world = 0;
static struct
{
dWorldID world;
dSpaceID space;
dJointGroupID contact_group;
double step_size;
}
Physics;
static void physics_near_callback(void* data, dGeomID body1, dGeomID body2);
void physics_init(void)
{
newton_world = NewtonCreate();
if(!newton_world)
if(dInitODE2(0) == 0)
{
log_error("physics:init", "Failed to initialize ode");
return;
}
dAllocateODEDataForThread(dAllocateMaskAll);
Physics.world = dWorldCreate();
if(!Physics.world)
{
log_error("physics:init", "Physics world created!");
}
else
{
log_message("Physics world created");
Physics.space = dHashSpaceCreate(0);
Physics.contact_group = dJointGroupCreate(0);
Physics.step_size = 0.16;
}
}
void physics_cleanup(void)
{
if(newton_world)
dJointGroupDestroy(Physics.contact_group);
dSpaceDestroy(Physics.space);
if(Physics.world)
{
dWorldDestroy(Physics.world);
}
dCleanupODEAllDataForThread();
dCloseODE();
}
void physics_step(float delta_time)
{
int steps = (int)ceilf(delta_time / Physics.step_size);
for(int i = 0; i < steps; i++)
{
dSpaceCollide(Physics.space, NULL, physics_near_callback);
dWorldQuickStep(Physics.world, Physics.step_size);
dJointGroupEmpty(Physics.contact_group);
}
}
void physics_gravity_set(float x, float y, float z)
{
dWorldSetGravity(Physics.world, x, y, z);
}
void physics_gravity_get(float * x, float * y, float * z)
{
assert(x && y && z);
dVector3 gravity;
dWorldGetGravity(Physics.world, gravity);
*x = gravity[0];
*y = gravity[1];
*z = gravity[2];
}
void physics_body_position_get(Rigidbody body, float * x, float * y, float * z)
{
assert(x && y && z);
const dReal* position = dBodyGetPosition(body);
*x = position[0];
*y = position[1];
*z = position[2];
}
void physics_body_position_set(Rigidbody body, float x, float y, float z)
{
dBodySetPosition(body, x, y, z);
}
void physics_body_rotation_get(Rigidbody body, float * x, float * y, float * z, float * w)
{
assert(x && y && z && w);
const dReal* rotation = dBodyGetQuaternion(body);
*x = rotation[1];
*y = rotation[2];
*z = rotation[3];
*w = rotation[0];
}
void physics_body_rotation_set(Rigidbody body, float x, float y, float z, float w)
{
dReal rotation[4] = { 0 };
rotation[1] = x;
rotation[2] = y;
rotation[3] = z;
rotation[0] = w;
dBodySetQuaternion(body, &rotation[0]);
}
void physics_near_callback(void* data, dGeomID o1, dGeomID o2)
{
assert(o1);
assert(o2);
if(dGeomIsSpace(o1) || dGeomIsSpace(o2))
{
NewtonDestroy(newton_world);
fprintf(stderr, "testing space %p %p\n", (void*)o1, (void*)o2);
// colliding a space with something
dSpaceCollide2(o1, o2, data, &physics_near_callback);
// Note we do not want to test intersections within a space,
// only between spaces.
return;
}
// fprintf(stderr,"testing geoms %p %p\n", o1, o2);
const int N = 32;
dContact contact[32];
int n = dCollide(o1, o2, N, &(contact[0].geom), sizeof(dContact));
if(n > 0)
{
for(int i = 0; i<n; i++)
{
// Paranoia <-- not working for some people, temporarily removed for 0.6
//dIASSERT(dVALIDVEC3(contact[i].geom.pos));
//dIASSERT(dVALIDVEC3(contact[i].geom.normal));
//dIASSERT(!dIsNan(contact[i].geom.depth));
contact[i].surface.slip1 = 0.7;
contact[i].surface.slip2 = 0.7;
contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactSlip1 | dContactSlip2;
contact[i].surface.mu = 50.0; // was: dInfinity
contact[i].surface.soft_erp = 0.96;
contact[i].surface.soft_cfm = 0.04;
dJointID c = dJointCreateContact(Physics.world, Physics.contact_group, &contact[i]);
dJointAttach(c,
dGeomGetBody(contact[i].geom.g1),
dGeomGetBody(contact[i].geom.g2));
}
}
}
Rigidbody physics_plane_create(float a, float b, float c, float d)
{
dGeomID plane = dCreatePlane(Physics.space, a, b, c, d);
/*dBodyID body = dBodyCreate(Physics.world);
dGeomSetBody(plane, body);*/
return plane;
}
Rigidbody physics_box_create(float length, float width, float height)
{
dGeomID box = dCreateBox(Physics.space, length, height, width);
dBodyID body = dBodyCreate(Physics.world);
dGeomSetBody(box, body);
return body;
}
void physics_body_set_moved_callback(Rigidbody body, RigidbodyMoveCB callback)
{
dBodySetMovedCallback(body, callback);
}
float physics_body_mass_get(Rigidbody body)
{
return 0.0f;
}
void physics_body_mass_set(Rigidbody body, float mass)
{
}
void physics_body_kinematic_set(Rigidbody body)
{
dBodySetKinematic(body);
}

@ -1,7 +1,28 @@
#ifndef PHYSICS_H
#define PHYSICS_H
#include "../common/common.h"
void physics_init(void);
void physics_cleanup(void);
void physics_gravity_set(float x, float y, float z);
void physics_gravity_get(float* x, float* y, float* z);
void physics_step(float delta_time);
void physics_body_position_get(Rigidbody body, float* x, float* y, float* z);
void physics_body_position_set(Rigidbody body, float x, float y, float z);
void physics_body_rotation_get(Rigidbody body, float* x, float* y, float* z, float* w);
void physics_body_rotation_set(Rigidbody body, float x, float y, float z, float w);
Rigidbody physics_plane_create(float a, float b, float c, float d);
Rigidbody physics_box_create(float length, float width, float height);
void physics_body_set_moved_callback(Rigidbody body, RigidbodyMoveCB callback);
float physics_body_mass_get(Rigidbody body);
void physics_body_mass_set(Rigidbody body, float mass);
void physics_body_kinematic_set(Rigidbody body);
#endif

@ -47,10 +47,14 @@ static void render(void);
static void debug(float dt);
static void debug_gui(float dt);
static void scene_setup(void);
static void on_box_move(Rigidbody body);
static struct Game_State* game_state = NULL;
struct Platform_Api* platform = NULL;
static int suz_id = 0;
bool game_init(struct Window* window, struct Platform_Api* platform_api)
{
if(!platform_api)
@ -98,6 +102,7 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api)
material_init();
entity_init();
platform->physics.init();
platform->physics.gravity_set(0.f, -9.8f, 0.f);
scene_init();
/* Debug scene setup */
@ -235,12 +240,23 @@ void scene_setup(void)
struct Entity* player = entity_find("player");
game_state->player_node = player->id;
struct Entity* suz = entity_find("Suzanne");
suz_id = suz->id;
/*struct Camera* camera = &player->camera;
camera->ortho = true;
camera->farz = 500.f;
camera->nearz = -500.f;
camera_update_proj(player);*/
}
platform->physics.plane_create(0, 1, 0, 0);
Rigidbody box = platform->physics.box_create(5, 5, 5);
platform->physics.body_position_set(box, 0.f, 50.f, 0.f);
platform->physics.body_set_moved_callback(box, on_box_move);
/*Rigidbody ground_box = platform->physics.box_create(1000, 5, 1000);
platform->physics.body_position_set(ground_box, 0.f, 0.f, 0.f);
platform->physics.body_kinematic_set(ground_box);*/
}
void debug(float dt)
@ -363,11 +379,11 @@ void debug(float dt)
transform_translate(model, &amount, TS_LOCAL);
}
struct Entity* model = scene_find("Model_Entity");
/*struct Entity* model = scene_find("Model_Entity");
vec3 x_axis = {0, 1, 0};
transform_rotate(model, &x_axis, 25.f * dt, TS_WORLD);
vec3 amount = {0, 0, -5 * dt};
transform_translate(model, &amount, TS_LOCAL);
transform_translate(model, &amount, TS_LOCAL);*/
struct Sprite_Batch* batch = get_batch();
@ -416,6 +432,7 @@ bool run(void)
gui_input_end();
update(delta_time, &should_window_close);
platform->physics.step(delta_time);
render();
platform->window.swap_buffers(game_state->window);
entity_post_update();
@ -1687,3 +1704,18 @@ struct Game_State* game_state_get(void)
{
return game_state;
}
void on_box_move(Rigidbody body)
{
struct Entity* suz = entity_get(suz_id);
vec3 pos = {0};
quat rot = {0};
platform->physics.body_position_get(body, &pos.x, &pos.y, &pos.z);
platform->physics.body_rotation_get(body, &rot.x, &rot.y, &rot.z, &rot.w);
quat_assign(&suz->transform.rotation, &rot);
transform_set_position(suz, &pos);
log_message("Pos : %.3f, %.3f, %.3f", pos.x, pos.y, pos.z);
}
Loading…
Cancel
Save