Show DopeEscena.cpp syntax highlighted
#include "DopeEscena.h"
#include "DopeJP.h"
#include "DopePlano.h"
#include "DopeJointSubtypes.h"
#include "DopeCamara.h"
//-------------------------------------------------------------------------
template<> Dope::Escena* Ogre::Singleton<Dope::Escena>::ms_Singleton = 0;
Dope::Escena* Dope::Escena::getSingletonPtr(void)
{
return ms_Singleton;
}
Dope::Escena& Dope::Escena::getSingleton(void)
{
assert( ms_Singleton ); return ( *ms_Singleton );
}
//-------------------------------------------------------------------------
namespace Dope
{
//-------------------------------------------------------------------------
Escena::Escena(SceneManager* sceneMgr, WorldType worldType)
: mSceneMgr(sceneMgr), mWorldType(worldType)
{
mSimulationStepSize = 0.01f;
// Create the dynamics world
mOdeWorld = new dWorld();
mOdeContactGroup = new dJointGroup();
mIntersectionQuery = mSceneMgr->createIntersectionQuery();
switch (worldType)
{
case Escena::WT_REFAPP_GENERIC:
mIntersectionQuery->setWorldFragmentType(SceneQuery::WFT_NONE);
break;
case Escena::WT_REFAPP_BSP:
mIntersectionQuery->setWorldFragmentType(SceneQuery::WFT_PLANE_BOUNDED_REGION);
break;
};
}
//-------------------------------------------------------------------------
Escena::~Escena()
{
clear();
delete mIntersectionQuery;
// Destroy dynamix world
delete mOdeContactGroup;
delete mOdeWorld;
}
//-------------------------------------------------------------------------
SceneManager* Escena::getSceneManager(void)
{
return mSceneMgr;
}
//-------------------------------------------------------------------------
JP* Escena::createJP(const String& name,
const Vector3& pos, const Quaternion& orientation)
{
JP* head = new JP(name);
head->setPosition(pos);
head->setOrientation(orientation);
mObjects[name] = head;
return head;
}
//-------------------------------------------------------------------------
Plano* Escena::createPlano(const String& name, Real width, Real height, const Vector3& pos,
const Quaternion& orientation)
{
Plano* plane = new Plano(name, width, height);
plane->setPosition(pos);
plane->setOrientation(orientation);
mObjects[name] = plane;
return plane;
}
//-------------------------------------------------------------------------
void Escena::clear(void)
{
ObjectMap::iterator i;
for (i = mObjects.begin(); i != mObjects.end(); ++i)
{
delete i->second;
}
mObjects.clear();
JointMap::iterator ji;
for (ji = mJoints.begin(); ji != mJoints.end(); ++ji)
{
delete ji->second;
}
mJoints.clear();
}
//-------------------------------------------------------------------------
dWorld* Escena::getOdeWorld(void)
{
return mOdeWorld;
}
//-------------------------------------------------------------------------
void Escena::_applyDynamics(Real timeElapsed)
{
if (timeElapsed != 0.0f)
{
// ODE will throw an error if timestep = 0
mOdeWorld->step(dReal(timeElapsed));
// Now update the objects in the world
ObjectSet::iterator i, iend;
iend = mDynamicsObjects.end();
for (i = mDynamicsObjects.begin(); i != iend; ++i)
{
(*i)->_updateFromDynamics();
}
// Clear contacts
mOdeContactGroup->empty();
}
}
//-------------------------------------------------------------------------
void Escena::_notifyDynamicsStateForObject(Entidad* obj, bool dynamicsEnabled)
{
// NB std::set prevents duplicates & errors on erasing non-existent objects
if (dynamicsEnabled)
{
mDynamicsObjects.insert(obj);
}
else
{
mDynamicsObjects.erase(obj);
}
}
//-------------------------------------------------------------------------
void Escena::setGravity(const Vector3& vec)
{
mGravity = vec;
mOdeWorld->setGravity(vec.x, vec.y, vec.z);
}
//-------------------------------------------------------------------------
const Vector3& Escena::getGravity(void)
{
return mGravity;
}
//-------------------------------------------------------------------------
dJointGroup* Escena::getOdeContactJointGroup(void)
{
return mOdeContactGroup;
}
//-------------------------------------------------------------------------
void Escena::_applyCollision(void)
{
// Collision detection
IntersectionSceneQueryResult& results = mIntersectionQuery->execute();
// Movables to Movables
SceneQueryMovableIntersectionList::iterator it, itend;
itend = results.movables2movables.end();
for (it = results.movables2movables.begin(); it != itend; ++it)
{
/* debugging
MovableObject *mo1, *mo2;
mo1 = it->first;
mo2 = it->second;
*/
// Get user defined objects (generic in OGRE)
UserDefinedObject *uo1, *uo2;
uo1 = it->first->getUserObject();
uo2 = it->second->getUserObject();
// Only perform collision if we have UserDefinedObject links
if (uo1 && uo2)
{
// Cast to ApplicationObject
Entidad *ao1, *ao2;
ao1 = static_cast<Entidad*>(uo1);
ao2 = static_cast<Entidad*>(uo2);
// Do detailed collision test
ao1->testCollide(ao2);
}
}
// Movables to World
SceneQueryMovableWorldFragmentIntersectionList::iterator wit, witend;
witend = results.movables2world.end();
for (wit = results.movables2world.begin(); wit != witend; ++wit)
{
MovableObject *mo = wit->first;
SceneQuery::WorldFragment *wf = wit->second;
// Get user defined objects (generic in OGRE)
UserDefinedObject *uo = mo->getUserObject();
// Only perform collision if we have UserDefinedObject link
if (uo)
{
// Cast to ApplicationObject
Entidad *ao = static_cast<Entidad*>(uo);
// Do detailed collision test
ao->testCollide(wf);
}
}
}
//-------------------------------------------------------------------------
Joint* Escena::createJoint(const String& name, Joint::JointType jtype,
Entidad* obj1, Entidad* obj2)
{
Joint* ret;
switch (jtype)
{
case Joint::JT_BALL:
ret = new BallJoint(jtype, obj1, obj2);
break;
case Joint::JT_HINGE:
ret = new HingeJoint(jtype, obj1, obj2);
break;
case Joint::JT_HINGE2:
ret = new Hinge2Joint(jtype, obj1, obj2);
break;
case Joint::JT_SLIDER:
ret = new SliderJoint(jtype, obj1, obj2);
break;
case Joint::JT_UNIVERSAL:
ret = new UniversalJoint(jtype, obj1, obj2);
break;
}
mJoints[name] = ret;
return ret;
}
//-------------------------------------------------------------------------
void Escena::setSimulationStepSize(Real step)
{
mSimulationStepSize = step;
}
//-------------------------------------------------------------------------
Real Escena::getSimulationStepSize(void)
{
return mSimulationStepSize;
}
//-------------------------------------------------------------------------
void Escena::simulationStep(Real timeElapsed)
{
/* Hmm, gives somewhat jerky results*/
static Real leftOverTime = 0.0f;
Real time = timeElapsed + leftOverTime;
unsigned int steps = (unsigned int)(time / mSimulationStepSize);
for(unsigned int i=0; i < steps; ++i)
{
_applyCollision();
_applyDynamics(mSimulationStepSize);
}
leftOverTime = time - (steps * mSimulationStepSize);
/*
_applyCollision();
_applyDynamics(timeElapsed);
*/
}
//-------------------------------------------------------------------------
Camara* Escena::createCamara(const String& name, const Vector3& pos,
const Quaternion& orientation )
{
Camara* cam = new Camara(name);
cam->setPosition(pos);
cam->setOrientation(orientation);
mObjects[name] = cam;
return cam;
}
}
See more files for this project here