Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 14, 2008, 7:08:36 PM (16 years ago)
Author:
rgrieder
Message:
  • orxonox::Scene should work properly with XMLPort and network synchronisation, no matter what input. No guarantee of course ;)
  • If you disable physics completely and then reactivate it, all rigid bodies that were removed will be added again.
  • new XML attributes: gravity, negativeWorldRange and positiveWorldRange
Location:
code/branches/physics_merge/src/orxonox/objects
Files:
3 edited

Legend:

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

    r2442 r2446  
    2222 *   Author:
    2323 *      Fabian 'x3n' Landau
     24 *      Reto Grieder (physics)
    2425 *   Co-authors:
    25  *      Reto Grieder (physics)
     26 *      ...
    2627 *
    2728 */
     
    7778        }
    7879
    79         // No physics for default
    80         this->physicalWorld_ = 0;
     80        // No physics yet, XMLPort will do that.
     81        const int defaultMaxWorldSize = 100000;
     82        this->negativeWorldRange_ = Vector3(-defaultMaxWorldSize, -defaultMaxWorldSize, -defaultMaxWorldSize);
     83        this->positiveWorldRange_ = Vector3( defaultMaxWorldSize,  defaultMaxWorldSize,  defaultMaxWorldSize);
     84        this->gravity_ = Vector3(0, 0, 0);
     85        this->physicalWorld_   = 0;
     86        this->solver_          = 0;
     87        this->dispatcher_      = 0;
     88        this->collisionConfig_ = 0;
     89        this->broadphase_      = 0;
    8190
    8291        // test test test
     
    107116                delete this->sceneManager_;
    108117            }
     118
     119            this->setPhysicalWorld(false);
    109120        }
    110121    }
     
    118129        XMLPortParam(Scene, "shadow", setShadow, getShadow, xmlelement, mode).defaultValues(true);
    119130
    120         //const int defaultMaxWorldSize = 100000;
    121         //Vector3 worldAabbMin(-defaultMaxWorldSize, -defaultMaxWorldSize, -defaultMaxWorldSize);
    122         //Vector3 worldAabbMax( defaultMaxWorldSize,  defaultMaxWorldSize,  defaultMaxWorldSize);
    123         //XMLPortParamVariable(Scene, "negativeWorldRange", worldAabbMin, xmlelement, mode);
    124         //XMLPortParamVariable(Scene, "positiveWorldRange", worldAabbMax, xmlelement, mode);
    125         XMLPortParam(Scene, "hasPhysics", setPhysicalWorld, hasPhysics, xmlelement, mode).defaultValue(0, true);//.defaultValue(1, worldAabbMin).defaultValue(2, worldAabbMax);
     131        XMLPortParam(Scene, "negativeWorldRange", setNegativeWorldRange, getNegativeWorldRange, xmlelement, mode);
     132        XMLPortParam(Scene, "positiveWorldRange", setPositiveWorldRange, getPositiveWorldRange, xmlelement, mode);
     133        XMLPortParam(Scene, "hasPhysics", setPhysicalWorld, hasPhysics, xmlelement, mode).defaultValues(true);
    126134
    127135        XMLPortObjectExtended(Scene, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
     
    130138    void Scene::registerVariables()
    131139    {
    132         registerVariable(this->skybox_,       variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
    133         registerVariable(this->ambientLight_, variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
    134         registerVariable(this->bHasPhysics_,  variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_hasPhysics));
    135     }
    136 
    137     void Scene::setPhysicalWorld(bool wantPhysics)//, const Vector3& worldAabbMin, const Vector3& worldAabbMax)
     140        registerVariable(this->skybox_,             variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
     141        registerVariable(this->ambientLight_,       variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
     142        registerVariable(this->negativeWorldRange_, variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_negativeWorldRange));
     143        registerVariable(this->positiveWorldRange_, variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_positiveWorldRange));
     144        registerVariable(this->gravity_,            variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_gravity));
     145        registerVariable(this->bHasPhysics_,        variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_hasPhysics));
     146    }
     147
     148    void Scene::setNegativeWorldRange(const Vector3& range)
     149    {
     150        if (range.length() < 10.0f)
     151        {
     152            CCOUT(2) << "Warning: Setting the negative world range to a very small value: "
     153                     << omni_cast<std::string>(range) << std::endl;
     154        }
     155        if (this->hasPhysics())
     156        {
     157            CCOUT(2) << "Warning: Attempting to set the physical world range at run time. "
     158                     << "This causes a complete physical reload which might take some time." << std::endl;
     159            this->setPhysicalWorld(false);
     160            this->negativeWorldRange_ = range;
     161            this->setPhysicalWorld(true);
     162        }
     163        else
     164            this->negativeWorldRange_ = range;
     165    }
     166
     167    void Scene::setPositiveWorldRange(const Vector3& range)
     168    {
     169        if (range.length() < 10.0f)
     170        {
     171            CCOUT(2) << "Warning: Setting the positive world range to a very small value: "
     172                     << omni_cast<std::string>(range) << std::endl;
     173        }
     174        if (this->hasPhysics())
     175        {
     176            CCOUT(2) << "Warning: Attempting to set the physical world range at run time. "
     177                     << "This causes a complete physical reload which might take some time." << std::endl;
     178            this->setPhysicalWorld(false);
     179            this->positiveWorldRange_ = range;
     180            this->setPhysicalWorld(true);
     181        }
     182        else
     183            this->positiveWorldRange_ = range;
     184    }
     185
     186    void Scene::setGravity(const Vector3& gravity)
     187    {
     188        this->gravity_ = gravity;
     189        if (this->hasPhysics())
     190            this->physicalWorld_->setGravity(omni_cast<btVector3>(this->gravity_));
     191    }
     192
     193    void Scene::setPhysicalWorld(bool wantPhysics)
    138194    {
    139195        this->bHasPhysics_ = wantPhysics;
    140196        if (wantPhysics && !hasPhysics())
    141197        {
    142             //float x = worldAabbMin.x;
    143             //float y = worldAabbMin.y;
    144             //float z = worldAabbMin.z;
    145             btVector3 worldAabbMin(-100000, -100000, -100000);
    146             //x = worldAabbMax.x;
    147             //y = worldAabbMax.y;
    148             //z = worldAabbMax.z;
    149             btVector3 worldAabbMax(100000, 100000, 100000);
    150 
    151             btDefaultCollisionConfiguration*     collisionConfig = new btDefaultCollisionConfiguration();
    152             btCollisionDispatcher*               dispatcher      = new btCollisionDispatcher(collisionConfig);
    153             bt32BitAxisSweep3*                   broadphase      = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax);
    154             btSequentialImpulseConstraintSolver* solver          = new btSequentialImpulseConstraintSolver;
    155 
    156             this->physicalWorld_ =  new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);
    157 
    158             // Disable Gravity for space
    159             this->physicalWorld_->setGravity(btVector3(0,0,0));
    160         }
    161         else
    162         {
    163             // TODO: Destroy Bullet physics
     198            // Note: These are all little known default classes and values.
     199            //       It would require further investigation to properly dertermine the right choices.
     200            this->broadphase_      = new bt32BitAxisSweep3(
     201                omni_cast<btVector3>(this->negativeWorldRange_), omni_cast<btVector3>(this->positiveWorldRange_));
     202            this->collisionConfig_ = new btDefaultCollisionConfiguration();
     203            this->dispatcher_      = new btCollisionDispatcher(this->collisionConfig_);
     204            this->solver_          = new btSequentialImpulseConstraintSolver;
     205
     206            this->physicalWorld_   = new btDiscreteDynamicsWorld(this->dispatcher_, this->broadphase_, this->solver_, this->collisionConfig_);
     207            this->physicalWorld_->setGravity(omni_cast<btVector3>(this->gravity_));
     208        }
     209        else if (!wantPhysics && hasPhysics())
     210        {
     211            // Remove all WorldEntities and shove them to the queue since they would still like to be in a physical world.
     212            for (std::set<WorldEntity*>::const_iterator it = this->physicalObjects_.begin();
     213                it != this->physicalObjects_.end(); ++it)
     214            {
     215                this->physicalWorld_->removeRigidBody((*it)->getPhysicalBody());
     216                this->physicalObjectQueue_.insert(*it);
     217            }
     218            this->physicalObjects_.clear();
     219
     220            delete this->physicalWorld_;
     221            delete this->solver_;
     222            delete this->dispatcher_;
     223            delete this->collisionConfig_;
     224            delete this->broadphase_;
     225            this->physicalWorld_   = 0;
     226            this->solver_          = 0;
     227            this->dispatcher_      = 0;
     228            this->collisionConfig_ = 0;
     229            this->broadphase_      = 0;
    164230        }
    165231    }
     
    172238            this->rootSceneNode_->_update(true, false);
    173239        }
    174         if (physicalWorld_)
    175         {
    176             if (this->physicsQueue_.size() > 0)
     240        if (this->hasPhysics())
     241        {
     242            // TODO: This here is bad practice! It will slow down the first tick() by ages.
     243            //       Rather have an initialise() method as well, called by the Level after everything has been loaded.
     244            if (this->physicalObjectQueue_.size() > 0)
    177245            {
    178246                // Add all scheduled WorldEntities
    179                 for (std::set<btRigidBody*>::const_iterator it = this->physicsQueue_.begin();
    180                     it != this->physicsQueue_.end(); ++it)
     247                for (std::set<WorldEntity*>::const_iterator it = this->physicalObjectQueue_.begin();
     248                    it != this->physicalObjectQueue_.end(); ++it)
    181249                {
    182                     if (!(*it)->isInWorld())
    183                     {
    184                         //COUT(0) << "body position: " << omni_cast<Vector3>((*it)->getWorldTransform().getOrigin()) << std::endl;
    185                         //COUT(0) << "body velocity: " << omni_cast<Vector3>((*it)->getLinearVelocity()) << std::endl;
    186                         //COUT(0) << "body orientation: " << omni_cast<Quaternion>((*it)->getWorldTransform().getRotation()) << std::endl;
    187                         //COUT(0) << "body angular: " << omni_cast<Vector3>((*it)->getAngularVelocity()) << std::endl;
    188                         //COUT(0) << "body mass: " << omni_cast<float>((*it)->getInvMass()) << std::endl;
    189                         //COUT(0) << "body inertia: " << omni_cast<Vector3>((*it)->getInvInertiaDiagLocal()) << std::endl;
    190                         this->physicalWorld_->addRigidBody(*it);
    191                     }
     250                    this->physicalWorld_->addRigidBody((*it)->getPhysicalBody());
    192251                }
    193                 this->physicsQueue_.clear();
    194             }
    195 
    196             // TODO: This is not stable! If physics cannot be calculated real time anymore,
    197             //       framerate will drop exponentially.
    198             physicalWorld_->stepSimulation(dt,(int)(dt/0.0166666f + 1.0f));
     252                this->physicalObjectQueue_.clear();
     253            }
     254
     255            // Note: 60 means that Bullet will do physics correctly down to 1 frames per seconds.
     256            //       Under that mark, the simulation will "loose time" and get unusable.
     257            physicalWorld_->stepSimulation(dt, 60);
    199258        }
    200259    }
     
    247306    }
    248307
    249     void Scene::addRigidBody(btRigidBody* body)
    250     {
    251         if (!this->physicalWorld_)
    252             COUT(1) << "Error: Cannot add WorldEntity body to physical Scene: No physics." << std::endl;
    253         else if (body)
    254             this->physicsQueue_.insert(body);
    255     }
    256 
    257     void Scene::removeRigidBody(btRigidBody* body)
    258     {
    259         if (!this->physicalWorld_)
    260             COUT(1) << "Error: Cannot remove WorldEntity body from physical Scene: No physics." << std::endl;
    261         else if (body)
    262         {
    263             this->physicalWorld_->removeRigidBody(body);
    264             // Also check queue
    265             std::set<btRigidBody*>::iterator it = this->physicsQueue_.find(body);
    266             if (it != this->physicsQueue_.end())
    267                 this->physicsQueue_.erase(it);
    268         }
     308    void Scene::addPhysicalObject(WorldEntity* object)
     309    {
     310        if (object)
     311        {
     312            std::set<WorldEntity*>::iterator it = this->physicalObjects_.find(object);
     313            if (it != this->physicalObjects_.end())
     314                return;
     315
     316            this->physicalObjectQueue_.insert(object);
     317        }
     318    }
     319
     320    void Scene::removePhysicalObject(WorldEntity* object)
     321    {
     322        // check queue first
     323        std::set<WorldEntity*>::iterator it = this->physicalObjectQueue_.find(object);
     324        if (it != this->physicalObjectQueue_.end())
     325        {
     326            this->physicalObjectQueue_.erase(it);
     327            return;
     328        }
     329
     330        it = this->physicalObjects_.find(object);
     331        if (it == this->physicalObjects_.end())
     332            return;
     333        this->physicalObjects_.erase(it);
     334
     335        if (this->hasPhysics())
     336            this->physicalWorld_->removeRigidBody(object->getPhysicalBody());
    269337    }
    270338}
  • code/branches/physics_merge/src/orxonox/objects/Scene.h

    r2442 r2446  
    2222 *   Author:
    2323 *      Fabian 'x3n' Landau
     24 *      Reto Grieder (physics)
    2425 *   Co-authors:
    2526 *      ...
     
    5354                { return this->rootSceneNode_; }
    5455
    55             inline btDiscreteDynamicsWorld* getPhysicalWorld() const
    56                 { return this->physicalWorld_; }
    57 
    5856            void setSkybox(const std::string& skybox);
    5957            inline const std::string& getSkybox() const
     
    6866                { return this->bShadows_; }
    6967
    70             inline bool hasPhysics()
    71                 { return this->physicalWorld_ != 0; }
    72             void setPhysicalWorld(bool wantsPhysics);//, const Vector3& worldAabbMin, const Vector3& worldAabbMax);
    73 
    74             void addRigidBody(btRigidBody* body);
    75             void removeRigidBody(btRigidBody* body);
    76 
    7768            virtual void tick(float dt);
    7869
     
    8576            void networkcallback_applyAmbientLight()
    8677                { this->setAmbientLight(this->ambientLight_); }
    87             void networkcallback_hasPhysics()
    88                 { this->setPhysicalWorld(this->bHasPhysics_); }
    8978
    9079            Ogre::SceneManager*      sceneManager_;
    9180            Ogre::SceneNode*         rootSceneNode_;
    92 
    93             btDiscreteDynamicsWorld* physicalWorld_;
    94             std::set<btRigidBody*>   physicsQueue_;
    95             bool                     bHasPhysics_;
    9681
    9782            std::string              skybox_;
     
    9984            std::list<BaseObject*>   objects_;
    10085            bool                     bShadows_;
     86
     87
     88        /////////////
     89        // Physics //
     90        /////////////
     91
     92        public:
     93            inline bool hasPhysics()
     94                { return this->physicalWorld_ != 0; }
     95            void setPhysicalWorld(bool wantsPhysics);
     96
     97            void setNegativeWorldRange(const Vector3& range);
     98            inline const Vector3& getNegativeWorldRange() const
     99                { return this->negativeWorldRange_; }
     100
     101            void setPositiveWorldRange(const Vector3& range);
     102            inline const Vector3& getPositiveWorldRange() const
     103                { return this->positiveWorldRange_; }
     104
     105            void setGravity(const Vector3& gravity);
     106            inline const Vector3& getGravity() const
     107                { return this->gravity_; }
     108
     109            void addPhysicalObject(WorldEntity* object);
     110            void removePhysicalObject(WorldEntity* object);
     111
     112        private:
     113            inline void networkcallback_hasPhysics()
     114                { this->setPhysicalWorld(this->bHasPhysics_); }
     115            inline void networkcallback_negativeWorldRange()
     116                { this->setNegativeWorldRange(this->negativeWorldRange_); }
     117            inline void networkcallback_positiveWorldRange()
     118                { this->setPositiveWorldRange(this->positiveWorldRange_); }
     119            inline void networkcallback_gravity()
     120                { this->setGravity(this->gravity_); }
     121
     122            // Bullet objects
     123            btDiscreteDynamicsWorld*             physicalWorld_;
     124            bt32BitAxisSweep3*                   broadphase_;
     125            btDefaultCollisionConfiguration*     collisionConfig_;
     126            btCollisionDispatcher*               dispatcher_;
     127            btSequentialImpulseConstraintSolver* solver_;
     128
     129            std::set<WorldEntity*>               physicalObjectQueue_;
     130            std::set<WorldEntity*>               physicalObjects_;
     131            bool                                 bHasPhysics_;
     132            Vector3                              negativeWorldRange_;
     133            Vector3                              positiveWorldRange_;
     134            Vector3                              gravity_;
    101135    };
    102136}
  • code/branches/physics_merge/src/orxonox/objects/worldentities/WorldEntity.cc

    r2442 r2446  
    312312        if (this->isActive() && this->hasPhysics() && !this->isPhysicsActive() && !this->parent_)
    313313        {
    314             this->getScene()->addRigidBody(this->physicalBody_);
     314            this->getScene()->addPhysicalObject(this);
    315315            this->bPhysicsActive_ = true;
    316316        }
     
    321321        if (this->isPhysicsActive())
    322322        {
    323             this->getScene()->removeRigidBody(this->physicalBody_);
     323            this->getScene()->removePhysicalObject(this);
    324324            this->bPhysicsActive_ = false;
    325325        }
Note: See TracChangeset for help on using the changeset viewer.