| [2072] | 1 | /* | 
|---|
 | 2 |  *   ORXONOX - the hottest 3D action shooter ever to exist | 
|---|
 | 3 |  *                    > www.orxonox.net < | 
|---|
 | 4 |  * | 
|---|
 | 5 |  * | 
|---|
 | 6 |  *   License notice: | 
|---|
 | 7 |  * | 
|---|
 | 8 |  *   This program is free software; you can redistribute it and/or | 
|---|
 | 9 |  *   modify it under the terms of the GNU General Public License | 
|---|
 | 10 |  *   as published by the Free Software Foundation; either version 2 | 
|---|
 | 11 |  *   of the License, or (at your option) any later version. | 
|---|
 | 12 |  * | 
|---|
 | 13 |  *   This program is distributed in the hope that it will be useful, | 
|---|
 | 14 |  *   but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
 | 15 |  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
 | 16 |  *   GNU General Public License for more details. | 
|---|
 | 17 |  * | 
|---|
 | 18 |  *   You should have received a copy of the GNU General Public License | 
|---|
 | 19 |  *   along with this program; if not, write to the Free Software | 
|---|
 | 20 |  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
|---|
 | 21 |  * | 
|---|
 | 22 |  *   Author: | 
|---|
 | 23 |  *      Fabian 'x3n' Landau | 
|---|
| [2662] | 24 |  *      Reto Grieder (physics) | 
|---|
| [2072] | 25 |  *   Co-authors: | 
|---|
 | 26 |  *      ... | 
|---|
 | 27 |  * | 
|---|
 | 28 |  */ | 
|---|
 | 29 |  | 
|---|
 | 30 | #ifndef _WorldEntity_H__ | 
|---|
 | 31 | #define _WorldEntity_H__ | 
|---|
 | 32 |  | 
|---|
 | 33 | #include "OrxonoxPrereqs.h" | 
|---|
 | 34 |  | 
|---|
| [3196] | 35 | #ifdef ORXONOX_RELEASE | 
|---|
 | 36 | #  include <OgreSceneNode.h> | 
|---|
| [2662] | 37 | #endif | 
|---|
| [3196] | 38 | #include <LinearMath/btMotionState.h> | 
|---|
| [10726] | 39 | #include <LinearMath/btAlignedAllocator.h> | 
|---|
| [2072] | 40 |  | 
|---|
| [2662] | 41 | #include "util/Math.h" | 
|---|
| [3196] | 42 | #include "util/OgreForwardRefs.h" | 
|---|
| [2072] | 43 | #include "core/BaseObject.h" | 
|---|
| [2662] | 44 | #include "network/synchronisable/Synchronisable.h" | 
|---|
| [2072] | 45 |  | 
|---|
 | 46 | namespace orxonox | 
|---|
 | 47 | { | 
|---|
| [2662] | 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 | 
|---|
| [6417] | 58 |         to create an entire hierarchy of derived objects. | 
|---|
| [2662] | 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). | 
|---|
| [6417] | 66 |         The physical body that is internally stored and administrated has the following supported properties: | 
|---|
 | 67 |         - Restitution, angular factor, linear damping, angular damping, friction, mass and collision shape. | 
|---|
| [2662] | 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 |     */ | 
|---|
| [6501] | 72 |     class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable, public btMotionState | 
|---|
| [2072] | 73 |     { | 
|---|
| [2662] | 74 |         friend class Scene; | 
|---|
 | 75 |  | 
|---|
| [2072] | 76 |         public: | 
|---|
| [10726] | 77 |             BT_DECLARE_ALIGNED_ALLOCATOR(); | 
|---|
 | 78 |  | 
|---|
| [3196] | 79 |             // Define our own transform space enum to avoid Ogre includes here | 
|---|
 | 80 |             /** | 
|---|
 | 81 |             @brief | 
|---|
 | 82 |                 Enumeration denoting the spaces which a transform can be relative to. | 
|---|
 | 83 |             */ | 
|---|
 | 84 |             enum TransformSpace | 
|---|
 | 85 |             { | 
|---|
 | 86 |                 //! Transform is relative to the local space | 
|---|
 | 87 |                 Local, | 
|---|
 | 88 |                 //! Transform is relative to the space of the parent node | 
|---|
 | 89 |                 Parent, | 
|---|
 | 90 |                 //! Transform is relative to world space | 
|---|
 | 91 |                 World | 
|---|
 | 92 |             }; | 
|---|
 | 93 |  | 
|---|
 | 94 |         public: | 
|---|
| [9667] | 95 |             WorldEntity(Context* context); | 
|---|
| [2072] | 96 |             virtual ~WorldEntity(); | 
|---|
 | 97 |  | 
|---|
 | 98 |             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); | 
|---|
 | 99 |  | 
|---|
| [2662] | 100 |             inline const Ogre::SceneNode* getNode() const | 
|---|
| [2072] | 101 |                 { return this->node_; } | 
|---|
 | 102 |  | 
|---|
 | 103 |             static const Vector3 FRONT; | 
|---|
 | 104 |             static const Vector3 BACK; | 
|---|
 | 105 |             static const Vector3 LEFT; | 
|---|
 | 106 |             static const Vector3 RIGHT; | 
|---|
 | 107 |             static const Vector3 DOWN; | 
|---|
 | 108 |             static const Vector3 UP; | 
|---|
| [7163] | 109 |  | 
|---|
| [6524] | 110 |             virtual void changedActivity(void); | 
|---|
 | 111 |             virtual void changedVisibility(void); | 
|---|
| [2072] | 112 |  | 
|---|
 | 113 |             virtual void setPosition(const Vector3& position) = 0; | 
|---|
 | 114 |             inline void setPosition(float x, float y, float z) | 
|---|
 | 115 |                 { this->setPosition(Vector3(x, y, z)); } | 
|---|
| [2662] | 116 |             const Vector3& getPosition() const; | 
|---|
 | 117 |             const Vector3& getWorldPosition() const; | 
|---|
| [2072] | 118 |  | 
|---|
| [3196] | 119 |             void translate(const Vector3& distance, TransformSpace relativeTo = WorldEntity::Parent); | 
|---|
 | 120 |             inline void translate(float x, float y, float z, TransformSpace relativeTo = WorldEntity::Parent) | 
|---|
| [2072] | 121 |                 { this->translate(Vector3(x, y, z), relativeTo); } | 
|---|
 | 122 |  | 
|---|
| [2662] | 123 |             virtual inline const Vector3& getVelocity() const | 
|---|
 | 124 |                 { return Vector3::ZERO; } | 
|---|
 | 125 |  | 
|---|
| [2072] | 126 |             virtual void setOrientation(const Quaternion& orientation) = 0; | 
|---|
 | 127 |             inline void setOrientation(float w, float x, float y, float z) | 
|---|
 | 128 |                 { this->setOrientation(Quaternion(w, x, y, z)); } | 
|---|
 | 129 |             inline void setOrientation(const Vector3& axis, const Radian& angle) | 
|---|
 | 130 |                 { this->setOrientation(Quaternion(angle, axis)); } | 
|---|
 | 131 |             inline void setOrientation(const Vector3& axis, const Degree& angle) | 
|---|
 | 132 |                 { this->setOrientation(Quaternion(angle, axis)); } | 
|---|
| [2662] | 133 |             const Quaternion& getOrientation() const; | 
|---|
 | 134 |             const Quaternion& getWorldOrientation() const; | 
|---|
| [2072] | 135 |  | 
|---|
| [3196] | 136 |             void rotate(const Quaternion& rotation, TransformSpace relativeTo = WorldEntity::Local); | 
|---|
 | 137 |             inline void rotate(const Vector3& axis, const Degree& angle, TransformSpace relativeTo = WorldEntity::Local) | 
|---|
| [2072] | 138 |                 { this->rotate(Quaternion(angle, axis), relativeTo); } | 
|---|
 | 139 |  | 
|---|
| [3196] | 140 |             inline void yaw(const Degree& angle, TransformSpace relativeTo = WorldEntity::Local) | 
|---|
| [2662] | 141 |                 { this->rotate(Quaternion(angle, Vector3::UNIT_Y), relativeTo); } | 
|---|
| [3196] | 142 |             inline void pitch(const Degree& angle, TransformSpace relativeTo = WorldEntity::Local) | 
|---|
| [2662] | 143 |                 { this->rotate(Quaternion(angle, Vector3::UNIT_X), relativeTo); } | 
|---|
| [3196] | 144 |             inline void roll(const Degree& angle, TransformSpace relativeTo = WorldEntity::Local) | 
|---|
| [2662] | 145 |                 { this->rotate(Quaternion(angle, Vector3::UNIT_Z), relativeTo); } | 
|---|
| [2072] | 146 |  | 
|---|
| [3196] | 147 |             void lookAt(const Vector3& target, TransformSpace relativeTo = WorldEntity::Parent, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z); | 
|---|
 | 148 |             void setDirection(const Vector3& direction, TransformSpace relativeTo = WorldEntity::Local, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z); | 
|---|
 | 149 |             inline void setDirection(float x, float y, float z, TransformSpace relativeTo = WorldEntity::Local, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z) | 
|---|
| [2072] | 150 |                 { this->setDirection(Vector3(x, y, z), relativeTo, localDirectionVector); } | 
|---|
 | 151 |  | 
|---|
| [2662] | 152 |             virtual void setScale3D(const Vector3& scale); | 
|---|
| [2072] | 153 |             inline void setScale3D(float x, float y, float z) | 
|---|
| [2662] | 154 |                 { this->setScale3D(Vector3(x, y, z)); } | 
|---|
| [3301] | 155 |             const Vector3& getScale3D() const; | 
|---|
| [2662] | 156 |             const Vector3& getWorldScale3D() const; | 
|---|
| [2072] | 157 |  | 
|---|
 | 158 |             inline void setScale(float scale) | 
|---|
| [2662] | 159 |                 { this->setScale3D(scale, scale, scale); } | 
|---|
| [2072] | 160 |             inline float getScale() const | 
|---|
 | 161 |                 { Vector3 scale = this->getScale3D(); return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1; } | 
|---|
| [2662] | 162 |             float getWorldScale() const; | 
|---|
| [2072] | 163 |  | 
|---|
 | 164 |             inline void scale3D(const Vector3& scale) | 
|---|
| [2662] | 165 |                 { this->setScale3D(this->getScale3D() * scale); } | 
|---|
| [2072] | 166 |             inline void scale3D(float x, float y, float z) | 
|---|
| [2662] | 167 |                 { this->scale3D(Vector3(x, y, z)); } | 
|---|
| [2072] | 168 |             inline void scale(float scale) | 
|---|
| [2662] | 169 |                 { this->scale3D(scale, scale, scale); } | 
|---|
| [2072] | 170 |  | 
|---|
| [2662] | 171 |             virtual void changedScale() {} | 
|---|
 | 172 |  | 
|---|
| [2072] | 173 |             void attach(WorldEntity* object); | 
|---|
 | 174 |             void detach(WorldEntity* object); | 
|---|
| [2662] | 175 |             WorldEntity* getAttachedObject(unsigned int index); | 
|---|
| [2072] | 176 |             inline const std::set<WorldEntity*>& getAttachedObjects() const | 
|---|
 | 177 |                 { return this->children_; } | 
|---|
 | 178 |  | 
|---|
| [3196] | 179 |             void attachOgreObject(Ogre::MovableObject*  object); | 
|---|
 | 180 |             void attachOgreObject(Ogre::BillboardSet*   object); | 
|---|
 | 181 |             void attachOgreObject(Ogre::Camera*         object); | 
|---|
 | 182 |             void attachOgreObject(Ogre::Entity*         object); | 
|---|
 | 183 |             void attachOgreObject(Ogre::ParticleSystem* object); | 
|---|
 | 184 |  | 
|---|
 | 185 |             void detachOgreObject(Ogre::MovableObject*  object); | 
|---|
 | 186 |             void detachOgreObject(Ogre::BillboardSet*   object); | 
|---|
 | 187 |             void detachOgreObject(Ogre::Camera*         object); | 
|---|
 | 188 |             void detachOgreObject(Ogre::Entity*         object); | 
|---|
 | 189 |             void detachOgreObject(Ogre::ParticleSystem* object); | 
|---|
 | 190 |  | 
|---|
| [2662] | 191 |             Ogre::MovableObject* detachOgreObject(const Ogre::String& name); | 
|---|
 | 192 |  | 
|---|
| [2072] | 193 |             inline void attachToParent(WorldEntity* parent) | 
|---|
 | 194 |                 { parent->attach(this); } | 
|---|
 | 195 |             inline void detachFromParent() | 
|---|
 | 196 |                 { if (this->parent_) { this->parent_->detach(this); } } | 
|---|
 | 197 |             inline WorldEntity* getParent() const | 
|---|
 | 198 |                 { return this->parent_; } | 
|---|
 | 199 |  | 
|---|
| [2662] | 200 |             void attachNode(Ogre::SceneNode* node); | 
|---|
 | 201 |             void detachNode(Ogre::SceneNode* node); | 
|---|
 | 202 |             void attachToNode(Ogre::SceneNode* node); | 
|---|
 | 203 |             void detachFromNode(Ogre::SceneNode* node); | 
|---|
 | 204 |  | 
|---|
| [3077] | 205 |             inline void setDeleteWithParent(bool value) | 
|---|
 | 206 |                 { this->bDeleteWithParent_ = value; } | 
|---|
 | 207 |             inline bool getDeleteWithParent() const | 
|---|
 | 208 |                 { return this->bDeleteWithParent_; } | 
|---|
 | 209 |  | 
|---|
| [2662] | 210 |             void notifyChildPropsChanged(); | 
|---|
 | 211 |  | 
|---|
| [2072] | 212 |         protected: | 
|---|
| [2851] | 213 |             virtual void parentChanged() {} | 
|---|
 | 214 |  | 
|---|
| [2072] | 215 |             Ogre::SceneNode* node_; | 
|---|
 | 216 |  | 
|---|
 | 217 |         private: | 
|---|
| [7163] | 218 |             void registerVariables(); | 
|---|
| [7910] | 219 |  | 
|---|
| [2072] | 220 |             inline void lookAt_xmlport(const Vector3& target) | 
|---|
 | 221 |                 { this->lookAt(target); } | 
|---|
 | 222 |             inline void setDirection_xmlport(const Vector3& direction) | 
|---|
 | 223 |                 { this->setDirection(direction); } | 
|---|
 | 224 |             inline void yaw_xmlport(const Degree& angle) | 
|---|
 | 225 |                 { this->yaw(angle); } | 
|---|
 | 226 |             inline void pitch_xmlport(const Degree& angle) | 
|---|
 | 227 |                 { this->pitch(angle); } | 
|---|
 | 228 |             inline void roll_xmlport(const Degree& angle) | 
|---|
 | 229 |                 { this->roll(angle); } | 
|---|
 | 230 |  | 
|---|
| [2662] | 231 |             // network callbacks | 
|---|
| [2851] | 232 |             void networkcallback_parentChanged(); | 
|---|
| [2662] | 233 |             inline void scaleChanged() | 
|---|
 | 234 |                 { this->setScale3D(this->getScale3D()); } | 
|---|
 | 235 |  | 
|---|
| [2072] | 236 |             WorldEntity* parent_; | 
|---|
 | 237 |             unsigned int parentID_; | 
|---|
 | 238 |             std::set<WorldEntity*> children_; | 
|---|
| [3077] | 239 |             bool bDeleteWithParent_; | 
|---|
| [7163] | 240 |  | 
|---|
| [6524] | 241 |             bool bActiveMem_; | 
|---|
 | 242 |             bool bVisibleMem_; | 
|---|
| [2662] | 243 |  | 
|---|
 | 244 |  | 
|---|
 | 245 |         ///////////// | 
|---|
 | 246 |         // Physics // | 
|---|
 | 247 |         ///////////// | 
|---|
 | 248 |  | 
|---|
 | 249 |         public: | 
|---|
 | 250 |             /** | 
|---|
 | 251 |             @brief | 
|---|
 | 252 |                 Denotes the possible types of physical objects in a Scene. | 
|---|
 | 253 |  | 
|---|
 | 254 |                 Dynamic:   The object is influenced by its physical environment, like for instance little ball. | 
|---|
 | 255 |                 Kinematic: The object can only influence other dynamic objects. It's movement is coordinated by your own saying. | 
|---|
 | 256 |                 Static:    Like kinematic but the object is not allowed to move during the simulation. | 
|---|
 | 257 |                 None:      The object has no physics at all. | 
|---|
 | 258 |             */ | 
|---|
 | 259 |             enum CollisionType | 
|---|
 | 260 |             { | 
|---|
 | 261 |                 Dynamic, | 
|---|
 | 262 |                 Kinematic, | 
|---|
 | 263 |                 Static, | 
|---|
 | 264 |                 None | 
|---|
 | 265 |             }; | 
|---|
 | 266 |  | 
|---|
 | 267 |             //! Tells whether the object has any connection to the Bullet physics engine. If hasPhysics() is false, the object may still have a velocity. | 
|---|
 | 268 |             bool hasPhysics()       const { return getCollisionType() != None     ; } | 
|---|
 | 269 |             //! @see CollisionType | 
|---|
 | 270 |             bool isStatic()         const { return getCollisionType() == Static   ; } | 
|---|
 | 271 |             //! @see CollisionType | 
|---|
 | 272 |             bool isKinematic()      const { return getCollisionType() == Kinematic; } | 
|---|
 | 273 |             //! @see CollisionType | 
|---|
 | 274 |             bool isDynamic()        const { return getCollisionType() == Dynamic  ; } | 
|---|
 | 275 |             //! Tells whether physics has been activated (you can temporarily deactivate it) | 
|---|
 | 276 |             bool isPhysicsActive()  const { return this->bPhysicsActive_; } | 
|---|
 | 277 |             bool addedToPhysicalWorld() const; | 
|---|
 | 278 |  | 
|---|
 | 279 |             void activatePhysics(); | 
|---|
 | 280 |             void deactivatePhysics(); | 
|---|
 | 281 |  | 
|---|
 | 282 |             //! Returns the CollisionType. @see CollisionType. | 
|---|
 | 283 |             inline CollisionType getCollisionType() const | 
|---|
 | 284 |                 { return this->collisionType_; } | 
|---|
 | 285 |             void setCollisionType(CollisionType type); | 
|---|
 | 286 |  | 
|---|
 | 287 |             void setCollisionTypeStr(const std::string& type); | 
|---|
 | 288 |             std::string getCollisionTypeStr() const; | 
|---|
 | 289 |  | 
|---|
 | 290 |             //! Sets the mass of this object. Note that the total mass may be influenced by attached objects! | 
|---|
 | 291 |             inline void setMass(float mass) | 
|---|
 | 292 |                 { this->mass_ = mass; recalculateMassProps(); } | 
|---|
 | 293 |             //! Returns the mass of this object without its children. | 
|---|
 | 294 |             inline float getMass() const | 
|---|
 | 295 |                 { return this->mass_; } | 
|---|
 | 296 |  | 
|---|
 | 297 |             //! Returns the total mass of this object with all its attached children. | 
|---|
 | 298 |             inline float getTotalMass() const | 
|---|
 | 299 |                 { return this->mass_ + this->childrenMass_; } | 
|---|
 | 300 |  | 
|---|
 | 301 |             /** | 
|---|
 | 302 |             @brief | 
|---|
 | 303 |                 Returns the diagonal elements of the inertia tensor when calculated in local coordinates. | 
|---|
| [7401] | 304 |             @note | 
|---|
| [2662] | 305 |                 The local inertia tensor cannot be set, but is calculated by Bullet according to the collisionShape. | 
|---|
 | 306 |                 With compound collision shapes, an approximation is used. | 
|---|
 | 307 |             */ | 
|---|
 | 308 |             inline const btVector3& getLocalInertia() const | 
|---|
 | 309 |                 { return this->localInertia_; } | 
|---|
 | 310 |  | 
|---|
 | 311 |             /** | 
|---|
 | 312 |             @brief | 
|---|
 | 313 |                 Sets how much reaction is applied in a collision. | 
|---|
| [2851] | 314 |  | 
|---|
| [2662] | 315 |                 Consider two equal spheres colliding with equal velocities: | 
|---|
 | 316 |                 Restitution 1 means that both spheres simply reverse their velocity (no loss of energy) | 
|---|
 | 317 |                 Restitution 0 means that both spheres will immediately stop moving | 
|---|
 | 318 |                 (maximum loss of energy without violating of the preservation of momentum) | 
|---|
 | 319 |             */ | 
|---|
 | 320 |             inline void setRestitution(float restitution) | 
|---|
 | 321 |                 { this->restitution_ = restitution; internalSetPhysicsProps(); } | 
|---|
 | 322 |             //! Returns the restitution parameter. @see setRestitution. | 
|---|
 | 323 |             inline float getRestitution() const | 
|---|
 | 324 |                 { return this->restitution_; } | 
|---|
 | 325 |  | 
|---|
 | 326 |             /** | 
|---|
 | 327 |             @brief | 
|---|
 | 328 |                 Sets an artificial parameter that tells how much torque is applied when you apply a non-central force. | 
|---|
 | 329 |  | 
|---|
| [6417] | 330 |                 Normally the angular factor is 1, which means it's physically 'correct'. However if you have a player | 
|---|
| [2662] | 331 |                 character that should not rotate when hit sideways, you can set the angular factor to 0. | 
|---|
 | 332 |             */ | 
|---|
 | 333 |             inline void setAngularFactor(float angularFactor) | 
|---|
 | 334 |                 { this->angularFactor_ = angularFactor; internalSetPhysicsProps(); } | 
|---|
 | 335 |             //! Returns the angular factor. @see setAngularFactor. | 
|---|
 | 336 |             inline float getAngularFactor() const | 
|---|
 | 337 |                 { return this->angularFactor_; } | 
|---|
 | 338 |  | 
|---|
 | 339 |             //! Applies a mass independent damping. Velocities will simply diminish exponentially. | 
|---|
 | 340 |             inline void setLinearDamping(float linearDamping) | 
|---|
 | 341 |                 { this->linearDamping_ = linearDamping; internalSetPhysicsProps(); } | 
|---|
 | 342 |             //! Returns the linear damping. @see setLinearDamping. | 
|---|
 | 343 |             inline float getLinearDamping() const | 
|---|
 | 344 |                 { return this->linearDamping_; } | 
|---|
 | 345 |  | 
|---|
 | 346 |             //! Applies a tensor independent rotation damping. Angular velocities will simply diminish exponentially. | 
|---|
 | 347 |             inline void setAngularDamping(float angularDamping) | 
|---|
 | 348 |                 { this->angularDamping_ = angularDamping; internalSetPhysicsProps(); } | 
|---|
 | 349 |             //! Returns the angular damping. @see setAngularDamping. | 
|---|
 | 350 |             inline float getAngularDamping() const | 
|---|
 | 351 |                 { return this->angularDamping_; } | 
|---|
 | 352 |  | 
|---|
 | 353 |             //! Applies friction to the object. Friction occurs when two objects collide. | 
|---|
 | 354 |             inline void setFriction(float friction) | 
|---|
 | 355 |                 { this->friction_ = friction; internalSetPhysicsProps(); } | 
|---|
 | 356 |             //! Returns the amount of friction applied to the object. | 
|---|
 | 357 |             inline float getFriction() const | 
|---|
 | 358 |                 { return this->friction_; } | 
|---|
 | 359 |  | 
|---|
| [10288] | 360 |             /** | 
|---|
 | 361 |              * Sets the motion threshold for continuous collision detection (CCD). This should be activated if an object moves further in one tick than its own | 
|---|
 | 362 |              * size. This means that in one tick the object may be in front of a wall and in the next tick it will be behind the wall without ever triggering a | 
|---|
 | 363 |              * collision. CCD ensures that collisions are still detected. By default it is deactivated (threshold = 0) which is fine for slow or static | 
|---|
 | 364 |              * objects, but it should be set to a real value for fast moving objects (e.g. projectiles). | 
|---|
 | 365 |              * | 
|---|
 | 366 |              * A good value for the threshold is (diameter^2). | 
|---|
 | 367 |              * | 
|---|
 | 368 |              * @param ccdMotionThreshold CCD is enabled if the squared velocity of the object is > ccdMotionThreshold (default 0.0). 0.0 means deactivated. | 
|---|
 | 369 |              */ | 
|---|
 | 370 |             inline void setCcdMotionThreshold(float ccdMotionThreshold) | 
|---|
 | 371 |                 { this->ccdMotionThreshold_ = ccdMotionThreshold; internalSetPhysicsProps(); } | 
|---|
 | 372 |             //! Returns the currently used motion threshold for CCD (0 means CCD is deactivated). | 
|---|
 | 373 |             inline float getCcdMotionThreshold() const | 
|---|
 | 374 |                 { return this->ccdMotionThreshold_; } | 
|---|
 | 375 |  | 
|---|
 | 376 |             /** | 
|---|
 | 377 |              * Sets the radius of the sphere which is used for continuous collision detection (CCD). The sphere should be embedded inside the objects collision | 
|---|
 | 378 |              * shape, preferably smaller. @see setCcdMotionThreshold for more information about CCD. | 
|---|
 | 379 |              * | 
|---|
 | 380 |              * A good value for the radius is (diameter/5). | 
|---|
 | 381 |              * | 
|---|
 | 382 |              * @param ccdSweptSphereRadius The diameter of the sphere which is used for CCD (default 0.0). | 
|---|
 | 383 |              */ | 
|---|
 | 384 |             inline void setCcdSweptSphereRadius(float ccdSweptSphereRadius) | 
|---|
 | 385 |                 { this->ccdSweptSphereRadius_ = ccdSweptSphereRadius; internalSetPhysicsProps(); } | 
|---|
 | 386 |             //! Returns the currently used radius of the sphere for CCD. | 
|---|
 | 387 |             inline float getCcdSweptSphereRadius() const | 
|---|
 | 388 |                 { return this->ccdSweptSphereRadius_; } | 
|---|
 | 389 |  | 
|---|
| [2662] | 390 |             void attachCollisionShape(CollisionShape* shape); | 
|---|
 | 391 |             void detachCollisionShape(CollisionShape* shape); | 
|---|
 | 392 |             CollisionShape* getAttachedCollisionShape(unsigned int index); | 
|---|
 | 393 |  | 
|---|
 | 394 |             void notifyCollisionShapeChanged(); | 
|---|
 | 395 |             void notifyChildMassChanged(); | 
|---|
 | 396 |  | 
|---|
 | 397 |             /** | 
|---|
 | 398 |             @brief | 
|---|
 | 399 |                 Virtual function that gets called when this object collides with another. | 
|---|
 | 400 |             @param otherObject | 
|---|
 | 401 |                 The object this one has collided into. | 
|---|
| [7401] | 402 |             @param contactPoint | 
|---|
| [2662] | 403 |                 Contact point provided by Bullet. Holds more information and can me modified. See return value. | 
|---|
| [7401] | 404 |             @return | 
|---|
| [2662] | 405 |                 Returning false means that no modification to the contactPoint has been made. Return true otherwise! | 
|---|
| [7401] | 406 |             @note | 
|---|
| [2662] | 407 |                 Condition is that enableCollisionCallback() was called. | 
|---|
 | 408 |             */ | 
|---|
| [10216] | 409 |             virtual inline bool collidesAgainst(WorldEntity* otherObject, const btCollisionShape* ownCollisionShape, btManifoldPoint& contactPoint) | 
|---|
| [2662] | 410 |                 { return false; } /* With false, Bullet assumes no modification to the collision objects. */ | 
|---|
 | 411 |  | 
|---|
 | 412 |             //! Enables the collidesAgainst(.) function. The object doesn't respond to collision otherwise! | 
|---|
 | 413 |             inline void enableCollisionCallback() | 
|---|
 | 414 |                 { this->bCollisionCallbackActive_ = true; this->collisionCallbackActivityChanged(); } | 
|---|
 | 415 |             //! Disables the collidesAgainst(.) function. @see enableCollisionCallback() | 
|---|
 | 416 |             inline void disableCollisionCallback() | 
|---|
 | 417 |                 { this->bCollisionCallbackActive_ = false; this->collisionCallbackActivityChanged(); } | 
|---|
 | 418 |             //! Tells whether there could be a collision callback via collidesAgainst(.) | 
|---|
 | 419 |             inline bool isCollisionCallbackActive() const | 
|---|
 | 420 |                 { return this->bCollisionCallbackActive_; } | 
|---|
 | 421 |  | 
|---|
 | 422 |             //! Enables or disables collision response (default is of course on) | 
|---|
 | 423 |             inline void setCollisionResponse(bool value) | 
|---|
 | 424 |                 { this->bCollisionResponseActive_ = value; this->collisionResponseActivityChanged(); } | 
|---|
 | 425 |             //! Tells whether there could be a collision response | 
|---|
 | 426 |             inline bool hasCollisionResponse() | 
|---|
 | 427 |                 { return this->bCollisionResponseActive_; } | 
|---|
 | 428 |  | 
|---|
 | 429 |         protected: | 
|---|
 | 430 |             /** | 
|---|
 | 431 |             @brief | 
|---|
 | 432 |                 Function checks whether the requested collision type is legal to this object. | 
|---|
 | 433 |  | 
|---|
 | 434 |                 You can override this function in a derived class to constrain the collision to e.g. None or Dynamic. | 
|---|
 | 435 |                 A projectile may not prove very useful if there is no physical body. Simply set the CollisionType | 
|---|
| [6417] | 436 |                 in its constructor and override this method. But be careful that a derived class's virtual functions | 
|---|
| [2662] | 437 |                 don't yet exist in the constructor if a base class. | 
|---|
 | 438 |             */ | 
|---|
 | 439 |             virtual bool isCollisionTypeLegal(CollisionType type) const = 0; | 
|---|
 | 440 |  | 
|---|
 | 441 |             btRigidBody*  physicalBody_; //!< Bullet rigid body. Everything physical is applied to this instance. | 
|---|
 | 442 |  | 
|---|
 | 443 |         private: | 
|---|
 | 444 |             void recalculateMassProps(); | 
|---|
 | 445 |             void internalSetPhysicsProps(); | 
|---|
 | 446 |  | 
|---|
 | 447 |             bool notifyBeingAttached(WorldEntity* newParent); | 
|---|
 | 448 |             void notifyDetached(); | 
|---|
 | 449 |  | 
|---|
 | 450 |             // network callbacks | 
|---|
 | 451 |             void collisionTypeChanged(); | 
|---|
 | 452 |             void physicsActivityChanged(); | 
|---|
 | 453 |             void collisionCallbackActivityChanged(); | 
|---|
 | 454 |             void collisionResponseActivityChanged(); | 
|---|
 | 455 |             //! Network callback workaround to call a function when the value changes. | 
|---|
 | 456 |             inline void massChanged() | 
|---|
 | 457 |                 { this->setMass(this->mass_); } | 
|---|
 | 458 |             //! Network callback workaround to call a function when the value changes. | 
|---|
 | 459 |             inline void restitutionChanged() | 
|---|
 | 460 |                 { this->setRestitution(this->restitution_); } | 
|---|
 | 461 |             //! Network callback workaround to call a function when the value changes. | 
|---|
 | 462 |             inline void angularFactorChanged() | 
|---|
 | 463 |                 { this->setAngularFactor(this->angularFactor_); } | 
|---|
 | 464 |             //! Network callback workaround to call a function when the value changes. | 
|---|
 | 465 |             inline void linearDampingChanged() | 
|---|
 | 466 |                 { this->setLinearDamping(this->linearDamping_); } | 
|---|
 | 467 |             //! Network callback workaround to call a function when the value changes. | 
|---|
 | 468 |             inline void angularDampingChanged() | 
|---|
 | 469 |                 { this->setAngularDamping(this->angularDamping_); } | 
|---|
 | 470 |             //! Network callback workaround to call a function when the value changes. | 
|---|
 | 471 |             inline void frictionChanged() | 
|---|
 | 472 |                 { this->setFriction(this->friction_); } | 
|---|
| [10288] | 473 |             //! Network callback workaround to call a function when the value changes. | 
|---|
 | 474 |             inline void ccdMotionThresholdChanged() | 
|---|
 | 475 |                 { this->setCcdMotionThreshold(this->ccdMotionThreshold_); } | 
|---|
 | 476 |             //! Network callback workaround to call a function when the value changes. | 
|---|
 | 477 |             inline void ccdSweptSphereRadiusChanged() | 
|---|
 | 478 |                 { this->setCcdSweptSphereRadius(this->ccdSweptSphereRadius_); } | 
|---|
| [2662] | 479 |  | 
|---|
 | 480 |             CollisionType                collisionType_;                 //!< @see setCollisionType | 
|---|
 | 481 |             CollisionType                collisionTypeSynchronised_;     //!< Network synchronised variable for collisionType_ | 
|---|
 | 482 |             bool                         bPhysicsActive_;                //!< @see isPhysicsActive | 
|---|
 | 483 |             bool                         bPhysicsActiveSynchronised_;    //!< Network synchronised variable for bPhysicsActive_ | 
|---|
 | 484 |             //! When attaching objects hierarchically this variable tells this object (as child) whether physics was activated before attaching (because the deactivate physics while being attached). | 
|---|
 | 485 |             bool                         bPhysicsActiveBeforeAttaching_; | 
|---|
 | 486 |             WorldEntityCollisionShape*   collisionShape_;                //!< Attached collision shapes go here | 
|---|
 | 487 |             btScalar                     mass_;                          //!< @see setMass | 
|---|
 | 488 |             btVector3                    localInertia_;                  //!< @see getLocalInertia | 
|---|
 | 489 |             btScalar                     restitution_;                   //!< @see setRestitution | 
|---|
 | 490 |             btScalar                     angularFactor_;                 //!< @see setAngularFactor | 
|---|
 | 491 |             btScalar                     linearDamping_;                 //!< @see setLinearDamping | 
|---|
 | 492 |             btScalar                     angularDamping_;                //!< @see setAngularDamping | 
|---|
 | 493 |             btScalar                     friction_;                      //!< @see setFriction | 
|---|
 | 494 |             btScalar                     childrenMass_;                  //!< Sum of all the children's masses | 
|---|
| [10288] | 495 |             btScalar                     ccdMotionThreshold_;            //!< @see setCcdMotionThreshold | 
|---|
 | 496 |             btScalar                     ccdSweptSphereRadius_;          //!< @see setCcdSweptSphereRadius | 
|---|
| [2662] | 497 |             bool                         bCollisionCallbackActive_;      //!< @see enableCollisionCallback | 
|---|
 | 498 |             bool                         bCollisionResponseActive_;      //!< Tells whether the object should respond to collisions | 
|---|
| [2072] | 499 |     }; | 
|---|
| [2662] | 500 |  | 
|---|
 | 501 |     // Inline heavily used functions for release builds. In debug, we better avoid including OgreSceneNode here. | 
|---|
| [3196] | 502 | #ifdef ORXONOX_RELEASE | 
|---|
| [2662] | 503 |     inline const Vector3& WorldEntity::getPosition() const | 
|---|
 | 504 |         { return this->node_->getPosition(); } | 
|---|
 | 505 |     inline const Quaternion& WorldEntity::getOrientation() const | 
|---|
| [2787] | 506 |         { return this->node_->getOrientation(); } | 
|---|
| [3301] | 507 |     inline const Vector3& WorldEntity::getScale3D() const | 
|---|
| [2662] | 508 |         { return this->node_->getScale(); } | 
|---|
 | 509 | #endif | 
|---|
 | 510 |  | 
|---|
 | 511 |     SUPER_FUNCTION(5, WorldEntity, changedScale, false); | 
|---|
| [2072] | 512 | } | 
|---|
 | 513 |  | 
|---|
 | 514 | #endif /* _WorldEntity_H__ */ | 
|---|