Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1933 was 1933, checked in by martisty, 16 years ago

Collision detection

  • 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
43namespace orxonox
44{
45    CreateFactory(PhysicsTest);
46
47    PhysicsTest::PhysicsTest()
48        : odeWorld_(0)
49        , odeSpace_(0)
50        , odeStepper_(0)
51        , odeGround_(0)   
52        , odeBody_(0)
53        , odeGeom_(0)
54        , sceneNode_(0)
55        , entity_(0)
56        , bRunning_(false)
57    {
58        RegisterObject(PhysicsTest);
59        setConfigValues();
60        ModifyConfigValue(bRunning_, tset, false);
61    }
62
63    PhysicsTest::~PhysicsTest()
64    {
65    }
66
67    void PhysicsTest::setConfigValues()
68    {
69        SetConfigValue(bRunning_, false);
70    }
71
72    /**
73    @brief
74        XML loading and saving.
75    @param
76        xmlelement The XML-element
77    @param
78        loading Loading (true) or saving (false)
79    @return
80        The XML-element
81    */
82    void PhysicsTest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
83    {
84        SUPER(PhysicsTest, XMLPort, xmlelement, mode);
85
86        Ogre::SceneManager* sceneMgr = GraphicsEngine::getInstance().getLevelSceneManager();
87
88        // set up OgreOde
89
90        odeWorld_ = new OgreOde::World(sceneMgr);
91        odeWorld_->setGravity(Vector3(0,-9.80665,0));
92        odeWorld_->setCFM(10e-5);
93        odeWorld_->setERP(0.8);
94        odeWorld_->setAutoSleep(true);
95        odeWorld_->setAutoSleepAverageSamplesCount(10);
96        odeWorld_->setContactCorrectionVelocity(1.0);
97        odeSpace_ = odeWorld_->getDefaultSpace();
98
99
100        // set up stepper
101
102        const Ogre::Real _time_step = 0.5;http://isg.ee.ethz.ch/
103        const Ogre::Real time_scale = Ogre::Real(1.7);
104        const Ogre::Real max_frame_time = Ogre::Real(1.0 / 4);
105        odeStepper_ = new OgreOde::StepHandler(odeWorld_, OgreOde::StepHandler::QuickStep,_time_step,
106            max_frame_time, time_scale);
107
108
109        // Create a hanging crate
110
111        odeGround_ = new OgreOde::InfinitePlaneGeometry(Ogre::Plane(Ogre::Vector3(0,1,0),0),
112            odeWorld_, odeWorld_->getDefaultSpace());
113
114        CollidingObject* collidingObject = new CollidingObject();
115       
116        odeGround_->setUserObject(static_cast<CollisionTestedObject*>(collidingObject));
117
118        // Use a load of meshes to represent the floor
119        int i = 0;
120        Ogre::StaticGeometry* floor;
121        floor = sceneMgr->createStaticGeometry("StaticFloor");
122        floor->setRegionDimensions(Ogre::Vector3(160.0, 100.0, 160.0));
123        // Set the region origin so the center is at 0 world
124        floor->setOrigin(Ogre::Vector3::ZERO);
125        for (Real z = -80.0; z <= 80.0; z += 20.0)
126        {
127            for (Real x = -80.0; x <= 80.0; x += 20.0)
128            {
129                std::string name = std::string("Ground") + convertToString(i++);
130                Ogre::Entity* entity = sceneMgr->createEntity(name, "plane.mesh");
131                entity->setQueryFlags (1<<4);
132                entity->setUserObject(odeGround_);
133                entity->setCastShadows(false);
134                floor->addEntity(entity, Ogre::Vector3(x,0,z));
135            }
136        }       
137
138        floor->build();
139
140
141        // create a plane in x-z dimensions.
142
143        entity_ = sceneMgr->createEntity("crate","crate.mesh");
144        entity_->setQueryFlags (1<<2);
145        sceneNode_ = sceneMgr->getRootSceneNode()->createChildSceneNode("crate");
146        sceneNode_->attachObject(entity_);
147        entity_->setNormaliseNormals(true);
148        entity_->setCastShadows(true);
149
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 Return = true;
205               
206        if (g1->getUserObject())
207                if (!static_cast<CollisionTestedObject*>(g1->getUserObject())->Collide(true, Contact))
208                        Return = false;
209       
210        if (g2->getUserObject())
211                if (!static_cast<CollisionTestedObject*>(g2->getUserObject())->Collide(false, Contact))
212                        Return = false;
213       
214        return Return;
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.