Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 15, 2008, 12:53:05 AM (16 years ago)
Author:
rgrieder
Message:

Merged physics_merge back to presentation branch.

Location:
code/branches/presentation
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentation

  • code/branches/presentation/src/orxonox/objects/Scene.cc

    r2371 r2459  
    2222 *   Author:
    2323 *      Fabian 'x3n' Landau
     24 *      Reto Grieder (physics)
    2425 *   Co-authors:
    2526 *      ...
     
    3536#include <OgreLight.h>
    3637
     38#include "BulletCollision/BroadphaseCollision/btAxisSweep3.h"
     39#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h"
     40#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
     41#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
     42
    3743#include "core/CoreIncludes.h"
    3844#include "core/Core.h"
    3945#include "core/XMLPort.h"
     46#include "tools/BulletConversions.h"
     47#include "objects/worldentities/WorldEntity.h"
    4048
    4149namespace orxonox
     
    6977            this->rootSceneNode_ = this->sceneManager_->getRootSceneNode();
    7078        }
     79
     80        // No physics yet, XMLPort will do that.
     81        const int defaultMaxWorldSize = 100000;
     82        this->negativeWorldRange_ = Vector3::UNIT_SCALE * -defaultMaxWorldSize;
     83        this->positiveWorldRange_ = Vector3::UNIT_SCALE *  defaultMaxWorldSize;
     84        this->gravity_ = Vector3::ZERO;
     85        this->physicalWorld_   = 0;
     86        this->solver_          = 0;
     87        this->dispatcher_      = 0;
     88        this->collisionConfig_ = 0;
     89        this->broadphase_      = 0;
    7190
    7291        // test test test
     
    91110            if (Ogre::Root::getSingletonPtr())
    92111            {
    93 //                this->sceneManager_->destroySceneNode(this->rootSceneNode_->getName()); // TODO: remove getName() for newer versions of Ogre
    94112                Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
    95113            }
     
    98116                delete this->sceneManager_;
    99117            }
     118
     119            this->setPhysicalWorld(false);
    100120        }
    101121    }
     
    109129        XMLPortParam(Scene, "shadow", setShadow, getShadow, xmlelement, mode).defaultValues(true);
    110130
     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);
     134
    111135        XMLPortObjectExtended(Scene, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
    112136    }
     
    114138    void Scene::registerVariables()
    115139    {
    116         registerVariable(this->skybox_,     variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
    117         registerVariable(this->ambientLight_, variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
     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)
     194    {
     195        this->bHasPhysics_ = wantPhysics;
     196        if (wantPhysics && !hasPhysics())
     197        {
     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;
     230        }
     231    }
     232
     233    void Scene::tick(float dt)
     234    {
     235        if (!Core::showsGraphics())
     236        {
     237            // We need to update the scene nodes if we don't render
     238            this->rootSceneNode_->_update(true, false);
     239        }
     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)
     245            {
     246                // Add all scheduled WorldEntities
     247                for (std::set<WorldEntity*>::const_iterator it = this->physicalObjectQueue_.begin();
     248                    it != this->physicalObjectQueue_.end(); ++it)
     249                {
     250                    this->physicalWorld_->addRigidBody((*it)->getPhysicalBody());
     251                }
     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);
     258        }
    118259    }
    119260
     
    165306    }
    166307
    167     void Scene::tick(float dt)
    168     {
    169         if (!Core::showsGraphics())
    170         {
    171             // We need to update the scene nodes if we don't render
    172             this->rootSceneNode_->_update(true, false);
    173         }
     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());
    174337    }
    175338}
Note: See TracChangeset for help on using the changeset viewer.