Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 13, 2008, 4:14:36 PM (15 years ago)
Author:
rgrieder
Message:
  • Added detach functions to CollisionShapes
  • Added update functions across the CollisionShape hierarchy so that when you change the radius of a sphere, everything up to the WE gets updated.
  • Setting the btCollisionShape at run time doesn't work after all, fixed that (you can still do it, just a question of internals)
  • Improved network synchronisation
  • new WE function: addedToPhysicalWorld() to check whether we can still perform operations that are disallowed at run time (esp. StaticEntity)

Conclusively, I can say that right now, all operations considering physics should be handled automatically, bugs not withstanding.

Location:
code/branches/physics/src/orxonox/objects/collisionshapes
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • code/branches/physics/src/orxonox/objects/collisionshapes/CollisionShape.cc

    r2403 r2423  
    7676    void CollisionShape::registerVariables()
    7777    {
    78         REGISTERDATA(this->parentID_, network::direction::toclient, new network::NetworkCallback<CollisionShape>(this, &CollisionShape::updateParent));
     78        REGISTERDATA(this->parentID_, network::direction::toclient, new network::NetworkCallback<CollisionShape>(this, &CollisionShape::parentChanged));
     79    }
     80
     81    void CollisionShape::parentChanged()
     82    {
     83        CompoundCollisionShape* parent = dynamic_cast<CompoundCollisionShape*>(Synchronisable::getSynchronisable(this->parentID_));
     84        if (parent)
     85            parent->addChildShape(this);
    7986    }
    8087
    8188    void CollisionShape::updateParent()
    8289    {
    83         CompoundCollisionShape* parent = dynamic_cast<CompoundCollisionShape*>(Synchronisable::getSynchronisable(this->parentID_));
    84         if (parent)
    85             parent->addChildShape(this);
     90        if (this->parent_)
     91            this->parent_->updateChildShape(this);
    8692    }
    8793
     
    95101    {
    96102        ThrowException(NotImplemented, "Cannot set the scale of a collision shape: Not yet implemented.");
     103        this->updateParent();
    97104    }
    98105
     
    100107    {
    101108        ThrowException(NotImplemented, "Cannot set the scale of a collision shape: Not yet implemented.");
     109        this->updateParent();
     110    }
     111
     112    btVector3 CollisionShape::getLocalInertia(btScalar mass) const
     113    {
     114        btVector3 inertia(0, 0, 0);
     115        if (this->collisionShape_)
     116            this->collisionShape_->calculateLocalInertia(mass, inertia);
     117        return inertia;
    102118    }
    103119}
  • code/branches/physics/src/orxonox/objects/collisionshapes/CollisionShape.h

    r2377 r2423  
    3232#include "OrxonoxPrereqs.h"
    3333
     34#include "LinearMath/btVector3.h"
    3435#include "util/Math.h"
    3536#include "core/BaseObject.h"
     
    4849
    4950            inline void setPosition(const Vector3& position)
    50                 { this->position_ = position; }
     51                { this->position_ = position; this->updateParent(); }
    5152            inline const Vector3& getPosition() const
    5253                { return this->position_; }
    5354
    5455            inline void setOrientation(const Quaternion& orientation)
    55                 { this->orientation_ = orientation; }
     56                { this->orientation_ = orientation; this->updateParent(); }
    5657            inline const Quaternion& getOrientation() const
    5758                { return this->orientation_; }
    5859
    59             void yaw(const Degree& angle)   { this->orientation_ = this->orientation_ * Quaternion(angle, Vector3::UNIT_Y); }
    60             void pitch(const Degree& angle) { this->orientation_ = this->orientation_ * Quaternion(angle, Vector3::UNIT_X); }
    61             void roll(const Degree& angle)  { this->orientation_ = this->orientation_ * Quaternion(angle, Vector3::UNIT_Z); }
     60            void yaw(const Degree& angle)   { this->setOrientation(this->orientation_ * Quaternion(angle, Vector3::UNIT_Y)); }
     61            void pitch(const Degree& angle) { this->setOrientation(this->orientation_ * Quaternion(angle, Vector3::UNIT_X)); }
     62            void roll(const Degree& angle)  { this->setOrientation(this->orientation_ * Quaternion(angle, Vector3::UNIT_Z)); }
    6263
    6364            virtual void setScale3D(const Vector3& scale);
     
    6667                { return this->scale_; }
    6768
    68             virtual inline btCollisionShape* getCollisionShape() const
     69            btVector3 getLocalInertia(float mass) const;
     70
     71            inline btCollisionShape* getCollisionShape() const
    6972                { return this->collisionShape_; }
    7073
     
    7578
    7679        protected:
    77             btCollisionShape* collisionShape_;
     80            virtual void updateParent();
     81
     82            btCollisionShape*       collisionShape_;
     83            CompoundCollisionShape* parent_;
    7884
    7985        private:
    80             void updateParent();
     86            void parentChanged();
    8187
    82             Vector3           position_;
    83             Quaternion        orientation_;
    84             Vector3           scale_;
    85             CompoundCollisionShape* parent_;
    86             unsigned int      parentID_;
     88            Vector3                 position_;
     89            Quaternion              orientation_;
     90            Vector3                 scale_;
     91            unsigned int            parentID_;
    8792    };
    8893}
  • code/branches/physics/src/orxonox/objects/collisionshapes/CompoundCollisionShape.cc

    r2407 r2423  
    3232#include "BulletCollision/CollisionShapes/btCompoundShape.h"
    3333
     34#include "util/Exception.h"
    3435#include "core/CoreIncludes.h"
    3536#include "core/XMLPort.h"
    3637#include "tools/BulletConversions.h"
     38#include "objects/worldentities/WorldEntity.h"
    3739
    3840namespace orxonox
     
    5052    {
    5153        if (this->isInitialized())
     54        {
     55            // Detatch all children first
     56            this->removeAllChildShapes();
    5257            delete this->compoundShape_;
     58        }
    5359    }
    5460
     
    6066    }
    6167
    62     btCollisionShape* CompoundCollisionShape::getCollisionShape() const
     68    void CompoundCollisionShape::addChildShape(CollisionShape* shape)
    6369    {
    64         // Note: Returning collisionShape_ means that it's the only one and has no transform.
    65         //       So we can get rid of the additional overhead with the compound shape.
    66         if (this->collisionShape_)
    67             return this->collisionShape_;
    68         else if (!this->empty())
    69             return this->compoundShape_;
    70         else
    71             return 0;
    72     }
    73 
    74     void CompoundCollisionShape::addChildShape(CollisionShape* shape, bool bWorldEntityRoot)
    75     {
    76         if (!shape)
     70        if (!shape || static_cast<CollisionShape*>(this) == shape)
    7771            return;
    78         this->childShapes_.push_back(shape);
     72        if (this->childShapes_.find(shape) != this->childShapes_.end())
     73        {
     74            ThrowException(NotImplemented, "Warning: Attaching a CollisionShape twice is not yet supported.");
     75            return;
     76        }
     77        this->childShapes_[shape] = shape->getCollisionShape();
    7978
    8079        if (shape->getCollisionShape())
     
    8483            this->compoundShape_->addChildShape(transf, shape->getCollisionShape());
    8584
    86             if (this->childShapes_.size() == 1 && !this->childShapes_[0]->hasTransform())
    87             {
    88                 // --> Only shape to be added, no transform; add it directly
    89                 this->collisionShape_ = shape->getCollisionShape();
    90             }
    91             else
    92             {
    93                 // Make sure we use the compound shape when returning the btCollisionShape
    94                 this->collisionShape_ = 0;
    95             }
     85            this->updatePublicShape();
    9686        }
    9787
    9888        // network synchro
    99         if (!bWorldEntityRoot)
    100             shape->setParent(this, this->getObjectID());
     89        shape->setParent(this, this->getObjectID());
     90    }
     91
     92    void CompoundCollisionShape::removeChildShape(CollisionShape* shape)
     93    {
     94        if (this->childShapes_.find(shape) != this->childShapes_.end())
     95        {
     96            shape->setParent(0, (unsigned int)-1);
     97            this->childShapes_.erase(shape);
     98            if (shape->getCollisionShape())
     99                this->compoundShape_->removeChildShape(shape->getCollisionShape());
     100
     101            this->updatePublicShape();
     102        }
     103    }
     104
     105    void CompoundCollisionShape::removeAllChildShapes()
     106    {
     107        while (this->childShapes_.size() > 0)
     108            this->removeChildShape(this->childShapes_.begin()->first);
     109    }
     110
     111    void CompoundCollisionShape::updateChildShape(CollisionShape* shape)
     112    {
     113        if (!shape)
     114            return;
     115        std::map<CollisionShape*, btCollisionShape*>::iterator it = this->childShapes_.find(shape);
     116        if (it == this->childShapes_.end())
     117        {
     118            CCOUT(2) << "Warning: Cannot update child shape: Instance not a child." << std::endl;
     119            return;
     120        }
     121
     122        // Remove old btCollisionShape, stored in the children map
     123        if (it->second)
     124            this->compoundShape_->removeChildShape(it->second);
     125        if (shape->getCollisionShape())
     126        {
     127            // Only actually attach if we didn't pick a CompoundCollisionShape with no content
     128            btTransform transf(omni_cast<btQuaternion>(shape->getOrientation()), omni_cast<btVector3>(shape->getPosition()));
     129            this->compoundShape_->addChildShape(transf, shape->getCollisionShape());
     130            it->second = shape->getCollisionShape();
     131        }
     132
     133        this->updatePublicShape();
     134    }
     135
     136    void CompoundCollisionShape::updatePublicShape()
     137    {
     138        btCollisionShape* primitive = 0;
     139        bool bPrimitive = true;
     140        bool bEmpty = true;
     141        for (std::map<CollisionShape*, btCollisionShape*>::const_iterator it = this->childShapes_.begin(); it != this->childShapes_.end(); ++it)
     142        {
     143            if (it->second)
     144            {
     145                bEmpty = false;
     146                if (!it->first->hasTransform())
     147                    primitive = it->second;
     148                else
     149                    bPrimitive = false;
     150            }
     151        }
     152        if (bEmpty)
     153            this->collisionShape_ = 0;
     154        else if (bPrimitive)
     155        {
     156            // --> Only one shape to be added, no transform; return it directly
     157            this->collisionShape_ = primitive;
     158        }
     159        else
     160        {
     161            // Make sure we use the compound shape when returning a btCollisionShape
     162            this->collisionShape_ = this->compoundShape_;
     163        }
     164        this->updateParent();
     165    }
     166
     167    void CompoundCollisionShape::updateParent()
     168    {
     169        if (this->parent_)
     170            this->parent_->updateChildShape(this);
     171        else
     172        {
     173            // We can do this, because the CompoundCollisionShape of a WorldEntity always belongs to it,
     174            // as long as its lifetime.
     175            WorldEntity* parent = dynamic_cast<WorldEntity*>(this->getCreator());
     176            if (parent)
     177                parent->notifyCollisionShapeChanged();
     178        }
    101179    }
    102180
    103181    CollisionShape* CompoundCollisionShape::getChildShape(unsigned int index) const
    104182    {
    105         if (index < this->childShapes_.size())
    106             return this->childShapes_[index];
    107         else
    108             return 0;
     183        unsigned int i = 0;
     184        for (std::map<CollisionShape*, btCollisionShape*>::const_iterator it = this->childShapes_.begin(); it != this->childShapes_.end(); ++it)
     185        {
     186            if (i == index)
     187                return it->first;
     188            ++i;
     189        }
     190        return 0;
    109191    }
    110192}
  • code/branches/physics/src/orxonox/objects/collisionshapes/CompoundCollisionShape.h

    r2407 r2423  
    4545            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
    4646
    47             void addChildShape(CollisionShape* shape, bool bWorldEntityRoot = false);
     47            void addChildShape(CollisionShape* shape);
     48            void removeChildShape(CollisionShape* shape);
     49            void removeAllChildShapes();
    4850            CollisionShape* getChildShape(unsigned int index) const;
    4951
    50             virtual btCollisionShape* getCollisionShape() const;
     52            void updateChildShape(CollisionShape* shape);
    5153
    52             inline bool empty() const
    53                 { return this->childShapes_.size() == 0; }
     54        protected:
     55            virtual void updateParent();
    5456
    5557        private:
    56             btCompoundShape*             compoundShape_;
    57             std::vector<CollisionShape*> childShapes_;
     58            void updatePublicShape();
     59
     60            btCompoundShape* compoundShape_;
     61            std::map<CollisionShape*, btCollisionShape*> childShapes_;
    5862    };
    5963}
  • code/branches/physics/src/orxonox/objects/collisionshapes/PlaneCollisionShape.cc

    r2403 r2423  
    7474            delete this->collisionShape_;
    7575        this->collisionShape_ = new btStaticPlaneShape(omni_cast<btVector3>(this->normal_), this->offset_);
     76        this->updateParent();
    7677    }
    7778}
  • code/branches/physics/src/orxonox/objects/collisionshapes/SphereCollisionShape.cc

    r2403 r2423  
    7272        if (this->collisionShape_)
    7373            delete this->collisionShape_;
     74        // When we recreate the shape, we have to inform the parent about this to update the shape
    7475        this->collisionShape_ = new btSphereShape(this->radius_);
     76        this->updateParent();
    7577    }
    7678}
Note: See TracChangeset for help on using the changeset viewer.