Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 29, 2008, 12:45:19 AM (16 years ago)
Author:
rgrieder
Message:

Clarified use of different physical bodies. The "collisionType" XML attribute of WE specifies the following:
"none": There is not physical body at all. Physics disabled.
"static": It is a StaticEntity with physics. Any other derived class of WE issues an exception by choosing this collision type.
"kinematic" or "dynamic": MovableEntity with physics. StaticEntity issues an exception when choosing one of these two.

Added two new Exceptions: ParseError and PhysicsViolation.

Location:
code/branches/physics/src/orxonox/objects/worldentities
Files:
7 edited

Legend:

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

    r2292 r2298  
    301301            this->node_->setDirection(direction, relativeTo, localDirectionVector);
    302302        }
     303    }
     304
     305    bool MovableEntity::isCollisionTypeLegal(WorldEntity::CollisionType type)
     306    {
     307        if (type == WorldEntity::Static)
     308        {
     309            ThrowException(PhysicsViolation, "Cannot tell a MovableEntity to have static collision type");
     310            return false;
     311        }
     312        else
     313            return true;
    303314    }
    304315
  • code/branches/physics/src/orxonox/objects/worldentities/MovableEntity.h

    r2292 r2298  
    7474            virtual void positionChanged() { }
    7575            virtual void orientationChanged() { }
     76            virtual bool isCollisionTypeLegal(WorldEntity::CollisionType type);
    7677
    7778            // Bullet btMotionState related
  • code/branches/physics/src/orxonox/objects/worldentities/StaticEntity.cc

    r2292 r2298  
    6060    }
    6161
    62     void StaticEntity::setCollisionType(CollisionType type)
     62    bool StaticEntity::isCollisionTypeLegal(WorldEntity::CollisionType type)
    6363    {
    64         if (!this->physicalBody_)
    65             return;
    66         if (type != Static)
    67             ThrowException(Argument, "Cannot tell a StaticEntity to be kinematic or dynamic");
    68 
    69         this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT);
     64        if (type == WorldEntity::Static)
     65        {
     66            ThrowException(PhysicsViolation, "Cannot tell a MovableEntity to have static collision type");
     67            return false;
     68        }
     69        else
     70            return true;
    7071    }
    7172
  • code/branches/physics/src/orxonox/objects/worldentities/StaticEntity.h

    r2292 r2298  
    7474        private:
    7575
    76             void setCollisionType(CollisionType type);
     76            bool isCollisionTypeLegal(CollisionType type);
    7777
    7878            // Bullet btMotionState related
  • code/branches/physics/src/orxonox/objects/worldentities/WorldEntity.cc

    r2292 r2298  
    4141
    4242#include "objects/Scene.h"
    43 
    44 #include "StaticEntity.h"
    4543
    4644namespace orxonox
     
    7068        // Default behaviour does not include physics
    7169        this->physicalBody_ = 0;
     70        updateCollisionType();
    7271
    7372        this->registerVariables();
     
    8180            if (this->getScene()->getSceneManager())
    8281                this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
    83            
    84             // Physics is not guaranteed, so check first
    85             if (this->physicalBody_)
    86             {
    87                 if (this->physicalBody_->isInWorld())
    88                     this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
    89                 if (this->physicalBody_->getCollisionShape())
    90                     delete this->physicalBody_->getCollisionShape();
    91                 delete this->physicalBody_;
    92             }
     82
     83            this->setCollisionType(None);
    9384        }
    9485    }
     
    10899        XMLPortParam(WorldEntity, "scale", setScale, getScale, xmlelement, mode);
    109100
     101        XMLPortParam(WorldEntity, "collisionType", setCollisionTypeStr, getCollisionTypeStr, xmlelement, mode);
    110102        XMLPortParam(WorldEntity, "collisionRadius", setCollisionRadius, getCollisionRadius, xmlelement, mode);
    111         XMLPortParam(WorldEntity, "collisionType", setCollisionTypeStr, getCollisionTypeStr, xmlelement, mode);
    112103        XMLPortParam(WorldEntity, "mass", setMass, getMass, xmlelement, mode);
    113104
    114         if (this->physicalBody_)
     105        XMLPortObject(WorldEntity, WorldEntity, "attached", attach, getAttachedObject, xmlelement, mode);
     106
     107        // Add the physical after loading because we cannot change its attributes without removing.
     108        if (getCollisionType() != None)
    115109            this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
    116 
    117         XMLPortObject(WorldEntity, WorldEntity, "attached", attach, getAttachedObject, xmlelement, mode);
    118110    }
    119111
     
    200192    }
    201193
    202     void WorldEntity::createPhysicalBody()
    203     {
    204         // Note: The motion state will be configured in a derived class.
    205         btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, 0, btVector3(0,0,0));
    206         this->physicalBody_ = new btRigidBody(bodyConstructionInfo);
    207     }
    208 
    209194    float WorldEntity::getMass()
    210195    {
    211         if (!this->physicalBody_)
     196        if (!checkPhysics())
    212197            return 0.0f;
    213198
     
    217202    void WorldEntity::setMass(float mass)
    218203    {
    219         if (!this->physicalBody_)
    220             this->createPhysicalBody();
    221 
    222         this->physicalBody_->setMassProps(mass, btVector3(0,0,0));
    223     }
    224 
    225     void WorldEntity::setCollisionType(WorldEntity::CollisionType type)
    226     {
    227         if (!this->physicalBody_)
    228             this->createPhysicalBody();
    229 
     204        if (!checkPhysics())
     205            return;
     206        else if (this->physicalBody_->isInWorld())
     207        {
     208            CCOUT(2) << "Cannot set the physical mass at run time." << std::endl;
     209            assert(false);
     210        }
     211        else
     212        {
     213            this->physicalBody_->setMassProps(mass, btVector3(0,0,0));
     214            updateCollisionType();
     215        }
     216    }
     217
     218    void WorldEntity::setCollisionType(CollisionType type)
     219    {
     220        // Check first whether we have to create or destroy.
     221        if (type != None && this->collisionType_ == None)
     222        {
     223            // Create new rigid body
     224            btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, 0, btVector3(0,0,0));
     225            this->physicalBody_ = new btRigidBody(bodyConstructionInfo);
     226            this->physicalBody_->setUserPointer(this);
     227
     228            // Adjust parameters according to the node
     229            btTransform nodeTransform;
     230            //this->
     231        }
     232        else if (type == None && this->collisionType_ != None)
     233        {
     234            // Destroy rigid body
     235            if (this->physicalBody_->isInWorld())
     236                this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
     237            if (this->physicalBody_->getCollisionShape())
     238                delete this->physicalBody_->getCollisionShape();
     239            delete this->physicalBody_;
     240            this->physicalBody_ = 0;
     241            this->collisionType_ = None;
     242            return;
     243        }
     244
     245        // Check for type legality. Could be StaticEntity or MovableEntity
     246        if (!this->isCollisionTypeLegal(type))
     247            return; // exception gets issued anyway
     248
     249        // Change type
    230250        switch (type)
    231251        {
     
    239259            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT);
    240260            break;
    241         }
    242     }
    243 
    244     WorldEntity::CollisionType WorldEntity::getCollisionType()
     261        case None:
     262            return; // this->collisionType_ was None too
     263        }
     264
     265        // Mass non zero is a bad idea for kinematic and static objects
     266        if ((type == Kinematic || type == Static) && getMass() != 0.0f)
     267            this->setMass(0.0f);
     268        // Mass zero is not such a good idea for dynamic objects
     269        else if (type == Dynamic && getMass() == 0.0f)
     270            this->setMass(1.0f);
     271
     272        // finally update our variable for faster checks
     273        updateCollisionType();
     274    }
     275
     276    void WorldEntity::updateCollisionType()
    245277    {
    246278        if (!this->physicalBody_)
    247             ThrowException(Argument, "Cannot retrieve collision type of a non physical object.");
    248 
    249         int flags = this->physicalBody_->getCollisionFlags();
    250         if (flags & btCollisionObject::CF_STATIC_OBJECT)
    251             return Static;
    252         else if (flags & btCollisionObject::CF_KINEMATIC_OBJECT)
    253             return Kinematic;
    254         else
    255             return Dynamic;
    256     }
    257 
    258     void WorldEntity::setCollisionTypeStr(const std::string& type)
    259     {
    260         std::string lower = getLowercase(type);
    261         if (lower == "dynamic")
    262             setCollisionType(Dynamic);
    263         else if (lower == "static")
    264             setCollisionType(Static);
    265         else if (lower == "kinematic")
    266             setCollisionType(Kinematic);
    267         else
    268             ThrowException(Argument, std::string("Trying to set an unknown collision type: '") + type + "'.");
     279            this->collisionType_ = None;
     280        else if (this->physicalBody_->isKinematicObject())
     281            this->collisionType_ = Kinematic;
     282        else if (this->physicalBody_->isStaticObject())
     283            this->collisionType_ = Static;
     284        else
     285            this->collisionType_ = Dynamic;
     286    }
     287
     288    void WorldEntity::setCollisionTypeStr(const std::string& typeStr)
     289    {
     290        std::string typeStrLower = getLowercase(typeStr);
     291        CollisionType type;
     292        if (typeStrLower == "dynamic")
     293            type = Dynamic;
     294        else if (typeStrLower == "static")
     295            type = Static;
     296        else if (typeStrLower == "kinematic")
     297            type = Kinematic;
     298        else if (typeStrLower == "none")
     299            type = None;
     300        else
     301            ThrowException(ParseError, std::string("Attempting to set an unknown collision type: '") + typeStr + "'.");
     302        this->setCollisionType(type);
    269303    }
    270304
     
    273307        switch (this->getCollisionType())
    274308        {
    275         case Dynamic:
    276             return "dynamic";
    277         case Kinematic:
    278             return "kinematic";
    279         case Static:
    280             return "static";
    281         default:
    282             ThrowException(Argument, "Encountered unknown collision Type.");
     309            case Dynamic:
     310                return "dynamic";
     311            case Kinematic:
     312                return "kinematic";
     313            case Static:
     314                return "static";
     315            case None:
     316                return "none";
     317            default:
     318                assert(false);
     319                return "";
    283320        }
    284321    }
     
    286323    void WorldEntity::setCollisionRadius(float radius)
    287324    {
    288         if (!this->physicalBody_)
    289             createPhysicalBody();
     325        if (!checkPhysics())
     326            return;
    290327
    291328        // destroy old one first
     
    299336    float WorldEntity::getCollisionRadius()
    300337    {
    301         if (this->physicalBody_)
     338        if (checkPhysics())
    302339        {
    303340            btSphereShape* sphere = dynamic_cast<btSphereShape*>(this->physicalBody_->getCollisionShape());
     
    307344        return 0.0f;
    308345    }
     346
     347    bool WorldEntity::checkPhysics()
     348    {
     349        if (!this->physicalBody_)
     350        {
     351            assert(this->getCollisionType() == None);
     352            COUT(2) << "WorldEntity was not fitted with physics, cannot set phyiscal property." << std::endl;
     353            return false;
     354        }
     355        else
     356            return true;
     357    }
    309358}
  • code/branches/physics/src/orxonox/objects/worldentities/WorldEntity.h

    r2296 r2298  
    4646    class _OrxonoxExport WorldEntity : public BaseObject, public network::Synchronisable, public btMotionState
    4747    {
    48         public:
    49             enum CollisionType
    50             {
    51                 Dynamic,
    52                 Kinematic,
    53                 Static
    54             };
    55 
    5648        public:
    5749            WorldEntity(BaseObject* creator);
     
    135127                { this->node_->scale(scale, scale, scale); }
    136128
    137             bool hasPhysics()  { return this->physicalBody_; }
    138             bool isKinematic() { return this->physicalBody_ && this->physicalBody_->isKinematicObject(); }
    139             bool isDynamic()   { return this->physicalBody_ && !this->physicalBody_->isStaticOrKinematicObject(); }
    140 
    141129            void attach(WorldEntity* object);
    142130            void detach(WorldEntity* object);
     
    159147                { return this->parent_; }
    160148
    161             void setCollisionRadius(float radius);
    162             float getCollisionRadius();
    163 
    164             void setCollisionTypeStr(const std::string& type);
    165             std::string getCollisionTypeStr();
    166 
    167             void setMass(float mass);
    168             float getMass();
    169 
    170             CollisionType getCollisionType();
    171 
    172149        protected:
    173             //virtual btCollisionShape* getCollisionShape() = 0;
    174 
    175             void createPhysicalBody();
    176             //virtual void attachPhysicalObject(WorldEntity* object);
    177             virtual void setCollisionType(CollisionType type);
    178 
    179150            Ogre::SceneNode* node_;
    180             btRigidBody* physicalBody_;
    181151
    182152        private:
     
    197167            unsigned int parentID_;
    198168            std::set<WorldEntity*> children_;
     169
     170            /////////////
     171            // Physics //
     172            /////////////
     173
     174        public:
     175            enum CollisionType
     176            {
     177                Dynamic,
     178                Kinematic,
     179                Static,
     180                None
     181            };
     182
     183            bool hasPhysics()  { return getCollisionType() != None; }
     184
     185            CollisionType getCollisionType() { return this->collisionType_; }
     186            void setCollisionType(CollisionType type);
     187
     188            void setCollisionTypeStr(const std::string& type);
     189            std::string getCollisionTypeStr();
     190
     191            bool isStatic()    { return getCollisionType() == Static   ; }
     192            bool isKinematic() { return getCollisionType() == Kinematic; }
     193            bool isDynamic()   { return getCollisionType() == Dynamic  ; }
     194
     195            void setMass(float mass);
     196            float getMass();
     197
     198            void setCollisionRadius(float radius);
     199            float getCollisionRadius();
     200
     201        protected:
     202            //virtual btCollisionShape* getCollisionShape() = 0;
     203            //virtual void attachPhysicalObject(WorldEntity* object);
     204
     205            virtual bool isCollisionTypeLegal(CollisionType type) = 0;
     206            bool checkPhysics();
     207            void updateCollisionType();
     208
     209            btRigidBody*  physicalBody_;
     210
     211        private:
     212            CollisionType collisionType_;
     213
    199214    };
    200215}
  • code/branches/physics/src/orxonox/objects/worldentities/pawns/SpaceShip.cc

    r2292 r2298  
    6060
    6161        this->setDestroyWhenPlayerLeft(true);
    62 
    63         // create a phyisical body
    64         OrxAssert(this->physicalBody_ == 0, " Check why there is already a physical body in the space ship.");
    65         this->createPhysicalBody();
    6662
    6763        this->setConfigValues();
Note: See TracChangeset for help on using the changeset viewer.