Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 28, 2008, 1:25:16 AM (15 years ago)
Author:
rgrieder
Message:

Finally managed to work out some physics. According to my tests, collisions with simple spheres should work with dynamic/kinematic/static objects. There are currently only a limited number of XML parameters, but we're surely going to extend that. Furthermore there is some more thinking to be done concerning changes of btRigidBody properties when it's already added to the world.

File:
1 edited

Legend:

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

    r2201 r2292  
    3232#include <cassert>
    3333#include <OgreSceneManager.h>
     34
    3435#include "BulletCollision/CollisionShapes/btSphereShape.h"
    3536
     37#include "util/Exception.h"
     38#include "util/Convert.h"
    3639#include "core/CoreIncludes.h"
    3740#include "core/XMLPort.h"
    38 #include "util/Convert.h"
    3941
    4042#include "objects/Scene.h"
     43
     44#include "StaticEntity.h"
    4145
    4246namespace orxonox
     
    6569
    6670        // Default behaviour does not include physics
    67         this->bAddedToPhysicalWorld_ = false;
    6871        this->physicalBody_ = 0;
    6972
     
    8285            if (this->physicalBody_)
    8386            {
    84                 if (this->bAddedToPhysicalWorld_)
     87                if (this->physicalBody_->isInWorld())
    8588                    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
    8689                if (this->physicalBody_->getCollisionShape())
     
    104107        XMLPortParamTemplate(WorldEntity, "scale3D", setScale3D, getScale3D, xmlelement, mode, const Vector3&);
    105108        XMLPortParam(WorldEntity, "scale", setScale, getScale, xmlelement, mode);
    106         XMLPortParam(WorldEntity, "collisionRadius", setcollisionRadius, getcollisionRadius, xmlelement, mode);
     109
     110        XMLPortParam(WorldEntity, "collisionRadius", setCollisionRadius, getCollisionRadius, xmlelement, mode);
     111        XMLPortParam(WorldEntity, "collisionType", setCollisionTypeStr, getCollisionTypeStr, xmlelement, mode);
     112        XMLPortParam(WorldEntity, "mass", setMass, getMass, xmlelement, mode);
     113
     114        if (this->physicalBody_)
     115            this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
    107116
    108117        XMLPortObject(WorldEntity, WorldEntity, "attached", attach, getAttachedObject, xmlelement, mode);
     
    145154
    146155        // Do the physical connection if required
    147         this->attachPhysicalObject(object);
    148     }
    149 
    150     void WorldEntitiy::attachPhysicalObject(WorldEntity* object){
    151     //function attachhysicalObject
    152         StaticEntity* staticObject = dynamic_cast<WorldEntity*>(object);
    153         if (staticObject != 0 && hasPhysics()){
    154            btCompountShape* compoundShape = dynamic_cast<btCompoundShape*>(physicalBody_->getCollisionShape());
    155            if(compoundShape == 0){
    156                 //NEW
    157                 btCompoundShape* newShape = new btCompoundShape();
    158                 newShape->addChildShape(this->physcialBody_->getCollisionShape());
    159                 newShape->addChildShape(staticObject->getCollisionShape());
    160                 this->physicalBody_->setCollisionShape();
    161            }
    162            else{
    163                compoundShape -> addChildShape(staticObject->getCollisionShape());
    164            }
    165         }
    166     }
     156        //this->attachPhysicalObject(object);
     157    }
     158
     159    //void WorldEntity::attachPhysicalObject(WorldEntity* object)
     160    //{
     161    //    StaticEntity* staticObject = dynamic_cast<StaticEntity*>(object);
     162    //    if (staticObject != 0 && this->hasPhysics())
     163    //    {
     164    //       btCompoundShape* compoundShape = dynamic_cast<btCompoundShape*>(this->physicalBody_->getCollisionShape());
     165    //       if (compoundShape == 0)
     166    //       {
     167    //            // create a compound shape and add both
     168    //            compoundShape = new btCompoundShape();
     169    //            compoundShape->addChildShape(this->physicalBody_->getCollisionShape());
     170    //            compoundShape->addChildShape(staticObject->getCollisionShape());
     171    //            this->physicalBody_->setCollisionShape();
     172    //       }
     173    //       else
     174    //       {
     175    //           compoundShape -> addChildShape(staticObject->getCollisionShape());
     176    //       }
     177    //    }
     178    //}
    167179
    168180    void WorldEntity::detach(WorldEntity* object)
     
    193205        btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, 0, btVector3(0,0,0));
    194206        this->physicalBody_ = new btRigidBody(bodyConstructionInfo);
    195         this->getScene()->getPhysicalWorld()->addRigidBody(this->physicalBody_);
    196         this->bAddedToPhysicalWorld_ = true;
    197     }
    198 
    199     void WorldEntity::setcollisionRadius(float radius)
     207    }
     208
     209    float WorldEntity::getMass()
     210    {
     211        if (!this->physicalBody_)
     212            return 0.0f;
     213
     214        return 1.0f/this->physicalBody_->getInvMass();
     215    }
     216
     217    void WorldEntity::setMass(float mass)
     218    {
     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
     230        switch (type)
     231        {
     232        case Dynamic:
     233            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !(btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_KINEMATIC_OBJECT));
     234            break;
     235        case Kinematic:
     236            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_KINEMATIC_OBJECT);
     237            break;
     238        case Static:
     239            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT);
     240            break;
     241        }
     242    }
     243
     244    WorldEntity::CollisionType WorldEntity::getCollisionType()
     245    {
     246        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 + "'.");
     269    }
     270
     271    std::string WorldEntity::getCollisionTypeStr()
     272    {
     273        switch (this->getCollisionType())
     274        {
     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.");
     283        }
     284    }
     285
     286    void WorldEntity::setCollisionRadius(float radius)
    200287    {
    201288        if (!this->physicalBody_)
    202289            createPhysicalBody();
    203290
    204         // destroy old onw first
     291        // destroy old one first
    205292        btCollisionShape* oldShape = this->physicalBody_->getCollisionShape();
    206293        if (oldShape)
     
    210297    }
    211298
    212     float WorldEntity::getcollisionRadius()
     299    float WorldEntity::getCollisionRadius()
    213300    {
    214301        if (this->physicalBody_)
Note: See TracChangeset for help on using the changeset viewer.