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

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:24 2004