Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 28, 2008, 7:15:55 PM (15 years ago)
Author:
rgrieder
Message:
  • Renamed TransformSpace::Space to TransformSpace::Enum
  • Small changes and adjustments WorldEntity (Revealed while commenting…)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentation/src/orxonox/objects/worldentities/WorldEntity.cc

    r2527 r2535  
    4242
    4343#include "objects/Scene.h"
    44 #include "objects/collisionshapes/CompoundCollisionShape.h"
    4544
    4645namespace orxonox
     
    5352    const Vector3 WorldEntity::UP    = Vector3::UNIT_Y;
    5453
    55     WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
     54    WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), Synchronisable(creator), collisionShape_(0)
     55
    5656    {
    5757        RegisterObject(WorldEntity);
     
    6868        this->node_->setOrientation(Quaternion::IDENTITY);
    6969
     70
    7071        // Default behaviour does not include physics
    71         this->physicalBody_ = 0;
    72         this->bPhysicsActive_ = false;
    73         this->bPhysicsActiveSynchronised_ = false;
    74         this->bPhysicsActiveBeforeAttaching_ = false;
    75         this->collisionShape_ = new CompoundCollisionShape(this);
    7672        // Note: CompoundCollisionShape is a Synchronisable, but must not be synchronised.
    7773        //       All objects will get attached on the client anyway, so we don't need synchronisation.
    78         this->collisionShape_->setWorldEntityParent(this);
    79         this->collisionType_ = None;
     74        this->collisionShape_.setWorldEntityParent(this);
     75        this->physicalBody_   = 0;
     76        this->bPhysicsActive_ = false;
     77        this->bPhysicsActiveSynchronised_    = false;
     78        this->bPhysicsActiveBeforeAttaching_ = false;
     79        this->collisionType_             = None;
    8080        this->collisionTypeSynchronised_ = None;
    8181        this->mass_           = 0;
    8282        this->childrenMass_   = 0;
    83         // Use bullet default values
     83        // Using bullet default values
    8484        this->restitution_    = 0;
    8585        this->angularFactor_  = 1;
     
    9696        if (this->isInitialized())
    9797        {
    98             this->node_->detachAllObjects();
     98            if (this->parent_)
     99                this->detachFromParent();
    99100
    100101            for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); )
    101102                delete (*(it++));
    102103
    103             if (this->parent_)
    104                 this->detachFromParent();
    105 
    106             this->node_->removeAllChildren();
    107 
    108104            if (this->physicalBody_)
    109105            {
     
    111107                delete this->physicalBody_;
    112108            }
    113             delete this->collisionShape_;
    114 
    115             if (this->getScene()->getSceneManager())
    116                 this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
     109
     110            this->node_->detachAllObjects();
     111            this->node_->removeAllChildren();
     112
     113            OrxAssert(this->getScene()->getSceneManager(), "No SceneManager defined in a WorldEntity.");
     114            this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
    117115        }
    118116    }
     
    184182    }
    185183
     184    void WorldEntity::attachToNode(Ogre::SceneNode* node)
     185    {
     186        Ogre::Node* parent = this->node_->getParent();
     187        if (parent)
     188            parent->removeChild(this->node_);
     189        node->addChild(this->node_);
     190    }
     191
     192    void WorldEntity::detachFromNode(Ogre::SceneNode* node)
     193    {
     194        node->removeChild(this->node_);
     195//        this->getScene()->getRootSceneNode()->addChild(this->node_);
     196    }
     197
    186198    void WorldEntity::collisionTypeChanged()
    187199    {
     
    223235    }
    224236
     237    void WorldEntity::attach(WorldEntity* object)
     238    {
     239        if (object == this)
     240        {
     241            COUT(2) << "Warning: Can't attach a WorldEntity to itself." << std::endl;
     242            return;
     243        }
     244
     245        if (!object->notifyBeingAttached(this))
     246            return;
     247
     248        this->attachNode(object->node_);
     249        this->children_.insert(object);
     250
     251        this->attachCollisionShape(&object->collisionShape_);
     252        // mass
     253        this->childrenMass_ += object->getMass();
     254        recalculateMassProps();
     255    }
     256
     257    bool WorldEntity::notifyBeingAttached(WorldEntity* newParent)
     258    {
     259        // check first whether attaching is even allowed
     260        if (this->hasPhysics())
     261        {
     262            if (!newParent->hasPhysics())
     263            {
     264                COUT(2) << "Warning: Cannot attach a physical object to a non physical one." << std::endl;
     265                return false;
     266            }
     267            else if (this->isDynamic())
     268            {
     269                COUT(2) << "Warning: Cannot attach a dynamic object to a WorldEntity." << std::endl;
     270                return false;
     271            }
     272            else if (this->isKinematic() && newParent->isDynamic())
     273            {
     274                COUT(2) << "Warning: Cannot attach a kinematic object to a dynamic one." << std::endl;
     275                return false;
     276            }
     277            else if (this->isKinematic())
     278            {
     279                COUT(2) << "Warning: Cannot attach a kinematic object to a static or kinematic one: Not yet implemented." << std::endl;
     280                return false;
     281            }
     282        }
     283
     284        if (this->isPhysicsActive())
     285            this->bPhysicsActiveBeforeAttaching_ = true;
     286        this->deactivatePhysics();
     287
     288        if (this->parent_)
     289            this->detachFromParent();
     290
     291        this->parent_ = newParent;
     292        this->parentID_ = newParent->getObjectID();
     293
     294        // apply transform to collision shape
     295        this->collisionShape_.setPosition(this->getPosition());
     296        this->collisionShape_.setOrientation(this->getOrientation());
     297        // TODO: Scale
     298       
     299        return true;
     300    }
     301
     302    void WorldEntity::detach(WorldEntity* object)
     303    {
     304        if (this->children_.find(object) == this->children_.end())
     305        {
     306            CCOUT(2) << "Warning: Cannot detach an object that is not a child." << std::endl;
     307            return;
     308        }
     309
     310        // collision shapes
     311        this->detachCollisionShape(&object->collisionShape_);
     312
     313        // mass
     314        if (object->getMass() > 0.0f)
     315        {
     316            this->childrenMass_ -= object->getMass();
     317            recalculateMassProps();
     318        }
     319
     320        this->detachNode(object->node_);
     321        this->children_.erase(object);
     322
     323        object->notifyDetached();
     324    }
     325
     326    void WorldEntity::notifyDetached()
     327    {
     328        this->parent_ = 0;
     329        this->parentID_ = OBJECTID_UNKNOWN;
     330
     331        // reset orientation of the collisionShape (cannot be set within a WE usually)
     332        this->collisionShape_.setPosition(Vector3::ZERO);
     333        this->collisionShape_.setOrientation(Quaternion::IDENTITY);
     334        // TODO: Scale
     335
     336        if (this->bPhysicsActiveBeforeAttaching_)
     337        {
     338            this->activatePhysics();
     339            this->bPhysicsActiveBeforeAttaching_ = false;
     340        }
     341    }
     342
     343    WorldEntity* WorldEntity::getAttachedObject(unsigned int index)
     344    {
     345        unsigned int i = 0;
     346        for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it)
     347        {
     348            if (i == index)
     349                return (*it);
     350            ++i;
     351        }
     352        return 0;
     353    }
     354
    225355    void WorldEntity::attachNode(Ogre::SceneNode* node)
    226356    {
     
    237367    }
    238368
    239     void WorldEntity::attachToNode(Ogre::SceneNode* node)
    240     {
    241         Ogre::Node* parent = this->node_->getParent();
    242         if (parent)
    243             parent->removeChild(this->node_);
    244         node->addChild(this->node_);
    245     }
    246 
    247     void WorldEntity::detachFromNode(Ogre::SceneNode* node)
    248     {
    249         node->removeChild(this->node_);
    250 //        this->getScene()->getRootSceneNode()->addChild(this->node_);
    251     }
    252 
    253     void WorldEntity::attach(WorldEntity* object)
    254     {
    255         if (object == this)
    256         {
    257             COUT(2) << "Warning: Can't attach a WorldEntity to itself." << std::endl;
    258             return;
    259         }
    260 
    261         if (!object->notifyBeingAttached(this))
    262             return;
    263 
    264         this->attachNode(object->node_);
    265         this->children_.insert(object);
    266 
    267         this->attachCollisionShape(object->getCollisionShape());
    268         // mass
    269         this->childrenMass_ += object->getMass();
    270         recalculateMassProps();
    271     }
    272 
    273     bool WorldEntity::notifyBeingAttached(WorldEntity* newParent)
    274     {
    275         // check first whether attaching is even allowed
    276         if (this->hasPhysics())
    277         {
    278             if (!newParent->hasPhysics())
    279             {
    280                 COUT(2) << "Warning: Cannot attach a physical object to a non physical one." << std::endl;
    281                 return false;
    282             }
    283             else if (this->isDynamic())
    284             {
    285                 COUT(2) << "Warning: Cannot attach a dynamic object to a WorldEntity." << std::endl;
    286                 return false;
    287             }
    288             else if (this->isKinematic() && newParent->isDynamic())
    289             {
    290                 COUT(2) << "Warning: Cannot attach a kinematic object to a dynamic one." << std::endl;
    291                 return false;
    292             }
    293             else if (this->isKinematic())
    294             {
    295                 COUT(2) << "Warning: Cannot attach a kinematic object to a static or kinematic one: Not yet implemented." << std::endl;
    296                 return false;
    297             }
    298         }
    299 
    300         if (this->isPhysicsActive())
    301             this->bPhysicsActiveBeforeAttaching_ = true;
    302         this->deactivatePhysics();
    303 
    304         if (this->parent_)
    305             this->detachFromParent();
    306 
    307         this->parent_ = newParent;
    308         this->parentID_ = newParent->getObjectID();
    309 
    310         // apply transform to collision shape
    311         this->collisionShape_->setPosition(this->getPosition());
    312         this->collisionShape_->setOrientation(this->getOrientation());
    313         // TODO: Scale
    314        
    315         return true;
    316     }
    317 
    318     void WorldEntity::detach(WorldEntity* object)
    319     {
    320         if (this->children_.find(object) == this->children_.end())
    321         {
    322             CCOUT(2) << "Warning: Cannot detach an object that is not a child." << std::endl;
    323             return;
    324         }
    325 
    326         // collision shapes
    327         this->detachCollisionShape(object->getCollisionShape());
    328 
    329         // mass
    330         if (object->getMass() > 0.0f)
    331         {
    332             this->childrenMass_ -= object->getMass();
    333             recalculateMassProps();
    334         }
    335 
    336         this->detachNode(object->node_);
    337         this->children_.erase(object);
    338 
    339         object->notifyDetached();
    340     }
    341 
    342     void WorldEntity::notifyDetached()
    343     {
    344         this->parent_ = 0;
    345         this->parentID_ = OBJECTID_UNKNOWN;
    346 
    347         // reset orientation of the collisionShape (cannot be set within a WE usually)
    348         this->collisionShape_->setPosition(Vector3::ZERO);
    349         this->collisionShape_->setOrientation(Quaternion::IDENTITY);
    350         // TODO: Scale
    351 
    352         if (this->bPhysicsActiveBeforeAttaching_)
    353         {
    354             this->activatePhysics();
    355             this->bPhysicsActiveBeforeAttaching_ = false;
    356         }
    357     }
    358 
    359     WorldEntity* WorldEntity::getAttachedObject(unsigned int index) const
    360     {
    361         unsigned int i = 0;
    362         for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it)
    363         {
    364             if (i == index)
    365                 return (*it);
    366             ++i;
    367         }
    368         return 0;
    369     }
    370 
    371369    void WorldEntity::attachOgreObject(Ogre::MovableObject* object)
    372370    {
     
    386384    void WorldEntity::attachCollisionShape(CollisionShape* shape)
    387385    {
    388         this->collisionShape_->attach(shape);
     386        this->collisionShape_.attach(shape);
    389387        // Note: this->collisionShape_ already notifies us of any changes.
    390388    }
     
    392390    void WorldEntity::detachCollisionShape(CollisionShape* shape)
    393391    {
    394         this->collisionShape_->detach(shape);
     392        this->collisionShape_.detach(shape);
    395393        // Note: this->collisionShape_ already notifies us of any changes.
    396394    }
     
    398396    CollisionShape* WorldEntity::getAttachedCollisionShape(unsigned int index) const
    399397    {
    400         return this->collisionShape_->getAttachedShape(index);
    401     }
    402 
    403     void WorldEntity::activatePhysics()
    404     {
    405         if (this->isActive() && this->hasPhysics() && !this->isPhysicsActive() && !this->parent_)
    406         {
    407             this->getScene()->addPhysicalObject(this);
    408             this->bPhysicsActive_ = true;
    409         }
    410     }
    411 
    412     void WorldEntity::deactivatePhysics()
    413     {
    414         if (this->isPhysicsActive())
    415         {
    416             this->getScene()->removePhysicalObject(this);
    417             this->bPhysicsActive_ = false;
    418         }
    419     }
    420 
    421     bool WorldEntity::addedToPhysicalWorld() const
    422     {
    423         return this->physicalBody_ && this->physicalBody_->isInWorld();
    424     }
    425 
     398        return this->collisionShape_.getAttachedShape(index);
     399    }
     400
     401    // Note: These functions are placed in WorldEntity.h as inline functions for the release build.
    426402#ifndef _NDEBUG
    427403    const Vector3& WorldEntity::getPosition() const
     
    451427    }
    452428
    453     void WorldEntity::translate(const Vector3& distance, TransformSpace::Space relativeTo)
     429    const Vector3& WorldEntity::getWorldScale3D() const
     430    {
     431        return this->node_->_getDerivedScale();
     432    }
     433
     434    float WorldEntity::getWorldScale() const
     435    {
     436        Vector3 scale = this->getWorldScale3D();
     437        return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1;
     438    }
     439
     440    void WorldEntity::setScale3D(const Vector3& scale)
     441    {
     442/*
     443HACK HACK HACK
     444        if (bScalePhysics && this->hasPhysics() && scale != Vector3::UNIT_SCALE)
     445        {
     446            CCOUT(2) << "Warning: Cannot set the scale of a physical object: Not yet implemented. Ignoring scaling." << std::endl;
     447            return;
     448        }
     449HACK HACK HACK
     450*/
     451        this->node_->setScale(scale);
     452
     453        this->changedScale();
     454    }
     455
     456    void WorldEntity::translate(const Vector3& distance, TransformSpace::Enum relativeTo)
    454457    {
    455458        switch (relativeTo)
     
    474477
    475478    void WorldEntity::rotate(const Quaternion& rotation, TransformSpace::Space relativeTo)
     479    void WorldEntity::rotate(const Quaternion& rotation, TransformSpace::Enum relativeTo)
    476480    {
    477481        switch(relativeTo)
     
    493497
    494498    void WorldEntity::lookAt(const Vector3& target, TransformSpace::Space relativeTo, const Vector3& localDirectionVector)
     499    void WorldEntity::lookAt(const Vector3& target, TransformSpace::Enum relativeTo, const Vector3& localDirectionVector)
    495500    {
    496501        Vector3 origin;
     
    511516
    512517    void WorldEntity::setDirection(const Vector3& direction, TransformSpace::Space relativeTo, const Vector3& localDirectionVector)
     518    void WorldEntity::setDirection(const Vector3& direction, TransformSpace::Enum relativeTo, const Vector3& localDirectionVector)
    513519    {
    514520        Quaternion savedOrientation(this->getOrientation());
     
    529535    }
    530536
    531     void WorldEntity::setScale3D(const Vector3& scale)
    532     {
    533 /*
    534         if (this->hasPhysics() && scale != Vector3::UNIT_SCALE)
    535         {
    536             CCOUT(2) << "Warning: Cannot set the scale of a physical object: Not yet implemented." << std::endl;
    537             return;
    538         }
    539 */
    540         this->node_->setScale(scale);
    541 
    542         this->changedScale();
    543     }
    544 
    545     const Vector3& WorldEntity::getWorldScale3D() const
    546     {
    547         return this->node_->_getDerivedScale();
    548     }
    549 
    550     float WorldEntity::getWorldScale() const
    551     {
    552         Vector3 scale = this->getWorldScale3D();
    553         return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1;
     537    void WorldEntity::activatePhysics()
     538    {
     539        if (this->isActive() && this->hasPhysics() && !this->isPhysicsActive() && !this->parent_)
     540        {
     541            this->getScene()->addPhysicalObject(this);
     542            this->bPhysicsActive_ = true;
     543        }
     544    }
     545
     546    void WorldEntity::deactivatePhysics()
     547    {
     548        if (this->isPhysicsActive())
     549        {
     550            this->getScene()->removePhysicalObject(this);
     551            this->bPhysicsActive_ = false;
     552        }
     553    }
     554
     555    bool WorldEntity::addedToPhysicalWorld() const
     556    {
     557        return this->physicalBody_ && this->physicalBody_->isInWorld();
    554558    }
    555559
    556560    void WorldEntity::setCollisionType(CollisionType type)
    557561    {
     562        if (this->collisionType_ == type)
     563            return;
     564
    558565        // If we are already attached to a parent, this would be a bad idea..
    559566        if (this->parent_)
     
    562569            return;
    563570        }
    564         else if (this->addedToPhysicalWorld())
    565         {
    566             CCOUT(2) << "Warning: Cannot set the collision type at run time." << std::endl;
    567             return;
    568         }
    569 
    570         // Check for type legality. Could be StaticEntity or MobileEntity
     571
     572        // Check for type legality. Could be StaticEntity or MobileEntity.
    571573        if (!this->isCollisionTypeLegal(type))
    572574            return;
     
    576578            return;
    577579        }
     580
     581        if (this->isPhysicsActive())
     582            this->deactivatePhysics();
     583
     584        bool bReactivatePhysics = true;
     585        if (this->hasPhysics() && !this->isPhysicsActive())
     586            bReactivatePhysics = false;
    578587
    579588        // Check whether we have to create or destroy.
     
    581590        {
    582591/*
     592HACK HACK HACK
    583593            // Check whether there was some scaling applied.
    584594            if (!this->node_->getScale().positionEquals(Vector3(1, 1, 1), 0.001))
     
    587597                return;
    588598            }
     599HACK HACK HACK
    589600*/
    590601            // Create new rigid body
    591             btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, this->collisionShape_->getCollisionShape());
     602            btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, this->collisionShape_.getCollisionShape());
    592603            this->physicalBody_ = new btRigidBody(bodyConstructionInfo);
    593604            this->physicalBody_->setUserPointer(this);
     
    619630            break;
    620631        case None:
    621             return; // this->collisionType_ was None too
    622         }
    623 
    624         // Only sets this->collisionShape_
     632            assert(false); // Doesn't happen
     633            return;
     634        }
     635
     636        // Only sets this->collisionType_
    625637        // However the assertion is to ensure that the internal bullet setting is right
    626638        updateCollisionType();
     
    629641        // update mass and inertia tensor
    630642        recalculateMassProps();
    631         resetPhysicsProps();
     643        internalSetPhysicsProps();
    632644        collisionCallbackActivityChanged();
    633         activatePhysics();
     645        if (bReactivatePhysics)
     646            activatePhysics();
    634647    }
    635648
     
    682695    }
    683696
    684     void WorldEntity::notifyChildMassChanged() // Called by a child WE
     697    void WorldEntity::notifyChildMassChanged()
    685698    {
    686699        // Note: CollisionShape changes of a child get handled over the internal CompoundCollisionShape already
     
    695708    }
    696709
    697     void WorldEntity::notifyCollisionShapeChanged() // called by this->collisionShape_
     710    void WorldEntity::notifyCollisionShapeChanged()
    698711    {
    699712        if (hasPhysics())
     
    703716            {
    704717                this->deactivatePhysics();
    705                 this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
     718                this->physicalBody_->setCollisionShape(this->collisionShape_.getCollisionShape());
    706719                this->activatePhysics();
    707720            }
    708721            else
    709                 this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
     722                this->physicalBody_->setCollisionShape(this->collisionShape_.getCollisionShape());
    710723        }
    711724        recalculateMassProps();
     
    716729        // Store local inertia for faster access. Evaluates to (0,0,0) if there is no collision shape.
    717730        float totalMass = this->mass_ + this->childrenMass_;
    718         this->collisionShape_->calculateLocalInertia(totalMass, this->localInertia_);
     731        this->collisionShape_.calculateLocalInertia(totalMass, this->localInertia_);
    719732        if (this->hasPhysics())
    720733        {
     
    729742                CCOUT(4) << "Warning: Setting the internal physical mass to 1.0 because mass_ is 0.0." << std::endl;
    730743                btVector3 inertia(0, 0, 0);
    731                 this->collisionShape_->calculateLocalInertia(1.0f, inertia);
     744                this->collisionShape_.calculateLocalInertia(1.0f, inertia);
    732745                this->physicalBody_->setMassProps(1.0f, inertia);
    733746            }
     
    739752    }
    740753
    741     void WorldEntity::resetPhysicsProps()
     754    void WorldEntity::internalSetPhysicsProps()
    742755    {
    743756        if (this->hasPhysics())
Note: See TracChangeset for help on using the changeset viewer.