Index: code/branches/physics/src/CMakeLists.txt
===================================================================
--- code/branches/physics/src/CMakeLists.txt	(revision 1918)
+++ code/branches/physics/src/CMakeLists.txt	(revision 1919)
@@ -6,4 +6,5 @@
 ADD_SUBDIRECTORY(ois)
 ADD_SUBDIRECTORY(tinyxml)
+ADD_SUBDIRECTORY(ogreode)
 ADD_SUBDIRECTORY(lua)
 ADD_SUBDIRECTORY(tolua)
Index: code/branches/physics/src/ogreode/CMakeLists.txt
===================================================================
--- code/branches/physics/src/ogreode/CMakeLists.txt	(revision 1919)
+++ code/branches/physics/src/ogreode/CMakeLists.txt	(revision 1919)
@@ -0,0 +1,19 @@
+SET( OGREODE_SRC_FILES
+  OgreOdeBody.cpp
+  OgreOdeCollision.cpp
+  OgreOdeDebugContact.cpp
+  OgreOdeDebugObject.cpp
+  OgreOdeEigenSolver.cpp
+  OgreOdeEntityInformer.cpp
+  OgreOdeGeometry.cpp
+  OgreOdeJoint.cpp
+  OgreOdeMass.cpp
+  OgreOdeSpace.cpp
+  OgreOdeStepper.cpp
+  OgreOdeTriangleMeshData.cpp
+  OgreOdeTriangleMeshDataManager.cpp
+  OgreOdeUtility.cpp
+  OgreOdeWorld.cpp
+)
+
+ADD_LIBRARY(ogreode_orxonox SHARED ${OGREODE_SRC_FILES})
Index: code/branches/physics/src/ogreode/OgreOdeBody.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeBody.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeBody.cpp	(revision 1919)
@@ -0,0 +1,854 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeWorld.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeMass.h"
+#include "OgreOdeDebugObject.h"
+#include "OgreOdeGeometry.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+
+//-----------------------------------------------------------------------
+BodyState::BodyState(const Ogre::Vector3	&position,
+                     const Ogre::Quaternion &orientation)
+{
+    _position = position;
+    _orientation = orientation;	
+}
+//-----------------------------------------------------------------------
+void BodyState::operator=(const BodyState &other)
+{
+    _position = other._position;
+    _orientation = other._orientation;
+}
+//-----------------------------------------------------------------------
+bool BodyState::operator==(const BodyState &other) const
+{
+    return _position == other._position && 
+        _orientation == other._orientation;			
+}
+//-----------------------------------------------------------------------
+bool BodyState::operator!=(const BodyState &other) const
+{
+    return _position != other._position || 
+        _orientation != other._orientation;
+} 
+//-----------------------------------------------------------------------
+/// compare with another physics state for "significant" differences.
+/// used for detecting position or orientation snaps which need smoothing.
+bool BodyState::isDifferent(const BodyState &other, const Ogre::Real threshold) const
+{
+    return (other._position-_position).squaredLength() > threshold || 
+        (other._orientation-_orientation).normalise() > threshold;
+}
+
+//-----------------------------------------------------------------------
+void BodyState::interpolate(const BodyState * const _previous_state, 
+                                   const BodyState * const _current_state, 
+                                   const Ogre::Real alpha)
+{
+    const Ogre::Real timeDiffuseless = Ogre::Real(0.0001);
+    if (alpha - timeDiffuseless < 0) // alpha <= 0
+    {	
+        _position = _current_state->_position;
+        _orientation = _current_state->_orientation;			
+    }
+    else if (alpha - 1 - timeDiffuseless > 0) // alpha >= 1
+    {	
+        _position = _previous_state->_position;
+        _orientation = _previous_state->_orientation;	
+    }
+    else
+#if _DEBUG 
+    if (_previous_state->isDifferent(*_current_state, Ogre::Real(0.01)))
+    {        
+        _position = _current_state->_position*alpha + _previous_state->_position * (1.0f - alpha);
+        _orientation = Ogre::Quaternion::Slerp(alpha, _previous_state->_orientation, _current_state->_orientation, true); //shortest path ?				
+    }
+    else
+    {
+        _position = _previous_state->_position;
+        _orientation = _previous_state->_orientation;
+    }
+#else
+    {
+        _position = _current_state->_position*alpha + _previous_state->_position * (1.0f - alpha);
+        _orientation = Ogre::Quaternion::Slerp(alpha, _previous_state->_orientation, _current_state->_orientation, true); //shortest path ?				
+    }
+#endif
+}
+
+//-----------------------------------------------------------------------
+int Body::_body_count = 0;
+//-----------------------------------------------------------------------
+const Ogre::String Body::MovableType = "OgreOde::Body";
+//-----------------------------------------------------------------------
+Body::Body(World *world, const Ogre::String& name):
+    MovableObject(),
+    //UserDefinedObject(),
+    _name(name), 
+    _world(world),
+	_modify_parent_orientation(true)
+{ 
+	_body_count++;
+	_body = dBodyCreate(_world->getWorldID()); 
+	
+	_debug_node = 0;
+	_mass = new Mass(); 
+
+	dBodySetData(_body,(void*)this);
+	_world->getBodyList().registerItem(this);
+
+	if (_name.empty())
+		_name = MovableType + Ogre::StringConverter::toString(_body_count);
+
+	setDamping (_world->_linear_damping, 
+				_world->_angular_damping);
+	_user_data = 0;
+	
+	_isEnabled = true;
+    _historyResize(_world->getHistorySize());
+    // Tie the physical body to the movable
+    // used when getting physical out of Movables. 
+    this->setUserObject (this);
+
+}
+//-----------------------------------------------------------------------
+void Body::_historyResize(const size_t size)
+{
+	_state_history.resize (size);
+	for (size_t i = 0; i < size; i++)
+	{
+		_state_history.add(new BodyState (_draw_state));
+	}
+}
+//-----------------------------------------------------------------------
+void Body::_notifyAttached(Node* parent,bool isTagPoint)
+{
+    MovableObject::_notifyAttached(parent,isTagPoint);
+    if (parent)
+    {
+        Body* other_body = _world->findBody(static_cast<SceneNode*>(parent));
+        if ((other_body) && (other_body != this))
+        {
+            static_cast<SceneNode*>(parent)->detachObject(other_body);
+
+        }
+
+        setPosition(parent->getPosition());
+        setOrientation(parent->getOrientation());
+    } 
+}
+//-----------------------------------------------------------------------
+void Body::destroyDebugNode()
+{
+	if (_debug_node)
+	{
+		_world->notifyGeometry(this);
+
+        SceneNode* sn = static_cast<SceneNode*>(_debug_node);
+        sn->removeAndDestroyAllChildren ();
+        sn = static_cast<SceneNode*>(_debug_node->getParent());
+        sn->removeAndDestroyChild(_debug_node->getName());
+		_debug_node = 0;
+	}
+}
+
+//-----------------------------------------------------------------------
+void Body::addDebugNode(Node* node)
+{
+	if (!_debug_node)
+	{
+		_debug_node = _world->_manager->getRootSceneNode()->createChild(_name + Ogre::String("_DebugBody"));
+	}
+   
+    _debug_node->addChild(node);
+   
+}
+
+//-----------------------------------------------------------------------
+void Body::setModifyParentOrientation(bool bModify)
+{
+	_modify_parent_orientation = bModify;
+} 
+//-----------------------------------------------------------------------
+void Body::setPosition(const Ogre::Vector3& position)
+{
+	dBodySetPosition(_body,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+
+	_draw_state._position = position;
+	for (size_t i = 0; i < _state_history.size (); i++)
+	{
+		_state_history[i]->_position = position;
+	}
+
+	if (mParentNode) 
+        mParentNode->setPosition(position);
+}
+
+//-----------------------------------------------------------------------
+void Body::setOrientation(const Ogre::Quaternion& orientation)
+{
+	dQuaternion q; 
+	q[0] = (dReal)orientation.w;
+	q[1] = (dReal)orientation.x;
+	q[2] = (dReal)orientation.y;
+	q[3] = (dReal)orientation.z;
+	dBodySetQuaternion(_body,q); 
+
+	_draw_state._orientation = orientation;
+	for (size_t i = 0; i < _state_history.size (); i++)
+	{
+		_state_history[i]->_orientation = orientation;
+	}
+
+	if (mParentNode && _modify_parent_orientation) 
+        mParentNode->setOrientation(orientation);
+}
+
+//-----------------------------------------------------------------------
+void Body::setLinearVelocity(const Ogre::Vector3& linear_velocity)
+{
+	dBodySetLinearVel(_body,(dReal)linear_velocity.x,(dReal)linear_velocity.y,(dReal)linear_velocity.z); 
+}
+
+//-----------------------------------------------------------------------
+void Body::setAngularVelocity(const Ogre::Vector3& angular_velocity)
+{
+	dBodySetAngularVel(_body,(dReal)angular_velocity.x,(dReal)angular_velocity.y,(dReal)angular_velocity.z); 
+}
+
+
+//-----------------------------------------------------------------------
+const Ogre::Vector3& Body::getLinearVelocity()
+{
+	const dReal* linear_velocity = dBodyGetLinearVel(_body); 
+	_linear_vel.x = (Real)linear_velocity[0];
+	_linear_vel.y = (Real)linear_velocity[1];
+	_linear_vel.z = (Real)linear_velocity[2];
+
+	return _linear_vel;
+}
+
+//-----------------------------------------------------------------------
+const Ogre::Vector3& Body::getAngularVelocity()
+{
+	const dReal* angular_velocity = dBodyGetAngularVel(_body); 
+	_angular_vel.x = (Real)angular_velocity[0];
+	_angular_vel.y = (Real)angular_velocity[1];
+	_angular_vel.z = (Real)angular_velocity[2];
+
+	return _angular_vel;
+}
+
+//-----------------------------------------------------------------------
+const Ogre::String& Body::getMovableType() const
+{
+	return MovableType;
+}
+
+//-----------------------------------------------------------------------
+void Body::_notifyCurrentCamera(Camera* camera)
+{
+}
+
+//-----------------------------------------------------------------------
+const AxisAlignedBox& Body::getBoundingBox(void) const
+{
+	return _bounding_box;
+}
+
+//-----------------------------------------------------------------------
+Real Body::getBoundingRadius(void) const
+{
+	return Ogre::Real(0.0);
+}
+//-----------------------------------------------------------------------
+void Body::_updateRenderQueue(RenderQueue* queue)
+{
+}
+//-----------------------------------------------------------------------
+void Body::setMass(const Mass& mass)
+{
+	dBodySetMass(_body,mass.getMassPtr());
+}
+
+//-----------------------------------------------------------------------
+const Mass& Body::getMass()
+{
+	dMass mass;
+	dBodyGetMass(_body,&mass); 
+	*_mass = &mass;
+	return *_mass;
+}
+
+//-----------------------------------------------------------------------
+void Body::addForce(const Ogre::Vector3& force)
+{
+	dBodyAddForce(_body,(dReal)force.x,(dReal)force.y,(dReal)force.z);
+}
+
+//-----------------------------------------------------------------------
+void Body::addTorque(const Ogre::Vector3& torque)
+{
+	dBodyAddTorque(_body,(dReal)torque.x,(dReal)torque.y,(dReal)torque.z);
+}
+
+//-----------------------------------------------------------------------
+void Body::addRelativeForce(const Ogre::Vector3& force)
+{
+	dBodyAddRelForce(_body,(dReal)force.x,(dReal)force.y,(dReal)force.z);
+}
+
+//-----------------------------------------------------------------------
+void Body::addRelativeTorque(const Ogre::Vector3& torque)
+{
+	dBodyAddRelTorque(_body,(dReal)torque.x,(dReal)torque.y,(dReal)torque.z);
+}
+
+//-----------------------------------------------------------------------
+void Body::addForceAt(const Ogre::Vector3& force,const Ogre::Vector3& position)
+{
+	dBodyAddForceAtPos(_body,(dReal)force.x,(dReal)force.y,(dReal)force.z,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+
+//-----------------------------------------------------------------------
+void Body::addForceAtRelative(const Ogre::Vector3& force,const Ogre::Vector3& position)
+{
+	dBodyAddForceAtRelPos(_body,(dReal)force.x,(dReal)force.y,(dReal)force.z,(dReal)position.x,(dReal)position.y,(dReal)position.z);
+}
+//-----------------------------------------------------------------------
+void Body::addRelativeForceAt(const Ogre::Vector3& force,const Ogre::Vector3& position)
+{
+    dBodyAddRelForceAtPos(_body,(dReal)force.x,(dReal)force.y,(dReal)force.z,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+//-----------------------------------------------------------------------
+void Body::addRelativeForceAtRelative(const Ogre::Vector3& force,const Ogre::Vector3& position)
+{
+	dBodyAddRelForceAtRelPos(_body,(dReal)force.x,(dReal)force.y,(dReal)force.z,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+//-----------------------------------------------------------------------
+const Ogre::Vector3& Body::getForce()
+{
+	const dReal* force = dBodyGetForce(_body); 
+	_force.x = force[0];
+	_force.y = force[1];
+	_force.z = force[2];
+
+	return _force;
+}
+//-----------------------------------------------------------------------
+const Ogre::Vector3& Body::getTorque()
+{
+	const dReal* torque = dBodyGetTorque(_body); 
+	_torque.x = torque[0];
+	_torque.y = torque[1];
+	_torque.z = torque[2];
+
+	return _torque;
+}
+//-----------------------------------------------------------------------
+void Body::setForce(const Ogre::Vector3& force)
+{
+    dBodySetForce(_body, (dReal) force.x, (dReal)force.y, (dReal)force.z);
+}
+//-----------------------------------------------------------------------
+void Body::setTorque(const Ogre::Vector3& torque)
+{
+    dBodySetTorque(_body, (dReal) torque.x, (dReal)torque.y, (dReal)torque.z);
+}
+//-----------------------------------------------------------------------
+/*
+Given a point on a body, get that point's position in the world
+*/
+Vector3 Body::getPointWorldPosition(const Ogre::Vector3& position)
+{
+	dVector3 result;
+	dBodyGetRelPointPos(_body,(dReal)position.x,(dReal)position.y,(dReal)position.z,result);
+
+	return Ogre::Vector3(result[0],result[1],result[2]);
+}
+//-----------------------------------------------------------------------
+/*
+Given a point on a body, get that point's velocity in the world
+*/
+Vector3 Body::getPointWorldVelocity(const Ogre::Vector3& position)
+{
+	dVector3 result;
+	dBodyGetRelPointVel(_body,(dReal)position.x,(dReal)position.y,(dReal)position.z,result);
+
+	return Ogre::Vector3(result[0],result[1],result[2]);
+}
+//-----------------------------------------------------------------------
+/*
+Given a point (in the world), get that point's velocity in the world with respect to the body
+i.e. convert the global point to a relative point on the body and compute the velocity of that
+point on the body
+*/
+Vector3 Body::getPointVelocity(const Ogre::Vector3& position)
+{
+	dVector3 result;
+	dBodyGetPointVel(_body,(dReal)position.x,(dReal)position.y,(dReal)position.z,result); 
+
+	return Ogre::Vector3(result[0],result[1],result[2]);
+}
+//-----------------------------------------------------------------------
+Vector3 Body::getPointBodyPosition(const Ogre::Vector3& position)
+{
+	dVector3 result;
+	dBodyGetPosRelPoint(_body,(dReal)position.x,(dReal)position.y,(dReal)position.z,result); 
+
+	return Ogre::Vector3(result[0],result[1],result[2]);
+}
+//-----------------------------------------------------------------------
+Vector3 Body::getVectorToWorld(const Ogre::Vector3& vector)
+{
+	dVector3 result;
+	dBodyVectorToWorld(_body,(dReal)vector.x,(dReal)vector.y,(dReal)vector.z,result);
+
+	return Ogre::Vector3(result[0],result[1],result[2]);
+}
+//-----------------------------------------------------------------------
+Vector3 Body::getVectorFromWorld(const Ogre::Vector3& vector)
+{
+	dVector3 result;
+	dBodyVectorFromWorld(_body,(dReal)vector.x,(dReal)vector.y,(dReal)vector.z,result); 
+
+	return Ogre::Vector3(result[0],result[1],result[2]);
+}
+//-----------------------------------------------------------------------
+void Body::wake()
+{
+	dBodyEnable(_body); 
+	_isEnabled = true;
+}
+//-----------------------------------------------------------------------
+void Body::sleep()
+{
+	dBodyDisable(_body); 
+	_isEnabled = false;
+}
+//-----------------------------------------------------------------------
+void Body::setAutoSleep(bool auto_disable)
+{
+	dBodySetAutoDisableFlag(_body,((auto_disable)?1:0)); 
+}
+//-----------------------------------------------------------------------
+bool Body::getAutoSleep()
+{
+	return ((dBodyGetAutoDisableFlag(_body))?true:false); 
+}
+//-----------------------------------------------------------------------
+void Body::setAutoSleepLinearThreshold(Real linear_threshold)
+{
+	dBodySetAutoDisableLinearThreshold(_body,(dReal)linear_threshold); 
+}
+//-----------------------------------------------------------------------
+Real Body::getAutoSleepLinearThreshold()
+{
+	return (Real)dBodyGetAutoDisableLinearThreshold(_body); 
+}
+//-----------------------------------------------------------------------
+void Body::setAutoSleepAngularThreshold(Real angular_threshold)
+{
+	dBodySetAutoDisableAngularThreshold(_body,(dReal)angular_threshold); 
+}
+//-----------------------------------------------------------------------
+Real Body::getAutoSleepAngularThreshold()
+{
+	return (Real)dBodyGetAutoDisableAngularThreshold(_body); 
+}
+//-----------------------------------------------------------------------
+void Body::setAutoSleepSteps(int steps)
+{
+	dBodySetAutoDisableSteps(_body,steps); 
+}
+//-----------------------------------------------------------------------
+int Body::getAutoSleepSteps()
+{
+	return dBodyGetAutoDisableSteps(_body); 
+}
+//-----------------------------------------------------------------------
+void Body::setAutoSleepTime(Real time)
+{
+	dBodySetAutoDisableTime(_body,(dReal)time); 
+}
+//-----------------------------------------------------------------------
+Real Body::getAutoSleepTime()
+{
+	return (Real)dBodyGetAutoDisableTime(_body); 
+}
+//-----------------------------------------------------------------------
+void Body::setAutoSleepDefaults()
+{
+	dBodySetAutoDisableDefaults(_body);
+}
+//-----------------------------------------------------------------------
+void Body::setFiniteRotationMode(bool on)
+{
+	dBodySetFiniteRotationMode(_body,((on)?1:0)); 
+}
+//-----------------------------------------------------------------------
+bool Body::getFiniteRotationMode()
+{
+	return ((dBodyGetFiniteRotationMode(_body))?true:false); 
+}
+//-----------------------------------------------------------------------
+void Body::setFiniteRotationAxis(const Ogre::Vector3& axis)
+{
+	dBodySetFiniteRotationAxis(_body,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z); 
+}
+//-----------------------------------------------------------------------
+const Ogre::Vector3& Body::getFiniteRotationAxis()
+{
+	dVector3 result;
+	dBodyGetFiniteRotationAxis(_body,result); 
+	_finite_axis.x = result[0];
+	_finite_axis.y = result[1];
+	_finite_axis.z = result[2];
+
+	return _finite_axis;
+}
+//-----------------------------------------------------------------------
+int Body::getJointCount()
+{
+	return dBodyGetNumJoints(_body); 
+}
+//-----------------------------------------------------------------------
+Joint* Body::getJoint(int index)
+{
+	return (Joint*)_world->getJointList().findItem((size_t)dBodyGetJoint(_body,index)); 
+}
+//-----------------------------------------------------------------------
+size_t Body::getGeometryCount()
+{
+    return _geometries.size();
+// 	int rc = 0;
+// 	Geometry* g= 0;
+// 	MaintainedItemIterator<Geometry> it = _world->_geometry_list.getIterator();
+// 	while(!it.end ())
+// 	{
+// 		g = (Geometry*) (it.getNext ());	
+// 		if (this == g->getBody()) 
+//             ++rc;
+// 	}
+// 
+// 	return rc;
+}
+//-----------------------------------------------------------------------
+Geometry* Body::getGeometry(int index)
+{
+    return _geometries[index];
+
+// 	Geometry* rc = 0;
+// 	int idx = 0;
+// 	Geometry* g = 0;
+// 	MaintainedItemIterator<Geometry> it = _world->_geometry_list.getIterator();
+// 	while(!it.end ())
+// 	{
+// 		g = (Geometry*) (it.getNext ());	
+// 		if (this == g->getBody())
+// 		{
+// 			rc = g;
+// 			++idx;
+// 
+// 			if (idx > index) 
+// 				break;
+// 		}
+// 	}
+// 
+// 	return rc;
+}
+GeometryArray* Body::getGeometries()
+{
+    return &_geometries;
+}
+
+//-----------------------------------------------------------------------
+void Body::addGeometry(Geometry *g) 
+{
+    _geometries.push_back(g);
+}
+//-----------------------------------------------------------------------
+void Body::removeGeometry(Geometry *g) 
+{
+    for (GeometryArray::iterator it = _geometries.begin ();
+        it != _geometries.end ();
+        ++it)
+    {
+        if (*it == g)
+        {
+            _geometries.erase (it);
+            return;
+        }
+    }
+}
+//-----------------------------------------------------------------------
+void Body::setAffectedByGravity(bool on)
+{
+	dBodySetGravityMode(_body,((on)?1:0)); 
+}
+//-----------------------------------------------------------------------
+bool Body::getAffectedByGravity()
+{
+	return ((dBodyGetGravityMode(_body))?true:false); 
+}
+//-----------------------------------------------------------------------
+dBodyID Body::getBodyID() const
+{
+	return _body;
+}
+//-----------------------------------------------------------------------
+const Ogre::String& Body::getName(void) const
+{
+	return _name;
+}
+
+//-----------------------------------------------------------------------
+void Body::deriveLocation()
+{
+	if (mParentNode)
+	{
+		setPosition(mParentNode->getPosition());
+		setOrientation(mParentNode->getOrientation());
+	}
+}
+
+//-----------------------------------------------------------------------
+void Body::recursiveSetMode(SceneNode* node)
+{
+	for(unsigned short i = 0;i < node->numChildren();i++)
+	{
+		recursiveSetMode(static_cast<SceneNode*>(node->getChild(i)));		
+	}
+
+	if (_debug_node)
+	{
+		for(unsigned short j = 0;j < node->numAttachedObjects();j++)
+		{
+			static_cast<DebugObject*>(node->getAttachedObject(j))->setMode(
+				(dBodyIsEnabled(_body))?
+				DebugObject::Mode_Enabled
+				:
+				DebugObject::Mode_Disabled);
+		}
+	}
+}
+//-----------------------------------------------------------------------
+void Body::setDamping(Real linear_damping,Real angular_damping)
+{
+	_linear_damping = -(dReal)linear_damping;
+	_is_linear_damped = (_linear_damping < 0.0);
+	_angular_damping = -(dReal)angular_damping;
+	_is_angular_damped = (_angular_damping < 0.0);
+
+	_is_damped = _linear_damping || _is_angular_damped;
+}
+//-----------------------------------------------------------------------
+void Body::setLinearDamping(Real linear_damping)
+{
+	_linear_damping = -(dReal)linear_damping;
+	_is_linear_damped = (_linear_damping < 0.0);
+
+	_is_damped = _linear_damping || _is_angular_damped;
+}
+//-----------------------------------------------------------------------
+void Body::setAngularDamping(Real angular_damping)
+{
+	_angular_damping = -(dReal)angular_damping;
+	_is_angular_damped = (_angular_damping < 0.0);
+
+	_is_damped = _linear_damping || _is_angular_damped;
+}
+//-----------------------------------------------------------------------
+Real Body::getLinearDamping()
+{
+	return -(Real)_linear_damping;
+}
+//-----------------------------------------------------------------------
+Real Body::getAngularDamping()
+{
+	return -(Real)_angular_damping;
+}
+//-----------------------------------------------------------------------
+void Body::applyDamping()
+{
+	assert (_isEnabled && _is_damped);
+	
+	if (_linear_damping)
+	{
+		const dReal * const v = dBodyGetLinearVel(_body);
+		dBodyAddForce(_body, v[0] * _linear_damping, v[1] * _linear_damping, v[2] * _linear_damping);
+	}
+
+	if (_is_angular_damped)
+	{
+		const dReal * const v = dBodyGetAngularVel(_body);
+		dBodyAddTorque(_body, v[0] * _angular_damping, v[1] * _angular_damping, v[2] * _angular_damping);
+	}	
+}
+//-----------------------------------------------------------------------
+void Body::setDebug(const bool debug)
+{
+	destroyDebugNode();
+}
+//-----------------------------------------------------------------------
+void Body::setUserData(size_t user_data)
+{
+	_user_data = user_data;
+}
+//-----------------------------------------------------------------------
+size_t Body::getUserData()
+{
+	return _user_data;
+}
+//-----------------------------------------------------------------------
+size_t Body::getID()
+{
+	return (size_t)_body;
+}
+//-----------------------------------------------------------------------
+Body::~Body()
+{
+	destroyDebugNode();
+	delete _mass;
+
+	_world->getBodyList().unregisterItem((size_t)_body);
+	dBodyDestroy(_body);
+}
+
+//-----------------------------------------------------------------------
+bool Body::collide(void* data, Geometry *otherGeometry)
+{
+    bool collided = false;
+    dContactGeom contactGeom;
+    Geometry *o1;
+    GeometryArray::const_iterator proxy1, proxy1end;
+    proxy1end = _geometries.end();
+
+    //dContact contact;
+    //Real bounce, velThresh, softness;
+
+    //CollisionInfo collInfo;
+
+    // @@TODO : HAS TO HANDLE TransFormedGeometry and GoemtryOffset
+    for (proxy1 = _geometries.begin(); proxy1 != proxy1end; ++proxy1)
+    {
+        o1 = *proxy1;
+        const int numc = dCollide(o1->getGeometryID(), otherGeometry->getGeometryID(), 0, &contactGeom, sizeof(dContactGeom));
+        if (numc)
+        {
+            // Create contact joints if either object is dynamics simulated
+            // If one is not, then sim will not affect it anyway, it will be fixed
+            // However if one is enabled, we need the contact joint
+            if (this->isAwake())
+            {
+                  _world->collisionCallback(data, o1->getGeometryID(), otherGeometry->getGeometryID());
+            }
+
+            // set return 
+            collided = true;
+            
+        }
+    }
+    return collided;
+}
+//-----------------------------------------------------------------------
+bool Body::collide(void* data, Body *otherBody)
+{
+    bool collided = false;
+    dContactGeom contactGeom;
+    Geometry *o1, *o2;
+    GeometryArray::const_iterator proxy1, proxy2, proxy1end, proxy2end;
+    proxy1end = _geometries.end();
+    proxy2end = otherBody->getGeometries()->end();
+
+    //dContact contact;
+    //Real bounce, velThresh, softness;
+
+    //CollisionInfo collInfo;
+
+    // @@TODO : HAS TO HANDLE TransFormedGeometry and GoemtryOffset
+    for (proxy1 = _geometries.begin(); proxy1 != proxy1end; ++proxy1)
+    {
+        for (proxy2 = otherBody->getGeometries()->begin(); proxy2 != proxy2end; ++proxy2)
+        {
+            o1 = *proxy1;
+            o2 = *proxy2;
+            const int numc = dCollide(o1->getGeometryID(), o2->getGeometryID(), 0, &contactGeom, sizeof(dContactGeom));
+            if (numc)
+            {
+                // Create contact joints if either object is dynamics simulated
+                // If one is not, then sim will not affect it anyway, it will be fixed
+                // However if one is enabled, we need the contact joint
+                if (this->isAwake() || otherBody->isAwake())
+                {
+
+                    _world->collisionCallback(data, o1->getGeometryID(), o2->getGeometryID());
+
+                }
+                // set return 
+                collided = true;
+            }
+        }
+    }
+    return collided;
+}
+//-------------------------------------------------------------------------
+bool Body::collidePlaneBounds(void* data, Ogre::SceneQuery::WorldFragment *wf)
+{
+    bool collided = false;
+    dContactGeom contactGeom;
+    Geometry *geom;
+    GeometryArray::const_iterator proxy, proxyend;
+    proxyend = _geometries.end();
+
+    std::list<Ogre::Plane>::const_iterator pi, piend;
+    piend = wf->planes->end();
+
+    //CollisionInfo collInfo;
+
+    // @@TODO : HAS TO HANDLE TransFormedGeometry and GoemtryOffset
+    for (proxy = _geometries.begin(); proxy != proxyend; ++proxy)
+    {
+        // Hack, simply collide against planes which is facing towards center
+        // We can't do this properly without mesh collision
+        geom = *proxy;
+        Ogre::Real maxdist = -1.0f;
+        const Ogre::Plane* bestPlane = 0;
+        for (pi = wf->planes->begin(); pi != piend; ++pi)
+        {
+            const Ogre::Plane * const boundPlane = &(*pi);
+            const Ogre::Real dist = boundPlane->getDistance (this->getPosition());
+            if (dist >= 0.0f)
+            {
+
+                //@@@@ TODO reuse a static InfinitePlaneGeometry ?
+                InfinitePlaneGeometry *sliding_plane = new InfinitePlaneGeometry(*boundPlane, 0);
+
+
+                int numc = dCollide(geom->getGeometryID(), 
+                                    sliding_plane->getGeometryID(), 
+                                    0, 
+                                    &contactGeom, 
+                                    sizeof(dContactGeom));
+                if (numc)
+                {
+                    // Create contact joints if object is dynamics simulated
+                    if (this->isAwake())
+                    {
+                        _world->collisionCallback(data, geom->getGeometryID(), sliding_plane->getGeometryID());
+
+                    }
+                    // set return 
+                    collided = true;
+                }
+            }
+        } 
+
+    }
+    return collided;
+}
Index: code/branches/physics/src/ogreode/OgreOdeBody.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeBody.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeBody.h	(revision 1919)
@@ -0,0 +1,419 @@
+#ifndef _OGREODEBODY_H_
+#define _OGREODEBODY_H_
+
+#include "OgreOdePreReqs.h"
+
+namespace OgreOde 
+{
+	//-----------------------------------------------------------------------
+	class _OgreOdeExport BodyState
+	{
+	public:
+		BodyState(){};
+		BodyState(const Ogre::Vector3	&position,
+				  const Ogre::Quaternion &orientation);
+
+        void operator=(const BodyState &other);
+		bool operator==(const BodyState &other) const;
+		bool operator!=(const BodyState &other) const;
+
+		//-----------------------------------------------------------------------
+		/// compare with another physics state for "significant" differences.
+		/// used for detecting position or orientation snaps which need smoothing.
+		bool isDifferent(const BodyState &other, const Ogre::Real threshold = Ogre::Real(0.01)) const;
+
+        void interpolate(const BodyState * const _previous_state, 
+                                const BodyState * const _current_state, 
+                                const Ogre::Real alpha);
+
+		Ogre::Vector3		_position;
+		Ogre::Quaternion	_orientation;
+	};
+
+	//-----------------------------------------------------------------------
+	template <class T>
+	class _OgreOdeExport CircularBuffer
+	{
+	public:
+
+		CircularBuffer() :
+			head (0),
+			tail (0)
+		{
+		}
+
+		void resize(const size_t size)
+		{
+			head = 0;
+			tail = 0;
+			buffers.resize(size);
+		}
+
+		size_t size()
+		{
+			int count = (int)head - (int)tail;
+			if (count<0)
+				count += (int) buffers.size();
+			return (size_t) count;
+		}
+
+		void add(const T &buffer)
+		{
+			buffers[head] = buffer;
+			next(head);
+
+		}
+
+		void remove()
+		{
+			assert(!empty());
+			next(tail);
+		}
+
+		T& oldest()
+		{
+			assert(!empty());
+			return buffers[tail];
+		}
+
+		T& newest()
+		{
+			assert(!empty());
+			int index = (int)head - 1;
+			if (index == -1)
+				index = (int) buffers.size() - 1;
+			return buffers[index];
+		}
+
+		T& almostNewest()
+		{
+			assert(buffers.size() > 1);
+			int index = (int)head - 2;
+			if (index == -1)
+				index = (int) buffers.size() - 1;
+			return buffers[index];
+		}
+
+		bool empty() const
+		{
+			return head == tail;
+		}
+
+		void next(size_t &index)
+		{
+			if (index  == (size_t)buffers.size()) 
+				index -= (size_t)buffers.size();
+			else
+				index ++;
+		}
+
+		void previous(size_t &index)
+		{			
+			if ((int)index - 1 < 0)
+				index += (size_t)buffers.size();
+			else
+				index --;
+		}
+
+		T& operator[](size_t index)
+		{
+			assert(index<(size_t)buffers.size());
+			return buffers[index];
+		}
+
+	public:
+
+		size_t head;
+		size_t tail;
+
+	private:
+		std::vector<T> buffers;
+	};
+    /** 
+        This object is the class defining a for all Dynamically physical objects in OgreOde.
+    @remarks
+        This object is tied attached to a scene node, 
+        or/and tied a Entity Object using UserDefinedObject
+    @remarks
+        It extends the OGRE UserDefinedObject to allow reverse links from Ogre::Entity.
+        It extends the OGRE MovableObject to allow scene node attachment.
+    */  
+	class _OgreOdeExport Body : public Ogre::MovableObject, public Ogre::UserDefinedObject
+    {
+		friend class Joint;
+		friend class World;
+		friend class Geometry;
+
+	public:
+		Body(World *world, const Ogre::String& name = Ogre::StringUtil::BLANK);
+		virtual ~Body();
+
+        static const Ogre::String MovableType;
+
+		void _historyResize(const size_t size);
+		inline void updateParentNode();
+		inline void updatePreviousState();
+		inline void updateCurrentState();
+		inline void updateDrawState ();
+		inline void interpolateDrawState(const Ogre::Real alpha);
+		inline void synchronise();
+
+		void deriveLocation();
+
+		void setPosition(const Ogre::Vector3& position); 
+		void setOrientation(const Ogre::Quaternion& orientation); 
+		void setLinearVelocity(const Ogre::Vector3& linear_velocity); 
+		void setAngularVelocity(const Ogre::Vector3& angular_velocity); 
+
+		inline const Ogre::Vector3& getPosition() const;
+
+		inline const Ogre::Quaternion& getOrientation() const;
+		inline void updatePosition(BodyState * const bodystate);
+        inline void updateOrientation(BodyState * const bodystate);
+
+		const Ogre::Vector3& getLinearVelocity(); 
+		const Ogre::Vector3& getAngularVelocity(); 
+
+		virtual const Ogre::String& getMovableType() const; 
+        virtual void _notifyAttached(Ogre::Node* parent,bool isTagPoint = false);
+		virtual const Ogre::String& getName(void) const;
+		virtual void _notifyCurrentCamera(Ogre::Camera* camera);
+		virtual const Ogre::AxisAlignedBox& getBoundingBox(void) const;
+		virtual Ogre::Real getBoundingRadius(void) const;
+        virtual void _updateRenderQueue(Ogre::RenderQueue* queue);
+#if OGRE_VERSION >= ((1 << 16) | (5 << 8))
+		virtual void visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables = false){}
+#endif
+		void setMass(const Mass& mass);
+		const Mass& getMass();
+
+		void addForce(const Ogre::Vector3& force); 
+		void addTorque(const Ogre::Vector3& torque); 
+		void addRelativeForce(const Ogre::Vector3& force); 
+		void addRelativeTorque(const Ogre::Vector3& torque); 
+		void addForceAt(const Ogre::Vector3& force,const Ogre::Vector3& position); 
+		void addForceAtRelative(const Ogre::Vector3& force,const Ogre::Vector3& position); 
+		void addRelativeForceAt(const Ogre::Vector3& force,const Ogre::Vector3& position); 
+		void addRelativeForceAtRelative(const Ogre::Vector3& force,const Ogre::Vector3& position); 
+
+		const Ogre::Vector3& getForce(); 
+        const Ogre::Vector3& getTorque(); 
+        void setForce(const Ogre::Vector3&); 
+        void setTorque(const Ogre::Vector3&); 
+
+
+		Ogre::Vector3 getPointWorldPosition(const Ogre::Vector3& position); 
+		Ogre::Vector3 getPointWorldVelocity(const Ogre::Vector3& position);
+		Ogre::Vector3 getPointVelocity(const Ogre::Vector3& position); 
+		Ogre::Vector3 getPointBodyPosition(const Ogre::Vector3& position);
+		Ogre::Vector3 getVectorToWorld(const Ogre::Vector3& vector);
+		Ogre::Vector3 getVectorFromWorld(const Ogre::Vector3& vector);
+
+		void wake();
+		void sleep(); 
+		inline bool isAwake() const; 
+		void setAutoSleep(bool auto_sleep);
+		bool getAutoSleep(); 
+		void setAutoSleepLinearThreshold(Ogre::Real linear_threshold);
+		Ogre::Real getAutoSleepLinearThreshold(); 
+		void setAutoSleepAngularThreshold(Ogre::Real angular_threshold);
+		Ogre::Real getAutoSleepAngularThreshold(); 
+		void setAutoSleepSteps(int steps);
+		int  getAutoSleepSteps(); 
+		void setAutoSleepTime(Ogre::Real time);
+		Ogre::Real getAutoSleepTime(); 
+		void setAutoSleepDefaults();
+
+		void setFiniteRotationMode(bool on); 
+		bool getFiniteRotationMode(); 
+		void setFiniteRotationAxis(const Ogre::Vector3& axis); 
+		const Ogre::Vector3& getFiniteRotationAxis(); 
+
+        int getJointCount(); 
+		Joint* getJoint(int index); 
+
+		void setModifyParentOrientation(bool bModify);
+
+        void addGeometry(Geometry *g); 
+        void removeGeometry(Geometry *g); 
+        size_t getGeometryCount(); 
+        Geometry* getGeometry(int index);
+        GeometryArray* getGeometries();
+
+		void setAffectedByGravity(bool on);
+		bool getAffectedByGravity(); 
+
+		void setDamping(Ogre::Real linear_damping, Ogre::Real angular_damping);
+		void setLinearDamping(Ogre::Real linear_damping);
+		void setAngularDamping(Ogre::Real angular_damping);
+		Ogre::Real getLinearDamping();
+		Ogre::Real getAngularDamping();
+
+		void setUserData(size_t user_data);
+		size_t getUserData();
+
+		virtual size_t getID();
+		virtual void setDebug(const bool debug);
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+            Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Body");return sName;};
+
+        bool collide(void* data, Geometry *g);
+        bool collide(void* data, Body *b);
+        bool collidePlaneBounds(void* data, Ogre::SceneQuery::WorldFragment *);
+
+	protected:
+		dBodyID getBodyID() const;
+
+		void destroyDebugNode();
+		void addDebugNode(Ogre::Node* node);
+
+		void recursiveSetMode(Ogre::SceneNode* node);
+		
+		void applyDamping();
+
+	protected:
+		dBodyID	_body;
+		Ogre::String _name;
+		Ogre::Node* _debug_node;
+
+		static int _body_count;
+
+		Ogre::Vector3 _linear_vel;
+		Ogre::Vector3 _angular_vel;
+		Ogre::Vector3 _finite_axis;
+		Ogre::Vector3 _force;
+		Ogre::Vector3 _torque;
+		Ogre::AxisAlignedBox _bounding_box;
+		Mass* _mass;
+
+		bool _is_damped;
+		bool _is_linear_damped;
+		dReal _linear_damping;
+		bool _is_angular_damped;
+		dReal _angular_damping;
+
+		size_t _user_data;
+
+		// Major members
+		bool _isEnabled;
+		bool _modify_parent_orientation; 
+
+		BodyState	   _draw_state;
+        CircularBuffer<BodyState *> _state_history;
+
+        /// Collision proxies, must be set up if collision enabled
+        GeometryArray _geometries;
+        
+		World *_world;
+
+	};
+
+    //-----------------------------------------------------------------------
+    inline bool Body::isAwake() const { return _isEnabled; }
+    //-----------------------------------------------------------------------
+    inline void Body::updateParentNode()
+    {
+        if (mParentNode)
+        { 
+            mParentNode->setPosition(_draw_state._position);
+            mParentNode->setOrientation(_draw_state._orientation);
+        }
+
+        if (_debug_node)
+        {
+            _debug_node->setPosition(_draw_state._position);
+            _debug_node->setOrientation(_draw_state._orientation);
+
+            recursiveSetMode(static_cast<Ogre::SceneNode*>(_debug_node));
+        }
+    } 
+    //-----------------------------------------------------------------------
+    inline void Body::updatePreviousState()
+    {
+        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
+        if (_isEnabled)
+        {
+            BodyState *previous = _state_history.almostNewest ();
+            updatePosition (previous);
+            updateOrientation (previous);
+        }
+    }
+    //-----------------------------------------------------------------------
+    inline void Body::updateCurrentState()
+    {
+        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
+        if (_isEnabled)
+        {
+            BodyState *current = _state_history.newest ();
+            updatePosition(current);
+            updateOrientation(current);
+        }
+    }
+    //-----------------------------------------------------------------------
+    inline void Body::updateDrawState ()
+    {
+        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
+        if (_isEnabled)
+        {
+            updatePosition(&_draw_state);
+            updateOrientation(&_draw_state);
+        }
+    }
+    //-----------------------------------------------------------------------
+    inline void Body::interpolateDrawState(const Ogre::Real alpha)
+    {
+        if (_isEnabled)
+        {
+            BodyState *current = _state_history.newest ();
+            BodyState *previous = _state_history.almostNewest ();
+            assert (current != previous);
+            _draw_state.interpolate (previous, current, alpha);
+        }
+    }
+    //-----------------------------------------------------------------------
+    inline void Body::synchronise()
+    {
+        if (_isEnabled)
+        {
+            if (_is_damped)
+                applyDamping();
+            updateParentNode();
+        }
+    }
+    //-----------------------------------------------------------------------
+    inline const Ogre::Vector3& Body::getPosition() const
+    {
+        return _draw_state._position;
+    }
+    //-----------------------------------------------------------------------
+    inline const Ogre::Quaternion& Body::getOrientation() const
+    {
+        return _draw_state._orientation;
+    }
+    //-----------------------------------------------------------------------
+    inline void Body::updatePosition(BodyState * const bodystate)
+    {
+        const dReal * const position = dBodyGetPosition(_body);
+
+        bodystate->_position.x = (Ogre::Real)position[0];
+        bodystate->_position.y = (Ogre::Real)position[1];
+        bodystate->_position.z = (Ogre::Real)position[2];
+    }
+    //-----------------------------------------------------------------------
+    inline void Body::updateOrientation(BodyState * const bodystate)
+    {
+        const dReal * const orientation = dBodyGetQuaternion(_body); 
+        bodystate->_orientation.w = (Ogre::Real)orientation[0];
+        bodystate->_orientation.x = (Ogre::Real)orientation[1];
+        bodystate->_orientation.y = (Ogre::Real)orientation[2];
+        bodystate->_orientation.z = (Ogre::Real)orientation[3];
+    }
+    //-----------------------------------------------------------------------
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdeCollision.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeCollision.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeCollision.cpp	(revision 1919)
@@ -0,0 +1,323 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeCollision.h"
+#include "OgreOdeSpace.h"
+#include "OgreOdeGeometry.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+//------------------------------------------------------------------------------------------------
+CollisionListener::CollisionListener()
+{
+}
+//------------------------------------------------------------------------------------------------
+CollisionListener::~CollisionListener()
+{
+}
+
+//------------------------------------------------------------------------------------------------
+CollisionCallback::CollisionCallback()
+{
+}
+
+//------------------------------------------------------------------------------------------------
+CollisionCallback::~CollisionCallback()
+{
+}
+
+//-----------------------------------------------------------------------
+void CollisionCallback::collisionCallback(Space* spaceFirst, Space* spaceSecond)
+{
+	spaceFirst->collide(static_cast<CollisionCallback*>(this), spaceSecond);
+}
+	
+//-----------------------------------------------------------------------
+void CollisionCallback::collisionCallback(Space* space, Geometry* geometry)
+{
+	space->collide(static_cast<CollisionCallback*>(this), geometry);
+}
+	
+//-----------------------------------------------------------------------
+void CollisionCallback::collisionCallback(Space* space)
+{
+	space->collide(static_cast<CollisionCallback*>(this));
+}
+	
+//-----------------------------------------------------------------------
+void CollisionCallback::collisionCallback(Geometry* geometryFirst, Geometry* geometrySecond)
+{
+	geometryFirst->collide(geometrySecond, static_cast<CollisionListener*>(this));
+}
+
+//-----------------------------------------------------------------------
+void CollisionCallback::collisionCallback(void *data, dGeomID geom_a, dGeomID geom_b)
+{
+	CollisionCallback* colCallback = (CollisionCallback*) data;
+
+	const bool a_space = (dGeomIsSpace(geom_a))?true:false;
+	const bool b_space = (dGeomIsSpace(geom_b))?true:false;
+	
+	void* const ptr_a = dGeomGetData(geom_a);
+	void* const ptr_b = dGeomGetData(geom_b);
+
+	if(a_space  || b_space )
+	{
+		// Collide a space with a space
+		if(a_space && b_space) 
+			colCallback->collisionCallback(static_cast<Space*>(ptr_a), static_cast<Space*>(ptr_b));
+			//static_cast<Space*>(ptr_a)->collide(static_cast<Space*>(ptr_b), colCallback);
+		else if(a_space) 
+			colCallback->collisionCallback(static_cast<Space*>(ptr_a), static_cast<Geometry*>(ptr_b));
+			//static_cast<Space*>(ptr_a)->collide(static_cast<Geometry*>(ptr_b), colCallback);
+		else 
+			colCallback->collisionCallback(static_cast<Space*>(ptr_b), static_cast<Geometry*>(ptr_a));
+			//static_cast<Space*>(ptr_b)->collide(static_cast<Geometry*>(ptr_a), colCallback);
+
+		// Collide geometries internal to the spaces
+		if(a_space) 
+            static_cast<Space*>(ptr_a)->collide(colCallback);
+
+		if(b_space) 
+            static_cast<Space*>(ptr_b)->collide(colCallback);
+	}
+    else
+	{
+		// Collide a geom with a geom, i.e. generate contacts
+		colCallback->collisionCallback(static_cast<Geometry*>(ptr_a), static_cast<Geometry*>(ptr_b));
+		//static_cast<Geometry*>(ptr_a)->collide(static_cast<Geometry*>(ptr_b), static_cast<CollisionListener*>(colCallback));
+	}
+}
+
+
+//------------------------------------------------------------------------------------------------
+Contact::Contact()
+{
+}
+//------------------------------------------------------------------------------------------------
+Contact::~Contact()
+{
+}
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& Contact::getPosition()
+{
+	_position.x = (Real)(_contact->geom.pos[0]);
+	_position.y = (Real)(_contact->geom.pos[1]);
+	_position.z = (Real)(_contact->geom.pos[2]);
+	return _position;
+}
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& Contact::getNormal()
+{
+	_normal.x = (Real)(_contact->geom.normal[0]);
+	_normal.y = (Real)(_contact->geom.normal[1]);
+	_normal.z = (Real)(_contact->geom.normal[2]);
+	return _normal;
+}
+//------------------------------------------------------------------------------------------------
+Real Contact::getPenetrationDepth()
+{
+	return (Real)(_contact->geom.depth);
+}
+//------------------------------------------------------------------------------------------------
+Geometry* Contact::getFirstGeometry()
+{
+	dGeomID g = _contact->geom.g1;
+	if(!g) return 0;
+
+	return (Geometry*)dGeomGetData(g);
+}
+//------------------------------------------------------------------------------------------------
+Geometry* Contact::getSecondGeometry()
+{
+	dGeomID g = _contact->geom.g2;
+	if(!g) return 0;
+
+	return (Geometry*)dGeomGetData(g);
+}
+//------------------------------------------------------------------------------------------------
+int Contact::getFirstSide()
+{
+   return _contact->geom.side1;
+}
+//------------------------------------------------------------------------------------------------
+int Contact::getSecondSide()
+{
+   return _contact->geom.side2;
+} 
+//------------------------------------------------------------------------------------------------
+void Contact::setFirstFrictionDirection(const Ogre::Vector3& vector)
+{
+	_contact->fdir1[0] = (dReal)vector.x;
+	_contact->fdir1[1] = (dReal)vector.y;
+	_contact->fdir1[2] = (dReal)vector.z;
+
+	_contact->surface.mode |= (int)Flag_UseFirstFrictionDirection;
+}
+//------------------------------------------------------------------------------------------------
+void Contact::setCoulombFriction(Real mu,Real additional_mu)
+{
+	_contact->surface.mu = mu;
+	
+	if(additional_mu >= 0.0)
+	{
+		_contact->surface.mu2 = additional_mu;
+		_contact->surface.mode |= (int)Flag_UseAdditionalFriction;
+	}
+}
+//------------------------------------------------------------------------------------------------
+void Contact::setBouncyness(Real bouncyness,Real velocity_threshold)
+{
+	_contact->surface.bounce = bouncyness;
+	if(velocity_threshold >= 0.0)
+	{
+		_contact->surface.bounce_vel = velocity_threshold;
+	}
+	_contact->surface.mode |= (int)Flag_SurfaceIsBouncy;
+}
+//------------------------------------------------------------------------------------------------
+void Contact::setSoftness(Real ERP,Real CFM)
+{
+	_contact->surface.soft_erp = ERP;
+	_contact->surface.soft_cfm = CFM;
+
+	_contact->surface.mode |= (int)Flag_UseERP;
+	_contact->surface.mode |= (int)Flag_UseCFM;
+}
+//------------------------------------------------------------------------------------------------
+void Contact::setIndependentMotion(Real velocity,Real additional_velocity)
+{
+	_contact->surface.motion1 = velocity;
+	_contact->surface.mode |= (int)Flag_IndependentMotion; 
+
+	if(additional_velocity >= 0.0)
+	{
+		_contact->surface.motion2 = additional_velocity;
+		_contact->surface.mode |= (int)Flag_AdditionalIndependentMotion;
+	}
+}
+//------------------------------------------------------------------------------------------------
+void Contact::setForceDependentSlip(Real FDS)
+{
+	_contact->surface.slip1 = FDS;
+	_contact->surface.mode |= (int)Flag_UseFDS;
+}
+//------------------------------------------------------------------------------------------------
+void Contact::setAdditionalFDS(Real FDS)
+{
+	_contact->surface.slip2 = FDS;
+	_contact->surface.mode |= (int)Flag_UseAdditionalFDS;
+}
+//------------------------------------------------------------------------------------------------
+void Contact::setFrictionMode(Contact::Flag flag)
+{
+	assert((flag == Flag_FrictionPyramid)||(flag == Flag_BothFrictionPyramids)||(flag == Flag_AdditionalFrictionPyramid));
+	_contact->surface.mode |= (int)flag;			
+}
+//------------------------------------------------------------------------------------------------
+ContactMapCollisionListener::ContactMapCollisionListener()
+{
+}
+//------------------------------------------------------------------------------------------------
+bool ContactMapCollisionListener::collision(Contact* contact)
+{
+	return false;
+	/*
+	size_t mt1 = contact->getFirstGeometry()->getMaterialType();
+	if(!mt1) return false;
+	
+	size_t mt2 = contact->getSecondGeometry()->getMaterialType();
+	if(!mt2) return false;
+
+	Contact *c = getContactPtr(mt1,mt2);
+	if(!c) return false;
+
+	contact->_contact->fdir1[0] = c->_contact->fdir1[0];
+	contact->_contact->fdir1[1] = c->_contact->fdir1[1];
+	contact->_contact->fdir1[2] = c->_contact->fdir1[2];
+
+	contact->_contact->surface.mu = c->_contact->surface.mu;
+	contact->_contact->surface.mu2 = c->_contact->surface.mu2;
+
+	contact->_contact->surface.bounce = c->_contact->surface.bounce;
+	contact->_contact->surface.bounce_vel = c->_contact->surface.bounce_vel;
+
+	contact->_contact->surface.soft_erp = c->_contact->surface.soft_erp;
+	contact->_contact->surface.soft_cfm = c->_contact->surface.soft_cfm;
+
+	contact->_contact->surface.motion1 = c->_contact->surface.motion1;
+	contact->_contact->surface.motion2 = c->_contact->surface.motion2;
+
+	contact->_contact->surface.slip1 = c->_contact->surface.slip1;
+	contact->_contact->surface.slip2 = c->_contact->surface.slip2;
+
+	contact->_contact->surface.mode = c->_contact->surface.mode;
+
+	return true;
+	*/
+}
+//------------------------------------------------------------------------------------------------
+void ContactMapCollisionListener::createContact(MaterialID materialA,MaterialID materialB)
+{
+	std::map<MaterialID,MaterialMap* >::iterator i = _map.find(materialA);
+	if(i == _map.end())
+	{
+		_map.insert(MaterialMapPair(materialA,new MaterialMap()));
+		i = _map.find(materialA);
+	}
+
+	MaterialMap::iterator j = i->second->find(materialB);
+	if(j == i->second->end())
+	{
+		Contact *c = new Contact();
+		memset(c->_contact,0,sizeof(dContact));
+
+		i->second->insert(std::pair<MaterialID,Contact*>(materialB,c));
+	}
+}
+//------------------------------------------------------------------------------------------------
+Contact *ContactMapCollisionListener::getContactPtr(MaterialID materialA,MaterialID materialB)
+{
+	Contact *c = 0;
+	MaterialID A = materialA;
+	MaterialID B = materialB;
+
+	std::map<MaterialID,MaterialMap* >::iterator i = _map.find(A);
+	if(i == _map.end())
+	{
+		B = materialA;
+		A = materialB;
+
+		i = _map.find(A);
+	}
+
+	if(i != _map.end())
+	{
+		MaterialMap::iterator j = i->second->find(B);
+		if(j != i->second->end())
+		{
+			c = j->second;
+		}
+	}
+
+	return c;
+}
+//------------------------------------------------------------------------------------------------
+ContactMapCollisionListener::~ContactMapCollisionListener()
+{
+	std::map<MaterialID,MaterialMap* >::iterator i = _map.begin();
+	std::map<MaterialID,MaterialMap* >::iterator i_end = _map.end();
+
+	for(;i != i_end;++i)
+	{
+		MaterialMap::iterator j = i->second->begin();
+		MaterialMap::iterator j_end = i->second->end();
+
+		for(;j != j_end;++j) 
+			delete j->second;
+
+		delete i->second;
+	}
+}
+//------------------------------------------------------------------------------------------------
Index: code/branches/physics/src/ogreode/OgreOdeCollision.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeCollision.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeCollision.h	(revision 1919)
@@ -0,0 +1,129 @@
+#ifndef _OGREODECOLLISION_H_
+#define _OGREODECOLLISION_H_
+
+#include "OgreOdePreReqs.h"
+
+namespace OgreOde 
+{
+	class _OgreOdeExport CollisionListener
+	{
+	public:
+		CollisionListener();
+		virtual ~CollisionListener();
+
+		virtual bool collision(Contact* contact) = 0;
+	};
+
+
+	/** Using the default collisionCallbacks provided here will use the internal collisions setting of 
+		of the space. 
+		The space collide function now takes a bool useInternalCollisionFlag if you want internal collisions.
+	*/
+	class _OgreOdeExport CollisionCallback : public CollisionListener
+	{
+	public:
+	
+		friend class Space;
+		friend class Geometry;
+	
+		CollisionCallback();
+		virtual ~CollisionCallback();
+		
+		/** handles the ode callback and passes on to pure virtual methods that inherited classes implement
+		*/
+		static void collisionCallback(void *data, dGeomID geom_a, dGeomID geom_b);
+
+		/** user impliemented
+		*/
+		virtual void collisionCallback(OgreOde::Space* spaceFirst, OgreOde::Space* spaceSecond);
+		
+		virtual void collisionCallback(OgreOde::Space* space, OgreOde::Geometry* geometry);
+		
+		virtual void collisionCallback(OgreOde::Space* space);
+		
+		// This is down to a AABB level of the geometry, call collide() in here to go down further.
+		virtual void collisionCallback(OgreOde::Geometry* geometryFirst, OgreOde::Geometry* geometrySecond);
+	};
+
+
+	class _OgreOdeExport Contact
+	{
+		friend class Geometry;
+		friend class ContactMapCollisionListener;
+	
+	public:
+		enum Flag
+		{
+			Flag_UseAdditionalFriction			= dContactMu2,
+			Flag_UseFirstFrictionDirection		= dContactFDir1,
+			Flag_SurfaceIsBouncy				= dContactBounce,
+			Flag_UseERP							= dContactSoftERP,
+			Flag_UseCFM							= dContactSoftCFM,
+			Flag_IndependentMotion				= dContactMotion1, 
+			Flag_AdditionalIndependentMotion	= dContactMotion2,
+			Flag_UseFDS							= dContactSlip1,
+			Flag_UseAdditionalFDS				= dContactSlip2,
+			Flag_FrictionPyramid				= dContactApprox1_1,
+			Flag_AdditionalFrictionPyramid		= dContactApprox1_2,
+			Flag_BothFrictionPyramids			= dContactApprox1 
+		};
+
+	public:
+		Contact();
+		~Contact();
+
+		const Ogre::Vector3& getPosition();
+		const Ogre::Vector3& getNormal();
+		Ogre::Real getPenetrationDepth();
+
+        int getFirstSide();
+        int getSecondSide();
+
+		Geometry* getFirstGeometry();
+		Geometry* getSecondGeometry();
+
+		void setFirstFrictionDirection(const Ogre::Vector3& vector);
+		void setFrictionMode(Contact::Flag flag);
+
+		void setCoulombFriction(Ogre::Real mu, Ogre::Real additional_mu = -1.0);
+		void setBouncyness(Ogre::Real bouncyness, Ogre::Real velocity_threshold = -1.0);
+		void setSoftness(Ogre::Real ERP, Ogre::Real CFM);
+		void setIndependentMotion(Ogre::Real velocity, Ogre::Real additional_velocity = -1.0);
+		void setForceDependentSlip(Ogre::Real FDS);
+		void setAdditionalFDS(Ogre::Real FDS);
+
+		inline void setContact(dContact* contact)
+		{
+			_contact = contact;
+			_contact->surface.mode = 0;
+		}
+	protected:
+		inline Contact& operator=(dContact* contact)
+		{
+			_contact = contact;
+			_contact->surface.mode = 0;
+			return *this;
+		}
+
+	protected:
+		dContact* _contact;
+		Ogre::Vector3 _position,_normal;
+	};
+
+	class _OgreOdeExport ContactMapCollisionListener:public CollisionListener
+	{
+	public:
+		ContactMapCollisionListener();
+		virtual ~ContactMapCollisionListener();
+
+		virtual bool collision(Contact* contact);
+
+		void createContact(MaterialID materialA,MaterialID materialB); 
+		Contact *getContactPtr(MaterialID materialA,MaterialID materialB); 
+
+	protected:
+		std::map<MaterialID,MaterialMap* > _map;
+	};
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdeDebugContact.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeDebugContact.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeDebugContact.cpp	(revision 1919)
@@ -0,0 +1,631 @@
+/**
+* File: OgreOdeDebugContact.cpp
+*
+* description: This create create a billboarding object that display a text.
+*  From MovableText
+* @author  2003 by cTh see gavocanov@rambler.ru
+* @update  2006 by barraq see nospam@barraquand.com
+*/
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "Ogre.h"
+#include "OgreFontManager.h"
+
+#include "OgreOdeDebugContact.h"
+#include "OgreOdeCollision.h"
+#include "OgreOdeGeometry.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeWorld.h"
+
+using namespace Ogre;
+
+#define POS_TEX_BINDING    0
+#define COLOUR_BINDING     1
+
+namespace OgreOde
+{
+    //------------------------------------------------------------------------------------------------
+    DebugContact::DebugContact(const String &name, World *world) : 
+        _name(name), 
+        _world(world),
+        _enabled(false)
+    {
+        // scene node 
+        _node = _world->getSceneManager()->getRootSceneNode ()->createChildSceneNode ();
+
+        // sphere attach to contact point
+        _point = _world->getSceneManager()->createEntity(name + String("_debug_point"), "sphere.mesh");
+        _point_node = _node->createChildSceneNode ();
+        _point_node->attachObject (_point);
+        _point_node->setScale(0.001, 0.001, 0.001);
+
+        // normal direction debug
+         _normal = new DebugNormal();
+         _node->attachObject (_normal);
+
+         // text info on contact
+        _text = new DebugContactText(name + String("_debug_text"), _node->createChildSceneNode ());
+        _text->setPosition (Vector3(0,5,0));
+        _text->setCaption ("-");
+        _text->setVisible (false);
+
+        _node->setVisible (false);
+    }
+     //------------------------------------------------------------------------------------------------
+    DebugContact::~DebugContact()
+    {
+        delete _text;
+
+        _point_node->detachObject (_point->getName ());
+        _node->detachObject (_normal->getName ());
+
+        _world->getSceneManager()->destroyEntity (_point->getName ());
+
+        _node->detachAllObjects ();
+        _node->removeAndDestroyAllChildren ();
+
+        delete _normal;
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContact::update(Contact * const contact)
+    {
+        _node->setPosition (contact->getPosition ());
+
+        _point_node->setPosition (contact->getPenetrationDepth () * contact->getNormal());
+
+        //String contactLabel("p: ");
+        //contactLabel = contactLabel + StringConverter::toString(contact->getPosition());
+        //contactLabel = contactLabel + ", n: ";
+        //contactLabel = contactLabel + StringConverter::toString(contact->getNormal());
+        //_text->setCaption (contactLabel);
+        //_text->setVisible (false);
+
+        //_text->setPosition (contact->getPosition () + Vector3(0,5,0));
+        
+        _normal->update (contact);
+    }
+    //------------------------------------------------------------------------------------------------
+    bool DebugContact::isEnabled () const 
+    {
+        return _enabled;
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContact::setEnabled (bool enable)
+    {
+        _enabled = enable;
+        _node->setVisible (_enabled);
+    };
+    //------------------------------------------------------------------------------------------------
+    void DebugNormal::update(Contact * const contact)
+    {
+       DebugLines::clear ();
+       // set normal following contact normal
+       //contact->_normal 
+       //contact->_position
+       DebugLines::addLine (Vector3::ZERO, 
+                            5*contact->getNormal ());
+        DebugLines::draw ();
+    }
+    //------------------------------------------------------------------------------------------------
+    DebugContactText::DebugContactText(const String &name, 
+                                SceneNode *node,
+                                const String &caption, 
+                                const String &fontName, 
+                                int charHeight, 
+                                const ColourValue &color)
+        : mpCam(NULL)
+        , mpWin(NULL)
+        , mpFont(NULL)
+        , mName(name)
+        , mCaption(caption)
+        , mFontName(fontName)
+        , mCharHeight(charHeight)
+        , mColor(color)
+        , mType("DebugContact")
+        , mTimeUntilNextToggle(0)
+        , mSpaceWidth(0)
+        , mUpdateColors(true)
+        , mOnTop(false)
+        , mHorizontalAlignment(H_LEFT)
+        , mVerticalAlignment(V_BELOW)
+        , mAdditionalHeight(0.0)
+        , mNode(node)
+
+    {
+        if (name.empty())
+            Exception(Exception::ERR_INVALIDPARAMS, "Trying to create DebugContact without name", "DebugContact::DebugContact");
+// 
+//         if (caption.empty())
+//            Exception(Exception::ERR_INVALIDPARAMS, "Trying to create DebugContact without caption", "DebugContact::DebugContact");
+
+        mRenderOp.vertexData = NULL;
+        this->setFontName(mFontName);
+        //this->_setupGeometry();
+        mNode->attachObject(this);
+    }
+    //------------------------------------------------------------------------------------------------
+    DebugContactText::~DebugContactText()
+    {
+        mNode->detachObject(this->getName());
+        if (mRenderOp.vertexData)
+            delete mRenderOp.vertexData;
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::setPosition(const Vector3 &pos)
+    {
+        mNode->setPosition (pos);
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::setFontName(const String &fontName)
+    {
+        if((Ogre::MaterialManager::getSingletonPtr()->resourceExists(mName + "Material"))) 
+        { 
+            Ogre::MaterialManager::getSingleton().remove(mName + "Material"); 
+        }
+
+        if (mFontName != fontName || mpMaterial.isNull() || !mpFont)
+        {
+            mFontName = fontName;
+            mpFont = (Font *)FontManager::getSingleton().getByName(mFontName).getPointer();
+            if (!mpFont)
+                Exception(Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + fontName, "DebugContact::setFontName");
+
+            mpFont->load();
+            if (!mpMaterial.isNull())
+            {
+                MaterialManager::getSingletonPtr()->remove(mpMaterial->getName());
+                mpMaterial.setNull();
+            }
+
+            mpMaterial = mpFont->getMaterial()->clone(mName + "Material");
+            if (!mpMaterial->isLoaded())
+                mpMaterial->load();
+
+            mpMaterial->setDepthCheckEnabled(!mOnTop);
+            mpMaterial->setDepthBias(0,!mOnTop);
+            mpMaterial->setDepthWriteEnabled(mOnTop);
+            mpMaterial->setLightingEnabled(false);
+            mNeedUpdate = true;
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::setCaption(const String &caption)
+    {
+        if (caption != mCaption)
+        {
+            mCaption = caption;
+            mNeedUpdate = true;
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::setColor(const ColourValue &color)
+    {
+        if (color != mColor)
+        {
+            mColor = color;
+            mUpdateColors = true;
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::setCharacterHeight(unsigned int height)
+    {
+        if (height != mCharHeight)
+        {
+            mCharHeight = height;
+            mNeedUpdate = true;
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::setSpaceWidth(unsigned int width)
+    {
+        if (width != mSpaceWidth)
+        {
+            mSpaceWidth = width;
+            mNeedUpdate = true;
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::setTextAlignment(const HorizontalAlignment& horizontalAlignment, const VerticalAlignment& verticalAlignment)
+    {
+        if(mHorizontalAlignment != horizontalAlignment)
+        {
+            mHorizontalAlignment = horizontalAlignment;
+            mNeedUpdate = true;
+        }
+        if(mVerticalAlignment != verticalAlignment)
+        {
+            mVerticalAlignment = verticalAlignment;
+            mNeedUpdate = true;
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::setAdditionalHeight( Real height )
+    {
+        if( mAdditionalHeight != height )
+        {
+            mAdditionalHeight = height;
+            mNeedUpdate = true;
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::showOnTop(bool show)
+    {
+        if( mOnTop != show && !mpMaterial.isNull() )
+        {
+            mOnTop = show;
+            mpMaterial->setDepthBias(0,!mOnTop);
+            mpMaterial->setDepthCheckEnabled(!mOnTop);
+            mpMaterial->setDepthWriteEnabled(mOnTop);
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::_setupGeometry()
+    {
+        assert(mpFont);
+        assert(!mpMaterial.isNull());
+
+        unsigned int vertexCount = static_cast<unsigned int>(mCaption.size() * 6);
+
+        if (mRenderOp.vertexData)
+        {
+            // Removed this test as it causes problems when replacing a caption
+            // of the same size: replacing "Hello" with "hello"
+            // as well as when changing the text alignment
+            //if (mRenderOp.vertexData->vertexCount != vertexCount)
+            {
+                delete mRenderOp.vertexData;
+                mRenderOp.vertexData = NULL;
+                mUpdateColors = true;
+            }
+        }
+
+        if (!mRenderOp.vertexData)
+            mRenderOp.vertexData = new VertexData();
+
+        mRenderOp.indexData = 0;
+        mRenderOp.vertexData->vertexStart = 0;
+        mRenderOp.vertexData->vertexCount = vertexCount;
+        mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; 
+        mRenderOp.useIndexes = false; 
+
+        VertexDeclaration  *decl = mRenderOp.vertexData->vertexDeclaration;
+        VertexBufferBinding   *bind = mRenderOp.vertexData->vertexBufferBinding;
+        size_t offset = 0;
+
+        // create/bind positions/tex.ccord. buffer
+        if (!decl->findElementBySemantic(VES_POSITION))
+            decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);
+
+        offset += VertexElement::getTypeSize(VET_FLOAT3);
+
+        if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
+            decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
+
+        HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING),
+            mRenderOp.vertexData->vertexCount,
+            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
+        bind->setBinding(POS_TEX_BINDING, ptbuf);
+
+        // Colours - store these in a separate buffer because they change less often
+        if (!decl->findElementBySemantic(VES_DIFFUSE))
+            decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);
+
+        HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING),
+            mRenderOp.vertexData->vertexCount,
+            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
+        bind->setBinding(COLOUR_BINDING, cbuf);
+
+        size_t charlen = mCaption.size();
+        Real *pPCBuff = static_cast<Real*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD));
+
+        float largestWidth = 0;
+        float left = 0 * 2.0 - 1.0;
+        float top = -((0 * 2.0) - 1.0);
+
+        // Derive space width from a capital A
+        if (mSpaceWidth == 0)
+            mSpaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0;
+
+        // for calculation of AABB
+        Ogre::Vector3 min, max, currPos;
+        Ogre::Real maxSquaredRadius;
+        bool first = true;
+
+        // Use iterator
+        String::iterator i, iend;
+        iend = mCaption.end();
+        bool newLine = true;
+        Real len = 0.0f;
+
+        if(mVerticalAlignment == DebugContactText::V_ABOVE)
+        {
+            // Raise the first line of the caption
+            top += mCharHeight;
+            for (i = mCaption.begin(); i != iend; ++i)
+            {
+                if (*i == '\n')
+                    top += mCharHeight * 2.0;
+            }
+        }
+
+        for (i = mCaption.begin(); i != iend; ++i)
+        {
+            if (newLine)
+            {
+                len = 0.0f;
+                for (String::iterator j = i; j != iend && *j != '\n'; j++)
+                {
+                    if (*j == ' ')
+                        len += mSpaceWidth;
+                    else 
+                        len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0;
+                }
+                newLine = false;
+            }
+
+            if (*i == '\n')
+            {
+                left = 0 * 2.0 - 1.0;
+                top -= mCharHeight * 2.0;
+                newLine = true;
+                continue;
+            }
+
+            if (*i == ' ')
+            {
+                // Just leave a gap, no tris
+                left += mSpaceWidth;
+                // Also reduce tri count
+                mRenderOp.vertexData->vertexCount -= 6;
+                continue;
+            }
+
+            Real horiz_height = mpFont->getGlyphAspectRatio(*i);
+            const Font::UVRect &uvRect = mpFont->getGlyphTexCoords(*i);
+            const Real u1 = uvRect.left; 
+            const Real u2 = uvRect.right; 
+            const Real v1 = uvRect.top; 
+            const Real v2 = uvRect.bottom; 
+
+            // each vert is (x, y, z, u, v)
+            //-------------------------------------------------------------------------------------
+            // First tri
+            //
+            // Upper left
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                *pPCBuff++ = left;
+            else
+                *pPCBuff++ = left - (len / 2);
+            *pPCBuff++ = top;
+            *pPCBuff++ = -1.0;
+            *pPCBuff++ = u1;
+            *pPCBuff++ = v1;
+
+            // Deal with bounds
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                currPos = Ogre::Vector3(left, top, -1.0);
+            else
+                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
+            if (first)
+            {
+                min = max = currPos;
+                maxSquaredRadius = currPos.squaredLength();
+                first = false;
+            }
+            else
+            {
+                min.makeFloor(currPos);
+                max.makeCeil(currPos);
+                maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
+            }
+
+            top -= mCharHeight * 2.0;
+
+            // Bottom left
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                *pPCBuff++ = left;
+            else
+                *pPCBuff++ = left - (len / 2);
+            *pPCBuff++ = top;
+            *pPCBuff++ = -1.0;
+            *pPCBuff++ = u1;
+            *pPCBuff++ = v2;
+
+            // Deal with bounds
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                currPos = Ogre::Vector3(left, top, -1.0);
+            else
+                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
+            min.makeFloor(currPos);
+            max.makeCeil(currPos);
+            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
+
+            top += mCharHeight * 2.0;
+            left += horiz_height * mCharHeight * 2.0;
+
+            // Top right
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                *pPCBuff++ = left;
+            else
+                *pPCBuff++ = left - (len / 2);
+            *pPCBuff++ = top;
+            *pPCBuff++ = -1.0;
+            *pPCBuff++ = u2;
+            *pPCBuff++ = v1;
+            //-------------------------------------------------------------------------------------
+
+            // Deal with bounds
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                currPos = Ogre::Vector3(left, top, -1.0);
+            else
+                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
+            min.makeFloor(currPos);
+            max.makeCeil(currPos);
+            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
+
+            //-------------------------------------------------------------------------------------
+            // Second tri
+            //
+            // Top right (again)
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                *pPCBuff++ = left;
+            else
+                *pPCBuff++ = left - (len / 2);
+            *pPCBuff++ = top;
+            *pPCBuff++ = -1.0;
+            *pPCBuff++ = u2;
+            *pPCBuff++ = v1;
+
+            currPos = Ogre::Vector3(left, top, -1.0);
+            min.makeFloor(currPos);
+            max.makeCeil(currPos);
+            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
+
+            top -= mCharHeight * 2.0;
+            left -= horiz_height  * mCharHeight * 2.0;
+
+            // Bottom left (again)
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                *pPCBuff++ = left;
+            else
+                *pPCBuff++ = left - (len / 2);
+            *pPCBuff++ = top;
+            *pPCBuff++ = -1.0;
+            *pPCBuff++ = u1;
+            *pPCBuff++ = v2;
+
+            currPos = Ogre::Vector3(left, top, -1.0);
+            min.makeFloor(currPos);
+            max.makeCeil(currPos);
+            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
+
+            left += horiz_height  * mCharHeight * 2.0;
+
+            // Bottom right
+            if(mHorizontalAlignment == DebugContactText::H_LEFT)
+                *pPCBuff++ = left;
+            else
+                *pPCBuff++ = left - (len / 2);
+            *pPCBuff++ = top;
+            *pPCBuff++ = -1.0;
+            *pPCBuff++ = u2;
+            *pPCBuff++ = v2;
+            //-------------------------------------------------------------------------------------
+
+            currPos = Ogre::Vector3(left, top, -1.0);
+            min.makeFloor(currPos);
+            max.makeCeil(currPos);
+            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
+
+            // Go back up with top
+            top += mCharHeight * 2.0;
+
+            float currentWidth = (left + 1)/2 - 0;
+            if (currentWidth > largestWidth)
+                largestWidth = currentWidth;
+        }
+
+        // Unlock vertex buffer
+        ptbuf->unlock();
+
+        // update AABB/Sphere radius
+        mAABB = Ogre::AxisAlignedBox(min, max);
+        mRadius = Ogre::Math::Sqrt(maxSquaredRadius);
+
+        if (mUpdateColors)
+            this->_updateColors();
+
+        mNeedUpdate = false;
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::_updateColors(void)
+    {
+        assert(mpFont);
+        assert(!mpMaterial.isNull());
+
+        // Convert to system-specific
+        RGBA color;
+        Root::getSingleton().convertColourValue(mColor, &color);
+        HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING);
+        RGBA *pDest = static_cast<RGBA*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
+        for (unsigned int i = 0; i < mRenderOp.vertexData->vertexCount; ++i)
+            *pDest++ = color;
+        vbuf->unlock();
+        mUpdateColors = false;
+    }
+    //------------------------------------------------------------------------------------------------
+#if OGRE_VERSION < ((1 << 16) | (5 << 8))
+    const Quaternion& DebugContactText::getWorldOrientation(void) const
+#else
+    const Quaternion& DebugContactText::_getDerivedOrientation(void) const
+#endif
+    {
+        assert(mpCam);
+        return const_cast<Quaternion&>(mpCam->getDerivedOrientation());
+    }
+    //------------------------------------------------------------------------------------------------
+#if OGRE_VERSION < ((1 << 16) | (5 << 8))
+    const Vector3& DebugContactText::getWorldPosition(void) const
+#else
+    const Vector3& DebugContactText::_getDerivedPosition(void) const
+#endif
+    {
+        assert(mParentNode);
+        return mParentNode->_getDerivedPosition();
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::getWorldTransforms(Matrix4 *xform) const 
+    {	
+        if (this->isVisible() && mpCam)
+        {
+            Matrix3 rot3x3, scale3x3 = Matrix3::IDENTITY;
+
+            // store rotation in a matrix
+            mpCam->getDerivedOrientation().ToRotationMatrix(rot3x3);
+
+            // parent node position
+            Vector3 ppos = mParentNode->_getDerivedPosition() + Vector3::UNIT_Y*mAdditionalHeight;
+
+            // apply scale
+            scale3x3[0][0] = mParentNode->_getDerivedScale().x / 2;
+            scale3x3[1][1] = mParentNode->_getDerivedScale().y / 2;
+            scale3x3[2][2] = mParentNode->_getDerivedScale().z / 2;
+
+            // apply all transforms to xform       
+            *xform = (rot3x3 * scale3x3);
+            xform->setTrans(ppos);
+        }
+   }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::getRenderOperation(RenderOperation &op)
+    {
+        if (this->isVisible())
+        {
+            if (mNeedUpdate)
+                this->_setupGeometry();
+            if (mUpdateColors)
+                this->_updateColors();
+            op = mRenderOp;
+        }
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::_notifyCurrentCamera(Camera *cam)
+    {
+        mpCam = cam;
+    }
+    //------------------------------------------------------------------------------------------------
+    void DebugContactText::_updateRenderQueue(RenderQueue* queue)
+    {
+        if (this->isVisible())
+        {
+            if (mNeedUpdate)
+                this->_setupGeometry();
+            if (mUpdateColors)
+                this->_updateColors();
+
+            queue->addRenderable(this, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY);
+            //      queue->addRenderable(this, mRenderQueueID, RENDER_QUEUE_SKIES_LATE);
+        }
+    }
+}
Index: code/branches/physics/src/ogreode/OgreOdeDebugContact.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeDebugContact.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeDebugContact.h	(revision 1919)
@@ -0,0 +1,162 @@
+/**
+* File: OgreOdeDebugContact.h
+*
+* description: This create create a billboarding object that display a text.
+* derived from Movable Text
+* @author  2003 by cTh see gavocanov@rambler.ru
+* @update  2006 by barraq see nospam@barraquand.com
+*/
+
+#ifndef __include_OgreOdeDebugContact_H__
+#define __include_OgreOdeDebugContact_H__
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeDebugObject.h"
+
+namespace OgreOde 
+{
+    class DebugContact
+    {
+    public:
+        DebugContact(const Ogre::String &name, World *world);
+         ~DebugContact();
+
+         bool isEnabled () const;
+         void setEnabled (bool enable);
+
+        void update(Contact * const contact);
+
+    private:
+        DebugNormal         *_normal;
+        DebugContactText    *_text;
+        Ogre::Entity        *_point;
+        bool                _enabled;
+        Ogre::String        _name;
+        Ogre::SceneNode     *_node;
+        Ogre::SceneNode     *_point_node;
+        World               *_world;
+    };
+
+    class DebugNormal : public DebugLines
+    {
+    public:
+        DebugNormal() : DebugLines(){};
+        ~DebugNormal(){};
+
+        void update (Contact * const contact);
+    };
+
+    class DebugContactText : public Ogre::MovableObject, public Ogre::Renderable
+    {
+    public:
+        enum HorizontalAlignment    {H_LEFT, H_CENTER};
+        enum VerticalAlignment      {V_BELOW, V_ABOVE};
+        /******************************** public methods ******************************/
+    public:
+        DebugContactText(const Ogre::String &name, 
+                         Ogre::SceneNode *node,
+                         const Ogre::String &caption = "", 
+                         const Ogre::String &fontName = "BlueHighway", 
+                         int charHeight = 32, 
+                         const Ogre::ColourValue &color = Ogre::ColourValue::White);
+
+
+         ~DebugContactText();
+
+        // Set settings
+        void    setPosition(const Ogre::Vector3 &pos);
+
+        void    setFontName(const Ogre::String &fontName);
+        void    setCaption(const Ogre::String &caption);
+        void    setColor(const Ogre::ColourValue &color);
+        void    setCharacterHeight(unsigned int height);
+        void    setSpaceWidth(unsigned int width);
+        void    setTextAlignment(const HorizontalAlignment& horizontalAlignment, 
+                                const VerticalAlignment& verticalAlignment);
+        void    setAdditionalHeight( Ogre::Real height );
+        void    showOnTop(bool show=true);
+
+        // Get settings
+        const   Ogre::String          &getFontName() const {return mFontName;}
+        const   Ogre::String          &getCaption() const {return mCaption;}
+        const   Ogre::ColourValue     &getColor() const {return mColor;}
+
+
+        unsigned int    getCharacterHeight() const {return mCharHeight;}
+        unsigned int    getSpaceWidth() const {return mSpaceWidth;}
+        Ogre::Real                  getAdditionalHeight() const {return mAdditionalHeight;}
+        bool                    getShowOnTop() const {return mOnTop;}
+        Ogre::AxisAlignedBox	        GetAABB(void) { return mAABB; }
+		
+#if OGRE_VERSION >= ((1 << 16) | (5 << 8))
+		virtual void visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables = false){}
+#endif
+
+        /******************************** protected methods and overload **************/
+    protected:
+
+        // from OgreOdeDebugContact, create the object
+        void	_setupGeometry();
+        void	_updateColors();
+
+        // from MovableObject
+        void                            getWorldTransforms(Ogre::Matrix4 *xform) const;
+        Ogre::Real                      getBoundingRadius(void) const {return mRadius;};
+        Ogre::Real                      getSquaredViewDepth(const Ogre::Camera *cam) const {return 0;};
+#if OGRE_VERSION < ((1 << 16) | (5 << 8))
+        const   Ogre::Quaternion        &getWorldOrientation() const;
+        const   Ogre::Vector3           &getWorldPosition() const;
+#else
+        const   Ogre::Quaternion        &_getDerivedOrientation(void) const;
+        const   Ogre::Vector3           &_getDerivedPosition(void) const;
+#endif
+        const   Ogre::AxisAlignedBox    &getBoundingBox(void) const {return mAABB;};
+        const   Ogre::String            &getName(void) const {return mName;};
+        const   Ogre::String            &getMovableType(void) const {static Ogre::String movType = "MovableText"; return movType;};
+
+        void                            _notifyCurrentCamera(Ogre::Camera *cam);
+        void                            _updateRenderQueue(Ogre::RenderQueue* queue);
+
+        // from renderable
+        void                            getRenderOperation(Ogre::RenderOperation &op);
+        const   Ogre::MaterialPtr       &getMaterial(void) const {assert(!mpMaterial.isNull());return mpMaterial;};
+        const   Ogre::LightList         &getLights(void) const {return mLList;};
+
+        /******************************** OgreOdeDebugContact data ****************************/
+  
+
+    protected:
+        Ogre::String			mFontName;
+        Ogre::String			mType;
+        Ogre::String			mName;
+        Ogre::String			mCaption;
+        HorizontalAlignment	    mHorizontalAlignment;
+        VerticalAlignment	    mVerticalAlignment;
+
+        Ogre::ColourValue		mColor;
+        Ogre::RenderOperation	mRenderOp;
+        Ogre::AxisAlignedBox	mAABB;
+        Ogre::LightList		    mLList;
+
+        unsigned int			mCharHeight;
+        unsigned int			mSpaceWidth;
+
+        bool			        mNeedUpdate;
+        bool			        mUpdateColors;
+        bool			        mOnTop;
+
+        Ogre::Real			    mTimeUntilNextToggle;
+        Ogre::Real			    mRadius;
+        Ogre::Real              mAdditionalHeight;
+
+        Ogre::Camera			*mpCam;
+        Ogre::RenderWindow	    *mpWin;
+        Ogre::Font			    *mpFont;
+        Ogre::MaterialPtr		mpMaterial;
+        Ogre::MaterialPtr		mpBackgroundMaterial;
+
+        Ogre::SceneNode         *mNode;
+    };
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdeDebugObject.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeDebugObject.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeDebugObject.cpp	(revision 1919)
@@ -0,0 +1,792 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeDebugObject.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+//------------------------------------------------------------------------------------------------
+bool DebugLines::_materials_created = false;
+//------------------------------------------------------------------------------------------------
+DebugLines::DebugLines() : SimpleRenderable()
+{
+	mRenderOp.vertexData = new Ogre::VertexData();
+   _drawn = false;
+
+	if (!_materials_created)
+	{
+		MaterialPtr red = MaterialManager::getSingleton().create("OgreOdeDebugLines/Disabled","OgreOde");
+		MaterialPtr green = MaterialManager::getSingleton().create("OgreOdeDebugLines/Enabled","OgreOde");
+		MaterialPtr blue = MaterialManager::getSingleton().create("OgreOdeDebugLines/Static","OgreOde");
+
+        red->setReceiveShadows(false);
+		red->getTechnique(0)->setLightingEnabled(true);
+		red->getTechnique(0)->getPass(0)->setSelfIllumination(1,0,0);
+
+        green->setReceiveShadows(false);
+		green->getTechnique(0)->setLightingEnabled(true);
+		green->getTechnique(0)->getPass(0)->setSelfIllumination(0,1,0);
+
+        blue->setReceiveShadows(false);
+		blue->getTechnique(0)->setLightingEnabled(true);
+		blue->getTechnique(0)->getPass(0)->setSelfIllumination(0,0,1);
+
+		_materials_created = true;
+	}
+    setCastShadows (false);
+	this->setMaterial("OgreOdeDebugLines/Enabled");
+}
+
+
+//------------------------------------------------------------------------------------------------
+void DebugLines::clear()
+{
+	if (_drawn)
+	{
+		_drawn = false;
+		_points.clear();
+		delete mRenderOp.vertexData;
+
+		mRenderOp.vertexData = new Ogre::VertexData();
+	}
+}
+//------------------------------------------------------------------------------------------------
+DebugLines::~DebugLines(void)
+{
+   clear();
+
+   delete mRenderOp.vertexData;
+}
+//------------------------------------------------------------------------------------------------
+void DebugLines::draw()
+{
+   if (_drawn) 
+       return;
+   else 
+       _drawn = true;
+
+   // Initialization stuff
+   mRenderOp.indexData = 0;
+   mRenderOp.vertexData->vertexCount = _points.size();
+   mRenderOp.vertexData->vertexStart = 0;
+   mRenderOp.operationType = RenderOperation::OT_LINE_LIST;
+   mRenderOp.useIndexes = false;
+
+   Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
+   Ogre::VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding;
+
+   decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
+
+   HardwareVertexBufferSharedPtr vbuf =
+	   HardwareBufferManager::getSingleton().createVertexBuffer(
+         decl->getVertexSize(0),
+         mRenderOp.vertexData->vertexCount,
+		 HardwareBuffer::HBU_STATIC_WRITE_ONLY);
+
+   bind->setBinding(0, vbuf);
+
+   // Drawing stuff
+   unsigned int size = (unsigned int)_points.size();
+   Ogre::Vector3 vaabMin = _points[0];
+   Ogre::Vector3 vaabMax = _points[0];
+
+   float *prPos = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
+
+   for(unsigned int i = 0; i < size; i++)
+   {
+      *prPos++ = _points[i].x;
+      *prPos++ = _points[i].y;
+      *prPos++ = _points[i].z;
+
+      if (_points[i].x < vaabMin.x)
+         vaabMin.x = _points[i].x;
+      if (_points[i].y < vaabMin.y)
+         vaabMin.y = _points[i].y;
+      if (_points[i].z < vaabMin.z)
+         vaabMin.z = _points[i].z;
+
+      if (_points[i].x > vaabMax.x)
+         vaabMax.x = _points[i].x;
+      if (_points[i].y > vaabMax.y)
+         vaabMax.y = _points[i].y;
+      if (_points[i].z > vaabMax.z)
+         vaabMax.z = _points[i].z;
+   }
+
+   vbuf->unlock();
+
+   mBox.setExtents(vaabMin, vaabMax);
+}
+//------------------------------------------------------------------------------------------------
+Real DebugLines::getSquaredViewDepth(const Camera *cam) const
+{
+	Vector3 vMin, vMax, vMid, vDist;
+	vMin = mBox.getMinimum();
+	vMax = mBox.getMaximum();
+	vMid = ((vMin - vMax) * 0.5) + vMin;
+	vDist = cam->getDerivedPosition() - vMid;
+
+	return vDist.squaredLength();
+}
+//------------------------------------------------------------------------------------------------
+Real DebugLines::getBoundingRadius() const
+{
+	return Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
+}
+//------------------------------------------------------------------------------------------------
+DebugObject::DebugObject(DebugObject::Mode mode) 
+{
+	_mode = DebugObject::Mode_Unknown;
+	setMode(mode);
+}
+//------------------------------------------------------------------------------------------------
+void DebugObject::setMode(DebugObject::Mode mode)
+{
+	if (mode != _mode)
+	{
+		_mode = mode;
+		switch(_mode)
+		{
+			case DebugObject::Mode_Enabled:
+				setMaterial("OgreOdeDebugLines/Enabled");
+			break;
+
+			case DebugObject::Mode_Disabled:
+				setMaterial("OgreOdeDebugLines/Disabled");
+
+			break;
+
+			case DebugObject::Mode_Static:
+				setMaterial("OgreOdeDebugLines/Static");
+			break;
+		}
+	}
+}
+//------------------------------------------------------------------------------------------------
+DebugObject::~DebugObject() 
+{
+}
+//------------------------------------------------------------------------------------------------
+BoxDebugObject::BoxDebugObject(const Ogre::Vector3& size):DebugObject()
+{
+	AxisAlignedBox aabb(-size.x * 0.5,-size.y * 0.5,-size.z * 0.5,
+						size.x * 0.5,size.y * 0.5,size.z * 0.5);
+
+	Vector3 vmax = aabb.getMaximum();
+	Vector3 vmin = aabb.getMinimum();
+
+	addLine(vmin.x,vmin.y,vmin.z,vmax.x,vmin.y,vmin.z);
+	addLine(vmin.x,vmin.y,vmin.z,vmin.x,vmin.y,vmax.z);
+	addLine(vmin.x,vmin.y,vmin.z,vmin.x,vmax.y,vmin.z);
+	addLine(vmin.x,vmax.y,vmin.z,vmin.x,vmax.y,vmax.z);
+	addLine(vmin.x,vmax.y,vmin.z,vmax.x,vmax.y,vmin.z);
+	addLine(vmax.x,vmin.y,vmin.z,vmax.x,vmin.y,vmax.z);
+	addLine(vmax.x,vmin.y,vmin.z,vmax.x,vmax.y,vmin.z);
+	addLine(vmin.x,vmax.y,vmax.z,vmax.x,vmax.y,vmax.z);
+	addLine(vmin.x,vmax.y,vmax.z,vmin.x,vmin.y,vmax.z);
+	addLine(vmax.x,vmax.y,vmin.z,vmax.x,vmax.y,vmax.z);
+	addLine(vmax.x,vmin.y,vmax.z,vmax.x,vmax.y,vmax.z);
+	addLine(vmin.x,vmin.y,vmax.z,vmax.x,vmin.y,vmax.z);
+
+	draw();
+}
+//------------------------------------------------------------------------------------------------
+BoxDebugObject::~BoxDebugObject()
+{
+}
+//------------------------------------------------------------------------------------------------
+SphereDebugObject::SphereDebugObject(Real radius):DebugObject()
+{
+	// X/Y axis
+
+	// NW quadrant
+	addLine(-radius,			0.0,				0.0,
+	-0.866 * radius,	0.5 * radius,		0.0);
+
+	addLine(-0.866 * radius,	0.5 * radius,		0.0,
+	-0.5 * radius,	0.866 * radius,	0.0);
+
+	addLine(-0.5 * radius,	0.866 * radius,	0.0,
+	0.0,				radius,			0.0);
+
+	// NE quadrant
+	addLine(0.0,				radius,			0.0,
+	0.5 * radius,		0.866 * radius,	0.0);
+
+	addLine(0.5 * radius,		0.866 * radius,	0.0,
+	0.866 * radius,	0.5 * radius,		0.0);
+
+	addLine(0.866 * radius,	0.5 * radius,		0.0,
+	radius,			0.0,				0.0);
+
+	// SW quadrant
+	addLine(-radius,			0.0,				0.0,
+	-0.866 * radius,	-0.5 * radius,	0.0);
+
+	addLine(-0.866 * radius,	-0.5 * radius,	0.0,
+	-0.5 * radius,	-0.866 * radius,	0.0);
+
+	addLine(-0.5 * radius,	-0.866 * radius,	0.0,
+	0.0,				-radius,			0.0);
+
+	// SE quadrant
+	addLine(0.0,				-radius,			0.0,
+	0.5 * radius,		-0.866 * radius,	0.0);
+
+	addLine(0.5 * radius,		-0.866 * radius,	0.0,
+	0.866 * radius,	-0.5 * radius,	0.0);
+
+	addLine(0.866 * radius,	-0.5 * radius,	0.0,
+	radius,			0.0,				0.0);
+
+	// X/Z axis
+
+	// NW quadrant
+	addLine(-radius,			0.0,	0.0,	
+	-0.866 * radius,	0.0,	0.5 * radius);
+
+	addLine(-0.866 * radius,	0.0,	0.5 * radius,
+	-0.5 * radius,	0.0,	0.866 * radius);
+
+	addLine(-0.5 * radius,	0.0,	0.866 * radius,
+	0.0,				0.0,	radius);
+
+	// NE quadrant
+	addLine(0.0,				0.0,	radius,
+	0.5 * radius,		0.0,	0.866 * radius);
+
+	addLine(0.5 * radius,		0.0,	0.866 * radius,
+	0.866 * radius,	0.0,	0.5 * radius);
+
+	addLine(0.866 * radius,	0.0,	0.5 * radius,
+	radius,			0.0,	0.0);
+
+	// SW quadrant
+	addLine(-radius,			0.0,	0.0,	
+	-0.866 * radius,	0.0,	-0.5 * radius);
+
+	addLine(-0.866 * radius,	0.0,	-0.5 * radius,
+	-0.5 * radius,	0.0,	-0.866 * radius);
+
+	addLine(-0.5 * radius,	0.0,	-0.866 * radius,
+	0.0,				0.0,	-radius);
+
+	// SE quadrant
+	addLine(0.0,				0.0,	-radius,
+	0.5 * radius,		0.0,	-0.866 * radius);
+
+	addLine(0.5 * radius,		0.0,	-0.866 * radius,
+	0.866 * radius,	0.0,	-0.5 * radius);
+
+	addLine(0.866 * radius,	0.0,	-0.5 * radius,
+	radius,			0.0,	0.0);
+
+	// Y/Z axis
+
+	// NW quadrant
+	addLine(0.0,	-radius,			0.0,	
+	0.0,	-0.866 * radius,	0.5 * radius);
+
+	addLine(0.0,	-0.866 * radius,	0.5 * radius,
+	0.0,	-0.5 * radius,	0.866 * radius);
+
+	addLine(0.0,	-0.5 * radius,	0.866 * radius,
+	0.0,	0.0,				radius);
+
+	// NE quadrant
+	addLine(0.0,	0.0,				radius,
+	0.0,	0.5 * radius,		0.866 * radius);
+
+	addLine(0.0,	0.5 * radius,		0.866 * radius,
+	0.0,	0.866 * radius,	0.5 * radius);
+
+	addLine(0.0,	0.866 * radius,	0.5 * radius,
+	0.0,	radius,			0.0);
+
+	// SW quadrant
+	addLine(0.0,	-radius,			0.0,	
+	0.0,	-0.866 * radius,	-0.5 * radius);
+
+	addLine(0.0,	-0.866 * radius,	-0.5 * radius,
+	0.0,	-0.5 * radius,	-0.866 * radius);
+
+	addLine(0.0,	-0.5 * radius,	-0.866 * radius,
+	0.0,	0.0,				-radius);
+
+	// SE quadrant
+	addLine(0.0,	0.0,				-radius,
+	0.0,	0.5 * radius,		-0.866 * radius);
+
+	addLine(0.0,	0.5 * radius,		-0.866 * radius,
+	0.0,	0.866 * radius,	-0.5 * radius);
+
+	addLine(0.0,	0.866 * radius,	-0.5 * radius,
+	0.0,	radius,			0.0);
+
+	draw();
+}
+//------------------------------------------------------------------------------------------------
+SphereDebugObject::~SphereDebugObject()
+{
+}
+//------------------------------------------------------------------------------------------------
+CapsuleDebugObject::CapsuleDebugObject(Real radius,Real length):DebugObject()
+{
+	Real halflen = length * 0.5;
+	AxisAlignedBox aabb(-radius,-radius,-(halflen + radius),radius,radius,halflen + radius);
+
+	// X/Y axis - Near
+
+	// NW quadrant
+	addLine(-radius,			0.0,				halflen,
+	-0.866 * radius,	0.5 * radius,		halflen);
+
+	addLine(-0.866 * radius,	0.5 * radius,		halflen,
+		-0.5 * radius,	0.866 * radius,	halflen);
+
+	addLine(-0.5 * radius,	0.866 * radius,	halflen,
+	0.0,				radius,			halflen);
+
+	// NE quadrant
+	addLine(0.0,				radius,			halflen,
+		0.5 * radius,		0.866 * radius,	halflen);
+
+	addLine(0.5 * radius,		0.866 * radius,	halflen,
+	0.866 * radius,	0.5 * radius,		halflen);
+
+	addLine(0.866 * radius,	0.5 * radius,		halflen,
+	radius,			0.0,				halflen);
+
+	// SW quadrant
+	addLine(-radius,			0.0,				halflen,
+	-0.866 * radius,	-0.5 * radius,	halflen);
+
+	addLine(-0.866 * radius,	-0.5 * radius,	halflen,
+	-0.5 * radius,	-0.866 * radius,	halflen);
+
+	addLine(-0.5 * radius,	-0.866 * radius,	halflen,
+	0.0,				-radius,			halflen);
+
+	// SE quadrant
+	addLine(0.0,				-radius,			halflen,
+	0.5 * radius,		-0.866 * radius,	halflen);
+
+	addLine(0.5 * radius,		-0.866 * radius,	halflen,
+	0.866 * radius,	-0.5 * radius,	halflen);
+
+	addLine(0.866 * radius,	-0.5 * radius,	halflen,
+	radius,			0.0,				halflen);
+	
+	// X/Y axis - Far
+
+	// NW quadrant
+	addLine(-radius,			0.0,				-halflen,
+	-0.866 * radius,	0.5 * radius,		-halflen);
+
+	addLine(-0.866 * radius,	0.5 * radius,		-halflen,
+	-0.5 * radius,	0.866 * radius,	-halflen);
+
+	addLine(-0.5 * radius,	0.866 * radius,	-halflen,
+	0.0,				radius,			-halflen);
+
+	// NE quadrant
+	addLine(0.0,				radius,			-halflen,
+	0.5 * radius,		0.866 * radius,	-halflen);
+
+	addLine(0.5 * radius,		0.866 * radius,	-halflen,
+	0.866 * radius,	0.5 * radius,		-halflen);
+
+	addLine(0.866 * radius,	0.5 * radius,		-halflen,
+	radius,			0.0,				-halflen);
+
+	// SW quadrant
+	addLine(-radius,			0.0,				-halflen,
+	-0.866 * radius,	-0.5 * radius,	-halflen);
+
+	addLine(-0.866 * radius,	-0.5 * radius,	-halflen,
+	-0.5 * radius,	-0.866 * radius,	-halflen);
+
+	addLine(-0.5 * radius,	-0.866 * radius,	-halflen,
+	0.0,				-radius,			-halflen);
+
+	// SE quadrant
+	addLine(0.0,				-radius,			-halflen,
+	0.5 * radius,		-0.866 * radius,	-halflen);
+
+	addLine(0.5 * radius,		-0.866 * radius,	-halflen,
+	0.866 * radius,	-0.5 * radius,	-halflen);
+
+	addLine(0.866 * radius,	-0.5 * radius,	-halflen,
+	radius,			0.0,				-halflen);
+
+	// X/Z axis
+
+	// NW quadrant
+	addLine(-radius,			0.0,	halflen,	
+	-0.866 * radius,	0.0,	(0.5 * radius) + halflen);
+
+	addLine(-0.866 * radius,	0.0,	(0.5 * radius) + halflen,
+	-0.5 * radius,	0.0,	(0.866 * radius) + halflen);
+
+	addLine(-0.5 * radius,	0.0,	(0.866 * radius) + halflen,
+	0.0,				0.0,	radius + halflen);
+
+	// NE quadrant
+	addLine(0.0,				0.0,	radius + halflen,
+	0.5 * radius,		0.0,	(0.866 * radius) + halflen);
+
+	addLine(0.5 * radius,		0.0,	(0.866 * radius) + halflen,
+	0.866 * radius,	0.0,	(0.5 * radius) + halflen);
+
+	addLine(0.866 * radius,	0.0,	(0.5 * radius) + halflen,
+	radius,			0.0,	halflen);
+
+	// SW quadrant
+	addLine(-radius,			0.0,	-halflen,	
+	-0.866 * radius,	0.0,	(-0.5 * radius) - halflen);
+
+	addLine(-0.866 * radius,	0.0,	(-0.5 * radius) - halflen,
+	-0.5 * radius,	0.0,	(-0.866 * radius) - halflen);
+
+	addLine(-0.5 * radius,	0.0,	(-0.866 * radius) - halflen,
+	0.0,				0.0,	-radius - halflen);
+
+	// SE quadrant
+	addLine(0.0,				0.0,	-radius - halflen,
+	0.5 * radius,		0.0,	(-0.866 * radius) - halflen);
+
+	addLine(0.5 * radius,		0.0,	(-0.866 * radius) - halflen,
+	0.866 * radius,	0.0,	(-0.5 * radius) - halflen);
+
+	addLine(0.866 * radius,	0.0,	(-0.5 * radius) - halflen,
+	radius,			0.0,	- halflen);
+
+	// Y/Z axis
+
+	// NW quadrant
+	addLine(0.0,	-radius,			halflen,	
+	0.0,	-0.866 * radius,	(0.5 * radius) + halflen);
+
+	addLine(0.0,	-0.866 * radius,	(0.5 * radius) + halflen,
+	0.0,	-0.5 * radius,	(0.866 * radius) + halflen);
+
+	addLine(0.0,	-0.5 * radius,	(0.866 * radius) + halflen,
+	0.0,	0.0,				radius + halflen);
+
+	// NE quadrant
+	addLine(0.0,	0.0,				radius + halflen,
+	0.0,	0.5 * radius,		(0.866 * radius) + halflen);
+
+	addLine(0.0,	0.5 * radius,		(0.866 * radius) + halflen,
+	0.0,	0.866 * radius,	(0.5 * radius) + halflen);
+
+	addLine(0.0,	0.866 * radius,	(0.5 * radius) + halflen,
+	0.0,	radius,			halflen);
+
+	// SW quadrant
+	addLine(0.0,	-radius,			-halflen,	
+	0.0,	-0.866 * radius,	(-0.5 * radius) - halflen);
+
+	addLine(0.0,	-0.866 * radius,	(-0.5 * radius) - halflen,
+	0.0,	-0.5 * radius,	(-0.866 * radius) - halflen);
+
+	addLine(0.0,	-0.5 * radius,	(-0.866 * radius) - halflen,
+	0.0,	0.0,				-radius - halflen);
+
+	// SE quadrant
+	addLine(0.0,	0.0,				-radius - halflen,
+	0.0,	0.5 * radius,		(-0.866 * radius) - halflen);
+
+	addLine(0.0,	0.5 * radius,		(-0.866 * radius) - halflen,
+	0.0,	0.866 * radius,	(-0.5 * radius) - halflen);
+
+	addLine(0.0,	0.866 * radius,	(-0.5 * radius) - halflen,
+	0.0,	radius,			-halflen);
+
+	// Side lines
+	addLine(-radius,	0.0,		-halflen,
+	-radius,	0.0,		halflen);
+
+	addLine(radius,	0.0,		-halflen,
+	radius,	0.0,		halflen);
+
+	addLine(0.0,		radius,	-halflen,
+	0.0,		radius,	halflen);
+
+	addLine(0.0,		-radius,	-halflen,
+	0.0,		-radius,	halflen);
+
+	draw();
+}
+//------------------------------------------------------------------------------------------------
+CapsuleDebugObject::~CapsuleDebugObject()
+{
+}
+//------------------------------------------------------------------------------------------------
+CylinderDebugObject::CylinderDebugObject(Real radius,Real length):DebugObject()
+{
+	Real halflen = length * 0.5;
+	AxisAlignedBox aabb(-radius,-radius,-(halflen + radius),radius,radius,halflen + radius);
+
+	// X/Y axis - Near
+
+	// NW quadrant
+	addLine(-radius,			0.0,				halflen,
+		-0.866 * radius,	0.5 * radius,		halflen);
+
+	addLine(-0.866 * radius,	0.5 * radius,		halflen,
+		-0.5 * radius,	0.866 * radius,	halflen);
+
+	addLine(-0.5 * radius,	0.866 * radius,	halflen,
+		0.0,				radius,			halflen);
+
+	// NE quadrant
+	addLine(0.0,				radius,			halflen,
+		0.5 * radius,		0.866 * radius,	halflen);
+
+	addLine(0.5 * radius,		0.866 * radius,	halflen,
+		0.866 * radius,	0.5 * radius,		halflen);
+
+	addLine(0.866 * radius,	0.5 * radius,		halflen,
+		radius,			0.0,				halflen);
+
+	// SW quadrant
+	addLine(-radius,			0.0,				halflen,
+		-0.866 * radius,	-0.5 * radius,	halflen);
+
+	addLine(-0.866 * radius,	-0.5 * radius,	halflen,
+		-0.5 * radius,	-0.866 * radius,	halflen);
+
+	addLine(-0.5 * radius,	-0.866 * radius,	halflen,
+		0.0,				-radius,			halflen);
+
+	// SE quadrant
+	addLine(0.0,				-radius,			halflen,
+		0.5 * radius,		-0.866 * radius,	halflen);
+
+	addLine(0.5 * radius,		-0.866 * radius,	halflen,
+		0.866 * radius,	-0.5 * radius,	halflen);
+
+	addLine(0.866 * radius,	-0.5 * radius,	halflen,
+		radius,			0.0,				halflen);
+
+	// X/Y axis - Far
+
+	// NW quadrant
+	addLine(-radius,			0.0,				-halflen,
+		-0.866 * radius,	0.5 * radius,		-halflen);
+
+	addLine(-0.866 * radius,	0.5 * radius,		-halflen,
+		-0.5 * radius,	0.866 * radius,	-halflen);
+
+	addLine(-0.5 * radius,	0.866 * radius,	-halflen,
+		0.0,				radius,			-halflen);
+
+	// NE quadrant
+	addLine(0.0,				radius,			-halflen,
+		0.5 * radius,		0.866 * radius,	-halflen);
+
+	addLine(0.5 * radius,		0.866 * radius,	-halflen,
+		0.866 * radius,	0.5 * radius,		-halflen);
+
+	addLine(0.866 * radius,	0.5 * radius,		-halflen,
+		radius,			0.0,				-halflen);
+
+	// SW quadrant
+	addLine(-radius,			0.0,				-halflen,
+		-0.866 * radius,	-0.5 * radius,	-halflen);
+
+	addLine(-0.866 * radius,	-0.5 * radius,	-halflen,
+		-0.5 * radius,	-0.866 * radius,	-halflen);
+
+	addLine(-0.5 * radius,	-0.866 * radius,	-halflen,
+		0.0,				-radius,			-halflen);
+
+	// SE quadrant
+	addLine(0.0,				-radius,			-halflen,
+		0.5 * radius,		-0.866 * radius,	-halflen);
+
+	addLine(0.5 * radius,		-0.866 * radius,	-halflen,
+		0.866 * radius,	-0.5 * radius,	-halflen);
+
+	addLine(0.866 * radius,	-0.5 * radius,	-halflen,
+		radius,			0.0,				-halflen);
+
+	// X/Z axis
+
+	// NW quadrant
+	addLine(-radius,			0.0,	halflen,	
+		-0.866 * radius,	0.0,	(0.5 * radius) + halflen);
+
+	addLine(-0.866 * radius,	0.0,	(0.5 * radius) + halflen,
+		-0.5 * radius,	0.0,	(0.866 * radius) + halflen);
+
+	addLine(-0.5 * radius,	0.0,	(0.866 * radius) + halflen,
+		0.0,				0.0,	radius + halflen);
+
+	// NE quadrant
+	addLine(0.0,				0.0,	radius + halflen,
+		0.5 * radius,		0.0,	(0.866 * radius) + halflen);
+
+	addLine(0.5 * radius,		0.0,	(0.866 * radius) + halflen,
+		0.866 * radius,	0.0,	(0.5 * radius) + halflen);
+
+	addLine(0.866 * radius,	0.0,	(0.5 * radius) + halflen,
+		radius,			0.0,	halflen);
+
+	// SW quadrant
+	addLine(-radius,			0.0,	-halflen,	
+		-0.866 * radius,	0.0,	(-0.5 * radius) - halflen);
+
+	addLine(-0.866 * radius,	0.0,	(-0.5 * radius) - halflen,
+		-0.5 * radius,	0.0,	(-0.866 * radius) - halflen);
+
+	addLine(-0.5 * radius,	0.0,	(-0.866 * radius) - halflen,
+		0.0,				0.0,	-radius - halflen);
+
+	// SE quadrant
+	addLine(0.0,				0.0,	-radius - halflen,
+		0.5 * radius,		0.0,	(-0.866 * radius) - halflen);
+
+	addLine(0.5 * radius,		0.0,	(-0.866 * radius) - halflen,
+		0.866 * radius,	0.0,	(-0.5 * radius) - halflen);
+
+	addLine(0.866 * radius,	0.0,	(-0.5 * radius) - halflen,
+		radius,			0.0,	- halflen);
+
+	// Y/Z axis
+
+	// NW quadrant
+	addLine(0.0,	-radius,			halflen,	
+		0.0,	-0.866 * radius,	(0.5 * radius) + halflen);
+
+	addLine(0.0,	-0.866 * radius,	(0.5 * radius) + halflen,
+		0.0,	-0.5 * radius,	(0.866 * radius) + halflen);
+
+	addLine(0.0,	-0.5 * radius,	(0.866 * radius) + halflen,
+		0.0,	0.0,				radius + halflen);
+
+	// NE quadrant
+	addLine(0.0,	0.0,				radius + halflen,
+		0.0,	0.5 * radius,		(0.866 * radius) + halflen);
+
+	addLine(0.0,	0.5 * radius,		(0.866 * radius) + halflen,
+		0.0,	0.866 * radius,	(0.5 * radius) + halflen);
+
+	addLine(0.0,	0.866 * radius,	(0.5 * radius) + halflen,
+		0.0,	radius,			halflen);
+
+	// SW quadrant
+	addLine(0.0,	-radius,			-halflen,	
+		0.0,	-0.866 * radius,	(-0.5 * radius) - halflen);
+
+	addLine(0.0,	-0.866 * radius,	(-0.5 * radius) - halflen,
+		0.0,	-0.5 * radius,	(-0.866 * radius) - halflen);
+
+	addLine(0.0,	-0.5 * radius,	(-0.866 * radius) - halflen,
+		0.0,	0.0,				-radius - halflen);
+
+	// SE quadrant
+	addLine(0.0,	0.0,				-radius - halflen,
+		0.0,	0.5 * radius,		(-0.866 * radius) - halflen);
+
+	addLine(0.0,	0.5 * radius,		(-0.866 * radius) - halflen,
+		0.0,	0.866 * radius,	(-0.5 * radius) - halflen);
+
+	addLine(0.0,	0.866 * radius,	(-0.5 * radius) - halflen,
+		0.0,	radius,			-halflen);
+
+	// Side lines
+	addLine(-radius,	0.0,		-halflen,
+		-radius,	0.0,		halflen);
+
+	addLine(radius,	0.0,		-halflen,
+		radius,	0.0,		halflen);
+
+	addLine(0.0,		radius,	-halflen,
+		0.0,		radius,	halflen);
+
+	addLine(0.0,		-radius,	-halflen,
+		0.0,		-radius,	halflen);
+
+	draw();
+}
+//------------------------------------------------------------------------------------------------
+CylinderDebugObject::~CylinderDebugObject()
+{
+}
+//------------------------------------------------------------------------------------------------
+TriangleMeshDebugObject::TriangleMeshDebugObject(int vertex_count):DebugObject()
+{
+    _points.reserve(vertex_count); 
+    _points.resize(vertex_count); 
+}
+//------------------------------------------------------------------------------------------------
+void TriangleMeshDebugObject::beginDefinition()
+{
+}
+//------------------------------------------------------------------------------------------------
+void TriangleMeshDebugObject::setVertex(int index,const Ogre::Vector3& vertex)
+{
+    assert ((unsigned int)index < _points.size());
+	_points[index] = vertex;
+}
+//------------------------------------------------------------------------------------------------
+void TriangleMeshDebugObject::endDefinition()
+{
+	draw();
+}
+//------------------------------------------------------------------------------------------------
+TriangleMeshDebugObject::~TriangleMeshDebugObject()
+{
+}
+//------------------------------------------------------------------------------------------------
+RayDebugObject::RayDebugObject(const Ogre::Vector3& start,
+							   const Ogre::Vector3& direction,
+							   const Ogre::Real length):
+DebugObject()
+{
+
+	Ogre::Vector3 end;
+
+	if(length == Ogre::Math::POS_INFINITY)
+	{
+		end = (start + (direction.normalisedCopy() * 100000.0));
+	}
+	else
+	{
+		end = (start + (direction.normalisedCopy() * length));
+	}
+
+	addLine(start, end);
+
+	draw();
+} 
+void RayDebugObject::setDefinition(const Ogre::Vector3& start,
+								   const Ogre::Vector3& direction,
+								   const Ogre::Real length)
+{
+	clear();
+
+	Ogre::Vector3 end;
+
+	if(length == Ogre::Math::POS_INFINITY)
+	{
+		end = (start + (direction.normalisedCopy() * 100000.0));
+	}
+	else
+	{
+		end = (start + (direction.normalisedCopy() * length));
+	}
+
+	addLine(start, end);
+
+	draw();
+} 
+//------------------------------------------------------------------------------------------------
+RayDebugObject::~RayDebugObject()
+{
+}
+//------------------------------------------------------------------------------------------------
+
Index: code/branches/physics/src/ogreode/OgreOdeDebugObject.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeDebugObject.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeDebugObject.h	(revision 1919)
@@ -0,0 +1,110 @@
+#ifndef _OGREODEDEBUGOBJECT_H_
+#define _OGREODEDEBUGOBJECT_H_
+
+#include "OgreOdePreReqs.h"
+
+namespace OgreOde
+{
+    //------------------------------------------------------------------------------------------------
+	class _OgreOdeExport DebugLines:public Ogre::SimpleRenderable
+	{
+	public:
+		DebugLines(void);
+		~DebugLines(void);
+
+		void addLine(const Ogre::Vector3 &start,const Ogre::Vector3 &end)
+		{
+			clear();
+
+			_points.push_back(start);
+			_points.push_back(end);
+		}
+		void addLine(Ogre::Real start_x, Ogre::Real start_y, Ogre::Real start_z, 
+            Ogre::Real end_x, Ogre::Real end_y, Ogre::Real end_z)
+		{
+			addLine(Ogre::Vector3(start_x,start_y,start_z),Ogre::Vector3(end_x,end_y,end_z));
+		}
+		void draw();
+		void clear();
+
+		Ogre::Real getSquaredViewDepth(const Ogre::Camera *cam) const;
+		Ogre::Real getBoundingRadius(void) const;
+
+	protected:
+
+		Vector3Array _points;
+		bool _drawn;
+
+		static bool _materials_created;
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport DebugObject:public DebugLines
+	{
+	public:
+		enum Mode
+		{
+			Mode_Unknown,
+			Mode_Enabled,
+			Mode_Disabled,
+			Mode_Static
+		};
+
+	public:
+        DebugObject(DebugObject::Mode mode = DebugObject::Mode_Enabled);
+		virtual ~DebugObject();
+
+		void setMode(DebugObject::Mode mode);
+
+	protected:
+		DebugObject::Mode _mode;
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport BoxDebugObject:public DebugObject
+	{
+	public:
+		BoxDebugObject(const Ogre::Vector3& size);
+		virtual ~BoxDebugObject();
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport SphereDebugObject:public DebugObject
+	{
+	public:
+		SphereDebugObject(Ogre::Real radius);
+		virtual ~SphereDebugObject();
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport CapsuleDebugObject:public DebugObject
+	{
+	public:
+		CapsuleDebugObject(Ogre::Real radius, Ogre::Real length);
+		virtual ~CapsuleDebugObject();
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport CylinderDebugObject:public DebugObject
+	{
+	public:
+		CylinderDebugObject(Ogre::Real radius, Ogre::Real length);
+		virtual ~CylinderDebugObject();
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport TriangleMeshDebugObject:public DebugObject
+	{
+	public:
+		TriangleMeshDebugObject(int vertex_count);
+		virtual ~TriangleMeshDebugObject();
+
+		void beginDefinition();
+		void setVertex(int index, const Ogre::Vector3& vertex);
+		void endDefinition();
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport RayDebugObject:public DebugObject
+	{
+	public:
+		RayDebugObject(const Ogre::Vector3& start,const Ogre::Vector3& direction,const Ogre::Real length);
+		void setDefinition(const Ogre::Vector3& start,const Ogre::Vector3& direction,const Ogre::Real length);
+		virtual ~RayDebugObject();
+	};
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdeEigenSolver.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeEigenSolver.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeEigenSolver.cpp	(revision 1919)
@@ -0,0 +1,400 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeEigenSolver.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+void EigenSolver::DecrSortEigenStuff3 ()
+{
+	Tridiagonal3();
+	QLAlgorithm();
+	DecreasingSort();
+	GuaranteeRotation();
+}
+
+void EigenSolver::Tridiagonal3 ()
+{
+	const Ogre::Real fM00 = m_kMat[0][0];
+   Ogre::Real fM01 = m_kMat[0][1];
+	Real fM02 = m_kMat[0][2];
+	const Ogre::Real fM11 = m_kMat[1][1];
+	const Ogre::Real fM12 = m_kMat[1][2];
+	const Ogre::Real fM22 = m_kMat[2][2];
+
+	m_afDiag[0] = fM00;
+	m_afSubd[2] = (Real)0.0;
+	if ( fM02 != (Real)0.0 )
+	{
+		const Ogre::Real fLength = sqrtf(fM01*fM01+fM02*fM02);
+		const Ogre::Real fInvLength = ((Real)1.0)/fLength;
+		fM01 *= fInvLength;
+		fM02 *= fInvLength;
+		const Ogre::Real fQ = ((Real)2.0)*fM01*fM12+fM02*(fM22-fM11);
+		m_afDiag[1] = fM11+fM02*fQ;
+		m_afDiag[2] = fM22-fM02*fQ;
+		m_afSubd[0] = fLength;
+		m_afSubd[1] = fM12-fM01*fQ;
+		m_kMat[0][0] = (Real)1.0;
+		m_kMat[0][1] = (Real)0.0;
+		m_kMat[0][2] = (Real)0.0;
+		m_kMat[1][0] = (Real)0.0;
+		m_kMat[1][1] = fM01;
+		m_kMat[1][2] = fM02;
+		m_kMat[2][0] = (Real)0.0;
+		m_kMat[2][1] = fM02;
+		m_kMat[2][2] = -fM01;
+	}
+	else
+	{
+		m_afDiag[1] = fM11;
+		m_afDiag[2] = fM22;
+		m_afSubd[0] = fM01;
+		m_afSubd[1] = fM12;
+		m_kMat[0][0] = (Real)1.0;
+		m_kMat[0][1] = (Real)0.0;
+		m_kMat[0][2] = (Real)0.0;
+		m_kMat[1][0] = (Real)0.0;
+		m_kMat[1][1] = (Real)1.0;
+		m_kMat[1][2] = (Real)0.0;
+		m_kMat[2][0] = (Real)0.0;
+		m_kMat[2][1] = (Real)0.0;
+		m_kMat[2][2] = (Real)1.0;
+	}
+}
+
+bool EigenSolver::QLAlgorithm ()
+{
+	const int iMaxIter = 32;
+
+	for (int i0 = 0; i0 < m_iSize; i0++)
+	{
+		int i1;
+		for (i1 = 0; i1 < iMaxIter; i1++)
+		{
+			int i2;
+			for (i2 = i0; i2 <= m_iSize-2; i2++)
+			{
+				Real fTmp = fabs(m_afDiag[i2]) + fabs(m_afDiag[i2+1]);
+				if ( fabs(m_afSubd[i2]) + fTmp == fTmp ) break;
+			}
+			if ( i2 == i0 ) break;
+
+			Real fG = (m_afDiag[i0+1] - m_afDiag[i0])/(((Real)2.0) * m_afSubd[i0]);
+			Real fR = sqrtf(fG*fG+(Real)1.0);
+			if ( fG < (Real)0.0 ) fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG-fR);
+			else fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG+fR);
+			Real fSin = (Real)1.0, fCos = (Real)1.0, fP = (Real)0.0;
+			for (int i3 = i2-1; i3 >= i0; i3--)
+			{
+				Real fF = fSin*m_afSubd[i3];
+               Ogre::Real fB = fCos*m_afSubd[i3];
+	            if ( fabs(fF) >= fabs(fG) )
+		        {
+			        fCos = fG/fF;
+				    fR = sqrtf(fCos*fCos+(Real)1.0);
+					m_afSubd[i3+1] = fF*fR;
+                    fSin = ((Real)1.0)/fR;
+	                fCos *= fSin;
+		        }
+			    else
+				{
+					fSin = fF/fG;
+					fR = sqrtf(fSin*fSin+(Real)1.0);
+					m_afSubd[i3+1] = fG*fR;
+					fCos = ((Real)1.0)/fR;
+					fSin *= fCos;
+				}
+				fG = m_afDiag[i3+1]-fP;
+                fR = (m_afDiag[i3]-fG)*fSin+((Real)2.0)*fB*fCos;
+	            fP = fSin*fR;
+		        m_afDiag[i3+1] = fG+fP;
+			    fG = fCos*fR-fB;
+
+				for (int i4 = 0; i4 < m_iSize; i4++)
+				{
+					fF = m_kMat[i4][i3+1];
+                    m_kMat[i4][i3+1] = fSin*m_kMat[i4][i3]+fCos*fF;
+	                m_kMat[i4][i3] = fCos*m_kMat[i4][i3]-fSin*fF;
+		        }
+			}
+			m_afDiag[i0] -= fP;
+			m_afSubd[i0] = fG;
+			m_afSubd[i2] = (Real)0.0;
+		}
+		if ( i1 == iMaxIter ) return false;
+	}
+	return true;
+}
+
+void EigenSolver::DecreasingSort ()
+{
+	// sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1]
+	for (int i0 = 0, i1; i0 <= m_iSize-2; i0++)
+	{
+		// locate maximum eigenvalue
+		i1 = i0;
+		Real fMax = m_afDiag[i1];
+		int i2;
+		for (i2 = i0+1; i2 < m_iSize; i2++)
+		{
+			if ( m_afDiag[i2] > fMax )
+			{
+				i1 = i2;
+				fMax = m_afDiag[i1];
+			}
+		}
+
+		if ( i1 != i0 )
+		{
+			// swap eigenvalues
+			m_afDiag[i1] = m_afDiag[i0];
+			m_afDiag[i0] = fMax;
+
+			// swap eigenvectors
+			for (i2 = 0; i2 < m_iSize; i2++)
+			{
+				Real fTmp = m_kMat[i2][i0];
+				m_kMat[i2][i0] = m_kMat[i2][i1];
+				m_kMat[i2][i1] = fTmp;
+				m_bIsRotation = !m_bIsRotation;
+			}
+		}
+	}
+}
+
+void EigenSolver::GuaranteeRotation ()
+{
+	if ( !m_bIsRotation )
+	{
+		// change sign on the first column
+		for (int iRow = 0; iRow < m_iSize; iRow++) 
+            m_kMat[iRow][0] = -m_kMat[iRow][0];
+	}
+}
+
+void EigenSolver::orthogonalLineFit(unsigned int vertex_count, const Ogre::Vector3* vertices,Vector3& origin,Vector3& direction)
+{
+	unsigned int i;
+
+    // compute average of points
+	origin = vertices[0];
+    for(i = 1; i < vertex_count; ++i) 
+        origin += vertices[i];
+
+	const Ogre::Real fInvQuantity = 1.0 / vertex_count;
+	origin *= fInvQuantity;
+
+	// compute sums of products
+	Real fSumXX = 0.0, fSumXY = 0.0, fSumXZ = 0.0;
+   Ogre::Real fSumYY = 0.0, fSumYZ = 0.0, fSumZZ = 0.0;
+	for (i = 0; i < vertex_count; i++) 
+	{
+		const Ogre::Vector3 kDiff (vertices[i] - origin);
+	    fSumXX += kDiff.x*kDiff.x;
+        fSumXY += kDiff.x*kDiff.y;
+		fSumXZ += kDiff.x*kDiff.z;
+	    fSumYY += kDiff.y*kDiff.y;
+        fSumYZ += kDiff.y*kDiff.z;
+		fSumZZ += kDiff.z*kDiff.z;
+	}
+	fSumXX *= fInvQuantity;
+	fSumXY *= fInvQuantity;
+	fSumXZ *= fInvQuantity;
+	fSumYY *= fInvQuantity;
+	fSumYZ *= fInvQuantity;
+	fSumZZ *= fInvQuantity;
+
+	// setup the eigensolver
+	EigenSolver kES(3);
+	kES(0,0) = fSumYY+fSumZZ;
+	kES(0,1) = -fSumXY;
+	kES(0,2) = -fSumXZ;
+	kES(1,0) = kES(0,1);
+	kES(1,1) = fSumXX+fSumZZ;
+	kES(1,2) = -fSumYZ;
+	kES(2,0) = kES(0,2);
+	kES(2,1) = kES(1,2);
+    kES(2,2) = fSumXX+fSumYY;
+
+	// compute eigenstuff, smallest eigenvalue is in last position
+	kES.DecrSortEigenStuff3();
+
+    // unit-length direction for best-fit line
+	kES.GetEigenvector(2,direction);
+}
+
+Real EigenSolver::SqrDistance(const Ogre::Vector3& rkPoint,const Ogre::Vector3& origin,const Ogre::Vector3& direction)
+{
+	Vector3 kDiff(rkPoint - origin);
+    const Ogre::Real fSqrLen = direction.squaredLength();
+	const Ogre::Real fT = kDiff.dotProduct(direction) / fSqrLen;
+
+    kDiff -= fT*direction;
+
+	return kDiff.squaredLength();
+}
+
+void EigenSolver::GenerateOrthonormalBasis (Vector3& rkU, Ogre::Vector3& rkV, Ogre::Vector3& rkW, bool bUnitLengthW)
+{
+	if ( !bUnitLengthW ) rkW.normalise();
+
+	Real fInvLength;
+
+	if ( fabs(rkW[0]) >= fabs(rkW[1]) )
+	{
+		// W.x or W.z is the largest magnitude component, swap them
+		fInvLength = 1.0 / sqrtf(rkW[0]*rkW[0] + rkW[2]*rkW[2]);
+
+	    rkU[0] = -rkW[2]*fInvLength;
+        rkU[1] = (Real)0.0;
+		rkU[2] = +rkW[0]*fInvLength;
+	}
+    else
+	{
+        // W.y or W.z is the largest magnitude component, swap them
+		fInvLength = 1.0 / sqrtf(rkW[1]*rkW[1] + rkW[2]*rkW[2]);
+
+	    rkU[0] = (Real)0.0;
+        rkU[1] = +rkW[2]*fInvLength;
+		rkU[2] = -rkW[1]*fInvLength;
+	}
+
+	rkV = rkW.crossProduct(rkU);
+}
+
+EigenSolver::EigenSolver(int iSize)
+{
+	assert( iSize >= 2 );
+    m_iSize = iSize;
+	m_afDiag = new Ogre::Real[m_iSize];
+    m_afSubd = new Ogre::Real[m_iSize];
+
+	// set according to the parity of the number of Householder reflections
+	m_bIsRotation = ((iSize % 2) == 0);
+}
+
+Ogre::Real& EigenSolver::operator() (int iRow, int iCol)
+{
+	return m_kMat[iRow][iCol];
+}
+
+EigenSolver::~EigenSolver()
+{
+    delete[] m_afSubd;
+	delete[] m_afDiag;
+}
+
+void EigenSolver::GetEigenvector (int i, Ogre::Vector3& rkV) const
+{
+	assert( m_iSize == 3 );
+	if ( m_iSize == 3 )
+	{
+		for (int iRow = 0; iRow < m_iSize; iRow++) 
+            rkV[iRow] = m_kMat[iRow][i];
+	}
+	else
+	{
+	    rkV = Ogre::Vector3::ZERO;
+    }
+}
+
+void EigenSolver::GaussPointsFit(unsigned int iQuantity,const Ogre::Vector3* akPoint,Vector3 &rkCenter,Vector3 akAxis[3],Real afExtent[3])
+{
+    // compute mean of points
+    rkCenter = akPoint[0];
+    unsigned int i;
+    for (i = 1; i < iQuantity; i++)
+        rkCenter += akPoint[i];
+    const Ogre::Real fInvQuantity = ((Real)1.0)/iQuantity;
+    rkCenter *= fInvQuantity;
+
+    // compute covariances of points
+   Ogre::Real fSumXX = (Real)0.0, fSumXY = (Real)0.0, fSumXZ = (Real)0.0;
+   Ogre::Real fSumYY = (Real)0.0, fSumYZ = (Real)0.0, fSumZZ = (Real)0.0;
+    for (i = 0; i < iQuantity; i++)
+    {
+        const Ogre::Vector3 kDiff (akPoint[i] - rkCenter);
+        fSumXX += kDiff.x*kDiff.x;
+        fSumXY += kDiff.x*kDiff.y;
+        fSumXZ += kDiff.x*kDiff.z;
+        fSumYY += kDiff.y*kDiff.y;
+        fSumYZ += kDiff.y*kDiff.z;
+        fSumZZ += kDiff.z*kDiff.z;
+    }
+    fSumXX *= fInvQuantity;
+    fSumXY *= fInvQuantity;
+    fSumXZ *= fInvQuantity;
+    fSumYY *= fInvQuantity;
+    fSumYZ *= fInvQuantity;
+    fSumZZ *= fInvQuantity;
+
+    // compute eigenvectors for covariance matrix
+    EigenSolver kES(3);
+    kES(0,0) = fSumXX;
+    kES(0,1) = fSumXY;
+    kES(0,2) = fSumXZ;
+    kES(1,0) = fSumXY;
+    kES(1,1) = fSumYY;
+    kES(1,2) = fSumYZ;
+    kES(2,0) = fSumXZ;
+    kES(2,1) = fSumYZ;
+    kES(2,2) = fSumZZ;
+    kES.IncrSortEigenStuff3();
+
+    for (i = 0; i < 3; i++)
+    {
+        afExtent[i] = kES.GetEigenvalue(i);
+        kES.GetEigenvector(i,akAxis[i]);
+    }
+}
+
+Real EigenSolver::GetEigenvalue (int i) const
+{
+    return m_afDiag[i];
+}
+
+void EigenSolver::IncrSortEigenStuff3 ()
+{
+    Tridiagonal3();
+    QLAlgorithm();
+    IncreasingSort();
+    GuaranteeRotation();
+}
+
+void EigenSolver::IncreasingSort ()
+{
+    // sort eigenvalues in increasing order, e[0] <= ... <= e[iSize-1]
+    for (int i0 = 0, i1; i0 <= m_iSize-2; i0++)
+    {
+        // locate minimum eigenvalue
+        i1 = i0;
+       Ogre::Real fMin = m_afDiag[i1];
+        int i2;
+        for (i2 = i0+1; i2 < m_iSize; i2++)
+        {
+            if ( m_afDiag[i2] < fMin )
+            {
+                i1 = i2;
+                fMin = m_afDiag[i1];
+            }
+        }
+
+        if ( i1 != i0 )
+        {
+            // swap eigenvalues
+            m_afDiag[i1] = m_afDiag[i0];
+            m_afDiag[i0] = fMin;
+
+            // swap eigenvectors
+            for (i2 = 0; i2 < m_iSize; i2++)
+            {
+               Ogre::Real fTmp = m_kMat[i2][i0];
+                m_kMat[i2][i0] = m_kMat[i2][i1];
+                m_kMat[i2][i1] = fTmp;
+                m_bIsRotation = !m_bIsRotation;
+            }
+        }
+    }
+}
Index: code/branches/physics/src/ogreode/OgreOdeEigenSolver.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeEigenSolver.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeEigenSolver.h	(revision 1919)
@@ -0,0 +1,68 @@
+#ifndef _OGREODEEIGENSOLVER_H_
+#define _OGREODEEIGENSOLVER_H_
+
+#include "OgreOdePreReqs.h"
+
+namespace OgreOde 
+{
+	class _OgreOdeExport EigenSolver
+	{
+	public:
+		EigenSolver(int iSize);
+		~EigenSolver();
+
+		// set the matrix for eigensolving
+		Ogre::Real& operator() (int iRow, int iCol);
+
+		// Get the eigenresults (eigenvectors are columns of eigenmatrix).  The
+		// GetEigenvector calls involving Vector2, Ogre::Vector3, and Vector4 should
+		// only be called if you know that the eigenmatrix is of the appropriate
+		// size.
+	    void GetEigenvector (int i, Ogre::Vector3& rkV) const;
+		Ogre::Real GetEigenvalue (int i) const;
+
+		// solve eigensystem, use decreasing sort on eigenvalues
+	    void DecrSortEigenStuff3 ();
+		void IncrSortEigenStuff3 ();
+
+		static void GenerateOrthonormalBasis (Ogre::Vector3& rkU, Ogre::Vector3& rkV, Ogre::Vector3& rkW, bool bUnitLengthW);
+		static void orthogonalLineFit(unsigned int vertex_count, const Ogre::Vector3* vertices, Ogre::Vector3& origin, Ogre::Vector3& direction);
+		static Ogre::Real SqrDistance(const Ogre::Vector3& rkPoint,const Ogre::Vector3& origin,const Ogre::Vector3& direction);
+		static void GaussPointsFit(unsigned int iQuantity,const Ogre::Vector3* akPoint, Ogre::Vector3 &rkCenter, Ogre::Vector3 akAxis[3], Ogre::Real afExtent[3]);
+
+	protected:
+		int m_iSize;
+		Ogre::Matrix3 m_kMat;
+		Ogre::Real* m_afDiag;
+		Ogre::Real* m_afSubd;
+
+		// For odd size matrices, the Householder reduction involves an odd
+		// number of reflections.  The product of these is a reflection.  The
+		// QL algorithm uses rotations for further reductions.  The final
+		// orthogonal matrix whose columns are the eigenvectors is a reflection,
+		// so its determinant is -1.  For even size matrices, the Householder
+		// reduction involves an even number of reflections whose product is a
+		// rotation.  The final orthogonal matrix has determinant +1.  Many
+		// algorithms that need an eigendecomposition want a rotation matrix.
+		// We want to guarantee this is the case, so m_bRotation keeps track of
+		// this.  The DecrSort and IncrSort further complicate the issue since
+		// they swap columns of the orthogonal matrix, causing the matrix to
+		// toggle between rotation and reflection.  The value m_bRotation must
+		// be toggled accordingly.
+		bool m_bIsRotation;
+		void GuaranteeRotation ();
+
+		// Householder reduction to tridiagonal form
+	    void Tridiagonal3 ();
+  
+		// QL algorithm with implicit shifting, applies to tridiagonal matrices
+		bool QLAlgorithm ();
+
+		// sort eigenvalues from largest to smallest
+		void DecreasingSort ();
+
+		void IncreasingSort ();
+	};
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdeEntityInformer.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeEntityInformer.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeEntityInformer.cpp	(revision 1919)
@@ -0,0 +1,773 @@
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeEntityInformer.h"
+#include "OgreOdeMaintainedList.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeGeometry.h"
+#include "OgreOdeMass.h"
+#include "OgreOdeEigenSolver.h"
+
+#include "OgreOdeTriangleMeshDataManager.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeEntityInformer.h"
+#include "OgreOdeMaintainedList.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeGeometry.h"
+#include "OgreOdeMass.h"
+#include "OgreOdeEigenSolver.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+//------------------------------------------------------------------------------------------------
+void EntityInformer::addVertexData(const VertexData *vertex_data,
+                                   const VertexData *blended_data,
+                                   const Mesh::IndexMap *indexMap)
+{
+	if (!vertex_data) 
+        return;
+
+	const VertexData *data = (blended_data) ? blended_data: vertex_data;
+
+	const unsigned int prev_size = _vertex_count;
+    _vertex_count += (unsigned int)data->vertexCount;
+
+    Ogre::Vector3* tmp_vert = new Ogre::Vector3[_vertex_count];
+	if (_vertices)
+	{
+		memcpy(tmp_vert,_vertices,sizeof(Vector3) * prev_size);
+		delete[] _vertices;
+	}
+	_vertices = tmp_vert;
+
+	// Get the positional buffer element
+    {	
+        const Ogre::VertexElement* posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);			
+        Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource());
+        const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
+
+	    unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
+	    float* pReal;
+        Ogre::Vector3 * curVertices = &_vertices[prev_size];
+        const unsigned int vertexCount = (unsigned int)data->vertexCount;
+	    for(unsigned int j = 0; j < vertexCount; ++j)
+	    {
+		    posElem->baseVertexPointerToElement(vertex, &pReal);
+            vertex += vSize;
+
+		    curVertices->x = (*pReal++);
+		    curVertices->y = (*pReal++);
+		    curVertices->z = (*pReal++);
+
+		    *curVertices = _transform * (*curVertices);
+            
+            curVertices++;
+        }
+	    vbuf->unlock();
+    }
+
+	// Get the bone index element
+	if (_entity && _entity->hasSkeleton())
+	{
+
+        Ogre::MeshPtr mesh = _entity->getMesh ();
+
+		const Ogre::VertexElement* bneElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_BLEND_INDICES);
+		assert (bneElem);
+		{
+            Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(bneElem->getSource());
+            const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
+			unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
+
+			unsigned char* pBone;
+
+            if (!_bone_mapping)
+                _bone_mapping = new BoneMapping();	
+            BoneMapping::iterator i;
+
+            Ogre::Vector3 * curVertices = &_vertices[prev_size];
+            
+            const unsigned int vertexCount = (unsigned int)vertex_data->vertexCount;
+			for(unsigned int j = 0; j < vertexCount; ++j)
+			{
+				bneElem->baseVertexPointerToElement(vertex, &pBone);
+                vertex += vSize;
+               
+                const unsigned char currBone = (indexMap) ? (*indexMap)[*pBone] : *pBone;
+				i = _bone_mapping->find (currBone);
+				Vector3Array* l = 0;
+				if (i == _bone_mapping->end())
+				{
+					l = new Vector3Array;
+					_bone_mapping->insert(BoneMappingKey(currBone, l));
+				}						
+				else 
+                {
+                    l = i->second;
+                }
+
+				l->push_back(*curVertices);
+
+                curVertices++;
+			}
+			vbuf->unlock();
+		}
+	}
+}
+
+
+//------------------------------------------------------------------------------------------------
+void EntityInformer::addIndexData(IndexData *data, const unsigned int offset)
+{
+    const unsigned int prev_size = _index_count;
+    _index_count += (unsigned int)data->indexCount;
+
+	TriangleIndex* tmp_ind = new TriangleIndex[_index_count];
+	if (_indices)
+	{
+		memcpy (tmp_ind, _indices, sizeof(unsigned int) * prev_size);
+		delete[] _indices;
+	}
+	_indices = tmp_ind;
+
+	const unsigned int numTris = (unsigned int) data->indexCount / 3;
+	HardwareIndexBufferSharedPtr ibuf = data->indexBuffer;	
+	const bool use32bitindexes = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT);
+    unsigned int index_offset = prev_size;
+
+	if (use32bitindexes) 
+    {
+        const unsigned int* pInt = static_cast<unsigned int*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
+        for(unsigned int k = 0; k < numTris; ++k)
+        {
+            _indices[index_offset ++] = offset + *pInt++;
+            _indices[index_offset ++] = offset + *pInt++;
+            _indices[index_offset ++] = offset + *pInt++;
+        }
+        ibuf->unlock();
+    }
+	else 
+    {
+        const unsigned short* pShort = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
+		for(unsigned int k = 0; k < numTris; ++k)
+        {
+            _indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
+            _indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
+            _indices[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
+        }
+        ibuf->unlock();
+    }
+
+}
+//------------------------------------------------------------------------------------------------
+void EntityInformer::addEntity(Entity *entity,const Matrix4 &transform)
+{
+	// Each entity added need to reset size and radius
+	// next time getRadius and getSize are asked, they're computed.
+	_size  = Ogre::Vector3(-1,-1,-1);
+	_radius = -1;
+
+	_entity = entity;
+	_node = (SceneNode*)(_entity->getParentNode());
+	_transform = transform;
+
+	const bool isSkeletonAnimated = _entity->hasSkeleton();
+	//const bool isHWanimated = isSkeletonAnimated && entity->isHardwareAnimationEnabled();
+	if (isSkeletonAnimated)
+	{
+		_entity->addSoftwareAnimationRequest(false);
+		_entity->_updateAnimation();
+	}
+
+
+	if (_entity->getMesh()->sharedVertexData)
+	{
+		if (!isSkeletonAnimated)
+			addVertexData (_entity->getMesh()->sharedVertexData);
+		else
+			addVertexData (_entity->getMesh()->sharedVertexData, 
+			_entity->_getSkelAnimVertexData(),
+			&_entity->getMesh()->sharedBlendIndexToBoneIndexMap); 
+	}
+
+	for(unsigned int i = 0;i < _entity->getNumSubEntities();++i)
+	{
+		SubMesh *sub_mesh = _entity->getSubEntity(i)->getSubMesh();
+
+		if (!sub_mesh->useSharedVertices)
+		{
+			addIndexData(sub_mesh->indexData,_vertex_count);
+
+			if (!isSkeletonAnimated)
+				addVertexData (sub_mesh->vertexData);
+			else
+				addVertexData (sub_mesh->vertexData, 
+				_entity->getSubEntity(i)->_getSkelAnimVertexData(),
+				&sub_mesh->blendIndexToBoneIndexMap); 
+		}
+		else 
+		{
+			addIndexData (sub_mesh->indexData);
+		}
+
+	}
+
+	if (isSkeletonAnimated) 
+		_entity->removeSoftwareAnimationRequest(false);
+}
+//------------------------------------------------------------------------------------------------
+void EntityInformer::addMesh(const MeshPtr &mesh, const Matrix4 &transform)
+{
+	// Each entity added need to reset size and radius
+	// next time getRadius and getSize are asked, they're computed.
+	_size  = Ogre::Vector3(-1,-1,-1);
+	_radius = -1;
+
+	//_entity = entity;
+	//_node = (SceneNode*)(_entity->getParentNode());
+	_transform = transform;
+
+	if (mesh->hasSkeleton ())
+		Ogre::LogManager::getSingleton().logMessage("EntityInformer::addMesh : Mesh " + mesh->getName () + " as skeleton but added to trimesh non animated");
+// 		OGRE_EXCEPT(1, "Mesh " + mesh->getName () + " as skeleton but added to trimesh non animated", 
+// 					"EntityInformer::addMesh");
+
+	if (mesh->sharedVertexData)
+	{
+		addVertexData (mesh->sharedVertexData);
+	}
+
+	for(unsigned int i = 0;i < mesh->getNumSubMeshes();++i)
+	{
+		SubMesh *sub_mesh = mesh->getSubMesh(i);
+
+		if (!sub_mesh->useSharedVertices)
+		{
+			addIndexData(sub_mesh->indexData, _vertex_count);
+			addVertexData (sub_mesh->vertexData);
+		}
+		else 
+		{
+			addIndexData (sub_mesh->indexData);
+		}
+
+	}
+}
+//------------------------------------------------------------------------------------------------
+EntityInformer::EntityInformer(Entity *entity,const Matrix4 &transform) :
+	_vertices (0),
+	_indices (0),
+	_vertex_count (0),
+	_index_count (0),
+	_size (Vector3(-1,-1,-1)),
+	_center (Vector3(-1,-1,-1)),
+	_radius (-1),
+	_bone_mapping (0)
+{
+	addEntity(entity, transform);	
+}
+//------------------------------------------------------------------------------------------------
+EntityInformer::EntityInformer() :
+		_vertices (0),
+		_indices (0),
+		_vertex_count (0),
+		_index_count (0),
+		_size (Vector3(-1,-1,-1)),
+		_center (Vector3(-1,-1,-1)),
+		_radius (-1),
+        _bone_mapping (0)
+{
+	 
+}
+//------------------------------------------------------------------------------------------------
+Real EntityInformer::getRadius()
+{
+	if (_radius == (-1))
+	{
+		getSize();
+		_radius = (std::max(_size.x,std::max(_size.y,_size.z)) * 0.5);
+	}
+	return _radius;
+}
+//------------------------------------------------------------------------------------------------
+Vector3 EntityInformer::getSize()
+{
+    const unsigned int vCount = getVertexCount();
+	if (_size == Ogre::Vector3(-1,-1,-1) && vCount > 0)
+	{
+
+		const Ogre::Vector3 * const v = getVertices();
+
+        Ogre::Vector3 vmin(v[0]);
+        Ogre::Vector3 vmax(v[0]);
+
+		for(unsigned int j = 1; j < vCount; j++)
+		{
+			vmin.x = std::min(vmin.x, v[j].x);
+			vmin.y = std::min(vmin.y, v[j].y);
+			vmin.z = std::min(vmin.z, v[j].z);
+
+			vmax.x = std::max(vmax.x, v[j].x);
+			vmax.y = std::max(vmax.y, v[j].y);
+			vmax.z = std::max(vmax.z, v[j].z);
+		}
+
+		_size.x = vmax.x - vmin.x;
+		_size.y = vmax.y - vmin.y;
+		_size.z = vmax.z - vmin.z;
+
+		_center.x = vmin.x + _size.x * 0.5;
+		_center.y = vmin.y + _size.y * 0.5;
+		_center.z = vmin.z + _size.z * 0.5;
+
+	}
+
+	return _size;
+}
+//------------------------------------------------------------------------------------------------
+Vector3 EntityInformer::getCenter()
+{
+	const unsigned int vCount = getVertexCount();
+	if (_center == Ogre::Vector3(-1,-1,-1) && vCount > 0)
+	{
+		getSize();
+	}
+
+	return _center;
+}
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3* EntityInformer::getVertices()
+{
+	return _vertices;
+}
+//------------------------------------------------------------------------------------------------
+unsigned int EntityInformer::getVertexCount()
+{
+	return _vertex_count;
+}
+//------------------------------------------------------------------------------------------------
+const TriangleIndex* EntityInformer::getIndices()
+{
+	return _indices;
+}
+//------------------------------------------------------------------------------------------------
+unsigned int EntityInformer::getIndexCount()
+{
+	return _index_count;
+}
+//------------------------------------------------------------------------------------------------
+Body* EntityInformer::createSingleDynamicSphere(Real mass, World *world, Space* space)
+{
+	const Ogre::Real rad = getRadius();
+
+	assert((rad > 0.0) && 
+        ("Sphere radius must be greater than zero"));
+
+	Body* body = new Body(world, "OgreOde::Body_" + _entity->getName());
+	body->setMass(SphereMass(mass, rad));
+
+	SphereGeometry* geom = new SphereGeometry(rad, world, space);
+	geom->setBody(body);
+
+	body->setPosition(_node->_getDerivedPosition());
+	body->setOrientation(_node->_getDerivedOrientation());
+
+	_node->attachObject(body);
+
+	return body;
+}
+//------------------------------------------------------------------------------------------------
+Body* EntityInformer::createSingleDynamicBox(Real mass, World *world, Space* space)
+{
+	const Ogre::Vector3 sz = getSize();
+
+	assert((sz.x > 0.0) && (sz.y > 0.0) && (sz.y > 0.0) && 
+        ("Size of box must be greater than zero on all axes"));
+
+	Body* body = new Body(world, "OgreOde::Body_" + _node->getName());
+	body->setMass(BoxMass(mass,sz));
+
+	BoxGeometry* geom = new BoxGeometry(sz, world, space);
+	geom->setBody(body);
+
+	body->setPosition(_node->_getDerivedPosition());
+	body->setOrientation(_node->_getDerivedOrientation());
+
+	_node->attachObject(body);
+
+	return body;
+}
+//------------------------------------------------------------------------------------------------
+TriangleMeshGeometry* EntityInformer::createStaticTriangleMesh(World *world, Space* space)
+{
+	assert(_vertex_count && (_index_count >= 6) && 
+        ("Mesh must have some vertices and at least 6 indices (2 triangles)"));
+
+	return new TriangleMeshGeometry(_vertices, _vertex_count,_indices, _index_count, world, space);
+}
+//------------------------------------------------------------------------------------------------
+BoxGeometry* EntityInformer::createSingleStaticBox(World *world, Space* space)
+{
+	BoxGeometry* geom = new BoxGeometry(getSize(), world, space);
+
+	geom->setPosition(_node->_getDerivedPosition());
+	geom->setOrientation(_node->_getDerivedOrientation());
+
+	return geom;
+}
+//------------------------------------------------------------------------------------------------
+bool EntityInformer::getBoneVertices(unsigned char bone, unsigned int &vertex_count, Ogre::Vector3* &vertices)
+{
+	BoneMapping::iterator i = _bone_mapping->find(bone);
+	
+    if (i == _bone_mapping->end()) 
+        return false;
+
+	if (i->second->empty()) 
+        return false;
+
+    vertex_count = (unsigned int) i->second->size() + 1;
+
+	vertices = new Ogre::Vector3[vertex_count];
+	vertices[0] = _entity->_getParentNodeFullTransform() * 
+            _entity->getSkeleton()->getBone(bone)->_getDerivedPosition();
+
+	unsigned int o = 1;
+	for(Vector3Array::iterator j = i->second->begin();
+        j != i->second->end(); ++j,++o) 
+    {
+        vertices[o] = (*j);
+    }       
+	return true;
+}
+//------------------------------------------------------------------------------------------------
+BoxGeometry* EntityInformer::createAlignedBox(unsigned char bone, World *world, Space* space)
+{
+	unsigned int vertex_count;
+	Vector3* vertices;
+	if (!getBoneVertices(bone, vertex_count, vertices)) 
+        return 0;
+
+	Vector3 min_vec(vertices[0]);
+	Vector3 max_vec(vertices[0]);
+
+	for(unsigned int j = 1; j < vertex_count ;j++)
+	{
+		min_vec.x = std::min(min_vec.x,vertices[j].x);
+		min_vec.y = std::min(min_vec.y,vertices[j].y);
+		min_vec.z = std::min(min_vec.z,vertices[j].z);
+
+		max_vec.x = std::max(max_vec.x,vertices[j].x);
+		max_vec.y = std::max(max_vec.y,vertices[j].y);
+		max_vec.z = std::max(max_vec.z,vertices[j].z);
+	}
+    const Ogre::Vector3 maxMinusMin(max_vec - min_vec);
+    BoxGeometry* box = new BoxGeometry(maxMinusMin, world, space);
+
+    const Ogre::Vector3 pos(min_vec.x + (maxMinusMin.x * 0.5),
+                      min_vec.y + (maxMinusMin.y * 0.5),
+                      min_vec.z + (maxMinusMin.z * 0.5));
+
+	box->setPosition(pos);
+
+	delete[] vertices;
+
+	return box;
+}
+//------------------------------------------------------------------------------------------------
+BoxGeometry* EntityInformer::createOrientedBox(unsigned char bone, World *world, Space* space)
+{
+
+#define TESTOOB
+#ifdef TESTOOB
+	unsigned int vertex_count;
+	Vector3* vertices;
+	if (!getBoneVertices(bone, vertex_count, vertices))
+		return 0;
+
+	Vector3 box_kCenter(Vector3::ZERO);
+	Ogre::Vector3 box_akAxis[3];
+	Ogre::Real box_afExtent[3];
+
+	//   EigenSolver::GaussPointsFit (vertex_count-1, &vertices[1], box_kCenter, box_akAxis, box_afExtent);
+
+	Ogre::Real invVertexCount=1.0/(Ogre::Real)vertex_count;
+	for(size_t c=0;c<vertex_count;c++)
+	{
+		box_kCenter+=vertices[c];
+	}
+	box_kCenter*=invVertexCount;
+
+	Quaternion orient=_entity->getSkeleton()->getBone(bone)->_getDerivedOrientation();
+	orient.ToAxes(box_akAxis);
+
+
+	// Let C be the box center and let U0, U1, and U2 be the box axes.  Each
+	// input point is of the form X = C + y0*U0 + y1*U1 + y2*U2.  The
+	// following code computes min(y0), max(y0), min(y1), max(y1), min(y2),
+	// and max(y2).  The box center is then adjusted to be
+	//   C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 +
+	//        0.5*(min(y2)+max(y2))*U2
+
+
+	Ogre::Vector3 kDiff (vertices[1] - box_kCenter);
+	Ogre::Real fY0Min = kDiff.dotProduct(box_akAxis[0]), fY0Max = fY0Min;
+	Ogre::Real fY1Min = kDiff.dotProduct(box_akAxis[1]), fY1Max = fY1Min;
+	Ogre::Real fY2Min = kDiff.dotProduct(box_akAxis[2]), fY2Max = fY2Min;
+
+	for (unsigned int i = 2; i < vertex_count; i++)
+	{
+		kDiff = vertices[i] - box_kCenter;
+
+		const Ogre::Real fY0 = kDiff.dotProduct(box_akAxis[0]);
+		if ( fY0 < fY0Min )
+			fY0Min = fY0;
+		else if ( fY0 > fY0Max )
+			fY0Max = fY0;
+
+		const Ogre::Real fY1 = kDiff.dotProduct(box_akAxis[1]);
+		if ( fY1 < fY1Min )
+			fY1Min = fY1;
+		else if ( fY1 > fY1Max )
+			fY1Max = fY1;
+
+		const Ogre::Real fY2 = kDiff.dotProduct(box_akAxis[2]);
+		if ( fY2 < fY2Min )
+			fY2Min = fY2;
+		else if ( fY2 > fY2Max )
+			fY2Max = fY2;
+	}
+
+	box_afExtent[0] = ((Real)0.5)*(fY0Max - fY0Min);
+	box_afExtent[1] = ((Real)0.5)*(fY1Max - fY1Min);
+	box_afExtent[2] = ((Real)0.5)*(fY2Max - fY2Min);
+
+	box_kCenter += (0.5*(fY0Max+fY0Min))*box_akAxis[0] +
+		(0.5*(fY1Max+fY1Min))*box_akAxis[1] +
+		(0.5*(fY2Max+fY2Min))*box_akAxis[2];
+
+	BoxGeometry *geom = new BoxGeometry(Vector3(box_afExtent[0] * 2.0,
+		box_afExtent[1] * 2.0,
+		box_afExtent[2] * 2.0),
+		world, space);
+	geom->setOrientation(Quaternion(box_akAxis[0],box_akAxis[1],box_akAxis[2]));
+	geom->setPosition(box_kCenter);
+	return geom; 
+#else
+	unsigned int vertex_count;
+	Vector3* vertices;
+	if (!getBoneVertices(bone, vertex_count, vertices)) 
+		return 0;
+
+	Vector3 box_kCenter;
+	Ogre::Vector3 box_akAxis[3];
+	Ogre::Real box_afExtent[3];
+
+	EigenSolver::GaussPointsFit (vertex_count, vertices, box_kCenter, box_akAxis, box_afExtent);
+
+	// Let C be the box center and let U0, U1, and U2 be the box axes.  Each
+	// input point is of the form X = C + y0*U0 + y1*U1 + y2*U2.  The
+	// following code computes min(y0), max(y0), min(y1), max(y1), min(y2),
+	// and max(y2).  The box center is then adjusted to be
+	//   C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 +
+	//        0.5*(min(y2)+max(y2))*U2
+
+	Ogre::Vector3 kDiff (vertices[0] - box_kCenter);
+	Ogre::Real fY0Min = kDiff.dotProduct(box_akAxis[0]), fY0Max = fY0Min;
+	Ogre::Real fY1Min = kDiff.dotProduct(box_akAxis[1]), fY1Max = fY1Min;
+	Ogre::Real fY2Min = kDiff.dotProduct(box_akAxis[2]), fY2Max = fY2Min;
+
+	for (unsigned int i = 1; i < vertex_count; i++)
+	{
+		kDiff = vertices[i] - box_kCenter;
+
+		const Ogre::Real fY0 = kDiff.dotProduct(box_akAxis[0]);
+		if ( fY0 < fY0Min )
+			fY0Min = fY0;
+		else if ( fY0 > fY0Max )
+			fY0Max = fY0;
+
+		const Ogre::Real fY1 = kDiff.dotProduct(box_akAxis[1]);
+		if ( fY1 < fY1Min )
+			fY1Min = fY1;
+		else if ( fY1 > fY1Max )
+			fY1Max = fY1;
+
+		const Ogre::Real fY2 = kDiff.dotProduct(box_akAxis[2]);
+		if ( fY2 < fY2Min )
+			fY2Min = fY2;
+		else if ( fY2 > fY2Max )
+			fY2Max = fY2;
+	}
+
+	box_afExtent[0] = ((Real)0.5)*(fY0Max - fY0Min);
+	box_afExtent[1] = ((Real)0.5)*(fY1Max - fY1Min);
+	box_afExtent[2] = ((Real)0.5)*(fY2Max - fY2Min);
+
+	box_kCenter += (box_afExtent[0])*box_akAxis[0] +
+		(box_afExtent[1])*box_akAxis[1] +
+		(box_afExtent[2])*box_akAxis[2];
+
+	BoxGeometry *geom = new BoxGeometry(Vector3(box_afExtent[0] * 2.0,
+		box_afExtent[1] * 2.0,
+		box_afExtent[2] * 2.0),
+		world, space);
+	geom->setOrientation(Quaternion(box_akAxis[0],box_akAxis[1],box_akAxis[2]));
+	geom->setPosition(box_kCenter);
+	return geom;
+#endif
+}
+//------------------------------------------------------------------------------------------------
+CapsuleGeometry* EntityInformer::createOrientedCapsule(unsigned char bone, World *world, Space* space)
+{
+	unsigned int vertex_count;
+	Vector3* vertices;
+
+	if (!getBoneVertices(bone,vertex_count,vertices)) 
+        return 0;
+
+	Vector3 cap_orig;
+	Vector3 cap_dir;
+	Real cap_rad;
+
+	Vector3 line_orig;
+	Vector3 line_dir;
+
+	EigenSolver::orthogonalLineFit (vertex_count, vertices, line_orig, line_dir);
+
+   Ogre::Real fMaxRadiusSqr = (Real) 0.0;
+    unsigned int c;
+    for (c = 0; c < vertex_count; c++)
+    {
+		const Ogre::Real fRadiusSqr = EigenSolver::SqrDistance(vertices[c], line_orig, line_dir);
+        if ( fRadiusSqr > fMaxRadiusSqr ) 
+            fMaxRadiusSqr = fRadiusSqr;
+    }
+
+    Ogre::Vector3 kU, kV, kW = line_dir;
+	EigenSolver::GenerateOrthonormalBasis (kU, kV, kW, true);
+
+   Ogre::Real fMin = FLT_MAX, fMax = -fMin;
+    for (c = 0; c < vertex_count; c++)
+    {
+        const  Ogre::Vector3 kDiff (vertices[c] - line_orig);
+        const Ogre::Real fU = kU.dotProduct (kDiff);
+        const Ogre::Real fV = kV.dotProduct (kDiff);
+        const Ogre::Real fW = kW.dotProduct (kDiff);
+        const Ogre::Real fDiscr = fMaxRadiusSqr - (fU*fU + fV*fV);
+        const Ogre::Real fRadical = sqrtf(fabs(fDiscr));
+
+        fMin = std::min(fW + fRadical, fMin);
+        fMax = std::max(fW - fRadical, fMax);
+    }
+
+    if ( fMin < fMax )
+    {
+        cap_orig = line_orig + fMin*line_dir;
+        cap_dir = (fMax-fMin)*line_dir;
+    }
+    else
+    {
+        // enclosing capsule is really a sphere
+        cap_orig = line_orig + (((Real)0.5)*(fMin+fMax))*line_dir;
+        //----------------------------
+        cap_dir = Ogre::Vector3::ZERO;
+        //cap_dir = (fMax-fMin)*line_dir;
+    }
+
+    cap_rad = sqrtf(fMaxRadiusSqr);
+
+
+    CapsuleGeometry* geom = 0;
+    const Ogre::Real cap_dirLength = cap_dir.length();
+    if (cap_rad > 0 && cap_dirLength > 0)
+    {
+        const Ogre::Vector3 orig_axis (Vector3::UNIT_Z);
+        const Ogre::Vector3 reqd_axis (cap_dir.normalisedCopy());
+        const Ogre::Vector3 rot_axis (orig_axis.crossProduct(reqd_axis));
+        const Ogre::Real cos_ang = orig_axis.dotProduct(reqd_axis);
+       Ogre::Real ang = acos(cos_ang);
+        if (cos_ang < 0.0) 
+            ang -= M_PI;
+
+        const Ogre::Quaternion orient = Ogre::Quaternion(Radian(ang),rot_axis);
+
+        geom = new CapsuleGeometry(cap_rad, cap_dirLength, world, space);
+        geom->setOrientation(orient);
+        geom->setPosition(cap_orig + (reqd_axis * (cap_dirLength * 0.5)));
+    }
+	return geom;
+}
+//------------------------------------------------------------------------------------------------
+EntityInformer::~EntityInformer()
+{
+	delete[] _vertices;
+	delete[] _indices;
+
+	if (_bone_mapping)
+	{
+		for(BoneMapping::iterator i = _bone_mapping->begin();
+            i != _bone_mapping->end();
+            ++i)
+		{
+			delete i->second;
+		}
+		delete _bone_mapping;
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+EntityInformerReuse::EntityInformerReuse(Entity *entity, const Vector3 &scale, bool forceRecreate) : EntityInformer()
+{
+	_transform.makeTransform(Vector3::ZERO, scale, Quaternion::IDENTITY);
+	
+	if(!forceRecreate)
+		_dataPtr = TriangleMeshDataManager::getSingleton().getTriangleMeshData(entity->getMesh()->getName(), scale);
+
+	if(_dataPtr.isNull()) 
+	{
+		EntityInformer::addEntity(entity, _transform);
+		
+		_dataPtr = new TriangleMeshData(entity->getMesh()->getName(), scale, _vertices, _vertex_count, _indices, _index_count);
+		TriangleMeshDataManager::getSingleton().addTriangleMeshData(entity->getMesh()->getName(), _dataPtr, scale);
+	}
+}
+//------------------------------------------------------------------------------------------------
+EntityInformerReuse::EntityInformerReuse(const MeshPtr &mesh, const Vector3 &scale, bool forceRecreate) : EntityInformer()
+{
+	_entity = NULL;
+	
+	_transform.makeTransform(Vector3::ZERO, scale, Quaternion::IDENTITY);
+	
+	if(!forceRecreate)
+		_dataPtr = TriangleMeshDataManager::getSingleton().getTriangleMeshData(mesh->getName(), scale);
+	
+	if(_dataPtr.isNull()) 
+	{
+		EntityInformer::addMesh(mesh, _transform);
+		
+		_dataPtr = new TriangleMeshData(mesh->getName(), scale, _vertices, _vertex_count, _indices, _index_count);
+		TriangleMeshDataManager::getSingleton().addTriangleMeshData(mesh->getName(), _dataPtr, scale);
+	}
+}
+//------------------------------------------------------------------------------------------------
+EntityInformerReuse::~EntityInformerReuse()
+{
+}
+//------------------------------------------------------------------------------------------------
+TriangleMeshGeometry* EntityInformerReuse::createStaticTriangleMesh(World *world, Space* space)
+{
+	return new TriangleMeshGeometry(_dataPtr, world, space);
+}
+//------------------------------------------------------------------------------------------------
+TriangleMeshGeometry* EntityInformerReuse::recreateStaticTriangleMesh(TriangleMeshGeometry* geom)
+{
+	geom->changeTriangleMeshData(_dataPtr);
+	return geom;
+}
Index: code/branches/physics/src/ogreode/OgreOdeEntityInformer.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeEntityInformer.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeEntityInformer.h	(revision 1919)
@@ -0,0 +1,106 @@
+#ifndef _OGREODEENTITYINFORMER_H_
+#define _OGREODEENTITYINFORMER_H_
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeTriangleMeshData.h"
+
+namespace OgreOde 
+{
+    class _OgreOdeExport EntityInformer
+    {
+	public:
+		EntityInformer(Ogre::Entity *entity,const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
+		EntityInformer();
+		~EntityInformer();
+
+		void addEntity(Ogre::Entity *entity,const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
+		// Cannot be animated. 
+		void addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
+
+		Ogre::Real getRadius();
+		Ogre::Vector3 getSize();
+		Ogre::Vector3 getCenter();
+
+		Body* createSingleDynamicSphere(Ogre::Real mass, World *world, Space* space = 0);
+		Body* createSingleDynamicBox(Ogre::Real mass, World *world, Space* space = 0);
+
+		TriangleMeshGeometry* createStaticTriangleMesh(World *world, Space* space = 0);
+		BoxGeometry* createSingleStaticBox(World *world, Space* space = 0);
+
+		CapsuleGeometry* createOrientedCapsule(unsigned char bone, World *world, Space* space = 0);
+		BoxGeometry* createOrientedBox(unsigned char bone, World *world, Space* space = 0);
+		BoxGeometry* createAlignedBox(unsigned char bone, World *world, Space* space = 0);
+
+		const Ogre::Vector3* getVertices();
+		unsigned int getVertexCount();
+		const TriangleIndex* getIndices();
+		unsigned int getIndexCount();
+
+	protected:
+        void addVertexData(const Ogre::VertexData *vertex_data, 
+            const Ogre::VertexData *blended_data = 0, 
+            const Ogre::Mesh::IndexMap *indexMap = 0);
+		void addIndexData(Ogre::IndexData *data, const unsigned int offset = 0);
+		bool getBoneVertices(unsigned char bone,unsigned int &vertex_count, Ogre::Vector3* &vertices);
+
+		Ogre::Entity*		_entity;
+		Ogre::SceneNode*	_node;
+		Ogre::Matrix4		_transform;
+
+		Ogre::Real			_radius;
+		Ogre::Vector3		_size;
+		Ogre::Vector3		_center;
+
+        Ogre::Vector3*		_vertices;
+		TriangleIndex*		_indices; 
+		unsigned int		_vertex_count;
+		unsigned int		_index_count;
+
+		BoneMapping *_bone_mapping;
+	};
+
+	/** Class may create a TriangleMeshDataPtr, store and reuses it with TriangleMeshDataManager.
+		This can limit the number of instances of the mesh data at a given scale to one.
+		Since TriangleMeshGeometry is created using TriangleMeshDataPtr, have the advantage that 
+		the TriangleMeshDataPtr can be changed without having to recreate the TriangleMeshGeometry see 
+		TriangleMeshGeometry::changeTriangleMeshData().
+		When TriangleMeshGeometry is created it is created at the origin with an identity orientation.
+	*/
+	class _OgreOdeExport EntityInformerReuse : public EntityInformer
+	{
+
+	public:
+	
+		/** forceRecreate will force the creation of a TriangleMeshDataPtr, use only when the mesh has undergone some change
+		*/
+		EntityInformerReuse(Ogre::Entity *entity, const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE, bool forceRecreate = false);
+		EntityInformerReuse(const Ogre::MeshPtr &mesh, const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE, bool forceRecreate = false);
+		
+		~EntityInformerReuse();
+		
+		/** Creates TriangleMeshGeometry using TriangleMeshDataPtr 
+		*/
+		TriangleMeshGeometry* createStaticTriangleMesh(World *world, Space* space = 0);
+		
+		/** Recreates any TriangleMeshGeometry with the TriangleMeshDataPtr
+		*/
+		TriangleMeshGeometry* recreateStaticTriangleMesh(TriangleMeshGeometry* geom);
+		
+		/** Shouldn't be adding Entity or Mesh, one TriangleMeshData per Mesh/Entity for any scale.
+		*/
+		virtual void addEntity(Ogre::Entity *entity,const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY){}
+		virtual void addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY){}
+		
+		TriangleMeshDataPtr getTriangleMeshDataPtr(){ return _dataPtr; }
+		
+	protected:
+	
+		TriangleMeshDataPtr _dataPtr;
+		
+	};
+
+}
+
+#endif
+
+
Index: code/branches/physics/src/ogreode/OgreOdeFrameListener.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeFrameListener.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeFrameListener.h	(revision 1919)
@@ -0,0 +1,151 @@
+/*
+    PhysicsFrameListener.h
+
+	A very simple wrapper class for ODE
+	primarily for the example car application
+*/
+#ifndef _PHYSICSFRAMELISTENER_H_
+#define _PHYSICSFRAMELISTENER_H_
+
+// Uncomment this if you're planning to use the Plane2D joint
+// But you'll have to have modified ODE first!
+// #define INCLUDE_PLANE2D_JOINT
+
+/*
+A physical thing
+*/
+class PhysicalThing : public RaySceneQueryListener
+{
+public:
+	// Doesn't actually do anything
+	PhysicalThing(dSpace *space);
+	~PhysicalThing(void);
+
+	// Just create geoms
+    void makePlane(Real a,Real b,Real c,Real d);				// Plane
+    void makeBox(Real x,Real y,Real z,Real lx,Real ly,Real lz);	// Box
+    void makeSphere(Real x,Real y,Real z,Real r);				// Sphere
+
+	// Create bodies and geoms
+    void makePlane(dWorld *world,SceneNode *node);
+	void makeBox(dWorld *world,SceneNode *node,Real mass = 1,Vector3 const &offs = Vector3(0,0,0));
+    void makeSphere(dWorld *world,SceneNode *node,Real mass = 1);
+	void makeTerrainTriMesh(dWorld *world,SceneManager *mgr,Real grid_size,Real grid_spacing);
+
+	// Callback functions for the ray scene query functionality
+	virtual bool queryResult(SceneQuery::WorldFragment *fragment,Real distance);
+	virtual bool queryResult(MovableObject *obj,Real distance);
+
+	// Update the position and orientation of the scene node we're controlling
+	void update(void);
+
+	// Utility functions to get at internal stuff
+	SceneNode *getNode(void);
+	dBodyID getBodyID(void);
+	dSpaceID getSpaceID(void);
+
+protected:
+	dGeom		*_geom;
+	dBody		*_body;
+	dSpace		*_space;
+	SceneNode	*_node;
+
+	std::list<Vector3> _frag;
+
+	dVector3 *_vertices;
+	int *_indices;
+};
+
+/*
+A Frame listener that implements the physics
+*/
+class PhysicsFrameListener : public FrameListener
+{
+protected:
+	// All the stuff we need for ODE
+    dWorld          *world;
+    dHashSpace      *space;
+    dJointGroup     *contactgroup;
+    dSpace          *current_space;
+	bool			paused;
+
+	// Keep track of anything we've created
+    std::list<PhysicalThing*>   things;
+    std::list<dSimpleSpace*>    spaces;
+	std::list<dJoint*>			joints;
+    
+	// Adjustable variables
+    Real total_time,step_size;
+	Real k_spring,k_damper,k_tyre,k_mu,k_erp,k_cfm;
+
+	// Utility function to find the physical thing associated with an Ogre scene node
+	dBodyID getBodyID(SceneNode *node);
+
+public:
+	// Standard constructor/destructor
+    PhysicsFrameListener(void);
+    ~PhysicsFrameListener(void);
+
+	// Tell us when every frame's about to be started
+    bool frameStarted(const FrameEvent& evt);
+	void pause(bool p = true);
+
+	// Mainly so we can access internal stuff from the collision callback
+    dWorld *getWorld(void){return world;};
+    dSpace *getSpace(void){return space;};
+    dJointGroup *getContactGroup(void){return contactgroup;};
+
+	// Create things manually, no physical bodies 
+	// so they won't move, but things will collide with them
+    PhysicalThing *createPlane(Real a,Real b,Real c,Real d);
+    PhysicalThing *createBox(Real x,Real y,Real z,Real lx,Real ly,Real lz);
+    PhysicalThing *createSphere(Real x,Real y,Real z,Real r);
+
+	// Create objects based on Ogre nodes, these nodes will then
+	// come under control of the physics simulation and will move about
+	// as if by magic!
+	// Except for the plane, which can't actually be a physical body
+	// and the trimesh which we're not going to allow to be a physical body
+    PhysicalThing *createPlane(SceneNode *node);
+	PhysicalThing *createBox(SceneNode *node,Real mass = 1,Vector3 const &offs = Vector3(0,0,0));
+    PhysicalThing *createSphere(SceneNode *node,Real mass = 1);
+	PhysicalThing *createTerrainTriMesh(SceneManager *mgr,Real grid_size,Real grid_spacing);
+
+	// Create and activate a new space inside the standard hash space
+	// Things won't collide within a space so (for example) the objects
+	// that make up a car won't collide with each other
+    dSimpleSpace *createSpace(void);
+
+	// Create joints between the nodes specified
+	// The order of n1/n2 does matter; n1 is what you want attaching
+	// and n2 is what you want it attaching to
+	dJoint *createHinge2(SceneNode *n1,SceneNode *n2,const Vector3 &suspension = Vector3(0,1,0),const Vector3 &axle = Vector3(1,0,0));
+	dJoint *createHinge(SceneNode *n1,SceneNode *n2,const Vector3 &axis = Vector3(1,0,0));
+	dJoint *createSlider(SceneNode *n1,SceneNode *n2,const Vector3 &axis = Vector3(0,1,0));
+	dJoint *createBall(SceneNode *n1,SceneNode *n2);
+#ifdef INCLUDE_PLANE2D_JOINT
+	dJoint *createPlane2D(SceneNode *n);
+#endif
+
+	// Apply forces to a body under our control
+	void addTorque(SceneNode *n,const Vector3 &force);
+
+	// Set the parameters used for the CFM/ERP joint parameters
+	void setSuspension(Real spring,Real damper);
+
+	// Set the acceleration due to gravity
+	void setGravity(Real g);
+
+	// Get our constants
+	Real getTyre(void){return k_tyre;};
+	Real getMu(void){return k_mu;};
+	Real getCFM(void){return k_cfm;};
+	Real getERP(void){return k_erp;};
+
+	// Static function for ODE to call when collisions (potentially) occur
+    static void collisionCallback(void *data,dGeomID o1,dGeomID o2);
+};
+
+#endif
+
+
Index: code/branches/physics/src/ogreode/OgreOdeGeometry.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeGeometry.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeGeometry.cpp	(revision 1919)
@@ -0,0 +1,1401 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeGeometry.h"
+#include "OgreOdeWorld.h"
+#include "OgreOdeSpace.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeCollision.h"
+#include "OgreOdeDebugObject.h"
+#include "OgreOdeDebugContact.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+//------------------------------------------------------------------------------------------------
+int Geometry::_geometry_count = 0;
+const Ogre::String Geometry::MovableType = "OgreOde_Geometry";
+
+//------------------------------------------------------------------------------------------------
+Geometry::Geometry(World *world, Space* space):
+    UserDefinedObject(),
+	_contact_high_water_mark (0),
+    _last_contact_num(0),
+	_max_contacts (32),
+    _debug_contacts (0),
+	_contacts (0),
+	_encapsulator (0),
+	_debug_obj (0),
+	_debug_node (0),
+	_user_data (0),
+	_user_object (0),
+	_geom (0),
+    _world(world)
+{
+	mName = "";
+}
+//------------------------------------------------------------------------------------------------
+Geometry::~Geometry()
+{
+    destroyDebugObject();
+
+    delete[] _contacts;
+    if (_debug_contacts)
+    {         
+        for (unsigned int i = 0; i < _max_contacts; i++)
+            delete _debug_contacts[i];
+        delete [] _debug_contacts;
+    }
+    if (_geom)
+    {
+        _world->getGeometryList().unregisterItem((unsigned long)_geom);
+        dGeomDestroy(_geom); 
+    }
+}
+//------------------------------------------------------------------------------------------------
+dGeomID Geometry::getGeometryID() const
+{
+	return _geom;
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::setEncapsulator(Geometry* encapsulator)
+{
+	_encapsulator = encapsulator;
+
+	if (_world->getShowDebugGeometries())
+	{
+		reparentDebugObject(encapsulator->_debug_node);
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::reparentDebugObject(Ogre::Node* node)
+{
+	if ((node)&&(_debug_node)&&(_debug_node->getParent() != node))
+	{
+		Ogre::SceneNode* parent = static_cast<Ogre::SceneNode*>(_debug_node->getParent());
+		parent->removeChild(_debug_node->getName());
+		node->addChild(_debug_node);
+
+		_debug_node->setPosition(getPosition());
+		_debug_node->setOrientation(getOrientation());
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::createDebugObject()
+{
+	if (!_debug_node)
+	{
+		Ogre::SceneNode* parent = _world->_manager->getRootSceneNode();
+		_debug_node = static_cast<Ogre::Node*>(parent->createChildSceneNode(Ogre::String("OgreOde::Geometry_") + Ogre::StringConverter::toString(_geometry_count) + Ogre::String("_Debug"))); 
+
+        if (_debug_obj)
+        {
+            static_cast<Ogre::SceneNode*>(_debug_node)->attachObject(_debug_obj);
+        }
+
+        if (getBody())
+        {
+            static_cast<Ogre::SceneNode*>(_debug_node->getParent())->removeChild(_debug_node->getName());
+            getBody()->addDebugNode(_debug_node);
+            if (_debug_obj) 
+				_debug_obj->setMode(DebugObject::Mode_Enabled);
+			
+			//reposition the debug node if the geometry has an offset
+			if(isOffset())
+				_debug_node->setPosition(getOffsetPosition()); 
+        }
+		else if (_encapsulator)
+		{
+			reparentDebugObject(_encapsulator->_debug_node);
+		}
+		else
+		{
+			if (_debug_obj) 
+                _debug_obj->setMode(DebugObject::Mode_Static);
+			
+			_debug_node->setPosition(getPosition());
+			_debug_node->setOrientation(getOrientation());
+		}
+		_geometry_count++;
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::destroyDebugObject()
+{
+	if (_debug_node)
+    {
+
+        Ogre::SceneNode* sn = static_cast<Ogre::SceneNode*>(_debug_node);
+        sn->removeAndDestroyAllChildren ();
+        sn = static_cast<Ogre::SceneNode*>(_debug_node->getParent());
+        sn->removeAndDestroyChild(_debug_node->getName());
+		_debug_node = 0;
+	}
+
+	if (_debug_obj)
+	{
+		delete _debug_obj;
+		_debug_obj = 0;
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::registerGeometry()
+{
+	dGeomSetData(_geom, (void*)this);
+	assert(_world);
+    _world->getGeometryList().registerItem(this);
+
+    if (_world->getShowDebugGeometries()) 
+        createDebugObject();
+
+    setMaxContacts (_max_contacts);
+}
+//------------------------------------------------------------------------------------------------
+dSpaceID Geometry::getSpaceID(Space* space) const
+{
+	if (!space) return 0;
+	return space->getSpaceID();
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::setBody(Body* body)
+{
+	destroyDebugObject();
+    if (body)
+    {
+        body->addGeometry (this);
+        dGeomSetBody(_geom, body->getBodyID()); 
+    }
+    else
+    {
+        dGeomSetBody(_geom, 0); 
+    }
+	if (_world->getShowDebugGeometries()) 
+        createDebugObject();
+}
+
+//------------------------------------------------------------------------------------------------
+Body* Geometry::getBody()
+{
+	const dBodyID body = dGeomGetBody(_geom);
+	if (!body) return 0;
+	else return (Body*)dBodyGetData(body); 
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::notify(Body* body)
+{
+	if (getBody() == body)
+	{
+		destroyDebugObject();
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::setDebug(const bool debug)
+{
+    destroyDebugObject();
+    if (debug) 
+        createDebugObject();    
+}
+//------------------------------------------------------------------------------------------------
+void Geometry::setDebugContact(const bool debug)
+{    
+    if (_debug_contacts)
+    {
+        for (unsigned int i = 0; i < _max_contacts; i++)
+            delete _debug_contacts[i];
+        delete [] _debug_contacts;
+        _debug_contacts = 0;
+    }
+    if (debug) 
+    {
+        _debug_contacts = new DebugContact*[_max_contacts];
+        for (unsigned int i = 0; i < _max_contacts; i++)
+            _debug_contacts[i] = new DebugContact(Ogre::StringConverter::toString((size_t)_geom) + 
+                                                    "_Contact_" + 
+                                                    Ogre::StringConverter::toString(i),
+                                                    _world);
+    }
+}
+//------------------------------------------------------------------------------------------------
+void Geometry::setPosition(const Ogre::Vector3& position)
+{
+    dGeomSetPosition(_geom,(dReal)position.x,(dReal)position.y,(dReal)position.z);
+
+    if ((_debug_node)&& ((!getBody()) || (_encapsulator)))
+        _debug_node->setPosition(position);
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::setOrientation(const Ogre::Quaternion& orientation)
+{
+	dQuaternion q;
+	q[0] = (dReal)orientation.w;
+	q[1] = (dReal)orientation.x;
+	q[2] = (dReal)orientation.y;
+	q[3] = (dReal)orientation.z;
+	dGeomSetQuaternion(_geom,q); 
+
+	if ((_debug_node)&& ((!getBody()) || (_encapsulator))) _debug_node->setOrientation(orientation);
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& Geometry::getPosition()
+{
+	const dReal* position = dGeomGetPosition(_geom);
+	_position.x = (Ogre::Real)position[0];
+	_position.y = (Ogre::Real)position[1];
+	_position.z = (Ogre::Real)position[2];
+	return _position;
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Quaternion& Geometry::getOrientation()
+{
+	dQuaternion orientation;
+	dGeomGetQuaternion(_geom,orientation); 
+	_orientation.w = (Real)orientation[0];
+	_orientation.x = (Real)orientation[1];
+	_orientation.y = (Real)orientation[2];
+	_orientation.z = (Real)orientation[3];
+	return _orientation;
+}
+
+//------------------------------------------------------------------------------------------------
+const AxisAlignedBox& Geometry::getAxisAlignedBox()
+{
+	dReal aabb[6];
+	dGeomGetAABB(_geom,aabb);
+	_bounding_box.setExtents((Real)aabb[0],(Real)aabb[2],(Real)aabb[4],(Real)aabb[1],(Real)aabb[3],(Real)aabb[5]);
+	return _bounding_box;
+}
+
+//------------------------------------------------------------------------------------------------
+Space* Geometry::getSpace()
+{
+	if (dGeomGetSpace(_geom) == 0) 
+	{
+		// not in any space
+		return NULL;
+	}
+
+	return (Space*)_world->getSpaceList().findItem((size_t)dGeomGetSpace(_geom));
+}
+
+
+//------------------------------------------------------------------------------------------------
+void Geometry::enable()
+{
+	dGeomEnable(_geom);
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::disable()
+{
+	dGeomDisable(_geom); 
+}
+
+//------------------------------------------------------------------------------------------------
+bool Geometry::isEnabled()
+{
+	return dGeomIsEnabled(_geom) != 0; 
+}
+
+//------------------------------------------------------------------------------------------------
+Geometry::Class Geometry::getClass() const
+{
+	return (Geometry::Class)dGeomGetClass(_geom);
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::setCategoryBitfield(unsigned long bits)
+{
+	dGeomSetCategoryBits(_geom,bits); 
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::setCollisionBitfield(unsigned long bits)
+{
+	dGeomSetCollideBits(_geom,bits); 
+}
+
+//------------------------------------------------------------------------------------------------
+unsigned long Geometry::getCategoryBitfield()
+{
+	return dGeomGetCategoryBits(_geom); 
+}
+
+//------------------------------------------------------------------------------------------------
+unsigned long Geometry::getCollisionBitfield()
+{
+	return dGeomGetCollideBits(_geom); 
+}
+
+//------------------------------------------------------------------------------------------------
+int Geometry::collide(Geometry* geometry,CollisionListener* listener)
+{
+	const unsigned int num_contacts = (unsigned int) dCollide(_geom,
+										geometry->getGeometryID(),
+										_max_contacts,
+										&(_contacts[0].geom),
+										sizeof(dContact));
+	if (num_contacts)
+	{
+		_contact_high_water_mark = std::max(_contact_high_water_mark,num_contacts);
+
+		Contact contact;
+		
+		const dWorldID wid = _world->getWorldID();
+		const dJointGroupID cid = _world->getContactGroupID();
+		const dBodyID b1 = dGeomGetBody(_geom);
+		const dBodyID b2 = dGeomGetBody(geometry->getGeometryID());
+
+		if (listener)
+		{
+			for(unsigned int i = 0;i < num_contacts;i++)
+			{
+				contact.setContact (&_contacts[i]);
+
+				if (listener->collision(&contact))
+				{
+					dJointAttach(dJointCreateContact(wid,cid,&_contacts[i]),b1,b2);
+                } 
+			}
+		}
+		else
+		{
+			for(unsigned int i = 0;i < num_contacts;i++)
+			{
+				contact.setContact (&_contacts[i]);
+   
+				dJointAttach(dJointCreateContact(wid,cid,&_contacts[i]), b1, b2);
+			}
+		} 
+    }
+    _last_contact_num = num_contacts;
+	return num_contacts;
+}
+//------------------------------------------------------------------------------------------------
+void Geometry::updateDebugContact()
+{
+    assert (_world->getShowDebugContact ());
+    assert (_debug_contacts);
+    {
+        unsigned int k = 0;
+        while (k < _max_contacts)
+        {
+            _debug_contacts[k++]->setEnabled(false);
+        }
+
+        if (_last_contact_num)
+        {
+            Contact contact;
+            for(unsigned int i = 0;i < _last_contact_num;i++)
+            {
+                k = 0;
+                while (k < _max_contacts)
+                {
+                    if (_debug_contacts[k]->isEnabled() == false)
+                        break;
+                    k++;
+                }
+                assert (k < _max_contacts);
+
+                _debug_contacts[k]->setEnabled(true);
+                contact.setContact (&_contacts[i]);
+                _debug_contacts[k]->update (&contact);
+            }
+        }
+    }
+    _last_contact_num = 0;
+ }
+//------------------------------------------------------------------------------------------------
+unsigned int Geometry::getMaxContacts() const
+{
+	return _max_contacts;
+}
+
+//------------------------------------------------------------------------------------------------
+void Geometry::setMaxContacts(unsigned int max_contacts)
+{
+	delete[] _contacts;
+	_contacts = new dContact[max_contacts];
+
+    if (_world->getShowDebugContact ())
+    {
+        if (_debug_contacts)
+        {         
+            for (unsigned int i = 0; i < _max_contacts; i++)
+                delete _debug_contacts[i];
+            delete [] _debug_contacts;
+        }
+        _debug_contacts = new DebugContact*[max_contacts];
+        for (unsigned int i = 0; i < max_contacts; i++)
+            _debug_contacts[i] = new DebugContact(Ogre::StringConverter::toString((size_t)_geom)  
+			+ "_Contact_" 
+			+ Ogre::StringConverter::toString(i),
+            _world);
+    }
+    _max_contacts = max_contacts;
+}
+
+//------------------------------------------------------------------------------------------------
+unsigned int Geometry::getContactHighWaterMark() const
+{
+	return _contact_high_water_mark;
+}
+
+//------------------------------------------------------------------------------------------------
+size_t Geometry::getID() const
+{
+	return (size_t)_geom;
+}
+//------------------------------------------------------------------------------------------------
+void Geometry::clearOffset()
+{
+	dGeomClearOffset(_geom);
+}
+//------------------------------------------------------------------------------------------------
+int Geometry::isOffset()
+{
+	return dGeomIsOffset(_geom);
+}
+//------------------------------------------------------------------------------------------------
+void Geometry::setOffsetPosition (const Ogre::Vector3 &pos)
+{
+	dGeomSetOffsetPosition (_geom, pos.x, pos.y, pos.z);
+
+	//move the debug object when setting offset if we have a body only
+	if ((_debug_node)&& ((getBody())/* || (_encapsulator)*/))
+		_debug_node->setPosition(getOffsetPosition()); 
+}
+//------------------------------------------------------------------------------------------------
+void Geometry::setOffsetQuaternion(const Ogre::Quaternion &quat) 
+{
+	dQuaternion q;
+	q[0] = quat.w; 
+	q[1] = quat.x; 
+	q[2] = quat.y; 
+	q[3] = quat.z;
+	dGeomSetOffsetQuaternion (_geom, q);
+
+	if ((_debug_node)&& ((getBody())/* || (_encapsulator)*/))
+		_debug_node->setOrientation(getOffsetQuaternion()); 
+}
+//------------------------------------------------------------------------------------------------
+void Geometry::setOffsetWorldPosition(const Ogre::Vector3 &pos) 
+{
+	dGeomSetOffsetWorldPosition(_geom, pos.x, pos.y, pos.z);
+
+	//move the debug object when setting offset if we have a body only
+	if ((_debug_node)&& ((getBody())/* || (_encapsulator)*/))
+		_debug_node->setPosition(getOffsetPosition()); 
+}
+//------------------------------------------------------------------------------------------------
+void Geometry::setOffsetWorldQuaternion(const Ogre::Quaternion &quat) 
+{
+	dQuaternion q;
+	q[0] = quat.w; 
+	q[1] = quat.x; 
+	q[2] = quat.y; 
+	q[3] = quat.z;
+	dGeomSetOffsetWorldQuaternion (_geom, q);
+
+	if ((_debug_node)&& ((getBody())/* || (_encapsulator)*/))
+		_debug_node->setOrientation(getOffsetQuaternion()); 
+}
+//------------------------------------------------------------------------------------------------
+Vector3 Geometry::getOffsetPosition() 
+{
+	const dReal *p =  dGeomGetOffsetPosition (_geom);
+	return Ogre::Vector3(p[0], p[1], p[2]);
+}
+//------------------------------------------------------------------------------------------------
+Quaternion Geometry::getOffsetQuaternion() 
+{
+	dQuaternion q;
+	dGeomGetOffsetQuaternion (_geom, q);
+	return Ogre::Quaternion(q[0], q[1], q[2], q[3]);
+}
+//-----------------------------------------------------------------------
+void Geometry::_notifyAttached(Node* parent, bool isTagPoint)
+{
+	MovableObject::_notifyAttached(parent, isTagPoint);
+	reparentDebugObject(parent);
+}
+//-----------------------------------------------------------------------
+void Geometry::_notifyMoved()
+{
+	MovableObject::_notifyMoved();
+		
+	if (!getBody())
+	{
+		setPosition(mParentNode->_getDerivedPosition());
+		setOrientation(mParentNode->_getDerivedOrientation());
+	}
+}
+//------------------------------------------------------------------------------------------------
+SphereGeometry::SphereGeometry(Real radius, World *world, Space* space):Geometry(world, space)
+{
+	_geom = dCreateSphere(getSpaceID(space),(dReal)radius); 
+	registerGeometry();
+}
+
+//------------------------------------------------------------------------------------------------
+void SphereGeometry::setRadius(Real radius)
+{
+	dGeomSphereSetRadius(_geom,(dReal)radius);
+}
+
+//------------------------------------------------------------------------------------------------
+Real SphereGeometry::getRadius()
+{
+	return (Real)dGeomSphereGetRadius(_geom); 
+}
+
+//------------------------------------------------------------------------------------------------
+Real SphereGeometry::getPointDepth(const Ogre::Vector3& point)
+{
+	return (Real)dGeomSpherePointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
+}
+
+//------------------------------------------------------------------------------------------------
+void SphereGeometry::createDebugObject()
+{
+	_debug_obj = new SphereDebugObject(getRadius());
+	Geometry::createDebugObject();
+}
+
+//------------------------------------------------------------------------------------------------
+SphereGeometry::~SphereGeometry()
+{
+}
+
+//------------------------------------------------------------------------------------------------
+BoxGeometry::BoxGeometry(const Ogre::Vector3& size, World *world, Space* space):Geometry(world, space)
+{
+	_geom = dCreateBox(getSpaceID(space),(dReal)size.x,(dReal)size.y,(dReal)size.z); 
+	registerGeometry();
+}
+
+//------------------------------------------------------------------------------------------------
+void BoxGeometry::setSize(const Ogre::Vector3& size)
+{
+	dGeomBoxSetLengths(_geom,(dReal)size.x,(dReal)size.y,(dReal)size.z); 
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& BoxGeometry::getSize()
+{
+	dVector3 result;
+	dGeomBoxGetLengths(_geom,result); 
+	_size.x = (Real)result[0];
+	_size.y = (Real)result[1];
+	_size.z = (Real)result[2];
+	return _size;
+}
+
+//------------------------------------------------------------------------------------------------
+Real BoxGeometry::getPointDepth(const Ogre::Vector3& point)
+{
+	return (Real)dGeomBoxPointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
+}
+
+//------------------------------------------------------------------------------------------------
+void BoxGeometry::createDebugObject()
+{
+	_debug_obj = new BoxDebugObject(getSize());
+	Geometry::createDebugObject();	
+}
+
+//------------------------------------------------------------------------------------------------
+BoxGeometry::~BoxGeometry()
+{
+}
+
+//------------------------------------------------------------------------------------------------
+InfinitePlaneGeometry::InfinitePlaneGeometry(const Plane& plane,World *world, Space* space):Geometry(world, space)
+{
+	_geom = dCreatePlane(getSpaceID(space),(dReal)plane.normal.x,(dReal)plane.normal.y,(dReal)plane.normal.z,(dReal)-plane.d); 
+	registerGeometry();
+}
+
+//------------------------------------------------------------------------------------------------
+void InfinitePlaneGeometry::setDefinition(const Plane& plane)
+{
+	dGeomPlaneSetParams(_geom,(dReal)plane.normal.x,(dReal)plane.normal.y,(dReal)plane.normal.z,(dReal)-plane.d); 
+}
+
+//------------------------------------------------------------------------------------------------
+const Plane& InfinitePlaneGeometry::getDefinition()
+{
+	dVector4 result;
+	dGeomPlaneGetParams(_geom,result); 
+	_plane.normal.x = result[0];
+	_plane.normal.y = result[1];
+	_plane.normal.z = result[2];
+	_plane.d = -result[3];
+	return _plane;
+}
+
+//------------------------------------------------------------------------------------------------
+Real InfinitePlaneGeometry::getPointDepth(const Ogre::Vector3& point)
+{
+	return (Real)dGeomPlanePointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
+}
+
+//------------------------------------------------------------------------------------------------
+void InfinitePlaneGeometry::setPosition(const Ogre::Vector3& position)
+{
+}
+
+//------------------------------------------------------------------------------------------------
+void InfinitePlaneGeometry::setOrientation(const Ogre::Quaternion& orientation)
+{
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& InfinitePlaneGeometry::getPosition()
+{
+	return Ogre::Vector3::ZERO;
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Quaternion& InfinitePlaneGeometry::getOrientation()
+{
+	return Ogre::Quaternion::ZERO;
+}
+
+//------------------------------------------------------------------------------------------------
+const AxisAlignedBox& InfinitePlaneGeometry::getAxisAlignedBox()
+{
+	return _bounding_box;
+}
+
+//------------------------------------------------------------------------------------------------
+InfinitePlaneGeometry::~InfinitePlaneGeometry()
+{
+}
+
+//------------------------------------------------------------------------------------------------
+CapsuleGeometry::CapsuleGeometry(Real radius,Real length,World *world, Space* space):Geometry(world, space)
+{
+	_geom = dCreateCapsule(getSpaceID(space),(dReal)radius,(dReal)length);
+	registerGeometry();
+}
+
+//------------------------------------------------------------------------------------------------
+void CapsuleGeometry::setDefinition(Real radius,Real length)
+{
+	dGeomCapsuleSetParams(_geom,(dReal)radius,(dReal)length);
+}
+
+//------------------------------------------------------------------------------------------------
+Real CapsuleGeometry::getRadius()
+{
+	dReal radius,length;
+	dGeomCapsuleGetParams(_geom,&radius,&length); 
+	return radius;
+}
+
+//------------------------------------------------------------------------------------------------
+Real CapsuleGeometry::getLength()
+{
+	dReal radius,length;
+	dGeomCapsuleGetParams(_geom,&radius,&length); 
+	return length;
+}
+
+//------------------------------------------------------------------------------------------------
+Real CapsuleGeometry::getPointDepth(const Ogre::Vector3& point)
+{
+	return (Real)dGeomCapsulePointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
+}
+
+//------------------------------------------------------------------------------------------------
+void CapsuleGeometry::createDebugObject()
+{
+	_debug_obj = new CapsuleDebugObject(getRadius(),getLength());
+	Geometry::createDebugObject();
+}
+
+//------------------------------------------------------------------------------------------------
+CapsuleGeometry::~CapsuleGeometry()
+{
+}
+
+//------------------------------------------------------------------------------------------------
+CylinderGeometry::CylinderGeometry(Real radius,Real length,World *world, Space* space):Geometry(world, space)
+{
+	_geom = dCreateCCylinder(getSpaceID(space),(dReal)radius,(dReal)length);
+	registerGeometry();
+}
+
+//------------------------------------------------------------------------------------------------
+void CylinderGeometry::setDefinition(Real radius,Real length)
+{
+	dGeomCCylinderSetParams(_geom,(dReal)radius,(dReal)length);
+}
+
+//------------------------------------------------------------------------------------------------
+Real CylinderGeometry::getRadius()
+{
+	dReal radius,length;
+	dGeomCCylinderGetParams(_geom,&radius,&length); 
+	return radius;
+}
+
+//------------------------------------------------------------------------------------------------
+Real CylinderGeometry::getLength()
+{
+	dReal radius,length;
+	dGeomCCylinderGetParams(_geom,&radius,&length); 
+	return length;
+}
+
+//------------------------------------------------------------------------------------------------
+Real CylinderGeometry::getPointDepth(const Ogre::Vector3& point)
+{
+	return (Real)dGeomCCylinderPointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
+}
+
+//------------------------------------------------------------------------------------------------
+void CylinderGeometry::createDebugObject()
+{
+	_debug_obj = new CylinderDebugObject(getRadius(),getLength());
+	Geometry::createDebugObject();
+}
+
+//------------------------------------------------------------------------------------------------
+CylinderGeometry::~CylinderGeometry()
+{
+}
+//------------------------------------------------------------------------------------------------
+RayGeometry::RayGeometry(Real length,World *world, Space* space) : Geometry(world, space)
+{
+	_geom = dCreateRay(getSpaceID(space),(dReal)length);
+	registerGeometry();
+}
+
+//------------------------------------------------------------------------------------------------
+void RayGeometry::createDebugObject()
+{
+	_debug_obj = new RayDebugObject(getStart(),getDirection(),getLength());
+	Geometry::createDebugObject();
+	if (_debug_node)
+	{
+		_debug_node->setPosition(Vector3::ZERO);
+		_debug_node->setOrientation(Quaternion::IDENTITY);
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+void RayGeometry::setLength(Real length)
+{
+	dGeomRaySetLength(_geom,(dReal)length); 
+}
+
+//------------------------------------------------------------------------------------------------
+Real RayGeometry::getLength()
+{
+	return (Real)dGeomRayGetLength(_geom); 
+}
+
+//------------------------------------------------------------------------------------------------
+void RayGeometry::setDefinition(const Ogre::Vector3& start,const Ogre::Vector3& direction)
+{
+	dGeomRaySet(_geom,
+					(dReal)start.x,(dReal)start.y,(dReal)start.z,
+					(dReal)direction.x,(dReal)direction.y,(dReal)direction.z);
+
+	if ((_debug_node)&& ((!getBody()) || (_encapsulator))) 
+		(static_cast<RayDebugObject *>(_debug_obj))->setDefinition(start, direction, (Real)dGeomRayGetLength(_geom));
+
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& RayGeometry::getStart()
+{
+	dVector3 start,direction;
+	dGeomRayGet(_geom,start,direction); 
+	_start.x = (Real)start[0];
+	_start.y = (Real)start[1];
+	_start.z = (Real)start[2];
+	return _start;
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& RayGeometry::getDirection()
+{
+	dVector3 start,direction;
+	dGeomRayGet(_geom,start,direction); 
+	_direction.x = (Real)direction[0];
+	_direction.y = (Real)direction[1];
+	_direction.z = (Real)direction[2];
+	return _direction;
+}
+
+//------------------------------------------------------------------------------------------------
+RayGeometry::~RayGeometry()
+{
+}
+
+//------------------------------------------------------------------------------------------------
+TransformGeometry::TransformGeometry(World *world, Space* space) : Geometry(world, space)
+{
+	_geom = dCreateGeomTransform(getSpaceID(space)); 
+	dGeomTransformSetCleanup(_geom,0);
+	dGeomTransformSetInfo(_geom,1);
+	registerGeometry();
+}
+
+//------------------------------------------------------------------------------------------------
+void TransformGeometry::setEncapsulatedGeometry(Geometry* geometry)
+{
+	dGeomTransformSetGeom(_geom,geometry->getGeometryID()); 
+	destroyDebugObject();
+	if (_world->getShowDebugGeometries()) 
+		createDebugObject();	
+
+	geometry->setEncapsulator(this);
+}
+
+//------------------------------------------------------------------------------------------------
+void TransformGeometry::createDebugObject()
+{
+	Geometry::createDebugObject();
+	if (getEncapsulatedGeometry())
+	{
+		getEncapsulatedGeometry()->destroyDebugObject();
+		getEncapsulatedGeometry()->createDebugObject();
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+void TransformGeometry::destroyDebugObject()
+{
+	if (getEncapsulatedGeometry()) getEncapsulatedGeometry()->destroyDebugObject();
+	Geometry::destroyDebugObject();
+}
+
+//------------------------------------------------------------------------------------------------
+Geometry* TransformGeometry::getEncapsulatedGeometry() const
+{
+	dGeomID id = dGeomTransformGetGeom(_geom);
+	if (id == 0) return 0;
+	else return (Geometry*)dGeomGetData(id); 
+}
+
+//------------------------------------------------------------------------------------------------
+TransformGeometry::~TransformGeometry()
+{
+}
+
+
+//------------------------------------------------------------------------------------------------
+TriangleMeshGeometry::TriangleMeshGeometry(const Ogre::Vector3* vertices,
+                                           unsigned int vertex_count,
+                                           const TriangleIndex* indices,
+                                           unsigned int index_count,
+                                           World *world, Space* space) : 
+    Geometry(world, space),
+    _vertex_count (vertex_count),
+    _index_count (index_count)
+{
+	_vertex_count = vertex_count;
+	_index_count = index_count;
+	_vertices = new dVector3[vertex_count];
+	_indices = new unsigned int[index_count];
+
+	for(unsigned int i = 0;i < vertex_count;i++)
+	{
+		_vertices[i][0] = (dReal)vertices[i].x;
+		_vertices[i][1] = (dReal)vertices[i].y;
+		_vertices[i][2] = (dReal)vertices[i].z;
+	}
+
+	memcpy(_indices,indices,sizeof(unsigned int) * index_count);
+
+	_data = dGeomTriMeshDataCreate(); 
+
+	//dGeomTriMeshDataBuildSimple(_data,(const dReal*)_vertices, (int)vertex_count, _indices, (int) index_count); 
+    // modified version
+	dGeomTriMeshDataBuildSimple(_data,(const dReal*)_vertices, (int)vertex_count, (dTriIndex*)_indices, (int) index_count); 
+
+	_geom = dCreateTriMesh(getSpaceID(space),_data,0,0,0);
+	registerGeometry();
+
+	_collision_listener = 0;
+}
+//------------------------------------------------------------------------------------------------
+TriangleMeshGeometry::TriangleMeshGeometry(TriangleMeshDataPtr dataPtr, World *world, Space* space) :
+	Geometry(world, space)
+{
+	// increases the referance count
+	_dataPtr = dataPtr;	
+	
+	//printf ("dataPtr counter %d\n", dataPtr.useCount() );
+	//printf ("_dataPtr counter %d\n", _dataPtr.useCount() );
+	
+	_data			= dataPtr.getPointer()->getData();
+	_vertex_count	= dataPtr.getPointer()->getVertexCount();
+	_index_count	= dataPtr.getPointer()->getIndexCount();
+	_vertices		= dataPtr.getPointer()->getVertices();
+	_indices		= (unsigned int*) dataPtr.getPointer()->getIndices();
+	
+	_geom = dCreateTriMesh(getSpaceID(space), _data,0,0,0);
+	registerGeometry();
+	
+	_collision_listener = 0;
+}
+//------------------------------------------------------------------------------------------------
+void TriangleMeshGeometry::changeTriangleMeshData(TriangleMeshDataPtr dataPtr)
+{
+	if(dataPtr.isNull() == false)
+	{
+		_dataPtr = dataPtr;
+		
+		_data			= dataPtr.getPointer()->getData();
+		_vertex_count	= dataPtr.getPointer()->getVertexCount();
+		_index_count	= dataPtr.getPointer()->getIndexCount();
+		_vertices		= dataPtr.getPointer()->getVertices();
+		_indices		= (unsigned int*) dataPtr.getPointer()->getIndices();
+	
+		dGeomTriMeshSetData(_geom, _data);
+	
+		if ( _world->getShowDebugGeometries() )
+		{
+			destroyDebugObject();
+			createDebugObject();
+		}
+	}
+	else // setting it to a NULL
+	{
+	
+		_dataPtr = dataPtr;
+		
+		_data			= NULL;
+		_vertex_count	= 0;
+		_index_count	= 0;
+		_vertices		= NULL;
+		_indices		= NULL;
+		
+		dGeomTriMeshSetData(_geom, _data);
+		
+		if ( _world->getShowDebugGeometries() )
+		{
+			destroyDebugObject();
+			createDebugObject();
+		}
+		//printf ("TriangleMeshGeometry::changeTriangleMeshData error : The TriangleMeshDataPtr passed in isNull\n");
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+Vector3 TriangleMeshGeometry::getPoint(unsigned int index,const Ogre::Vector3& uv)
+{
+	dVector3 out;
+	dGeomTriMeshGetPoint(_geom, (int) index, (dReal)uv.x, (dReal)uv.y, out); 
+	return Ogre::Vector3((Real)out[0],(Real)out[1],(Real)out[2]);
+}
+
+//------------------------------------------------------------------------------------------------
+TriangleMeshTriangle TriangleMeshGeometry::getTriangle(int index)
+{
+	dVector3 v0,v1,v2;
+	dGeomTriMeshGetTriangle(_geom,(int)index, &v0, &v1, &v2); 
+	
+	TriangleMeshTriangle tri;
+
+	tri.v0.x = v0[0]; tri.v0.y = v0[1]; tri.v0.z = v0[2];
+	tri.v1.x = v1[0]; tri.v1.y = v1[1]; tri.v1.z = v1[2];
+	tri.v2.x = v2[0]; tri.v2.y = v2[1]; tri.v2.z = v2[2];
+	
+	return tri;
+}
+
+//------------------------------------------------------------------------------------------------
+void TriangleMeshGeometry::clearTemporalCoherenceCache()
+{
+	dGeomTriMeshClearTCCache(_geom); 
+}
+
+//------------------------------------------------------------------------------------------------
+void TriangleMeshGeometry::enableTemporalCoherence(Geometry::Class geometry_class, bool enable)
+{
+	assert((geometry_class == Geometry::Class_Sphere)||(geometry_class == Geometry::Class_Box));
+	dGeomTriMeshEnableTC(_geom,(int)geometry_class,(enable)?1:0); 
+}
+
+//------------------------------------------------------------------------------------------------
+bool TriangleMeshGeometry::isTemporalCoherenceEnabled(Geometry::Class geometry_class)
+{
+	return ((dGeomTriMeshIsTCEnabled(_geom,(int)geometry_class))?true:false);
+}
+
+//------------------------------------------------------------------------------------------------
+int TriangleMeshGeometry::_collisionCallback(dGeomID mesh,dGeomID object,int triangle)
+{
+	TriangleMeshGeometry* trimesh = (TriangleMeshGeometry*)dGeomGetData(mesh);
+	if (trimesh->_collision_listener)
+	{
+		Geometry* geometry = (object)?((Geometry*)dGeomGetData(object)):0;
+		return ((trimesh->_collision_listener->collide(trimesh,geometry,triangle))?1:0);
+	}
+	return 1;
+}
+
+//------------------------------------------------------------------------------------------------
+void TriangleMeshGeometry::setCollisionListener(TriangleMeshCollisionListener* collision_listener)
+{
+	_collision_listener = collision_listener;
+	dGeomTriMeshSetCallback(_geom,(_collision_listener)?TriangleMeshGeometry::_collisionCallback:0); 
+}
+
+//------------------------------------------------------------------------------------------------
+void TriangleMeshGeometry::_intersectionCallback(dGeomID mesh,dGeomID object,const int* triangles,int triangle_count)
+{
+	TriangleMeshGeometry* trimesh = (TriangleMeshGeometry*)dGeomGetData(mesh);
+	if (trimesh->_intersection_listener)
+	{
+		Geometry* geometry = (object)?((Geometry*)dGeomGetData(object)):0;
+		trimesh->_intersection_listener->intersect(trimesh,geometry,triangles,triangle_count);
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+void TriangleMeshGeometry::setIntersectionListener(TriangleMeshIntersectionListener* intersection_listener)
+{
+	_intersection_listener = intersection_listener;
+	dGeomTriMeshSetArrayCallback(_geom,(_intersection_listener)?TriangleMeshGeometry::_intersectionCallback:0); 
+}
+
+//------------------------------------------------------------------------------------------------
+int TriangleMeshGeometry::_rayCallback(dGeomID mesh,dGeomID ray,int triangle,dReal u,dReal v)
+{
+	TriangleMeshGeometry* trimesh = (TriangleMeshGeometry*)dGeomGetData(mesh);
+	if (trimesh->_ray_listener)
+	{
+		RayGeometry* ray_geometry = (ray)?((RayGeometry*)dGeomGetData(ray)):0;
+		return ((trimesh->_ray_listener->collide(trimesh,ray_geometry,triangle,Vector3((Real)u,(Real)v,0.0)))?1:0);
+	}
+	return 1;
+}
+
+//------------------------------------------------------------------------------------------------
+void TriangleMeshGeometry::setRayListener(TriangleMeshRayListener* ray_listener)
+{
+	_ray_listener = ray_listener;
+	dGeomTriMeshSetRayCallback(_geom,(_ray_listener)?TriangleMeshGeometry::_rayCallback:0); 
+}
+
+//------------------------------------------------------------------------------------------------
+void TriangleMeshGeometry::createDebugObject()
+{
+	if (_index_count != 0)
+	{
+		_debug_obj = new TriangleMeshDebugObject((_index_count / 3) * 6);
+		TriangleMeshDebugObject* obj = static_cast<TriangleMeshDebugObject*>(_debug_obj);
+
+		obj->beginDefinition();
+		for(unsigned int i = 0,j = 0;i < _index_count;i+=3,j+=6)
+		{
+			obj->setVertex(j,Vector3((Real)_vertices[_indices[i]][0],(Real)_vertices[_indices[i]][1],(Real)_vertices[_indices[i]][2]));
+			obj->setVertex(j+1,Vector3((Real)_vertices[_indices[i+1]][0],(Real)_vertices[_indices[i+1]][1],(Real)_vertices[_indices[i+1]][2]));
+
+			obj->setVertex(j+2,Vector3((Real)_vertices[_indices[i+1]][0],(Real)_vertices[_indices[i+1]][1],(Real)_vertices[_indices[i+1]][2]));
+			obj->setVertex(j+3,Vector3((Real)_vertices[_indices[i+2]][0],(Real)_vertices[_indices[i+2]][1],(Real)_vertices[_indices[i+2]][2]));
+
+			obj->setVertex(j+4,Vector3((Real)_vertices[_indices[i+2]][0],(Real)_vertices[_indices[i+2]][1],(Real)_vertices[_indices[i+2]][2]));
+			obj->setVertex(j+5,Vector3((Real)_vertices[_indices[i]][0],(Real)_vertices[_indices[i]][1],(Real)_vertices[_indices[i]][2]));
+		}
+		obj->endDefinition();
+
+		Geometry::createDebugObject();
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+TriangleMeshGeometry::~TriangleMeshGeometry()
+{
+	if (_dataPtr.isNull())
+	{
+		dGeomTriMeshDataDestroy(_data); 
+		delete[] _vertices;
+		delete[] _indices;
+	}
+}
+
+
+//------------------------------------------------------------------------------------------------
+ConvexGeometry::ConvexGeometry(const Ogre::Vector3* vertices,
+							   unsigned int vertex_count,
+							   const unsigned int* indices,
+							   unsigned int index_count,
+                               World *world, Space* space) : 
+    Geometry(world, space),
+    _vertex_count (vertex_count),
+    _index_count (index_count)
+{
+	_vertices = new dReal[vertex_count*3];
+	_indices = new unsigned int[index_count];
+
+	for(unsigned int i = 0;i < vertex_count;i++)
+	{
+		_vertices[i*3 + 0] = (dReal)vertices[i].x;
+		_vertices[i*3 + 1] = (dReal)vertices[i].y;
+		_vertices[i*3 + 2] = (dReal)vertices[i].z;
+	}
+
+	memcpy(_indices,indices,sizeof(unsigned int) * index_count);
+
+
+	_geom = dCreateConvex (getSpaceID(space),
+		0,//dReal *_planes,
+		0,//unsigned int _planecount,
+		_vertices,
+		vertex_count,
+		0);//unsigned int *_polygons)
+
+	// 	dGeomSetConvex (dGeomID g,
+	// 		dReal *_planes,
+	// 		unsigned int _count,
+	// 		dReal *_points,
+	// 		unsigned int _pointcount,unsigned int *_polygons);
+
+	registerGeometry();
+}
+//------------------------------------------------------------------------------------------------
+void ConvexGeometry::createDebugObject()
+{
+	_debug_obj = new TriangleMeshDebugObject((_index_count / 3) * 6);
+	TriangleMeshDebugObject* obj = static_cast<TriangleMeshDebugObject*>(_debug_obj);
+
+	obj->beginDefinition();
+	for(unsigned int i = 0,j = 0;i < _index_count;i+=3,j+=6)
+	{
+		obj->setVertex(j,Vector3((Real)_vertices[_indices[i]*3 + 0],(Real)_vertices[_indices[i]*3 + 1],(Real)_vertices[_indices[i]*3 + 2]));
+		obj->setVertex(j+1,Vector3((Real)_vertices[_indices[i+1]*3 + 0],(Real)_vertices[_indices[i+1]*3 + 1],(Real)_vertices[_indices[i+1]*3 + 2]));
+
+		obj->setVertex(j+2,Vector3((Real)_vertices[_indices[i+1]*3 + 0],(Real)_vertices[_indices[i+1]*3 + 1],(Real)_vertices[_indices[i+1]*3 + 2]));
+		obj->setVertex(j+3,Vector3((Real)_vertices[_indices[i+2]*3 + 0],(Real)_vertices[_indices[i+2]*3 + 1],(Real)_vertices[_indices[i+2]*3 + 2]));
+
+		obj->setVertex(j+4,Vector3((Real)_vertices[_indices[i+2]*3 + 0],(Real)_vertices[_indices[i+2]*3 + 1],(Real)_vertices[_indices[i+2]*3 + 2]));
+		obj->setVertex(j+5,Vector3((Real)_vertices[_indices[i]*3 + 0],(Real)_vertices[_indices[i]*3 + 1],(Real)_vertices[_indices[i]*3 + 2]));
+	}
+	obj->endDefinition();
+
+	Geometry::createDebugObject();
+}
+//------------------------------------------------------------------------------------------------
+ConvexGeometry::~ConvexGeometry()
+{
+	delete[] _vertices;
+	delete[] _indices;
+}
+
+//------------------------------------------------------------------------------------------------
+TerrainGeometry::TerrainGeometry(World *world, Space* space,
+								const Ogre::Vector3 &scale,
+                                int nodes_per_sideX,
+                                int nodes_per_sideY,
+                                Ogre::Real worldSizeX,
+                                Ogre::Real worldSizeZ,
+								bool centered,
+                                Ogre::Real thickness) :
+                        Geometry(world, space),
+                        _sample_width(scale.x),
+                        _sample_height(scale.z),
+                        _max_height (scale.y),
+                        _halfWorldSizeX(worldSizeX * 0.5),
+                        _halfWorldSizeZ(worldSizeZ * 0.5),
+                        _centered(centered)
+{
+	dHeightfieldDataID heightid = dGeomHeightfieldDataCreate();
+	dGeomHeightfieldDataBuildCallback(	heightid, //getSpaceID(space), 
+										this, // pUserData ?
+										TerrainGeometry::_heightCallback, 
+										(dReal) (worldSizeX), //X
+										(dReal) (worldSizeZ), //Z
+										nodes_per_sideX, // w // Vertex count along edge >= 2
+										nodes_per_sideY, // h // Vertex count along edge >= 2
+										REAL( 1.0 ),     //scale
+										REAL( 0.0 ),	// vOffset
+										thickness,	// vThickness
+										 0); // nWrapMode
+
+
+	// Give some very bounds which, while conservative,
+	// makes AABB computation more accurate than +/-INF.
+	dGeomHeightfieldDataSetBounds( heightid, REAL( 0.0 ),  _max_height );
+	_geom = dCreateHeightfield( getSpaceID(space), heightid, 1 );
+
+	_listener = 0;
+	_ray = Ogre::Ray (Ogre::Vector3::ZERO, Ogre::Vector3::NEGATIVE_UNIT_Y);
+	_ray_query = _world->getSceneManager()->createRayQuery(_ray);
+
+	_ray_query->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK );
+	_ray_query->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION); 
+
+	registerGeometry();
+
+	if (_centered)
+	{
+		// PLSM2 is centered by default.	
+        //setPosition (Ogre::Vector3::ZERO);
+        ;
+	}
+	else
+	{
+        // TSM is not centered by default.	
+		setPosition (Ogre::Vector3(_halfWorldSizeX, 
+                                    0, 
+                                    _halfWorldSizeZ));
+	}
+	setOrientation(Ogre::Quaternion::ZERO);
+}
+
+//------------------------------------------------------------------------------------------------
+dReal TerrainGeometry::_heightCallback(void* data,int x,int z)
+{
+	TerrainGeometry * const terrain = (TerrainGeometry*)data;    
+	if (terrain->_listener)
+	{
+		return static_cast <dReal> (terrain->_listener->heightAt(Vector3((Ogre::Real)x,
+                                                                terrain->_max_height,
+                                                                (Ogre::Real)z)));
+	}
+    else
+    {
+        return static_cast <dReal> (terrain->getHeightAt(Vector3((Ogre::Real)x, 
+                                                        terrain->_max_height, 
+                                                        (Ogre::Real)z)));
+    }
+}
+
+//------------------------------------------------------------------------------------------------
+Ogre::Real TerrainGeometry::getPointDepth(const Ogre::Vector3& point)
+{
+	//return (Real)dGeomTerrainCallbackPointDepth(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z); 
+	//return (Real) dGeomHeightfieldPointDepth (_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z);
+	//dGetDepthFn(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z);
+	return (Real) 0.0;
+}
+
+//------------------------------------------------------------------------------------------------
+void TerrainGeometry::setHeightListener(TerrainGeometryHeightListener* listener)
+{
+	_listener = listener;
+}
+//------------------------------------------------------------------------------------------------
+bool TerrainGeometry::queryResult(Ogre::MovableObject *obj, Ogre::Real distance)
+{
+	return false;
+}
+
+//------------------------------------------------------------------------------------------------
+bool TerrainGeometry::queryResult(Ogre::SceneQuery::WorldFragment *fragment,Ogre::Real distance)
+{
+	_distance_to_terrain = distance;
+	return false;
+}
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& TerrainGeometry::getPosition()
+{
+	return Ogre::Vector3::ZERO;
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Quaternion& TerrainGeometry::getOrientation()
+{
+	return Ogre::Quaternion::ZERO;
+}
+
+//------------------------------------------------------------------------------------------------
+TerrainGeometry::~TerrainGeometry()
+{
+	_world->getSceneManager()->destroyQuery(_ray_query);
+}
+
+//------------------------------------------------------------------------------------------------
+std::list<Ogre::Plane>* PlaneBoundedRegionGeometry::_planeCallback(void* data,int x,int z)
+{
+    PlaneBoundedRegionGeometry* terrain = (PlaneBoundedRegionGeometry*)data;
+
+    if (terrain->_listener)
+    {
+        return terrain->_listener->planesAt(Vector3((Ogre::Real)x,
+            terrain->_max_height,
+            (Ogre::Real)z));
+    }
+    else
+    {
+        return  terrain->planesAt(Vector3((Ogre::Real)x, 
+                terrain->_max_height, 
+                (Ogre::Real)z));
+    }
+    return 0;
+}
+//------------------------------------------------------------------------------------------------
+PlaneBoundedRegionGeometry::PlaneBoundedRegionGeometry (World *world, Space* space,
+                                                        const Ogre::AxisAlignedBox &Size) : 
+    Geometry(world,space)
+{
+
+    _ray = Ogre::Ray (Ogre::Vector3::ZERO, Ogre::Vector3::NEGATIVE_UNIT_Y);
+    _ray_query = _world->getSceneManager()->createRayQuery(_ray);
+
+    _ray_query->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK );
+    _ray_query->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION); 
+
+}
+
+//------------------------------------------------------------------------------------------------
+Ogre::Real PlaneBoundedRegionGeometry::getPointDepth(const Ogre::Vector3& point)
+{
+    //dGetDepthFn(_geom,(dReal)point.x,(dReal)point.y,(dReal)point.z);
+    return (Real) 0.0;
+}
+
+//------------------------------------------------------------------------------------------------
+void PlaneBoundedRegionGeometry::setPlaneListener(PlaneBoundedRegionGeometryPlaneListener* listener)
+{
+    _listener = listener;
+}
+//------------------------------------------------------------------------------------------------
+bool PlaneBoundedRegionGeometry::queryResult(Ogre::MovableObject *obj, Ogre::Real distance)
+{
+    return false;
+}
+
+//------------------------------------------------------------------------------------------------
+bool PlaneBoundedRegionGeometry::queryResult(Ogre::SceneQuery::WorldFragment *fragment,Ogre::Real distance)
+{
+    _distance_to_terrain = distance;
+    return false;
+}
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& PlaneBoundedRegionGeometry::getPosition()
+{
+    return Ogre::Vector3::ZERO;
+}
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Quaternion& PlaneBoundedRegionGeometry::getOrientation()
+{
+    return Ogre::Quaternion::ZERO;
+}
+
+//------------------------------------------------------------------------------------------------
+PlaneBoundedRegionGeometry::~PlaneBoundedRegionGeometry()
+{
+    _world->getSceneManager()->destroyQuery(_ray_query);
+}
+
+
Index: code/branches/physics/src/ogreode/OgreOdeGeometry.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeGeometry.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeGeometry.h	(revision 1919)
@@ -0,0 +1,613 @@
+#ifndef _OGREODEGEOMETRY_H_
+#define _OGREODEGEOMETRY_H_
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeMaintainedList.h"
+
+#include "OgreOdeTriangleMeshData.h"
+
+namespace OgreOde 
+{
+    /** 
+    This object is the base class for all Geometry objects in OgreOde.
+    @remarks
+        This object is tied either to a Body (acting as collision proxy for a physic object) 
+        or to a Entity Object (which then is physically "static")
+    @remarks
+        It extends the OGRE UserDefinedObject to allow reverse links from Ogre::Entity.
+        Note that this class does not override the UserDefinedObject's getTypeId method 
+        because this class is abstract.
+    */  
+    class _OgreOdeExport Geometry : public Ogre::UserDefinedObject, public Ogre::MovableObject
+	{
+		friend class Space;
+        friend class World;
+        friend class Body;
+		friend class TransformGeometry;
+
+	public:
+		enum Class
+		{
+			Class_Sphere		= dSphereClass,
+			Class_Box			= dBoxClass,
+			Class_Capsule		= dCapsuleClass,
+			Class_Cylinder		= dCCylinderClass,
+			Class_InfinitePlane = dPlaneClass,
+			Class_Ray			= dRayClass,
+			Class_TriangleMesh	= dTriMeshClass,
+			Class_Terrain		= dHeightfieldClass,
+			Class_Convex		= dConvexClass,
+			Class_Transform		= dGeomTransformClass,
+			Class_NoGeometry
+		};
+
+	public:
+        Geometry(World *world,  Space* space = 0);
+		virtual ~Geometry();
+
+		virtual void                        setBody(Body* body);
+		Body*                               getBody(); 
+
+
+		virtual void                        setPosition(const Ogre::Vector3& position);
+		virtual void                        setOrientation(const Ogre::Quaternion& orientation);	
+		virtual const Ogre::Vector3&        getPosition();
+		virtual const Ogre::Quaternion&     getOrientation();
+		virtual const Ogre::AxisAlignedBox& getAxisAlignedBox(); 
+
+
+		Space*                              getSpace(); 
+
+		void                                 enable();
+		void                                 disable();
+		bool                                 isEnabled(); 
+
+		Geometry::Class                     getClass() const; 
+
+        void                                 setCategoryBitfield(unsigned long bits); 
+        void                                 setCollisionBitfield(unsigned long bits); 
+		unsigned long						 getCategoryBitfield(); 
+		unsigned long						 getCollisionBitfield(); 
+
+		int                                 collide(Geometry* geometry, CollisionListener* listener = 0);
+
+		void                                setMaxContacts(unsigned int max_contacts);
+		unsigned int                        getMaxContacts() const;
+		unsigned int                        getContactHighWaterMark() const;
+
+		void                                setEncapsulator(Geometry* encapsulator);
+		Geometry*                           getEncapsulator(){return _encapsulator;}
+
+		void                                setUserData(size_t user_data){_user_data = user_data;}
+		size_t								getUserData() const {return _user_data;}
+
+		void                                setUserObject(UserDefinedObject* object){_user_object = object;}
+		UserDefinedObject*                  getUserObject(){return _user_object;}
+
+		virtual size_t						 getID() const ;
+		virtual void                        notify(Body* body);
+
+
+        virtual void                        setDebug(const bool debug);
+        virtual void                        createDebugObject();
+        virtual void                        destroyDebugObject();
+        void                                reparentDebugObject(Ogre::Node* node);
+
+        virtual void                        setDebugContact(const bool debug);
+        void                                updateDebugContact();
+
+		void                                clearOffset();
+		int                                 isOffset();
+
+		void                                setOffsetPosition (const Ogre::Vector3 &position);
+		void                                setOffsetQuaternion(const Ogre::Quaternion &orientation);
+
+		 void                               setOffsetWorldPosition(const Ogre::Vector3 &position);		
+		 void                               setOffsetWorldQuaternion(const Ogre::Quaternion &orientation) ;
+
+		 Ogre::Vector3                      getOffsetPosition() ;
+		 Ogre::Quaternion                   getOffsetQuaternion() ;
+
+
+		/**	returns mGeometry's AABB
+		*/
+		virtual const Ogre::AxisAlignedBox& getBoundingBox(void) const	{return _bounding_box; };
+
+		/**
+		*/
+		static const Ogre::String MovableType;
+		virtual const Ogre::String& getMovableType() const { return MovableType; }; 
+
+		/**
+		*/		
+		virtual Ogre::Real getBoundingRadius(void) const { return Ogre::Real(0.0); }
+		
+		/**
+		*/
+		virtual void _updateRenderQueue(Ogre::RenderQueue* queue){}
+		
+		/** added for Ogre 1.5
+		*/
+#if OGRE_VERSION >= ((1 << 16) | (5 << 8))
+		virtual void visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables = false){}
+#endif
+
+		/** set mParentNode and sets mGeometrys position and orientation to match mParentNode's
+		*/
+		virtual void _notifyAttached(Ogre::Node* parent, bool isTagPoint = false);
+		
+		/** sets mGeometry position and orientation to match mParentNode's
+		*/
+		virtual void _notifyMoved();
+		
+		
+		virtual const Ogre::String& getName (void) const { return mName; }
+		
+		/** setting mName is not important - its not actually being used
+		it just helps debugging code
+		*/
+		void setName (Ogre::String name){ mName = name; }
+
+
+
+	protected:
+		dGeomID                             getGeometryID() const;
+		void                                registerGeometry();
+		dSpaceID                            getSpaceID(Space* space) const;
+
+	protected:
+		Ogre::String						mName;
+		dGeomID                             _geom;
+		unsigned int                        _max_contacts;
+        unsigned int                        _contact_high_water_mark;
+        unsigned int                        _last_contact_num;
+		dContact*                           _contacts;
+
+		DebugObject*                        _debug_obj;
+        Ogre::Node*                         _debug_node;
+        DebugContact**                      _debug_contacts;
+
+		Geometry*                           _encapsulator;
+		Ogre::AxisAlignedBox                _bounding_box;
+		Ogre::Quaternion                    _orientation;
+		Ogre::Vector3                       _position;
+
+		static int                          _geometry_count;
+		size_t								_user_data;
+		UserDefinedObject*                  _user_object;
+        World                               *_world;
+
+	};
+
+	//------------------------------------------------------------------------------------------------
+    class _OgreOdeExport SphereGeometry:public Geometry
+	{
+	public:
+		SphereGeometry(Ogre::Real radius, World *world, Space* space = 0);
+		~SphereGeometry();
+
+		virtual void createDebugObject();
+
+		void setRadius(Ogre::Real radius);
+		Ogre::Real getRadius();
+        Ogre::Real getPointDepth(const Ogre::Vector3& point);  
+        /** Return a string identifying the type of user defined object.
+           @remarks
+           Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Sphere");return sName;};
+
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport BoxGeometry:public Geometry
+	{
+	public:
+		BoxGeometry(const Ogre::Vector3& size,  World *world, Space* space = 0);
+		~BoxGeometry();
+
+		virtual void createDebugObject();
+
+		void setSize(const Ogre::Vector3& size);
+		const Ogre::Vector3& getSize();
+		Ogre::Real getPointDepth(const Ogre::Vector3& point);
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Box");return sName;};
+
+	protected:
+		Ogre::Vector3 _size;
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport InfinitePlaneGeometry:public Geometry
+	{
+	public:
+		InfinitePlaneGeometry(const Ogre::Plane& plane, World *world, Space* space = 0);
+		~InfinitePlaneGeometry();
+
+		void setDefinition(const Ogre::Plane& plane);
+		const Ogre::Plane& getDefinition();
+		Ogre::Real getPointDepth(const Ogre::Vector3& point);
+
+		void setPosition(const Ogre::Vector3& position);
+		void setOrientation(const Ogre::Quaternion& orientation);	
+		const Ogre::Vector3& getPosition();
+		const Ogre::Quaternion& getOrientation();
+		const Ogre::AxisAlignedBox& getAxisAlignedBox(); 
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Infinity Plane");return sName;};
+
+	protected:
+		Ogre::Plane _plane;
+    };
+    //------------------------------------------------------------------------------------------------
+	class _OgreOdeExport CapsuleGeometry:public Geometry
+	{
+	public:
+		CapsuleGeometry(Ogre::Real radius, Ogre::Real length, World *world, Space* space = 0);
+		~CapsuleGeometry();
+
+		virtual void createDebugObject();
+ 
+		void setDefinition(Ogre::Real radius, Ogre::Real length);
+		Ogre::Real getRadius();
+		Ogre::Real getLength();
+		Ogre::Real getPointDepth(const Ogre::Vector3& point);
+
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Capsule");return sName;};
+
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport CylinderGeometry:public Geometry
+	{
+	public:
+		CylinderGeometry(Ogre::Real radius, Ogre::Real length, World *world, Space* space = 0);
+		~CylinderGeometry();
+
+		virtual void createDebugObject();
+
+		void setDefinition(Ogre::Real radius, Ogre::Real length);
+		Ogre::Real getRadius();
+		Ogre::Real getLength();
+		Ogre::Real getPointDepth(const Ogre::Vector3& point);
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Cylinder");return sName;};
+
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport RayGeometry:public Geometry
+	{
+	public:
+		RayGeometry(Ogre::Real length, World *world, Space* space = 0);
+		~RayGeometry();
+
+		virtual void createDebugObject();
+		
+		void setLength(Ogre::Real length);
+		Ogre::Real getLength();
+		void setDefinition(const Ogre::Vector3& start, const Ogre::Vector3& direction);
+		const Ogre::Vector3& getStart();
+		const Ogre::Vector3& getDirection();
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Ray");return sName;};
+
+	protected:
+		Ogre::Vector3 _direction,_start;
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport TransformGeometry:public Geometry
+	{
+	public:
+		TransformGeometry(World *world, Space* space);
+		~TransformGeometry();
+
+		virtual void createDebugObject();
+		virtual void destroyDebugObject();
+
+		void setEncapsulatedGeometry(Geometry* geometry);
+		Geometry* getEncapsulatedGeometry() const;
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Transform");return sName;};
+
+	};
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport TriangleMeshCollisionListener
+	{
+	public:
+		TriangleMeshCollisionListener(){}
+		virtual ~TriangleMeshCollisionListener(){}
+
+		virtual bool collide(TriangleMeshGeometry* triangle_mesh, Geometry* geometry, int triangle) {return true;}
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport TriangleMeshIntersectionListener
+	{
+	public:
+		TriangleMeshIntersectionListener(){}
+		virtual ~TriangleMeshIntersectionListener(){}
+
+		virtual void intersect(TriangleMeshGeometry* triangle_mesh, Geometry* geometry, const int* triangles, int triangle_count){}
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport TriangleMeshRayListener
+	{
+	public:
+		TriangleMeshRayListener(){}
+		virtual ~TriangleMeshRayListener(){}
+
+		virtual bool collide(TriangleMeshGeometry* triangle_mesh, RayGeometry* ray,int triangle, const Ogre::Vector3& uv){return true;}
+	};
+
+	//------------------------------------------------------------------------------------------------
+	struct _OgreOdeExport TriangleMeshTriangle
+	{
+		Ogre::Vector3 v0,v1,v2;
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport TriangleMeshGeometry:public Geometry
+	{
+	public:
+		TriangleMeshGeometry(const Ogre::Vector3* vertices, 
+                             unsigned int vertex_count, 
+                             const TriangleIndex* indices,
+                             unsigned int index_count,
+                             World *world, 
+                             Space* space = 0);
+		
+		TriangleMeshGeometry(TriangleMeshDataPtr dataPtr, World *world, Space* space = 0);
+		
+		void changeTriangleMeshData(TriangleMeshDataPtr dataPtr);
+		
+		TriangleMeshDataPtr TriangleMeshGeometry::getTriangleMeshData(){ return _dataPtr; }
+		
+		~TriangleMeshGeometry();
+
+		Ogre::Vector3 getPoint(unsigned int index, const Ogre::Vector3& uv);
+		TriangleMeshTriangle getTriangle(int index);
+
+		void clearTemporalCoherenceCache(); 
+		void enableTemporalCoherence(Geometry::Class geometry_class,bool enable); 
+		bool isTemporalCoherenceEnabled(Geometry::Class geometry_class);
+
+		static int _collisionCallback(dGeomID mesh,dGeomID object,int triangle);
+		void setCollisionListener(TriangleMeshCollisionListener* collision_listener);
+
+		static void _intersectionCallback(dGeomID mesh,dGeomID object,const int* triangles,int triangle_count);
+		void setIntersectionListener(TriangleMeshIntersectionListener* intersection_listener); 
+
+		static int _rayCallback(dGeomID mesh,dGeomID ray,int triangle,dReal u,dReal v);
+		void setRayListener(TriangleMeshRayListener* ray_listener); 
+
+		virtual void createDebugObject();
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Trimesh");return sName;};
+
+	protected:
+		dTriMeshDataID _data;
+		dVector3* _vertices;
+		unsigned int* _indices;
+		unsigned int _vertex_count;
+        unsigned int _index_count;
+
+		TriangleMeshDataPtr _dataPtr;
+		
+		TriangleMeshCollisionListener* _collision_listener;
+		TriangleMeshIntersectionListener* _intersection_listener;
+		TriangleMeshRayListener* _ray_listener;
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport ConvexGeometry:public Geometry
+	{
+	public:
+		ConvexGeometry(const Ogre::Vector3* vertices, 
+						unsigned int vertex_count, 
+						const unsigned int* indices,
+						unsigned int index_count,
+						World *world, 
+                        Space* space = 0);
+		~ConvexGeometry();
+
+
+		virtual void createDebugObject();
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Convex");return sName;};
+
+	protected:
+		dReal	* _vertices;
+		unsigned int* _indices;
+		unsigned int _vertex_count;
+		unsigned int _index_count;
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport TerrainGeometryHeightListener
+	{
+	public:
+		TerrainGeometryHeightListener(){}
+		virtual ~TerrainGeometryHeightListener(){}
+
+		virtual Ogre::Real heightAt(const Ogre::Vector3& position) = 0;
+	};
+
+	//------------------------------------------------------------------------------------------------
+	class _OgreOdeExport TerrainGeometry:public Geometry, public Ogre::RaySceneQueryListener
+	{
+	public:
+        TerrainGeometry(World *world, 
+                        Space* space,
+                        const Ogre::Vector3 &scale,
+                        int nodes_per_sideX,
+                        int nodes_per_sideY,
+                        Ogre::Real worldSizeX,
+                        Ogre::Real worldSizeZ,
+                        bool centered,
+                        Ogre::Real thickness = 10.0f);
+
+		~TerrainGeometry();
+
+		Ogre::Real getPointDepth(const Ogre::Vector3& point);
+		const Ogre::Vector3& getPosition();
+		const Ogre::Quaternion& getOrientation();
+		
+		static dReal _heightCallback(void* data, dReal x, dReal z);
+		static dReal _heightCallback(void* data, int x, int z);
+		void setHeightListener(TerrainGeometryHeightListener* listener);
+
+        inline Ogre::Real getHeightAt(const Ogre::Vector3& position)
+        {
+            _num_query++;
+            const Ogre::Vector3 pos (position.x * _sample_width - (_centered?_halfWorldSizeX:0),
+                position.y,
+                position.z * _sample_height - (_centered?_halfWorldSizeZ:0)); 
+            _ray.setOrigin(pos);
+            _ray_query->setRay(_ray);
+            _distance_to_terrain = static_cast<Ogre::Real>(0.0);
+            _ray_query->execute(this);
+            return position.y - _distance_to_terrain;
+        }
+
+		bool queryResult(Ogre::MovableObject *obj, Ogre::Real distance);
+		bool queryResult(Ogre::SceneQuery::WorldFragment *fragment, Ogre::Real distance);
+
+        size_t getNumQueries() const {return _num_query;};
+        void resetNumQueries(){_num_query = 0;};
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Terrain");return sName;};
+
+	protected:
+		Ogre::Real _max_height;
+		Ogre::Real _distance_to_terrain;
+		Ogre::Real _sample_width, _sample_height;
+		TerrainGeometryHeightListener* _listener;
+		Ogre::Ray _ray;
+		Ogre::RaySceneQuery* _ray_query;
+        bool _centered;
+        Ogre::Real _halfWorldSizeX; 
+        Ogre::Real _halfWorldSizeZ;
+        size_t _num_query;
+    };
+    //------------------------------------------------------------------------------------------------
+    class _OgreOdeExport PlaneBoundedRegionGeometryPlaneListener
+    {
+    public:
+        PlaneBoundedRegionGeometryPlaneListener(){}
+        virtual ~PlaneBoundedRegionGeometryPlaneListener(){}
+
+        virtual std::list<Ogre::Plane>* planesAt(const Ogre::Vector3& position) = 0;
+    };
+
+    //------------------------------------------------------------------------------------------------
+    class _OgreOdeExport PlaneBoundedRegionGeometry:public Geometry, public Ogre::RaySceneQueryListener
+    {
+    public:
+        PlaneBoundedRegionGeometry(World *world, 
+                                    Space* space,
+                                    const Ogre::AxisAlignedBox &scale);
+
+        ~PlaneBoundedRegionGeometry();
+
+        Ogre::Real getPointDepth(const Ogre::Vector3& point);
+        const Ogre::Vector3& getPosition();
+        const Ogre::Quaternion& getOrientation();
+
+        static std::list<Ogre::Plane> * _planeCallback(void* data, dReal x, dReal z);
+        static std::list<Ogre::Plane> * _planeCallback(void* data, int x, int z);
+        void setPlaneListener(PlaneBoundedRegionGeometryPlaneListener* listener);
+
+        inline std::list<Ogre::Plane> *planesAt(const Ogre::Vector3& position)
+        {
+            _num_query++;
+//             const Ogre::Vector3 pos (position.x * _sample_width - (_centered?_halfWorldSizeX:0),
+//                                     position.y,
+//                                     position.z * _sample_height - (_centered?_halfWorldSizeZ:0)); 
+//             _ray.setOrigin(pos);
+//             _ray_query->setRay(_ray);
+//             _distance_to_terrain = static_cast<Ogre::Real>(0.0);
+//             _ray_query->execute(this);
+
+            return _last_query_results;
+
+        }
+
+        bool queryResult(Ogre::MovableObject *obj, Ogre::Real distance);
+        bool queryResult(Ogre::SceneQuery::WorldFragment *fragment, Ogre::Real distance);
+
+        size_t getNumQueries() const {return _num_query;};
+        void resetNumQueries(){_num_query = 0;};
+
+        /** Return a string identifying the type of user defined object.
+        @remarks
+        Used to differentiate between different Bodies, Geometries and prefab_object
+        */
+        const Ogre::String& getTypeName(void) const
+        {static Ogre::String sName("Geometry Plane Bounded Region");return sName;};
+
+    protected:
+        Ogre::Real _max_height;
+        Ogre::Real _distance_to_terrain;
+        Ogre::Real _sample_width, _sample_height;
+        PlaneBoundedRegionGeometryPlaneListener* _listener;
+        Ogre::Ray _ray;
+        Ogre::RaySceneQuery* _ray_query;
+        bool _centered;
+        Ogre::Real _halfWorldSizeX; 
+        Ogre::Real _halfWorldSizeZ;
+        size_t _num_query;
+
+        std::list<Ogre::Plane> *_last_query_results;
+    };
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdeJoint.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeJoint.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeJoint.cpp	(revision 1919)
@@ -0,0 +1,903 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeGeometry.h"
+#include "OgreOdeWorld.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeGeometry.h"
+#include "OgreOdeJoint.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+//------------------------------------------------------------------------------------------------
+JointGroup::JointGroup(World *world):
+_world(world)
+{
+	_joint_group = dJointGroupCreate(0); 
+	_world->getJointGroupList().registerItem(this);
+}
+//------------------------------------------------------------------------------------------------
+dJointGroupID JointGroup::getJointGroupID() const
+{
+	return _joint_group;
+}
+
+size_t JointGroup::getID()
+{
+	return (size_t)_joint_group;
+}
+
+void JointGroup::empty()
+{
+	dJointGroupEmpty(_joint_group); 
+}
+
+JointGroup::~JointGroup()
+{
+	_world->getJointGroupList().unregisterItem((size_t)_joint_group);
+	dJointGroupDestroy(_joint_group); 
+}
+
+Joint::Joint(World *world, const JointGroup* group):
+    _world(world)
+{
+}
+
+void Joint::registerJoint()
+{
+	_world->getJointList().registerItem(this);
+}
+
+void Joint::setAnchor(const Ogre::Vector3& position)
+{
+}
+
+void Joint::addTorque(Real torque,Real torque2,Real torque3)
+{
+}
+
+void Joint::addForce(Real force,Real force2,Real force3)
+{
+}
+
+const Ogre::Vector3& Joint::getAnchor()
+{
+	return Ogre::Vector3::ZERO;
+}
+
+const Ogre::Vector3& Joint::getAnchorError()
+{
+	return Ogre::Vector3::ZERO;
+}
+
+void Joint::setAxis(const Ogre::Vector3& axis)
+{
+}
+
+const Ogre::Vector3& Joint::getAxis()
+{
+	return Ogre::Vector3::ZERO;
+}
+
+void Joint::setAdditionalAxis(const Ogre::Vector3& axis)
+{
+}
+
+const Ogre::Vector3& Joint::getAdditionalAxis()
+{
+	return Ogre::Vector3::ZERO;
+}
+
+Real Joint::getAngle()
+{
+	return 0.0;
+}
+
+Real Joint::getAngleRate()
+{
+	return 0.0;
+}
+
+Real Joint::getPosition()
+{
+	return 0.0;
+}
+
+Real Joint::getPositionRate()
+{
+	return 0.0;
+}
+
+size_t Joint::getID()
+{
+	return (size_t)_joint;
+}
+
+Joint::~Joint()
+{
+	_world->getJointList().unregisterItem((size_t)_joint);
+	dJointDestroy(_joint); 
+}
+
+dWorldID Joint::getWorldID()
+{
+	return _world->getWorldID();
+}
+
+dJointGroupID Joint::getJointGroupID(const JointGroup* group) const
+{
+	return ((group)?group->getJointGroupID():0);
+}
+
+dJointID Joint::getJointID()
+{
+	return _joint;
+}
+
+Joint::Type Joint::getType()
+{
+	return (Joint::Type)(dJointGetType(_joint));
+}
+
+Body* Joint::getFirstBody()
+{
+	dBodyID b = dJointGetBody(_joint, 0); 
+	return ((Body*)dBodyGetData(b));
+}
+
+Body* Joint::getSecondBody()
+{
+	dBodyID b = dJointGetBody(_joint,1);
+	return b ? ((Body*)dBodyGetData(b)) : 0; 
+}
+
+bool Joint::areConnected(const Body* body_a,const Body* body_b)
+{
+	return (dAreConnected(body_a->getBodyID(),body_b->getBodyID()))?true:false; 
+}
+
+bool Joint::areConnectedExcluding(const Body* body_a,const Body* body_b,Joint::Type joint_type)
+{
+	return (dAreConnectedExcluding(body_a->getBodyID(),body_b->getBodyID(),(int)joint_type))?true:false; 
+}
+
+void Joint::enableFeedback()
+{
+	dJointSetFeedback(_joint,&_feedback); 
+}
+
+void Joint::disableFeedback()
+{
+	dJointSetFeedback(_joint,0); 
+}
+
+void Joint::detach()
+{
+	dJointAttach(_joint,0,0); 
+}
+
+void Joint::attach(const Body* body)
+{
+	dJointAttach(_joint,body->getBodyID(),0); 
+}
+
+void Joint::attach(const Body* body_a,const Body* body_b)
+{
+	dJointAttach(_joint,body_a->getBodyID(),body_b->getBodyID()); 
+}
+
+const Ogre::Vector3& Joint::getFirstForce()
+{
+	assert(dJointGetFeedback(_joint) == &_feedback);
+
+	_first_force.x = _feedback.f1[0];
+	_first_force.y = _feedback.f1[1];
+	_first_force.z = _feedback.f1[2];
+	return _first_force;
+}
+
+const Ogre::Vector3& Joint::getFirstTorque()
+{
+	assert(dJointGetFeedback(_joint) == &_feedback);
+
+	_first_torque.x = _feedback.t1[0];
+	_first_torque.y = _feedback.t1[1];
+	_first_torque.z = _feedback.t1[2];
+	return _first_torque;
+}
+
+const Ogre::Vector3& Joint::getSecondForce()
+{
+	assert(dJointGetFeedback(_joint) == &_feedback);
+
+	_second_force.x = _feedback.f2[0];
+	_second_force.y = _feedback.f2[1];
+	_second_force.z = _feedback.f2[2];
+	return _second_force;
+}
+
+const Ogre::Vector3& Joint::getSecondTorque()
+{
+	assert(dJointGetFeedback(_joint) == &_feedback);
+
+	_second_torque.x = _feedback.t2[0];
+	_second_torque.y = _feedback.t2[1];
+	_second_torque.z = _feedback.t2[2];
+	return _second_torque;
+}
+
+void Joint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+}
+
+Real Joint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return 0.0;
+}
+
+BallJoint::BallJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreateBall(getWorldID(),getJointGroupID(group));
+	registerJoint();
+}
+
+void BallJoint::setAnchor(const Ogre::Vector3& position)
+{
+	dJointSetBallAnchor(_joint,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+
+const Ogre::Vector3& BallJoint::getAnchor()
+{
+	dVector3 result;
+	dJointGetBallAnchor(_joint,result); 
+	_anchor.x = (Real)result[0];
+	_anchor.y = (Real)result[1];
+	_anchor.z = (Real)result[2];
+	return _anchor;
+}
+
+const Ogre::Vector3& BallJoint::getAnchorError()
+{
+	dVector3 result1,result2;
+	dJointGetBallAnchor(_joint,result1); 
+	dJointGetBallAnchor2(_joint,result2); 
+	_anchor_error.x = (Real)(result1[0] - result2[0]);
+	_anchor_error.y = (Real)(result1[1] - result2[1]);
+	_anchor_error.z = (Real)(result1[2] - result2[2]);
+	return _anchor_error;
+}
+
+void BallJoint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetBallParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value);  
+}
+
+Real BallJoint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return (Real)dJointGetBallParam(_joint,((int)parameter) + dParamGroup * (axis - 1));
+}
+
+
+BallJoint::~BallJoint()
+{
+}
+
+HingeJoint::HingeJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreateHinge(getWorldID(),getJointGroupID(group)); 
+	registerJoint();
+}
+
+void HingeJoint::setAnchor(const Ogre::Vector3& position)
+{
+	dJointSetHingeAnchor(_joint,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+
+void HingeJoint::addTorque(Real torque,Real torque2,Real torque3)
+{
+	dJointAddHingeTorque(_joint,(dReal)torque);
+}
+
+const Ogre::Vector3& HingeJoint::getAnchor()
+{
+	dVector3 result;
+	dJointGetHingeAnchor(_joint,result); 
+	_anchor.x = (Real)result[0];
+	_anchor.y = (Real)result[1];
+	_anchor.z = (Real)result[2];
+	return _anchor;
+}
+
+const Ogre::Vector3& HingeJoint::getAnchorError()
+{
+	dVector3 result1,result2;
+	dJointGetHingeAnchor(_joint,result1); 
+	dJointGetHingeAnchor2(_joint,result2); 
+	_anchor_error.x = (Real)(result1[0] - result2[0]);
+	_anchor_error.y = (Real)(result1[1] - result2[1]);
+	_anchor_error.z = (Real)(result1[2] - result2[2]);
+	return _anchor_error;
+}
+
+void HingeJoint::setAxis(const Ogre::Vector3& axis)
+{
+	dJointSetHingeAxis(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& HingeJoint::getAxis()
+{
+	dVector3 result;
+	dJointGetHingeAxis(_joint,result); 
+	_axis.x = (Real)result[0];
+	_axis.y = (Real)result[1];
+	_axis.z = (Real)result[2];
+	return _axis;
+}
+
+Real HingeJoint::getAngle()
+{
+	return (Real)dJointGetHingeAngle(_joint); 
+}
+
+Real HingeJoint::getAngleRate()
+{
+	return (Real)dJointGetHingeAngleRate(_joint); 
+}
+
+void HingeJoint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetHingeParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value); 
+}
+
+Real HingeJoint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return (Real)dJointGetHingeParam(_joint,((int)parameter) + dParamGroup * (axis - 1));
+}
+
+HingeJoint::~HingeJoint()
+{
+}
+
+SliderJoint::SliderJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreateSlider(getWorldID(),getJointGroupID(group)); 
+	registerJoint();
+}
+
+void SliderJoint::setAxis(const Ogre::Vector3& axis)
+{
+	dJointSetSliderAxis(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& SliderJoint::getAxis()
+{
+	dVector3 result;
+	dJointGetSliderAxis(_joint,result); 
+	_axis.x = (Real)result[0];
+	_axis.y = (Real)result[1];
+	_axis.z = (Real)result[2];
+	return _axis;
+}
+
+void SliderJoint::addForce(Real force,Real force2,Real force3)
+{
+	dJointAddSliderForce(_joint,(dReal)force);
+}
+
+Real SliderJoint::getPosition()
+{
+	return (Real)dJointGetSliderPosition(_joint); 
+}
+
+Real SliderJoint::getPositionRate()
+{
+	return (Real)dJointGetSliderPositionRate(_joint); 
+}
+
+void SliderJoint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetSliderParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value); 
+}
+
+Real SliderJoint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return (Real)dJointGetSliderParam(_joint,((int)parameter) + dParamGroup * (axis - 1));
+}
+
+SliderJoint::~SliderJoint()
+{
+}
+
+UniversalJoint::UniversalJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreateUniversal(getWorldID(),getJointGroupID(group)); 
+	registerJoint();
+}
+
+void UniversalJoint::setAnchor(const Ogre::Vector3& position)
+{
+	dJointSetUniversalAnchor(_joint,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+
+void UniversalJoint::addTorque(Real torque,Real torque2,Real torque3)
+{
+	dJointAddUniversalTorques(_joint,(dReal)torque,(dReal)torque2);
+}
+
+const Ogre::Vector3& UniversalJoint::getAnchor()
+{
+	dVector3 result;
+	dJointGetUniversalAnchor(_joint,result); 
+	_anchor.x = (Real)result[0];
+	_anchor.y = (Real)result[1];
+	_anchor.z = (Real)result[2];
+	return _anchor;
+}
+
+const Ogre::Vector3& UniversalJoint::getAnchorError()
+{
+	dVector3 result1,result2;
+	dJointGetUniversalAnchor(_joint,result1); 
+	dJointGetUniversalAnchor2(_joint,result2); 
+	_anchor_error.x = (Real)(result1[0] - result2[0]);
+	_anchor_error.y = (Real)(result1[1] - result2[1]);
+	_anchor_error.z = (Real)(result1[2] - result2[2]);
+	return _anchor_error;
+}
+
+void UniversalJoint::setAxis(const Ogre::Vector3& axis)
+{
+	dJointSetUniversalAxis1(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& UniversalJoint::getAxis()
+{
+	dVector3 result;
+	dJointGetUniversalAxis1(_joint,result); 
+	_axis.x = (Real)result[0];
+	_axis.y = (Real)result[1];
+	_axis.z = (Real)result[2];
+	return _axis;
+}
+
+void UniversalJoint::setAdditionalAxis(const Ogre::Vector3& axis)
+{
+	dJointSetUniversalAxis2(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& UniversalJoint::getAdditionalAxis()
+{
+	dVector3 result;
+	dJointGetUniversalAxis2(_joint,result); 
+	_additional_axis.x = (Real)result[0];
+	_additional_axis.y = (Real)result[1];
+	_additional_axis.z = (Real)result[2];
+	return _additional_axis;
+}
+
+void UniversalJoint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetUniversalParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value); 
+}
+
+Real UniversalJoint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return (Real)dJointGetUniversalParam(_joint,((int)parameter) + dParamGroup * (axis - 1));
+}
+
+UniversalJoint::~UniversalJoint()
+{
+}
+
+FixedJoint::FixedJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreateFixed(getWorldID(),getJointGroupID(group)); 
+	registerJoint();
+}
+
+void FixedJoint::attach(const Body* body)
+{
+	Joint::attach(body);
+	dJointSetFixed(_joint); 
+}
+
+void FixedJoint::attach(const Body* body_a,const Body* body_b)
+{
+	Joint::attach(body_a,body_b);
+	dJointSetFixed(_joint); 
+}
+
+FixedJoint::~FixedJoint()
+{
+}
+
+SuspensionJoint::SuspensionJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreateHinge2(getWorldID(),getJointGroupID(group)); 
+	registerJoint();
+}
+
+void SuspensionJoint::setAnchor(const Ogre::Vector3& position)
+{
+	dJointSetHinge2Anchor(_joint,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+
+
+void SuspensionJoint::addTorque(Real torque,Real torque2,Real torque3)
+{
+	dJointAddHinge2Torques(_joint,(dReal)torque,(dReal)torque2);
+}
+
+const Ogre::Vector3& SuspensionJoint::getAnchor()
+{
+	dVector3 result;
+	dJointGetHinge2Anchor(_joint,result); 
+	_anchor.x = (Real)result[0];
+	_anchor.y = (Real)result[1];
+	_anchor.z = (Real)result[2];
+	return _anchor;
+}
+
+const Ogre::Vector3& SuspensionJoint::getAdditionalAnchor()
+{
+	dVector3 result;
+	dJointGetHinge2Anchor2(_joint,result);
+	_anchor2.x = (Real)result[0];
+	_anchor2.y = (Real)result[1];
+	_anchor2.z = (Real)result[2];
+	return _anchor2;
+}
+
+const Ogre::Vector3& SuspensionJoint::getAnchorError()
+{
+	dVector3 result1,result2;
+	dJointGetHinge2Anchor(_joint,result1); 
+	dJointGetHinge2Anchor2(_joint,result2); 
+	_anchor_error.x = (Real)(result1[0] - result2[0]);
+	_anchor_error.y = (Real)(result1[1] - result2[1]);
+	_anchor_error.z = (Real)(result1[2] - result2[2]);
+	return _anchor_error;
+}
+
+void SuspensionJoint::setAxis(const Ogre::Vector3& axis)
+{
+	dJointSetHinge2Axis1(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& SuspensionJoint::getAxis()
+{
+	dVector3 result;
+	dJointGetHinge2Axis1(_joint,result); 
+	_axis.x = (Real)result[0];
+	_axis.y = (Real)result[1];
+	_axis.z = (Real)result[2];
+	return _axis;
+}
+
+void SuspensionJoint::setAdditionalAxis(const Ogre::Vector3& axis)
+{
+	dJointSetHinge2Axis2(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& SuspensionJoint::getAdditionalAxis()
+{
+	dVector3 result;
+	dJointGetHinge2Axis2(_joint,result); 
+	_additional_axis.x = (Real)result[0];
+	_additional_axis.y = (Real)result[1];
+	_additional_axis.z = (Real)result[2];
+	return _additional_axis;
+}
+
+Real SuspensionJoint::getAngle()
+{
+	return (Real)dJointGetHinge2Angle1(_joint); 
+}
+
+Real SuspensionJoint::getAngleRate()
+{
+	return (Real)dJointGetHinge2Angle1Rate(_joint); 
+}
+
+Real SuspensionJoint::getPositionRate()
+{
+	return (Real)dJointGetHinge2Angle2Rate(_joint); 
+}
+
+void SuspensionJoint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetHinge2Param(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value); 
+}
+
+Real SuspensionJoint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return (Real)dJointGetHinge2Param(_joint,((int)parameter) + dParamGroup * (axis - 1));
+}
+
+SuspensionJoint::~SuspensionJoint()
+{
+}
+
+AngularMotorJoint::AngularMotorJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreateAMotor(getWorldID(),getJointGroupID(group)); 
+	registerJoint();
+}
+
+void AngularMotorJoint::setMode(AngularMotorJoint::Mode mode)
+{
+	dJointSetAMotorMode(_joint,(int)mode); 
+}
+
+AngularMotorJoint::Mode AngularMotorJoint::getMode()
+{
+	return (AngularMotorJoint::Mode)dJointGetAMotorMode(_joint); 
+}
+
+void AngularMotorJoint::addTorque(Real torque,Real torque2,Real torque3)
+{
+	dJointAddAMotorTorques(_joint,(dReal)torque,(dReal)torque2,(dReal)torque3);
+}
+
+void AngularMotorJoint::setAxisCount(int axes)
+{
+	assert((axes >= 0) && (axes <= 3));
+	dJointSetAMotorNumAxes(_joint,axes); 
+}
+
+int AngularMotorJoint::getAxisCount()
+{
+	return dJointGetAMotorNumAxes(_joint); 
+}
+
+void AngularMotorJoint::setAxis(int axis_number,AngularMotorJoint::RelativeOrientation orientation,const Ogre::Vector3& axis)
+{
+	dJointSetAMotorAxis(_joint,axis_number,(int)orientation,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z); 
+}
+
+const Ogre::Vector3& AngularMotorJoint::getAxis(int axis_number)
+{
+	dVector3 result;
+	dJointGetAMotorAxis(_joint,axis_number,result); 
+	_axis.x = (Real)result[0];
+	_axis.y = (Real)result[1];
+	_axis.z = (Real)result[2];
+	return _axis;
+}
+
+AngularMotorJoint::RelativeOrientation AngularMotorJoint::getAxisRelativeOrientation(int axis_number)
+{
+	return (AngularMotorJoint::RelativeOrientation)dJointGetAMotorAxisRel(_joint,axis_number); 
+}
+
+void AngularMotorJoint::setAngle(int axis,Real angle)
+{
+	dJointSetAMotorAngle(_joint,axis,(dReal)angle); 
+}
+
+Real AngularMotorJoint::getAngle(int axis)
+{
+	return (Real)dJointGetAMotorAngle(_joint,axis); 
+}
+
+Real AngularMotorJoint::getAngleRate(int axis)
+{
+	return (Real)dJointGetAMotorAngleRate(_joint,axis); 
+}
+
+void AngularMotorJoint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetAMotorParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value); 
+}
+
+Real AngularMotorJoint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return (Real)dJointGetAMotorParam(_joint,((int)parameter) + dParamGroup * (axis - 1));
+}
+
+AngularMotorJoint::~AngularMotorJoint()
+{
+}
+
+PlanarJoint::PlanarJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreatePlane2D(getWorldID(),getJointGroupID(group)); 
+	registerJoint();
+}
+
+void PlanarJoint::setParameterX(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetPlane2DXParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value);
+}
+
+void PlanarJoint::setParameterY(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetPlane2DYParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value);
+}
+
+void PlanarJoint::setParameterAngle(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetPlane2DAngleParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value);
+}
+
+PlanarJoint::~PlanarJoint()
+{
+}
+
+
+
+SliderHingeJoint::SliderHingeJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreatePR(getWorldID(),getJointGroupID(group)); 
+	registerJoint();
+}
+
+SliderHingeJoint::~SliderHingeJoint()
+{
+}
+
+void SliderHingeJoint::setAnchor(const Ogre::Vector3& position)
+{
+	dJointSetPRAnchor(_joint,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+
+const Ogre::Vector3& SliderHingeJoint::getAnchor()
+{
+	dVector3 result;
+	dJointGetPRAnchor(_joint,result); 
+	_anchor.x = (Real)result[0];
+	_anchor.y = (Real)result[1];
+	_anchor.z = (Real)result[2];
+	return _anchor;
+}
+
+
+Real SliderHingeJoint::getPosition()
+{
+	return (Real)dJointGetPRPosition(_joint); 
+}
+
+Real SliderHingeJoint::getPositionRate()
+{
+	return (Real)dJointGetPRPositionRate(_joint); 
+}
+
+void SliderHingeJoint::setAxis(const Ogre::Vector3& axis)
+{
+	dJointSetPRAxis1(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& SliderHingeJoint::getAxis()
+{
+	dVector3 result;
+	dJointGetPRAxis1(_joint,result); 
+	_axis.x = (Real)result[0];
+	_axis.y = (Real)result[1];
+	_axis.z = (Real)result[2];
+	return _axis;
+}
+
+void SliderHingeJoint::setAdditionalAxis(const Ogre::Vector3& axis)
+{
+	dJointSetPRAxis2(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& SliderHingeJoint::getAdditionalAxis()
+{
+	dVector3 result;
+	dJointGetPRAxis2(_joint,result); 
+	_additional_axis.x = (Real)result[0];
+	_additional_axis.y = (Real)result[1];
+	_additional_axis.z = (Real)result[2];
+	return _additional_axis;
+}
+
+void SliderHingeJoint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetPRParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value); 
+}
+
+Real SliderHingeJoint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return (Real)dJointGetPRParam(_joint,((int)parameter) + dParamGroup * (axis - 1));
+}
+
+void SliderHingeJoint::addTorque(Real torque,Real torque2,Real torque3)
+{
+	dJointAddPRTorque(_joint, (dReal)torque);
+}
+
+
+
+#if ODE_VERSION_MINOR > 9
+
+PistonJoint::PistonJoint(World *world, const JointGroup* group) : Joint(world, group)
+{
+	_joint = dJointCreatePiston(getWorldID(), getJointGroupID(group)); 
+	registerJoint();
+}
+
+void PistonJoint::setAnchor(const Ogre::Vector3& position)
+{
+	dJointSetPistonAnchor(_joint,(dReal)position.x,(dReal)position.y,(dReal)position.z); 
+}
+
+const Ogre::Vector3& PistonJoint::getAnchor()
+{
+	dVector3 result;
+	dJointGetPistonAnchor(_joint,result); 
+	_anchor.x = (Real)result[0];
+	_anchor.y = (Real)result[1];
+	_anchor.z = (Real)result[2];
+	return _anchor;
+}
+
+const Ogre::Vector3& PistonJoint::getAnchorError()
+{
+	dVector3 result1,result2;
+	dJointGetPistonAnchor(_joint,result1); 
+	dJointGetPistonAnchor2(_joint,result2); 
+	_anchor_error.x = (Real)(result1[0] - result2[0]);
+	_anchor_error.y = (Real)(result1[1] - result2[1]);
+	_anchor_error.z = (Real)(result1[2] - result2[2]);
+	return _anchor_error;
+}
+
+void PistonJoint::setAxis(const Ogre::Vector3& axis)
+{
+	dJointSetPistonAxis(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z);
+}
+
+const Ogre::Vector3& PistonJoint::getAxis()
+{
+	dVector3 result;
+	dJointGetPistonAxis(_joint,result); 
+	_axis.x = (Real)result[0];
+	_axis.y = (Real)result[1];
+	_axis.z = (Real)result[2];
+	return _axis;
+}
+
+void PistonJoint::setAxisDelta(const Ogre::Vector3& axis, const Ogre::Vector3& initalPosition)
+{
+	dJointSetPistonAxisDelta(_joint,(dReal)axis.x,(dReal)axis.y,(dReal)axis.z,
+		(dReal)initalPosition.x,(dReal)initalPosition.y,(dReal)initalPosition.z);
+}
+
+Real PistonJoint::getPosition()
+{
+	return (Real)dJointGetPistonPosition(_joint); 
+}
+
+Real PistonJoint::getPositionRate()
+{
+	return (Real)dJointGetPistonPositionRate(_joint); 
+}
+
+Real PistonJoint::getAngle()
+{
+	return (Real)dJointGetPistonAngle(_joint); 
+}
+
+Real PistonJoint::getAngleRate()
+{
+	return (Real)dJointGetPistonAngleRate(_joint); 
+}
+
+void PistonJoint::addForce(Real force,Real force2,Real force3)
+{
+	dJointAddPistonForce(_joint,(dReal)force);
+}
+
+void PistonJoint::setParameter(Joint::Parameter parameter,Real value,int axis)
+{
+	dJointSetPistonParam(_joint,((int)parameter) + dParamGroup * (axis - 1),(dReal)value);  
+}
+
+Real PistonJoint::getParameter(Joint::Parameter parameter,int axis)
+{
+	return (Real)dJointGetPistonParam(_joint,((int)parameter) + dParamGroup * (axis - 1));
+}
+
+#endif /* ODE_VERSION_MINOR > 9 */
Index: code/branches/physics/src/ogreode/OgreOdeJoint.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeJoint.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeJoint.h	(revision 1919)
@@ -0,0 +1,382 @@
+#ifndef _OGREODEJOINT_H_
+#define _OGREODEJOINT_H_
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeMaintainedList.h"
+
+namespace OgreOde 
+{
+	class _OgreOdeExport JointGroup
+	{
+		friend class World;
+		friend class Joint;
+
+	public:
+        JointGroup(World *world);
+		virtual ~JointGroup();
+
+		void empty();
+
+		virtual size_t getID();
+
+	protected:
+		dJointGroupID getJointGroupID() const;
+
+	protected:
+        dJointGroupID _joint_group;
+        World *_world;
+	};
+
+	class _OgreOdeExport Joint
+    {
+		friend class World;
+
+	public:
+		enum Type
+		{
+			Type_BallJoint					= dJointTypeBall,
+			Type_HingeJoint					= dJointTypeHinge,
+			Type_SliderJoint				= dJointTypeSlider,
+			Type_UniversalJoint				= dJointTypeUniversal,
+			Type_Suspension_Joint			= dJointTypeHinge2,
+			Type_FixedJoint					= dJointTypeFixed,
+			Type_AngularMotorJoint			= dJointTypeAMotor,
+			Type_PlanarJoint				= dJointTypePlane2D,
+#if ODE_VERSION_MINOR > 9
+			Type_SliderHingeJoint			= dJointTypePR,
+			Type_SliderUniversalJoint		= dJointTypePU,
+			Type_PistonJoint				= dJointTypePiston
+#else
+			Type_SliderHingeJoint			= dJointTypePR
+#endif
+		};
+
+		enum Parameter
+		{
+			Parameter_LowStop				= dParamLoStop,
+			Parameter_HighStop				= dParamHiStop,
+			Parameter_MotorVelocity			= dParamVel,
+			Parameter_MaximumForce			= dParamFMax,
+			Parameter_FudgeFactor			= dParamFudgeFactor,
+			Parameter_Bounceyness			= dParamBounce,
+			Parameter_CFM					= dParamCFM,
+			Parameter_ERP					= dParamERP,
+			Parameter_StopERP				= dParamStopERP,
+			Parameter_StopCFM				= dParamStopCFM,
+			Parameter_SuspensionERP			= dParamSuspensionERP, // SuspensionJoint
+			Parameter_SuspensionCFM			= dParamSuspensionCFM  // SuspensionJoint
+		};
+
+	public:
+		Joint(World *world, const JointGroup* group = 0);
+		virtual ~Joint();
+
+		Joint::Type getType(); 
+
+		void registerJoint();
+
+		void detach();
+		virtual void attach(const Body* body);
+		virtual void attach(const Body* body_a,const Body* body_b); 
+
+		Body* getFirstBody(); 
+		Body* getSecondBody(); 
+		
+		static bool areConnected(const Body* body_a,const Body* body_b); 
+		static bool areConnectedExcluding(const Body* body_a,const Body* body_b,Joint::Type joint_type); 
+	
+		void enableFeedback(); 
+		void disableFeedback(); 
+		const Ogre::Vector3& getFirstForce();
+		const Ogre::Vector3& getFirstTorque();
+		const Ogre::Vector3& getSecondForce();
+		const Ogre::Vector3& getSecondTorque();
+
+		virtual void setAnchor(const Ogre::Vector3& position);
+		virtual const Ogre::Vector3& getAnchor();
+		virtual const Ogre::Vector3& getAnchorError();
+		virtual void setAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAxis();
+		virtual void setAdditionalAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAdditionalAxis();
+		virtual Ogre::Real getAngle();
+		virtual Ogre::Real getAngleRate();
+		virtual Ogre::Real getPosition();
+		virtual Ogre::Real getPositionRate();
+
+		virtual void setParameter(Joint::Parameter parameter,Ogre::Real value,int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter,int axis = 1);
+
+		virtual size_t getID();
+
+		virtual void addTorque(Ogre::Real torque, Ogre::Real torque2 = 0.0, Ogre::Real torque3 = 0.0);
+		virtual void addForce(Ogre::Real force, Ogre::Real force2 = 0.0, Ogre::Real force3 = 0.0);
+
+	protected:
+		dJointID getJointID();
+
+		dWorldID getWorldID();
+		dJointGroupID getJointGroupID(const JointGroup* group) const;
+
+	protected:
+		dJointID _joint;
+		dJointFeedback _feedback;
+		Ogre::Vector3 _axis,_anchor,_anchor_error,_additional_axis;
+        Ogre::Vector3 _first_force,_first_torque,_second_force,_second_torque;
+        World *_world;
+	};
+
+	class _OgreOdeExport BallJoint:public Joint
+	{
+	public:
+		BallJoint(World *world, const JointGroup* group = 0);
+		~BallJoint();
+
+		virtual void setAnchor(const Ogre::Vector3& position);
+		virtual const Ogre::Vector3& getAnchor();
+		virtual const Ogre::Vector3& getAnchorError();
+		
+		// as of ode-0.9 can set Parameter_CFM and Parameter_ERP to make the joint springy, an axis value isn't needed
+		virtual void setParameter(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter,int axis = 1);
+	};
+
+	class _OgreOdeExport HingeJoint:public Joint
+	{
+	public:
+		HingeJoint(World *world, const JointGroup* group = 0);
+		~HingeJoint();
+
+		virtual void setAnchor(const Ogre::Vector3& position);
+		virtual const Ogre::Vector3& getAnchor();
+		virtual const Ogre::Vector3& getAnchorError();
+		virtual void setAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAxis();
+		virtual Ogre::Real getAngle();
+		virtual Ogre::Real getAngleRate();
+
+		virtual void setParameter(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter,int axis = 1);
+
+		virtual void addTorque(Ogre::Real torque, Ogre::Real torque2 = 0.0, Ogre::Real torque3 = 0.0);
+	};
+
+	class _OgreOdeExport SliderJoint:public Joint
+	{
+	public:
+		SliderJoint(World *world, const JointGroup* group = 0);
+		~SliderJoint();
+
+		virtual void setAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAxis();
+		virtual Ogre::Real getPosition();
+		virtual Ogre::Real getPositionRate();
+
+		virtual void setParameter(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter, int axis = 1);
+
+		virtual void addForce(Ogre::Real force, Ogre::Real force2 = 0.0, Ogre::Real force3 = 0.0);
+	};
+
+	class _OgreOdeExport UniversalJoint:public Joint
+	{
+	public:
+		UniversalJoint(World *world, const JointGroup* group = 0);
+		~UniversalJoint();
+
+		virtual void setAnchor(const Ogre::Vector3& position);
+		virtual const Ogre::Vector3& getAnchor();
+		virtual const Ogre::Vector3& getAnchorError();
+		virtual void setAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAxis();
+		virtual void setAdditionalAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAdditionalAxis();
+
+		virtual void setParameter(Joint::Parameter parameter, Ogre::Real value, int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter,int axis = 1);
+
+		virtual void addTorque(Ogre::Real torque, Ogre::Real torque2 = 0.0, Ogre::Real torque3 = 0.0);
+	};
+
+	class _OgreOdeExport FixedJoint:public Joint
+	{
+	public:
+		FixedJoint(World *world, const JointGroup* group = 0);
+		~FixedJoint();
+
+		virtual void attach(const Body* body);
+		virtual void attach(const Body* body_a,const Body* body_b); 
+	};
+
+	class _OgreOdeExport SuspensionJoint:public Joint
+	{
+	public:
+		SuspensionJoint(World *world, const JointGroup* group = 0);
+		~SuspensionJoint();
+
+		virtual void setAnchor(const Ogre::Vector3& position);
+		virtual const Ogre::Vector3& getAnchor();
+		virtual const Ogre::Vector3& getAdditionalAnchor();
+		virtual const Ogre::Vector3& getAnchorError();
+		virtual void setAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAxis();
+		virtual void setAdditionalAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAdditionalAxis();
+		virtual Ogre::Real getAngle();
+		virtual Ogre::Real getAngleRate();
+		virtual Ogre::Real getPositionRate();
+
+		virtual void setParameter(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter,int axis = 1);
+
+		virtual void addTorque(Ogre::Real torque, Ogre::Real torque2 = 0.0, Ogre::Real torque3 = 0.0);
+
+	protected:
+		Ogre::Vector3 _anchor2;
+	};
+
+	class _OgreOdeExport AngularMotorJoint:public Joint
+	{
+	public:
+		enum Mode
+		{
+			Mode_UserAngularMotor	= dAMotorUser,
+			Mode_EulerAngularMotor	= dAMotorEuler 
+		};
+
+		enum RelativeOrientation
+		{
+			RelativeOrientation_GlobalFrame = 0,
+			RelativeOrientation_FirstBody	= 1,		
+			RelativeOrientation_SecondBody	= 2
+		};
+
+	public:
+		AngularMotorJoint(World *world, const JointGroup* group = 0);
+		~AngularMotorJoint();
+
+		void setMode(AngularMotorJoint::Mode mode);
+		AngularMotorJoint::Mode getMode(); 
+
+		void setAxisCount(int axes);
+		int getAxisCount(); 
+
+		void setAxis(int axis_number,AngularMotorJoint::RelativeOrientation orientation,const Ogre::Vector3& axis);
+		const Ogre::Vector3& getAxis(int axis_number);
+		AngularMotorJoint::RelativeOrientation getAxisRelativeOrientation(int axis_number); 
+
+		void setAngle(int axis, Ogre::Real angle); 
+		Ogre::Real getAngle(int axis); 
+		Ogre::Real getAngleRate(int axis); 
+
+		virtual void setParameter(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter,int axis = 1);
+
+		virtual void addTorque(Ogre::Real torque, Ogre::Real torque2 = 0.0, Ogre::Real torque3 = 0.0);
+	};
+
+	/** Planar joints are for 2D physics in the x, y plane wth z=0
+	*/
+	class _OgreOdeExport PlanarJoint:public Joint
+	{
+	public:
+		PlanarJoint(World *world, const JointGroup* group = 0);
+		~PlanarJoint();
+
+		virtual void setParameterX(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual void setParameterY(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual void setParameterAngle(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+	};
+	
+	
+	/** A prismatic and rotoide joint (ODE_API JointPR) combines a Slider (prismatic) and a Hinge (rotoide). 
+		It can be used to decrease the number of bodies in a simulation. 
+		Usually you cannot attach 2 ODE joints together they need a body in between. 
+		An example of use of this type of joint can be in the creation of a hydraulic piston.
+		
+		The 2 axies must not be parallel. Since this is a new joint only when the 2 joint are at 
+		90deg of each other was fully tested.
+	*/
+	class _OgreOdeExport SliderHingeJoint:public Joint
+	{
+	public:
+		SliderHingeJoint(World *world, const JointGroup* group = 0);
+		~SliderHingeJoint();
+		
+		virtual void setAnchor(const Ogre::Vector3& position);
+		virtual const Ogre::Vector3& getAnchor();
+		
+		// Equivalent to getting the Slider's extension
+		virtual Ogre::Real getPosition();
+		virtual Ogre::Real getPositionRate();
+		
+		// Set the axis for the Slider articulation
+		virtual void setAxis(const Ogre::Vector3& axis);
+		// Get the axis for the Slider articulation
+		virtual const Ogre::Vector3& getAxis();
+		// Set the axis for the Hinge articulation. 
+		virtual void setAdditionalAxis(const Ogre::Vector3& axis);
+		// Get the axis for the Hinge articulation
+		virtual const Ogre::Vector3& getAdditionalAxis();
+		
+		// Set joint parameter axis = 3 for Hinge
+		virtual void setParameter(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter,int axis = 1);
+		
+		// Applies the torque about the Hinge axis of the joint 
+		virtual void addTorque(Ogre::Real torque, Ogre::Real torque2 = 0.0, Ogre::Real torque3 = 0.0);
+	};
+	
+	
+#if ODE_VERSION_MINOR > 9
+
+	/** "A piston joint is similar to a Slider joint except that rotation around the translation axis is possible."
+	*/
+	class _OgreOdeExport PistonJoint : public Joint
+	{
+	public:
+		PistonJoint(World *world, const JointGroup* group = 0);
+		
+		// "The joint will try to keep the distance of this point fixed with respect to body2. 
+		// The input is specified in world coordinates. 
+		// If there is no body attached to the joint this function has not effect."
+		virtual void setAnchor(const Ogre::Vector3& position);
+		virtual const Ogre::Vector3& getAnchor();
+		virtual const Ogre::Vector3& getAnchorError();
+		
+		virtual void setAxis(const Ogre::Vector3& axis);
+		virtual const Ogre::Vector3& getAxis();
+		// "This function set prismatic axis of the joint and also set the position of the joint."
+		virtual void setAxisDelta(const Ogre::Vector3& axis, const Ogre::Vector3& initalPosition);
+		
+		// "Get the piston linear position.
+		// When the anchor is set, the current position of body1 and the anchor is examined and that 
+		// position will be the zero position"		
+		virtual Ogre::Real getPosition();
+		virtual Ogre::Real getPositionRate();
+		
+		// "Get the angle and the time derivative of this value. 
+		// The angle is measured between the two bodies, or between the body and the static environment. 
+		// The angle will be between -pi..pi. 
+		// The only possible axis of rotation is the one defined by the dJointSetPistonAxis.
+		// When the piston anchor or axis is set, the current position of the attached bodies is examined 
+		// and that position will be the zero angle."
+		virtual Ogre::Real getAngle();
+		virtual Ogre::Real getAngleRate();
+		
+		// "This function create a force inside the piston and this force will be applied on the 2 bodies.
+		// Then	force is apply to the center of mass of each body and the orientation of the force vector is 
+		// along the axis of the piston"
+		// One axis so only the first force is used
+		virtual void addForce(Ogre::Real force, Ogre::Real force2 = 0.0, Ogre::Real force3 = 0.0);
+		
+		// Set joint parameter
+		virtual void setParameter(Joint::Parameter parameter, Ogre::Real value,int axis = 1);
+		virtual Ogre::Real getParameter(Joint::Parameter parameter,int axis = 1);
+	};
+
+#endif /* ODE_VERSION_MINOR > 9 */
+
+}
+
+#endif 
Index: code/branches/physics/src/ogreode/OgreOdeMaintainedList.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeMaintainedList.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeMaintainedList.h	(revision 1919)
@@ -0,0 +1,191 @@
+/*!
+ * <File comment goes here!!>
+ * 
+ * Copyright (c) 2005 by <your name/ organization here>
+ */
+#ifndef _OGREODEMAINTAINEDLIST_H_
+#define _OGREODEMAINTAINEDLIST_H_
+
+#include "OgreOdePreReqs.h"
+
+/*!
+ * \brief
+ * Write brief comment for OgreOde here.
+ * 
+ * Write detailed description for OgreOde here.
+ * 
+ * \remarks
+ * Write remarks for OgreOde here.
+ * 
+ * \see
+ * Separate items with the '|' character.
+ */
+namespace OgreOde
+{
+
+	/** Convenience class to make it easy to step through all MaintainedItem in a MaintainedList.
+	*/
+	template <class T>
+	class _OgreOdeExport MaintainedItemIterator
+	{
+
+	public:
+		typedef std::deque<T*> MaintainedItemList;
+		typedef std::map<size_t,T*> MaintainedItemMap;
+
+
+	protected:
+		typename MaintainedItemList::iterator mPos;
+		typename MaintainedItemList::iterator mStart;
+		typename MaintainedItemList::iterator mEnd;
+
+
+	public:
+		/// constructor, only available for MaintainedList::getIterator
+		MaintainedItemIterator(typename MaintainedItemList::iterator start, typename MaintainedItemList::iterator end)
+		{
+			mStart = mPos = start;
+			mEnd = end;
+		}
+		// Returns true when at the end of the MaintainedItem list
+		inline bool end(void) const 
+		{
+			return (mPos == mEnd);
+		}
+		/** Returns a pointer to the next MaintainedItem, and moves the iterator on by 1 element. */
+		inline T* getNext(void)
+		{
+			return static_cast<T*>(*mPos++);
+		}
+	};
+
+	template <class T>
+	class _OgreOdeExport MaintainedList
+	{
+	public:
+		typedef std::deque<T*>				MaintainedItemList;
+		typedef std::map<size_t,T*>	MaintainedItemMap;
+
+	public:
+		MaintainedList(){};
+		~MaintainedList(){};
+
+		void registerItem(T* ptr)	
+		{
+			assert(ptr->getID());
+			_map[ptr->getID()] = ptr;
+			_list.push_back (ptr);
+		}
+
+		T* findItem(size_t id)
+		{
+			assert (_map.find(id) != _map.end());
+			return _map[id];
+		}
+
+		void unregisterItem(size_t id)
+		{
+			assert (_map.find(id) != _map.end());
+			T* m = _map[id];
+			_map.erase(id);
+
+			typename MaintainedItemList::iterator i = std::find(_list.begin (), 
+				_list.end (), 
+				m);
+			if(i != _list.end())
+			{
+				assert(*i == m);
+				_list.erase(i);
+			}
+		}
+
+		void setDebug(const bool debug)
+		{
+			typename MaintainedItemList::iterator i = _list.begin();
+			typename MaintainedItemList::iterator end = _list.end();
+			for(;i != end;++i)
+			{
+				(*i)->setDebug(debug);
+			}
+        }
+
+        void setDebugContact(const bool debug)
+        {
+            typename MaintainedItemList::iterator i = _list.begin();
+            typename MaintainedItemList::iterator end = _list.end();
+            for(;i != end;++i)
+            {
+                (*i)->setDebugContact(debug);
+            }
+        }
+
+        void updateDebugContact()
+        {
+            std::for_each(_list.begin (), 
+                _list.end (),  
+                std::mem_fun(&T::updateDebugContact));
+        }
+
+
+
+		void synchronise()
+		{
+			std::for_each(_list.begin (), 
+				_list.end (),  
+				std::mem_fun(&T::synchronise));
+		}
+
+		void updateDrawState()
+		{
+			std::for_each(_list.begin (), 
+				_list.end (),  
+				std::mem_fun(&T::updateDrawState));
+		}
+		void updatePreviousState()
+		{
+			std::for_each(_list.begin (), 
+				_list.end (),  
+				std::mem_fun(&T::updatePreviousState));
+		}
+
+		void updateCurrentState()
+		{
+			std::for_each(_list.begin (), 
+				_list.end (),  
+				std::mem_fun(&T::updateCurrentState));
+		}
+
+		void interpolateDrawState(const Ogre::Real alpha)
+		{
+			typename MaintainedItemList::iterator i = _list.begin();
+			typename MaintainedItemList::iterator end = _list.end();
+			for(;i != end;++i)
+			{
+				(*i)->interpolateDrawState(alpha);
+			}
+		}
+
+		void notify(Body* body)
+		{
+			typename MaintainedItemList::iterator i = _list.begin();
+			typename MaintainedItemList::iterator end = _list.end();
+			for(;i != end;++i)
+			{
+				(*i)->notify(body);
+			}
+		}
+
+		MaintainedItemIterator<T> getIterator(void)
+		{
+			return MaintainedItemIterator<T>(_list.begin(), _list.end());
+		}
+
+	protected:
+
+		MaintainedItemMap  _map;
+		MaintainedItemList _list;
+	};
+
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdeMass.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeMass.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeMass.cpp	(revision 1919)
@@ -0,0 +1,176 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeMass.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+Mass::Mass()
+{
+	dMassSetZero(&_mass); 
+}
+
+Mass::Mass(Real mass,const Ogre::Vector3& center_of_gravity,const Matrix3& intertia_matrix)
+{
+	dMassSetParameters
+	(
+		&_mass,
+		(dReal)mass,
+		(dReal)center_of_gravity.x,(dReal)center_of_gravity.y,(dReal)center_of_gravity.z,
+		(dReal)intertia_matrix[0][0],(dReal)intertia_matrix[1][1],(dReal)intertia_matrix[2][2],
+		(dReal)intertia_matrix[0][1],(dReal)intertia_matrix[0][2],(dReal)intertia_matrix[1][2]
+	); 
+}
+
+Mass::~Mass()
+{
+}
+
+void Mass::adjust(Real mass)
+{
+	dMassAdjust(&_mass,(dReal)mass); 
+}
+
+void Mass::translate(const Ogre::Vector3& offset)
+{
+	dMassTranslate(&_mass,offset.x,offset.y,offset.z); 
+}
+
+void Mass::rotate(const Ogre::Quaternion& orientation)
+{
+	Matrix3 m;
+	orientation.ToRotationMatrix(m);
+	dMatrix3 r;
+
+	r[0] = m[0][0];
+	r[1] = m[0][1];
+	r[2] = m[0][2];
+
+	r[3] = m[1][0];
+	r[4] = m[1][1];
+	r[5] = m[1][2];
+
+	r[6] = m[2][0];
+	r[7] = m[2][1];
+	r[8] = m[2][2];
+
+	r[9] = 0.0;
+	r[10] = 0.0;
+	r[11] = 0.0;
+
+	dMassRotate(&_mass,r); 
+}
+
+Ogre::Real Mass::getMassValue() const
+{
+	return _mass.mass;
+}
+
+Ogre::Vector3 Mass::getCenterOfGravity() const
+{
+	// not sure why its a dVector4 in dMass and not a dVector3
+	// and I think ode requires the center of mass to be the bodies position so this 
+	// would always return Vector3::ZERO
+	return Vector3(_mass.c[0], _mass.c[1], _mass.c[2]);
+}
+
+
+
+Ogre::Matrix3 Mass::getLocalInertiaTensor() const
+{
+	return Ogre::Matrix3(   
+		_mass.I[0], _mass.I[1], _mass.I[2],
+		_mass.I[4], _mass.I[5], _mass.I[6],
+		_mass.I[8], _mass.I[9], _mass.I[10]);
+}
+void Mass::add(const Mass& other)
+{
+	dMassAdd(&_mass,&(other._mass)); 
+}
+
+const dMass* Mass::getMassPtr() const
+{
+	return &_mass;
+}
+
+SphereMass::SphereMass():Mass()
+{
+}
+
+SphereMass::SphereMass(Real mass,Real radius)
+{
+	dMassSetSphereTotal(&_mass,(dReal)mass,(dReal)radius); 
+}
+
+SphereMass::~SphereMass()
+{
+}
+
+void SphereMass::setDensity(Real density,Real radius)
+{
+	dMassSetSphere(&_mass,(dReal)density,(dReal)radius); 
+}
+
+CapsuleMass::CapsuleMass():Mass()
+{
+}
+
+CapsuleMass::CapsuleMass(Real mass,Real radius,const Ogre::Vector3& direction,Real length)
+{
+	int dir = (direction == Ogre::Vector3::UNIT_X)?1:(direction == Ogre::Vector3::UNIT_Y)?2:(direction == Ogre::Vector3::UNIT_Z)?3:0;
+	assert(dir);
+	dMassSetCappedCylinderTotal(&_mass,(dReal)mass,dir,(dReal)radius,(dReal)length); 
+}
+
+CapsuleMass::~CapsuleMass()
+{
+}
+
+void CapsuleMass::setDensity(Real density,Real radius,const Ogre::Vector3& direction,Real length)
+{
+	int dir = (direction == Ogre::Vector3::UNIT_X)?1:(direction == Ogre::Vector3::UNIT_Y)?2:(direction == Ogre::Vector3::UNIT_Z)?3:0;
+	assert(dir && "Invalid direction specified for CapsuleMass");
+	dMassSetCappedCylinder(&_mass,(dReal)density,dir,(dReal)radius,(dReal)length); 
+}
+
+CylinderMass::CylinderMass():Mass()
+{
+}
+
+CylinderMass::CylinderMass(Real mass,const Ogre::Vector3& direction,Real radius,Real length)
+{
+	int dir = (direction == Ogre::Vector3::UNIT_X)?1:(direction == Ogre::Vector3::UNIT_Y)?2:(direction == Ogre::Vector3::UNIT_Z)?3:0;
+	assert(dir);
+	dMassSetCylinderTotal(&_mass,(dReal)mass,dir,(dReal)radius,(dReal)length); 
+}
+
+CylinderMass::~CylinderMass()
+{
+}
+
+void CylinderMass::setDensity(Real density,const Ogre::Vector3& direction,Real radius,Real length)
+{
+	int dir = (direction == Ogre::Vector3::UNIT_X)?1:(direction == Ogre::Vector3::UNIT_Y)?2:(direction == Ogre::Vector3::UNIT_Z)?3:0;
+	assert(dir);
+	dMassSetCylinder(&_mass,(dReal)density,dir,(dReal)radius,(dReal)length); 
+}
+
+BoxMass::BoxMass():Mass()
+{
+}
+
+BoxMass::BoxMass(Real mass,const Ogre::Vector3& size)
+{
+	dMassSetBoxTotal(&_mass,(dReal)mass,(dReal)size.x,(dReal)size.y,(dReal)size.z);
+}
+
+BoxMass::~BoxMass()
+{
+}
+
+void BoxMass::setDensity(Real density,const Ogre::Vector3& size)
+{
+	dMassSetBox(&_mass,(dReal)density,(dReal)size.x,(dReal)size.y,(dReal)size.z); 
+}
Index: code/branches/physics/src/ogreode/OgreOdeMass.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeMass.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeMass.h	(revision 1919)
@@ -0,0 +1,96 @@
+#ifndef _OGREODEMASS_H_
+#define _OGREODEMASS_H_
+
+#include "OgreOdePreReqs.h"
+
+namespace OgreOde 
+{
+	class _OgreOdeExport Mass
+	{
+		friend class Body;
+
+	public:
+		Mass();
+        Mass(Ogre::Real mass, const Ogre::Vector3& center_of_gravity, const Ogre::Matrix3& intertia_matrix); 
+		virtual ~Mass();
+
+		inline Mass(const Mass& other)
+		{
+			memcpy(&_mass,&(other._mass),sizeof(_mass));
+		}
+
+		inline Mass& operator=(const Mass& other)
+		{
+			memcpy(&_mass,&(other._mass),sizeof(_mass));
+			return *this;
+		}
+
+		inline Mass& operator=(const dMass* other)
+		{
+			assert(other);
+			memcpy(&_mass,other,sizeof(_mass));
+			return *this;
+		}
+
+		void adjust(Ogre::Real mass); 
+		void translate(const Ogre::Vector3& offset); 
+		void rotate(const Ogre::Quaternion& orientation); 
+		void add(const Mass& other); 
+		
+		// total mass of the rigid body
+		Ogre::Real getMassValue() const;
+		// center of gravity position in body frame (x,y,z)
+		Ogre::Vector3 getCenterOfGravity() const;
+		// 3x3 inertia tensor in body frame, about POR
+		Ogre::Matrix3 getLocalInertiaTensor() const; 
+
+	protected:
+		const dMass* getMassPtr() const;
+		dMass _mass;
+	};
+
+	class _OgreOdeExport SphereMass:public Mass
+	{
+	public:
+		SphereMass();
+		SphereMass(Ogre::Real mass, Ogre::Real radius);
+		~SphereMass();
+
+		void setDensity(Ogre::Real density, Ogre::Real radius);
+	};
+	
+	// To add
+	// void dMassSetTrimesh(dMass *, dReal density, dGeomID g)
+
+	class _OgreOdeExport CapsuleMass:public Mass
+	{
+	public:
+		CapsuleMass();
+		CapsuleMass(Ogre::Real mass, Ogre::Real radius,const Ogre::Vector3& direction, Ogre::Real length);
+		~CapsuleMass();
+
+		void setDensity(Ogre::Real density, Ogre::Real radius,const Ogre::Vector3& direction, Ogre::Real length);
+	};
+
+	class _OgreOdeExport CylinderMass:public Mass
+	{
+	public:
+		CylinderMass();
+		CylinderMass(Ogre::Real mass,const Ogre::Vector3& direction, Ogre::Real radius, Ogre::Real length);
+		~CylinderMass();
+
+		void setDensity(Ogre::Real density,const Ogre::Vector3& direction, Ogre::Real radius, Ogre::Real length);
+	};
+
+	class _OgreOdeExport BoxMass:public Mass
+	{
+	public:
+		BoxMass();
+		BoxMass(Ogre::Real mass,const Ogre::Vector3& size);
+		~BoxMass();
+
+		void setDensity(Ogre::Real density,const Ogre::Vector3& size);
+	};
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdePreReqs.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdePreReqs.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdePreReqs.h	(revision 1919)
@@ -0,0 +1,119 @@
+#ifndef _OGREODEPREREQS_H_
+#define _OGREODEPREREQS_H_
+
+#include "Ogre.h"
+#include "OgreNoMemoryMacros.h"
+#include "ode/ode.h"
+#include "OgreMemoryMacros.h"
+
+
+namespace OgreOde 
+{
+    #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+    #   if defined( OGREODE_EXPORTS )
+    #       define _OgreOdeExport __declspec( dllexport )
+    #   else
+    #       if defined( __MINGW32__ )
+    #           define _OgreOdeExport
+    #       else
+    #           define _OgreOdeExport __declspec(dllimport)
+    #       endif
+    #   endif
+    #elif defined ( OGRE_GCC_VISIBILITY )
+    #   define _OgreOdeExport  __attribute__ ((visibility("default")))
+    #else
+    #   define _OgreOdeExport
+    #endif
+
+// determine ODE version. In 0.10 and following, ODE uses odeconfig.h in the headers and
+// out-"sourced" config.h to hide it from the include folder. So there is a new macro for the
+// header: ODECONFIG_H instead of _ODE_CONFIG_H_
+#ifdef ODECONFIG_H
+#  define ODE_VERSION_MINOR 10 // or larger
+#else
+#  define ODE_VERSION_MINOR 9 // or smaller
+#endif
+
+
+#if ODE_VERSION_MINOR < 10
+#  ifndef dTriIndex
+#    if dTRIMESH_16BIT_INDICES
+#      if dTRIMESH_GIMPACT
+	     typedef uint32 dTriIndex;
+#      else // dTRIMESH_GIMPACT
+	     typedef uint16 dTriIndex;
+#      endif // dTRIMESH_GIMPACT
+#    else // dTRIMESH_16BIT_INDICES
+	   typedef int dTriIndex;
+#    endif // dTRIMESH_16BIT_INDICES
+#  endif
+#endif
+
+	typedef dTriIndex TriangleIndex;
+
+
+	class World;
+	class Space;
+
+	class Body;
+	class Mass;
+
+	class JointGroup;
+	class Joint;
+
+    class Geometry;
+    typedef std::list<Geometry*>   GeometryList;
+    typedef std::vector<Geometry*> GeometryArray;
+
+    class RayGeometry;
+    class CylinderGeometry;
+    class SphereGeometry;
+    class InfinitePlaneGeometry;
+    class TransformGeometry;
+	
+	class TriangleMeshData;
+	class TriangleMeshDataPtr;
+	class TriangleMeshGeometry;
+	class BoxGeometry;
+    class CapsuleGeometry;
+
+
+	class Contact;
+
+    class StepListener;
+
+    class StepHandler;
+    class BasicStepper;
+    class QuickStepper;
+    class FastStepper;
+
+    class StepMode;
+    class BasicStepMode;
+    class QuickStepMode;
+    class FastStepMode;
+
+
+
+	class CollisionListener;
+	class CollisionCallback;
+	class MaintainedItem;
+
+
+	class EntityInformer;
+    typedef std::vector<Ogre::Vector3> Vector3Array;
+	typedef std::map<unsigned char,Vector3Array* > BoneMapping;
+	typedef std::pair<unsigned short,Vector3Array* > BoneMappingKey;
+
+	typedef size_t MaterialID;
+	typedef std::map<MaterialID,Contact*> MaterialMap;
+    typedef std::pair<MaterialID,MaterialMap* > MaterialMapPair;
+
+    class DebugObject;
+    class DebugContact;
+    class DebugContactText;
+    class DebugNormal;
+}
+
+
+#endif
+
Index: code/branches/physics/src/ogreode/OgreOdePrecompiledHeaders.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdePrecompiledHeaders.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdePrecompiledHeaders.cpp	(revision 1919)
@@ -0,0 +1,1 @@
+#include "OgreOdePrecompiledHeaders.h"
Index: code/branches/physics/src/ogreode/OgreOdePrecompiledHeaders.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdePrecompiledHeaders.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdePrecompiledHeaders.h	(revision 1919)
@@ -0,0 +1,29 @@
+#ifndef __OgreOdePrecompiledHeaders_
+#define __OgreOdePrecompiledHeaders_
+ 
+#ifdef _PRECOMP
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeWorld.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeMass.h" 
+#include "OgreOdeJoint.h"
+#include "OgreOdeSpace.h"
+#include "OgreOdeGeometry.h"
+#include "OgreOdeCollision.h"
+#include "OgreOdeStepper.h"
+
+#include "OgreOdeEntityInformer.h"
+
+
+#include "OgreOdeEigenSolver.h"
+#include "OgreOdeUtility.h"
+
+#include "OgreOdeDebugObject.h"
+#include "OgreOdeDebugContact.h"
+
+#include "OgreOdeTriangleMeshData.h"
+#include "OgreOdeTriangleMeshDataManager.h"
+
+#endif //_PRECOMP
+#endif //__OgreOdePrecompiledHeaders_
Index: code/branches/physics/src/ogreode/OgreOdeSpace.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeSpace.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeSpace.cpp	(revision 1919)
@@ -0,0 +1,372 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeBody.h"
+#include "OgreOdeSpace.h"
+#include "OgreOdeGeometry.h"
+#include "OgreOdeWorld.h"
+
+#include "OgreOdeCollision.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+//------------------------------------------------------------------------------------------------
+Space::Space(World *world, const Space* space) :
+    _world(world),
+    _internal_collisions (true)
+{
+}
+//------------------------------------------------------------------------------------------------
+#if ODE_VERSION_MINOR > 9
+Space::Class Space::getClass()
+{
+	return (Space::Class)(dSpaceGetClass(_space));
+}
+#endif
+//------------------------------------------------------------------------------------------------
+dSpaceID Space::getSpaceID() const
+{
+	return _space;
+}
+//------------------------------------------------------------------------------------------------
+dSpaceID Space::getSpaceID(const Space* space) const
+{
+	if(space) 
+        return space->getSpaceID();
+	return 0;
+}
+//------------------------------------------------------------------------------------------------
+void Space::setAutoCleanup(bool on)
+{
+	dSpaceSetCleanup(_space,(on)?1:0);
+}
+//------------------------------------------------------------------------------------------------
+bool Space::getAutoCleanup()
+{
+	return ((dSpaceGetCleanup(_space))?true:false); 
+}
+//------------------------------------------------------------------------------------------------
+void Space::addGeometry(const Geometry& geometry)
+{
+	dSpaceAdd(_space,geometry.getGeometryID()); 
+}
+//------------------------------------------------------------------------------------------------
+void Space::removeGeometry(const Geometry& geometry)
+{
+	dSpaceRemove(_space,geometry.getGeometryID()); 
+}
+//------------------------------------------------------------------------------------------------
+bool Space::containsGeometry(const Geometry& geometry)
+{
+	return ((dSpaceQuery(_space,geometry.getGeometryID()))?true:false); 
+}
+//------------------------------------------------------------------------------------------------
+int Space::getGeometryCount()
+{
+	return dSpaceGetNumGeoms(_space); 
+}
+//------------------------------------------------------------------------------------------------
+Geometry* Space::getGeometry(int index)
+{
+	return (Geometry*) _world->getGeometryList().findItem((size_t)dSpaceGetGeom(_space,index)); 
+}
+//------------------------------------------------------------------------------------------------
+void Space::registerSpace()
+{
+	_world->getSpaceList().registerItem(this);
+	dGeomSetData((dGeomID)_space,(void*)this);
+}
+//------------------------------------------------------------------------------------------------
+void Space::collide(void* data)
+{
+	if(_internal_collisions)
+	{
+		dSpaceCollide(_space,data,World::collisionCallback);
+	}
+}
+//------------------------------------------------------------------------------------------------
+void Space::collide(Space* space,void* data)
+{
+	dSpaceCollide2((dGeomID)_space,(dGeomID)(space->getSpaceID()),data,World::collisionCallback);
+}
+//------------------------------------------------------------------------------------------------
+void Space::collide(Geometry* geometry,void* data)
+{
+	dSpaceCollide2((dGeomID)_space,geometry->getGeometryID(),data,World::collisionCallback);
+}
+
+//------------------------------------------------------------------------------------------------
+void Space::collide(CollisionCallback* colCallback, bool useInternalCollisionFlag)
+{
+	if(useInternalCollisionFlag && !_internal_collisions)
+	{
+		return;
+	}
+	void* data = colCallback;	
+	dSpaceCollide(_space, data, CollisionCallback::collisionCallback);
+}
+//------------------------------------------------------------------------------------------------
+void Space::collide(CollisionCallback* colCallback, Space* space)
+{
+	void* data = colCallback;	
+	dSpaceCollide2((dGeomID)_space,(dGeomID)(space->getSpaceID()),data, CollisionCallback::collisionCallback);
+}
+//------------------------------------------------------------------------------------------------
+void Space::collide(CollisionCallback* colCallback, Geometry* geometry, bool useInternalCollisionFlag)
+{
+	if(useInternalCollisionFlag && !_internal_collisions && geometry->getSpace() == this )
+		return;
+
+	void* data = colCallback;	
+	dSpaceCollide2((dGeomID)_space, geometry->getGeometryID(), data, CollisionCallback::collisionCallback);
+}
+
+//------------------------------------------------------------------------------------------------
+void Space::setInternalCollisions(bool collide)
+{
+	_internal_collisions = collide;
+}
+//------------------------------------------------------------------------------------------------
+bool Space::getInternalCollisions()
+{
+	return _internal_collisions;
+}
+//------------------------------------------------------------------------------------------------
+const AxisAlignedBox& Space::getAxisAlignedBox()
+{
+	dReal aabb[6];
+	dGeomGetAABB((dGeomID)_space,aabb);
+	_bounding_box.setExtents((Real)aabb[0],(Real)aabb[2],(Real)aabb[4],(Real)aabb[1],(Real)aabb[3],(Real)aabb[5]);
+	return _bounding_box;
+}
+//------------------------------------------------------------------------------------------------
+size_t Space::getID()
+{
+	return (size_t)_space;
+}
+//------------------------------------------------------------------------------------------------
+Space::~Space()
+{
+	_world->getSpaceList().unregisterItem((size_t)_space);
+	dSpaceDestroy(_space); 
+}
+//------------------------------------------------------------------------------------------------
+SimpleSpace::SimpleSpace(World *world, const Space* space) : Space (world, space)
+{
+	_space = dSimpleSpaceCreate(getSpaceID(space)); 
+	registerSpace();
+}
+//------------------------------------------------------------------------------------------------
+SimpleSpace::~SimpleSpace()
+{
+}
+//------------------------------------------------------------------------------------------------
+HashTableSpace::HashTableSpace(World *world, const Space* space) : Space (world, space)
+{
+	_space = dHashSpaceCreate(getSpaceID(space)); 
+	registerSpace();
+}
+//------------------------------------------------------------------------------------------------
+void HashTableSpace::setLevels(int min_level,int max_level)
+{
+	dHashSpaceSetLevels(_space,min_level,max_level); 
+}
+//------------------------------------------------------------------------------------------------
+int HashTableSpace::getMinimumLevel()
+{
+	int min_level,max_level;
+	dHashSpaceGetLevels(_space,&min_level,&max_level);
+	return min_level;
+}
+//------------------------------------------------------------------------------------------------
+int HashTableSpace::getMaximumLevel()
+{
+	int min_level,max_level;
+	dHashSpaceGetLevels(_space,&min_level,&max_level);
+	return max_level;
+}
+//------------------------------------------------------------------------------------------------
+HashTableSpace::~HashTableSpace()
+{
+}
+//------------------------------------------------------------------------------------------------
+#if ODE_VERSION_MINOR > 9
+SweepAndPruneSpace::SweepAndPruneSpace(AxisOrder axisOrder, World *world, const Space* space) : Space (world, space)
+{
+	_space = dSweepAndPruneSpaceCreate(getSpaceID(space), axisOrder);
+	registerSpace();
+}
+#endif
+//------------------------------------------------------------------------------------------------
+QuadTreeSpace::QuadTreeSpace(const Ogre::Vector3& center,const Ogre::Vector3& extents,int depth,World *world, const Space* space) : Space (world, space)
+{
+	dVector3 c,e;
+	
+	c[0] = (dReal)center.x;
+	c[1] = (dReal)center.y;
+	c[2] = (dReal)center.z;
+
+	e[0] = (dReal)extents.x;
+	e[1] = (dReal)extents.y;
+	e[2] = (dReal)extents.z;
+
+	_space = dQuadTreeSpaceCreate(getSpaceID(space),c,e,depth); 
+	registerSpace();
+}
+//------------------------------------------------------------------------------------------------
+QuadTreeSpace::~QuadTreeSpace()
+{
+}
+//------------------------------------------------------------------------------------------------
+OgreSceneManagerSpace::OgreSceneManagerSpace(const Ogre::Vector3& center,
+                                             const Ogre::Vector3& extents,
+                                             int depth,
+                                             Ogre::SceneManager *_scn_mgr,
+                                             World *world, const Space* space) : 
+        Space (world, space),
+        _scn_mgr(_scn_mgr)
+{
+    _intersection_query = _scn_mgr->createIntersectionQuery();
+
+    const std::set<Ogre::SceneQuery::WorldFragmentType> *supportedQueryTypes = _intersection_query->getSupportedWorldFragmentTypes();
+    std::set<Ogre::SceneQuery::WorldFragmentType>::const_iterator it = 
+        supportedQueryTypes->find (Ogre::SceneQuery::WFT_PLANE_BOUNDED_REGION);
+    if (it != supportedQueryTypes->end())
+    {
+        _intersection_query->setWorldFragmentType(Ogre::SceneQuery::WFT_PLANE_BOUNDED_REGION);
+        _scene_geometry = true;
+    }
+    else
+    {
+        _intersection_query->setWorldFragmentType(Ogre::SceneQuery::WFT_NONE);
+        _scene_geometry = false;
+    }
+
+    // for now register a dummy space in ode.
+    // perhaps this step can be avoided.dVector3 c,e;
+
+    dVector3 c;
+    c[0] = (dReal)center.x;
+    c[1] = (dReal)center.y;
+    c[2] = (dReal)center.z;
+
+    dVector3 e;
+    e[0] = (dReal)extents.x;
+    e[1] = (dReal)extents.y;
+    e[2] = (dReal)extents.z;
+
+    _space = dQuadTreeSpaceCreate(getSpaceID(space), c, e,depth); 
+    registerSpace();
+}
+//------------------------------------------------------------------------------------------------
+OgreSceneManagerSpace::~OgreSceneManagerSpace()
+{
+    delete _intersection_query;
+}
+//------------------------------------------------------------------------------------------------
+void OgreSceneManagerSpace::collide(void* data)
+{
+    if(_internal_collisions)
+    {
+        // Collision detection
+        Ogre::IntersectionSceneQueryResult& results = _intersection_query->execute();
+
+        Body *body1, *body2;
+        Geometry *geom;
+        Ogre::UserDefinedObject *uo1, *uo2;
+
+        // Movables to Movables
+        Ogre::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)
+            uo1 = it->first->getUserObject();
+            uo2 = it->second->getUserObject();
+
+            // Only perform collision if we have UserDefinedObject links
+            if (uo1 && uo2)
+            {
+                bool isBody1 = false;
+                if (uo1->getTypeName () == "Body")
+                    isBody1 = true;
+
+                bool isBody2 = false;
+                if (uo2->getTypeName () == "Body")
+                    isBody2 = true;
+                if (isBody1 || isBody2)
+                {
+                    if (isBody2 && isBody1)
+                    {
+                        // Both are dynamic object
+                       body1 = static_cast<Body*>(uo1);
+                       body2 = static_cast<Body*>(uo2);
+
+                        // Do detailed collision test
+                        body1->collide (data, body2);
+                    }
+                    else
+                    {
+                        // Both are dynamic object
+                        if (isBody1)
+                        {
+                            body1 = static_cast<Body*>     (uo1);
+                            geom  = static_cast<Geometry*> (uo2);
+                        }
+                        else
+                        {
+                            geom  = static_cast<Geometry*> (uo1);
+                            body1 = static_cast<Body*>     (uo2);
+                        }
+
+                        // Do detailed collision test
+                        body1->collide(data, geom);
+                    }
+                }
+            }
+        }
+
+        // Movables to World
+        if (_scene_geometry)
+        {
+            Ogre::MovableObject *mo;
+            Ogre::SceneQuery::WorldFragment *wf;
+
+            Ogre::SceneQueryMovableWorldFragmentIntersectionList::iterator wit, witend;
+            witend = results.movables2world.end();
+            for (wit = results.movables2world.begin(); wit != witend; ++wit)
+            {
+                mo = wit->first;
+                wf = wit->second;
+
+                // Get user defined objects (generic in OGRE)
+                uo1 = mo->getUserObject();
+                // Only perform collision if we have UserDefinedObject link
+                // otherwise ...
+                if (uo1)
+                {
+                    // Cast to ApplicationObject
+                    if (uo1->getTypeName () == "Body")
+                    {
+                        body1 = static_cast<Body*>(uo1);
+                        body1->collidePlaneBounds(data, wf);
+                    }
+//                     else // static objects don't collide against Scene Geometry
+//                     {
+//                         geom = static_cast<Geometry*>(uo);
+//                         // Do detailed collision test
+//                     }
+                }
+            }
+        }
+        // no need to use that one.
+        // dSpaceCollide(_space,data, World::collisionCallback);
+    }
+}
Index: code/branches/physics/src/ogreode/OgreOdeSpace.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeSpace.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeSpace.h	(revision 1919)
@@ -0,0 +1,146 @@
+#ifndef _OGREODESPACE_H_
+#define _OGREODESPACE_H_
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeMaintainedList.h"
+
+namespace OgreOde 
+{
+	class _OgreOdeExport Space
+	{
+        friend class Geometry;
+		friend class World;
+	
+#if ODE_VERSION_MINOR > 9
+	public:
+		enum Class
+		{
+			Class_SimpleSpace		= dSimpleSpaceClass,
+			Class_HashSpace			= dHashSpaceClass,
+			Class_SweepAndPrune		= dSweepAndPruneSpaceClass,
+			Class_QuadTree			= dQuadTreeSpaceClass,
+			Class_FirstUser			= dFirstUserClass,
+			Class_LastUser			= dLastUserClass
+		};
+		Space::Class getClass(); 
+#endif
+
+	public:
+		Space(World *world, const Space* space = 0);
+		virtual ~Space();
+
+		void registerSpace();
+
+		void setAutoCleanup(bool on); 
+		bool getAutoCleanup(); 
+
+		void addGeometry(const Geometry& geometry); 
+		void removeGeometry(const Geometry& geometry); 
+		bool containsGeometry(const Geometry& geometry); 
+		int getGeometryCount(); 
+		Geometry* getGeometry(int index);
+
+		virtual void collide(void* data = 0);
+		virtual void collide(Space* space,void* data = 0);
+		virtual void collide(Geometry* geometry,void* data = 0);
+		
+		
+		virtual void collide(CollisionCallback* colCallback, bool useInternalCollisionFlag = true);
+		virtual void collide(CollisionCallback* colCallback, Space* space);
+		virtual void collide(CollisionCallback* colCallback, Geometry* geometry, bool useInternalCollisionFlag = true);
+		
+		
+		void setInternalCollisions(bool collide);
+		bool getInternalCollisions();
+
+		virtual const Ogre::AxisAlignedBox& getAxisAlignedBox(); 
+
+		virtual size_t getID();
+
+		World* getWorld(){ return _world; }
+
+	protected:
+		dSpaceID getSpaceID() const;
+		dSpaceID getSpaceID(const Space* space) const;
+
+	protected:
+		dSpaceID                _space;
+		bool                    _internal_collisions;
+		Ogre::AxisAlignedBox    _bounding_box;
+        World                   *_world;
+	};
+
+	class _OgreOdeExport SimpleSpace:public Space
+	{
+	public:
+		SimpleSpace(World *world, const Space* space = 0);
+		~SimpleSpace();
+	};
+
+	class _OgreOdeExport HashTableSpace:public Space
+	{
+	public:
+		HashTableSpace(World *world, const Space* space = 0);
+		~HashTableSpace();
+
+		void setLevels(int min_level,int max_level);
+		int getMinimumLevel();
+		int getMaximumLevel();
+	};
+
+	class _OgreOdeExport QuadTreeSpace:public Space
+	{
+	public:
+		QuadTreeSpace(const Ogre::Vector3& center,const Ogre::Vector3& extents,int depth,World *world, const Space* space = 0);
+		~QuadTreeSpace();
+    };
+
+#if ODE_VERSION_MINOR > 9
+	class _OgreOdeExport SweepAndPruneSpace : public Space
+	{
+	public:
+		enum AxisOrder
+		{
+			AxisOrder_XYZ = dSAP_AXES_XYZ,
+			AxisOrder_XZY = dSAP_AXES_XZY,
+			AxisOrder_YXZ = dSAP_AXES_YXZ,
+			AxisOrder_YZX = dSAP_AXES_YZX,
+			AxisOrder_ZXY = dSAP_AXES_ZXY,
+			AxisOrder_ZYX = dSAP_AXES_ZYX
+		};
+		
+		// "Order XZY or ZXY usually works best, if your Y is up."
+		SweepAndPruneSpace(AxisOrder axisOrder, World *world, const Space* space = 0);
+	};
+#endif
+	
+    /*
+    * use Scene manager specialized scene partition algo to find collision
+    * 
+    */
+    class _OgreOdeExport OgreSceneManagerSpace:public Space
+    {
+    public:
+        OgreSceneManagerSpace(const Ogre::Vector3& center,
+                                const Ogre::Vector3& extents,
+                                int depth,
+                                Ogre::SceneManager *scn_mgr,
+                                World *world, const Space* space = 0);
+        ~OgreSceneManagerSpace();
+
+        void collide(void* data = 0);
+
+    private:
+        Ogre::SceneManager              *_scn_mgr;
+        Ogre::IntersectionSceneQuery    *_intersection_query;
+
+        // does scene manager has plane collision geometry support
+        // BSP scene manager has that.
+        bool                            _scene_geometry;
+    };
+
+	
+}
+
+#endif
+
Index: code/branches/physics/src/ogreode/OgreOdeStepper.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeStepper.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeStepper.cpp	(revision 1919)
@@ -0,0 +1,376 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeGeometry.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeWorld.h"
+#include "OgreOdeSpace.h"
+#include "OgreOdeStepper.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+//------------------------------------------------------------------------------------------------
+const Ogre::Real cEpsilon = std::numeric_limits<Real>::epsilon();
+//------------------------------------------------------------------------------------------------
+StepHandler::StepHandler(World *world, 
+                 StepModeType stepModeType,
+                 const Ogre::Real step_size, 
+                 const Ogre::Real max_interval, 
+                 const Ogre::Real time_scale) :
+    _world  (world),
+    _paused (false),
+    _listener (0),
+    _auto_pre (false),
+    _auto_post (false), 
+    _root  (0),
+    _step_size (step_size),
+    _total_time (Ogre::Real(0.0)),
+    _max_interval (max_interval),
+    _time_scale (time_scale)
+{
+    switch (stepModeType)
+    {
+        case BasicStep:
+            _current_stepper = new BasicStepMode(world);
+            break;
+        case QuickStep:
+            _current_stepper = new QuickStepMode(world);
+            break;
+        case FastStep:
+            _current_stepper = new FastStepMode(world);
+            break;
+        case StepModeTypeCount:
+        default:
+            assert(0);
+    }
+    assert((step_size > 0)&&("Step size must be greater than zero"));
+    assert((max_interval > 0)&&("max interval must be greater than zero"));
+}
+//------------------------------------------------------------------------------------------------
+void StepHandler::pause(bool pause)
+{
+	_paused = pause;
+}
+//------------------------------------------------------------------------------------------------
+void StepHandler::setStepListener(StepListener* listener)
+{
+	_listener = listener;
+}
+//------------------------------------------------------------------------------------------------
+bool StepHandler::isPaused()
+{
+	return _paused;
+}
+//------------------------------------------------------------------------------------------------
+void StepHandler::setAutomatic(StepHandler::AutoMode mode, Root* root)
+{
+	if ((_root)&&((_auto_pre)||(_auto_post))) 
+        _root->removeFrameListener(this);
+
+	_auto_pre = (mode == AutoMode_PreFrame)?true:false;
+	_auto_post = (mode == AutoMode_PostFrame)?true:false;
+
+	if ((root)&&((_auto_pre)||(_auto_post)))
+	{
+		_root = root;
+		_root->addFrameListener(this);
+	}
+}
+//------------------------------------------------------------------------------------------------
+bool StepHandler::frameStarted(const FrameEvent& evt)
+{
+	if (_auto_pre)
+	{
+		if (step (evt.timeSinceLastFrame)) 
+			_world->synchronise();
+	}
+	return true;
+}
+//------------------------------------------------------------------------------------------------
+bool StepHandler::frameEnded(const FrameEvent& evt)
+{
+	if (_auto_post)
+	{
+		if (step (evt.timeSinceLastFrame))
+			_world->synchronise();
+	}
+	return true;
+}
+//------------------------------------------------------------------------------------------------
+StepHandler::~StepHandler()
+{
+	setAutomatic(AutoMode_NotAutomatic);
+}
+//------------------------------------------------------------------------------------------------
+bool StepHandler::basicStep(const Ogre::Real time)
+{
+    if (_listener && !_listener->preStep(time))
+        return false;
+
+    _world->getDefaultSpace()->collide();
+
+    if (_listener && !_listener->middleStep(time))
+        return false;
+
+    _current_stepper->step(time);
+
+
+	_world->clearContacts();
+
+    if (_listener && !_listener->postStep(time))
+        return false;
+
+	return true;
+}
+//------------------------------------------------------------------------------------------------
+bool StepHandler::isRunning(const Ogre::Real time)
+{
+    if (!_paused)
+    {
+       return true;
+    }
+    return false;
+}
+//------------------------------------------------------------------------------------------------
+bool StepHandler::prepareSteppingTime(const Ogre::Real time)
+{
+    // make sure time is not too high (alt-tab, debug)
+	if (_max_interval - time < cEpsilon
+		)
+	{
+		_total_time += _max_interval * _time_scale;
+	}
+	else
+	{
+		_total_time += time * _time_scale;
+	}
+	return (_total_time - cEpsilon > 0);
+}
+//------------------------------------------------------------------------------------------------
+bool StepHandler::step(const Ogre::Real time)
+{
+	if (isRunning(time) && prepareSteppingTime(time))
+	{ 
+		if (basicStep(_total_time))
+		{
+			_world->updateDrawState ();
+            _total_time = Ogre::Real(0);
+		}
+		return true;
+	}
+	return false;
+}
+//------------------------------------------------------------------------------------------------
+ExactVariableStepHandler::ExactVariableStepHandler(World *world, 
+                                                   StepModeType stepModeType,
+                                                   const Ogre::Real step_size, 
+                                                   const Ogre::Real max_interval, 
+                                                   const Ogre::Real time_scale):
+    StepHandler(world, stepModeType, step_size,  max_interval, time_scale)
+{
+}
+//------------------------------------------------------------------------------------------------
+bool ExactVariableStepHandler::step(const Ogre::Real time)
+{
+    if (isRunning(time) && prepareSteppingTime(time))
+    {
+        // Steps in fixed time slices first...
+        bool did_run = false;
+
+        while (_total_time - _step_size > cEpsilon)
+        {
+            if (StepHandler::basicStep(_step_size))
+            {
+                did_run = true;
+                _total_time -= _step_size;
+            }
+            else 
+            {
+                break;
+            }
+        } 
+
+        // Then do a little clean-up step
+        if (_total_time > cEpsilon)
+        {
+            if (StepHandler::basicStep(_total_time))
+            {
+                did_run = true;
+                _total_time = Ogre::Real(0);
+            }
+        }
+
+        if (did_run)
+        {
+            _world->updateDrawState ();
+        }
+        return did_run;
+    }
+    return false;
+}
+//------------------------------------------------------------------------------------------------
+ExactVariableStepHandler::~ExactVariableStepHandler()
+{
+}
+//------------------------------------------------------------------------------------------------
+ForwardFixedStepHandler::ForwardFixedStepHandler(World *world, 
+    StepModeType stepModeType,
+    const Ogre::Real step_size, 
+    const Ogre::Real max_interval, 
+    const Ogre::Real time_scale):
+    StepHandler(world, stepModeType, step_size, max_interval, time_scale)
+{
+}
+//------------------------------------------------------------------------------------------------
+bool ForwardFixedStepHandler::step(const Ogre::Real time)
+{
+	if (isRunning(time) && prepareSteppingTime(time))
+	{
+		// Slightly different type of ODE stepper, always makes sure
+		// the ODE world is at least level with real-time, and possibly
+		// up to one step ahead, seems to make things a bit smoother (?)
+		bool did_run = false;
+
+        while (_total_time  > cEpsilon)
+        {
+            if (StepHandler::basicStep(_step_size))
+            {
+                did_run = true;
+                _total_time -= _step_size;
+            }
+            else 
+            {
+                break;
+            }
+        } 
+
+
+		if (did_run)
+			_world->updateDrawState ();
+
+		return did_run;
+	}
+	return false;
+}
+//------------------------------------------------------------------------------------------------
+ForwardFixedStepHandler::~ForwardFixedStepHandler()
+{
+}
+//------------------------------------------------------------------------------------------------
+ForwardFixedInterpolatedStepHandler::ForwardFixedInterpolatedStepHandler(World *world, 
+    StepModeType stepModeType,
+    const Ogre::Real step_size, 
+    const Ogre::Real frame_rate, 
+    const Ogre::Real max_interval, 
+    const Ogre::Real time_scale):
+        StepHandler(world, stepModeType, step_size, max_interval, time_scale),
+        _dbl_step_size(step_size * 2),
+        _frame_rate (frame_rate),
+        _inv_step_size(1.0 / frame_rate)
+{
+    if (frame_rate == Ogre::Real(0))
+    {
+        _fixed_frame_rate = false;
+        _next_frame_step_count = 1;
+    }
+    else
+    {
+        _fixed_frame_rate = true;
+        _next_frame_step_count = _frame_rate / (_step_size * _time_scale);
+        if (_next_frame_step_count == 0)
+            _next_frame_step_count = 1;
+    }
+    // compute here the frame_rate adapted to step_size
+    _next_total_time = _next_frame_step_count * _step_size;
+    _inv_next_total_time = 1 / _next_total_time;
+
+	// Need at least _previous and _current position
+	if (_world->getHistorySize() < 2)
+		_world->setHistorySize (2);
+}
+//------------------------------------------------------------------------------------------------
+bool ForwardFixedInterpolatedStepHandler::step(const Ogre::Real time)
+{
+    if (isRunning(time))
+	{	
+		bool did_run = false;
+
+        // if some time did elapse
+        bool should_run = prepareSteppingTime(time);
+        // if fixed frame rate.
+        // make sure we're waiting until next fixed frame rate stepping.
+        if (_fixed_frame_rate && _total_time - _next_total_time < cEpsilon)
+            should_run = false;
+
+        if (should_run)
+        {
+#ifdef _one_step_forward
+            // normal steps, without storing results in history
+            while (_total_time - _step_size > cEpsilon)
+            {
+                if (StepHandler::basicStep(_step_size))
+                {
+                    did_run = true;
+                    _total_time -= _step_size;
+                }
+                else 
+                {
+                    break;
+                }
+            }
+            if (did_run)
+            {
+                // last Special Single Step is specific as we save last state prior stepping.
+                _world->updatePreviousState ();
+                // compute next Frame physic state
+                StepHandler::basicStep(_step_size);
+                _world->updateCurrentState ();	
+            }
+
+#else// _OLD
+
+            // last Special Step is specific as we save last state prior stepping.
+            _world->updatePreviousState ();
+
+            // normal steps, without storing results in history
+            unsigned int next_frame_step_count = _next_frame_step_count;
+            while (next_frame_step_count--)
+            {
+                if (StepHandler::basicStep(_step_size))
+                {
+                    did_run = true;
+                }
+                else 
+                {
+                    break;
+                }
+            }
+
+            if (did_run)
+                _world->updateCurrentState ();	
+
+            _total_time = std::max(_total_time - _next_total_time, Ogre::Real(0.0));
+
+#endif// _OLD
+    		
+        }
+	    // even if no new physic step happened
+        // interpolation may changed its value if time changed...	
+
+	    // interpolate between previousState and currentState;
+        // currentState*interpolationTime + previousState * (1.0f - interpolationTime)
+        // interpolate 
+	    _world->interpolateDrawState(
+            Ogre::Real(1.0) -  (_next_total_time - _total_time) * _inv_next_total_time
+            //(_total_time - _next_total_time) * _inv_next_total_time
+            );
+		return true;
+	}
+	return false;
+}
+//------------------------------------------------------------------------------------------------
+ForwardFixedInterpolatedStepHandler::~ForwardFixedInterpolatedStepHandler()
+{
+}
+
Index: code/branches/physics/src/ogreode/OgreOdeStepper.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeStepper.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeStepper.h	(revision 1919)
@@ -0,0 +1,177 @@
+#ifndef _OGREODESTEPPER_H_
+#define _OGREODESTEPPER_H_
+
+#include "OgreOdePreReqs.h"
+
+namespace OgreOde 
+{
+    //------------------------------------------------------------------------------------------------
+    class _OgreOdeExport StepMode
+    {
+    public:
+        StepMode(World *world) : _world(world){};
+        virtual ~StepMode(){};
+
+        virtual void step(const Ogre::Real time) = 0;
+
+    protected:
+        World* _world;
+    };
+    //------------------------------------------------------------------------------------------------
+    class _OgreOdeExport BasicStepMode : public StepMode
+    {
+    public:
+        BasicStepMode(World *world) : StepMode(world) {};
+        virtual ~BasicStepMode(){};
+
+        inline void step(const Ogre::Real time){ dWorldStep(_world->getWorldID(), (dReal)time);};
+    };
+    //------------------------------------------------------------------------------------------------
+    class _OgreOdeExport QuickStepMode : public StepMode
+    {
+    public:
+        QuickStepMode(World *world) : StepMode(world) {};
+        virtual ~QuickStepMode(){};
+
+        inline void step(const Ogre::Real time){ dWorldQuickStep(_world->getWorldID(), (dReal)time);};
+    };
+    //------------------------------------------------------------------------------------------------
+    class _OgreOdeExport FastStepMode : public StepMode
+    {
+    public:
+        FastStepMode(World *world, int max_iteration = 40) : StepMode(world), _max_iteration(max_iteration) {};
+        virtual ~FastStepMode(){};
+
+        inline void step(const Ogre::Real time){ dWorldStepFast1(_world->getWorldID(), (dReal)time, _max_iteration);};
+    private:
+        int _max_iteration;
+    };
+    //------------------------------------------------------------------------------------------------
+	class _OgreOdeExport StepListener
+	{
+	public:
+		StepListener(){};
+		virtual ~StepListener(){};
+
+        virtual bool preStep(Ogre::Real time) { return true; };
+        virtual bool postStep(Ogre::Real time)  { return true; };
+        virtual bool middleStep(Ogre::Real time)  { return true; };
+    };
+    //------------------------------------------------------------------------------------------------
+	class _OgreOdeExport StepHandler:public Ogre::FrameListener
+    {
+	public:
+		enum AutoMode
+		{
+			AutoMode_NotAutomatic,
+			AutoMode_PreFrame,
+			AutoMode_PostFrame
+        };
+        enum StepModeType
+        {
+            BasicStep = 0,
+            QuickStep,
+            FastStep,
+            StepModeTypeCount
+        };
+
+	public:
+        StepHandler(World *world, 
+            StepModeType stepModeType = QuickStep,
+            const Ogre::Real step_size = Ogre::Real (0.01), 
+            const Ogre::Real max_interval = Ogre::Real(1.0 / 4), 
+            const Ogre::Real time_scale = Ogre::Real(1.0));
+		virtual ~StepHandler();
+
+		virtual bool step(const Ogre::Real time);
+
+		Ogre::Real getStepSize() const {return _step_size;}
+		void setStepSize (const Ogre::Real step_size){_step_size = step_size;}
+
+		void pause(bool pause);
+		bool isPaused();
+
+		void setStepListener(StepListener* listener);
+		void setAutomatic(StepHandler::AutoMode mode, Ogre::Root* root = 0);
+
+		bool frameStarted(const Ogre::FrameEvent& evt);
+		bool frameEnded(const Ogre::FrameEvent& evt);
+
+    protected:
+        bool isRunning(const Ogre::Real time);
+        bool prepareSteppingTime(const Ogre::Real time);
+        bool basicStep(const Ogre::Real time);
+
+	protected:
+		World* _world;
+		bool _paused,_auto_pre,_auto_post;
+		StepListener* _listener;
+		Ogre::Root* _root;
+		Ogre::Real _step_size;
+        Ogre::Real _total_time;
+        Ogre::Real _max_interval;
+        Ogre::Real _time_scale;
+
+        StepMode *_current_stepper;
+    };
+
+    //------------------------------------------------------------------------------------------------
+	class _OgreOdeExport ForwardFixedStepHandler:public StepHandler
+	{
+	public:
+        ForwardFixedStepHandler(World *world, 
+            StepModeType stepModeType = QuickStep,
+            const Ogre::Real step_size = Ogre::Real (0.01), 
+            const Ogre::Real max_interval = Ogre::Real(1.0 / 4), 
+            const Ogre::Real time_scale = Ogre::Real(1.0));
+		virtual ~ForwardFixedStepHandler();
+
+		virtual bool step(const Ogre::Real time);
+    };
+    //------------------------------------------------------------------------------------------------
+	class _OgreOdeExport ExactVariableStepHandler:public StepHandler
+	{
+	public:
+        ExactVariableStepHandler(World *world ,
+            StepModeType stepModeType = QuickStep,
+            const Ogre::Real step_size = Ogre::Real (0.01), 
+            const Ogre::Real max_interval = Ogre::Real(1.0 / 4), 
+            const Ogre::Real time_scale = Ogre::Real(1.0));
+		virtual ~ExactVariableStepHandler();
+
+		virtual bool step(const Ogre::Real time);
+    };
+    //------------------------------------------------------------------------------------------------
+	// Fix your timestep Gaffer implementation.
+	// http://www.gaffer.org/articles/Timestep.html
+	// Gaffer :"If you implement this interpolation technique you ensure that there will
+	// not be any visual stuttering when your display and physics framerates 
+	// are out of sync. It will also perfectly handle the undersampling case so 
+	// your objects will move smoothly when you view your simulation in slow 
+	// motion or ten years from now on that Sexium." 
+	class _OgreOdeExport ForwardFixedInterpolatedStepHandler :public StepHandler
+	{
+	public:
+        ForwardFixedInterpolatedStepHandler(World *world, 
+            StepModeType stepModeType = QuickStep,
+            const Ogre::Real step_size = Ogre::Real (0.01), 
+            const Ogre::Real frame_rate = Ogre::Real (1.0 / 60),
+            const Ogre::Real max_interval = Ogre::Real(1.0 / 4), 
+            const Ogre::Real time_scale = Ogre::Real(1.0));
+		virtual ~ForwardFixedInterpolatedStepHandler();
+
+		virtual bool step(const Ogre::Real time);
+    private :
+        Ogre::Real _dbl_step_size;
+        Ogre::Real _inv_step_size;
+
+        Ogre::Real _next_total_time;
+        unsigned int _next_frame_step_count;
+        Ogre::Real _inv_next_total_time;
+        bool _fixed_frame_rate;
+        Ogre::Real _frame_rate;
+	};
+
+}
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOdeTriangleMeshData.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeTriangleMeshData.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeTriangleMeshData.cpp	(revision 1919)
@@ -0,0 +1,69 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeGeometry.h"
+#include "OgreOdeWorld.h"
+#include "OgreOdeSpace.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeCollision.h"
+#include "OgreOdeDebugObject.h"
+#include "OgreOdeDebugContact.h"
+
+#include "OgreOdeTriangleMeshData.h"
+
+#include "OgreOdeTriangleMeshDataManager.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+
+//------------------------------------------------------------------------------------------------
+TriangleMeshData::TriangleMeshData(String name,
+								   Vector3 scale,
+								   const Ogre::Vector3* vertices,
+								   unsigned int vertex_count,
+								   const TriangleIndex* indices,
+								   unsigned int index_count
+								   ) : 
+    _vertex_count (vertex_count),
+    _index_count (index_count)
+{
+	_name = name;
+	_scale = scale;
+	_vertex_count = vertex_count;
+	_index_count = index_count;
+	_vertices = new dVector3[vertex_count];
+	_indices = new TriangleIndex[index_count];
+
+	for(unsigned int i = 0;i < vertex_count;i++)
+	{
+		_vertices[i][0] = (dReal)vertices[i].x;
+		_vertices[i][1] = (dReal)vertices[i].y;
+		_vertices[i][2] = (dReal)vertices[i].z;
+	}
+
+	memcpy(_indices, indices, sizeof(unsigned int) * index_count);
+
+	_data = dGeomTriMeshDataCreate(); 
+	dGeomTriMeshDataBuildSimple(_data, (const dReal*)_vertices, (int)vertex_count, (dTriIndex*)_indices, (int)index_count); 
+	
+}
+
+
+
+
+//------------------------------------------------------------------------------------------------
+TriangleMeshData::~TriangleMeshData()
+{
+
+	//printf ("destroy TriangleMeshData\n");
+	
+	dGeomTriMeshDataDestroy(_data);
+	
+	TriangleMeshDataManager::getSingleton().removeTriangleMeshData(_name, _scale);
+	
+	delete[] _vertices;
+	delete[] _indices;
+}
+
+
Index: code/branches/physics/src/ogreode/OgreOdeTriangleMeshData.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeTriangleMeshData.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeTriangleMeshData.h	(revision 1919)
@@ -0,0 +1,62 @@
+#ifndef __OgreOdeTriangleMeshData_H__
+#define __OgreOdeTriangleMeshData_H__
+
+#include <Ogre.h>
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeMaintainedList.h"
+
+using namespace std;
+
+namespace OgreOde
+{
+	/** Stores triangle mesh data once and shares it between all geoms that require it
+	*/
+	class _OgreOdeExport TriangleMeshData
+	{
+	public:
+
+		TriangleMeshData(Ogre::String name, Ogre::Vector3 scale, const Ogre::Vector3* vertices, unsigned int vertex_count, const TriangleIndex* indices, unsigned int index_count);
+
+		virtual ~TriangleMeshData();
+		
+		Ogre::String getMeshName(){ return _name; }
+		
+		Ogre::Vector3 getScale(){ return _scale; }
+
+		dTriMeshDataID getData(){ return _data; }
+
+		dVector3* getVertices(){ return _vertices; }
+
+		TriangleIndex* getIndices(){ return _indices; }
+	
+		unsigned int getVertexCount(){ return _vertex_count; }
+
+		unsigned int getIndexCount(){ return _index_count; }		
+		
+	protected:
+	
+		Ogre::String _name;
+		Ogre::Vector3 _scale;
+		dTriMeshDataID _data;
+		dVector3* _vertices;
+		TriangleIndex* _indices;
+		unsigned int _vertex_count;
+        unsigned int _index_count;
+	};
+
+	/** SharedPtr of TriangleMeshData
+	*/
+	class _OgreOdeExport TriangleMeshDataPtr : public Ogre::SharedPtr<TriangleMeshData> 
+	{
+	public:
+		TriangleMeshDataPtr() : Ogre::SharedPtr<TriangleMeshData>() {}
+		TriangleMeshDataPtr(TriangleMeshData* rep) : Ogre::SharedPtr<TriangleMeshData>(rep) {}
+		TriangleMeshDataPtr(const TriangleMeshDataPtr& r) : Ogre::SharedPtr<TriangleMeshData>(r) {} 
+	};
+	
+}
+
+#endif //__OgreOdeTriangleMeshData_H__
+
+
Index: code/branches/physics/src/ogreode/OgreOdeTriangleMeshDataManager.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeTriangleMeshDataManager.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeTriangleMeshDataManager.cpp	(revision 1919)
@@ -0,0 +1,110 @@
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeTriangleMeshDataManager.h"
+
+using namespace Ogre;
+using namespace OgreOde;
+
+namespace Ogre
+{
+	template<> TriangleMeshDataManager *Ogre::Singleton<TriangleMeshDataManager>::ms_Singleton = 0;
+}
+
+namespace OgreOde
+{
+
+	
+	//-----------------------------------------------------------------------
+	TriangleMeshDataManager::TriangleMeshDataManager()
+	{
+	}
+
+	//-----------------------------------------------------------------------
+	TriangleMeshDataManager::~TriangleMeshDataManager()
+	{
+		//mTriangleMeshDataMap.clear();
+	}
+	
+	//-----------------------------------------------------------------------
+	TriangleMeshDataManager *TriangleMeshDataManager::getSingletonPtr () 
+	{
+		return ms_Singleton;
+	}
+
+	//-----------------------------------------------------------------------
+	TriangleMeshDataManager &TriangleMeshDataManager::getSingleton ()
+	{  
+		assert (ms_Singleton);  
+		return (*ms_Singleton);
+	}
+
+
+	//-----------------------------------------------------------------------
+	void TriangleMeshDataManager::addTriangleMeshData(const String& name, TriangleMeshDataPtr shape, Vector3 scale)
+	{
+
+		mTriangleMeshDataMap[name][scale] = shape;
+		
+		// reduce count so when Ode::Geometry changes its dataPtr or is deleted we arn't
+		// left with this one on a referance count of 1
+		unsigned int* count = shape.useCountPointer();
+		(*count)--;
+		
+	}
+
+
+	//-----------------------------------------------------------------------
+	void TriangleMeshDataManager::removeTriangleMeshData(const String& name, Vector3 scale)
+	{
+		
+		TriangleMeshDataPtrMap::iterator itr = mTriangleMeshDataMap.find(name);
+		if(itr != mTriangleMeshDataMap.end())
+		{
+		
+			std::map<Ogre::Vector3, TriangleMeshDataPtr, vectorLess>::iterator itr2;
+			
+			itr2 = itr->second.find(scale);
+			
+			if ( itr2 != itr->second.end() )
+			{
+				//printf ("no TriangleMeshData for scale so erase it\n");
+				itr->second.erase(itr2);
+				itr2->second.setNull();
+			}
+			
+			if (itr->second.size() == 0) 
+			{
+				//printf ("have no TriangleMeshData for this mesh so erase it from map\n");
+				mTriangleMeshDataMap.erase(itr); 
+			}
+		}
+			
+	}
+	
+	
+	/** looks for mesh name then size or returns a NULL TriangleMeshDataPtr
+	*/
+	//-----------------------------------------------------------------------
+	TriangleMeshDataPtr TriangleMeshDataManager::getTriangleMeshData(const String& name, Vector3 scale)
+	{
+	
+		TriangleMeshDataPtrMap::iterator itr = mTriangleMeshDataMap.find(name);
+		if(itr != mTriangleMeshDataMap.end())
+		{
+			std::map<Ogre::Vector3, TriangleMeshDataPtr, vectorLess>::iterator itr2;
+			
+			itr2 = itr->second.find(scale);
+			
+			if ( itr2 != itr->second.end() )
+			{
+				return itr2->second;
+			}
+		}
+		
+		//printf ("TriangleMeshDataManager::getTriangleMeshData not found\n");
+		
+		return NULL;
+	
+	}
+
+}
Index: code/branches/physics/src/ogreode/OgreOdeTriangleMeshDataManager.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeTriangleMeshDataManager.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeTriangleMeshDataManager.h	(revision 1919)
@@ -0,0 +1,79 @@
+#ifndef __OgreOdeTriangleMeshDataManager_H__
+#define __OgreOdeTriangleMeshDataManager_H__
+
+#include <Ogre.h>
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeTriangleMeshData.h"
+
+using namespace std;
+
+namespace OgreOde
+{
+
+	/** Each time a new TriangleMeshData is created it is added to this mananger, in TriangleMeshData's
+		destructor it is removed from the manager
+	*/
+	class TriangleMeshDataManager : public Ogre::Singleton<TriangleMeshDataManager>
+	{
+	
+	protected:
+
+		struct vectorLess {
+			bool operator()(const Ogre::Vector3& a, const Ogre::Vector3& b) const
+			{
+				if (a.x < b.x) return true;
+				if (a.x > b.x) return false;
+				if (a.y < b.y) return true;
+				if (a.y > b.y) return false;
+				return a.z < b.z;
+			}
+		};
+		
+	public:
+	
+		typedef map<Ogre::String, map<Ogre::Vector3, TriangleMeshDataPtr, vectorLess > > TriangleMeshDataPtrMap;
+
+		/** 
+		*/
+		TriangleMeshDataManager();
+
+		/**
+		*/
+		virtual ~TriangleMeshDataManager();
+		
+		/**
+		*/
+		static TriangleMeshDataManager* getSingletonPtr();
+		
+		/**
+		*/
+		static TriangleMeshDataManager& getSingleton();
+		
+		/** 
+		*/
+		void addTriangleMeshData(const Ogre::String& name, TriangleMeshDataPtr shape, Ogre::Vector3 scale);
+		
+		/** 
+		*/
+		void removeTriangleMeshData(const Ogre::String& name, Ogre::Vector3 scale);
+		
+		/** 
+		*/
+		TriangleMeshDataPtr getTriangleMeshData(const Ogre::String& name, Ogre::Vector3 scale);
+		
+		/** 
+		*/
+		const TriangleMeshDataPtrMap getTriangleMeshDataPtrMap(){ return mTriangleMeshDataMap; }
+		
+	protected:
+
+		// mesh name, scale, TriangleMeshDataPtr
+		TriangleMeshDataPtrMap mTriangleMeshDataMap;
+
+	};
+}
+
+#endif //__OgreOdeTriangleMeshDataManager_H__
+
+
Index: code/branches/physics/src/ogreode/OgreOdeUtility.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeUtility.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeUtility.cpp	(revision 1919)
@@ -0,0 +1,49 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeUtility.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+const Ogre::Real Utility::Infinity = dInfinity;
+
+Real Utility::randomReal()
+{
+	return (Real)dRandReal();
+}
+
+/**
+According to the ODE docs;
+	
+By adjusting the values of ERP and CFM, you can achieve various effects. 
+For example you can simulate springy constraints, where the two bodies oscillate 
+as though connected by springs. Or you can simulate more spongy constraints, without 
+the oscillation. In fact, ERP and CFM can be selected to have the same effect as any 
+desired spring and damper constants. If you have a spring constant kp and damping constant kd, 
+then the corresponding ODE constants are:
+	
+ERP = h kp / (h kp + kd)
+CFM = 1 / (h kp + kd)
+	
+where h is the stepsize. These values will give the same effect as a spring-and-damper 
+system simulated with implicit first order integration.
+*/
+//-----------------------------------------------------------------------
+Real Utility::getCFM(Real spring, Real dampening, Real timeStep)
+{
+	return 1 / ((timeStep * spring) + dampening);
+}
+
+//-----------------------------------------------------------------------
+Real Utility::getERP(Real spring, Real dampening, Real timeStep)
+{
+	return  (timeStep * spring) / ((timeStep * spring) + dampening);
+}
+	
+//-----------------------------------------------------------------------
+void Utility::getSpringConstants(Real CFM, Real ERP, Real timeStep, Real &spring, Real &dampening)
+{
+	spring = (ERP / CFM) / timeStep;
+	dampening = (1 / CFM) - timeStep * spring;
+}
Index: code/branches/physics/src/ogreode/OgreOdeUtility.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeUtility.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeUtility.h	(revision 1919)
@@ -0,0 +1,34 @@
+#ifndef _OGREODEUTILITY_H_
+#define _OGREODEUTILITY_H_
+
+#include "OgreOdePreReqs.h"
+
+namespace OgreOde
+{
+	class _OgreOdeExport Utility
+	{
+	public:
+		Utility(){}
+		~Utility(){}
+
+		static Ogre::Real randomReal();
+
+		static const Ogre::Real Infinity;
+
+		/** returns a CFM value for use on joints or contacts
+			@param timeStep is the the stepping time for the world, see Steppers
+		*/
+		static Ogre::Real getCFM(Ogre::Real spring, Ogre::Real dampening, Ogre::Real timeStep);
+
+		/** returns a ERP value for use on joints or contacts
+		*/
+		static Ogre::Real getERP(Ogre::Real spring, Ogre::Real dampening, Ogre::Real timeStep);
+		
+		/** can be used to get spring constants out of a ERP and CFM value
+		*/
+		static void getSpringConstants(Ogre::Real CFM, Ogre::Real ERP, Ogre::Real timeStep, Ogre::Real &spring, Ogre::Real &dampening);
+	};
+}
+
+#endif
+
Index: code/branches/physics/src/ogreode/OgreOdeWorld.cpp
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeWorld.cpp	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeWorld.cpp	(revision 1919)
@@ -0,0 +1,288 @@
+
+#include "OgreOdePrecompiledHeaders.h"
+
+#include "OgreOdeWorld.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeJoint.h"
+#include "OgreOdeGeometry.h"
+#include "OgreOdeSpace.h"
+#include "OgreOdeDebugObject.h"
+
+using namespace OgreOde;
+using namespace Ogre;
+
+CollisionListener* World::_collision_listener = 0;
+//------------------------------------------------------------------------------------------------
+void World::setCollisionListener(CollisionListener* collision_listener)
+{
+	_collision_listener = collision_listener;
+}
+//------------------------------------------------------------------------------------------------
+CollisionListener* World::getCollisionListener()
+{
+	return _collision_listener;
+}
+//------------------------------------------------------------------------------------------------
+World::World(SceneManager* manager) :
+    _show_debug_geoms (false),
+    _show_debug_contact (false),
+    _manager (manager)
+{
+#if ODE_VERSION_MINOR > 9
+	dInitODE2(0);
+	dAllocateODEDataForThread(dAllocateMaskAll);
+#endif
+
+
+	_world = dWorldCreate();
+	_contacts = dJointGroupCreate(0);
+
+	_default_space = new HashTableSpace(this);
+	_default_space->setAutoCleanup(false);
+	_default_space->setInternalCollisions(true);
+
+	setDamping(0.0,0.0);
+	setHistorySize (1);
+
+
+}
+//------------------------------------------------------------------------------------------------
+void World::setHistorySize(size_t historySize)
+{
+	_history_size = historySize;
+
+	MaintainedItemIterator<Body> it = _body_list.getIterator();
+	while(!it.end ())
+	{
+		Body * const b = (Body *) (it.getNext ());
+		b->_historyResize(historySize);
+	}
+
+}
+//------------------------------------------------------------------------------------------------
+size_t World::getHistorySize() const 
+{
+	return _history_size;
+}
+//------------------------------------------------------------------------------------------------
+void World::setGravity(const Ogre::Vector3& gravity)
+{
+	dWorldSetGravity(_world,(dReal)gravity.x,(dReal)gravity.y,(dReal)gravity.z);
+}
+//------------------------------------------------------------------------------------------------
+const Ogre::Vector3& World::getGravity()
+{
+	dVector3 g;
+	dWorldGetGravity(_world,g);
+	_gravity.x = (Real)g[0];
+	_gravity.y = (Real)g[1];
+	_gravity.z = (Real)g[2];
+	return _gravity;
+}
+//------------------------------------------------------------------------------------------------
+void World::setERP(Real erp)
+{
+	dWorldSetERP(_world,(dReal)erp);
+}
+//------------------------------------------------------------------------------------------------
+Real World::getERP()
+{
+	return (Real)dWorldGetERP(_world);
+}
+//------------------------------------------------------------------------------------------------
+void World::setCFM(Real cfm)
+{
+	dWorldSetCFM(_world,(dReal)cfm);
+}
+//------------------------------------------------------------------------------------------------
+Real World::getCFM()
+{
+	return (Real)dWorldGetCFM(_world);
+}
+//------------------------------------------------------------------------------------------------
+void World::setAutoSleep(bool auto_sleep)
+{
+	dWorldSetAutoDisableFlag(_world,(auto_sleep)?1:0);
+}
+//------------------------------------------------------------------------------------------------
+bool World::getAutoSleep()
+{
+	return (dWorldGetAutoDisableFlag(_world))?true:false;
+}
+//------------------------------------------------------------------------------------------------
+void World::setAutoSleepLinearThreshold(Real linear_threshold)
+{
+	dWorldSetAutoDisableLinearThreshold(_world,(dReal)linear_threshold);
+}
+//------------------------------------------------------------------------------------------------
+Real World::getAutoSleepLinearThreshold()
+{
+	return (Real)dWorldGetAutoDisableLinearThreshold(_world);
+}
+//------------------------------------------------------------------------------------------------
+void World::setAutoSleepAngularThreshold(Real angular_threshold)
+{
+	dWorldSetAutoDisableAngularThreshold(_world,(dReal)angular_threshold);
+}
+//------------------------------------------------------------------------------------------------
+Real World::getAutoSleepAngularThreshold()
+{
+	return (Real)dWorldGetAutoDisableAngularThreshold(_world);
+}
+//------------------------------------------------------------------------------------------------
+void World::setAutoSleepSteps(int steps)
+{
+	dWorldSetAutoDisableSteps(_world,steps);
+}
+//------------------------------------------------------------------------------------------------
+int World::getAutoSleepSteps()
+{
+	return dWorldGetAutoDisableSteps(_world);
+}
+//------------------------------------------------------------------------------------------------
+void World::setAutoSleepTime(Real time)
+{
+	dWorldSetAutoDisableTime(_world,(dReal)time);
+}
+//------------------------------------------------------------------------------------------------
+Real World::getAutoSleepTime()
+{
+	return (Real)dWorldGetAutoDisableTime(_world);
+}
+//------------------------------------------------------------------------------------------------
+void World::setAutoSleepAverageSamplesCount(unsigned int time)
+{
+    dWorldSetAutoDisableAverageSamplesCount(_world, time);
+}
+//------------------------------------------------------------------------------------------------
+size_t World::getAutoSleepAverageSamplesCount()
+{
+    return (Real)dWorldGetAutoDisableAverageSamplesCount(_world);
+}
+//------------------------------------------------------------------------------------------------
+void World::setContactCorrectionVelocity(Real velocity)
+{
+	dWorldSetContactMaxCorrectingVel(_world,(dReal)velocity);
+}
+//------------------------------------------------------------------------------------------------
+void World::setContactSurfaceLayer(Real layer)
+{
+	dWorldSetContactSurfaceLayer(_world,(dReal)layer);
+}
+
+//------------------------------------------------------------------------------------------------
+void World::collisionCallback(void *data,dGeomID geom_a,dGeomID geom_b)
+{
+	const bool a_space = (dGeomIsSpace(geom_a))?true:false;
+	const bool b_space = (dGeomIsSpace(geom_b))?true:false;
+	
+	void* const ptr_a = dGeomGetData(geom_a);
+	void* const ptr_b = dGeomGetData(geom_b);
+
+	if(a_space  || b_space )
+	{
+		// Collide a space with a space
+		if(a_space && b_space) 
+			static_cast<Space*>(ptr_a)->collide(static_cast<Space*>(ptr_b),data);
+		else if(a_space) 
+			static_cast<Space*>(ptr_a)->collide(static_cast<Geometry*>(ptr_b),data);
+		else 
+			static_cast<Space*>(ptr_b)->collide(static_cast<Geometry*>(ptr_a),data);
+
+		// Collide geometries internal to the spaces
+		if(a_space) 
+            static_cast<Space*>(ptr_a)->collide(data);
+
+		if(b_space) 
+            static_cast<Space*>(ptr_b)->collide(data);
+	}
+    else
+	{
+		// Collide a geom with a geom, i.e. generate contacts
+		static_cast<Geometry*>(ptr_a)->collide(static_cast<Geometry*>(ptr_b),_collision_listener);
+	}
+}
+//------------------------------------------------------------------------------------------------
+Body* World::findBody(SceneNode* node)
+{
+	Body* body = 0;
+	for(int i = 0;i < node->numAttachedObjects();i++)
+	{
+		MovableObject* obj = node->getAttachedObject(i);
+		if(obj)
+		{
+			if(obj->getMovableType() == Ogre::String("OgreOde::Body"))
+			{
+				body = static_cast<Body*>(obj);
+				break;
+			}
+		}
+	}
+	return body;
+}
+//------------------------------------------------------------------------------------------------
+Body* World::findBody(const Ogre::String& name)
+{
+	Body *b = 0;
+	MaintainedItemIterator<Body> it = _body_list.getIterator();
+	while(!it.end ())
+	{
+		b = (Body*) (it.getNext ());
+		if(b->getName() == name) 
+			return b;
+	}
+	return 0;
+}
+//------------------------------------------------------------------------------------------------
+void World::setDefaultSpace(Space* space)
+{
+	delete _default_space;
+	_default_space = space;
+}
+//------------------------------------------------------------------------------------------------
+void World::setQuickStepIterations(int iterations)
+{
+	dWorldSetQuickStepNumIterations(_world,iterations);
+}
+//------------------------------------------------------------------------------------------------
+int World::getQuickStepIterations()
+{
+	return dWorldGetQuickStepNumIterations(_world);
+}
+//------------------------------------------------------------------------------------------------
+void World::setShowDebugGeometries(bool show)
+{
+	_body_list.setDebug(show);
+	_geometry_list.setDebug(show);
+	_show_debug_geoms = show;
+}
+//------------------------------------------------------------------------------------------------
+void World::setShowDebugContact(bool show)
+{
+    _geometry_list.setDebugContact(show);
+    _show_debug_contact = show;
+}
+//------------------------------------------------------------------------------------------------
+void World::setDamping(Real linear_damping,Real angular_damping)
+{
+	_linear_damping = -(dReal)linear_damping;
+	_angular_damping = -(dReal)angular_damping;
+}
+//------------------------------------------------------------------------------------------------
+Real World::getLinearDamping()
+{
+	return -(Real)_linear_damping;
+}
+//------------------------------------------------------------------------------------------------
+Real World::getAngularDamping()
+{
+	return -(Real)_angular_damping;
+}
+//------------------------------------------------------------------------------------------------
+World::~World()
+{
+	delete _default_space;
+	dJointGroupDestroy(_contacts);
+    dWorldDestroy(_world);
+    dCloseODE();
+}
Index: code/branches/physics/src/ogreode/OgreOdeWorld.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOdeWorld.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOdeWorld.h	(revision 1919)
@@ -0,0 +1,216 @@
+#ifndef _OGREODEWORLD_H_
+#define _OGREODEWORLD_H_
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeMaintainedList.h"
+#include "OgreSingleton.h"
+
+#include <map>
+
+namespace OgreOde 
+{
+	/** The main class which you will use to simulate your world.
+     * 
+	 * This is the core class of OgreOde, it is directly analogous to the ODE world except that
+	 * in OgreOde you can have only one world, which is why it is Singleton.
+	 *
+	 * A World is a container for all the bodies and geometries in you simulation. You also
+	 * use it to set global options for things like gravity, ERP, CFM and automatic sleeping.
+	 * Also, the World is what you step when you want to advance your simulation by a certain time
+	 * period.
+	 */
+	class _OgreOdeExport World
+    {
+        friend class Body;
+		friend class JointGroup;
+		friend class Joint;
+		friend class Space;
+		friend class Geometry;
+		friend class StepHandler;
+
+	public:
+		/** Construct a new World.
+		 * 
+		 * You will need to call this to create the World into which you cabn place your physical objects.
+		 * The World requires a reference to the scene manager you are using in order to create things
+		 * like nodes for debug objects and to obtain configuration options for world geometry.
+		 * 
+		 * \param manager The scene manager you are using.
+		 */
+		World(Ogre::SceneManager* manager);
+		~World();
+
+		void setGravity(const Ogre::Vector3& gravity = Ogre::Vector3::ZERO);
+		const Ogre::Vector3& getGravity();
+
+		void setHistorySize (size_t historySize);
+		size_t getHistorySize () const;
+
+		void setERP(Ogre::Real erp = 0.2);
+		Ogre::Real getERP();
+		void setCFM(Ogre::Real cfm = 10e-5);
+		Ogre::Real getCFM();
+
+		void setContactCorrectionVelocity(Ogre::Real velocity = 0.1);
+		void setContactSurfaceLayer(Ogre::Real layer = 0.001);
+
+		void setAutoSleep(bool auto_sleep = false);
+		bool getAutoSleep();
+		void setAutoSleepLinearThreshold(Ogre::Real linear_threshold = 0.01);
+		Ogre::Real getAutoSleepLinearThreshold();
+		void setAutoSleepAngularThreshold(Ogre::Real angular_threshold = 0.01);
+		Ogre::Real getAutoSleepAngularThreshold();
+		void setAutoSleepSteps(int steps = 10);
+		int getAutoSleepSteps();
+		void setAutoSleepTime(Ogre::Real time = 0);
+		Ogre::Real getAutoSleepTime(); 
+        void setAutoSleepAverageSamplesCount(unsigned int  time = 10);
+        size_t getAutoSleepAverageSamplesCount();
+		inline void step(Ogre::Real stepsize); 
+        inline void quickStep(Ogre::Real stepsize);
+        inline void fastStep(Ogre::Real stepsize);
+
+		void setQuickStepIterations(int iterations);
+		int getQuickStepIterations();
+
+		Body* findBody(Ogre::SceneNode* node);
+		Body* findBody(const Ogre::String& name);
+
+		inline void clearContacts();
+
+		void setCollisionListener(CollisionListener* collision_listener);
+		CollisionListener* getCollisionListener();
+
+		void setShowDebugGeometries(bool show);
+        bool getShowDebugGeometries(){return _show_debug_geoms;}
+
+        void setShowDebugContact(bool show);
+        bool getShowDebugContact(){return _show_debug_contact;}
+
+		inline void notifyGeometry(Body* body);
+
+		Space* getDefaultSpace(){return _default_space;}
+		void setDefaultSpace(Space* space);
+
+		inline Ogre::SceneManager* getSceneManager(){return _manager;}
+
+		void setDamping(Ogre::Real linear_damping,Ogre::Real angular_damping);
+		Ogre::Real getLinearDamping();
+		Ogre::Real getAngularDamping();
+
+		inline void synchronise();
+	
+		inline void updateDrawState();
+		inline void updatePreviousState();
+		inline void updateCurrentState();
+		inline void interpolateDrawState(const Ogre::Real alpha);
+
+
+		inline MaintainedList<Body>			&getBodyList()		{return _body_list;}
+		inline MaintainedList<Joint>		&getJointList()		{return _joint_list;}
+		inline MaintainedList<JointGroup>	&getJointGroupList(){return _joint_group_list;}
+		inline MaintainedList<Geometry>		&getGeometryList()	{return _geometry_list;}
+		inline MaintainedList<Space>		&getSpaceList()		{return _space_list;}
+
+        inline dWorldID                            getWorldID();
+	protected:
+
+        inline dJointGroupID                       getContactGroupID();
+		static void                         collisionCallback(void *data,
+                                                            dGeomID geom_a,
+                                                            dGeomID geom_b);
+
+	protected:
+		dWorldID		            _world;
+		dJointGroupID	            _contacts;
+
+		Space*		                _default_space;
+		
+		static CollisionListener*   _collision_listener;
+
+		MaintainedList<Body>		_body_list;
+		MaintainedList<Joint>		_joint_list;
+		MaintainedList<JointGroup>	_joint_group_list;
+		MaintainedList<Geometry>	_geometry_list;
+		MaintainedList<Space>		_space_list;
+
+        bool			            _show_debug_geoms;
+        bool			            _show_debug_contact;
+
+		Ogre::SceneManager*        	_manager;
+
+		Ogre::Vector3               _gravity;
+		dReal	                    _linear_damping,_angular_damping;
+		size_t                      _history_size;
+	};
+
+
+    //------------------------------------------------------------------------------------------------
+    //INLINED Methods
+    //------------------------------------------------------------------------------------------------
+    //------------------------------------------------------------------------------------------------
+    inline dWorldID World::getWorldID()
+    {
+        return _world;
+    }
+    //------------------------------------------------------------------------------------------------
+    inline dJointGroupID World::getContactGroupID()
+    {
+        return _contacts;
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::notifyGeometry(Body* body)
+    {
+        _geometry_list.notify(body);
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::synchronise()
+    {
+        _body_list.synchronise ();
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::updateDrawState()
+    {
+        _body_list.updateDrawState ();
+        if (_show_debug_contact)
+            _geometry_list.updateDebugContact();
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::interpolateDrawState(const Ogre::Real alpha)
+    {
+        _body_list.interpolateDrawState(alpha);
+        if (_show_debug_contact)
+            _geometry_list.updateDebugContact();
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::updatePreviousState()
+    {
+        _body_list.updatePreviousState();
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::updateCurrentState()
+    {
+        _body_list.updateCurrentState ();
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::clearContacts()
+    {
+        dJointGroupEmpty(_contacts);
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::step(Ogre::Real stepsize)
+    {
+        dWorldStep(_world,(dReal)stepsize); 
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::quickStep(Ogre::Real stepsize)
+    {
+        dWorldQuickStep(_world,(dReal)stepsize);
+    }
+    //------------------------------------------------------------------------------------------------
+    inline void World::fastStep(Ogre::Real stepsize)
+    {
+        dWorldStepFast1(_world,(dReal)stepsize,20);
+    }
+}
+#endif
Index: code/branches/physics/src/ogreode/OgreOde_Core.h
===================================================================
--- code/branches/physics/src/ogreode/OgreOde_Core.h	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOde_Core.h	(revision 1919)
@@ -0,0 +1,17 @@
+#ifndef _OGREODE_CORE_H_
+#define _OGREODE_CORE_H_
+
+#include "OgreOdePreReqs.h"
+#include "OgreOdeUtility.h"
+#include "OgreOdeWorld.h"
+#include "OgreOdeBody.h"
+#include "OgreOdeMass.h"
+#include "OgreOdeJoint.h"
+#include "OgreOdeSpace.h"
+#include "OgreOdeGeometry.h"
+#include "OgreOdeCollision.h"
+#include "OgreOdeStepper.h"
+#include "OgreOdeEntityInformer.h"
+#include "OgreOdeDebugObject.h"
+
+#endif
Index: code/branches/physics/src/ogreode/OgreOde_LGPL.txt
===================================================================
--- code/branches/physics/src/ogreode/OgreOde_LGPL.txt	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOde_LGPL.txt	(revision 1919)
@@ -0,0 +1,514 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
Index: code/branches/physics/src/ogreode/OgreOde_licence.txt
===================================================================
--- code/branches/physics/src/ogreode/OgreOde_licence.txt	(revision 1919)
+++ code/branches/physics/src/ogreode/OgreOde_licence.txt	(revision 1919)
@@ -0,0 +1,25 @@
+Licence for OgreOde
+===================
+
+Copyright 2004-2005 Ed "Green Eyed Monster" Jones.
+Copyright 2006 Paul "Tuan Kuranes" Cheyrou-Lagrèze.
+
+This file is part of OgreOde an integration layer between the OGRE 3D 
+graphics engine and the ODE rigid body dynamics library.
+
+OgreOde is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+OgreOde is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with OgreOde; see the file OgreOde_LGPL.txt If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+
Index: code/branches/physics/visual_studio/vc8/base.vsprops
===================================================================
--- code/branches/physics/visual_studio/vc8/base.vsprops	(revision 1918)
+++ code/branches/physics/visual_studio/vc8/base.vsprops	(revision 1919)
@@ -8,5 +8,5 @@
 	<Tool
 		Name="VCCLCompilerTool"
-		AdditionalIncludeDirectories="&quot;$(RootDir)&quot;;&quot;$(RootDir)src&quot;;&quot;$(RootDir)src\orxonox&quot;;&quot;$(RootDir)src\ceguilua-0.6.1&quot;;&quot;$(LibDir)ogre-1.4.9\include&quot;;&quot;$(LibDir)boost-1.35.0\include&quot;;&quot;$(LibDir)cegui-0.6.1\include&quot;;&quot;$(LibDir)enet-1.2\include&quot;;&quot;$(LibDir)libogg-1.1.3\include&quot;;&quot;$(LibDir)libvorbis-1.2.0\include&quot;;&quot;$(LibDir)openal-1.1\include&quot;;&quot;$(LibDir)freealut-1.1.0\include&quot;;&quot;$(LibDir)tcl-8.5.2\include&quot;;&quot;$(LibDir)zlib-1.2.3\include&quot;"
+		AdditionalIncludeDirectories="&quot;$(RootDir)&quot;;&quot;$(RootDir)src&quot;;&quot;$(RootDir)src\orxonox&quot;;&quot;$(RootDir)src\ceguilua-0.6.1&quot;;&quot;$(LibDir)ogre-1.4.9\include&quot;;&quot;$(LibDir)boost-1.35.0\include&quot;;&quot;$(LibDir)cegui-0.6.1\include&quot;;&quot;$(LibDir)enet-1.2\include&quot;;&quot;$(LibDir)libogg-1.1.3\include&quot;;&quot;$(LibDir)libvorbis-1.2.0\include&quot;;&quot;$(LibDir)openal-1.1\include&quot;;&quot;$(LibDir)freealut-1.1.0\include&quot;;&quot;$(LibDir)tcl-8.5.2\include&quot;;&quot;$(LibDir)zlib-1.2.3\include&quot;;&quot;$(LibDir)ode-0.10.1\include&quot;"
 		PreprocessorDefinitions="WIN32;__WIN32__;_WIN32;_WINDOWS;BOOST_ALL_DYN_LINK;OIS_DYNAMIC_LIB;ZLIB_WINAPI"
 		WarningLevel="3"
@@ -21,5 +21,5 @@
 		Name="VCLinkerTool"
 		OutputFile="$(OutDir)$(ProjectName)$(CS).dll"
-		AdditionalLibraryDirectories="&quot;$(LibDir)boost-1.35.0\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)cegui-0.6.1\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)enet-1.2\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)freealut-1.1.0\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)libogg-1.1.3\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)libvorbis-1.2.0\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)ogre-1.4.9\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)openal-1.1\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)tcl-8.5.2\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)zlib-1.2.3\lib\$(ConfigurationName)&quot;"
+		AdditionalLibraryDirectories="&quot;$(LibDir)boost-1.35.0\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)cegui-0.6.1\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)enet-1.2\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)freealut-1.1.0\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)libogg-1.1.3\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)libvorbis-1.2.0\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)ode-0.10.1\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)ogre-1.4.9\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)openal-1.1\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)tcl-8.5.2\lib\$(ConfigurationName)&quot;;&quot;$(LibDir)zlib-1.2.3\lib\$(ConfigurationName)&quot;"
 		SubSystem="1"
 		ImportLibrary="$(IntDir)\$(TargetName).lib"
Index: code/branches/physics/visual_studio/vc8/ogreode.vcproj
===================================================================
--- code/branches/physics/visual_studio/vc8/ogreode.vcproj	(revision 1919)
+++ code/branches/physics/visual_studio/vc8/ogreode.vcproj	(revision 1919)
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="ogreode"
+	ProjectGUID="{BBA88DC2-CD78-4C00-814B-183899090F3E}"
+	RootNamespace="orxonox"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\debug.vsprops;.\ogreode.vsprops"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\release.vsprops;.\ogreode.vsprops"
+			CharacterSet="1"
+			WholeProgramOptimization="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="TOLUA_RELEASE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeBody.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeCollision.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeDebugContact.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeDebugObject.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeEigenSolver.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeEntityInformer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeGeometry.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeJoint.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeMass.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdePrecompiledHeaders.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+						PrecompiledHeaderThrough="OgreOdePrecompiledHeaders.h"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeSpace.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeStepper.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeTriangleMeshData.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeTriangleMeshDataManager.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeUtility.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeWorld.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOde_Core.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeBody.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeCollision.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeDebugContact.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeDebugObject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeEigenSolver.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeEntityInformer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeFrameListener.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeGeometry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeJoint.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeMaintainedList.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeMass.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdePrecompiledHeaders.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdePreReqs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeSpace.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeStepper.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeTriangleMeshData.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeTriangleMeshDataManager.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeUtility.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ogreode\OgreOdeWorld.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: code/branches/physics/visual_studio/vc8/ogreode.vsprops
===================================================================
--- code/branches/physics/visual_studio/vc8/ogreode.vsprops	(revision 1919)
+++ code/branches/physics/visual_studio/vc8/ogreode.vsprops	(revision 1919)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="ogreode"
+	InheritedPropertySheets=".\directories.vsprops"
+	>
+	<Tool
+		Name="VCCLCompilerTool"
+		AdditionalOptions="/MP2 /Zm200"
+		PreprocessorDefinitions="OGREODE_EXPORTS;_PRECOMP"
+		UsePrecompiledHeader="2"
+		PrecompiledHeaderThrough="OgreOdePrecompiledHeaders.h"
+	/>
+	<Tool
+		Name="VCLinkerTool"
+		AdditionalDependencies="OgreMain$(CS).lib ode_single$(CS).lib"
+	/>
+</VisualStudioPropertySheet>
Index: code/branches/physics/visual_studio/vc8/orxonox.vsprops
===================================================================
--- code/branches/physics/visual_studio/vc8/orxonox.vsprops	(revision 1918)
+++ code/branches/physics/visual_studio/vc8/orxonox.vsprops	(revision 1919)
@@ -8,5 +8,5 @@
 	<Tool
 		Name="VCCLCompilerTool"
-		AdditionalOptions="/MP2"
+		AdditionalOptions="/MP2 /Zm200"
 		PreprocessorDefinitions="ORXONOX_NO_EXPORTS;NETWORK_STATIC_BUILD;LUA_BUILD_AS_DLL"
 		UsePrecompiledHeader="2"
@@ -22,5 +22,5 @@
 		Name="VCPostBuildEventTool"
 		Description="Copying files from init folder..."
-		CommandLine="for %%a in ($(RootDir)\init\$(SolutionName)\$(ConfigurationName)\*) do replace %%a $(OutDir). /A &gt;nul&#x0D;&#x0A;for %%a in ($(RootDir)\init\common\*) do replace %%a $(OutDir). /A &gt;nul"
+		CommandLine="for %%a in ($(RootDir)\init\$(SolutionName)\$(ConfigurationName)\*) do replace %%a $(OutDir). /A &gt;nul&#x0D;&#x0A;for %%a in ($(RootDir)\init\common\*) do replace %%a $(OutDir). /A &gt;nul&#x0D;&#x0A;"
 	/>
 </VisualStudioPropertySheet>
Index: code/branches/physics/visual_studio/vc8/orxonox_vc8.sln
===================================================================
--- code/branches/physics/visual_studio/vc8/orxonox_vc8.sln	(revision 1918)
+++ code/branches/physics/visual_studio/vc8/orxonox_vc8.sln	(revision 1919)
@@ -142,4 +142,10 @@
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ogreode", "ogreode.vcproj", "{BBA88DC2-CD78-4C00-814B-183899090F3E}"
+	ProjectSection(WebsiteProperties) = preProject
+		Debug.AspNetCompiler.Debug = "True"
+		Release.AspNetCompiler.Debug = "False"
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -148,4 +154,8 @@
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{0B6C5CFD-F91B-432A-80A3-2610F61E060B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0B6C5CFD-F91B-432A-80A3-2610F61E060B}.Debug|Win32.Build.0 = Debug|Win32
+		{0B6C5CFD-F91B-432A-80A3-2610F61E060B}.Release|Win32.ActiveCfg = Release|Win32
+		{0B6C5CFD-F91B-432A-80A3-2610F61E060B}.Release|Win32.Build.0 = Release|Win32
 		{53C56131-E2AA-4A27-B460-7AC05D61A0E6}.Debug|Win32.ActiveCfg = Debug|Win32
 		{53C56131-E2AA-4A27-B460-7AC05D61A0E6}.Debug|Win32.Build.0 = Debug|Win32
@@ -184,8 +194,4 @@
 		{35575B59-E1AE-40E8-89C4-2862B5B09B68}.Release|Win32.ActiveCfg = Release|Win32
 		{35575B59-E1AE-40E8-89C4-2862B5B09B68}.Release|Win32.Build.0 = Release|Win32
-		{0B6C5CFD-F91B-432A-80A3-2610F61E060B}.Debug|Win32.ActiveCfg = Debug|Win32
-		{0B6C5CFD-F91B-432A-80A3-2610F61E060B}.Debug|Win32.Build.0 = Debug|Win32
-		{0B6C5CFD-F91B-432A-80A3-2610F61E060B}.Release|Win32.ActiveCfg = Release|Win32
-		{0B6C5CFD-F91B-432A-80A3-2610F61E060B}.Release|Win32.Build.0 = Release|Win32
 		{63B3E57A-4382-42F3-85EC-E869CFCCA88F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{63B3E57A-4382-42F3-85EC-E869CFCCA88F}.Debug|Win32.Build.0 = Debug|Win32
@@ -208,4 +214,8 @@
 		{8F5B7ED0-D380-4B4F-A744-3A568718176C}.Release|Win32.ActiveCfg = Release|Win32
 		{8F5B7ED0-D380-4B4F-A744-3A568718176C}.Release|Win32.Build.0 = Release|Win32
+		{BBA88DC2-CD78-4C00-814B-183899090F3E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{BBA88DC2-CD78-4C00-814B-183899090F3E}.Debug|Win32.Build.0 = Debug|Win32
+		{BBA88DC2-CD78-4C00-814B-183899090F3E}.Release|Win32.ActiveCfg = Release|Win32
+		{BBA88DC2-CD78-4C00-814B-183899090F3E}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
@@ -223,4 +233,5 @@
 		{C6692661-9160-49E6-B109-A155F9485402} = {B9D56701-B4DB-43F8-9920-241CA418C1CE}
 		{8F5B7ED0-D380-4B4F-A744-3A568718176C} = {B9D56701-B4DB-43F8-9920-241CA418C1CE}
+		{BBA88DC2-CD78-4C00-814B-183899090F3E} = {B9D56701-B4DB-43F8-9920-241CA418C1CE}
 	EndGlobalSection
 EndGlobal
