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(const Radian& angle)
    00723     {
    00724         rotate(Vector3::UNIT_Z, angle);
    00725     }
    00726     //-------------------------------------------------------------------------
    00727     void ApplicationObject::pitch(const Radian& angle)
    00728     {
    00729         rotate(Vector3::UNIT_X, angle);
    00730     }
    00731     //-------------------------------------------------------------------------
    00732     void ApplicationObject::yaw(const Radian& angle)
    00733     {
    00734         rotate(Vector3::UNIT_Y, angle);
    00735     }
    00736     //-------------------------------------------------------------------------
    00737     void ApplicationObject::rotate(const Vector3& axis, const Radian& angle)
    00738     {
    00739         Quaternion q;
    00740         q.FromAngleAxis(angle,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 Sun Nov 28 19:48:41 2004