Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreRefAppApplicationObject.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of the OGRE Reference Application, a layer built
00004 on top of OGRE(Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 
00026 #include "OgreRefAppApplicationObject.h"
00027 #include "OgreRefAppWorld.h"
00028 #include "ode/collision.h"
00029 #include "OgreControllerManager.h"
00030 #include "OgreStringConverter.h"
00031 #include "OgreRoot.h"
00032 
00033 namespace OgreRefApp
00034 {
00035     //-------------------------------------------------------------------------
00036     ApplicationObject::ApplicationObject(const String& name)
00037     {
00038         mSceneNode = 0;
00039         mEntity = 0;
00040         mOdeBody = 0;
00041         mDynamicsEnabled = false;
00042         mReenableIfInteractedWith = false;
00043         mCollisionEnabled = true;
00044         mSoftness = 0.0;
00045         mBounceCoeffRestitution = 0;
00046         mBounceVelocityThreshold = 0.1;
00047         setFriction(Math::POS_INFINITY);
00048         dMassSetZero(&mMass);
00049 
00050         mDisableTimeEnd = 0;
00051         mDisableTime = 3000.0f; // millisenconds
00052         mAngularVelDisableThreshold = 1.0f;
00053         mLinearVelDisableThreshold = 1.0f;
00054 
00055 
00056 
00057     }
00058     //-------------------------------------------------------------------------
00059     ApplicationObject::~ApplicationObject()
00060     {
00061         SceneManager* sm = World::getSingleton().getSceneManager();
00062         if (mSceneNode)
00063         {
00064             sm->destroySceneNode(mSceneNode->getName());
00065             mSceneNode = 0;
00066         }
00067 
00068         // TODO destroy entity
00069 
00070         // Destroy mass
00071         if (mOdeBody)
00072         {
00073             delete mOdeBody;
00074             mOdeBody = 0;
00075         }
00076 
00077         // Destroy collision proxies
00078         CollisionProxyList::iterator i, iend;
00079         iend = mCollisionProxies.end();
00080         for (i = mCollisionProxies.begin(); i != iend; ++i)
00081         {
00082             delete (*i);
00083         }
00084 
00085 
00086 
00087     }
00088     //-------------------------------------------------------------------------
00089     void ApplicationObject::setPosition(const Vector3& vec)
00090     {
00091         setPosition(vec.x, vec.y, vec.z);
00092     }
00093     //-------------------------------------------------------------------------
00094     void ApplicationObject::setPosition(Real x, Real y, Real z)
00095     {
00096         mSceneNode->setPosition(x, y, z);
00097         if (isDynamicsEnabled() && mOdeBody)
00098             mOdeBody->setPosition(x, y, z);
00099         updateCollisionProxies();
00100     }
00101     //-------------------------------------------------------------------------
00102     void ApplicationObject::setOrientation(const Quaternion& orientation)
00103     {
00104         mSceneNode->setOrientation(orientation);
00105         if (isDynamicsEnabled() && mOdeBody)
00106         {
00107             dReal dquat[4] = {orientation.w, orientation.x, orientation.y, orientation.z };
00108             mOdeBody->setQuaternion(dquat);
00109         }
00110         updateCollisionProxies();
00111     }
00112     //-------------------------------------------------------------------------
00113     const Vector3& ApplicationObject::getPosition(void)
00114     {
00115         return mSceneNode->getPosition();
00116     }
00117     //-------------------------------------------------------------------------
00118     const Quaternion& ApplicationObject::getOrientation(void)
00119     {
00120         return mSceneNode->getOrientation();
00121     }
00122     //-------------------------------------------------------------------------
00123     void ApplicationObject::setDynamicsDisableThreshold(Real linearSq, 
00124         Real angularSq, Real overTime)
00125     {
00126         mLinearVelDisableThreshold = linearSq;
00127         mAngularVelDisableThreshold = angularSq;
00128         mDisableTime = overTime * 1000;
00129     }
00130     //-------------------------------------------------------------------------
00131     void ApplicationObject::_updateFromDynamics()
00132     {
00133         if (!mOdeBody)
00134         {
00135             return;
00136         }
00137         // Update dynamics enabled flag from dynamics (may have been reenabled)
00138         if (mReenableIfInteractedWith)
00139         {
00140             mDynamicsEnabled = mOdeBody->isEnabled() == 0 ? false : true;
00141         }
00142 
00143         if (mDynamicsEnabled)
00144         {
00145             // Get position & rotation from ODE
00146             const dReal* pos = mOdeBody->getPosition();
00147             const dReal* quat = mOdeBody->getQuaternion();
00148 
00149             mSceneNode->setPosition((Real)pos[0], (Real)pos[1], (Real)pos[2]);
00150             mSceneNode->setOrientation((Real)quat[0], (Real)quat[1], 
00151                 (Real)quat[2], (Real)quat[3]);
00152 
00153             updateCollisionProxies();
00154 
00155             // Check to see if object has stabilised, if so turn off dynamics
00156             // to save processor time
00157             // NB will be reenabled if interacted with
00158             
00159             if (this->getLinearVelocity().squaredLength() <= mLinearVelDisableThreshold
00160                 && this->getAngularVelocity().squaredLength() <= mAngularVelDisableThreshold)
00161             {
00162                 if (mDisableTimeEnd > 0.0f)
00163                 {
00164                     // We're counting, check disable time
00165                     if (Root::getSingleton().getTimer()->getMilliseconds() > mDisableTimeEnd)
00166                     {
00167                         this->setDynamicsEnabled(false, true);
00168                         //LogManager::getSingleton().logMessage(mEntity->getName() + " disabled");
00169                         mDisableTimeEnd = 0.0f;
00170                     }
00171 
00172                 }
00173                 else 
00174                 {
00175                     // We're not counting down yet, so start the count
00176                     // NB is mDisableTime = 0 we never disable
00177                     if (mDisableTime > 0)
00178                     {
00179                         mDisableTimeEnd = Root::getSingleton().getTimer()->getMilliseconds() + mDisableTime;
00180                         //LogManager::getSingleton().logMessage("Starting countdown...");
00181                     }
00182                 }
00183             }
00184             else
00185             {
00186                 // We're still moving
00187                 mDisableTimeEnd = 0.0f;
00188             }
00189 
00190         }
00191     }
00192     //-------------------------------------------------------------------------
00193     bool ApplicationObject::isCollisionEnabled(void)
00194     {
00195         return mCollisionEnabled;
00196     }
00197     //-------------------------------------------------------------------------
00198     bool ApplicationObject::isDynamicsEnabled(void)
00199     {
00200         return (mDynamicsEnabled || mReenableIfInteractedWith);
00201     }
00202     //-------------------------------------------------------------------------
00203     void ApplicationObject::setCollisionEnabled(bool enabled)
00204     {
00205         mCollisionEnabled = enabled;
00206         setEntityQueryFlags();
00207     }
00208     //-------------------------------------------------------------------------
00209     void ApplicationObject::setDynamicsEnabled(bool enabled, bool reEnableOnInteraction)
00210     {
00211         
00212         mDynamicsEnabled = enabled;
00213         mReenableIfInteractedWith = reEnableOnInteraction;
00214 
00215         // World must keep an eye on enabled or potentially reenabled objects
00216         World::getSingleton()._notifyDynamicsStateForObject(this, 
00217             mDynamicsEnabled || mReenableIfInteractedWith);
00218         
00219         if (mDynamicsEnabled)
00220         {
00221             // Ensure body is synced
00222             mOdeBody->enable();
00223         }
00224         else if (mOdeBody)
00225         {
00226             mOdeBody->disable();
00227         }
00228         // Set properties
00229         if (mDynamicsEnabled || mReenableIfInteractedWith)
00230         {
00231             const Vector3& pos = getPosition();
00232             mOdeBody->setPosition(pos.x, pos.y, pos.z);
00233             const Quaternion& q = getOrientation();
00234             dReal dquat[4] = {q.w, q.x, q.y, q.z };
00235             mOdeBody->setQuaternion(dquat);
00236         }
00237     }
00238     //-------------------------------------------------------------------------
00239     void ApplicationObject::addForce(const Vector3& direction, const Vector3& atPosition)
00240     {
00241         addForce(direction.x, direction.y, direction.z, 
00242             atPosition.x, atPosition.y, atPosition.z);
00243     }
00244     //-------------------------------------------------------------------------
00245     void ApplicationObject::addForce(Real dir_x, Real dir_y, Real dir_z, 
00246         Real pos_x, Real pos_y, Real pos_z)
00247     {
00248         assert (mOdeBody && "No dynamics body set up for this object");
00249         mOdeBody->addRelForceAtRelPos(dir_x, dir_y, dir_z, 
00250             pos_x, pos_y, pos_z);
00251 
00252     }
00253     //-------------------------------------------------------------------------
00254     void ApplicationObject::addForceWorldSpace(const Vector3& direction, const Vector3& atPosition)
00255     {
00256         addForceWorldSpace(direction.x, direction.y, direction.z, 
00257             atPosition.x, atPosition.y, atPosition.z);
00258     }
00259     //-------------------------------------------------------------------------
00260     void ApplicationObject::addForceWorldSpace(Real dir_x, Real dir_y, Real dir_z, 
00261         Real pos_x, Real pos_y, Real pos_z)
00262     {
00263         assert (mOdeBody && "No dynamics body set up for this object");
00264         mOdeBody->addForceAtPos(dir_x, dir_y, dir_z, 
00265             pos_x, pos_y, pos_z);
00266     }
00267     //-------------------------------------------------------------------------
00268     void ApplicationObject::addTorque(const Vector3& direction)
00269     {
00270         addTorque(direction.x, direction.y, direction.z);
00271     }
00272     //-------------------------------------------------------------------------
00273     void ApplicationObject::addTorque(Real x, Real y, Real z)
00274     {
00275         assert (mOdeBody && "No dynamics body set up for this object");
00276         mOdeBody->addRelTorque(x, y, z);
00277     }
00278     //-------------------------------------------------------------------------
00279     void ApplicationObject::addTorqueWorldSpace(const Vector3& direction)
00280     {
00281         addTorqueWorldSpace(direction.x, direction.y, direction.z);
00282     }
00283     //-------------------------------------------------------------------------
00284     void ApplicationObject::addTorqueWorldSpace(Real x, Real y, Real z)
00285     {
00286         assert (mOdeBody && "No dynamics body set up for this object");
00287         mOdeBody->addTorque(x, y, z);
00288     }
00289     //-------------------------------------------------------------------------
00290     SceneNode* ApplicationObject::getSceneNode(void)
00291     {
00292         return mSceneNode;
00293     }
00294     //-------------------------------------------------------------------------
00295     Entity* ApplicationObject::getEntity(void)
00296     {
00297         return mEntity;
00298     }
00299     //-------------------------------------------------------------------------
00300     dBody* ApplicationObject::getOdeBody(void)
00301     {
00302         if (isDynamicsEnabled())
00303         {
00304             return mOdeBody;
00305         }
00306         else
00307         {
00308             // dynamics are disabled
00309             return 0;
00310         }
00311     }
00312     //-------------------------------------------------------------------------
00313     void ApplicationObject::updateCollisionProxies(void)
00314     {
00315         CollisionProxyList::iterator i, iend;
00316         iend = mCollisionProxies.end();
00317         for (i = mCollisionProxies.begin(); i != iend; ++i)
00318         {
00319             // set from node
00320             const Vector3& pos = mSceneNode->getPosition();
00321             dGeom* pProxy = *i;
00322             pProxy->setPosition(pos.x, pos.y, pos.z);
00323             const Quaternion& orientation = mSceneNode->getOrientation();
00324             // Hmm, no setQuaternion on proxy
00325             // Do a conversion
00326             dReal dquat[4] = {orientation.w, orientation.x, orientation.y, orientation.z };
00327             dMatrix3 dm3;
00328             memset(dm3, 0, sizeof(dMatrix3));
00329             dQtoR(dquat, dm3);
00330             pProxy->setRotation(dm3); 
00331             
00332         }
00333 
00334     }
00335     //-------------------------------------------------------------------------
00336     bool ApplicationObject::testCollide(ApplicationObject* otherObj)
00337     {
00338         bool collided = false;
00339         dContactGeom contactGeom;
00340         dGeom *o1, *o2;
00341         CollisionProxyList::const_iterator proxy1, proxy2, proxy1end, proxy2end;
00342         proxy1end = mCollisionProxies.end();
00343         proxy2end = otherObj->mCollisionProxies.end();
00344 
00345         CollisionInfo collInfo;
00346 
00347         for (proxy1 = mCollisionProxies.begin(); proxy1 != proxy1end; ++proxy1)
00348         {
00349             for (proxy2 = otherObj->mCollisionProxies.begin(); proxy2 != proxy2end; ++proxy2)
00350             {
00351                 o1 = *proxy1;
00352                 o2 = *proxy2;
00353                 int numc = dCollide(o1->id(), o2->id(), 0, &contactGeom, sizeof(dContactGeom));
00354                 if (numc)
00355                 {
00356                     // Create contact joints if either object is dynamics simulated
00357                     // If one is not, then sim will not affect it anyway, it will be fixed
00358                     // However if one is enabled, we need the contact joint
00359                     if (this->isDynamicsEnabled() || otherObj->isDynamicsEnabled())
00360                     {
00361                         // We use the most agressive parameters from both objects for the contact
00362                         dContact contact;
00363                         Real bounce, velThresh, softness;
00364                         // Use the highest coeff of restitution from both objects
00365                         bounce = std::max(this->getBounceRestitutionValue(), 
00366                                 otherObj->getBounceRestitutionValue());
00367                         // Use the lowest velocity threshold from both objects
00368                         velThresh = std::min(this->getBounceVelocityThreshold(),
00369                                 otherObj->getBounceVelocityThreshold());
00370                         // Set flags
00371                         contact.surface.mode = dContactBounce | dContactApprox1;
00372                         contact.surface.bounce = bounce;
00373                         contact.surface.bounce_vel = velThresh;
00374 
00375                         softness = this->getSoftness() + otherObj->getSoftness();
00376                         if (softness > 0)
00377                         {
00378                             contact.surface.mode |= dContactSoftCFM;
00379                             contact.surface.soft_cfm = softness;
00380                         }
00381                         
00382                         // Set friction to min of 2 objects
00383                         // Note that ODE dInfinity == Math::POS_INFINITY
00384                         contact.surface.mu = std::min(this->getFriction(), otherObj->getFriction());
00385                         contact.surface.mu2 = 0;
00386                         contact.geom = contactGeom;
00387                         dContactJoint contactJoint(
00388                             World::getSingleton().getOdeWorld()->id(), 
00389                             World::getSingleton().getOdeContactJointGroup()->id(), 
00390                             &contact);
00391 
00392                         // Get ODE bodies
00393                         // May be null, if so use 0 (immovable) body ids
00394                         dBody *b1, *b2;
00395                         dBodyID bid1, bid2;
00396                         bid1 = bid2 = 0;
00397                         b1 = this->getOdeBody();
00398                         b2 = otherObj->getOdeBody();
00399                         if (b1) bid1 = b1->id();
00400                         if (b2) bid2 = b2->id();
00401                         contactJoint.attach(bid1, bid2);
00402                     }
00403 
00404                     // Tell both objects about the collision
00405                     collInfo.position.x = contactGeom.pos[0];
00406                     collInfo.position.y = contactGeom.pos[1];
00407                     collInfo.position.z = contactGeom.pos[2];
00408                     collInfo.normal.x = contactGeom.normal[0];
00409                     collInfo.normal.y = contactGeom.normal[1];
00410                     collInfo.normal.z = contactGeom.normal[2];
00411                     collInfo.penetrationDepth = contactGeom.depth;
00412                     this->_notifyCollided(otherObj, collInfo);
00413                     otherObj->_notifyCollided(this, collInfo);
00414 
00415 
00416                     // set return 
00417                     collided = true;
00418                 }
00419             }
00420         }
00421         return collided;
00422 
00423     }
00424     //-------------------------------------------------------------------------
00425     bool ApplicationObject::testCollide(SceneQuery::WorldFragment* wf)
00426     {
00427         switch (wf->fragmentType)
00428         {
00429         case SceneQuery::WFT_NONE:
00430             return false;
00431         case SceneQuery::WFT_PLANE_BOUNDED_REGION:
00432             return testCollidePlaneBounds(wf);
00433         default:
00434             break;
00435         };
00436 
00437         // not handled
00438         return false;
00439     }
00440     //-------------------------------------------------------------------------
00441     bool ApplicationObject::testCollidePlaneBounds(SceneQuery::WorldFragment* wf)
00442     {
00443         bool collided = false;
00444         dContactGeom contactGeom;
00445         dGeom *obj;
00446         CollisionProxyList::const_iterator proxy, proxyend;
00447         proxyend = mCollisionProxies.end();
00448 
00449         std::list<Plane>::const_iterator pi, piend;
00450         piend = wf->planes->end();
00451 
00452         CollisionInfo collInfo;
00453 
00454         for (proxy = mCollisionProxies.begin(); proxy != proxyend; ++proxy)
00455         {
00456             // Hack, simply collide against planes which is facing towards center
00457             // We can't do this properly without mesh collision
00458             obj = *proxy;
00459             Real maxdist = -1.0f;
00460             const Plane* bestPlane = 0;
00461             for (pi = wf->planes->begin(); pi != piend; ++pi)
00462             {
00463                 const Plane *boundPlane = &(*pi);
00464                 Real dist = boundPlane->getDistance(this->getPosition());
00465                 if (dist >= 0.0f)
00466                 {
00467                     dPlane odePlane(0, boundPlane->normal.x, boundPlane->normal.y, boundPlane->normal.z, 
00468                         -boundPlane->d);
00469 
00470                     int numc = dCollide(obj->id(), odePlane.id() , 0, &contactGeom, sizeof(dContactGeom));
00471                     if (numc)
00472                     {
00473                         // Create contact joints if object is dynamics simulated
00474                         if (this->isDynamicsEnabled())
00475                         {
00476                             // TODO: combine object parameters with WorldFragment physical properties
00477                             dContact contact;
00478                             // Set flags
00479                             contact.surface.mode = dContactBounce | dContactApprox1;
00480                             contact.surface.bounce = this->getBounceRestitutionValue();
00481                             contact.surface.bounce_vel = this->getBounceVelocityThreshold();
00482                             Real softness = this->getSoftness();
00483                             if (softness > 0)
00484                             {
00485                                 contact.surface.mode |= dContactSoftCFM;
00486                                 contact.surface.soft_cfm = softness;
00487                             }
00488                             
00489                             // Set friction 
00490                             contact.surface.mu = this->getFriction();
00491                             contact.surface.mu2 = 0;
00492                             contact.geom = contactGeom;
00493                             dContactJoint contactJoint(
00494                                 World::getSingleton().getOdeWorld()->id(), 
00495                                 World::getSingleton().getOdeContactJointGroup()->id(), 
00496                                 &contact);
00497 
00498                             // Get ODE body,world fragment body is 0 clearly (immovable)
00499                             dBody* body = this->getOdeBody();
00500                             dBodyID bid;
00501                             bid = 0;
00502                             if (body) bid = body->id();
00503                             contactJoint.attach(bid, 0);
00504                         }
00505 
00506                         // Tell object about the collision
00507                         collInfo.position.x = contactGeom.pos[0];
00508                         collInfo.position.y = contactGeom.pos[1];
00509                         collInfo.position.z = contactGeom.pos[2];
00510                         collInfo.normal.x = contactGeom.normal[0];
00511                         collInfo.normal.y = contactGeom.normal[1];
00512                         collInfo.normal.z = contactGeom.normal[2];
00513 
00514                         // NB clamp the depth to compensate for crazy results
00515                         collInfo.penetrationDepth = contactGeom.depth;
00516                         //collInfo.penetrationDepth = std::max(collInfo.penetrationDepth,
00517                         //    this->getLinearVelocity().length());
00518                         this->_notifyCollided(wf, collInfo);
00519 
00520 
00521                         // set return 
00522                         collided = true;
00523                     }
00524                 }
00525             } 
00526             
00527         }
00528         return collided;
00529     }
00530     //-------------------------------------------------------------------------
00531     void ApplicationObject::_notifyCollided(ApplicationObject* otherObj, 
00532         const ApplicationObject::CollisionInfo& info)
00533     {
00534         // NB contacts for physics are not created here but in testCollide
00535         // Application subclasses should do their own respose here if required
00536     }
00537     //-------------------------------------------------------------------------
00538     void ApplicationObject::_notifyCollided(SceneQuery::WorldFragment* wf, 
00539         const CollisionInfo& info)
00540     {
00541         // NB contacts for physics are not created here but in testCollide
00542         // Application subclasses should do their own respose here if required
00543     }
00544     //-------------------------------------------------------------------------
00545     void ApplicationObject::setBounceParameters(Real restitutionValue, 
00546             Real velocityThreshold)
00547     {
00548         mBounceCoeffRestitution = restitutionValue;
00549         mBounceVelocityThreshold = velocityThreshold;
00550     }
00551     //-------------------------------------------------------------------------
00552     Real ApplicationObject::getBounceRestitutionValue(void)
00553     {
00554         return mBounceCoeffRestitution;
00555     }
00556     //-------------------------------------------------------------------------
00557     Real ApplicationObject::getBounceVelocityThreshold(void)
00558     {
00559         return mBounceVelocityThreshold;
00560     }
00561     //-------------------------------------------------------------------------
00562     void ApplicationObject::setSoftness(Real softness)
00563     {
00564         mSoftness = softness;
00565     }
00566     //-------------------------------------------------------------------------
00567     Real ApplicationObject::getSoftness(void)
00568     {
00569         return mSoftness;
00570     }
00571     //-------------------------------------------------------------------------
00572     void ApplicationObject::setFriction(Real friction)
00573     {
00574         if (friction == Math::POS_INFINITY)
00575         {
00576             mFriction = dInfinity;
00577         }
00578         else
00579         {
00580             mFriction = friction;
00581         }
00582     }
00583     //-------------------------------------------------------------------------
00584     Real ApplicationObject::getFriction(void)
00585     {
00586         return mFriction;
00587     }
00588     //-------------------------------------------------------------------------
00589     void ApplicationObject::setMassSphere(Real density, Real radius)
00590     {
00591         dMassSetSphere(&mMass, density, radius);
00592         mOdeBody->setMass(&mMass);
00593     }
00594     //-------------------------------------------------------------------------
00595     void ApplicationObject::setMassBox(Real density, const Vector3& dimensions, 
00596         const Quaternion& orientation)
00597     {
00598         dMassSetBox(&mMass, density, dimensions.x, dimensions.y, dimensions.z);
00599 
00600         Matrix3 m3;
00601         orientation.ToRotationMatrix(m3);
00602         dMatrix3 dm3;
00603         OgreToOde(m3, dm3);
00604         dMassRotate(&mMass, dm3);
00605 
00606         mOdeBody->setMass(&mMass);
00607 
00608 
00609     }
00610     //-------------------------------------------------------------------------
00611     void ApplicationObject::setMassCappedCylinder(Real density, Real length, Real width, 
00612         const Quaternion& orientation)
00613     {
00614         dMassSetCappedCylinder(&mMass, density, 3, width, length);
00615 
00616         Matrix3 m3;
00617         orientation.ToRotationMatrix(m3);
00618         dMatrix3 dm3;
00619         OgreToOde(m3, dm3);
00620         dMassRotate(&mMass, dm3);
00621 
00622         mOdeBody->setMass(&mMass);
00623     }
00624     //-------------------------------------------------------------------------
00625     void ApplicationObject::setMassExpert(Real mass, const Vector3 center, const Matrix3 inertia)
00626     {
00627 
00628         mMass.mass = mass;
00629         mMass.c[0] = center.x;
00630         mMass.c[1] = center.y;
00631         mMass.c[2] = center.z;
00632         OgreToOde(inertia, mMass.I);
00633         
00634         mOdeBody->setMass(&mMass);
00635 
00636     }
00637     //-------------------------------------------------------------------------
00638     const dMass* ApplicationObject::getOdeMass(void)
00639     {
00640         return &mMass;
00641     }
00642     //-------------------------------------------------------------------------
00643     void ApplicationObject::setLinearVelocity(const Vector3& vel)
00644     {
00645         setLinearVelocity(vel.x, vel.y, vel.z);
00646     }
00647     //-------------------------------------------------------------------------
00648     void ApplicationObject::setLinearVelocity(Real x, Real y, Real z)
00649     {
00650         assert(mOdeBody && isDynamicsEnabled() &&
00651             "Cannot set velocity on an object unless dynamics are enabled and"
00652             " an ODE body exists");
00653         mOdeBody->setLinearVel(x, y, z);
00654         // Reenable if on trigger
00655         setDynamicsEnabled(true, true);
00656     }
00657     //-------------------------------------------------------------------------
00658     const Vector3& ApplicationObject::getLinearVelocity(void)
00659     {
00660         assert(mOdeBody && isDynamicsEnabled() &&
00661             "Cannot get velocity on an object unless dynamics are enabled and"
00662             " an ODE body exists");
00663         static Vector3 vel;
00664         const dReal* odeVel = mOdeBody->getLinearVel();
00665         vel.x = odeVel[0];
00666         vel.y = odeVel[1];
00667         vel.z = odeVel[2];
00668         return vel;
00669         
00670     }
00671     //-------------------------------------------------------------------------
00672     const Vector3& ApplicationObject::getAngularVelocity(void)
00673     {
00674         assert(mOdeBody && isDynamicsEnabled() &&
00675             "Cannot get velocity on an object unless dynamics are enabled and"
00676             " an ODE body exists");
00677         static Vector3 vel;
00678         const dReal* odeVel = mOdeBody->getAngularVel();
00679         vel.x = odeVel[0];
00680         vel.y = odeVel[1];
00681         vel.z = odeVel[2];
00682         return vel;
00683     }
00684     //-------------------------------------------------------------------------
00685     void ApplicationObject::setAngularVelocity(const Vector3& vel)
00686     {
00687         setAngularVelocity(vel.x, vel.y, vel.z);
00688     }
00689     //-------------------------------------------------------------------------
00690     void ApplicationObject::setAngularVelocity(Real x, Real y, Real z)
00691     {
00692         assert(mOdeBody && isDynamicsEnabled() &&
00693             "Cannot set velocity on an object unless dynamics are enabled and"
00694             " an ODE body exists");
00695         mOdeBody->setAngularVel(x, y, z);
00696         // Reenable if on trigger
00697         setDynamicsEnabled(true, true);
00698     }
00699     //-------------------------------------------------------------------------
00700     void ApplicationObject::translate(const Vector3& d)
00701     {
00702         // Adjust position by rotation
00703         Vector3 newTrans = mSceneNode->getOrientation() * d;
00704         translateWorldSpace(newTrans);
00705     }
00706     //-------------------------------------------------------------------------
00707     void ApplicationObject::translate(Real x, Real y, Real z)
00708     {
00709         translate(Vector3(x, y, z));
00710     }
00711     //-------------------------------------------------------------------------
00712     void ApplicationObject::translateWorldSpace(const Vector3& d)
00713     {
00714         setPosition(getPosition() + d);
00715     }
00716     //-------------------------------------------------------------------------
00717     void ApplicationObject::translateWorldSpace(Real x, Real y, Real z)
00718     {
00719         translateWorldSpace(Vector3(x, y, z));
00720     }
00721     //-------------------------------------------------------------------------
00722     void ApplicationObject::roll(Real angleunits)
00723     {
00724         rotate(Vector3::UNIT_Z, angleunits);
00725     }
00726     //-------------------------------------------------------------------------
00727     void ApplicationObject::pitch(Real angleunits)
00728     {
00729         rotate(Vector3::UNIT_X, angleunits);
00730     }
00731     //-------------------------------------------------------------------------
00732     void ApplicationObject::yaw(Real angleunits)
00733     {
00734         rotate(Vector3::UNIT_Y, angleunits);
00735     }
00736     //-------------------------------------------------------------------------
00737     void ApplicationObject::rotate(const Vector3& axis, Real angleunits)
00738     {
00739         Quaternion q;
00740         q.FromAngleAxis(Math::AngleUnitsToRadians(angleunits),axis);
00741         rotate(q);
00742     }
00743     //-------------------------------------------------------------------------
00744     void ApplicationObject::rotate(const Quaternion& q)
00745     {
00746         setOrientation(getOrientation() * q);
00747     }
00748     //-------------------------------------------------------------------------
00749     void ApplicationObject::setEntityQueryFlags(void)
00750     {
00751         // Real basic query mask usage for now
00752         // collision enabled = 0xFFFFFFFF
00753         // collision disabled = 0x0
00754         if (mEntity)
00755         {
00756             mEntity->setQueryFlags( mCollisionEnabled ? 0xFFFFFFFF : 0 );
00757         }
00758     }
00759 
00760 
00761 
00762 }
00763 

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:38 2004