Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 11, 2008, 2:18:34 PM (15 years ago)
Author:
rgrieder
Message:

Renamed MovableEntity to MobileEntity and LinearEntity to MovableEntity.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/physics/src/orxonox/objects/worldentities/MovableEntity.cc

    r2407 r2408  
    2121 *
    2222 *   Author:
    23  *      Reto Grieder
     23 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      Martin Stypinski
     25 *      ...
    2626 *
    2727 */
     
    3030#include "MovableEntity.h"
    3131
    32 #include "BulletDynamics/Dynamics/btRigidBody.h"
    33 
    34 #include "util/Debug.h"
    35 #include "util/MathConvert.h"
    36 #include "util/Exception.h"
    3732#include "core/CoreIncludes.h"
    3833#include "core/XMLPort.h"
    39 
    40 #include "objects/Scene.h"
     34#include "core/Executor.h"
     35#include "tools/Timer.h"
    4136
    4237namespace orxonox
    4338{
    44     MovableEntity::MovableEntity(BaseObject* creator) : WorldEntity(creator)
     39    static const float MAX_RESYNCHRONIZE_TIME = 3.0f;
     40
     41    CreateFactory(MovableEntity);
     42
     43    MovableEntity::MovableEntity(BaseObject* creator) : MobileEntity(creator)
    4544    {
    4645        RegisterObject(MovableEntity);
    4746
    48         this->linearAcceleration_  = Vector3::ZERO;
    49         this->linearVelocity_      = Vector3::ZERO;
    50         this->angularAcceleration_ = Vector3::ZERO;
    51         this->angularVelocity_     = Vector3::ZERO;
     47        this->overwrite_position_    = Vector3::ZERO;
     48        this->overwrite_orientation_ = Quaternion::IDENTITY;
    5249
    5350        this->registerVariables();
     
    6158    {
    6259        SUPER(MovableEntity, XMLPort, xmlelement, mode);
    63 
    64         XMLPortParamTemplate(MovableEntity, "velocity",     setVelocity,     getVelocity,     xmlelement, mode, const Vector3&);
    65         XMLPortParamTemplate(MovableEntity, "rotationaxis", setRotationAxis, getRotationAxis, xmlelement, mode, const Vector3&);
    66         XMLPortParam(MovableEntity, "rotationrate", setRotationRate, getRotationRate, xmlelement, mode);
    6760    }
    6861
    6962    void MovableEntity::registerVariables()
    7063    {
     64        REGISTERDATA(this->linearVelocity_,        network::direction::toclient, new network::NetworkCallback<MovableEntity>(this, &MovableEntity::processLinearVelocity));
     65        REGISTERDATA(this->angularVelocity_,       network::direction::toclient, new network::NetworkCallback<MovableEntity>(this, &MovableEntity::processAngularVelocity));
     66
     67        REGISTERDATA(this->overwrite_position_,    network::direction::toclient, new network::NetworkCallback<MovableEntity>(this, &MovableEntity::overwritePosition));
     68        REGISTERDATA(this->overwrite_orientation_, network::direction::toclient, new network::NetworkCallback<MovableEntity>(this, &MovableEntity::overwriteOrientation));
    7169    }
    7270
    7371    void MovableEntity::tick(float dt)
    7472    {
     73        MobileEntity::tick(dt);
     74
    7575        if (this->isActive())
    7676        {
    77             // Check whether Bullet doesn't do the physics for us
    78             if (!this->isDynamic())
    79             {
    80                 // Linear part
    81                 this->linearVelocity_.x += this->linearAcceleration_.x * dt;
    82                 this->linearVelocity_.y += this->linearAcceleration_.y * dt;
    83                 this->linearVelocity_.z += this->linearAcceleration_.z * dt;
    84                 linearVelocityChanged(true);
    85                 this->node_->translate(this->linearVelocity_ * dt);
    86                 positionChanged(true);
    87 
    88                 // Angular part
    89                 // Note: angularVelocity_ is a Quaternion with w = 0 while angularAcceleration_ is a Vector3
    90                 this->angularVelocity_.x += angularAcceleration_.x * dt;
    91                 this->angularVelocity_.y += angularAcceleration_.y * dt;
    92                 this->angularVelocity_.z += angularAcceleration_.z * dt;
    93                 angularVelocityChanged(true);
    94                 // Calculate new orientation with quaternion derivative. This is about 30% faster than with angle/axis method.
    95                 float mult = dt * 0.5;
    96                 // TODO: this could be optimized by writing it out. The calls currently create 4 new Quaternions!
    97                 Quaternion newOrientation(0.0f, this->angularVelocity_.x * mult, this->angularVelocity_.y * mult, this->angularVelocity_.z * mult);
    98                 newOrientation = this->node_->getOrientation() + newOrientation * this->node_->getOrientation();
    99                 newOrientation.normalise();
    100                 this->node_->setOrientation(newOrientation);
    101                 orientationChanged(true);
    102             }
    10377        }
    10478    }
    10579
    106     void MovableEntity::setPosition(const Vector3& position)
     80    void MovableEntity::overwritePosition()
    10781    {
    108         if (this->isDynamic())
    109         {
    110             btTransform transf = this->physicalBody_->getWorldTransform();
    111             transf.setOrigin(btVector3(position.x, position.y, position.z));
    112             this->physicalBody_->setWorldTransform(transf);
    113         }
    114 
    115         this->node_->setPosition(position);
    116         positionChanged(false);
     82        this->setPosition(this->overwrite_position_);
    11783    }
    11884
    119     void MovableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
     85    void MovableEntity::overwriteOrientation()
    12086    {
    121         if (this->isDynamic())
    122         {
    123             OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot translate physical object relative \
    124                                                           to any other space than TS_LOCAL.");
    125             this->physicalBody_->translate(btVector3(distance.x, distance.y, distance.z));
    126         }
    127 
    128         this->node_->translate(distance, relativeTo);
    129         positionChanged(false);
     87        this->setOrientation(this->overwrite_orientation_);
    13088    }
    13189
    132     void MovableEntity::setOrientation(const Quaternion& orientation)
     90    void MovableEntity::clientConnected(unsigned int clientID)
    13391    {
    134         if (this->isDynamic())
    135         {
    136             btTransform transf = this->physicalBody_->getWorldTransform();
    137             transf.setRotation(btQuaternion(orientation.x, orientation.y, orientation.z, orientation.w));
    138             this->physicalBody_->setWorldTransform(transf);
    139         }
     92        resynchronize();
     93        new Timer<MovableEntity>(rnd() * MAX_RESYNCHRONIZE_TIME, true, this, createExecutor(createFunctor(&MovableEntity::resynchronize)), false);
     94    }
    14095
    141         this->node_->setOrientation(orientation);
     96    void MovableEntity::clientDisconnected(unsigned int clientID)
     97    {
     98    }
     99
     100    void MovableEntity::resynchronize()
     101    {
     102        positionChanged(false);
    142103        orientationChanged(false);
    143104    }
    144105
    145     void MovableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
     106    void MovableEntity::positionChanged(bool bContinuous)
    146107    {
    147         if (this->isDynamic())
    148         {
    149             OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot rotate physical object relative \
    150                                                           to any other space than TS_LOCAL.");
    151             btTransform transf = this->physicalBody_->getWorldTransform();
    152             this->physicalBody_->setWorldTransform(transf * btTransform(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)));
    153         }
    154 
    155         this->node_->rotate(rotation, relativeTo);
    156         orientationChanged(false);
     108        if (!bContinuous)
     109            this->overwrite_position_ = this->getPosition();
    157110    }
    158111
    159     void MovableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
     112    void MovableEntity::orientationChanged(bool bContinuous)
    160113    {
    161         if (this->isDynamic())
    162         {
    163             OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot yaw physical object relative \
    164                                                           to any other space than TS_LOCAL.");
    165             btTransform transf = this->physicalBody_->getWorldTransform();
    166             btTransform rotation(btQuaternion(angle.valueRadians(), 0.0f, 0.0f));
    167             this->physicalBody_->setWorldTransform(transf * rotation);
    168         }
    169 
    170         this->node_->yaw(angle, relativeTo);
    171         orientationChanged(false);
    172     }
    173 
    174     void MovableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
    175     {
    176         if (this->isDynamic())
    177         {
    178             OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot pitch physical object relative \
    179                                                           to any other space than TS_LOCAL.");
    180             btTransform transf = this->physicalBody_->getWorldTransform();
    181             btTransform rotation(btQuaternion(0.0f, angle.valueRadians(), 0.0f));
    182             this->physicalBody_->setWorldTransform(transf * rotation);
    183         }
    184 
    185         this->node_->pitch(angle, relativeTo);
    186         orientationChanged(false);
    187     }
    188 
    189     void MovableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
    190     {
    191         if (this->isDynamic())
    192         {
    193             OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot roll physical object relative \
    194                                                           to any other space than TS_LOCAL.");
    195             btTransform transf = this->physicalBody_->getWorldTransform();
    196             btTransform rotation(btQuaternion(angle.valueRadians(), 0.0f, 0.0f));
    197             this->physicalBody_->setWorldTransform(transf * rotation);
    198         }
    199 
    200         this->node_->roll(angle, relativeTo);
    201         orientationChanged(false);
    202     }
    203 
    204     void MovableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
    205     {
    206         if (this->isDynamic())
    207         {
    208             ThrowException(NotImplemented, "ControllableEntity::lookAt() is not yet supported for physical objects.");
    209             OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot align physical object relative \
    210                                                           to any other space than TS_LOCAL.");
    211         }
    212 
    213         this->node_->lookAt(target, relativeTo, localDirectionVector);
    214         orientationChanged(false);
    215     }
    216 
    217     void MovableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
    218     {
    219         if (this->isDynamic())
    220         {
    221             ThrowException(NotImplemented, "ControllableEntity::setDirection() is not yet supported for physical objects.");
    222             OrxAssert(relativeTo == Ogre::Node::TS_LOCAL, "Cannot align physical object relative \
    223                                                           to any other space than TS_LOCAL.");
    224         }
    225 
    226         this->node_->setDirection(direction, relativeTo, localDirectionVector);
    227         orientationChanged(false);
    228     }
    229 
    230     void MovableEntity::setVelocity(const Vector3& velocity)
    231     {
    232         if (this->isDynamic())
    233             this->physicalBody_->setLinearVelocity(btVector3(velocity.x, velocity.y, velocity.z));
    234 
    235         this->linearVelocity_ = velocity;
    236         linearVelocityChanged(false);
    237     }
    238 
    239     void MovableEntity::setAngularVelocity(const Vector3& velocity)
    240     {
    241         if (this->isDynamic())
    242             this->physicalBody_->setAngularVelocity(btVector3(velocity.x, velocity.y, velocity.z));
    243 
    244         this->angularVelocity_ = velocity;
    245         angularVelocityChanged(false);
    246     }
    247 
    248     void MovableEntity::setAcceleration(const Vector3& acceleration)
    249     {
    250         if (this->isDynamic())
    251             this->physicalBody_->applyCentralForce(btVector3(acceleration.x * this->getMass(), acceleration.y * this->getMass(), acceleration.z * this->getMass()));
    252 
    253         this->linearAcceleration_ = acceleration;
    254     }
    255 
    256     void MovableEntity::setAngularAcceleration(const Vector3& acceleration)
    257     {
    258         if (this->isDynamic())
    259         {
    260             btVector3 inertia(btVector3(1, 1, 1) / this->physicalBody_->getInvInertiaDiagLocal());
    261             this->physicalBody_->applyTorque(btVector3(acceleration.x, acceleration.y, acceleration.z) * inertia);
    262         }
    263 
    264         this->angularAcceleration_ = acceleration;
    265     }
    266 
    267     bool MovableEntity::isCollisionTypeLegal(WorldEntity::CollisionType type) const
    268     {
    269         if (type == WorldEntity::Static)
    270         {
    271             ThrowException(PhysicsViolation, "Cannot tell a MovableEntity to have static collision type");
    272             return false;
    273         }
    274         else
    275             return true;
    276     }
    277 
    278     void MovableEntity::setWorldTransform(const btTransform& worldTrans)
    279     {
    280         // We use a dynamic body. So we translate our node accordingly.
    281         this->node_->setPosition(Vector3(worldTrans.getOrigin().x(), worldTrans.getOrigin().y(), worldTrans.getOrigin().z()));
    282         this->node_->setOrientation(Quaternion(worldTrans.getRotation().w(), worldTrans.getRotation().x(), worldTrans.getRotation().y(), worldTrans.getRotation().z()));
    283         this->linearVelocity_.x = this->physicalBody_->getLinearVelocity().x();
    284         this->linearVelocity_.y = this->physicalBody_->getLinearVelocity().y();
    285         this->linearVelocity_.z = this->physicalBody_->getLinearVelocity().z();
    286         this->angularVelocity_.x = this->physicalBody_->getAngularVelocity().x();
    287         this->angularVelocity_.y = this->physicalBody_->getAngularVelocity().y();
    288         this->angularVelocity_.z = this->physicalBody_->getAngularVelocity().z();
    289         linearVelocityChanged(true);
    290         angularVelocityChanged(true);
    291         positionChanged(true);
    292         orientationChanged(true);
    293     }
    294 
    295     void MovableEntity::getWorldTransform(btTransform& worldTrans) const
    296     {
    297         // We use a kinematic body
    298         worldTrans.setOrigin(btVector3(node_->getPosition().x, node_->getPosition().y, node_->getPosition().z));
    299         worldTrans.setRotation(btQuaternion(node_->getOrientation().x, node_->getOrientation().y, node_->getOrientation().z, node_->getOrientation().w));
    300         if (this->isDynamic())
    301         {
    302             // This function gets called only once for dynamic objects to set the initial conditions
    303             // We have to set the velocities too.
    304             this->physicalBody_->setLinearVelocity(btVector3(linearVelocity_.x, linearVelocity_.y, linearVelocity_.z));
    305             this->physicalBody_->setAngularVelocity(btVector3(angularVelocity_.x, angularVelocity_.y, angularVelocity_.z));
    306         }
     114        if (!bContinuous)
     115            this->overwrite_orientation_ = this->getOrientation();
    307116    }
    308117}
Note: See TracChangeset for help on using the changeset viewer.