[ODE] trimesh collision

Fenyvesi Peter 11.E fenyvesip at tagdebr.sulinet.hu
Fri Jul 28 14:14:21 MST 2006


Hello

I had some problem with the trimesh collision.
Jason said me, that I would tell the problem. So I send the the most  
important part of the source:

This is some static data for the nearCallback function:

static dWorldID WorldToCollision=0;
static dJointGroupID JointGroupToCollision=0;
static int MaxNumberOfContacts=4;
static bool Collision=false;	//it indicates collision was happened

static void nearCallback(void *data, dGeomID o1, dGeomID o2)
{
	int i=0;

	dBodyID b1 = dGeomGetBody(o1);
	dBodyID b2 = dGeomGetBody(o2);
	if (b1 && b2 && dAreConnectedExcluding(b1, b2, dJointTypeContact)) return;

	dContact *contact=new dContact[MaxNumberOfContacts];
	for (i=0; i<MaxNumberOfContacts; i++)
	{
		contact[i].surface.mode=dContactBounce | dContactSoftCFM | dContactApprox1;
		contact[i].surface.mu = 0.6f;
		contact[i].surface.mu2 = 0;
		contact[i].surface.bounce = 0.1f;
		contact[i].surface.bounce_vel = 0.1f;
		contact[i].surface.soft_cfm = 0.01f;
	}

	if (int numc = dCollide(o1, o2, MaxNumberOfContacts,  
&contact[0].geom, sizeof(dContact)))
	{
		if (dGeomGetClass(o1)==dTriMeshClass ||
			dGeomGetClass(o2)==dTriMeshClass)
		{
			Collision=true;
		}

		for (i=0; i<numc; i++)
		{
			dJointID c=dJointCreateContact(WorldToCollision,  
JointGroupToCollision, &contact[i]);
			dJointAttach(c, b1, b2);
		}
	}
	delete[] contact;
}

This is my trimesh class:

class TriangleMesh
{
public:
	dGeomID GeomID;
	dTriMeshDataID DataID;

	StridedVertex Vertex[4];		//struct StridedVertex{ dVector3 Vertex;};
	StridedTri Face[2];				//struct StridedTri{ int Indices[3];};
	StridedVertex Normals[2];
	int VertexStride;
	int TriStride;
	int VertexCount;
	int IndexCount;
	Color color;

	Vector Position;

	Vector cv1,cv2,cv3;

TriangleMesh(Color color0, dSpaceID container_space)
{
	color=color0;

	Vertex[0].Vertex[0]= 1.0f; Vertex[0].Vertex[1]= 0.0f;  
Vertex[0].Vertex[2]=-1.0f;
	Vertex[1].Vertex[0]=-1.0f; Vertex[1].Vertex[1]= 0.0f;  
Vertex[1].Vertex[2]=-1.0f;
	Vertex[2].Vertex[0]=-1.0f; Vertex[2].Vertex[1]= 0.0f;  
Vertex[2].Vertex[2]= 1.0f;
	Vertex[3].Vertex[0]= 1.0f; Vertex[3].Vertex[1]= 0.0f;  
Vertex[3].Vertex[2]= 1.0f;

	VertexStride=sizeof(StridedVertex);
	VertexCount=4;

	Face[0].Indices[0]=0; Face[0].Indices[1]=1; Face[0].Indices[2]=2;
	Face[1].Indices[0]=0; Face[1].Indices[1]=2; Face[1].Indices[2]=3;

	Normals[0].Vertex[0]=1.0f; Normals[0].Vertex[1]=0.0f;  
Normals[0].Vertex[2]=0.0f;
	Normals[1].Vertex[0]=1.0f; Normals[1].Vertex[1]=0.0f;  
Normals[1].Vertex[2]=0.0f;

	TriStride=sizeof(StridedTri);
	IndexCount=2;

	DataID=dGeomTriMeshDataCreate();
	dGeomTriMeshDataBuildSingle1(DataID, Vertex, VertexStride,  
VertexCount, Face, IndexCount, TriStride, Normals);
	GeomID=dCreateTriMesh(container_space, DataID, NULL, NULL, NULL);

	dQuaternion r1,r2,r3,r4,rfinal;
	dQFromAxisAndAngle(r1,0.0f, 0.0f, 1.0f, 0.0f);
	dQFromAxisAndAngle(r2,0.0f, 1.0f, 0.0f, 0.0f);
	dQFromAxisAndAngle(r3,1.0f, 0.0f, 0.0f, 0.0f);
	dQMultiply0(r4, r1, r2);
	dQMultiply0(rfinal, r4, r3);
	dGeomSetPosition(GeomID, 0.0f, 0.0f, 0.0f);
	dGeomSetQuaternion(GeomID, rfinal);

	dGeomEnable(GeomID);
	dGeomTriMeshEnableTC(GeomID, dBoxClass, int(true));
	dGeomTriMeshEnableTC(GeomID, dSphereClass, int(true));
}

And this is the most important class:

class Physics
{
public:
dWorldID myWorld;
dSpaceID mySpace;
dJointGroupID myContactGroup;
Vector myGravity;

//odegeomclass is the parent class of my box, sphere and plane class
//it work's well
OdeGeomClass *doboz;
OdeGeomClass *plane;

TriangleMesh *trimesh;

Physics()
{
	myWorld=dWorldCreate();
	mySpace=dHashSpaceCreate(0);
	myContactGroup=dJointGroupCreate(0);

	//initialising of the static data
	WorldToCollision=myWorld;
	JointGroupToCollision=myContactGroup;
	MaxNumberOfContacts=10;

	dWorldSetCFM(myWorld, 0.00001f);
	dWorldSetAutoDisableFlag(myWorld,int(true));
	dWorldSetContactMaxCorrectingVel(myWorld,0.1f);
	dWorldSetContactSurfaceLayer(myWorld,0.001f);
	dWorldSetAutoDisableSteps(myWorld, 15);

	myGravity=Vector(0.0f, -0.01f, 0.0f);
	dWorldSetGravity(myWorld, myGravity.x, myGravity.y, myGravity.z);

	//Box(position, rotation, linearvel, angularvel, mass, xlenght,  
ylength, zlength, color)
	doboz=new Box(	Vector(0.0f, 0.2f, 0.0f), Vector(0.0f, 0.0f, 0.0f),
					Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 0.0f),
					5.0f, 0.4f, 0.4f, 0.4f, Color(0.0f, 1.0f, 0.0f, 1.0f));
	doboz->SetObject(myWorld, mySpace);

	//Plane(a point of the plane, the normal, size-only for the rendering, color)
	plane=new Plane(Vector(0.0f, -1.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f),  
5.0f, Color(0.5f, 0.5f, 0.5f, 1.0f));
	plane->SetObject(myWorld, mySpace);

	//creating the trimesh class
	trimesh=new TriangleMesh(Color(0.0f, 0.0f, 1.0f, 1.0f), mySpace);
}
//destructor
~Physics()
{
	dJointGroupDestroy(myContactGroup);
	dSpaceDestroy(mySpace);
	dWorldDestroy(myWorld);
	dCloseODE();

	delete doboz;
	delete plane;
	delete trimesh;
}

//this function animate the world
//dt is the timestep, it's always 0.015f
void AnimateIt(float dt)
{
	Collision=false;							//set the indicator flag
	dSpaceCollide(mySpace, NULL, nearCallback); //collision detection

	dWorldStep(myWorld, dt);

	//get the new position and rotation of the moving objects
	doboz->RefreshData();
	gomb->RefreshData();

	dJointGroupEmpty(myContactGroup);

	dGeomTriMeshClearTCCache(trimesh->GeomID);
}

This is everything.
I made some test, and realized that the trimesh really should collide  
with the box, in the nearCallback function,
the program never go into the last box (at the last condition).
Can somebody help me?
Thanks, and I'm sorry for my mistakes, but I'm Hungarian and I'm not  
good at speaking English.

Peter




More information about the ODE mailing list