1 module world;
2 
3 import core.runtime;
4 import core.memory;
5 import dlib.core.memory;
6 import dlib.container.bst;
7 import dlib.math.vector;
8 import dmech.world;
9 import dmech.rigidbody;
10 import dmech.geometry;
11 import dmech.shape;
12 import dmech.constraint;
13 import dmech.raycast;
14 
15 int numWorlds = 0;
16 
17 extern(C):
18 
19 export void dmInit()
20 {
21     version(linux) Runtime.initialize();
22     GC.disable();
23 }
24 
25 export void* dmCreateWorld(uint maxCollisions)
26 {
27     PhysicsWorld world = New!PhysicsWorld(maxCollisions);
28     numWorlds++;
29     return cast(void*)world;
30 }
31 
32 export void dmDeleteWorld(void* pWorld)
33 {
34     PhysicsWorld world = cast(PhysicsWorld)pWorld;        
35     if (world)
36     {
37         Delete(world);
38         numWorlds--;
39     }
40 }
41 
42 export int dmGetNumWorlds()
43 {
44     return numWorlds;
45 }
46 
47 export void* dmWorldAddStaticBody(void* pWorld, float px, float py, float pz)
48 {
49     PhysicsWorld world = cast(PhysicsWorld)pWorld;        
50     if (world)
51     {
52         RigidBody rb = world.addStaticBody(Vector3f(px, py, pz));
53         return cast(void*)rb;
54     }
55     else
56         return null;
57 }
58 
59 export void* dmWorldAddDynamicBody(void* pWorld, float px, float py, float pz, float mass)
60 {
61     PhysicsWorld world = cast(PhysicsWorld)pWorld;        
62     if (world)
63     {
64         RigidBody rb = world.addDynamicBody(Vector3f(px, py, pz), mass);
65         return cast(void*)rb;
66     }
67     else
68         return null;
69 }
70 
71 export int dmWorldGetNumStaticBodies(void* pWorld)
72 {
73     PhysicsWorld world = cast(PhysicsWorld)pWorld;
74     if (world)
75         return world.staticBodies.length;
76     else
77         return 0;
78 }
79 
80 export int dmWorldGetNumDynamicBodies(void* pWorld)
81 {
82     PhysicsWorld world = cast(PhysicsWorld)pWorld;
83     if (world)
84         return world.dynamicBodies.length;
85     else
86         return 0;
87 }
88 
89 export void* dmWorldAddCollisionShape(void* pWorld, void* pBody, void* pGeom, float px, float py, float pz, float mass)
90 {
91     PhysicsWorld world = cast(PhysicsWorld)pWorld;
92     RigidBody rb = cast(RigidBody)pBody;
93     Geometry geom = cast(Geometry)pGeom;
94     if (world && rb && geom)
95     {
96         ShapeComponent sc = world.addShapeComponent(rb, geom, Vector3f(px, py, pz), mass);
97         return cast(void*)sc;
98     }
99     else
100         return null;
101 }
102 
103 export int dmWorldGetNumCollisionShapes(void* pWorld)
104 {
105     PhysicsWorld world = cast(PhysicsWorld)pWorld;
106     if (world)
107         return world.shapeComponents.length;
108     else
109         return 0;
110 }
111 
112 export void* dmWorldAddConstraint(void* pWorld, void* pConstraint)
113 {
114     PhysicsWorld world = cast(PhysicsWorld)pWorld;
115     Constraint c = cast(Constraint)pConstraint;
116     if (world && c)
117     {
118         world.addConstraint(c);
119         return pConstraint;
120     }
121     else
122         return null;
123 }
124 
125 export int dmWorldGetNumConstraints(void* pWorld)
126 {
127     PhysicsWorld world = cast(PhysicsWorld)pWorld;
128     if (world)
129         return world.constraints.length;
130     else
131         return 0;
132 }
133 
134 export void* dmWorldSetStaticMesh(void* pMesh)
135 {
136     // TODO
137     return null;
138 }
139 
140 export void dmWorldSetGravity(void* pWorld, float x, float y, float z)
141 {
142     PhysicsWorld world = cast(PhysicsWorld)pWorld;        
143     if (world)
144     {
145         world.gravity = Vector3f(x, y, z);
146     }
147 }
148 
149 export void dmWorldSetSolverIterations(void* pWorld, uint posCorrIter, uint velCorrIter)
150 {
151     PhysicsWorld world = cast(PhysicsWorld)pWorld;        
152     if (world)
153     {
154         world.positionCorrectionIterations = posCorrIter;
155         world.constraintIterations = velCorrIter;
156     }
157 }
158 
159 export void dmWorldSetBroadphase(void* pWorld, int b)
160 {
161     PhysicsWorld world = cast(PhysicsWorld)pWorld;        
162     if (world)
163     {
164         world.broadphase = cast(bool)b;
165     }
166 }
167 
168 export void dmWorldUpdate(void* pWorld, double dt)
169 {
170     PhysicsWorld world = cast(PhysicsWorld)pWorld;        
171     if (world)
172     {
173         world.update(dt);
174     }
175 }
176 
177 struct DMRay
178 {
179     float sx; float sy; float sz;
180     float dx; float dy; float dz;
181     float length;
182 }
183 
184 struct DMRayCastInfo
185 {
186     float px; float py; float pz;
187     float nx; float ny; float nz;
188     float param;
189     void* rbody;
190     void* shape;
191 }
192 
193 export int dmWorldRayCastQuery(void* pWorld, DMRay* ray, DMRayCastInfo* info, int checkBodies, int checkBVH)
194 {
195     PhysicsWorld world = cast(PhysicsWorld)pWorld;        
196     if (world && ray && info)
197     {
198         CastResult cr;
199         bool res = world.raycast(
200             Vector3f(ray.sx, ray.sy, ray.sz),
201             Vector3f(ray.dx, ray.dy, ray.dz),
202             ray.length, cr,
203             cast(bool)checkBodies, cast(bool)checkBVH);
204 
205         if (res)
206         {
207             info.px = cr.point.x;
208             info.py = cr.point.y;
209             info.pz = cr.point.z;
210 
211             info.nx = cr.normal.x;
212             info.ny = cr.normal.y;
213             info.nz = cr.normal.z;
214 
215             info.param = cr.param;
216             info.rbody = cast(void*)cr.rbody;
217             info.shape = cast(void*)cr.shape;
218 
219             return 1;
220         }
221         else
222             return 0;
223     }
224     else
225         return 0;
226 }
227 
228