- Timestamp:
- Feb 14, 2009, 10:17:35 PM (15 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/orxonox/objects/worldentities/WorldEntity.h
r2171 r2662 22 22 * Author: 23 23 * Fabian 'x3n' Landau 24 * Reto Grieder (physics) 24 25 * Co-authors: 25 26 * ... … … 32 33 #include "OrxonoxPrereqs.h" 33 34 34 #define OGRE_FORCE_ANGLE_TYPES 35 35 #ifdef _NDEBUG 36 36 #include <OgreSceneNode.h> 37 38 #include "network/Synchronisable.h" 37 #else 38 #include <OgrePrerequisites.h> 39 #endif 40 #include "LinearMath/btMotionState.h" 41 42 #include "util/Math.h" 39 43 #include "core/BaseObject.h" 40 #include " util/Math.h"44 #include "network/synchronisable/Synchronisable.h" 41 45 42 46 namespace orxonox 43 47 { 44 class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable 48 /** 49 @brief 50 The WorldEntity represents everything that can be put in a Scene at a certain location. 51 52 It is supposed to be the base class of everything you would call an 'object' in a Scene. 53 The class itself is abstract which means you cannot use it directly. You may use StaticEntity 54 as the simplest derivative or (derived from MobileEntity) MovableEntity and ControllableEntity 55 as more advanced ones. 56 57 The basic task of the WorldEntity is provide a location, a direction and a scaling and the possibility 58 to create an entire hierarchy of derivated objects. 59 It is also the basis for the physics interface to the Bullet physics engine. 60 Every WorldEntity can have a specific collision type: @see CollisionType 61 This would then imply that every scene object could have any collision type. To limit this, you can always 62 override this->isCollisionTypeLegal(CollisionType). Return false if the collision type is not supported 63 for a specific object. 64 There is also support for attaching WorldEntities with physics to each other. Currently, the collision shape 65 of both objects simply get merged into one larger shape (for static collision type). 66 The phyiscal body that is internally stored and administrated has the following supported properties: 67 - Restitution, angular factor, linear damping, angular damping, fricition, mass and collision shape. 68 You can get more information at the corresponding set function. 69 70 Collision shapes: These are controlled by the internal WorldEntityCollisionShape. @see WorldEntityCollisionShape. 71 */ 72 class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable, public btMotionState 45 73 { 74 friend class Scene; 75 46 76 public: 47 77 WorldEntity(BaseObject* creator); … … 51 81 void registerVariables(); 52 82 53 inline Ogre::SceneNode* getNode() const83 inline const Ogre::SceneNode* getNode() const 54 84 { return this->node_; } 55 85 … … 64 94 inline void setPosition(float x, float y, float z) 65 95 { this->setPosition(Vector3(x, y, z)); } 66 inline const Vector3& getPosition() const 67 { return this->node_->getPosition(); } 68 inline const Vector3& getWorldPosition() const 69 { return this->node_->getWorldPosition(); } 70 71 virtual void translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0; 72 inline void translate(float x, float y, float z, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) 96 const Vector3& getPosition() const; 97 const Vector3& getWorldPosition() const; 98 99 void translate(const Vector3& distance, TransformSpace::Enum relativeTo = TransformSpace::Parent); 100 inline void translate(float x, float y, float z, TransformSpace::Enum relativeTo = TransformSpace::Parent) 73 101 { this->translate(Vector3(x, y, z), relativeTo); } 102 103 virtual inline const Vector3& getVelocity() const 104 { return Vector3::ZERO; } 74 105 75 106 virtual void setOrientation(const Quaternion& orientation) = 0; … … 80 111 inline void setOrientation(const Vector3& axis, const Degree& angle) 81 112 { this->setOrientation(Quaternion(angle, axis)); } 82 inline const Quaternion& getOrientation() const 83 { return this->node_->getOrientation(); } 84 inline const Quaternion& getWorldOrientation() const 85 { return this->node_->getWorldOrientation(); } 86 87 virtual void rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0; 88 inline void rotate(const Vector3& axis, const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) 113 const Quaternion& getOrientation() const; 114 const Quaternion& getWorldOrientation() const; 115 116 void rotate(const Quaternion& rotation, TransformSpace::Enum relativeTo = TransformSpace::Local); 117 inline void rotate(const Vector3& axis, const Degree& angle, TransformSpace::Enum relativeTo = TransformSpace::Local) 89 118 { this->rotate(Quaternion(angle, axis), relativeTo); } 90 inline void rotate(const Vector3& axis, const Radian& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) 91 { this->rotate(Quaternion(angle, axis), relativeTo); } 92 93 virtual void yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0; 94 inline void yaw(const Radian& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) 95 { this->yaw(Degree(angle), relativeTo); } 96 virtual void pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0; 97 inline void pitch(const Radian& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) 98 { this->pitch(Degree(angle), relativeTo); } 99 virtual void roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0; 100 inline void roll(const Radian& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) 101 { this->roll(Degree(angle), relativeTo); } 102 103 virtual void lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z) = 0; 104 virtual void setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z) = 0; 105 inline void setDirection(float x, float y, float z, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z) 119 120 inline void yaw(const Degree& angle, TransformSpace::Enum relativeTo = TransformSpace::Local) 121 { this->rotate(Quaternion(angle, Vector3::UNIT_Y), relativeTo); } 122 inline void pitch(const Degree& angle, TransformSpace::Enum relativeTo = TransformSpace::Local) 123 { this->rotate(Quaternion(angle, Vector3::UNIT_X), relativeTo); } 124 inline void roll(const Degree& angle, TransformSpace::Enum relativeTo = TransformSpace::Local) 125 { this->rotate(Quaternion(angle, Vector3::UNIT_Z), relativeTo); } 126 127 void lookAt(const Vector3& target, TransformSpace::Enum relativeTo = TransformSpace::Parent, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z); 128 void setDirection(const Vector3& direction, TransformSpace::Enum relativeTo = TransformSpace::Local, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z); 129 inline void setDirection(float x, float y, float z, TransformSpace::Enum relativeTo = TransformSpace::Local, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z) 106 130 { this->setDirection(Vector3(x, y, z), relativeTo, localDirectionVector); } 107 131 108 inline void setScale3D(const Vector3& scale) 109 { this->node_->setScale(scale); } 132 virtual void setScale3D(const Vector3& scale); 110 133 inline void setScale3D(float x, float y, float z) 111 { this-> node_->setScale(x, y, z); }112 inline const Vector3& getScale3D(void) const113 { return this->node_->getScale(); }134 { this->setScale3D(Vector3(x, y, z)); } 135 const Vector3& getScale3D(void) const; 136 const Vector3& getWorldScale3D() const; 114 137 115 138 inline void setScale(float scale) 116 { this-> node_->setScale(scale, scale, scale); }139 { this->setScale3D(scale, scale, scale); } 117 140 inline float getScale() const 118 141 { Vector3 scale = this->getScale3D(); return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1; } 142 float getWorldScale() const; 119 143 120 144 inline void scale3D(const Vector3& scale) 121 { this-> node_->scale(scale); }145 { this->setScale3D(this->getScale3D() * scale); } 122 146 inline void scale3D(float x, float y, float z) 123 { this-> node_->scale(x, y, z); }147 { this->scale3D(Vector3(x, y, z)); } 124 148 inline void scale(float scale) 125 { this->node_->scale(scale, scale, scale); } 149 { this->scale3D(scale, scale, scale); } 150 151 virtual void changedScale() {} 126 152 127 153 void attach(WorldEntity* object); 128 154 void detach(WorldEntity* object); 129 WorldEntity* getAttachedObject(unsigned int index) const;155 WorldEntity* getAttachedObject(unsigned int index); 130 156 inline const std::set<WorldEntity*>& getAttachedObjects() const 131 157 { return this->children_; } 158 159 void attachOgreObject(Ogre::MovableObject* object); 160 void detachOgreObject(Ogre::MovableObject* object); 161 Ogre::MovableObject* detachOgreObject(const Ogre::String& name); 132 162 133 163 inline void attachToParent(WorldEntity* parent) … … 138 168 { return this->parent_; } 139 169 170 void attachNode(Ogre::SceneNode* node); 171 void detachNode(Ogre::SceneNode* node); 172 void attachToNode(Ogre::SceneNode* node); 173 void detachFromNode(Ogre::SceneNode* node); 174 175 void notifyChildPropsChanged(); 176 140 177 protected: 141 178 Ogre::SceneNode* node_; 142 179 143 180 private: 144 void updateParent();145 146 181 inline void lookAt_xmlport(const Vector3& target) 147 182 { this->lookAt(target); } … … 155 190 { this->roll(angle); } 156 191 192 // network callbacks 193 void parentChanged(); 194 inline void scaleChanged() 195 { this->setScale3D(this->getScale3D()); } 196 157 197 WorldEntity* parent_; 158 198 unsigned int parentID_; 159 199 std::set<WorldEntity*> children_; 200 201 202 ///////////// 203 // Physics // 204 ///////////// 205 206 public: 207 /** 208 @brief 209 Denotes the possible types of physical objects in a Scene. 210 211 Dynamic: The object is influenced by its physical environment, like for instance little ball. 212 Kinematic: The object can only influence other dynamic objects. It's movement is coordinated by your own saying. 213 Static: Like kinematic but the object is not allowed to move during the simulation. 214 None: The object has no physics at all. 215 */ 216 enum CollisionType 217 { 218 Dynamic, 219 Kinematic, 220 Static, 221 None 222 }; 223 224 //! Tells whether the object has any connection to the Bullet physics engine. If hasPhysics() is false, the object may still have a velocity. 225 bool hasPhysics() const { return getCollisionType() != None ; } 226 //! @see CollisionType 227 bool isStatic() const { return getCollisionType() == Static ; } 228 //! @see CollisionType 229 bool isKinematic() const { return getCollisionType() == Kinematic; } 230 //! @see CollisionType 231 bool isDynamic() const { return getCollisionType() == Dynamic ; } 232 //! Tells whether physics has been activated (you can temporarily deactivate it) 233 bool isPhysicsActive() const { return this->bPhysicsActive_; } 234 bool addedToPhysicalWorld() const; 235 236 void activatePhysics(); 237 void deactivatePhysics(); 238 239 //! Returns the CollisionType. @see CollisionType. 240 inline CollisionType getCollisionType() const 241 { return this->collisionType_; } 242 void setCollisionType(CollisionType type); 243 244 void setCollisionTypeStr(const std::string& type); 245 std::string getCollisionTypeStr() const; 246 247 //! Sets the mass of this object. Note that the total mass may be influenced by attached objects! 248 inline void setMass(float mass) 249 { this->mass_ = mass; recalculateMassProps(); } 250 //! Returns the mass of this object without its children. 251 inline float getMass() const 252 { return this->mass_; } 253 254 //! Returns the total mass of this object with all its attached children. 255 inline float getTotalMass() const 256 { return this->mass_ + this->childrenMass_; } 257 258 /** 259 @brief 260 Returns the diagonal elements of the inertia tensor when calculated in local coordinates. 261 @Note 262 The local inertia tensor cannot be set, but is calculated by Bullet according to the collisionShape. 263 With compound collision shapes, an approximation is used. 264 */ 265 inline const btVector3& getLocalInertia() const 266 { return this->localInertia_; } 267 268 /** 269 @brief 270 Sets how much reaction is applied in a collision. 271 272 Consider two equal spheres colliding with equal velocities: 273 Restitution 1 means that both spheres simply reverse their velocity (no loss of energy) 274 Restitution 0 means that both spheres will immediately stop moving 275 (maximum loss of energy without violating of the preservation of momentum) 276 */ 277 inline void setRestitution(float restitution) 278 { this->restitution_ = restitution; internalSetPhysicsProps(); } 279 //! Returns the restitution parameter. @see setRestitution. 280 inline float getRestitution() const 281 { return this->restitution_; } 282 283 /** 284 @brief 285 Sets an artificial parameter that tells how much torque is applied when you apply a non-central force. 286 287 Normally the angular factor is 1, which means it's physically 'correct'. Howerver if you have a player 288 character that should not rotate when hit sideways, you can set the angular factor to 0. 289 */ 290 inline void setAngularFactor(float angularFactor) 291 { this->angularFactor_ = angularFactor; internalSetPhysicsProps(); } 292 //! Returns the angular factor. @see setAngularFactor. 293 inline float getAngularFactor() const 294 { return this->angularFactor_; } 295 296 //! Applies a mass independent damping. Velocities will simply diminish exponentially. 297 inline void setLinearDamping(float linearDamping) 298 { this->linearDamping_ = linearDamping; internalSetPhysicsProps(); } 299 //! Returns the linear damping. @see setLinearDamping. 300 inline float getLinearDamping() const 301 { return this->linearDamping_; } 302 303 //! Applies a tensor independent rotation damping. Angular velocities will simply diminish exponentially. 304 inline void setAngularDamping(float angularDamping) 305 { this->angularDamping_ = angularDamping; internalSetPhysicsProps(); } 306 //! Returns the angular damping. @see setAngularDamping. 307 inline float getAngularDamping() const 308 { return this->angularDamping_; } 309 310 //! Applies friction to the object. Friction occurs when two objects collide. 311 inline void setFriction(float friction) 312 { this->friction_ = friction; internalSetPhysicsProps(); } 313 //! Returns the amount of friction applied to the object. 314 inline float getFriction() const 315 { return this->friction_; } 316 317 void attachCollisionShape(CollisionShape* shape); 318 void detachCollisionShape(CollisionShape* shape); 319 CollisionShape* getAttachedCollisionShape(unsigned int index); 320 321 void notifyCollisionShapeChanged(); 322 void notifyChildMassChanged(); 323 324 /** 325 @brief 326 Virtual function that gets called when this object collides with another. 327 @param otherObject 328 The object this one has collided into. 329 @pram contactPoint 330 Contact point provided by Bullet. Holds more information and can me modified. See return value. 331 @Return 332 Returning false means that no modification to the contactPoint has been made. Return true otherwise! 333 @Note 334 Condition is that enableCollisionCallback() was called. 335 */ 336 virtual inline bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint) 337 { return false; } /* With false, Bullet assumes no modification to the collision objects. */ 338 339 //! Enables the collidesAgainst(.) function. The object doesn't respond to collision otherwise! 340 inline void enableCollisionCallback() 341 { this->bCollisionCallbackActive_ = true; this->collisionCallbackActivityChanged(); } 342 //! Disables the collidesAgainst(.) function. @see enableCollisionCallback() 343 inline void disableCollisionCallback() 344 { this->bCollisionCallbackActive_ = false; this->collisionCallbackActivityChanged(); } 345 //! Tells whether there could be a collision callback via collidesAgainst(.) 346 inline bool isCollisionCallbackActive() const 347 { return this->bCollisionCallbackActive_; } 348 349 //! Enables or disables collision response (default is of course on) 350 inline void setCollisionResponse(bool value) 351 { this->bCollisionResponseActive_ = value; this->collisionResponseActivityChanged(); } 352 //! Tells whether there could be a collision response 353 inline bool hasCollisionResponse() 354 { return this->bCollisionResponseActive_; } 355 356 protected: 357 /** 358 @brief 359 Function checks whether the requested collision type is legal to this object. 360 361 You can override this function in a derived class to constrain the collision to e.g. None or Dynamic. 362 A projectile may not prove very useful if there is no physical body. Simply set the CollisionType 363 in its constructor and override this method. But be careful that a derived classe's virtual functions 364 don't yet exist in the constructor if a base class. 365 */ 366 virtual bool isCollisionTypeLegal(CollisionType type) const = 0; 367 368 btRigidBody* physicalBody_; //!< Bullet rigid body. Everything physical is applied to this instance. 369 370 private: 371 void recalculateMassProps(); 372 void internalSetPhysicsProps(); 373 374 bool notifyBeingAttached(WorldEntity* newParent); 375 void notifyDetached(); 376 377 // network callbacks 378 void collisionTypeChanged(); 379 void physicsActivityChanged(); 380 void collisionCallbackActivityChanged(); 381 void collisionResponseActivityChanged(); 382 //! Network callback workaround to call a function when the value changes. 383 inline void massChanged() 384 { this->setMass(this->mass_); } 385 //! Network callback workaround to call a function when the value changes. 386 inline void restitutionChanged() 387 { this->setRestitution(this->restitution_); } 388 //! Network callback workaround to call a function when the value changes. 389 inline void angularFactorChanged() 390 { this->setAngularFactor(this->angularFactor_); } 391 //! Network callback workaround to call a function when the value changes. 392 inline void linearDampingChanged() 393 { this->setLinearDamping(this->linearDamping_); } 394 //! Network callback workaround to call a function when the value changes. 395 inline void angularDampingChanged() 396 { this->setAngularDamping(this->angularDamping_); } 397 //! Network callback workaround to call a function when the value changes. 398 inline void frictionChanged() 399 { this->setFriction(this->friction_); } 400 401 CollisionType collisionType_; //!< @see setCollisionType 402 CollisionType collisionTypeSynchronised_; //!< Network synchronised variable for collisionType_ 403 bool bPhysicsActive_; //!< @see isPhysicsActive 404 bool bPhysicsActiveSynchronised_; //!< Network synchronised variable for bPhysicsActive_ 405 //! When attaching objects hierarchically this variable tells this object (as child) whether physics was activated before attaching (because the deactivate physics while being attached). 406 bool bPhysicsActiveBeforeAttaching_; 407 WorldEntityCollisionShape* collisionShape_; //!< Attached collision shapes go here 408 btScalar mass_; //!< @see setMass 409 btVector3 localInertia_; //!< @see getLocalInertia 410 btScalar restitution_; //!< @see setRestitution 411 btScalar angularFactor_; //!< @see setAngularFactor 412 btScalar linearDamping_; //!< @see setLinearDamping 413 btScalar angularDamping_; //!< @see setAngularDamping 414 btScalar friction_; //!< @see setFriction 415 btScalar childrenMass_; //!< Sum of all the children's masses 416 bool bCollisionCallbackActive_; //!< @see enableCollisionCallback 417 bool bCollisionResponseActive_; //!< Tells whether the object should respond to collisions 160 418 }; 419 420 // Inline heavily used functions for release builds. In debug, we better avoid including OgreSceneNode here. 421 #ifdef _NDEBUG 422 inline const Vector3& WorldEntity::getPosition() const 423 { return this->node_->getPosition(); } 424 inline const Quaternion& WorldEntity::getOrientation() const 425 { return this->node_->getrOrientation(); } 426 inline const Vector3& WorldEntity::getScale3D(void) const 427 { return this->node_->getScale(); } 428 #endif 429 430 SUPER_FUNCTION(5, WorldEntity, changedScale, false); 161 431 } 162 432
Note: See TracChangeset
for help on using the changeset viewer.