Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 2313


Ignore:
Timestamp:
Dec 3, 2008, 1:17:12 AM (16 years ago)
Author:
rgrieder
Message:

Added body queue to Scene: Physical objects now request to be added to the physical world.

Location:
code/branches/physics/src/orxonox/objects
Files:
4 edited

Legend:

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

    r2306 r2313  
    125125
    126126        XMLPortObjectExtended(Scene, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
    127 
    128         // finally add all rigid bodies to the physics engine
    129         if (hasPhysics())
    130         {
    131             for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
    132             {
    133                 WorldEntity* temp = dynamic_cast<WorldEntity*>(*it);
    134                 if (temp)
    135                 {
    136                     if (temp->getCollisionType() != WorldEntity::None)
    137                         this->physicalWorld_->addRigidBody(temp->getPhysicalBody());
    138                 }
    139             }
    140         }
    141127    }
    142128
     
    172158    void Scene::tick(float dt)
    173159    {
    174         // TODO: This is not stable! If physics cannot be calculated real time anymore,
    175         //       framerate will drop exponentially.
    176160        if (physicalWorld_)
     161        {
     162            if (this->physicsQueue_.size() > 0)
     163            {
     164                // Add all scheduled WorldEntities
     165                for (std::set<btRigidBody*>::const_iterator it = this->physicsQueue_.begin();
     166                    it != this->physicsQueue_.end(); ++it)
     167                {
     168                    if (!(*it)->isInWorld())
     169                        this->physicalWorld_->addRigidBody(*it);
     170                }
     171                this->physicsQueue_.clear();
     172            }
     173
     174            // TODO: This is not stable! If physics cannot be calculated real time anymore,
     175            //       framerate will drop exponentially.
    177176            physicalWorld_->stepSimulation(dt,(int)(dt/0.0166666f + 1.0f));
     177        }
    178178    }
    179179
     
    224224        return 0;
    225225    }
     226
     227    void Scene::addRigidBody(btRigidBody* body)
     228    {
     229        if (!this->physicalWorld_)
     230            COUT(1) << "Error: Cannot WorldEntity body to physical Scene: No physics." << std::endl;
     231        else if (body)
     232            this->physicsQueue_.insert(body);
     233    }
     234
     235    void Scene::removeRigidBody(btRigidBody* body)
     236    {
     237        if (!this->physicalWorld_)
     238            COUT(1) << "Error: Cannot WorldEntity body to physical Scene: No physics." << std::endl;
     239        else if (body)
     240        {
     241            this->physicalWorld_->removeRigidBody(body);
     242            // Also check queue
     243            std::set<btRigidBody*>::iterator it = this->physicsQueue_.find(body);
     244            if (it != this->physicsQueue_.end())
     245                this->physicsQueue_.erase(it);
     246        }
     247    }
    226248}
  • code/branches/physics/src/orxonox/objects/Scene.h

    r2303 r2313  
    6868                { return this->bShadows_; }
    6969
    70             //inline const Vector3& getWorldAabbMax()
    71             //{
    72             //    this->physicalWorld_->getBroadphase();
    73             //}
    74 
    7570            inline bool hasPhysics()
    7671                { return this->physicalWorld_ != 0; }
    7772            void setPhysicalWorld(bool wantsPhysics, const Vector3& worldAabbMin, const Vector3& worldAabbMax);
     73
     74            void addRigidBody(btRigidBody* body);
     75            void removeRigidBody(btRigidBody* body);
    7876
    7977            void tick(float dt);
     
    9290
    9391            btDiscreteDynamicsWorld* physicalWorld_;
     92            std::set<btRigidBody*>   physicsQueue_;
    9493
    9594            std::string            skybox_;
  • code/branches/physics/src/orxonox/objects/worldentities/WorldEntity.cc

    r2306 r2313  
    8989                this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
    9090
    91             this->setCollisionType(None);
     91            if (this->physicalBody_)
     92            {
     93                if (this->physicalBody_->isInWorld())
     94                    this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
     95                delete this->physicalBody_;
     96            }
     97            // TODO: Delete collisionShapes
    9298        }
    9399    }
     
    147153            else if (object->isKinematic())
    148154                ThrowException(NotImplemented, "Cannot attach a kinematic object to a static or kinematic one: Not yet implemented.");
    149             else if (object->physicalBody_->isInWorld() || this->physicalBody_->isInWorld())
    150                 ThrowException(PhysicsViolation, "Cannot attach a physical object at runtime.");
    151155            else
    152156            {
     157                if (this->physicalBody_->isInWorld())
     158                    removeFromPhysicalWorld();
     159                if (object->physicalBody_->isInWorld())
     160                    this->getScene()->removeRigidBody(object->physicalBody_);
     161
    153162                // static to static/kinematic/dynamic --> merge shapes
    154163                this->childMass_ += object->getMass();
     
    157166                // That also implies that cannot add a physics WE to the child afterwards.
    158167                object->setCollisionType(None);
     168
     169                addToPhysicalWorld();
    159170            }
    160171        }
     
    209220            // recalculate inertia tensor
    210221            if (this->isDynamic())
    211             {
    212222                internalSetMassProps();
    213             }
    214223        }
    215224        else
     
    228237        {
    229238            if (this->physicalBody_->isInWorld())
    230                 COUT(2) << "Warning: Cannot attach a physical object at runtime.";
    231             else
    232                 this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
    233         }
     239            {
     240                COUT(2) << "Warning: Attaching collision shapes at run time causes its physical body to be removed and added again.";
     241                removeFromPhysicalWorld();
     242            }
     243            this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
     244        }
     245
     246        addToPhysicalWorld();
    234247    }
    235248
     
    257270    }
    258271
     272    void WorldEntity::addToPhysicalWorld() const
     273    {
     274        if (this->isActive() && this->hasPhysics() && !this->physicalBody_->isInWorld())
     275            this->getScene()->addRigidBody(this->physicalBody_);
     276    }
     277
     278    void WorldEntity::removeFromPhysicalWorld() const
     279    {
     280        if (this->hasPhysics())
     281            this->getScene()->removeRigidBody(this->physicalBody_);
     282    }
     283
    259284    void WorldEntity::setScale3D(const Vector3& scale)
    260285    {
     
    278303        if (!this->hasPhysics())
    279304            COUT(3) << "Warning: Setting the mass of a WorldEntity with no physics has no effect." << std::endl;
    280         else if (this->physicalBody_->isInWorld())
    281             COUT(2) << "Warning: Cannot set the physical mass at run time. Storing new mass." << std::endl;
    282         else
     305        else
     306        {
     307            if (this->physicalBody_->isInWorld())
     308            {
     309                COUT(2) << "Warning: Setting the mass of a WorldEntity at run time causes its physical body to be removed and added again." << std::endl;
     310                removeFromPhysicalWorld();
     311            }
    283312            internalSetMassProps();
     313        }
     314
     315        addToPhysicalWorld();
    284316    }
    285317
     
    340372        {
    341373            // Destroy rigid body
    342             if (this->physicalBody_->isInWorld())
    343                 this->getScene()->getPhysicalWorld()->removeRigidBody(this->physicalBody_);
     374            assert(this->physicalBody_);
     375            removeFromPhysicalWorld();
    344376            delete this->physicalBody_;
    345377            this->physicalBody_ = 0;
     
    370402        // update mass and inertia tensor
    371403        internalSetMassProps(); // type is not None! See case None: in switch
     404
     405        addToPhysicalWorld();
    372406    }
    373407
  • code/branches/physics/src/orxonox/objects/worldentities/WorldEntity.h

    r2306 r2313  
    217217            btVector3 getLocalInertia(btScalar mass) const;
    218218            bool checkPhysics() const;
     219            void addToPhysicalWorld() const;
     220            void removeFromPhysicalWorld() const;
    219221
    220222            CollisionType                collisionType_;
Note: See TracChangeset for help on using the changeset viewer.