Stunt Rally - version 2.6

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
User avatar
Progman
Kobold
Posts: 38
Joined: Sun Aug 08, 2010 9:13 am

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Progman » Sun Aug 08, 2010 9:32 am

Hi, the binary demo crashs with "Application initialisation error".
i tried to build from source but i got link error: libboost_thread-vc90-mt-p_142.lib.
as i use OgreSDK 1.7.1. the bundled boost library is not compiled with stlport.
how can one fix this ?
thanx.
0 x
Keyboard error: Press any key to continue...

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Crystal Hammer » Sun Aug 08, 2010 8:31 pm

Yes, I'm realising now there is something wrong in those dll's or with msvc dll's.
First, which Windows do you have ?
If it is the (0xc0150002) error or even if it's not, check the issue here:
http://code.google.com/p/vdrift-ogre/issues/detail?id=3
maybe something there will solve the problem,
if not I'll have to rebuild it all in next release, or make an installer for it.
So 1.7.1 uses this libboost_thread-vc90-mt-p_142.lib, it would have to be compiled with stlport then, since the whole game uses it.
I was compiling Ogre from source for it (OIS too).
0 x

BTolputt
Greenskin
Posts: 121
Joined: Thu Feb 18, 2010 8:05 am

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by BTolputt » Mon Aug 09, 2010 7:31 am

I too am getting a crashed executable. Haven't tried building it myself (way too many dependencies for me to try it on something I just want to look at), but I am on a Windows XP Pro Dell machine with decent graphics card... however given the application crashes before any details show up - I'm thinking this might be a missing/bad DLL issue.
0 x

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Crystal Hammer » Mon Aug 09, 2010 8:25 am

This is surely a DLL issue, I just don't know if it is a missing .Net Framework, redist or something in those I've compiled.
Have you tried copying d3dx9_41.dll and installing VS 2008 redist and .Net 2.0 ? Links are in this issue topic:
http://code.google.com/p/vdrift-ogre/issues/detail?id=3
0 x

User avatar
Progman
Kobold
Posts: 38
Joined: Sun Aug 08, 2010 9:13 am

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Progman » Mon Aug 09, 2010 9:46 am

About the link error with ogre 1.7.1 and libboost_thread-mt-p_1-42.lib.
Because Ogre uses Boost with no STLport, and your project redirect Boost config headers to select the STLport lib instead of libboost_thread-mt-1_42.lib bundeled with Ogre.
i tried to build it with vc9 STL but i got compile error with std:list.

So, clearly, you have to get rid of STLport and deal with std::list problem, just like Ogre, Bullet and others do.

for information:
about the .Net framework, i don't think it's has something to do with runtime problem, as none other libraries needed by the project use it. and it's better this way.
i build with VC9(Visual Studio 2008 Express Edition) on XP SP3.
0 x
Keyboard error: Press any key to continue...

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by jacmoe » Mon Aug 09, 2010 10:01 am

Progman wrote:So, clearly, you have to get rid of STLport and deal with std::list problem, just like Ogre, Bullet and others do.
That's really VDrift - IMO that project has some serious issues...
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Crystal Hammer » Mon Aug 09, 2010 10:06 am

Yeah, its just me building it in VS2008. It is released on linux,windows and mac so they build it ok without problems I think.
Anyway I'm having serious trouble finding what to do to avoid this (0xc0150002) error with msvc90*.dll dependency.
I will try to build it again from start without stlport or in a different IDE, this MS VC stuff isn't working here at all, but this will consume some time.
0 x

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by jacmoe » Mon Aug 09, 2010 10:50 am

<rant>
Crystal Hammer wrote:Yeah, its just me building it in VS2008. It is released on linux,windows and mac so they build it ok without problems I think.
I think the problem is that it only works in GCC.
Even on Windows, it's assumed that you compile it using the MinGW tool set.
That's really appalling! I mean: why not fix it? :)
</rant>
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

User avatar
Progman
Kobold
Posts: 38
Joined: Sun Aug 08, 2010 9:13 am

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Progman » Mon Aug 09, 2010 11:00 am

i was looking for the STL memory alignement error and i found an interesting solution, as the project uses Bullet, it might fix it.
check out:
http://ompf.org/forum/viewtopic.php?f=11&t=686#p10591
and on Bullet forum:
http://www.bulletphysics.org/Bullet/php ... stl#p13749
0 x
Keyboard error: Press any key to continue...

User avatar
Progman
Kobold
Posts: 38
Joined: Sun Aug 08, 2010 9:13 am

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Progman » Tue Aug 10, 2010 4:55 pm

I finaly build it without STLport.
simply changed few lines in collision_detection.cpp and collision_detection.h
i replaced the std::list by btAlignedObjectArray, and fixed the iterator with old integer loop.
you have to remove #include <stl/_auto_ptr.h> from the stdafx.h
and the stlportxxx.lib library link reference.

here is the code:
collision_detection.h

Code: Select all

#ifndef _COLLISION_DETECTION_H
#define _COLLISION_DETECTION_H

#include "mathvector.h"
#include "quaternion.h"
#include "vertexarray.h"
#include "aabb.h"
#include "aabb_space_partitioning.h"

//#include "btBulletCollisionCommon.h"
//#include "BulletCollision/Gimpact/btGImpactShape.h"
//#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"


namespace COLLISION_DETECTION
{
	btVector3 ToBulletVector(const MATHVECTOR <float, 3> & v);
	MATHVECTOR <float, 3> ToMathVector(const btVector3 & v);
	btQuaternion ToBulletQuaternion(const QUATERNION <float> & q);
	QUATERNION <float> ToMathQuaternion(const btQuaternion & q);
};

struct	MultipleRayResultCallback : public btCollisionWorld::RayResultCallback
{
	MultipleRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) : m_rayFromWorld(rayFromWorld), m_rayToWorld(rayToWorld) {}
	btVector3	m_rayFromWorld;//used to calculate hitPointWorld from hitFraction
	btVector3	m_rayToWorld;
	
	btAlignedObjectArray <btCollisionWorld::LocalRayResult> results;
	//std::list <btCollisionWorld::LocalRayResult> results;
	
	virtual	btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
	{
		//m_closestHitFraction = rayResult.m_hitFraction;
		m_closestHitFraction = 1.0;
		results.push_back(rayResult);
		
		if (!normalInWorldSpace)
		{
			///need to transform normal into worldspace
			//results.back().m_hitNormalLocal = rayResult.m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
			results.pop_back();
			results.at( results.size()-1 ).m_hitNormalLocal = rayResult.m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
		}
		
		return 1.0;
	}
};

struct COLLISION_OBJECT_VERTEX
{
	float vertex[3];
};

struct COLLISION_OBJECT_FACE
{
	int index[3];
};

class COLLISION_OBJECT_SETTINGS
{
	public:
		enum OBJECT_TYPE
		{
			STATIC,
   			DYNAMIC
		};
	private:
		OBJECT_TYPE type;
		void * objid;
		unsigned short int mask;
		unsigned short int group;
	
	public:
		COLLISION_OBJECT_SETTINGS() : type(STATIC), objid(NULL), mask(1), group(1) {}
		void SetStaticObject() {type = STATIC;}
		void SetDynamicObject() {type = DYNAMIC;}
		void SetObjectID(void * newobjid) {objid = newobjid;}
	
		OBJECT_TYPE GetType() const {return type;}
		const void * ObjID() const {return objid;}
		
		///groupid is 0 through 15.  by default objects are members of group 0. objects can be members of multiple groups.
		void SetDynamicObjectGroup(unsigned int groupid, bool isamember)
		{
			unsigned int bits = 1 << (groupid);
			if (isamember)
				group = group | bits;
			else
				group = group & (~bits);
		}
		
		///maskid is 0 through 15.  by default objects have mask 0 enabled. objects can have multiple masks enabled.
		///objects that have a mask enabled will collide with objects of that group.
		void SetDynamicObjectMask(unsigned int maskid, bool enable)
		{
			unsigned int bits = 1 << (maskid);
			if (enable)
				mask = mask | bits;
			else
				mask = mask & (~bits);
		}

		unsigned short int GetMask() const
		{
			return mask;
		}
	
		unsigned short int GetGroup() const
		{
			return group;
		}
};

class COLLISION_OBJECT
{
	private:
		btCollisionObject id;
		btCollisionShape * shape;
		btTriangleIndexVertexArray * trimesh_varray;
	
		bool loaded;
		
		AABB <float> bbox;
	
		COLLISION_OBJECT_SETTINGS settings;

	public:
		COLLISION_OBJECT() : shape(NULL),trimesh_varray(NULL),loaded(false) {}
		~COLLISION_OBJECT() {DeInit();}
	
		AABB <float> GetBBOX() const;
		btCollisionObject & GetBulletObject() {return id;}
	
		void InitTrimesh(const float * vertices, int vstride, int vcount, const int * faces, int fcount, int istride, const float * normals, const COLLISION_OBJECT_SETTINGS & objsettings);
		void InitTrimesh(const VERTEXARRAY & varray, const COLLISION_OBJECT_SETTINGS & objsettings);
		void InitConvexHull(const std::vector <float> & varray, const COLLISION_OBJECT_SETTINGS & objsettings);
		void InitBox(const MATHVECTOR <float, 3> & halfextents, const COLLISION_OBJECT_SETTINGS & objsettings);
		
		///the cylinder is pointing along the Z axis and the half dimensions are provided in the halfextents vector
		void InitCylinderZ(const MATHVECTOR <float, 3> & halfextents, const COLLISION_OBJECT_SETTINGS & objsettings);
		
		void DeInit();
		void SetPosition(const MATHVECTOR <float, 3> & newpos);
		void SetQuaternion(const QUATERNION <float> & newquat);
		MATHVECTOR <float, 3> GetPosition() const;
	
		COLLISION_OBJECT_SETTINGS & GetSettings() {return settings;}
		const COLLISION_OBJECT_SETTINGS & GetSettings() const {return settings;}
		
		const void * ObjID() const {return settings.ObjID();}
};

class COLLISION_CONTACT
{
	private:
		MATHVECTOR <float, 3> position;
		MATHVECTOR <float, 3> normal;
		COLLISION_OBJECT * col1, * col2;

	public:
		float depth;
		COLLISION_CONTACT() : depth(0), col1(NULL), col2(NULL) {}
		//void SetFromODEContactGeom(dContactGeom odecontactgeom, const PHYSICSCOLLISIONSETTINGS & colsettings);
		//void SetFromBulletContact(btCollisionWorld::LocalRayResult * contact, const PHYSICSCOLLISIONSETTINGS & colsettings);
		const MATHVECTOR <float, 3> & GetContactPosition() const {return position;}
		const MATHVECTOR <float, 3> & GetContactNormal() const {return normal;}
		float GetContactDepth() const {return depth;}
		bool operator<(const COLLISION_CONTACT& other) {return depth < other.depth;}

		COLLISION_OBJECT * GetCollidingObject1() {return col1;}
		COLLISION_OBJECT * GetCollidingObject2() {return col2;}
		void Set(const MATHVECTOR <float, 3> & pos, const MATHVECTOR <float, 3> & norm, float d, COLLISION_OBJECT * c1, COLLISION_OBJECT * c2)
		{
			position = pos;
			normal = norm;
			depth = d;
			col1 = c1;
			col2 = c2;
		}
		void SetCollisionObjects(COLLISION_OBJECT * c1, COLLISION_OBJECT * c2)
		{
			col1 = c1;
			col2 = c2;
		}
		bool CollideRay(const MATHVECTOR <float, 3> & origin, const MATHVECTOR <float, 3> & direction, const float length, COLLISION_CONTACT & output_contact) const;
};
static bool operator<(const COLLISION_CONTACT& first, const COLLISION_CONTACT& other) {return first.depth < other.depth;}

class COLLISION_SETTINGS
{
	private:
		bool staticcollide;
		bool dynamiccollide;
		std::list <void *> exception_objectids;
		unsigned short int raymask;
	
	public:
		COLLISION_SETTINGS() : staticcollide(true),dynamiccollide(false),raymask(0xFF) {}
		
		void SetExceptionObjectID(void * except_id) {exception_objectids.push_back(except_id);}
		const std::list <void *> & GetExceptionObjectIDs() const {return exception_objectids;}

		void SetStaticCollide ( bool value )
		{
			staticcollide = value;
		}
	
		bool GetStaticCollide() const
		{
			return staticcollide;
		}
	
		void SetDynamicCollide ( bool value )
		{
			dynamiccollide = value;
		}
	
		bool GetDynamicCollide() const
		{
			return dynamiccollide;
		}
		
		bool CanCollide(const COLLISION_OBJECT & obj) const
		{
			return (staticcollide && obj.GetSettings().GetType() == COLLISION_OBJECT_SETTINGS::STATIC) ||
				   (dynamiccollide && obj.GetSettings().GetType() == COLLISION_OBJECT_SETTINGS::DYNAMIC);
		}

		unsigned short int GetRayMask() const
		{
			return raymask;
		}

		///set the ray mask to a given short int. this can be used to clear raymask to 0x00 or 0xFF.
		///specific bits can be set with the SetRayMaskBit function
		void SetRayMask ( const unsigned short int& value )
		{
			raymask = value;
		}
		
		///maskid is 0 through 15
		void SetRayMaskBit(unsigned int maskid, bool enable)
		{
			unsigned int bits = 1 << (maskid);
			if (enable)
				raymask = raymask | bits;
			else
				raymask = raymask & (~bits);
		}
};

class COLLISION_WORLD
{
	private:
		btDefaultCollisionConfiguration* collisionconfig;
		/*mutable*/ btCollisionDispatcher* collisiondispatcher; //the dispatcher unfortunately likes to allocate memory when we do queries, so we have to make it mutable to keep our collision query interface const
		bt32BitAxisSweep3* collisionbroadphase;
		//btSimpleBroadphase collisionbroadphase;
		/*mutable*/ btCollisionWorld* id; //we want to keep collision queries const

		AABB_SPACE_PARTITIONING_NODE <COLLISION_OBJECT *> colspeedup;
		std::set <COLLISION_OBJECT *> dynamic_objects;

		bool PassesFilter(const COLLISION_SETTINGS & settings, void * checkme) const;

		struct BulletBroadphaseFilterCallback : public btOverlapFilterCallback
		{
        	// return true when pairs need collision
			virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
			{
				bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
				collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
				btCollisionObject * obj0 = reinterpret_cast<btCollisionObject*>(proxy0->m_clientObject);
				btCollisionObject * obj1 = reinterpret_cast<btCollisionObject*>(proxy1->m_clientObject);
				if (obj0 && obj1)
				{
					COLLISION_OBJECT * col0 = reinterpret_cast<COLLISION_OBJECT*>(obj0->getUserPointer());
					COLLISION_OBJECT * col1 = reinterpret_cast<COLLISION_OBJECT*>(obj1->getUserPointer());
					if (col0 && col1)
					{
						collides = collides && (col0->ObjID() != col1->ObjID());
					}
				}
				return collides;
			}
		} bulletbroadphasefiltercallback;

	public:
		//COLLISION_WORLD() : collisionconfig(), collisiondispatcher(&collisionconfig),collisionbroadphase(),
		//	id(&collisiondispatcher, &collisionbroadphase, &collisionconfig)
		//collisionbroadphase(btVector3(-10000, -10000, -10000), btVector3(10000, 10000, 10000)),
		//					id(&collisiondispatcher, &collisionbroadphase, &collisionconfig)
		COLLISION_WORLD()
		{
			//. . . . . . . . . . .  NEW
			collisionconfig = new btDefaultCollisionConfiguration();
			collisiondispatcher = new btCollisionDispatcher(collisionconfig);
			btVector3 worldMin(-1000,-1000,-1000);
			btVector3 worldMax(1000,1000,1000);
			collisionbroadphase = new bt32BitAxisSweep3(worldMin,worldMax);
			id = new btCollisionWorld(collisiondispatcher, collisionbroadphase, collisionconfig);
			// . . .
			//btGImpactCollisionAlgorithm::registerAlgorithm(&collisiondispatcher);

			//m_shapeDrawer = new GL_ShapeDrawer();
			//m_shapeDrawer->enableTexture(true);

			//m_DebugDrawer = new GLDebugDrawer();
			//id->setDebugDrawer(m_DebugDrawer);
			//id->getDebugDrawer()->setDebugMode(0xff1);  ///*2+*/4+8+64 +128+256+1024+(1<<11)+(1<<12));
			////btIDebugDraw::DebugDrawModes::DBG_DrawAabb
		}
		~COLLISION_WORLD() {Clear();}
		
		void DebugPrint(std::ostream & out)
		{
			std::stringstream junk;
			int numobj(0);
			colspeedup.DebugPrint(0, numobj, true, junk);
			out << "Collision objects: " << numobj << " (internal), " << id->getNumCollisionObjects() << " (external)" << std::endl;
		}
		
		void CollideRay(const MATHVECTOR <float, 3> & position, const MATHVECTOR <float, 3> & direction, const float length, std::list <COLLISION_CONTACT> & outputcontactlist, const COLLISION_SETTINGS & settings) const;
		void CollideObject(COLLISION_OBJECT & object, std::list <COLLISION_CONTACT> & outputcontactlist, const COLLISION_SETTINGS & settings) const;
		
		///slow delete
		void DeletePhysicsObject(COLLISION_OBJECT * objtodel)
		{
			assert(objtodel);
			if (objtodel->GetSettings().GetType() == COLLISION_OBJECT_SETTINGS::DYNAMIC)
			{
				id->removeCollisionObject(&objtodel->GetBulletObject());
				dynamic_objects.erase(objtodel);
			}
			else
				colspeedup.Delete(objtodel);
		}
		
		///fast delete
		void DeletePhysicsObject(COLLISION_OBJECT * objtodel, AABB <float> & bbox)
		{
			assert(objtodel);
			if (objtodel->GetSettings().GetType() == COLLISION_OBJECT_SETTINGS::DYNAMIC)
			{
				id->removeCollisionObject(&objtodel->GetBulletObject());
				dynamic_objects.erase(objtodel);
			}
			else
				colspeedup.Delete(objtodel, bbox);
		}
		
		void Clear()
		{
			for (std::set <COLLISION_OBJECT *>::iterator i = dynamic_objects.begin();
				i != dynamic_objects.end(); ++i)
			{
				id->removeCollisionObject(&(*i)->GetBulletObject());
			}
			dynamic_objects.clear();
			colspeedup.Clear();
		}
		
		void OptimizeObjects() {colspeedup.Optimize();}
		
		void AddPhysicsObject(COLLISION_OBJECT & object)
		{
			COLLISION_OBJECT * obj = &object;
			
			if (object.GetSettings().GetType() == COLLISION_OBJECT_SETTINGS::DYNAMIC)
			{
				short int group = object.GetSettings().GetGroup();
				short int mask = object.GetSettings().GetMask();
				btCollisionObject * colobj = &object.GetBulletObject();
				assert(colobj);
				id->addCollisionObject(colobj, group, mask);
				dynamic_objects.insert(&object);
				//std::cout << "Adding dynamic collision object: " << group << ", " << mask << std::endl;
			}
			else
			{
				AABB <float> bbox = object.GetBBOX();
				colspeedup.Add(obj, bbox);
			}
		}
		
		void CollideDynamicObjects(std::map <COLLISION_OBJECT *, std::list <COLLISION_CONTACT> > & outputcontactlist) const;
		
		void CollideBox(const MATHVECTOR <float, 3> & position, const QUATERNION <float> & orientation, const MATHVECTOR <float, 3> & dimensions, std::list <COLLISION_CONTACT> & outputcontactlist, const COLLISION_SETTINGS & settings) const;
		
		void CollideMovingBox(const MATHVECTOR <float, 3> & position, const MATHVECTOR <float, 3> & velocity, const QUATERNION <float> & orientation, const MATHVECTOR <float, 3> & half_dimensions, std::list <COLLISION_CONTACT> & outputcontactlist, const COLLISION_SETTINGS & settings, float dt) const;
		
		///prevent dynamic objects that have ObjIDs pointing to the same place from colliding
		void FilterOutDynamicCollisionsFromEqualObjectIDs()
		{
			id->getPairCache()->setOverlapFilterCallback(&bulletbroadphasefiltercallback);
		}
};

#endif

and
collision_detection.cpp

Code: Select all

#include "stdafx.h"

#include "collision_detection.h"
#include "unittest.h"

#include <list>
using std::list;

namespace COLLISION_DETECTION
{
btVector3 ToBulletVector(const MATHVECTOR <float, 3> & v)
{
	return btVector3(v[0],v[1],v[2]);
}

MATHVECTOR <float, 3> ToMathVector(const btVector3 & v)
{
	return MATHVECTOR <float, 3> (v.x(),v.y(),v.z());
}

btQuaternion ToBulletQuaternion(const QUATERNION <float> & q)
{
	return btQuaternion(q.x(), q.y(), q.z(), q.w());
}

QUATERNION <float> ToMathQuaternion(const btQuaternion & q)
{
	return QUATERNION <float> (q.x(), q.y(), q.z(), q.w());
}
};

void COLLISION_WORLD::CollideRay(const MATHVECTOR <float, 3> & position, const MATHVECTOR <float, 3> & direction, const float length, std::list <COLLISION_CONTACT> & outputcontactlist, const COLLISION_SETTINGS & settings) const
{
	outputcontactlist.clear();
	
	//return;
	
	MATHVECTOR <float, 3> rpos = position;
	MATHVECTOR <float, 3> rdir = direction;
	MATHVECTOR <float, 3> rayend = position + direction * length;
	AABB <float> raybox;
	raybox.SetFromCorners(position,rayend);
	
	btVector3 rayFrom = COLLISION_DETECTION::ToBulletVector(position);
	btVector3 rayTo = COLLISION_DETECTION::ToBulletVector(rayend);
	MultipleRayResultCallback colresult(rayFrom, rayTo);
	colresult.m_collisionFilterGroup = 0xFF;
	colresult.m_collisionFilterMask = settings.GetRayMask();
	btTransform rayFromTrans,rayToTrans;
	rayFromTrans.setIdentity();
	rayFromTrans.setOrigin(rayFrom);
	rayToTrans.setIdentity();
	rayToTrans.setOrigin(rayTo);
	
	if (settings.GetDynamicCollide())
		id->rayTest(rayFrom, rayTo, colresult);
	
	if (settings.GetStaticCollide())
	{
		list <COLLISION_OBJECT *> candidates;
		colspeedup.Query(AABB<float>::RAY(rpos, rdir, length), candidates);
		
		//cout << "collision candidates: " << candidates.size() << endl;
		for (list <COLLISION_OBJECT *>::iterator i = candidates.begin(); i != candidates.end(); ++i)
		{
			if (settings.CanCollide(**i))
			{
				btCollisionObject * collisionObject = &((*i)->GetBulletObject());
				id->rayTestSingle(rayFromTrans,rayToTrans,
						collisionObject,
						collisionObject->getCollisionShape(),
						collisionObject->getWorldTransform(),
						colresult);
			}
		}
	}
	
	//id.rayTest(rayFrom, rayTo, colresult, raymask);
	
	//cout << "Ray collisions: " << colresult.results.size() << endl;
	
	//if (!colresult.results.empty())
	if (!colresult.results.size())
	{
		//HandleCollision(settings, &colresult, outputcontactlist);
		
		//for (list <btCollisionWorld::LocalRayResult>::iterator i = colresult.results.begin(); i != colresult.results.end(); ++i)
		for (int i = 0; i < colresult.results.size(); ++i)
		{
			//cout << "processing collision" << endl;
			
			assert (colresult.results.at(i)->m_collisionObject); //assert collision hit is tied to an object
			
			if (PassesFilter(settings, colresult.results.at(i).m_collisionObject->getUserPointer()))// && (!i->m_collisionObject->getBroadphaseHandle() || i->m_collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & raymask))
			{
				COLLISION_CONTACT newcont;
				outputcontactlist.push_back(newcont);
				
				MATHVECTOR <float, 3> normal;
				normal.Set(colresult.results.at(i).m_hitNormalLocal.x(),
					colresult.results.at(i).m_hitNormalLocal.y(),
					colresult.results.at(i).m_hitNormalLocal.z());
				normal = normal.Normalize();
				
				btVector3 hp;
				hp.setInterpolate3(colresult.m_rayFromWorld,colresult.m_rayToWorld,colresult.results.at(i).m_hitFraction);
				MATHVECTOR <float, 3> hpv;
				hpv.Set(hp.x(),hp.y(),hp.z());
				outputcontactlist.back().Set(hpv,
					normal,
					(colresult.m_rayToWorld - colresult.m_rayFromWorld).length() * colresult.results.at(i).m_hitFraction,
					(COLLISION_OBJECT*)colresult.results.at(i).m_collisionObject->getUserPointer(),
					(COLLISION_OBJECT*)colresult.results.at(i).m_collisionObject->getUserPointer());
				
				//outputcontactlist.pop_back();
				
				//cout << "PHYSICS::COLLIDERAY Collision hit: raylength=" << (colresult.m_rayToWorld - colresult.m_rayFromWorld).length() << ", hitfraction=" << i->m_hitFraction << ", depth=" << (colresult.m_rayToWorld - colresult.m_rayFromWorld).length() * i->m_hitFraction << ", hitpoint=";VERTEX(hp.x(),hp.y(),hp.z()).DebugPrint();
				//cout << "Collision hit: raylength=" << (colresult.m_rayToWorld - colresult.m_rayFromWorld).length() << ", hitfraction=" << i->m_hitFraction << ", depth=" << (colresult.m_rayToWorld - colresult.m_rayFromWorld).length() * i->m_hitFraction << ", normal=";normal.DebugPrint();
			}
			/*else
			{
				std::cout << "discarded collision due to filtering" << std::endl;
				if (i->m_collisionObject->getBroadphaseHandle())
					std::cout << i->m_collisionObject->getBroadphaseHandle()->m_collisionFilterGroup << ", " << raymask << std::endl;
			}*/
		}
	}
}

AABB <float> COLLISION_OBJECT::GetBBOX() const
{
	if (settings.GetType() == COLLISION_OBJECT_SETTINGS::STATIC)
		return bbox;
	else
	{
		btVector3 aabbMin, aabbMax;
		shape->getAabb(id.getWorldTransform(), aabbMin, aabbMax);
		AABB <float> transformedbox;
		transformedbox.SetFromCorners(COLLISION_DETECTION::ToMathVector(aabbMin), COLLISION_DETECTION::ToMathVector(aabbMax));
		return transformedbox;
	}
}

void COLLISION_WORLD::CollideObject(COLLISION_OBJECT & object, std::list <COLLISION_CONTACT> & outputcontactlist, const COLLISION_SETTINGS & settings) const
{
	outputcontactlist.clear();
	
	//return;
	
	//determine collision candidates in a speedy way
	list <COLLISION_OBJECT *> candidates;
	colspeedup.Query(object.GetBBOX(), candidates);
	
	btCollisionAlgorithm * algo(NULL);
	
	int last_num_manifolds = collisiondispatcher->getNumManifolds();
	
	//std::cout << "Manifolds before: " << collisiondispatcher.getNumManifolds() << std::endl;
	
	for (list <COLLISION_OBJECT *>::iterator i = candidates.begin(); i != candidates.end(); ++i)
	{
		algo = collisiondispatcher->findAlgorithm(&object.GetBulletObject(), &((*i)->GetBulletObject()));
		
		assert (algo); //make sure we can find a collision algorithm
		
		btManifoldResult manifoldout(&object.GetBulletObject(), &((*i)->GetBulletObject()));
		algo->processCollision(&object.GetBulletObject(), &((*i)->GetBulletObject()), id->getDispatchInfo(), &manifoldout);
	}

	//find the number of hits
	int num_manifolds = collisiondispatcher->getNumManifolds();
	
	assert(num_manifolds >= last_num_manifolds);
	
	//if (num_manifolds > 0) std::cout << num_manifolds << " manifolds after" << std::endl;
	
	for (int i=0; i < num_manifolds; i++)
	{
		//find the number of contacts
		btPersistentManifold* manifold = collisiondispatcher->getManifoldByIndexInternal(i);
		btCollisionObject* obA = static_cast<btCollisionObject*>(manifold->getBody0());
		btCollisionObject* obB = static_cast<btCollisionObject*>(manifold->getBody1());
		manifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTransform());
		
		btCollisionObject * otherobject(NULL);
		bool obAisbox(obA == &object.GetBulletObject());
		
		if (obAisbox)
			otherobject = obB;
		else
			otherobject = obA;
		
		int num_contacts = manifold->getNumContacts();
		//if (num_contacts > 0) cout << i << ". " << num_contacts << " contacts" << endl;
		for (int j=0; j < num_contacts; j++)
		{
			btManifoldPoint& pt = manifold->getContactPoint(j);
			btVector3 ptA = pt.getPositionWorldOnA();
			btVector3 ptB = pt.getPositionWorldOnB();
			MATHVECTOR <float, 3> boxpt, otherpt;
			
			if (obAisbox)
			{
				boxpt = COLLISION_DETECTION::ToMathVector(ptA);
				otherpt = COLLISION_DETECTION::ToMathVector(ptB);
			}
			else
			{
				boxpt = COLLISION_DETECTION::ToMathVector(ptB);
				otherpt = COLLISION_DETECTION::ToMathVector(ptA);
			}

			if (PassesFilter(settings, otherobject->getUserPointer()))
			{
				COLLISION_CONTACT newcont;
				outputcontactlist.push_back(newcont);
				
				MATHVECTOR <float, 3> ptv = COLLISION_DETECTION::ToMathVector(pt.m_normalWorldOnB);
				
				outputcontactlist.back().Set(otherpt,
										ptv,
										(otherpt-boxpt).Magnitude(),
										&object,
										(COLLISION_OBJECT*)otherobject->getUserPointer());
			}
		}
		
		manifold->BRAND NAME();
	}
	
	if (algo)
		collisiondispatcher->freeCollisionAlgorithm(algo);
	
	for (int i=0; i < num_manifolds-last_num_manifolds; i++)
		collisiondispatcher->releaseManifold(collisiondispatcher->getManifoldByIndexInternal(collisiondispatcher->getNumManifolds()-1));
}

void COLLISION_WORLD::CollideDynamicObjects(std::map <COLLISION_OBJECT *, std::list <COLLISION_CONTACT> > & outputcontactlist) const
{
	outputcontactlist.clear();
	
	//return;
	
	id->performDiscreteCollisionDetection();
	
	int num_manifolds = collisiondispatcher->getNumManifolds();
	//std::cout << num_manifolds << std::endl;
	
	for (int i=0; i < num_manifolds; i++)
	{
		//find the number of contacts
		btPersistentManifold* manifold = collisiondispatcher->getManifoldByIndexInternal(i);
		btCollisionObject* obA = static_cast<btCollisionObject*>(manifold->getBody0());
		btCollisionObject* obB = static_cast<btCollisionObject*>(manifold->getBody1());
		manifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTransform());
		
		int num_contacts = manifold->getNumContacts();
		//if (num_contacts > 0) cout << i << ". " << num_contacts << " contacts" << endl;
		for (int j=0; j < num_contacts; j++)
		{
			btManifoldPoint& pt = manifold->getContactPoint(j);
			
			MATHVECTOR <float, 3> ptA = COLLISION_DETECTION::ToMathVector(pt.getPositionWorldOnA());
			MATHVECTOR <float, 3> ptB = COLLISION_DETECTION::ToMathVector(pt.getPositionWorldOnB());

			//if (PassesFilter(settings, otherobject->getUserPointer()))
			{
				COLLISION_OBJECT* colobjA = (COLLISION_OBJECT*)obA->getUserPointer();
				COLLISION_OBJECT* colobjB = (COLLISION_OBJECT*)obB->getUserPointer();
				
				assert(colobjA);
				assert(colobjB);
				
				std::list <COLLISION_CONTACT> & outputlist = outputcontactlist[colobjA];
				outputlist.push_back(COLLISION_CONTACT());
				
				MATHVECTOR <float, 3> ptv = COLLISION_DETECTION::ToMathVector(pt.m_normalWorldOnB);
				
				outputlist.back().Set(ptB, ptv, (ptB-ptA).Magnitude(), colobjA, colobjB);
			}
		}
		
		manifold->BRAND NAME();
	}
	
	//for (int i=0; i < num_manifolds; i++) collisiondispatcher.releaseManifold(collisiondispatcher.getManifoldByIndexInternal(collisiondispatcher.getNumManifolds()-1));
}

bool COLLISION_WORLD::PassesFilter(const COLLISION_SETTINGS & settings, void * checkme) const
{
	bool exception = false;
	
	for (list <void *>::const_iterator i = settings.GetExceptionObjectIDs().begin(); i != settings.GetExceptionObjectIDs().end(); ++i)
	{
		exception = exception || (*i == checkme);
	}
	
	return !exception;
}

void COLLISION_OBJECT::InitTrimesh(const float * vertices, int vstride, int vcount, const int * faces, int fcount, int istride, const float * normals, const COLLISION_OBJECT_SETTINGS & objsettings)
{
	assert(!loaded); //Tried to double load a physics object
	
	if (shape != NULL || trimesh_varray != NULL)
		DeInit();
	
	assert(fcount % 3 == 0); //Face count is not a multiple of 3
	
	trimesh_varray = new btTriangleIndexVertexArray(fcount/3, (int*) faces, istride, vcount, (float*) vertices, vstride);
	shape = new btBvhTriangleMeshShape(trimesh_varray, true);
	//shape = new btGImpactMeshShape(trimesh_varray);
	
	id.getWorldTransform().setIdentity();
	id.setCollisionShape(shape);
	
	btVector3 AabbMin,AabbMax;
	id.getCollisionShape()->getAabb(id.getWorldTransform(),AabbMin,AabbMax);
	MATHVECTOR <float, 3> bboxmin;
	bboxmin.Set(AabbMin.x(),AabbMin.y(),AabbMin.z());
	MATHVECTOR <float, 3> bboxmax;
	bboxmax.Set(AabbMax.x(),AabbMax.y(),AabbMax.z());
	
	bbox.SetFromCorners(bboxmin, bboxmax);
	bbox.SetFromCorners(bboxmin, bboxmax);
	//std::cout << bboxmin << " -- " << bboxmax << std::endl;
	//id.setUserPointer(const_cast<void *>(objsettings.ObjID()));
	id.setUserPointer(this);
	settings = objsettings;
	
	loaded = true;
}

void COLLISION_OBJECT::InitConvexHull(const std::vector <float> & varray, const COLLISION_OBJECT_SETTINGS & objsettings)
{
	/*const float * vertices;
	int vcount;
	varray.GetVertices(vertices, vcount);*/
	
	assert(!loaded); //Tried to double load a physics object
	
	if (shape != NULL)
		DeInit();
	
	//shape = new btConvexHullShape(&(varray[0]), varray.size());
	btConvexHullShape * hull = new btConvexHullShape();
	shape = hull;
	for (unsigned int i = 0; i < varray.size(); i+=3)
	{
		btVector3 vert(varray[i],varray[i+1],varray[i+2]);
		hull->addPoint(vert);
	}
	
	/*btConvexHullShape * hull = new btConvexHullShape();
	shape = hull;
	for (int i = 0; i < vcount; i+=3)
	{
		btVector3 vert(vertices[i],vertices[i+1],vertices[i+2]);
		if (!hull->isInside(vert, 0))
			hull->addPoint(vert);
	}*/
	
	id.getWorldTransform().setIdentity();
	id.setCollisionShape(shape);
	id.setUserPointer(this);
	settings = objsettings;
	
	loaded = true;
}

void COLLISION_OBJECT::InitBox(const MATHVECTOR <float, 3> & halfextents, const COLLISION_OBJECT_SETTINGS & objsettings)
{
	assert(!loaded); //Tried to double load a physics object
	
	if (shape != NULL)
		DeInit();
	
	shape = new btBoxShape(COLLISION_DETECTION::ToBulletVector(halfextents));
	id.getWorldTransform().setIdentity();
	id.setCollisionShape(shape);
	bbox.SetFromCorners(halfextents, -halfextents);
	//id.setUserPointer(const_cast<void *>(objsettings.ObjID()));
	id.setUserPointer(this);
	settings = objsettings;
	
	loaded = true;
}

void COLLISION_OBJECT::InitCylinderZ(const MATHVECTOR <float, 3> & halfextents, const COLLISION_OBJECT_SETTINGS & objsettings)
{
	assert(!loaded); //Tried to double load a physics object
	
	if (shape != NULL)
		DeInit();
	
	shape = new btCylinderShapeZ(COLLISION_DETECTION::ToBulletVector(halfextents));
	id.getWorldTransform().setIdentity();
	id.setCollisionShape(shape);
	bbox.SetFromCorners(halfextents, -halfextents);
	//id.setUserPointer(const_cast<void *>(objsettings.ObjID()));
	id.setUserPointer(this);
	settings = objsettings;
	
	loaded = true;
}

void COLLISION_OBJECT::InitTrimesh(const VERTEXARRAY & varray, const COLLISION_OBJECT_SETTINGS & objsettings)
{
	const float * vertices;
	int vcount;
	const int * faces;
	int fcount;
	float * normals(NULL);
	varray.GetVertices(vertices, vcount);
	varray.GetFaces(faces, fcount);
	//std::cout << "verts: " << vcount << ", faces: " << fcount << std::endl;
	InitTrimesh(vertices, sizeof(float)*3, vcount, faces, fcount, sizeof(int)*3, normals, objsettings);
}

void COLLISION_OBJECT::DeInit()
{
	if (trimesh_varray != NULL)
		delete trimesh_varray;
	trimesh_varray = NULL;
	
	if (shape != NULL)
		delete shape;
	shape = NULL;
}

void COLLISION_OBJECT::SetPosition(const MATHVECTOR <float, 3> & newpos)
{
	assert(loaded); //Physics object not loaded yet
	id.getWorldTransform().setOrigin(btVector3(newpos[0],newpos[1],newpos[2]));
}

MATHVECTOR <float, 3> COLLISION_OBJECT::GetPosition() const
{
	assert(loaded); //Physics object not loaded yet
	btVector3 newpos = id.getWorldTransform().getOrigin();
	return MATHVECTOR <float, 3> (newpos[0],newpos[1],newpos[2]);
}

void COLLISION_OBJECT::SetQuaternion(const QUATERNION <float> & newquat)
{
	assert(loaded); //Physics object not loaded yet
	id.getWorldTransform().setRotation(btQuaternion(newquat.x(),newquat.y(),newquat.z(),newquat.w()));
}

bool COLLISION_CONTACT::CollideRay(const MATHVECTOR <float, 3> & origin, const MATHVECTOR <float, 3> & direction, const float length, COLLISION_CONTACT & output_contact) const
{
	/*//simple approximation
	output_contact.Set(position, normal, depth, col1, col2);
	return true;*/

	//enhanced plane-based approximation
	float D = - normal.dot ( position );
	float Pn_dot_Rd = normal.dot ( direction );
	bool newcon ( true );
	if ( Pn_dot_Rd != 0 )
	{
		float t = - ( normal.dot ( origin ) + D ) / ( Pn_dot_Rd );
		if ( t >= 0 )
		{
			MATHVECTOR <float, 3> newpos = origin + direction*t;

			float newdepth = t;

			output_contact.Set(newpos, normal, newdepth, col1, col2);
		}
		else
			newcon = false;
	}
	else
		newcon = false;
	
	return newcon;
}

void COLLISION_WORLD::CollideBox(const MATHVECTOR <float, 3> & position, const QUATERNION <float> & orientation, const MATHVECTOR <float, 3> & dimensions, std::list <COLLISION_CONTACT> & outputcontactlist, const COLLISION_SETTINGS & settings) const
{
	COLLISION_OBJECT_SETTINGS boxsettings;
	boxsettings.SetDynamicObject();
	COLLISION_OBJECT mybox;
	mybox.InitBox(dimensions, boxsettings);
	mybox.SetPosition(position);
	mybox.SetQuaternion(orientation);
	
	CollideObject(mybox, outputcontactlist, settings);
}

void COLLISION_WORLD::CollideMovingBox(const MATHVECTOR <float, 3> & position, const MATHVECTOR <float, 3> & velocity, const QUATERNION <float> & orientation, const MATHVECTOR <float, 3> & half_dimensions, std::list <COLLISION_CONTACT> & outputcontactlist, const COLLISION_SETTINGS & settings, float dt) const
{
	//CollideBox(position, orientation, half_dimensions, outputcontactlist, settings);
	
	//extend our box back in the direction of negative velocity
	MATHVECTOR <float, 3> poschange = velocity*dt;
	MATHVECTOR <float, 3> velocity_local = poschange;
	(-orientation).RotateVector(velocity_local);
	MATHVECTOR <float, 3> newposition = position-poschange*0.5;
	MATHVECTOR <float, 3> absvel = velocity_local;
	absvel.absify();
	MATHVECTOR <float, 3> newdimensions = half_dimensions+absvel*0.5;
	
	/*std::cout << poschange << std::endl;
	std::cout << velocity_local << std::endl;
	std::cout << position << " to " << newposition << std::endl;
	std::cout << half_dimensions << " to " << newdimensions << std::endl;*/
	
	CollideBox(newposition, orientation, newdimensions, outputcontactlist, settings);
	
	for (std::list <COLLISION_CONTACT>::iterator i = outputcontactlist.begin(); i != outputcontactlist.end(); ++i)
	{
		
	}
}

QT_TEST(collision_test)
{
	{
		COLLISION_OBJECT_SETTINGS settings;
		QT_CHECK_EQUAL(settings.GetMask(),1);
		QT_CHECK_EQUAL(settings.GetGroup(),1);
		settings.SetDynamicObjectMask(0,false);
		QT_CHECK_EQUAL(settings.GetMask(),0);
		settings.SetDynamicObjectGroup(2,true);
		QT_CHECK_EQUAL(settings.GetGroup(),5);
		settings.SetDynamicObjectGroup(0,false);
		QT_CHECK_EQUAL(settings.GetGroup(),4);
	}
	{
		COLLISION_OBJECT_SETTINGS settings;
		QT_CHECK_EQUAL(settings.GetGroup(),1);
		settings.SetDynamicObjectGroup(0,false);
		settings.SetDynamicObjectGroup(1,true);
		QT_CHECK_EQUAL(settings.GetGroup(),2);
	}
}
0 x
Keyboard error: Press any key to continue...

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Crystal Hammer » Tue Aug 10, 2010 7:59 pm

Wow, great job and big thanks for finding that.
I think it will be a LOT easier for anyone to build it now.
Strange thing is, I've rebuilded everything without stlport, applied those changes, removed any references to stlport and everthing compiled and linked fine, but when I start the application I get heap errors at start in BaseApp constructor, can't even start the exe.
Did you change anything else in project properites ?

Earlier I rebuilded everything from start, using Ogre from hg repo, and I changed in every dll to link static with msvc (multi-threaded /MT), it worked fine with stlport.x.5.2 and it will resolve the (0xc0150002) issue because it doesn't need any msvc*.dll.
0 x

User avatar
Progman
Kobold
Posts: 38
Joined: Sun Aug 08, 2010 9:13 am

Re: Stunt Rally (VDrift+Ogre) - new version 3

Post by Progman » Tue Aug 10, 2010 8:49 pm

Well, no changes in project settings, but rememeber, i'm using stable OgreSDK 1.7.1
i've found 2 issues.
1: app exits immediatly, because of _ogreset.cfg, it's has to match the machine hardware.
so, i have to delete it before running on alien one. this way the ogre render system dialog will popup.
an easy solution is to force this in the code.

2: there's no text on the overlay dialogs of the GUI, i didn't yet investigate the cause.

3: About app initialization error, it seems that it occures only with the dlls you got in demo.
i copied the app and dlls from my system to a machine with XP sp3, no VS, no Ogre, and it runs perfectly.

P.S.
if you wanna go on with this project, you have to select the ogre version and let us work and talk with same dev references.
P.P.S
Sorry, last edit: check out the binaries:
http://rapidshare.com/files/412204138/S ... v3_bin.rar
0 x
Keyboard error: Press any key to continue...

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 4

Post by Crystal Hammer » Tue Aug 10, 2010 10:42 pm

It's crashing now on some free in loading plugins in new Root. Let's choose stable 1.7.1 then. I will check it soon. And it took about half an hour to get the latest from hg repo.
I've checked your version quickly, the missing text is really odd. And reflections are gone. Btw. you know that you can force ogre dialog to show up in _game.cfg by ogredialog = on, I set it in each release.
Anyway I think I know now why I had those problems with dll's: I linked OgreMain.dll with downloaded dependencies built on vs2008 sp1, and I was building without SP1 so 2 different vc redist's in one dll. I needed to either rebuild all dependencies (freetype lib and so) or install vs sp1 (still don't know what for).

Finally: I've uploaded new release version 4 which doesn't crash at start, it has no msvc dependencies so it should start on all computers.
Has some messed up materials though. But the stunt test track 4 with loops is there.
0 x

User avatar
Progman
Kobold
Posts: 38
Joined: Sun Aug 08, 2010 9:13 am

Re: Stunt Rally (VDrift+Ogre) - version 4

Post by Progman » Tue Aug 10, 2010 10:47 pm

great, i'll check it out tomorrow.
0 x
Keyboard error: Press any key to continue...

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 4

Post by Crystal Hammer » Wed Aug 11, 2010 7:04 am

About the missing text in GUI, I've checked MyGUI.log:
| Error | ResourceTrueTypeFont 'font_Vera.14' - Ttf font disabled. Define MYGUI_USE_FREETYPE if you need ttf fonts.
You just have to check the MYGUI_USE_FREETYPE checkbox in CMake for MyGUI config and rebuild it.
0 x

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 4

Post by jacmoe » Fri Aug 13, 2010 9:06 am

This project was featured at FreeGamer:
http://freegamer.blogspot.com/2010/08/two-weeks.html :)
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

User avatar
koirat
Orc
Posts: 446
Joined: Mon Feb 25, 2008 7:56 pm

Re: Stunt Rally (VDrift+Ogre) - version 4

Post by koirat » Tue Sep 07, 2010 10:57 am

Good:
This looks just too good.

Bad:
What is highly noticeable are shadows that appears with the trees. Dark blink that just don't look to good.

Also you could do something with the grass in front of a car. Maybe start showing some grass further and increase density when closer to the car. This would prevent this rapid wall of grass.
0 x
This is a block of text that can be added to posts you make. There is a 255 character limit.

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 5

Post by Crystal Hammer » Sun Sep 19, 2010 6:10 pm

I don't actually know which problem did you mean with shadows, but there are a lot of problems here.
But you can check the new release 5, maybe it's fixed.
As for the grass, it indeed needs a new shader: to finally enable shadows for grass, and later some thing can be added that removes grass from inside the car when driving. :D

As for the shadows I am using PSSM with 3 textures, basically the setup from Ogre Terrain demo).
If I understand it right (for PSSM), an entity can either cast shadows, or recieive them (correct me if both is possible).
It's written here http://www.ogre3d.org/tikiwiki/Depth+Sh ... e=Cookbook
If I wanted to have self shadowing (is kind of necessary for roads in air casting at those down on terrain) this can be resolved using depth shadows.
But do they have one texture (not 3) and how demanding are they, I tried to implement them but got somewhere about half the framerate of PSSM (I have GeForce 8800 GT 512MB) and PSSM is already quite demanding. The first thing when you have low fps is to turn off shadows.
0 x

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 6, with Track Editor

Post by Crystal Hammer » Mon Nov 15, 2010 5:05 pm

Hi, as for the new release, fixed lot of stuff: grass is shadowed, road material has per pixel normal mapping with shadows and fog.
Had a strange issue with fog_params. Fog is 4x denser in DirectX while in OpenGL it looks normal.
Anyway both render systems should now give the same result (post if somehow not).
Shadows are still broken, but should look more consistent all around. I tested depth shadows here but they are more demanding.

The editor is in its early days, still very basic. It's possible to deform/smooth terrain and modify road,
saving exports all needed data so the modified track can be driven in game. If anyone has suggestions, feel free to post.
I resigned from using Ogitor since it would take me a lot more time to have it suitable for tracks and their export.
Editing is now easy and fast (for me).
Also advanced features like aligning terrain to road, random terrain generation and such will be easier to implement here.
0 x

User avatar
Progman
Kobold
Posts: 38
Joined: Sun Aug 08, 2010 9:13 am

Re: Stunt Rally (VDrift+Ogre) - version 6, with Track Editor

Post by Progman » Wed Nov 17, 2010 7:27 pm

Great work man !
The road alignment with the terrain, the tour-tracks and bridges are terrific !
i have some remarks, suggestions and questions:
The car sim. does not work good: terrain deformations have no effect on the torc, you drive the same way on horizontal road or while climing high hill !
Collision detection for trees, rocks or whatever object could be easly achieved with box meshes or very lowpoly models.
Why car models are not in Ogre mesh format ?
Is the terrain paged ?
Could you make some kind if documentation on how the different parts of the project are stick together(terrain, tracks, bullet, car sim...) and details about the car sim. engine and the tracks ?
0 x
Keyboard error: Press any key to continue...

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 6, with Track Editor

Post by Crystal Hammer » Wed Nov 17, 2010 11:29 pm

Just made columns for bridges/in air roads and fixed few bugs in road. Now I'm implementing pipe roads, they are smoothly drivable.
As for the terrain: it's indeed not very realistic, mainly because of bullet dynamics being simple. Boosting to high frequency of simulation helps only a little.
Anyway the 3S gravel car is very powerful so it can drive on almost vertical roads. The terrain influence isn't that big because of wheels having only ray collision and not taking normal from surface bumpiness.
I'm planing to assign some capsules or other shapes for trees if I do I'll make also an option to disable it, right now I'm just having fun driving through trees :)
Car models aren't in Ogre meshes because those are VDrift cars in .joe format, this way you can have any VDrift car used here too. I guess mesh format would be faster but then it had to be a tool to import them from .joe to .mesh.
Terrain is paged, this is standard Ogre terrain (much like in the demo) with offset mapping material and lod morphing and so on.

I didn't think of writing a documentation on this even in my furthest plans, but I can give some basic info about it:
Car simulation is from VDrift integrated with bullet (I'm still using a revision from April or so).
1. Car's chassis is a dynamic rigid body which collision is simulated in bullet's dynamic world (this way it collides with all shapes in bullet world). Car is made from a btMultiSphereShape for smoother collision.
2. Tires, suspension, gearbox, clutch, differentials, brakes, engine, wheels and aerodynamics (basically all car simulation components) are written in VDrift and simulated there. Pacejka's Magic Formula is used for tires.
Tires collide with terrain (which is in bullet a btHeightfieldTerrainShape) using one ray cast per wheel (I would be more realistic with a cylinder sweep).
Right now this ray can collide also with road (which is in bullet a btBvhTriangleMeshShape). When hit on terrain it gets a material from it (terrain texture layers) by reading the blend map. Surface parameters can be seen in surfaces.txt in any track's dir.
I didn't change much in VDrift's simulation (only gearbox a little) it was already great, I'm more interested in creating a whole game with an editor.
So more info is probably in source code, all files matching car*.h and cpp are about it.
0 x

dudeabot
Gnome
Posts: 334
Joined: Thu Jun 28, 2007 2:12 pm
Location: Brazil
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 6, with Track Editor

Post by dudeabot » Thu Nov 18, 2010 12:38 am

first, this is the best open source racing game i have seen so far =)

i like the simulation very much but i agree with what Progman pointed out.

apart from this, i also have a feeling the grass pops out from nowhere but maybe this can be tweaked easily, also maybe where the road joins the terrain could be improved (though i have no experience this) it doesnt look very smooth right now.. but this are only some details i noticed thinking as a end user =P
0 x

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 6, with Track Editor

Post by Crystal Hammer » Thu Nov 18, 2010 8:44 am

This is true both road and grass appear from nowhere. Grass can be tweaked, by smoothing the density map, I will check it soon. Road could also have some part that fades with alpha to blend smoothly into terrain, I didn't get to that part yet. Thanks for comments.
0 x

User avatar
Progman
Kobold
Posts: 38
Joined: Sun Aug 08, 2010 9:13 am

Re: Stunt Rally (VDrift+Ogre) - version 6, with Track Editor

Post by Progman » Thu Nov 18, 2010 10:56 am

Crystal Hammer wrote: Anyway the 3S gravel car is very powerful so it can drive on almost vertical roads. The terrain influence isn't that big because of wheels having only ray collision and not taking normal from surface bumpiness.
I think this issu must be fixed first, because it's not serious to drive the same way everywhere.
The car should not drive at 100 Km/H over a slopping terrain !
Also, Bullet can handle realistic physics simulation and maybe the problem is the mix with VDrift car sim.
0 x
Keyboard error: Press any key to continue...

User avatar
Crystal Hammer
Greenskin
Posts: 131
Joined: Sat Jun 23, 2007 5:16 pm
Location: Poland
Contact:

Re: Stunt Rally (VDrift+Ogre) - version 6, with Track Editor

Post by Crystal Hammer » Thu Nov 18, 2010 1:00 pm

It probably is the most important, when it comes to simulation realism. But on the other hand, if you won't let driving a slope at 100 km/h then loops will become undriveable. And now they are quite easy, 70 km/h is still enough. If you're thinking of it only for terrain, then that's okay.
I feel like there is some squared velocity damping missing, when wheels are in mud, or on terrain, those dampings present here are to weak. I've also set bullet friction to 0, it should be near 1, but 0 is good when colliding sideways with bridge wall for example. Friction should be different for different parts of car I guess.
Anyway I put first implementing new features (many are missing (pipe road, replays) and editor is really basic) then fixing really annoying bugs (like shadows, grass in car), and at end improving realism. But this project is open so anyone could try to experiment with it and fix it.
0 x

Post Reply