Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/orxonox/objects/PhysicsTest.cc @ 2170

Last change on this file since 2170 was 2124, checked in by rgrieder, 16 years ago

Physics: HelloBullet.cc should compile and run again. Testing tardis now.

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "PhysicsTest.h"
31
32#include <OgreStaticGeometry.h>
33#include <OgreSceneManager.h>
34#include <OgreEntity.h>
35#include "ogreode/OgreOde_Core.h"
36#include "ogreode/OgreOdeGeometry.h"
37#include "util/Convert.h"
38#include "core/CoreIncludes.h"
39#include "core/ConfigValueIncludes.h"
40#include "core/XMLPort.h"
41#include "GraphicsEngine.h"
42#include "Scene.h"
43
44namespace orxonox
45{
46    CreateFactory(PhysicsTest);
47
48    PhysicsTest::PhysicsTest(BaseObject* creator)
49        : BaseObject(creator)
50        , odeWorld_(0)
51        , odeSpace_(0)
52        , odeStepper_(0)
53        , odeGround_(0)   
54        , odeBody_(0)
55        , odeGeom_(0)
56        , sceneNode_(0)
57        , entity_(0)
58        , bRunning_(false)
59    {
60        RegisterObject(PhysicsTest);
61        setConfigValues();
62        ModifyConfigValue(bRunning_, tset, false);
63    }
64
65    PhysicsTest::~PhysicsTest()
66    {
67    }
68
69    void PhysicsTest::setConfigValues()
70    {
71        SetConfigValue(bRunning_, false);
72    }
73
74    /**
75    @brief
76        XML loading and saving.
77    @param
78        xmlelement The XML-element
79    @param
80        loading Loading (true) or saving (false)
81    @return
82        The XML-element
83    */
84    void PhysicsTest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
85    {
86        SUPER(PhysicsTest, XMLPort, xmlelement, mode);
87
88        Ogre::SceneManager* sceneMgr = this->getScene()->getSceneManager();
89
90        // set up OgreOde
91
92        odeWorld_ = new OgreOde::World(sceneMgr);
93        odeWorld_->setGravity(Vector3(0,-9.80665,0));
94        odeWorld_->setCFM(10e-5);
95        odeWorld_->setERP(0.8);
96        odeWorld_->setAutoSleep(true);
97        odeWorld_->setAutoSleepAverageSamplesCount(10);
98        odeWorld_->setContactCorrectionVelocity(1.0);
99        odeSpace_ = odeWorld_->getDefaultSpace();
100
101
102        // set up stepper
103
104        const Ogre::Real _time_step = 0.5;http://isg.ee.ethz.ch/
105        const Ogre::Real time_scale = Ogre::Real(1.7);
106        const Ogre::Real max_frame_time = Ogre::Real(1.0 / 4);
107        odeStepper_ = new OgreOde::StepHandler(odeWorld_, OgreOde::StepHandler::QuickStep, _time_step,
108            max_frame_time, time_scale);
109
110
111        // create a plane in x-z dimensions.
112
113        odeGround_ = new OgreOde::InfinitePlaneGeometry(Ogre::Plane(Ogre::Vector3(0,1,0),0),
114            odeWorld_, odeWorld_->getDefaultSpace());
115
116        CollidingObject* collidingObject = new CollidingObject();
117        odeGround_->setUserObject(static_cast<CollisionTestedObject*>(collidingObject));
118
119        // Use a load of meshes to represent the floor
120        int i = 0;
121        Ogre::StaticGeometry* floor;
122        floor = sceneMgr->createStaticGeometry("StaticFloor");
123        floor->setRegionDimensions(Ogre::Vector3(160.0, 100.0, 160.0));
124        // Set the region origin so the center is at 0 world
125        floor->setOrigin(Ogre::Vector3::ZERO);
126        for (Real z = -80.0; z <= 80.0; z += 20.0)
127        {
128            for (Real x = -80.0; x <= 80.0; x += 20.0)
129            {
130                std::string name = std::string("Ground") + convertToString(i++);
131                Ogre::Entity* entity = sceneMgr->createEntity(name, "plane.mesh");
132                entity->setQueryFlags (1<<4);
133                entity->setUserObject(odeGround_);
134                entity->setCastShadows(false);
135                floor->addEntity(entity, Ogre::Vector3(x,0,z));
136            }
137        }       
138
139        floor->build();
140
141
142        // create a hanging crate
143
144        entity_ = sceneMgr->createEntity("crate","crate.mesh");
145        entity_->setQueryFlags (1<<2);
146        sceneNode_ = sceneMgr->getRootSceneNode()->createChildSceneNode("crate");
147        sceneNode_->attachObject(entity_);
148        entity_->setNormaliseNormals(true);
149        entity_->setCastShadows(true);
150
151        odeBody_ = new OgreOde::Body(odeWorld_);
152        sceneNode_->attachObject(odeBody_);
153
154       
155        // set size and mass of the crate
156
157        Vector3 size(10.0, 10.0, 10.0);
158        odeMass_ = OgreOde::BoxMass(0.5, size);
159        odeMass_.setDensity(5.0, size);
160        odeGeom_ = new OgreOde::BoxGeometry(size, odeWorld_, odeSpace_);
161        sceneNode_->setScale(size.x * 0.1, size.y * 0.1, size.z * 0.1);
162        odeBody_->setMass(odeMass_);
163        odeGeom_->setBody(odeBody_);
164        entity_->setUserObject(odeGeom_);
165        odeGeom_->setUserObject(static_cast<CollisionTestedObject*>(this));
166
167
168        odeBody_->setOrientation(Quaternion(Degree(30.0), Vector3(0,0,0)));
169        odeBody_->setPosition(Vector3(0,120,-20));
170
171    }
172
173    void PhysicsTest::tick(float dt)
174    {
175        // only update physics in a certain interval
176        if (this->bRunning_ && odeStepper_->step(dt))
177            odeWorld_->synchronise();
178    }
179
180    bool PhysicsTest::collision(OgreOde::Contact* contact)
181    {
182        // Check for collisions between things that are connected and ignore them
183        OgreOde::Geometry * const g1 = contact->getFirstGeometry();
184        OgreOde::Geometry * const g2 = contact->getSecondGeometry();
185
186        if (g1 && g2)
187        {
188            const OgreOde::Body * const b1 = g2->getBody();
189            const OgreOde::Body * const b2 = g1->getBody();
190            if (b1 && b2 && OgreOde::Joint::areConnected(b1, b2)) 
191                return false; 
192        }
193
194        //set contact parameters:
195        contact->setBouncyness(1.0);
196        contact->setCoulombFriction(OgreOde::Utility::Infinity);
197        contact->setForceDependentSlip(1.0);
198        contact->setAdditionalFDS(1.0);
199
200        // we have 2 collidable objects from our object system, if one of the Collide function returns false, e return false in this method, too, else we return true, so ode computes a normal collision.
201        // true means ode will treat this like a normal collison => rigid body behavior
202        // false means ode will not treat this collision at all => objects ignore each other
203
204        bool res = true;
205
206        if (g1->getUserObject())
207            if (!static_cast<CollisionTestedObject*>(g1->getUserObject())->collide(true, contact))
208                res = false;
209
210        if (g2->getUserObject())
211            if (!static_cast<CollisionTestedObject*>(g2->getUserObject())->collide(false, contact))
212                res = false;
213
214        return res;
215    }
216
217    bool CollidingObject::Collide(bool MineIsFirst, OgreOde::Contact* contact)
218    {
219        contact->setForceDependentSlip(contact->getForceDependentSlip() * ForceDependentSlip);
220        contact->setAdditionalFDS(contact->getForceDependentSlip2() * ForceDependentSlip);
221        contact->setCoulombFriction(contact->getCoulombFrictionMu() * Friction);
222        contact->setBouncyness(contact->getBouncyness() * Bouncyness, contact->getBouncynessVelocity() * BounceVelocity);
223        return true;
224    }
225
226}
Note: See TracBrowser for help on using the repository browser.