[1919] | 1 | #include "OgreOdePrecompiledHeaders.h" |
---|
[1923] | 2 | #include "OgreOdeWorld.h" |
---|
[1919] | 3 | |
---|
[1923] | 4 | #include <OgreSceneNode.h> |
---|
| 5 | #include <OgreMovableObject.h> |
---|
| 6 | |
---|
[1919] | 7 | #include "OgreOdeBody.h" |
---|
| 8 | #include "OgreOdeGeometry.h" |
---|
| 9 | #include "OgreOdeSpace.h" |
---|
| 10 | |
---|
| 11 | using namespace OgreOde; |
---|
| 12 | using namespace Ogre; |
---|
| 13 | |
---|
| 14 | CollisionListener* World::_collision_listener = 0; |
---|
| 15 | //------------------------------------------------------------------------------------------------ |
---|
| 16 | void World::setCollisionListener(CollisionListener* collision_listener) |
---|
| 17 | { |
---|
| 18 | _collision_listener = collision_listener; |
---|
| 19 | } |
---|
| 20 | //------------------------------------------------------------------------------------------------ |
---|
| 21 | CollisionListener* World::getCollisionListener() |
---|
| 22 | { |
---|
| 23 | return _collision_listener; |
---|
| 24 | } |
---|
| 25 | //------------------------------------------------------------------------------------------------ |
---|
| 26 | World::World(SceneManager* manager) : |
---|
| 27 | _show_debug_geoms (false), |
---|
| 28 | _show_debug_contact (false), |
---|
| 29 | _manager (manager) |
---|
| 30 | { |
---|
| 31 | #if ODE_VERSION_MINOR > 9 |
---|
| 32 | dInitODE2(0); |
---|
| 33 | dAllocateODEDataForThread(dAllocateMaskAll); |
---|
| 34 | #endif |
---|
| 35 | |
---|
| 36 | |
---|
| 37 | _world = dWorldCreate(); |
---|
| 38 | _contacts = dJointGroupCreate(0); |
---|
| 39 | |
---|
| 40 | _default_space = new HashTableSpace(this); |
---|
| 41 | _default_space->setAutoCleanup(false); |
---|
| 42 | _default_space->setInternalCollisions(true); |
---|
| 43 | |
---|
| 44 | setDamping(0.0,0.0); |
---|
| 45 | setHistorySize (1); |
---|
| 46 | |
---|
| 47 | |
---|
| 48 | } |
---|
| 49 | //------------------------------------------------------------------------------------------------ |
---|
| 50 | void World::setHistorySize(size_t historySize) |
---|
| 51 | { |
---|
| 52 | _history_size = historySize; |
---|
| 53 | |
---|
| 54 | MaintainedItemIterator<Body> it = _body_list.getIterator(); |
---|
| 55 | while(!it.end ()) |
---|
| 56 | { |
---|
| 57 | Body * const b = (Body *) (it.getNext ()); |
---|
| 58 | b->_historyResize(historySize); |
---|
| 59 | } |
---|
| 60 | |
---|
| 61 | } |
---|
| 62 | //------------------------------------------------------------------------------------------------ |
---|
| 63 | size_t World::getHistorySize() const |
---|
| 64 | { |
---|
| 65 | return _history_size; |
---|
| 66 | } |
---|
| 67 | //------------------------------------------------------------------------------------------------ |
---|
| 68 | void World::setGravity(const Ogre::Vector3& gravity) |
---|
| 69 | { |
---|
| 70 | dWorldSetGravity(_world,(dReal)gravity.x,(dReal)gravity.y,(dReal)gravity.z); |
---|
| 71 | } |
---|
| 72 | //------------------------------------------------------------------------------------------------ |
---|
| 73 | const Ogre::Vector3& World::getGravity() |
---|
| 74 | { |
---|
| 75 | dVector3 g; |
---|
| 76 | dWorldGetGravity(_world,g); |
---|
| 77 | _gravity.x = (Real)g[0]; |
---|
| 78 | _gravity.y = (Real)g[1]; |
---|
| 79 | _gravity.z = (Real)g[2]; |
---|
| 80 | return _gravity; |
---|
| 81 | } |
---|
| 82 | //------------------------------------------------------------------------------------------------ |
---|
| 83 | void World::setERP(Real erp) |
---|
| 84 | { |
---|
| 85 | dWorldSetERP(_world,(dReal)erp); |
---|
| 86 | } |
---|
| 87 | //------------------------------------------------------------------------------------------------ |
---|
| 88 | Real World::getERP() |
---|
| 89 | { |
---|
| 90 | return (Real)dWorldGetERP(_world); |
---|
| 91 | } |
---|
| 92 | //------------------------------------------------------------------------------------------------ |
---|
| 93 | void World::setCFM(Real cfm) |
---|
| 94 | { |
---|
| 95 | dWorldSetCFM(_world,(dReal)cfm); |
---|
| 96 | } |
---|
| 97 | //------------------------------------------------------------------------------------------------ |
---|
| 98 | Real World::getCFM() |
---|
| 99 | { |
---|
| 100 | return (Real)dWorldGetCFM(_world); |
---|
| 101 | } |
---|
| 102 | //------------------------------------------------------------------------------------------------ |
---|
| 103 | void World::setAutoSleep(bool auto_sleep) |
---|
| 104 | { |
---|
| 105 | dWorldSetAutoDisableFlag(_world,(auto_sleep)?1:0); |
---|
| 106 | } |
---|
| 107 | //------------------------------------------------------------------------------------------------ |
---|
| 108 | bool World::getAutoSleep() |
---|
| 109 | { |
---|
| 110 | return (dWorldGetAutoDisableFlag(_world))?true:false; |
---|
| 111 | } |
---|
| 112 | //------------------------------------------------------------------------------------------------ |
---|
| 113 | void World::setAutoSleepLinearThreshold(Real linear_threshold) |
---|
| 114 | { |
---|
| 115 | dWorldSetAutoDisableLinearThreshold(_world,(dReal)linear_threshold); |
---|
| 116 | } |
---|
| 117 | //------------------------------------------------------------------------------------------------ |
---|
| 118 | Real World::getAutoSleepLinearThreshold() |
---|
| 119 | { |
---|
| 120 | return (Real)dWorldGetAutoDisableLinearThreshold(_world); |
---|
| 121 | } |
---|
| 122 | //------------------------------------------------------------------------------------------------ |
---|
| 123 | void World::setAutoSleepAngularThreshold(Real angular_threshold) |
---|
| 124 | { |
---|
| 125 | dWorldSetAutoDisableAngularThreshold(_world,(dReal)angular_threshold); |
---|
| 126 | } |
---|
| 127 | //------------------------------------------------------------------------------------------------ |
---|
| 128 | Real World::getAutoSleepAngularThreshold() |
---|
| 129 | { |
---|
| 130 | return (Real)dWorldGetAutoDisableAngularThreshold(_world); |
---|
| 131 | } |
---|
| 132 | //------------------------------------------------------------------------------------------------ |
---|
| 133 | void World::setAutoSleepSteps(int steps) |
---|
| 134 | { |
---|
| 135 | dWorldSetAutoDisableSteps(_world,steps); |
---|
| 136 | } |
---|
| 137 | //------------------------------------------------------------------------------------------------ |
---|
| 138 | int World::getAutoSleepSteps() |
---|
| 139 | { |
---|
| 140 | return dWorldGetAutoDisableSteps(_world); |
---|
| 141 | } |
---|
| 142 | //------------------------------------------------------------------------------------------------ |
---|
| 143 | void World::setAutoSleepTime(Real time) |
---|
| 144 | { |
---|
| 145 | dWorldSetAutoDisableTime(_world,(dReal)time); |
---|
| 146 | } |
---|
| 147 | //------------------------------------------------------------------------------------------------ |
---|
| 148 | Real World::getAutoSleepTime() |
---|
| 149 | { |
---|
| 150 | return (Real)dWorldGetAutoDisableTime(_world); |
---|
| 151 | } |
---|
| 152 | //------------------------------------------------------------------------------------------------ |
---|
| 153 | void World::setAutoSleepAverageSamplesCount(unsigned int time) |
---|
| 154 | { |
---|
| 155 | dWorldSetAutoDisableAverageSamplesCount(_world, time); |
---|
| 156 | } |
---|
| 157 | //------------------------------------------------------------------------------------------------ |
---|
| 158 | size_t World::getAutoSleepAverageSamplesCount() |
---|
| 159 | { |
---|
[1922] | 160 | return dWorldGetAutoDisableAverageSamplesCount(_world); |
---|
[1919] | 161 | } |
---|
| 162 | //------------------------------------------------------------------------------------------------ |
---|
| 163 | void World::setContactCorrectionVelocity(Real velocity) |
---|
| 164 | { |
---|
| 165 | dWorldSetContactMaxCorrectingVel(_world,(dReal)velocity); |
---|
| 166 | } |
---|
| 167 | //------------------------------------------------------------------------------------------------ |
---|
| 168 | void World::setContactSurfaceLayer(Real layer) |
---|
| 169 | { |
---|
| 170 | dWorldSetContactSurfaceLayer(_world,(dReal)layer); |
---|
| 171 | } |
---|
| 172 | |
---|
| 173 | //------------------------------------------------------------------------------------------------ |
---|
| 174 | void World::collisionCallback(void *data,dGeomID geom_a,dGeomID geom_b) |
---|
| 175 | { |
---|
| 176 | const bool a_space = (dGeomIsSpace(geom_a))?true:false; |
---|
| 177 | const bool b_space = (dGeomIsSpace(geom_b))?true:false; |
---|
| 178 | |
---|
| 179 | void* const ptr_a = dGeomGetData(geom_a); |
---|
| 180 | void* const ptr_b = dGeomGetData(geom_b); |
---|
| 181 | |
---|
| 182 | if(a_space || b_space ) |
---|
| 183 | { |
---|
| 184 | // Collide a space with a space |
---|
| 185 | if(a_space && b_space) |
---|
| 186 | static_cast<Space*>(ptr_a)->collide(static_cast<Space*>(ptr_b),data); |
---|
| 187 | else if(a_space) |
---|
| 188 | static_cast<Space*>(ptr_a)->collide(static_cast<Geometry*>(ptr_b),data); |
---|
| 189 | else |
---|
| 190 | static_cast<Space*>(ptr_b)->collide(static_cast<Geometry*>(ptr_a),data); |
---|
| 191 | |
---|
| 192 | // Collide geometries internal to the spaces |
---|
| 193 | if(a_space) |
---|
| 194 | static_cast<Space*>(ptr_a)->collide(data); |
---|
| 195 | |
---|
| 196 | if(b_space) |
---|
| 197 | static_cast<Space*>(ptr_b)->collide(data); |
---|
| 198 | } |
---|
| 199 | else |
---|
| 200 | { |
---|
| 201 | // Collide a geom with a geom, i.e. generate contacts |
---|
| 202 | static_cast<Geometry*>(ptr_a)->collide(static_cast<Geometry*>(ptr_b),_collision_listener); |
---|
| 203 | } |
---|
| 204 | } |
---|
| 205 | //------------------------------------------------------------------------------------------------ |
---|
| 206 | Body* World::findBody(SceneNode* node) |
---|
| 207 | { |
---|
| 208 | Body* body = 0; |
---|
| 209 | for(int i = 0;i < node->numAttachedObjects();i++) |
---|
| 210 | { |
---|
| 211 | MovableObject* obj = node->getAttachedObject(i); |
---|
| 212 | if(obj) |
---|
| 213 | { |
---|
| 214 | if(obj->getMovableType() == Ogre::String("OgreOde::Body")) |
---|
| 215 | { |
---|
| 216 | body = static_cast<Body*>(obj); |
---|
| 217 | break; |
---|
| 218 | } |
---|
| 219 | } |
---|
| 220 | } |
---|
| 221 | return body; |
---|
| 222 | } |
---|
| 223 | //------------------------------------------------------------------------------------------------ |
---|
| 224 | Body* World::findBody(const Ogre::String& name) |
---|
| 225 | { |
---|
| 226 | Body *b = 0; |
---|
| 227 | MaintainedItemIterator<Body> it = _body_list.getIterator(); |
---|
| 228 | while(!it.end ()) |
---|
| 229 | { |
---|
| 230 | b = (Body*) (it.getNext ()); |
---|
| 231 | if(b->getName() == name) |
---|
| 232 | return b; |
---|
| 233 | } |
---|
| 234 | return 0; |
---|
| 235 | } |
---|
| 236 | //------------------------------------------------------------------------------------------------ |
---|
| 237 | void World::setDefaultSpace(Space* space) |
---|
| 238 | { |
---|
| 239 | delete _default_space; |
---|
| 240 | _default_space = space; |
---|
| 241 | } |
---|
| 242 | //------------------------------------------------------------------------------------------------ |
---|
| 243 | void World::setQuickStepIterations(int iterations) |
---|
| 244 | { |
---|
| 245 | dWorldSetQuickStepNumIterations(_world,iterations); |
---|
| 246 | } |
---|
| 247 | //------------------------------------------------------------------------------------------------ |
---|
| 248 | int World::getQuickStepIterations() |
---|
| 249 | { |
---|
| 250 | return dWorldGetQuickStepNumIterations(_world); |
---|
| 251 | } |
---|
| 252 | //------------------------------------------------------------------------------------------------ |
---|
| 253 | void World::setShowDebugGeometries(bool show) |
---|
| 254 | { |
---|
| 255 | _body_list.setDebug(show); |
---|
| 256 | _geometry_list.setDebug(show); |
---|
| 257 | _show_debug_geoms = show; |
---|
| 258 | } |
---|
| 259 | //------------------------------------------------------------------------------------------------ |
---|
| 260 | void World::setShowDebugContact(bool show) |
---|
| 261 | { |
---|
| 262 | _geometry_list.setDebugContact(show); |
---|
| 263 | _show_debug_contact = show; |
---|
| 264 | } |
---|
| 265 | //------------------------------------------------------------------------------------------------ |
---|
| 266 | void World::setDamping(Real linear_damping,Real angular_damping) |
---|
| 267 | { |
---|
| 268 | _linear_damping = -(dReal)linear_damping; |
---|
| 269 | _angular_damping = -(dReal)angular_damping; |
---|
| 270 | } |
---|
| 271 | //------------------------------------------------------------------------------------------------ |
---|
| 272 | Real World::getLinearDamping() |
---|
| 273 | { |
---|
| 274 | return -(Real)_linear_damping; |
---|
| 275 | } |
---|
| 276 | //------------------------------------------------------------------------------------------------ |
---|
| 277 | Real World::getAngularDamping() |
---|
| 278 | { |
---|
| 279 | return -(Real)_angular_damping; |
---|
| 280 | } |
---|
| 281 | //------------------------------------------------------------------------------------------------ |
---|
| 282 | World::~World() |
---|
| 283 | { |
---|
| 284 | delete _default_space; |
---|
| 285 | dJointGroupDestroy(_contacts); |
---|
| 286 | dWorldDestroy(_world); |
---|
| 287 | dCloseODE(); |
---|
| 288 | } |
---|