1 /*************************************************************************
2  *                                                                       *
3  * Tokamak Physics Engine, Copyright (C) 2002-2007 David Lam.            *
4  * All rights reserved.  Email: david@tokamakphysics.com                 *
5  *                       Web: www.tokamakphysics.com                     *
6  *                                                                       *
7  * This library is distributed in the hope that it will be useful,       *
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
10  * LICENSE.TXT for more details.                                         *
11  *                                                                       *
12  *************************************************************************/
13 
14 #ifndef COLLISION_H
15 #define COLLISION_H
16 
17 typedef enum
18 {
19 	IMPULSE_IGNORE,
20 	IMPULSE_NORMAL,
21 	IMPULSE_CONTACT,
22 	IMPULSE_CONSTRAINT,
23 	IMPULSE_SLIDER,
24 	IMPULSE_SLIDER_LIMIT_PRIMARY,
25 //	IMPULSE_LIMIT,
26 	IMPULSE_ANGULAR_LIMIT_PRIMARY,
27 	IMPULSE_ANGULAR_LIMIT_SECONDARY,
28 	IMPULSE_ANGULAR_MOTOR_PRIMARY,
29 	IMPULSE_ANGULAR_MOTOR_SECONDARY,
30 	IMPULSE_RELATIVE_LINEAR_VELOCITY,
31 }neImpulseType;
32 
33 class neRigidBodyBase;
34 
35 class neRigidBody_;
36 
37 ///////////////////////////////////////////////////////////////////
38 //
39 //	Collision Model
40 //
41 //
42 ///////////////////////////////////////////////////////////////////
43 
44 typedef struct
45 {
46 	neV3	point[2];		// closest point in world space, but relative to object centre
47 	neV3	normal;			// toward feature on body A
48 
49 	f32		distance;
50 	bool	penetrated;
51 
52 	int		matIndex[2];
53 }TCollisionResult;
54 
55 ///////////////////////////////////////////////////////////////////
56 
57 //typedef struct neBox neBox;
58 
59 typedef struct _neBox
60 {
61 	neV3	boxSize; //half of dimensions
62 	//f32 boxSize[4];
63 }neBox;
64 
65 struct neTri
66 {
67 	s32 indices[3];
68 };
69 
70 struct neTriangleTerrain
71 {
72 	neSimpleArray<s32> * triIndex;
73 	neArray<neTriangle_> * triangles;
74 };
75 
76 struct neSphere
77 {
78 	f32 radius;
79 	f32 radiusSq;
80 };
81 
82 struct neCylinder
83 {
84 	f32 radius;
85 	f32 radiusSq;
86 	f32 halfHeight;
87 };
88 
89 struct neConvexMesh
90 {
91 	neV3 * vertices;
92 	s32 * neighbours;
93 	s32 vertexCount;
94 };
95 
96 struct neConvexDCD
97 {
98 	neByte * convexData;
99 	neV3 * vertices;
100 	s32 numVerts;
101 };
102 
103 #ifdef USE_OPCODE
104 
105 struct neOPCMesh
106 {
107 	Opcode::OPCODE_Model * opmodel;
108 	IceMaths::Point * vertices;
109 	u32 vertCount;
110 	IndexedTriangle * triIndices;
111 	u32 triCount;
112 };
113 
114 #endif
115 
116 typedef struct neBreakInfo neBreakInfo;
117 
118 struct neBreakInfo
119 {
120 	neV3 inertiaTensor;
121 	neV3 breakPlane;
122 	f32 mass;
123 	f32 breakMagnitude;
124 	f32 breakAbsorb;
125 	f32 neighbourRadius;
126 	neGeometry::neBreakFlag flag; //break all,
127 };
128 
129 typedef struct TConvex TConvex;
130 
131 struct TConvex
132 {
133 	enum
134 	{
135 		POINT,
136 		LINE,
137 		TRIANGLE,
138 		BOX,
139 		SPHERE,
140 		CYLINDER,
141 		TERRAIN,
142 		CONVEXITY,
143 		CONVEXDCD,
144 		OPCODE_MESH,
145 	};
146 
147 	union
148 	{
149 		neBox box;
150 		neTri tri;
151 		neTriangleTerrain terrain;
152 		neSphere sphere;
153 		neCylinder cylinder;
154 		neConvexMesh convexMesh;
155 		neConvexDCD convexDCD;
156 #ifdef USE_OPCODE
157 		neOPCMesh opcodeMesh;
158 #endif
159 	}as;
160 
161 	neT3	c2p;	// convex to physics object
162 	f32		boundingRadius;
163 	f32		envelope;
164 	u32		type;
165 	s32		matIndex;
166 	u32		userData;
167 	neBreakInfo breakInfo;
168 	neV3 *	vertices;
169 
170 	void	SetBoxSize(f32 width, f32 height, f32 depth);
171 	void	SetSphere(f32 radius);
172 	void	SetTriangle(s32 a, s32 b, s32 c, neV3 * vertices);
173 	void	SetTerrain(neSimpleArray<s32> & triangleIndex, neArray<neTriangle_> & triangles, neV3 * vertices);
174 	void	SetConvexMesh(neByte * convexData);
175 
176 #ifdef USE_OPCODE
177 
178 	void	SetOpcodeMesh(IndexedTriangle * triIndex, u32 triCount, IceMaths::Point * vertArray, u32 vertCount);
179 
180 #endif
181 
182 	void	SetTransform(neT3 & t3);
183 	neT3	GetTransform();
SetUserDataTConvex184 	void	SetUserData(u32 ud)
185 	{
186 			userData = ud;
187 	}
GetUserDataTConvex188 	u32		GetUserData()
189 	{
190 			return userData;
191 	}
192 	void	SetMaterialId(s32 id);
193 	s32		GetMaterialId();
194 	f32		GetBoundRadius();
195 	u32		GetType();
196 	void	Initialise();
197 	neM3	CalcInertiaTensor(f32 density, f32 & mass);
198 	void	GetExtend(neV3 & minExt, neV3 & maxEnt);
199 
200 	//quick access functions
BoxSizeTConvex201 	NEINLINE f32 BoxSize(s32 dir)
202 	{
203 		ASSERT(type == BOX);
204 
205 		return as.box.boxSize[dir];
206 	}
RadiusTConvex207 	NEINLINE f32 Radius()
208 	{
209 		ASSERT(type == SPHERE);
210 
211 		return as.sphere.radius;
212 	}
RadiusSqTConvex213 	NEINLINE f32 RadiusSq()
214 	{
215 		ASSERT(type == SPHERE);
216 
217 		return as.sphere.radiusSq;
218 	}
CylinderRadiusTConvex219 	NEINLINE f32 CylinderRadius()
220 	{
221 		ASSERT(type == CYLINDER);
222 
223 		return as.cylinder.radius;
224 	}
CylinderRadiusSqTConvex225 	NEINLINE f32 CylinderRadiusSq()
226 	{
227 		ASSERT(type == CYLINDER);
228 
229 		return as.cylinder.radiusSq;
230 	}
CylinderHalfHeightTConvex231 	NEINLINE f32 CylinderHalfHeight()
232 	{
233 		ASSERT(type == CYLINDER);
234 
235 		return as.cylinder.halfHeight;
236 	}
237 };
238 
239 class neSensor_
240 {
241 public:
242 	neV3 pos;
243 
244 	neV3 dir;
245 
246 	neV3 dirNormal;
247 
248 	f32 length;
249 
250 	u32 cookies;
251 
252 	//results
253 
254 	neV3 normal;
255 
256 	neV3 contactPoint;
257 
258 	f32 depth;
259 
260 	s32 materialID;
261 
262 	neRigidBodyBase * body;
263 
264 public:
265 
neSensor_()266 	neSensor_()
267 	{
268 		pos.SetZero();
269 		dir.SetZero();
270 		cookies = 0;
271 		normal.SetZero();
272 		depth = 0;
273 		materialID = 0;
274 		body = NULL;
275 	}
276 };
277 /****************************************************************************
278 *
279 *	NE Physics Engine
280 *
281 *	Class: neCollision
282 *
283 *	Desc:
284 *
285 ****************************************************************************/
286 
287 typedef neFreeListItem<TConvex> TConvexItem;
288 
289 class neCollision
290 {
291 public:
neCollision()292 	neCollision()
293 	{
294 		convex = NULL;
295 		convexCount = 0;
296 		boundingRadius = 0.0f;
297 		obb.SetBoxSize(1.0f, 1.0f, 1.0f);
298 	}
299 
300 //	void		SeTConvex(TConvex * con, s32 count)
301 //	{
302 //		convex = con;
303 //		convexCount = count+1;
304 //	}
305 
306 	void		CalcBB();
307 
308 public:
309 	TConvex		obb;
310 	TConvex *	convex;
311 	s32			convexCount;
312 	f32			boundingRadius;
313 };
314 
315 class neCollisionResult;
316 
317 typedef neCollection<neCollisionResult>::itemType neCollisionResultHandle;
318 
319 class neCollisionResult
320 {
321 PLACEMENT_MAGIC
322 public:
323 	//neCollisionResultHandle bodyAHandle;
324 	//neCollisionResultHandle bodyBHandle;
325 
326 	neV3 contactA;
327 	neV3 contactB;
328 
329 	neV3 contactABody; // or relative tangential velocity
330 	neV3 contactBBody; // or angular limit axis
331 
332 	neV3 contactAWorld;
333 	neV3 contactBWorld;
334 
335 	neM3 collisionFrame;
336 
337 	neM3 w2c;
338 
339 	neV3 initRelVelWorld;
340 	neV3 initRelVel;
341 	neV3 finaltRelVel;
342 
343 	s32	 materialIdA;
344 	s32	 materialIdB;
345 	f32	 depth; //+ve
346 	neBool penetrate;
347 
348 	neRigidBodyBase * bodyA;
349 	neRigidBodyBase * bodyB;
350 
351 	f32 relativeSpeed;
352 	f32 finalRelativeSpeed;
353 
354 	TConvex * convexA;
355 	TConvex * convexB;
356 
357 	neM3 k;
358 
359 	neM3 kInv;
360 
361 	f32 impulseScale;
362 
363 	neImpulseType impulseType;
364 
365 	neBool flag;
366 
367 	void UpdateConstraintRelativeSpeed();
368 	void StartStage2();
369 	void PrepareForSolver(neBool aIdle = false, neBool bIdle = false);
370 	void CalcCollisionMatrix(neRigidBody_* ba, neRigidBody_ * bb, neBool isWorld);
371 	void CalcCollisionMatrix2(neRigidBody_* ba, neRigidBody_ * bb);
372 	void CalcCollisionMatrix3(neRigidBody_* ba, neRigidBody_ * bb);
373 
374 	f32 SolveContact(neFixedTimeStepSimulator * sim);
375 	f32 SolveConstraint(neFixedTimeStepSimulator * sim);
376 	f32 SolveSlider(neFixedTimeStepSimulator * sim);
377 	f32 SolveSliderLimit(neFixedTimeStepSimulator * sim);
378 	f32 SolveAngularPrimary(neFixedTimeStepSimulator * sim);
379 	f32 SolveAngularSecondary(neFixedTimeStepSimulator * sim);
380 	f32 SolveAngularMotorPrimary(neFixedTimeStepSimulator * sim);
381 	f32 SolveRelativeLinear(neFixedTimeStepSimulator * sim);
382 
383 	f32 SolveAngular(f32 depth, const neV3 & axis, f32 relAV, neFixedTimeStepSimulator * sim);
384 	f32 SolveAngular2(const neV3 & axisA, const neV3 & axisB, f32 relAV, f32 desireAV, f32 depth, neFixedTimeStepSimulator * sim);
385 	f32 SolveAngular3(f32 depth, const neV3 & axis, f32 relAV, neFixedTimeStepSimulator * sim);
386 
387 	void CalcError(neFixedTimeStepSimulator * sim);
388 //	void AddToBodies();
389 
Value()390 	f32 Value(){
391 		return relativeSpeed;};
392 
393 	neBool CheckIdle();
394 
Swap()395 	void Swap()
396 	{
397 		collisionFrame[2] *=  -1.0f;
398 
399 		neSwap(contactA, contactB);
400 
401 		neSwap(convexA, convexB);
402 	}
403 };
404 
405 void CollisionTest(neCollisionResult & result, neCollision & colA, neT3 & transA, neCollision & colB, neT3 & transB, const neV3 & backupVector);
406 
407 void CollisionTestSensor(TConvex * obbA, neSensor_ * sensorsA, neT3 & transA, neCollision & colB, neT3 & transB, neRigidBodyBase * body);
408 
409 void ConvexCollisionTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB, const neV3 & backupVector);
410 
411 void Box2BoxTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB, const neV3 & backupVector);
412 
413 void Box2TriangleTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB);
414 
415 void Box2TerrainTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB);
416 
417 void Box2SphereTest(neCollisionResult & result, TConvex & boxA, neT3 & transA, TConvex & sphereB, neT3 & transB);
418 
419 void Box2CylinderTest(neCollisionResult & result, TConvex & boxA, neT3 & transA, TConvex & sphereB, neT3 & transB);
420 
421 void Sphere2TerrainTest(neCollisionResult & result, TConvex & sphereA, neT3 & transA, TConvex & terrainB);
422 
423 void Sphere2SphereTest(neCollisionResult & result, TConvex & sphereA, neT3 & transA, TConvex & sphereB, neT3 & transB);
424 
425 void Cylinder2CylinderTest(neCollisionResult & result, TConvex & cA, neT3 & transA, TConvex & cB, neT3 & transB);
426 
427 void Cylinder2TerrainTest(neCollisionResult & result, TConvex & cylinderA, neT3 & transA, TConvex & terrainB);
428 
429 void Cylinder2SphereTest(neCollisionResult & result, TConvex & cylinderA, neT3 & transA, TConvex & sphereB, neT3 & transB);
430 
431 void Box2ConvexTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB, const neV3 & backupVector);
432 
433 void Convex2ConvexTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB, const neV3 & backupVector);
434 
435 void TranslateCOM(neM3 & I, neV3 &translate, f32 mass, f32 factor);
436 
437 void DiagonalizeMassTensor(neM3 & I, neV3 & diagonal, neM3 & eigenVectors);
438 
439 void SensorTest(neSensor_ & sensorA, TConvex & convexB, neT3 & transB);
440 
441 #ifdef USE_OPCODE
442 
443 void Box2OpcodeTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB);
444 
445 void Sphere2OpcodeTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB);
446 
447 void Cylinder2OpcodeTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB);
448 
449 void Opcode2TerrainTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB);
450 
451 void Opcode2OpcodeTest(neCollisionResult & result, TConvex & convexA, neT3 & transA, TConvex & convexB, neT3 & transB);
452 
453 #endif //USE_OPCODE
454 
455 #endif
456 
457 
458 
459 
460 
461 
462 
463 
464 
465 
466 
467 
468 
469 
470 
471 
472 
473 
474 
475 
476