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

# OgreRefAppWorld.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 #include "OgreRefAppWorld.h"
    00026 #include "OgreRefAppOgreHead.h"
    00027 #include "OgreRefAppPlane.h"
    00028 #include "OgreRefAppBall.h"
    00029 #include "OgreRefAppJointSubtypes.h"
    00030 #include "OgreRefAppBox.h"
    00031 #include "OgreRefAppCollideCamera.h"
    00032
    00033 //-------------------------------------------------------------------------
    00034 template<> OgreRefApp::World* Ogre::Singleton<OgreRefApp::World>::ms_Singleton = 0;
    00035 OgreRefApp::World* OgreRefApp::World::getSingletonPtr(void)
    00036 {
    00037     return ms_Singleton;
    00038 }
    00039 OgreRefApp::World& OgreRefApp::World::getSingleton(void)
    00040 {
    00041     assert( ms_Singleton );  return ( *ms_Singleton );
    00042 }
    00043 //-------------------------------------------------------------------------
    00044 namespace OgreRefApp
    00045 {
    00046     //-------------------------------------------------------------------------
    00047     World::World(SceneManager* sceneMgr, WorldType worldType)
    00048         : mSceneMgr(sceneMgr), mWorldType(worldType)
    00049     {
    00050         mSimulationStepSize = 0.01f;
    00051
    00052         // Create the dynamics world
    00053         mOdeWorld = new dWorld();
    00054         mOdeContactGroup = new dJointGroup();
    00055
    00056         mIntersectionQuery = mSceneMgr->createIntersectionQuery();
    00057         switch (worldType)
    00058         {
    00059         case World::WT_REFAPP_GENERIC:
    00060             mIntersectionQuery->setWorldFragmentType(SceneQuery::WFT_NONE);
    00061             break;
    00062         case World::WT_REFAPP_BSP:
    00063             mIntersectionQuery->setWorldFragmentType(SceneQuery::WFT_PLANE_BOUNDED_REGION);
    00064             break;
    00065         };
    00066
    00067     }
    00068     //-------------------------------------------------------------------------
    00069     World::~World()
    00070     {
    00071         clear();
    00072
    00073         delete mIntersectionQuery;
    00074
    00075         // Destroy dynamix world
    00076         delete mOdeContactGroup;
    00077         delete mOdeWorld;
    00078
    00079     }
    00080     //-------------------------------------------------------------------------
    00081     SceneManager* World::getSceneManager(void)
    00082     {
    00083         return mSceneMgr;
    00084     }
    00085     //-------------------------------------------------------------------------
    00086     OgreHead* World::createOgreHead(const String& name,
    00087         const Vector3& pos, const Quaternion& orientation)
    00088     {
    00089         OgreHead* head = new OgreHead(name);
    00090         head->setPosition(pos);
    00091         head->setOrientation(orientation);
    00092
    00093         mObjects[name] = head;
    00094
    00095         return head;
    00096     }
    00097     //-------------------------------------------------------------------------
    00098     FinitePlane* World::createPlane(const String& name, Real width, Real height, const Vector3& pos,
    00099         const Quaternion& orientation)
    00100     {
    00101         FinitePlane* plane = new FinitePlane(name, width, height);
    00102         plane->setPosition(pos);
    00103         plane->setOrientation(orientation);
    00104
    00105         mObjects[name] = plane;
    00106
    00107         return plane;
    00108     }
    00109     //-------------------------------------------------------------------------
    00110     Ball* World::createBall(const String& name, Real radius, const Vector3& pos,
    00111         const Quaternion& orientation)
    00112     {
    00113         OgreRefApp::Ball* ball = new OgreRefApp::Ball(name, radius);
    00114         ball->setPosition(pos);
    00115         ball->setOrientation(orientation);
    00116
    00117         mObjects[name] = ball;
    00118
    00119         return ball;
    00120     }
    00121     //-------------------------------------------------------------------------
    00122     void World::clear(void)
    00123     {
    00124         ObjectMap::iterator i;
    00125         for (i = mObjects.begin(); i != mObjects.end(); ++i)
    00126         {
    00127             delete i->second;
    00128         }
    00129         mObjects.clear();
    00130
    00131         JointMap::iterator ji;
    00132         for (ji = mJoints.begin(); ji != mJoints.end(); ++ji)
    00133         {
    00134             delete ji->second;
    00135         }
    00136         mJoints.clear();
    00137     }
    00138     //-------------------------------------------------------------------------
    00139     dWorld* World::getOdeWorld(void)
    00140     {
    00141         return mOdeWorld;
    00142     }
    00143     //-------------------------------------------------------------------------
    00144     void World::_applyDynamics(Real timeElapsed)
    00145     {
    00146         if (timeElapsed != 0.0f)
    00147         {
    00148             // ODE will throw an error if timestep = 0
    00149
    00150             mOdeWorld->step(dReal(timeElapsed));
    00151             // Now update the objects in the world
    00152             ObjectSet::iterator i, iend;
    00153             iend = mDynamicsObjects.end();
    00154             for (i = mDynamicsObjects.begin(); i != iend; ++i)
    00155             {
    00156                 (*i)->_updateFromDynamics();
    00157             }
    00158             // Clear contacts
    00159             mOdeContactGroup->empty();
    00160         }
    00161
    00162     }
    00163     //-------------------------------------------------------------------------
    00164     void World::_notifyDynamicsStateForObject(ApplicationObject* obj, bool dynamicsEnabled)
    00165     {
    00166         // NB std::set prevents duplicates & errors on erasing non-existent objects
    00167         if (dynamicsEnabled)
    00168         {
    00169             mDynamicsObjects.insert(obj);
    00170         }
    00171         else
    00172         {
    00173             mDynamicsObjects.erase(obj);
    00174         }
    00175     }
    00176     //-------------------------------------------------------------------------
    00177     void World::setGravity(const Vector3& vec)
    00178     {
    00179         mGravity = vec;
    00180         mOdeWorld->setGravity(vec.x, vec.y, vec.z);
    00181     }
    00182     //-------------------------------------------------------------------------
    00183     const Vector3& World::getGravity(void)
    00184     {
    00185         return mGravity;
    00186     }
    00187     //-------------------------------------------------------------------------
    00188     dJointGroup* World::getOdeContactJointGroup(void)
    00189     {
    00190         return mOdeContactGroup;
    00191     }
    00192     //-------------------------------------------------------------------------
    00193     void World::_applyCollision(void)
    00194     {
    00195         // Collision detection
    00196         IntersectionSceneQueryResult& results = mIntersectionQuery->execute();
    00197
    00198         // Movables to Movables
    00199         SceneQueryMovableIntersectionList::iterator it, itend;
    00200         itend = results.movables2movables.end();
    00201         for (it = results.movables2movables.begin(); it != itend; ++it)
    00202         {
    00203             /* debugging
    00204             MovableObject *mo1, *mo2;
    00205             mo1 = it->first;
    00206             mo2 = it->second;
    00207             */
    00208
    00209             // Get user defined objects (generic in OGRE)
    00210             UserDefinedObject *uo1, *uo2;
    00211             uo1 = it->first->getUserObject();
    00212             uo2 = it->second->getUserObject();
    00213
    00214             // Only perform collision if we have UserDefinedObject links
    00215             if (uo1 && uo2)
    00216             {
    00217                 // Cast to ApplicationObject
    00218                 ApplicationObject *ao1, *ao2;
    00219                 ao1 = static_cast<ApplicationObject*>(uo1);
    00220                 ao2 = static_cast<ApplicationObject*>(uo2);
    00221                 // Do detailed collision test
    00222                 ao1->testCollide(ao2);
    00223             }
    00224         }
    00225
    00226         // Movables to World
    00227         SceneQueryMovableWorldFragmentIntersectionList::iterator wit, witend;
    00228         witend = results.movables2world.end();
    00229         for (wit = results.movables2world.begin(); wit != witend; ++wit)
    00230         {
    00231             MovableObject *mo = wit->first;
    00232             SceneQuery::WorldFragment *wf = wit->second;
    00233
    00234             // Get user defined objects (generic in OGRE)
    00235             UserDefinedObject *uo = mo->getUserObject();
    00236
    00237             // Only perform collision if we have UserDefinedObject link
    00238             if (uo)
    00239             {
    00240                 // Cast to ApplicationObject
    00241                 ApplicationObject *ao = static_cast<ApplicationObject*>(uo);
    00242                 // Do detailed collision test
    00243                 ao->testCollide(wf);
    00244             }
    00245         }
    00246
    00247     }
    00248     //-------------------------------------------------------------------------
    00249     Joint* World::createJoint(const String& name, Joint::JointType jtype,
    00250         ApplicationObject* obj1, ApplicationObject* obj2)
    00251     {
    00252         Joint* ret;
    00253         switch (jtype)
    00254         {
    00255         case Joint::JT_BALL:
    00256             ret = new BallJoint(jtype, obj1, obj2);
    00257             break;
    00258         case Joint::JT_HINGE:
    00259             ret = new HingeJoint(jtype, obj1, obj2);
    00260             break;
    00261         case Joint::JT_HINGE2:
    00262             ret = new Hinge2Joint(jtype, obj1, obj2);
    00263             break;
    00264         case Joint::JT_SLIDER:
    00265             ret = new SliderJoint(jtype, obj1, obj2);
    00266             break;
    00267         case Joint::JT_UNIVERSAL:
    00268             ret = new UniversalJoint(jtype, obj1, obj2);
    00269             break;
    00270
    00271         }
    00272
    00273         mJoints[name] = ret;
    00274         return ret;
    00275     }
    00276     //-------------------------------------------------------------------------
    00277     void World::setSimulationStepSize(Real step)
    00278     {
    00279         mSimulationStepSize = step;
    00280     }
    00281     //-------------------------------------------------------------------------
    00282     Real World::getSimulationStepSize(void)
    00283     {
    00284         return mSimulationStepSize;
    00285     }
    00286     //-------------------------------------------------------------------------
    00287     void World::simulationStep(Real timeElapsed)
    00288     {
    00289         /* Hmm, gives somewhat jerky results*/
    00290         static Real leftOverTime = 0.0f;
    00291
    00292         Real time = timeElapsed + leftOverTime;
    00293         unsigned int steps = (unsigned int)(time / mSimulationStepSize);
    00294         for(unsigned int  i=0; i < steps; ++i)
    00295         {
    00296             _applyCollision();
    00297             _applyDynamics(mSimulationStepSize);
    00298         }
    00299         leftOverTime = time - (steps * mSimulationStepSize);
    00300         /*
    00301         _applyCollision();
    00302         _applyDynamics(timeElapsed);
    00303         */
    00304
    00305
    00306     }
    00307     //-------------------------------------------------------------------------
    00308     OgreRefApp::Box* World::createBox(const String& name,
    00309         Real width, Real height, Real depth,
    00310         const Vector3& pos, const Quaternion& orientation)
    00311     {
    00312         OgreRefApp::Box* box = new OgreRefApp::Box(name, width, height, depth);
    00313         box->setPosition(pos);
    00314         box->setOrientation(orientation);
    00315
    00316         mObjects[name] = box;
    00317
    00318         return box;
    00319     }
    00320     //-------------------------------------------------------------------------
    00321     CollideCamera* World::createCamera(const String& name, const Vector3& pos,
    00322         const Quaternion& orientation )
    00323     {
    00324         CollideCamera* cam = new CollideCamera(name);
    00325         cam->setPosition(pos);
    00326         cam->setOrientation(orientation);
    00327
    00328         mObjects[name] = cam;
    00329
    00330         return cam;
    00331
    00332     }
    00333 }
    00334

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:41 2004