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