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