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 TOKAMAK_H
15 #define TOKAMAK_H
16 
17 #define TOKAMAK_VERSION_MAJOR 1
18 #define TOKAMAK_VERSION_MINOR 0
19 #define TOKAMAK_VERSION_BUGFIX 5
20 #define TOKAMAK_VERSION  (( TOKAMAK_VERSION_MAJOR <<24)+(TOKAMAK_VERSION_MINOR <<16)+(TOKAMAK_VERSION_BUGFIX <<8) + 0)
21 #include <stdlib.h>
22 
23 #include "math/ne_math.h"
24 
25 #ifdef TOKAMAK_USE_DLL
26 #ifdef TOKAMAK_DLL_EXPORTS
27 #define TOKAMAK_API __declspec(dllexport)
28 #else
29 #define TOKAMAK_API __declspec(dllimport)
30 #endif
31 #else
32 #define TOKAMAK_API
33 #endif
34 
35 #define NE_INTERFACE(n) protected: n(){}; n& operator = (const n & e){return (*this);}
36 
37 class TOKAMAK_API neRigidBody;
38 
39 typedef enum
40 {
41 	NE_TERRAIN = 0,
42 	NE_RIGID_BODY,
43 	NE_ANIMATED_BODY,
44 } neBodyType;
45 
46 /****************************************************************************
47 *
48 *	Tokamak Game Physics SDK
49 *
50 *	Class: neAllocatorAbstract
51 *
52 *	Desc:
53 *
54 ****************************************************************************/
55 
56 class neAllocatorAbstract
57 {
58 public:
59 	virtual neByte * Alloc(s32 size, s32 alignment = 0) = 0;
60 
61 	virtual void   Free(neByte *) = 0;
62 };
63 
64 
65 /****************************************************************************
66 *
67 *	Tokamak Game Physics SDK
68 *
69 *	Class: neAllocatorDefault
70 *
71 *	Desc:
72 *
73 ****************************************************************************/
74 
75 class neAllocatorDefault: public neAllocatorAbstract
76 {
77 public:
neAllocatorDefault()78 	neAllocatorDefault()
79 	{
80 		usedMem = 0;
81 	}
82 	neByte * Alloc(s32 size, s32 alignment = 0) {
83 
84 		usedMem += size;
85 
86 		return (neByte *)malloc(size);
87 	}
Free(neByte * ptr)88 	void Free(neByte * ptr) {
89 
90 		free(ptr);
91 	}
92 public:
93 	s32 usedMem;
94 };
95 
96 
97 /****************************************************************************
98 *
99 *	Tokamak Game Physics SDK
100 *
101 *	Class: nePerformanceReport
102 *
103 *	Desc:
104 *
105 ****************************************************************************/
106 
107 class nePerformanceReport
108 {
109 public:
110 	enum{
111 		NE_PERF_TOTAL_TIME = 0,
112 		NE_PERF_DYNAMIC,
113 		NE_PERF_POSITION,
114 		NE_PERF_CONTRAIN_SOLVING_1,
115 		NE_PERF_CONTRAIN_SOLVING_2,
116 		NE_PERF_COLLISION_DETECTION,
117 		NE_PERF_COLLISION_CULLING,
118 		NE_PERF_TERRAIN_CULLING,
119 		NE_PERF_TERRAIN,
120 		NE_PERF_CONTROLLER_CALLBACK,
121 		NE_PERF_LAST,
122 	};
123 	enum
124 	{
125 		NE_PERF_RUNNING_AVERAGE = 0,
126 		NE_PERF_SAMPLE,
127 	};
128 	f32 time[NE_PERF_LAST];
129 	f32 accTime[NE_PERF_LAST];
130 
Reset()131 	void Reset()
132 	{
133 		for (s32 i = 0; i < NE_PERF_LAST; i++)
134 		{
135 			time[i] = 0.0f;
136 			accTime[i] = 0.0f;
137 		}
138 		numSample = 0;
139 	}
SetReportType(s32 type)140 	void SetReportType(s32 type)
141 	{
142 		reportType = type;
143 	}
144 	s32 reportType;
145 	s32 numSample;
146 };
147 
148 /****************************************************************************
149 *
150 *	Tokamak Game Physics SDK
151 *
152 *	Class: neGeometry
153 *
154 *	Desc:
155 *
156 ****************************************************************************/
157 
158 class TOKAMAK_API neGeometry;
159 
160 typedef void (neBreakageCallback)(neByte * originalBody, neBodyType bodyType, neGeometry * brokenGeometry, neRigidBody * newBody);
161 
162 class TOKAMAK_API neGeometry
163 {
164 NE_INTERFACE(neGeometry)
165 
166 public:
167 
168 typedef enum
169 {
170 	NE_BREAK_DISABLE,
171 	NE_BREAK_NORMAL,
172 	NE_BREAK_ALL,
173 	NE_BREAK_NEIGHBOUR,
174 
175 	/*	the following are the same as above,
176 		except it create a rigid particle instead of a rigid body
177 	*/
178 
179 	NE_BREAK_NORMAL_PARTICLE,
180 	NE_BREAK_ALL_PARTICLE,
181 	NE_BREAK_NEIGHBOUR_PARTICLE,
182 } neBreakFlag;
183 
184 public:
185 	void	SetTransform(neT3 & t);
186 
187 	void	SetMaterialIndex(s32 index);
188 
189 	s32		GetMaterialIndex();
190 
191 	neT3	GetTransform();
192 
193 	void	SetUserData(u32 userData);
194 
195 	u32		GetUserData();
196 
197 	/*
198 		Box
199 	*/
200 	void	SetBoxSize(f32 width, f32 height, f32 depth);
201 
202 	void	SetBoxSize(const neV3 & boxSize);
203 
204 	neBool	GetBoxSize(neV3 & boxSize); // return false if geometry is not a box
205 
206 	/*
207 		Sphere
208 	*/
209 	void	SetSphereDiameter(f32 diameter);
210 
211 	neBool	GetSphereDiameter(f32 & diameter); // return false if geometry is not a sphere
212 
213 	/*
214 		Cylinder
215 	*/
216 	void	SetCylinder(f32 diameter, f32 height);
217 
218 	neBool	GetCylinder(f32 & diameter, f32 & height); // return false if geometry is not a cylinder
219 
220 	/*
221 		Convex
222 	*/
223 	void	SetConvexMesh(neByte * convexData);
224 
225 	neBool	GetConvexMesh(neByte *& convexData);
226 
227 	/*
228 		Breakage functions
229 	*/
230 	void	SetBreakageFlag(neBreakFlag flag);
231 
232 	neBreakFlag GetBreakageFlag();
233 
234 	void	SetBreakageMass(f32 mass);
235 
236 	f32		GetBreakageMass();
237 
238 	void	SetBreakageInertiaTensor(const neV3 & tensor);
239 
240 	neV3	GetBreakageInertiaTensor();
241 
242 	void	SetBreakageMagnitude(f32 mag);
243 
244 	f32		GetBreakageMagnitude();
245 
246 	void	SetBreakageAbsorption(f32 absorb);
247 
248 	f32		GetBreakageAbsorption();
249 
250 	void	SetBreakagePlane(const neV3 & planeNormal);
251 
252 	neV3	GetBreakagePlane();
253 
254 	void	SetBreakageNeighbourRadius(f32 radius);
255 
256 	f32		GetBreakageNeighbourRadius();
257 };
258 
259 /****************************************************************************
260 *
261 *	Tokamak Game Physics SDK
262 *
263 *	Class: neTriangleMesh
264 *
265 *	Desc:
266 *
267 ****************************************************************************/
268 class neTriangle
269 {
270 public:
neTriangle()271 	neTriangle()
272 	{
273 		flag = NE_TRI_TRIANGLE;
274 		materialID = 0;
275 		indices[0] = -1;
276 		indices[1] = -1;
277 		indices[2] = -1;
278 		userData = 0;
279 	}
280 
281 	enum
282 	{
283 		NE_TRI_TRIANGLE = 0,
284 		NE_TRI_HEIGHT_MAP,
285 	};
286 	s32 indices[3];
287 	s32 materialID;
288 	u32 flag;
289 	u32 userData;
290 };
291 
292 class neTriangleMesh
293 {
294 public:
295 	neV3 * vertices;
296 
297 	s32 vertexCount;
298 
299 	neTriangle * triangles;
300 
301 	s32 triangleCount;
302 };
303 
304 /****************************************************************************
305 *
306 *	Tokamak Game Physics SDK
307 *
308 *	Class: neSensor
309 *
310 *	Desc:
311 *
312 ****************************************************************************/
313 
314 class TOKAMAK_API neRigidBody;
315 
316 class TOKAMAK_API neAnimatedBody;
317 
318 class TOKAMAK_API neSensor
319 {
320 NE_INTERFACE(neSensor)
321 
322 public:
323 	void	SetLineSensor(const neV3 & pos, const neV3 & lineVector);
324 
325 	void	SetUserData(u32 userData);
326 
327 	u32		GetUserData();
328 
329 	neV3	GetLineVector();
330 
331 	neV3	GetLineUnitVector();
332 
333 	neV3	GetLinePos();
334 
335 	f32		GetDetectDepth();
336 
337 	neV3	GetDetectNormal();
338 
339 	neV3	GetDetectContactPoint();
340 
341 	neRigidBody * GetDetectRigidBody();
342 
343 	neAnimatedBody * GetDetectAnimatedBody();
344 
345 	s32		GetDetectMaterial();
346 };
347 
348 /****************************************************************************
349 *
350 *	Tokamak Game Physics SDK
351 *
352 *	Class: neAnimatedBody
353 *
354 *	Desc:
355 *
356 ****************************************************************************/
357 
358 class TOKAMAK_API neAnimatedBody
359 {
360 NE_INTERFACE(neAnimatedBody)
361 
362 public:
363 
364 //spatial states
365 	neV3	GetPos();
366 
367 	void	SetPos(const neV3 & p);
368 
369 	neM3	GetRotationM3();
370 
371 	neQ		GetRotationQ();
372 
373 	void	SetRotation(const neM3 & m);
374 
375 	void	SetRotation(const neQ & q);
376 
377 	neT3	GetTransform();
378 
379 //collision related
380 	void	SetCollisionID(s32 cid);
381 
382 	s32		GetCollisionID();
383 
384 	void	SetUserData(u32 userData);
385 
386 	u32		GetUserData();
387 
388 	s32		GetGeometryCount();
389 
390 //collision geometries and sensors
391 
392 	neGeometry *	AddGeometry();
393 
394 	neBool			RemoveGeometry(neGeometry * g);
395 
396 	void			BeginIterateGeometry();
397 
398 	neGeometry *	GetNextGeometry();
399 
400 	neRigidBody *	BreakGeometry(neGeometry * g);
401 
402 	neSensor *		AddSensor();
403 
404 	neBool			RemoveSensor(neSensor * s);
405 
406 	void			BeginIterateSensor();
407 
408 	neSensor *		GetNextSensor();
409 
410 	void			UseCustomCollisionDetection(neBool yes, const neT3 * obb, f32 boundingRadius);
411 
412 	neBool			UseCustomCollisionDetection();
413 
414 //functions
415 	void	UpdateBoundingInfo();
416 
417 	// collide with any body which connected to this body indirectly
418 
419 	void	CollideConnected(neBool yes);
420 
421 	neBool	CollideConnected();
422 
423 	// collide with any body which connected to this body directly
424 
425 	void	CollideDirectlyConnected(neBool yes);
426 
427 	neBool	CollideDirectlyConnected();
428 
429 	void	Active(neBool yes, neRigidBody * hint = NULL);
430 
431 	void	Active(neBool yes, neAnimatedBody * hint = NULL);
432 
433 	neBool	Active();
434 };
435 
436 /****************************************************************************
437 *
438 *	Tokamak Game Physics SDK
439 *
440 *	Class: neRigidBody
441 *
442 *	Desc:
443 *
444 ****************************************************************************/
445 
446 class TOKAMAK_API neRigidBodyController;
447 
448 class TOKAMAK_API neJointController;
449 
450 class neRigidBodyControllerCallback
451 {
452 public:
453 	virtual void RigidBodyControllerCallback(neRigidBodyController * controller, float timeStep) = 0;
454 };
455 
456 class neJointControllerCallback
457 {
458 public:
459 	virtual void ConstraintControllerCallback(neJointController * controller, float timeStep) = 0;
460 };
461 
462 class TOKAMAK_API neRigidBody
463 {
464 NE_INTERFACE(neRigidBody)
465 
466 public:
467 
468 //physical properties
469 	f32		GetMass();
470 
471 	void	SetMass(f32 mass);
472 
473 	void	SetInertiaTensor(const neM3 & tensor);
474 
475 	void	SetInertiaTensor(const neV3 & tensor);
476 
477 //other properties
478 	void	SetCollisionID(s32 cid);
479 
480 	s32		GetCollisionID();
481 
482 	void	SetUserData(u32 userData);
483 
484 	u32		GetUserData();
485 
486 	s32		GetGeometryCount();
487 
488 	void	SetLinearDamping(f32 damp);
489 
490 	f32		GetLinearDamping();
491 
492 	void	SetAngularDamping(f32 damp);
493 
494 	f32		GetAngularDamping();
495 
496 	void	SetSleepingParameter(f32 sleepingParam);
497 
498 	f32		GetSleepingParameter();
499 
500 //collision geometries, sensors and controllers
501 
502 	neGeometry *	AddGeometry();
503 
504 	neBool			RemoveGeometry(neGeometry * g);
505 
506 	void			BeginIterateGeometry();
507 
508 	neGeometry *	GetNextGeometry();
509 
510 	neRigidBody *	BreakGeometry(neGeometry * g);
511 
512 	void			UseCustomCollisionDetection(neBool yes,  const neT3 * obb, f32 boundingRadius);
513 
514 	neBool			UseCustomCollisionDetection();
515 
516 	neSensor *		AddSensor();
517 
518 	neBool			RemoveSensor(neSensor * s);
519 
520 	void			BeginIterateSensor();
521 
522 	neSensor *		GetNextSensor();
523 
524 	neRigidBodyController * AddController(neRigidBodyControllerCallback * controller, s32 period);
525 
526 	neBool			RemoveController(neRigidBodyController * rbController);
527 
528 	void			BeginIterateController();
529 
530 	neRigidBodyController * GetNextController();
531 
532 //spatial states
533 	neV3	GetPos();
534 
535 	void	SetPos(const neV3 & p);
536 
537 	neM3	GetRotationM3();
538 
539 	neQ		GetRotationQ();
540 
541 	void	SetRotation(const neM3 & m);
542 
543 	void	SetRotation(const neQ & q);
544 
545 	neT3	GetTransform();
546 
547 //dynamic states
548 	neV3	GetVelocity();
549 
550 	void	SetVelocity(const neV3 & v);
551 
552 	neV3	GetAngularVelocity();
553 
554 	neV3	GetAngularMomentum();
555 
556 	void	SetAngularMomentum(const neV3& am);
557 
558 	neV3	GetVelocityAtPoint(const neV3 & pt);
559 
560 //functions
561 	void	UpdateBoundingInfo();
562 
563 	void	UpdateInertiaTensor();
564 
565 	void	SetForce(const neV3 & force);
566 
567 	void	SetTorque(const neV3 & torque);
568 
569 	void	SetForce(const neV3 & force, const neV3 & pos);
570 
571 	neV3	GetForce();
572 
573 	neV3	GetTorque();
574 
575 	void	ApplyImpulse(const neV3 & impulse);
576 
577 	void	ApplyImpulse(const neV3 & impulse, const neV3 & pos);
578 
579 	void	ApplyTwist(const neV3 & twist);
580 
581 	void	GravityEnable(neBool yes);
582 
583 	neBool	GravityEnable();
584 
585 	// collide with any body which connected to this body indirectly
586 
587 	void	CollideConnected(neBool yes);
588 
589 	neBool	CollideConnected();
590 
591 	// collide with any body which connected to this body directly
592 
593 	void	CollideDirectlyConnected(neBool yes);
594 
595 	neBool	CollideDirectlyConnected();
596 
597 	void	Active(neBool yes, neRigidBody * hint = NULL);
598 
599 	void	Active(neBool yes, neAnimatedBody * hint = NULL);
600 
601 	neBool	Active();
602 
603 	neBool	IsIdle();
604 };
605 
606 /****************************************************************************
607 *
608 *	Tokamak Game Physics SDK
609 *
610 *	Class: neJoint
611 *
612 *	Desc:
613 *
614 ****************************************************************************/
615 
616 class TOKAMAK_API neJoint
617 {
618 NE_INTERFACE(neJoint)
619 
620 public:
621 	typedef enum
622 	{
623 		NE_JOINT_BALLSOCKET,
624 		NE_JOINT_BALLSOCKET2,
625 		NE_JOINT_HINGE,
626 		NE_JOINT_SLIDE,
627 
628 	}ConstraintType;
629 
630 	void SetType(ConstraintType t);
631 
632 	ConstraintType GetType();
633 
634 	void SetJointFrameA(const neT3 & frameA);
635 
636 	void SetJointFrameB(const neT3 & frameB);
637 
638 	void SetJointFrameWorld(const neT3 & frame);
639 
640 	neT3 GetJointFrameA();
641 
642 	neT3 GetJointFrameB();
643 
644 	void SetJointLength(f32 length);
645 
646 	f32 GetJointLength();
647 
648 	neRigidBody * GetRigidBodyA();
649 
650 	neRigidBody * GetRigidBodyB();
651 
652 	neAnimatedBody * GetAnimatedBodyB();
653 
654 	void Enable(neBool yes);
655 
656 	neBool Enable();
657 
658 	void SetDampingFactor(f32 damp);
659 
660 	f32 GetDampingFactor();
661 
662 	/*
663 		Query Joint position
664 	*/
665 
666 	f32 GetPosition();
667 
668 	f32 GetPosition2();
669 
670 	/*
671 		Constraint primary limit functions
672 	*/
673 	neBool EnableLimit();
674 
675 	void EnableLimit(neBool yes);
676 
677 	f32 GetUpperLimit();
678 
679 	void SetUpperLimit(f32 upperLimit);
680 
681 	f32 GetLowerLimit();
682 
683 	void SetLowerLimit(f32 lowerLimit);
684 
685 	/*
686 		Constraint secondary limit functions (only apply to some Constraint types)
687 	*/
688 
689 	neBool EnableLimit2();
690 
691 	void EnableLimit2(neBool yes);
692 
693 	f32 GetUpperLimit2();
694 
695 	void SetUpperLimit2(f32 upperLimit);
696 
697 	f32 GetLowerLimit2();
698 
699 	void SetLowerLimit2(f32 lowerLimit);
700 
701 	/*
702 		relates to accuracy and speed of the joint solver
703 	*/
704 	void SetEpsilon(f32 e);
705 
706 	f32 GetEpsilon();
707 
708 	void SetIteration(s32 i);
709 
710 	s32 GetIteration();
711 
712 	/*
713 		Constraint controller functions
714 	*/
715 
716 	neJointController * AddController(neJointControllerCallback * controller, s32 period);
717 
718 	neBool	RemoveController(neJointController * rbController);
719 
720 	void	BeginIterateController();
721 
722 	neJointController * GetNextController();
723 
724 	/*
725 	 	Constraint primary motor function, currently only implemented for hinge Constraint
726 	 */
727 	enum MotorType
728 	{
729 		NE_MOTOR_SPEED,
730 		NE_MOTOR_POSITION, //not implemented
731 	};
732 	neBool EnableMotor();
733 
734 	void EnableMotor(neBool yes);
735 
736 	void SetMotor(MotorType motorType, f32 desireValue, f32 maxForce);
737 
738 	void GetMotor(MotorType & motorType, f32 & desireValue, f32 & maxForce);
739 
740 	neBool EnableMotor2();
741 
742 	void EnableMotor2(neBool yes);
743 
744 	void SetMotor2(MotorType motorType, f32 desireValue, f32 maxForce);
745 
746 	void GetMotor2(MotorType & motorType, f32 & desireValue, f32 & maxForce);
747 };
748 
749 /****************************************************************************
750 *
751 *	Tokamak Game Physics SDK
752 *
753 *	Class:
754 *
755 *	Desc:
756 *
757 ****************************************************************************/
758 
759 class TOKAMAK_API neRigidBodyController
760 {
761 NE_INTERFACE(neRigidBodyController);
762 
763 public:
764 	neRigidBody * GetRigidBody();
765 
766 	neV3 GetControllerForce();
767 
768 	neV3 GetControllerTorque();
769 
770 	void SetControllerForce(const neV3 & force);
771 
772 	void SetControllerTorque(const neV3 & torque);
773 
774 	void SetControllerForceWithTorque(const neV3 & force, const neV3 & pos);
775 };
776 
777 class TOKAMAK_API neJointController
778 {
779 NE_INTERFACE(neJointController);
780 
781 public:
782 	neJoint * GetJoint();
783 
784 	neV3 GetControllerForceBodyA();
785 
786 	neV3 GetControllerForceBodyB();
787 
788 	neV3 GetControllerTorqueBodyA();
789 
790 	neV3 GetControllerTorqueBodyB();
791 
792 	void SetControllerForceBodyA(const neV3 & force);
793 
794 	void SetControllerForceBodyB(const neV3 & force);
795 
796 	void SetControllerForceWithTorqueBodyA(const neV3 & force, const neV3 & pos);
797 
798 	void SetControllerForceWithTorqueBodyB(const neV3 & force, const neV3 & pos);
799 
800 	void SetControllerTorqueBodyA(const neV3 & torque);
801 
802 	void SetControllerTorqueBodyB(const neV3 & torque);
803 };
804 /****************************************************************************
805 *
806 *	Tokamak Game Physics SDK
807 *
808 *	Class: neCollisionTable
809 *
810 *	Desc:
811 *
812 ****************************************************************************/
813 
814 class TOKAMAK_API neCollisionTable
815 {
816 NE_INTERFACE(neCollisionTable)
817 
818 public:
819 	enum neReponseBitFlag
820 	{
821 		RESPONSE_IGNORE = 0,
822 		RESPONSE_IMPULSE = 1,
823 		RESPONSE_CALLBACK = 2,
824 		RESPONSE_IMPULSE_CALLBACK = 3,
825 	};
826 
827 	enum
828 	{
829 		NE_COLLISION_TABLE_MAX = 64,
830 	};
831 	void Set(s32 collisionID1, s32 collisionID2, neReponseBitFlag response = RESPONSE_IMPULSE);
832 
833 	neReponseBitFlag Get(s32 collisionID1, s32 collisionID2);
834 
835 	s32 GetMaxCollisionID();
836 };
837 
838 /****************************************************************************
839 *
840 *	Tokamak Game Physics SDK
841 *
842 *	Class: neSimulatorSizeInfo
843 *
844 *	Desc:
845 *
846 ****************************************************************************/
847 
848 
849 class neSimulatorSizeInfo
850 {
851 public:
852 	enum
853 	{
854 		DEFAULT_RIGIDBODIES_COUNT = 50,
855 		DEFAULT_ANIMATEDBODIES_COUNT = 50,
856 		DEFAULT_RIGIDPARTICLES_COUNT = 50,
857 
858 		DEFAULT_CONTROLLERS_COUNT = 50,
859 		DEFAULT_OVERLAPPED_PAIRS_COUNT = 1225,
860 
861 		DEFAULT_GEOMETRIES_COUNT = 50,
862 
863 		DEFAULT_CONSTRAINTS_COUNT = 100,
864 		DEFAULT_CONTRAINT_SETS_COUNT = 100,
865 		DEFAULT_SOLVER_BUFFER_SIZE = 2000,
866 		DEFAULT_SENSORS_COUNT = 100,
867 
868 		DEFAULT_TERRAIN_NODES_START_COUNT = 200,
869 		DEFAULT_TERRAIN_NODES_GROWBY_COUNT = -1,
870 	};
871 
872 public:
873 
874 	s32 rigidBodiesCount;		/* Number of rigid bodies in the simulation */
875 	s32 animatedBodiesCount;	/* Number of animated bodies in the simulation */
876 	s32 rigidParticleCount;		/* Number of rigid particles in the simulation */
877 
878 	s32 controllersCount;		/* Number of controller instances in the simulation */
879 
880 	s32 overlappedPairsCount;	/* Number of possible overlapping pairs.
881 								   This has the maximum value of (n x (n - 1)) / 2,
882 								   where n = rigidBodyCount + animatedBodyCount.
883 								   But in practice it rarely reach that high.
884 								   You can try to specify a smaller number to save memory.
885 								*/
886 	s32 geometriesCount;		/* Number of collision geometries in the simulator*/
887 
888 
889 	s32 constraintsCount;		/* Number of joints in the simulation */
890 	s32 constraintSetsCount;	/* Number of joint Sets in the simulation */
891 	s32 constraintBufferSize;	/* Size of the buffer use to solve joints */
892 	s32 sensorsCount;
893 
894 	s32 terrainNodesStartCount;	/* Number of nodes use to store terrain triangles */
895 	s32 terrainNodesGrowByCount;/* Grow by this size if run out of nodes */
896 
897 public:
898 
neSimulatorSizeInfo()899 	neSimulatorSizeInfo()		/* Fill with default size values */
900 	{
901 		rigidBodiesCount = DEFAULT_RIGIDBODIES_COUNT;
902 		animatedBodiesCount = DEFAULT_ANIMATEDBODIES_COUNT;
903 		rigidParticleCount = DEFAULT_RIGIDPARTICLES_COUNT;
904 
905 		controllersCount = DEFAULT_CONTROLLERS_COUNT;
906 
907 		overlappedPairsCount = DEFAULT_OVERLAPPED_PAIRS_COUNT;
908 
909 		geometriesCount = DEFAULT_GEOMETRIES_COUNT;
910 
911 		constraintsCount = DEFAULT_CONSTRAINTS_COUNT;
912 		constraintSetsCount = DEFAULT_CONTRAINT_SETS_COUNT;
913 		constraintBufferSize = DEFAULT_SOLVER_BUFFER_SIZE;
914 		sensorsCount = DEFAULT_SENSORS_COUNT;
915 
916 		terrainNodesStartCount = DEFAULT_TERRAIN_NODES_START_COUNT;
917 		terrainNodesGrowByCount = DEFAULT_TERRAIN_NODES_GROWBY_COUNT;
918 										/* -1 signify double the number of terrainNode, whenever the
919 										   it reach full capacity.
920 										*/
921 	}
922 };
923 
924 /****************************************************************************
925 *
926 *	Tokamak Game Physics SDK
927 *
928 *	Class: neSimulator
929 *
930 *	Desc:
931 *
932 ****************************************************************************/
933 typedef struct neCollisionInfo neCollisionInfo;
934 
935 struct neCollisionInfo
936 {
937 	neByte * bodyA;
938 	neByte * bodyB;
939 	neBodyType typeA;
940 	neBodyType typeB;
941 	neGeometry * geometryA;
942 	neGeometry * geometryB;
943 	s32 materialIdA;
944 	s32 materialIdB;
945 	neV3 bodyContactPointA;		// contact point A in body space of A
946 	neV3 bodyContactPointB;		// contact point B in body space of B
947 	neV3 worldContactPointA;	// contact point A in world space
948 	neV3 worldContactPointB;	// contact point B in world space
949 	neV3 relativeVelocity;
950 	neV3 collisionNormal;
951 };
952 
953 typedef void (neLogOutputCallback)(char * logString);
954 
955 typedef void (neCollisionCallback)(neCollisionInfo & collisionInfo);
956 
957 typedef void (neTerrainTriangleQueryCallback)(const neV3 & minBound, const neV3 & maxBound,
958 											  s32 ** candidateTriangles,
959 												neTriangle ** triangles,
960 												neV3 ** vertices,
961 												s32 * candidateCount,
962 												s32 * triangleCount,
963 												neRigidBody * body);
964 
965 typedef struct neCustomCDInfo neCustomCDInfo;
966 
967 struct neCustomCDInfo
968 {
969 	neV3 collisionNormal;
970 	neV3 worldContactPointA;
971 	neV3 worldContactPointB;
972 	f32 penetrationDepth;
973 	s32 materialIdA;
974 	s32 materialIdB;
975 };
976 
977 typedef neBool (neCustomCDRB2RBCallback)(neRigidBody * bodyA, neRigidBody * bodyB, neCustomCDInfo & cdInfo);
978 
979 typedef neBool (neCustomCDRB2ABCallback)(neRigidBody * bodyA, neAnimatedBody * bodyB, neCustomCDInfo & cdInfo);
980 
981 class TOKAMAK_API neSimulator
982 {
983 NE_INTERFACE(neSimulator)
984 
985 public:
986 	typedef enum
987 	{
988 		LOG_OUTPUT_LEVEL_NONE = 0,
989 		LOG_OUTPUT_LEVEL_ONE,
990 		LOG_OUTPUT_LEVEL_FULL,
991 	} LOG_OUTPUT_LEVEL;
992 
993 public:
994 	/*
995 		Static factory functions
996 	*/
997 
998 	static neSimulator * CreateSimulator(const neSimulatorSizeInfo & sizeInfo,
999 										neAllocatorAbstract * alloc = NULL,
1000 										const neV3 * gravity = NULL);
1001 
1002 	static void DestroySimulator(neSimulator * sim);
1003 
1004 	/*
1005 		Rigid body managment functions
1006 	*/
1007 
1008 	neRigidBody * CreateRigidBody();
1009 
1010 	neRigidBody * CreateRigidParticle();
1011 
1012 	neAnimatedBody * CreateAnimatedBody();
1013 
1014 	void FreeRigidBody(neRigidBody * body);
1015 
1016 	void FreeAnimatedBody(neAnimatedBody * body);
1017 
1018 	neCollisionTable * GetCollisionTable();
1019 
1020 	/*
1021 		Material managment functions
1022 	*/
1023 
1024 	bool SetMaterial(s32 index, f32 friction, f32 restitution);
1025 
1026 	bool GetMaterial(s32 index, f32& friction, f32& restitution);
1027 
1028 	/*
1029 		Advancing the simulation
1030 	*/
1031 
1032 	void Advance(f32 sec, s32 nSteps = 1, nePerformanceReport * perfReport = NULL);
1033 
1034 	void Advance(f32 sec, f32 minTimeStep, f32 maxTimeStep, nePerformanceReport * perfReport = NULL);
1035 
1036 	/*
1037 		Terrain setup function
1038 	*/
1039 
1040 	void SetTerrainMesh(neTriangleMesh * tris);
1041 
1042 	void FreeTerrainMesh();
1043 
1044 	/*
1045 		Constraint related
1046 	*/
1047 
1048 	neJoint * CreateJoint(neRigidBody * bodyA);
1049 
1050 	neJoint * CreateJoint(neRigidBody * bodyA, neRigidBody * bodyB);
1051 
1052 	neJoint * CreateJoint(neRigidBody * bodyA, neAnimatedBody * bodyB);
1053 
1054 	void FreeJoint(neJoint * joint);
1055 
1056 	/*
1057 		Others
1058 	*/
1059 	neV3 Gravity();
1060 
1061 	void Gravity(const neV3 & gravity);
1062 
1063 	void SetBreakageCallback(neBreakageCallback * cb);
1064 
1065 	neBreakageCallback * GetBreakageCallback();
1066 
1067 	void SetCollisionCallback(neCollisionCallback * cb);
1068 
1069 	neCollisionCallback * GetCollisionCallback();
1070 
1071 	void SetTerrainTriangleQueryCallback(neTerrainTriangleQueryCallback * cb);
1072 
1073 	neTerrainTriangleQueryCallback * GetTerrainTriangleQueryCallback();
1074 
1075 	void SetCustomCDRB2RBCallback(neCustomCDRB2RBCallback * cb);
1076 
1077 	neCustomCDRB2RBCallback * GetCustomCDRB2RBCallback();
1078 
1079 	void SetCustomCDRB2ABCallback(neCustomCDRB2ABCallback * cb);
1080 
1081 	neCustomCDRB2ABCallback * GetCustomCDRB2ABCallback();
1082 
1083 	void SetLogOutputCallback(neLogOutputCallback * cb);
1084 
1085 	neLogOutputCallback * GetLogOutputCallback();
1086 
1087 	void SetLogOutputLevel(LOG_OUTPUT_LEVEL lvl = LOG_OUTPUT_LEVEL_FULL);
1088 
1089 	neSimulatorSizeInfo GetCurrentSizeInfo();
1090 
1091 	neSimulatorSizeInfo GetStartSizeInfo();
1092 
1093 	void GetMemoryAllocated(s32 & memoryAllocated);
1094 };
1095 
1096 
1097 /****************************************************************************
1098 *
1099 *	Tokamak Game Physics SDK
1100 *
1101 *	Misc. helper functions
1102 *
1103 *
1104 *
1105 ****************************************************************************/
1106 
1107 neV3 TOKAMAK_API neBoxInertiaTensor(f32 width, f32 height, f32 depth, f32 mass);
1108 
1109 neV3 TOKAMAK_API neBoxInertiaTensor(const neV3 & boxSize, f32 mass);
1110 
1111 neV3 TOKAMAK_API neSphereInertiaTensor(f32 diameter, f32 mass);
1112 
1113 neV3 TOKAMAK_API neCylinderInertiaTensor(f32 diameter, f32 height, f32 mass);
1114 
1115 #endif//TOKAMAK_H
1116