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