Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ReferenceApplication/ReferenceAppLayer/src/OgreRefAppApplicationObject.cpp @ 1

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