Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Feb 14, 2009, 10:17:35 PM (15 years ago)
Author:
rgrieder
Message:

Merged presentation branch back to trunk.

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/orxonox/objects/worldentities/WorldEntity.h

    r2171 r2662  
    2222 *   Author:
    2323 *      Fabian 'x3n' Landau
     24 *      Reto Grieder (physics)
    2425 *   Co-authors:
    2526 *      ...
     
    3233#include "OrxonoxPrereqs.h"
    3334
    34 #define OGRE_FORCE_ANGLE_TYPES
    35 
     35#ifdef _NDEBUG
    3636#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"
    3943#include "core/BaseObject.h"
    40 #include "util/Math.h"
     44#include "network/synchronisable/Synchronisable.h"
    4145
    4246namespace orxonox
    4347{
    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
    4573    {
     74        friend class Scene;
     75
    4676        public:
    4777            WorldEntity(BaseObject* creator);
     
    5181            void registerVariables();
    5282
    53             inline Ogre::SceneNode* getNode() const
     83            inline const Ogre::SceneNode* getNode() const
    5484                { return this->node_; }
    5585
     
    6494            inline void setPosition(float x, float y, float z)
    6595                { 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)
    73101                { this->translate(Vector3(x, y, z), relativeTo); }
     102
     103            virtual inline const Vector3& getVelocity() const
     104                { return Vector3::ZERO; }
    74105
    75106            virtual void setOrientation(const Quaternion& orientation) = 0;
     
    80111            inline void setOrientation(const Vector3& axis, const Degree& angle)
    81112                { 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)
    89118                { 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)
    106130                { this->setDirection(Vector3(x, y, z), relativeTo, localDirectionVector); }
    107131
    108             inline void setScale3D(const Vector3& scale)
    109                 { this->node_->setScale(scale); }
     132            virtual void setScale3D(const Vector3& scale);
    110133            inline void setScale3D(float x, float y, float z)
    111                 { this->node_->setScale(x, y, z); }
    112             inline const Vector3& getScale3D(void) const
    113                 { return this->node_->getScale(); }
     134                { this->setScale3D(Vector3(x, y, z)); }
     135            const Vector3& getScale3D(void) const;
     136            const Vector3& getWorldScale3D() const;
    114137
    115138            inline void setScale(float scale)
    116                 { this->node_->setScale(scale, scale, scale); }
     139                { this->setScale3D(scale, scale, scale); }
    117140            inline float getScale() const
    118141                { Vector3 scale = this->getScale3D(); return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1; }
     142            float getWorldScale() const;
    119143
    120144            inline void scale3D(const Vector3& scale)
    121                 { this->node_->scale(scale); }
     145                { this->setScale3D(this->getScale3D() * scale); }
    122146            inline void scale3D(float x, float y, float z)
    123                 { this->node_->scale(x, y, z); }
     147                { this->scale3D(Vector3(x, y, z)); }
    124148            inline void scale(float scale)
    125                 { this->node_->scale(scale, scale, scale); }
     149                { this->scale3D(scale, scale, scale); }
     150
     151            virtual void changedScale() {}
    126152
    127153            void attach(WorldEntity* object);
    128154            void detach(WorldEntity* object);
    129             WorldEntity* getAttachedObject(unsigned int index) const;
     155            WorldEntity* getAttachedObject(unsigned int index);
    130156            inline const std::set<WorldEntity*>& getAttachedObjects() const
    131157                { return this->children_; }
     158
     159            void attachOgreObject(Ogre::MovableObject* object);
     160            void detachOgreObject(Ogre::MovableObject* object);
     161            Ogre::MovableObject* detachOgreObject(const Ogre::String& name);
    132162
    133163            inline void attachToParent(WorldEntity* parent)
     
    138168                { return this->parent_; }
    139169
     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
    140177        protected:
    141178            Ogre::SceneNode* node_;
    142179
    143180        private:
    144             void updateParent();
    145 
    146181            inline void lookAt_xmlport(const Vector3& target)
    147182                { this->lookAt(target); }
     
    155190                { this->roll(angle); }
    156191
     192            // network callbacks
     193            void parentChanged();
     194            inline void scaleChanged()
     195                { this->setScale3D(this->getScale3D()); }
     196
    157197            WorldEntity* parent_;
    158198            unsigned int parentID_;
    159199            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
    160418    };
     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);
    161431}
    162432
Note: See TracChangeset for help on using the changeset viewer.