Project

General

Profile

SO3Engine
OgreNewt_Body.h
Go to the documentation of this file.
1/*
2 OgreNewt Library
3
4 Ogre implementation of Newton Game Dynamics SDK
5
6 OgreNewt basically has no license, you may use any or all of the library however you desire... I hope it can help you in any way.
7
8
9 please note that the "boost" library files included here are not of my creation, refer to those files and boost.org for information.
10
11
12 by Walaber
13 some changes by melven
14
15 */
16
17#ifndef _INCLUDE_OGRENEWT_BODY
18#define _INCLUDE_OGRENEWT_BODY
19
21#include "OgreNewt_MaterialID.h"
22#include "OgreNewt_Collision.h"
23#include "CustomTriggerManager.h"
24
25
26// OgreNewt namespace. all functions and classes use this namespace.
27namespace OgreNewt
28{
29 /*
30 CLASS DEFINITION:
31
32 Body
33
34 USE:
35 this class represents a NewtonBody rigid body!
36 */
38 class _OgreNewtExport Body : public _DestructorCallback<Body>
39 {
40 public:
42
49 typedef std::function<void(OgreNewt::Body*, Ogre::Real timeStep, int threadIndex)> ForceCallback;
50
51 typedef std::function<void(OgreNewt::Body*)> TriggerEnterCallback;
52 typedef std::function<void(OgreNewt::Body*)> TriggerInsideCallback;
53 typedef std::function<void(OgreNewt::Body*)> TriggerExitCallback;
54
55
57 /*
58 this function pointer, when set, is called from updateNode to notify the application
59 the this node the function is controlling has being modified.
60 The application can use this function to re calculate relative position of child nodes, or any other depended transform.
61
62 You can set this as the by using the setnNodeUpdateNotify() function.
63 Using std::function means OgreNewt can now accept pointers to member functions of specific classes.
64 */
65 typedef std::function<void(OgreNewt::Body*)> NodeUpdateNotifyCallback;
66
67
68#if 0
70
77 //typedef std::function<void(OgreNewt::Body*, const Ogre::Quaternion&, const Ogre::Vector3&, int threadIndex)> TransformCallback;
78 //typedef std::function<void(OgreNewt::Body*, int threadIndex)> TransformCallback;
79#endif
80
81
83
91 typedef std::function<bool(dLong, OgreNewt::Body*, const Ogre::Quaternion&, const Ogre::Vector3&, Ogre::Plane&)> buoyancyPlaneCallback;
92
94
100 Body(World* const W, const OgreNewt::CollisionPtr& col, int bodytype = 0, bool trigger = false);
101
103 ~Body();
104
106
110#ifndef OGRENEWT_NO_OGRE_ANY
111 void setUserData(const Ogre::Any& data) { m_userdata = data; }
112#else
113 void setUserData( void* data ) { m_userdata = data; }
114#endif
115
117#ifndef OGRENEWT_NO_OGRE_ANY
118 const Ogre::Any& getUserData() const { return m_userdata; }
119#else
120 void* getUserData() const { return m_userdata; }
121#endif
122
124
127 NewtonBody* getNewtonBody() const { return m_body; }
128
130
133 Ogre::Node* getOgreNode() const { return m_node; }
134
136 OgreNewt::World* const getWorld() const { return m_world; }
137
139
143 void setType(int type) { m_type = type; }
144
146 int getType() const { return m_type; }
147
149
152 void attachNode(Ogre::Node* node);
153
154 void enableSimulation(bool state);
155
157
161 void setStandardForceCallback();
162
164 /*
165 This specifies a custom callback to use for applying forces to a body. if you are using a standard non-member function, or a static member function, you can simply pass a pointer to the function here.. like this:
166 setCustomForceAndTorqueCallback( &myCallbackFunction );
167
168 If you want to bind to a class member, you also need to pass a pointer to the class itself, using the std::bind system, like so:
169 setCustomForceAndTorqueCallback( std::bind( &MyClass::myCallback, (MyClass*)classInstance, std::placeholders::_1 ) ); (from outside the class) or:
170 setCustomForceAndTorqueCallback( std::bind( &MyClass::myCallback, this, std::placeholders::_1 ) ); (from inside the class).
171
172 You can also use:
173 setCustomForceAndTorqueCallback<>( &MyClass::myCallback, (MyClass*)classInstance ); (from outside the class) or:
174 setCustomForceAndTorqueCallback<>( &MyClass::myCallback, this ); (from inside the class).
175 Note: Notice the "<>" after the function name.
176 */
177 void setCustomForceAndTorqueCallback(ForceCallback callback);
178 template<class c> void setCustomForceAndTorqueCallback(std::function<void(c*, Body*, float, int)> callback, c *instancedClassPointer)
179 {
180 setCustomForceAndTorqueCallback(std::bind(callback, instancedClassPointer, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
181 }
182
183 void setTriggerEnterCallback(TriggerEnterCallback callback);
184 template<class c> void setTriggerEnterCallback(std::function<void(c*, Body*)> callback, c *instancedClassPointer)
185 {
186 setTriggerEnterCallback(std::bind(callback, instancedClassPointer, std::placeholders::_1));
187 }
188
189 void setTriggerInsideCallback(TriggerInsideCallback callback);
190 template<class c> void setTriggerInsideCallback(std::function<void(c*, Body*)> callback, c *instancedClassPointer)
191 {
192 setTriggerInsideCallback(std::bind(callback, instancedClassPointer, std::placeholders::_1));
193 }
194
195 void setTriggerExitCallback(TriggerExitCallback callback);
196 template<class c> void setTriggerExitCallback(std::function<void(c*, Body*)> callback, c *instancedClassPointer)
197 {
198 setTriggerExitCallback(std::bind(callback, instancedClassPointer, std::placeholders::_1));
199 }
200
202 void removeForceAndTorqueCallback() { NewtonBodySetForceAndTorqueCallback(m_body, NULL); m_forcecallback = NULL; }
203
206 {
207 return m_forcecallback;
208 }
209
210
212 /*
213 set a function pointer to be called for function nodeUpdate when the application desires to be notified that this node is bing updated.
214 Control joints like the vehicle an drag dolls use the function to calculate the correct matrix of wheels and body parts.
215 */
216 void setNodeUpdateNotify(NodeUpdateNotifyCallback callback);
217 template<class c> void setNodeUpdateNotify(std::function<void(c*, OgreNewt::Body*)> callback, c *instancedClassPointer)
218 {
219 setNodeUpdateNotify(std::bind(callback, instancedClassPointer, std::placeholders::_1));
220 }
221
223 void removeNodeUpdateNotify() { m_nodeupdatenotifycallback = NULL; }
224
225 void setNodeUpdateJointNotify(NodeUpdateNotifyCallback callback);
226 template<class c> void setNodeUpdateJointNotify(std::function<void(c*, OgreNewt::Body*)> callback, c *instancedClassPointer)
227 {
228 setNodeUpdateJointNotify(std::bind(callback, instancedClassPointer, std::placeholders::_1));
229 }
230
232 void removeNodeUpdateJointNotify() { m_nodeupdatejointnotifycallback = NULL; }
233
235
241 void setPositionOrientation(const Ogre::Vector3& pos, const Ogre::Quaternion& orient, int threadIndex = -1);
242
244
250 void setPositionOrientationFromNode(int threadIndex = -1);
251
252 void updatePositionOrientation(const Ogre::Vector3& pos, const Ogre::Quaternion& orient, int threadIndex = -1);
253
254 void setVisualPosition(Ogre::Vector3 pos, Ogre::Quaternion quat);
255
257
262 void setMassMatrix(Ogre::Real mass, const Ogre::Vector3& inertia);
263
264 void setMass(Ogre::Real mass);
265
267
271 void setCenterOfMass(const Ogre::Vector3& centerOfMass)
272 {
273 dVector fvec;
274 fvec.m_x = dFloat(centerOfMass.x);
275 fvec.m_y = dFloat(centerOfMass.y);
276 fvec.m_z = dFloat(centerOfMass.z);
277 NewtonBodySetCentreOfMass(m_body, &fvec.m_x);
278 }
279
281
284 Ogre::Vector3 getCenterOfMass() const;
285
286 Ogre::Vector3 calculateOffset() const;
287
288 Ogre::Vector3 calculateInertialMatrix() const;
289
291
295 void freeze() { NewtonBodySetFreezeState(m_body, 1); }
296
298
301 void unFreeze() { NewtonBodySetFreezeState(m_body, 0); }
302
304 bool isFreezed() { return NewtonBodyGetFreezeState(m_body) != 0; }
305
307
313 {
314 m_matid = ID;
315 NewtonBodySetMaterialGroupID(m_body, m_matid->getID());
316 }
317
319
325 void setContinuousCollisionMode(unsigned state) { NewtonBodySetContinuousCollisionMode(m_body, state); }
326
328 void setJointRecursiveCollision(unsigned state) { NewtonBodySetJointRecursiveCollision(m_body, state); }
329
331
335 void setOmega(const Ogre::Vector3& omega)
336 {
337 dVector fvec;
338 fvec.m_x = dFloat(omega.x);
339 fvec.m_y = dFloat(omega.y);
340 fvec.m_z = dFloat(omega.z);
341 NewtonBodySetOmega(m_body, &fvec.m_x);
342 }
343
345
349 void setVelocity(const Ogre::Vector3& vel);
350
352 void setLinearDamping(Ogre::Real damp) { NewtonBodySetLinearDamping(m_body, dFloat(damp)); }
353
355 void setAngularDamping(const Ogre::Vector3& damp)
356 {
357 dVector fvec;
358 fvec.m_x = dFloat(damp.x);
359 fvec.m_y = dFloat(damp.y);
360 fvec.m_z = dFloat(damp.z);
361 NewtonBodySetAngularDamping(m_body, &fvec.m_x);
362 }
363
365
369 void setCollision(const OgreNewt::CollisionPtr& col);
370
372
375 void setAutoSleep(int flag) { NewtonBodySetAutoSleep(m_body, flag); }
376
378 int getAutoSleep() { return NewtonBodyGetAutoSleep(m_body); }
379
380
381 bool isSleeping() { return NewtonBodyGetSleepState(m_body) != 0; }
382
383 void setSleep()
384 {
385 setVelocity(Ogre::Vector3::ZERO);
386 setOmega(Ogre::Vector3::ZERO);
387 NewtonBodySetSleepState(m_body, 1);
388 }
389
390 void wakeUp()
391 {
392 NewtonBodySetSleepState(m_body, 0);
393
394 // hack to wakeup the bodies
395 dVector fvec;
396 fvec.m_x = dFloat(0.0);
397 fvec.m_y = dFloat(0.0);
398 fvec.m_z = dFloat(0.0);
399 NewtonBodyAddImpulse(m_body, &fvec.m_x, &fvec.m_x);
400 }
401
403 //void setFreezeThreshold( Ogre::Real speed, Ogre::Real omega, int framecount ) { NewtonBodySetFreezeTreshold( m_body, (float)speed, (float)omega, framecount ); }
404
406 const OgreNewt::CollisionPtr& getCollision() const;
407
409 void setScale(const Ogre::Vector3& scale, const Ogre::Quaternion& orient, Ogre::Vector3& pos);
410
412 const OgreNewt::MaterialID* getMaterialGroupID() const;
413
415 int getContinuousCollisionMode() const { return NewtonBodyGetContinuousCollisionMode(m_body); }
416
418 int getJointRecursiveCollision() const { return NewtonBodyGetJointRecursiveCollision(m_body); }
419
421 void getPositionOrientation(Ogre::Vector3& pos, Ogre::Quaternion& orient) const;
422
424 Ogre::Vector3 getPosition() const;
425
427 Ogre::Quaternion getOrientation() const;
428
430
433 void getVisualPositionOrientation(Ogre::Vector3& pos, Ogre::Quaternion& orient) const;
434
436 Ogre::Vector3 getVisualPosition() const;
437
439 Ogre::Quaternion getVisualOrientation() const;
440
442 Ogre::AxisAlignedBox getAABB() const;
443
445 void getMassMatrix(Ogre::Real& mass, Ogre::Vector3& inertia) const;
446
448 Ogre::Real getMass() const;
449
451 Ogre::Vector3 getInertia() const;
452
454 void getInvMass(Ogre::Real& mass, Ogre::Vector3& inertia) const;
455
457 Ogre::Vector3 getOmega() const;
458
460 Ogre::Vector3 getVelocity() const;
461
463 Ogre::Vector3 getForce() const;
464
466 Ogre::Vector3 getTorque() const;
467
469 Ogre::Vector3 getForceAcceleration() const;
470
472 Ogre::Vector3 getTorqueAcceleration() const;
473
475 Ogre::Real getLinearDamping() const { return (Ogre::Real)NewtonBodyGetLinearDamping(m_body); }
476
478 Ogre::Vector3 getAngularDamping() const;
479
481 Ogre::Vector3 calculateInverseDynamicsForce(Ogre::Real timestep, Ogre::Vector3 desiredVelocity);
482
484 //void getFreezeThreshold( Ogre::Real& speed, Ogre::Real& omega ) const { NewtonBodyGetFreezeTreshold( m_body, &speed, &omega ); }
485
487 void addImpulse(const Ogre::Vector3& deltav, const Ogre::Vector3& posit)
488 {
489 dVector fdvec;
490 fdvec.m_x = dFloat(deltav.x);
491 fdvec.m_y = dFloat(deltav.y);
492 fdvec.m_z = dFloat(deltav.z);
493
494 dVector fpvec;
495 fpvec.m_x = dFloat(posit.x);
496 fpvec.m_y = dFloat(posit.y);
497 fpvec.m_z = dFloat(posit.z);
498 NewtonBodyAddImpulse(m_body, &fdvec.m_x, &fpvec.m_x);
499 }
500
502
505 void addForce(const Ogre::Vector3& force)
506 {
507 dVector fvec;
508 fvec.m_x = dFloat(force.x);
509 fvec.m_y = dFloat(force.y);
510 fvec.m_z = dFloat(force.z);
511
512 NewtonBodyAddForce(m_body, &fvec.m_x);
513 }
514
516
519 void addTorque(const Ogre::Vector3& torque)
520 {
521 dVector fvec;
522 fvec.m_x = dFloat(torque.x);
523 fvec.m_y = dFloat(torque.y);
524 fvec.m_z = dFloat(torque.z);
525
526 NewtonBodyAddTorque(m_body, &fvec.m_x);
527 }
528
530
533 void setForce(const Ogre::Vector3& force)
534 {
535 dVector fvec;
536 fvec.m_x = dFloat(force.x);
537 fvec.m_y = dFloat(force.y);
538 fvec.m_z = dFloat(force.z);
539
540 NewtonBodySetForce(m_body, &fvec.m_x);
541 }
542
544
547 void setTorque(const Ogre::Vector3& torque)
548 {
549 dVector fvec;
550 fvec.m_x = dFloat(torque.x);
551 fvec.m_y = dFloat(torque.y);
552 fvec.m_z = dFloat(torque.z);
553
554 NewtonBodySetTorque(m_body, &fvec.m_x);
555 }
556
558 Body* getNext() const;
559
561
566 void addGlobalForce(const Ogre::Vector3& force, const Ogre::Vector3& pos);
567
569
575 void addGlobalForceAccumulate(const Ogre::Vector3& force, const Ogre::Vector3& pos);
576
577 // helper function that adds a force (and resulting torque) to an object in local coordinates.
583 void addLocalForce(const Ogre::Vector3& force, const Ogre::Vector3& pos);
584
586
589 CollisionPrimitiveType getCollisionPrimitiveType() const { return Collision::getCollisionPrimitiveType(getNewtonCollision()); }
590
592
595 NewtonCollision *getNewtonCollision() const { return NewtonBodyGetCollision(m_body); }
596
597#if 0
599
605 void requestNodeUpdate(int threadIndex, bool forceNodeUpdate = false);
606
608 bool isNodeUpdateNeeded() const {return m_nodeupdateneeded;}
609#endif
610
611 /*
613 bool isNodeUpdateNeeded() const {return m_nodeupdateneeded;}
614
616 void setNodeUpdateNeeded(bool state) {m_nodeupdateneeded = state;}
617 */
618
620 void updateNode(Ogre::Real interpolatParam);
621
622 void MoveToPosition(const Ogre::Vector3 &destPos, const Ogre::Real &stiffness, Ogre::Real timestep);
623 void RotateToOrientation(const Ogre::Quaternion &destquat, const Ogre::Real &stiffness, Ogre::Real timestep);
624
625 protected:
626
627 NewtonBody* m_body;
631
632 std::vector<std::pair<Ogre::Vector3, Ogre::Vector3> > m_accumulatedGlobalForces;
633 Ogre::Vector3 m_nodePosit;
634 Ogre::Vector3 m_curPosit;
635 Ogre::Vector3 m_prevPosit;
636 Ogre::Vector3 m_scale;
637 Ogre::Quaternion m_nodeRotation;
638 Ogre::Quaternion m_curRotation;
639 Ogre::Quaternion m_prevRotation;
640
641
642#ifndef OGRENEWT_NO_OGRE_ANY
643 Ogre::Any m_userdata;
644#else
646#endif
647
649 Ogre::Node* m_node;
650 //bool m_nodeupdateneeded;
651
656
659
660 private:
661 CustomTriggerController* m_triggerController;
662 static void _CDECL newtonDestructor(const NewtonBody* body);
663
664 static void _CDECL newtonTransformCallback(const NewtonBody* body, const dFloat* matrix, int threadIndex);
665 static void _CDECL newtonForceTorqueCallback(const NewtonBody* body, dFloat timestep, int threadIndex);
666 void newtonTriggerEnterCallback(NewtonBody* const visitor);
667 void newtonTriggerInsideCallback(NewtonBody* const visitor);
668 void newtonTriggerExitCallback(NewtonBody* const visitor);
669
670 // standard gravity force callback.
671 static void standardForceCallback(Body* me, dFloat timeStep, int threadIndex);
672
673 };
674
675
676
677
678}
679
680#endif
681// _INCLUDE_OGRENEWT_BODY
682
helper class: OgreNewt-classes can derive from this class to implement a destructor-callback
main class for all Rigid Bodies in the system.
CollisionPrimitiveType getCollisionPrimitiveType() const
Returns the Collisiontype for the Collision from this Body.
void setTriggerEnterCallback(std::function< void(c *, Body *)> callback, c *instancedClassPointer)
Ogre::Vector3 m_nodePosit
const Ogre::Any & getUserData() const
retrieve pointer to previously set user data.
void setContinuousCollisionMode(unsigned state)
prevents fast moving bodies from "tunneling" through other bodies.
void setUserData(const Ogre::Any &data)
set user data to connect this class to another.
Ogre::Any m_userdata
bool isFreezed()
is the body freezed?
void setCustomForceAndTorqueCallback(std::function< void(c *, Body *, float, int)> callback, c *instancedClassPointer)
void removeForceAndTorqueCallback()
remove any force callbacks.
OgreNewt::World *const getWorld() const
get a pointer to the OgreNewt::World this body belongs to.
void setAngularDamping(const Ogre::Vector3 &damp)
set the angular damping for the body.
void setMaterialGroupID(const MaterialID *ID)
set the material for the body
void addImpulse(const Ogre::Vector3 &deltav, const Ogre::Vector3 &posit)
get the freeze threshold
int getAutoSleep()
get whether the body should "sleep" when equilibrium is reached.
TriggerInsideCallback m_triggerInsideCallback
void freeze()
freeze the rigid body.
void setNodeUpdateJointNotify(std::function< void(c *, OgreNewt::Body *)> callback, c *instancedClassPointer)
std::function< void(OgreNewt::Body *)> TriggerEnterCallback
void requestNodeUpdate(int threadIndex, bool forceNodeUpdate=false)
Call this to signify that the position/orientation of the attached node needs to be updated.
void setTriggerInsideCallback(std::function< void(c *, Body *)> callback, c *instancedClassPointer)
void setForce(const Ogre::Vector3 &force)
set the force for a body.
ForceCallback m_forcecallback
TriggerEnterCallback m_triggerEnterCallback
Ogre::Vector3 m_scale
Ogre::Vector3 m_prevPosit
void addTorque(const Ogre::Vector3 &torque)
add torque to the body.
void setTriggerExitCallback(std::function< void(c *, Body *)> callback, c *instancedClassPointer)
std::function< void(OgreNewt::Body *)> TriggerExitCallback
void addForce(const Ogre::Vector3 &force)
add force to the body.
NewtonBody * m_body
NodeUpdateNotifyCallback m_nodeupdatejointnotifycallback
Ogre::Node * m_node
int getType() const
get the type set for this body.
std::function< void(OgreNewt::Body *)> NodeUpdateNotifyCallback
node update notify.
Ogre::Quaternion m_curRotation
std::function< void(OgreNewt::Body *, Ogre::Real timeStep, int threadIndex)> ForceCallback
custom force callback.
int getJointRecursiveCollision() const
returns current setting for this body.
void setUserData(void *data)
std::vector< std::pair< Ogre::Vector3, Ogre::Vector3 > > m_accumulatedGlobalForces
World *const m_world
Ogre::Real getLinearDamping() const
get linear damping
void setType(int type)
set the type for this body.
NewtonBody * getNewtonBody() const
get a pointer to the NewtonBody object
void * getUserData() const
const MaterialID * m_matid
TriggerExitCallback m_triggerExitCallback
void setNodeUpdateNotify(std::function< void(c *, OgreNewt::Body *)> callback, c *instancedClassPointer)
NodeUpdateNotifyCallback m_nodeupdatenotifycallback
void setTorque(const Ogre::Vector3 &torque)
set the torque for a body.
void removeNodeUpdateNotify()
remove any transform callbacks.
Ogre::Vector3 m_curPosit
int getContinuousCollisionMode() const
returns current setting for this body.
bool isNodeUpdateNeeded() const
Return if an node update was requested.
void removeNodeUpdateJointNotify()
remove any transform callbacks.
void setOmega(const Ogre::Vector3 &omega)
set an arbitrary omega for the body.
Ogre::Node * getOgreNode() const
get a pointer to the attached Node.
void setLinearDamping(Ogre::Real damp)
set the linear damping for the body.
void setJointRecursiveCollision(unsigned state)
set whether all parent/children pairs connected to this body should be allowed to collide.
OgreNewt::CollisionPtr m_collision
std::function< bool(dLong, OgreNewt::Body *, const Ogre::Quaternion &, const Ogre::Vector3 &, Ogre::Plane &)> buoyancyPlaneCallback
custom transform callback.
Ogre::Quaternion m_prevRotation
ForceCallback getForceTorqueCallback()
returns correct force-torque callback
std::function< void(OgreNewt::Body *)> TriggerInsideCallback
NewtonCollision * getNewtonCollision() const
Returns the Newton Collision for this Body.
void setAutoSleep(int flag)
set whether the body should "sleep" when equilibruim is reached.
Ogre::Quaternion m_nodeRotation
void setCenterOfMass(const Ogre::Vector3 &centerOfMass)
set the body's center of mass
void unFreeze()
unfreeze the rigid body.
represents a shape for collision detection
represents a material
represents a physics world.