From: <me...@us...> - 2009-11-27 21:57:58
|
Revision: 2759 http://ogreaddons.svn.sourceforge.net/ogreaddons/?rev=2759&view=rev Author: melven2 Date: 2009-11-27 21:57:51 +0000 (Fri, 27 Nov 2009) Log Message: ----------- added a destructor callback for OgreNewt::Joint and OgreNewt::Body (because these can be destroyed indirectly through newton callbacks!) Modified Paths: -------------- branches/ogrenewt/newton20/inc/OgreNewt.h branches/ogrenewt/newton20/inc/OgreNewt_Body.h branches/ogrenewt/newton20/inc/OgreNewt_Joint.h branches/ogrenewt/newton20/inc/OgreNewt_Prerequisites.h branches/ogrenewt/newton20/inc/OgreNewt_Vehicle.h branches/ogrenewt/newton20/src/OgreNewt_Body.cpp branches/ogrenewt/newton20/src/OgreNewt_PlayerController.cpp Modified: branches/ogrenewt/newton20/inc/OgreNewt.h =================================================================== --- branches/ogrenewt/newton20/inc/OgreNewt.h 2009-11-27 21:08:26 UTC (rev 2758) +++ branches/ogrenewt/newton20/inc/OgreNewt.h 2009-11-27 21:57:51 UTC (rev 2759) @@ -66,6 +66,7 @@ \section new New in this version New in this version + - added a destructor callback for OgreNewt::Joint and OgreNewt::Body (because these can be destroyed indirectly through newton callbacks!) - removed CollisionTools::CollisionCalculateAABB (because there's col->getAABB() ) and added a function to calculate the correct AABB CollisionTools::CollisionCalculateFittingAABB - ConvexCast: Modified: branches/ogrenewt/newton20/inc/OgreNewt_Body.h =================================================================== --- branches/ogrenewt/newton20/inc/OgreNewt_Body.h 2009-11-27 21:08:26 UTC (rev 2758) +++ branches/ogrenewt/newton20/inc/OgreNewt_Body.h 2009-11-27 21:57:51 UTC (rev 2759) @@ -35,7 +35,7 @@ this class represents a NewtonBody rigid body! */ //! main class for all Rigid Bodies in the system. -class _OgreNewtExport Body +class _OgreNewtExport Body : public _DestructorCallback<Body> { public: //! custom force callback. Modified: branches/ogrenewt/newton20/inc/OgreNewt_Joint.h =================================================================== --- branches/ogrenewt/newton20/inc/OgreNewt_Joint.h 2009-11-27 21:08:26 UTC (rev 2758) +++ branches/ogrenewt/newton20/inc/OgreNewt_Joint.h 2009-11-27 21:57:51 UTC (rev 2759) @@ -25,7 +25,7 @@ /*! this class is inherited by all other specific joint types. */ -class _OgreNewtExport Joint +class _OgreNewtExport Joint : public _DestructorCallback<Joint> { public: Modified: branches/ogrenewt/newton20/inc/OgreNewt_Prerequisites.h =================================================================== --- branches/ogrenewt/newton20/inc/OgreNewt_Prerequisites.h 2009-11-27 21:08:26 UTC (rev 2758) +++ branches/ogrenewt/newton20/inc/OgreNewt_Prerequisites.h 2009-11-27 21:57:51 UTC (rev 2759) @@ -79,6 +79,64 @@ class CollisionSerializer; class ConvexCollision; class Debugger; + + + //! helper class: OgreNewt-classes can derive from this class to implement a destructor-callback + /*! + * Consider the following example: + * You delete a body thats part of joint, so newton deletes the joint, then you could still have a pointer to that joint. Using this pointer will fail, + * thats why you need a way to get to know, when an object gets deleted... + */ + template<class DerivedClass> + class _DestructorCallback + { + public: + //! destructor callback + /*! + * This function is called, when the object is destroyed. It's only argument is a pointer to the instance currently destroyed + * @warning the pointer to the destroyed class instance is already invalid (the class is already destroyed!) + */ + typedef boost::function<void(DerivedClass*)> DestructorCallbackFunction; + + //! constructor + _DestructorCallback() : m_callback(NULL) {} + + //! destructor + virtual ~_DestructorCallback() + { + if( m_callback ) + m_callback((DerivedClass*)(this)); + } + + //! remove any destructor callback + void removeDestructorCallback() {m_callback = NULL;} + + //! set the destructor callback + /*! + * + * This specifies a custom callback that's called when this class is destroyed. 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: + * setDestructorCallback( &myCallbackFunction ); + * + * If you want to bind to a class member, you also need to pass a pointer to the class itself, using the boost::bind system, like so: + * setDestructorCallback( boost::bind( &MyClass::myCallback, (MyClass*)classInstance, _1 ) ); (from outside the class) or: + * setDestructorCallback( boost::bind( &MyClass::myCallback, this, _1 ) ); (from inside the class). + * + * You can also use: + * setDestructorCallback<>( &MyClass::myCallback, (MyClass*)classInstance ); (from outside the class) or: + * setDestructorCallback<>( &MyClass::myCallback, this ); (from inside the class). + * Note: Notice the "<>" after the function name. + * + */ + void setDestructorCallback( DestructorCallbackFunction fun ) { m_callback = fun; } + template<class c> void setDestructorCallback( boost::function<void(c*, DerivedClass*)> callback, c *instancedClassPointer ) + { + setDestructorCallback( boost::bind(callback, instancedClassPointer, _1) ); + } + private: + DestructorCallbackFunction m_callback; + + }; } #endif Modified: branches/ogrenewt/newton20/inc/OgreNewt_Vehicle.h =================================================================== --- branches/ogrenewt/newton20/inc/OgreNewt_Vehicle.h 2009-11-27 21:08:26 UTC (rev 2758) +++ branches/ogrenewt/newton20/inc/OgreNewt_Vehicle.h 2009-11-27 21:57:51 UTC (rev 2759) @@ -25,7 +25,7 @@ /*! this class represents a basic vehicle, meant to be inherited by the user, with functionality added. */ - class _OgreNewtExport Vehicle + class _OgreNewtExport Vehicle : public _DestructorCallback<Vehicle> { public: Modified: branches/ogrenewt/newton20/src/OgreNewt_Body.cpp =================================================================== --- branches/ogrenewt/newton20/src/OgreNewt_Body.cpp 2009-11-27 21:08:26 UTC (rev 2758) +++ branches/ogrenewt/newton20/src/OgreNewt_Body.cpp 2009-11-27 21:57:51 UTC (rev 2759) @@ -351,9 +351,9 @@ getPositionOrientation( bodypos, bodyorient ); Ogre::Vector3 localMassCenter = getCenterOfMass(); - Ogre::Vector3 globalMassCenter = bodyorient * localMassCenter; + Ogre::Vector3 globalMassCenter = bodypos + bodyorient * localMassCenter; - Ogre::Vector3 topoint = pos - bodypos - globalMassCenter; + Ogre::Vector3 topoint = pos - globalMassCenter; Ogre::Vector3 torque = topoint.crossProduct( force ); addForce( force ); Modified: branches/ogrenewt/newton20/src/OgreNewt_PlayerController.cpp =================================================================== --- branches/ogrenewt/newton20/src/OgreNewt_PlayerController.cpp 2009-11-27 21:08:26 UTC (rev 2758) +++ branches/ogrenewt/newton20/src/OgreNewt_PlayerController.cpp 2009-11-27 21:57:51 UTC (rev 2759) @@ -265,15 +265,18 @@ Ogre::Quaternion ori; Ogre::Real invMass; Ogre::Vector3 invInertia; - Ogre::Vector3 frontDir, upDir, strafeDir; + Ogre::Vector3 localFrontDir, localUpDir, localStrafeDir, globalFrontDir, globalUpDir, globalStrafeDir; m_body->getInvMass(invMass, invInertia); m_body->getPositionOrientation(pos,ori); Ogre::Quaternion localFrameRotation = m_localFrame.extractQuaternion(); - frontDir = localFrameRotation * Ogre::Vector3::NEGATIVE_UNIT_Z; - upDir = localFrameRotation * Ogre::Vector3::UNIT_Y; - strafeDir = localFrameRotation * Ogre::Vector3::UNIT_X; + localFrontDir = localFrameRotation * Ogre::Vector3::NEGATIVE_UNIT_Z; + localUpDir = localFrameRotation * Ogre::Vector3::UNIT_Y; + localStrafeDir = localFrameRotation * Ogre::Vector3::UNIT_X; + globalFrontDir = ori*localFrontDir; + globalUpDir = ori*localUpDir; + globalStrafeDir = ori*localStrafeDir; @@ -283,8 +286,7 @@ // if the body has rotated by some amount, there will be a plane of rotation - Ogre::Vector3 realUp = ori*(localFrameRotation*Ogre::Vector3::UNIT_Y); - Ogre::Vector3 lateralDir = realUp.crossProduct(upDir); + Ogre::Vector3 lateralDir = globalUpDir.crossProduct(localUpDir); Ogre::Real mag = lateralDir.length(); if( mag > 1.0e-3f) { @@ -297,14 +299,14 @@ // in theory only one correction is needed, but this produces instability as the body may move sideway. // a lateral correction prevent this from happening. - Ogre::Vector3 frontDir = lateralDir.crossProduct(upDir); + Ogre::Vector3 frontDir = lateralDir.crossProduct(globalUpDir); addAngularRow(Ogre::Radian(0), lateralDir); } else { // if the angle error is very small then two angular correction along the plane axis do the trick - addAngularRow( Ogre::Radian(0), strafeDir ); - addAngularRow( Ogre::Radian(0), frontDir ); + addAngularRow( Ogre::Radian(0), globalStrafeDir ); + addAngularRow( Ogre::Radian(0), globalFrontDir ); } @@ -313,7 +315,7 @@ if( m_playerState == PS_ONLAND ) { Ogre::Vector3 vel = m_body->getVelocity(); - Ogre::Vector3 desiredVel = frontDir* m_forwardSpeed + upDir * (vel.dotProduct(upDir)) + strafeDir * m_sideSpeed; + Ogre::Vector3 desiredVel = globalFrontDir* m_forwardSpeed + globalUpDir * (vel.dotProduct(globalUpDir)) + globalStrafeDir * m_sideSpeed; m_body->setVelocity(desiredVel); } @@ -525,7 +527,7 @@ Ogre::Vector3 newPos; newPos = castStart + (castTarget - castStart)*dist - step + upDir * m_kinematicCushion; - m_body->setPositionOrientation(pos, ori); + m_body->setPositionOrientation(newPos, ori); Ogre::Vector3 floorNormal = allBodyConvexCast.getInfoAt(0).mContactNormal; @@ -596,7 +598,7 @@ allBodyConvexCast2.go(m_bodyFloorSensorShape, castStart2, ori, castTarget2, 1, threadIndex, filterBodies); - if( distanceToFirstHit >= allBodyConvexCast2.getDistanceToFirstHit() && allBodyConvexCast2.getContactsCount() > 0 ) + if( distanceToFirstHit >= allBodyConvexCast2.getDistanceToFirstHit() || allBodyConvexCast2.getContactsCount() == 0 ) { setPlayerState(PS_ONILLEGALRAMP); } @@ -623,7 +625,7 @@ castStart3 = pos + step + upDir*(m_stairHeight - m_kinematicCushion); castTarget3 = castStart3 - upDir*2.0f * m_stairHeight; - allBodyConvexCast3.go(m_bodyFloorSensorShape, castStart3, ori, castTarget3, 1, threadIndex, filterBodies); + allBodyConvexCast3.go(m_bodyFloorSensorShape, castStart3, ori, castTarget3, 1, threadIndex); contactCount = allBodyConvexCast3.getContactsCount(); if( contactCount > 0 ) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |