- Timestamp:
- Nov 29, 2008, 12:45:19 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/physics/src/orxonox/objects/worldentities/WorldEntity.cc
r2292 r2298 41 41 42 42 #include "objects/Scene.h" 43 44 #include "StaticEntity.h"45 43 46 44 namespace orxonox … … 70 68 // Default behaviour does not include physics 71 69 this->physicalBody_ = 0; 70 updateCollisionType(); 72 71 73 72 this->registerVariables(); … … 81 80 if (this->getScene()->getSceneManager()) 82 81 this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName()); 83 84 // Physics is not guaranteed, so check first 85 if (this->physicalBody_) 86 { 87 if (this->physicalBody_->isInWorld()) 88 this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_); 89 if (this->physicalBody_->getCollisionShape()) 90 delete this->physicalBody_->getCollisionShape(); 91 delete this->physicalBody_; 92 } 82 83 this->setCollisionType(None); 93 84 } 94 85 } … … 108 99 XMLPortParam(WorldEntity, "scale", setScale, getScale, xmlelement, mode); 109 100 101 XMLPortParam(WorldEntity, "collisionType", setCollisionTypeStr, getCollisionTypeStr, xmlelement, mode); 110 102 XMLPortParam(WorldEntity, "collisionRadius", setCollisionRadius, getCollisionRadius, xmlelement, mode); 111 XMLPortParam(WorldEntity, "collisionType", setCollisionTypeStr, getCollisionTypeStr, xmlelement, mode);112 103 XMLPortParam(WorldEntity, "mass", setMass, getMass, xmlelement, mode); 113 104 114 if (this->physicalBody_) 105 XMLPortObject(WorldEntity, WorldEntity, "attached", attach, getAttachedObject, xmlelement, mode); 106 107 // Add the physical after loading because we cannot change its attributes without removing. 108 if (getCollisionType() != None) 115 109 this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_); 116 117 XMLPortObject(WorldEntity, WorldEntity, "attached", attach, getAttachedObject, xmlelement, mode);118 110 } 119 111 … … 200 192 } 201 193 202 void WorldEntity::createPhysicalBody()203 {204 // Note: The motion state will be configured in a derived class.205 btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, 0, btVector3(0,0,0));206 this->physicalBody_ = new btRigidBody(bodyConstructionInfo);207 }208 209 194 float WorldEntity::getMass() 210 195 { 211 if (! this->physicalBody_)196 if (!checkPhysics()) 212 197 return 0.0f; 213 198 … … 217 202 void WorldEntity::setMass(float mass) 218 203 { 219 if (!this->physicalBody_) 220 this->createPhysicalBody(); 221 222 this->physicalBody_->setMassProps(mass, btVector3(0,0,0)); 223 } 224 225 void WorldEntity::setCollisionType(WorldEntity::CollisionType type) 226 { 227 if (!this->physicalBody_) 228 this->createPhysicalBody(); 229 204 if (!checkPhysics()) 205 return; 206 else if (this->physicalBody_->isInWorld()) 207 { 208 CCOUT(2) << "Cannot set the physical mass at run time." << std::endl; 209 assert(false); 210 } 211 else 212 { 213 this->physicalBody_->setMassProps(mass, btVector3(0,0,0)); 214 updateCollisionType(); 215 } 216 } 217 218 void WorldEntity::setCollisionType(CollisionType type) 219 { 220 // Check first whether we have to create or destroy. 221 if (type != None && this->collisionType_ == None) 222 { 223 // Create new rigid body 224 btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, 0, btVector3(0,0,0)); 225 this->physicalBody_ = new btRigidBody(bodyConstructionInfo); 226 this->physicalBody_->setUserPointer(this); 227 228 // Adjust parameters according to the node 229 btTransform nodeTransform; 230 //this-> 231 } 232 else if (type == None && this->collisionType_ != None) 233 { 234 // Destroy rigid body 235 if (this->physicalBody_->isInWorld()) 236 this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_); 237 if (this->physicalBody_->getCollisionShape()) 238 delete this->physicalBody_->getCollisionShape(); 239 delete this->physicalBody_; 240 this->physicalBody_ = 0; 241 this->collisionType_ = None; 242 return; 243 } 244 245 // Check for type legality. Could be StaticEntity or MovableEntity 246 if (!this->isCollisionTypeLegal(type)) 247 return; // exception gets issued anyway 248 249 // Change type 230 250 switch (type) 231 251 { … … 239 259 this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT); 240 260 break; 241 } 242 } 243 244 WorldEntity::CollisionType WorldEntity::getCollisionType() 261 case None: 262 return; // this->collisionType_ was None too 263 } 264 265 // Mass non zero is a bad idea for kinematic and static objects 266 if ((type == Kinematic || type == Static) && getMass() != 0.0f) 267 this->setMass(0.0f); 268 // Mass zero is not such a good idea for dynamic objects 269 else if (type == Dynamic && getMass() == 0.0f) 270 this->setMass(1.0f); 271 272 // finally update our variable for faster checks 273 updateCollisionType(); 274 } 275 276 void WorldEntity::updateCollisionType() 245 277 { 246 278 if (!this->physicalBody_) 247 ThrowException(Argument, "Cannot retrieve collision type of a non physical object."); 248 249 int flags = this->physicalBody_->getCollisionFlags(); 250 if (flags & btCollisionObject::CF_STATIC_OBJECT) 251 return Static; 252 else if (flags & btCollisionObject::CF_KINEMATIC_OBJECT) 253 return Kinematic; 254 else 255 return Dynamic; 256 } 257 258 void WorldEntity::setCollisionTypeStr(const std::string& type) 259 { 260 std::string lower = getLowercase(type); 261 if (lower == "dynamic") 262 setCollisionType(Dynamic); 263 else if (lower == "static") 264 setCollisionType(Static); 265 else if (lower == "kinematic") 266 setCollisionType(Kinematic); 267 else 268 ThrowException(Argument, std::string("Trying to set an unknown collision type: '") + type + "'."); 279 this->collisionType_ = None; 280 else if (this->physicalBody_->isKinematicObject()) 281 this->collisionType_ = Kinematic; 282 else if (this->physicalBody_->isStaticObject()) 283 this->collisionType_ = Static; 284 else 285 this->collisionType_ = Dynamic; 286 } 287 288 void WorldEntity::setCollisionTypeStr(const std::string& typeStr) 289 { 290 std::string typeStrLower = getLowercase(typeStr); 291 CollisionType type; 292 if (typeStrLower == "dynamic") 293 type = Dynamic; 294 else if (typeStrLower == "static") 295 type = Static; 296 else if (typeStrLower == "kinematic") 297 type = Kinematic; 298 else if (typeStrLower == "none") 299 type = None; 300 else 301 ThrowException(ParseError, std::string("Attempting to set an unknown collision type: '") + typeStr + "'."); 302 this->setCollisionType(type); 269 303 } 270 304 … … 273 307 switch (this->getCollisionType()) 274 308 { 275 case Dynamic: 276 return "dynamic"; 277 case Kinematic: 278 return "kinematic"; 279 case Static: 280 return "static"; 281 default: 282 ThrowException(Argument, "Encountered unknown collision Type."); 309 case Dynamic: 310 return "dynamic"; 311 case Kinematic: 312 return "kinematic"; 313 case Static: 314 return "static"; 315 case None: 316 return "none"; 317 default: 318 assert(false); 319 return ""; 283 320 } 284 321 } … … 286 323 void WorldEntity::setCollisionRadius(float radius) 287 324 { 288 if (! this->physicalBody_)289 createPhysicalBody();325 if (!checkPhysics()) 326 return; 290 327 291 328 // destroy old one first … … 299 336 float WorldEntity::getCollisionRadius() 300 337 { 301 if ( this->physicalBody_)338 if (checkPhysics()) 302 339 { 303 340 btSphereShape* sphere = dynamic_cast<btSphereShape*>(this->physicalBody_->getCollisionShape()); … … 307 344 return 0.0f; 308 345 } 346 347 bool WorldEntity::checkPhysics() 348 { 349 if (!this->physicalBody_) 350 { 351 assert(this->getCollisionType() == None); 352 COUT(2) << "WorldEntity was not fitted with physics, cannot set phyiscal property." << std::endl; 353 return false; 354 } 355 else 356 return true; 357 } 309 358 }
Note: See TracChangeset
for help on using the changeset viewer.