source: OGRE/trunk/ogrenew/ReferenceApplication/ReferenceAppLayer/src/OgreRefAppApplicationObject.cpp @ 692

Revision 692, 29.4 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of the OGRE Reference Application, a layer built
4on top of OGRE(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25
26#include "OgreRefAppApplicationObject.h"
27#include "OgreRefAppWorld.h"
28#include "ode/collision.h"
29#include "OgreControllerManager.h"
30#include "OgreStringConverter.h"
31#include "OgreRoot.h"
32
33namespace OgreRefApp
34{
35    //-------------------------------------------------------------------------
36    ApplicationObject::ApplicationObject(const String& name)
37    {
38        mSceneNode = 0;
39        mEntity = 0;
40        mOdeBody = 0;
41        mDynamicsEnabled = false;
42        mReenableIfInteractedWith = false;
43        mCollisionEnabled = true;
44                mSoftness = 0.0;
45                mBounceCoeffRestitution = 0;
46                mBounceVelocityThreshold = 0.1;
47        setFriction(Math::POS_INFINITY);
48        dMassSetZero(&mMass);
49
50        mDisableTimeEnd = 0;
51        mDisableTime = 3000.0f; // millisenconds
52        mAngularVelDisableThreshold = 1.0f;
53        mLinearVelDisableThreshold = 1.0f;
54
55
56
57    }
58    //-------------------------------------------------------------------------
59    ApplicationObject::~ApplicationObject()
60    {
61        SceneManager* sm = World::getSingleton().getSceneManager();
62        if (mSceneNode)
63        {
64            sm->destroySceneNode(mSceneNode->getName());
65            mSceneNode = 0;
66        }
67
68        // TODO destroy entity
69
70        // Destroy mass
71        if (mOdeBody)
72        {
73            delete mOdeBody;
74            mOdeBody = 0;
75        }
76
77        // Destroy collision proxies
78        CollisionProxyList::iterator i, iend;
79        iend = mCollisionProxies.end();
80        for (i = mCollisionProxies.begin(); i != iend; ++i)
81        {
82            delete (*i);
83        }
84
85
86
87    }
88    //-------------------------------------------------------------------------
89    void ApplicationObject::setPosition(const Vector3& vec)
90    {
91        setPosition(vec.x, vec.y, vec.z);
92    }
93    //-------------------------------------------------------------------------
94    void ApplicationObject::setPosition(Real x, Real y, Real z)
95    {
96        mSceneNode->setPosition(x, y, z);
97        if (isDynamicsEnabled() && mOdeBody)
98            mOdeBody->setPosition(x, y, z);
99        updateCollisionProxies();
100    }
101    //-------------------------------------------------------------------------
102    void ApplicationObject::setOrientation(const Quaternion& orientation)
103    {
104        mSceneNode->setOrientation(orientation);
105        if (isDynamicsEnabled() && mOdeBody)
106        {
107            dReal dquat[4] = {orientation.w, orientation.x, orientation.y, orientation.z };
108            mOdeBody->setQuaternion(dquat);
109        }
110        updateCollisionProxies();
111    }
112    //-------------------------------------------------------------------------
113    const Vector3& ApplicationObject::getPosition(void)
114    {
115        return mSceneNode->getPosition();
116    }
117    //-------------------------------------------------------------------------
118    const Quaternion& ApplicationObject::getOrientation(void)
119    {
120        return mSceneNode->getOrientation();
121    }
122    //-------------------------------------------------------------------------
123    void ApplicationObject::setDynamicsDisableThreshold(Real linearSq,
124        Real angularSq, Real overTime)
125    {
126        mLinearVelDisableThreshold = linearSq;
127        mAngularVelDisableThreshold = angularSq;
128        mDisableTime = overTime * 1000;
129    }
130    //-------------------------------------------------------------------------
131    void ApplicationObject::_updateFromDynamics()
132    {
133        if (!mOdeBody)
134        {
135            return;
136        }
137        // Update dynamics enabled flag from dynamics (may have been reenabled)
138        if (mReenableIfInteractedWith)
139        {
140            mDynamicsEnabled = mOdeBody->isEnabled() == 0 ? false : true;
141        }
142
143        if (mDynamicsEnabled)
144        {
145            // Get position & rotation from ODE
146            const dReal* pos = mOdeBody->getPosition();
147            const dReal* quat = mOdeBody->getQuaternion();
148
149            mSceneNode->setPosition((Real)pos[0], (Real)pos[1], (Real)pos[2]);
150            mSceneNode->setOrientation((Real)quat[0], (Real)quat[1],
151                (Real)quat[2], (Real)quat[3]);
152
153            updateCollisionProxies();
154
155            // Check to see if object has stabilised, if so turn off dynamics
156            // to save processor time
157            // NB will be reenabled if interacted with
158           
159            if (this->getLinearVelocity().squaredLength() <= mLinearVelDisableThreshold
160                && this->getAngularVelocity().squaredLength() <= mAngularVelDisableThreshold)
161            {
162                if (mDisableTimeEnd > 0.0f)
163                {
164                    // We're counting, check disable time
165                    if (Root::getSingleton().getTimer()->getMilliseconds() > mDisableTimeEnd)
166                    {
167                        this->setDynamicsEnabled(false, true);
168                        //LogManager::getSingleton().logMessage(mEntity->getName() + " disabled");
169                        mDisableTimeEnd = 0.0f;
170                    }
171
172                }
173                else
174                {
175                    // We're not counting down yet, so start the count
176                    // NB is mDisableTime = 0 we never disable
177                    if (mDisableTime > 0)
178                    {
179                        mDisableTimeEnd = Root::getSingleton().getTimer()->getMilliseconds() + mDisableTime;
180                        //LogManager::getSingleton().logMessage("Starting countdown...");
181                    }
182                }
183            }
184            else
185            {
186                // We're still moving
187                mDisableTimeEnd = 0.0f;
188            }
189
190        }
191    }
192    //-------------------------------------------------------------------------
193    bool ApplicationObject::isCollisionEnabled(void)
194    {
195        return mCollisionEnabled;
196    }
197    //-------------------------------------------------------------------------
198    bool ApplicationObject::isDynamicsEnabled(void)
199    {
200        return (mDynamicsEnabled || mReenableIfInteractedWith);
201    }
202    //-------------------------------------------------------------------------
203    void ApplicationObject::setCollisionEnabled(bool enabled)
204    {
205        mCollisionEnabled = enabled;
206        setEntityQueryFlags();
207    }
208    //-------------------------------------------------------------------------
209    void ApplicationObject::setDynamicsEnabled(bool enabled, bool reEnableOnInteraction)
210    {
211       
212        mDynamicsEnabled = enabled;
213        mReenableIfInteractedWith = reEnableOnInteraction;
214
215        // World must keep an eye on enabled or potentially reenabled objects
216        World::getSingleton()._notifyDynamicsStateForObject(this,
217            mDynamicsEnabled || mReenableIfInteractedWith);
218       
219        if (mDynamicsEnabled)
220        {
221            // Ensure body is synced
222            mOdeBody->enable();
223        }
224        else if (mOdeBody)
225        {
226            mOdeBody->disable();
227        }
228        // Set properties
229        if (mDynamicsEnabled || mReenableIfInteractedWith)
230        {
231            const Vector3& pos = getPosition();
232            mOdeBody->setPosition(pos.x, pos.y, pos.z);
233            const Quaternion& q = getOrientation();
234            dReal dquat[4] = {q.w, q.x, q.y, q.z };
235            mOdeBody->setQuaternion(dquat);
236        }
237    }
238    //-------------------------------------------------------------------------
239    void ApplicationObject::addForce(const Vector3& direction, const Vector3& atPosition)
240    {
241        addForce(direction.x, direction.y, direction.z,
242            atPosition.x, atPosition.y, atPosition.z);
243    }
244    //-------------------------------------------------------------------------
245    void ApplicationObject::addForce(Real dir_x, Real dir_y, Real dir_z,
246        Real pos_x, Real pos_y, Real pos_z)
247    {
248        assert (mOdeBody && "No dynamics body set up for this object");
249        mOdeBody->addRelForceAtRelPos(dir_x, dir_y, dir_z,
250            pos_x, pos_y, pos_z);
251
252    }
253    //-------------------------------------------------------------------------
254    void ApplicationObject::addForceWorldSpace(const Vector3& direction, const Vector3& atPosition)
255    {
256        addForceWorldSpace(direction.x, direction.y, direction.z,
257            atPosition.x, atPosition.y, atPosition.z);
258    }
259    //-------------------------------------------------------------------------
260    void ApplicationObject::addForceWorldSpace(Real dir_x, Real dir_y, Real dir_z,
261        Real pos_x, Real pos_y, Real pos_z)
262    {
263        assert (mOdeBody && "No dynamics body set up for this object");
264        mOdeBody->addForceAtPos(dir_x, dir_y, dir_z,
265            pos_x, pos_y, pos_z);
266    }
267    //-------------------------------------------------------------------------
268    void ApplicationObject::addTorque(const Vector3& direction)
269    {
270        addTorque(direction.x, direction.y, direction.z);
271    }
272    //-------------------------------------------------------------------------
273    void ApplicationObject::addTorque(Real x, Real y, Real z)
274    {
275        assert (mOdeBody && "No dynamics body set up for this object");
276        mOdeBody->addRelTorque(x, y, z);
277    }
278    //-------------------------------------------------------------------------
279    void ApplicationObject::addTorqueWorldSpace(const Vector3& direction)
280    {
281        addTorqueWorldSpace(direction.x, direction.y, direction.z);
282    }
283    //-------------------------------------------------------------------------
284    void ApplicationObject::addTorqueWorldSpace(Real x, Real y, Real z)
285    {
286        assert (mOdeBody && "No dynamics body set up for this object");
287        mOdeBody->addTorque(x, y, z);
288    }
289    //-------------------------------------------------------------------------
290    SceneNode* ApplicationObject::getSceneNode(void)
291    {
292        return mSceneNode;
293    }
294    //-------------------------------------------------------------------------
295    Entity* ApplicationObject::getEntity(void)
296    {
297        return mEntity;
298    }
299    //-------------------------------------------------------------------------
300    dBody* ApplicationObject::getOdeBody(void)
301    {
302        if (isDynamicsEnabled())
303        {
304            return mOdeBody;
305        }
306        else
307        {
308            // dynamics are disabled
309            return 0;
310        }
311    }
312    //-------------------------------------------------------------------------
313    void ApplicationObject::updateCollisionProxies(void)
314    {
315        CollisionProxyList::iterator i, iend;
316        iend = mCollisionProxies.end();
317        for (i = mCollisionProxies.begin(); i != iend; ++i)
318        {
319            // set from node
320            const Vector3& pos = mSceneNode->getPosition();
321            dGeom* pProxy = *i;
322            pProxy->setPosition(pos.x, pos.y, pos.z);
323            const Quaternion& orientation = mSceneNode->getOrientation();
324            // Hmm, no setQuaternion on proxy
325            // Do a conversion
326            dReal dquat[4] = {orientation.w, orientation.x, orientation.y, orientation.z };
327            dMatrix3 dm3;
328            memset(dm3, 0, sizeof(dMatrix3));
329            dQtoR(dquat, dm3);
330            pProxy->setRotation(dm3);
331           
332        }
333
334    }
335    //-------------------------------------------------------------------------
336    bool ApplicationObject::testCollide(ApplicationObject* otherObj)
337    {
338        bool collided = false;
339        dContactGeom contactGeom;
340        dGeom *o1, *o2;
341        CollisionProxyList::const_iterator proxy1, proxy2, proxy1end, proxy2end;
342        proxy1end = mCollisionProxies.end();
343        proxy2end = otherObj->mCollisionProxies.end();
344
345        CollisionInfo collInfo;
346
347        for (proxy1 = mCollisionProxies.begin(); proxy1 != proxy1end; ++proxy1)
348        {
349            for (proxy2 = otherObj->mCollisionProxies.begin(); proxy2 != proxy2end; ++proxy2)
350            {
351                o1 = *proxy1;
352                o2 = *proxy2;
353                int numc = dCollide(o1->id(), o2->id(), 0, &contactGeom, sizeof(dContactGeom));
354                if (numc)
355                {
356                    // Create contact joints if either object is dynamics simulated
357                    // If one is not, then sim will not affect it anyway, it will be fixed
358                    // However if one is enabled, we need the contact joint
359                    if (this->isDynamicsEnabled() || otherObj->isDynamicsEnabled())
360                    {
361                                                // We use the most agressive parameters from both objects for the contact
362                        dContact contact;
363                                                Real bounce, velThresh, softness;
364                                                // Use the highest coeff of restitution from both objects
365                                                bounce = std::max(this->getBounceRestitutionValue(),
366                                                                otherObj->getBounceRestitutionValue());
367                                                // Use the lowest velocity threshold from both objects
368                                                velThresh = std::min(this->getBounceVelocityThreshold(),
369                                                                otherObj->getBounceVelocityThreshold());
370                                                // Set flags
371                                                contact.surface.mode = dContactBounce | dContactApprox1;
372                                                contact.surface.bounce = bounce;
373                                                contact.surface.bounce_vel = velThresh;
374
375                                                softness = this->getSoftness() + otherObj->getSoftness();
376                                                if (softness > 0)
377                                                {
378                                contact.surface.mode |= dContactSoftCFM;
379                                                        contact.surface.soft_cfm = softness;
380                                                }
381                                               
382                        // Set friction to min of 2 objects
383                        // Note that ODE dInfinity == Math::POS_INFINITY
384                        contact.surface.mu = std::min(this->getFriction(), otherObj->getFriction());
385                        contact.surface.mu2 = 0;
386                        contact.geom = contactGeom;
387                        dContactJoint contactJoint(
388                            World::getSingleton().getOdeWorld()->id(),
389                            World::getSingleton().getOdeContactJointGroup()->id(),
390                            &contact);
391
392                        // Get ODE bodies
393                        // May be null, if so use 0 (immovable) body ids
394                        dBody *b1, *b2;
395                        dBodyID bid1, bid2;
396                        bid1 = bid2 = 0;
397                        b1 = this->getOdeBody();
398                        b2 = otherObj->getOdeBody();
399                        if (b1) bid1 = b1->id();
400                        if (b2) bid2 = b2->id();
401                        contactJoint.attach(bid1, bid2);
402                    }
403
404                    // Tell both objects about the collision
405                    collInfo.position.x = contactGeom.pos[0];
406                    collInfo.position.y = contactGeom.pos[1];
407                    collInfo.position.z = contactGeom.pos[2];
408                    collInfo.normal.x = contactGeom.normal[0];
409                    collInfo.normal.y = contactGeom.normal[1];
410                    collInfo.normal.z = contactGeom.normal[2];
411                    collInfo.penetrationDepth = contactGeom.depth;
412                    this->_notifyCollided(otherObj, collInfo);
413                    otherObj->_notifyCollided(this, collInfo);
414
415
416                    // set return
417                    collided = true;
418                }
419            }
420        }
421        return collided;
422
423    }
424    //-------------------------------------------------------------------------
425    bool ApplicationObject::testCollide(SceneQuery::WorldFragment* wf)
426    {
427        switch (wf->fragmentType)
428        {
429        case SceneQuery::WFT_NONE:
430            return false;
431        case SceneQuery::WFT_PLANE_BOUNDED_REGION:
432            return testCollidePlaneBounds(wf);
433        default:
434            break;
435        };
436
437        // not handled
438        return false;
439    }
440    //-------------------------------------------------------------------------
441    bool ApplicationObject::testCollidePlaneBounds(SceneQuery::WorldFragment* wf)
442    {
443        bool collided = false;
444        dContactGeom contactGeom;
445        dGeom *obj;
446        CollisionProxyList::const_iterator proxy, proxyend;
447        proxyend = mCollisionProxies.end();
448
449        std::list<Plane>::const_iterator pi, piend;
450        piend = wf->planes->end();
451
452        CollisionInfo collInfo;
453
454        for (proxy = mCollisionProxies.begin(); proxy != proxyend; ++proxy)
455        {
456            // Hack, simply collide against planes which is facing towards center
457            // We can't do this properly without mesh collision
458            obj = *proxy;
459            Real maxdist = -1.0f;
460            const Plane* bestPlane = 0;
461            for (pi = wf->planes->begin(); pi != piend; ++pi)
462            {
463                const Plane *boundPlane = &(*pi);
464                Real dist = boundPlane->getDistance(this->getPosition());
465                if (dist >= 0.0f)
466                {
467                    dPlane odePlane(0, boundPlane->normal.x, boundPlane->normal.y, boundPlane->normal.z,
468                        -boundPlane->d);
469
470                    int numc = dCollide(obj->id(), odePlane.id() , 0, &contactGeom, sizeof(dContactGeom));
471                    if (numc)
472                    {
473                        // Create contact joints if object is dynamics simulated
474                        if (this->isDynamicsEnabled())
475                        {
476                            // TODO: combine object parameters with WorldFragment physical properties
477                            dContact contact;
478                                                // Set flags
479                                                contact.surface.mode = dContactBounce | dContactApprox1;
480                                                contact.surface.bounce = this->getBounceRestitutionValue();
481                                                contact.surface.bounce_vel = this->getBounceVelocityThreshold();
482                                                Real softness = this->getSoftness();
483                                                if (softness > 0)
484                                                {
485                                contact.surface.mode |= dContactSoftCFM;
486                                                        contact.surface.soft_cfm = softness;
487                                                }
488                                       
489                            // Set friction
490                            contact.surface.mu = this->getFriction();
491                            contact.surface.mu2 = 0;
492                            contact.geom = contactGeom;
493                            dContactJoint contactJoint(
494                                World::getSingleton().getOdeWorld()->id(),
495                                World::getSingleton().getOdeContactJointGroup()->id(),
496                                &contact);
497
498                            // Get ODE body,world fragment body is 0 clearly (immovable)
499                            dBody* body = this->getOdeBody();
500                            dBodyID bid;
501                            bid = 0;
502                            if (body) bid = body->id();
503                            contactJoint.attach(bid, 0);
504                        }
505
506                        // Tell object about the collision
507                        collInfo.position.x = contactGeom.pos[0];
508                        collInfo.position.y = contactGeom.pos[1];
509                        collInfo.position.z = contactGeom.pos[2];
510                        collInfo.normal.x = contactGeom.normal[0];
511                        collInfo.normal.y = contactGeom.normal[1];
512                        collInfo.normal.z = contactGeom.normal[2];
513
514                        // NB clamp the depth to compensate for crazy results
515                        collInfo.penetrationDepth = contactGeom.depth;
516                        //collInfo.penetrationDepth = std::max(collInfo.penetrationDepth,
517                        //    this->getLinearVelocity().length());
518                        this->_notifyCollided(wf, collInfo);
519
520
521                        // set return
522                        collided = true;
523                    }
524                }
525            }
526           
527        }
528        return collided;
529    }
530    //-------------------------------------------------------------------------
531    void ApplicationObject::_notifyCollided(ApplicationObject* otherObj,
532        const ApplicationObject::CollisionInfo& info)
533    {
534        // NB contacts for physics are not created here but in testCollide
535        // Application subclasses should do their own respose here if required
536    }
537    //-------------------------------------------------------------------------
538    void ApplicationObject::_notifyCollided(SceneQuery::WorldFragment* wf,
539        const CollisionInfo& info)
540    {
541        // NB contacts for physics are not created here but in testCollide
542        // Application subclasses should do their own respose here if required
543    }
544    //-------------------------------------------------------------------------
545        void ApplicationObject::setBounceParameters(Real restitutionValue,
546                        Real velocityThreshold)
547        {
548                mBounceCoeffRestitution = restitutionValue;
549                mBounceVelocityThreshold = velocityThreshold;
550        }
551    //-------------------------------------------------------------------------
552        Real ApplicationObject::getBounceRestitutionValue(void)
553        {
554                return mBounceCoeffRestitution;
555        }
556    //-------------------------------------------------------------------------
557        Real ApplicationObject::getBounceVelocityThreshold(void)
558        {
559                return mBounceVelocityThreshold;
560        }
561    //-------------------------------------------------------------------------
562        void ApplicationObject::setSoftness(Real softness)
563        {
564                mSoftness = softness;
565        }
566    //-------------------------------------------------------------------------
567        Real ApplicationObject::getSoftness(void)
568        {
569                return mSoftness;
570        }
571    //-------------------------------------------------------------------------
572    void ApplicationObject::setFriction(Real friction)
573    {
574        if (friction == Math::POS_INFINITY)
575        {
576            mFriction = dInfinity;
577        }
578        else
579        {
580            mFriction = friction;
581        }
582    }
583    //-------------------------------------------------------------------------
584    Real ApplicationObject::getFriction(void)
585    {
586        return mFriction;
587    }
588    //-------------------------------------------------------------------------
589    void ApplicationObject::setMassSphere(Real density, Real radius)
590    {
591        dMassSetSphere(&mMass, density, radius);
592        mOdeBody->setMass(&mMass);
593    }
594    //-------------------------------------------------------------------------
595    void ApplicationObject::setMassBox(Real density, const Vector3& dimensions,
596        const Quaternion& orientation)
597    {
598        dMassSetBox(&mMass, density, dimensions.x, dimensions.y, dimensions.z);
599
600        Matrix3 m3;
601        orientation.ToRotationMatrix(m3);
602        dMatrix3 dm3;
603        OgreToOde(m3, dm3);
604        dMassRotate(&mMass, dm3);
605
606        mOdeBody->setMass(&mMass);
607
608
609    }
610    //-------------------------------------------------------------------------
611    void ApplicationObject::setMassCappedCylinder(Real density, Real length, Real width,
612        const Quaternion& orientation)
613    {
614        dMassSetCappedCylinder(&mMass, density, 3, width, length);
615
616        Matrix3 m3;
617        orientation.ToRotationMatrix(m3);
618        dMatrix3 dm3;
619        OgreToOde(m3, dm3);
620        dMassRotate(&mMass, dm3);
621
622        mOdeBody->setMass(&mMass);
623    }
624    //-------------------------------------------------------------------------
625    void ApplicationObject::setMassExpert(Real mass, const Vector3 center, const Matrix3 inertia)
626    {
627
628        mMass.mass = mass;
629        mMass.c[0] = center.x;
630        mMass.c[1] = center.y;
631        mMass.c[2] = center.z;
632        OgreToOde(inertia, mMass.I);
633       
634        mOdeBody->setMass(&mMass);
635
636    }
637    //-------------------------------------------------------------------------
638    const dMass* ApplicationObject::getOdeMass(void)
639    {
640        return &mMass;
641    }
642    //-------------------------------------------------------------------------
643    void ApplicationObject::setLinearVelocity(const Vector3& vel)
644    {
645        setLinearVelocity(vel.x, vel.y, vel.z);
646    }
647    //-------------------------------------------------------------------------
648    void ApplicationObject::setLinearVelocity(Real x, Real y, Real z)
649    {
650        assert(mOdeBody && isDynamicsEnabled() &&
651            "Cannot set velocity on an object unless dynamics are enabled and"
652            " an ODE body exists");
653        mOdeBody->setLinearVel(x, y, z);
654        // Reenable if on trigger
655        setDynamicsEnabled(true, true);
656    }
657    //-------------------------------------------------------------------------
658    const Vector3& ApplicationObject::getLinearVelocity(void)
659    {
660        assert(mOdeBody && isDynamicsEnabled() &&
661            "Cannot get velocity on an object unless dynamics are enabled and"
662            " an ODE body exists");
663        static Vector3 vel;
664        const dReal* odeVel = mOdeBody->getLinearVel();
665        vel.x = odeVel[0];
666        vel.y = odeVel[1];
667        vel.z = odeVel[2];
668        return vel;
669       
670    }
671    //-------------------------------------------------------------------------
672    const Vector3& ApplicationObject::getAngularVelocity(void)
673    {
674        assert(mOdeBody && isDynamicsEnabled() &&
675            "Cannot get velocity on an object unless dynamics are enabled and"
676            " an ODE body exists");
677        static Vector3 vel;
678        const dReal* odeVel = mOdeBody->getAngularVel();
679        vel.x = odeVel[0];
680        vel.y = odeVel[1];
681        vel.z = odeVel[2];
682        return vel;
683    }
684    //-------------------------------------------------------------------------
685    void ApplicationObject::setAngularVelocity(const Vector3& vel)
686    {
687        setAngularVelocity(vel.x, vel.y, vel.z);
688    }
689    //-------------------------------------------------------------------------
690    void ApplicationObject::setAngularVelocity(Real x, Real y, Real z)
691    {
692        assert(mOdeBody && isDynamicsEnabled() &&
693            "Cannot set velocity on an object unless dynamics are enabled and"
694            " an ODE body exists");
695        mOdeBody->setAngularVel(x, y, z);
696        // Reenable if on trigger
697        setDynamicsEnabled(true, true);
698    }
699    //-------------------------------------------------------------------------
700    void ApplicationObject::translate(const Vector3& d)
701    {
702        // Adjust position by rotation
703        Vector3 newTrans = mSceneNode->getOrientation() * d;
704        translateWorldSpace(newTrans);
705    }
706    //-------------------------------------------------------------------------
707    void ApplicationObject::translate(Real x, Real y, Real z)
708    {
709        translate(Vector3(x, y, z));
710    }
711    //-------------------------------------------------------------------------
712    void ApplicationObject::translateWorldSpace(const Vector3& d)
713    {
714        setPosition(getPosition() + d);
715    }
716    //-------------------------------------------------------------------------
717    void ApplicationObject::translateWorldSpace(Real x, Real y, Real z)
718    {
719        translateWorldSpace(Vector3(x, y, z));
720    }
721    //-------------------------------------------------------------------------
722    void ApplicationObject::roll(const Radian& angle)
723    {
724        rotate(Vector3::UNIT_Z, angle);
725    }
726    //-------------------------------------------------------------------------
727    void ApplicationObject::pitch(const Radian& angle)
728    {
729        rotate(Vector3::UNIT_X, angle);
730    }
731    //-------------------------------------------------------------------------
732    void ApplicationObject::yaw(const Radian& angle)
733    {
734        rotate(Vector3::UNIT_Y, angle);
735    }
736    //-------------------------------------------------------------------------
737    void ApplicationObject::rotate(const Vector3& axis, const Radian& angle)
738    {
739        Quaternion q;
740        q.FromAngleAxis(angle,axis);
741        rotate(q);
742    }
743    //-------------------------------------------------------------------------
744    void ApplicationObject::rotate(const Quaternion& q)
745    {
746        setOrientation(getOrientation() * q);
747    }
748    //-------------------------------------------------------------------------
749    void ApplicationObject::setEntityQueryFlags(void)
750    {
751        // Real basic query mask usage for now
752        // collision enabled = 0xFFFFFFFF
753        // collision disabled = 0x0
754        if (mEntity)
755        {
756            mEntity->setQueryFlags( mCollisionEnabled ? 0xFFFFFFFF : 0 );
757        }
758    }
759
760
761
762}
763
Note: See TracBrowser for help on using the repository browser.