[ODE] Trimesh collision (Terrain)

matt stephure stephure at gmail.com
Tue Aug 23 12:46:28 MST 2005


Thanks for the assistance, but I finally got it working. I think the
memory for the vertices was inadvertantly being cleared. But
everything is working just fine. I appreciate it.

I had another question, a little off topic. I'm having trouble
constructing the index array from my height map. The loop that creates
the height map looks like this:

int Terrain::createDL(float x_offset, float y_offset, float z_offset)
{
	GLuint terrainDL;
	float startW, startL;

	int i, j, aux, aux_flat, vIndex;

	startW = terrainGridWidth / 2.0 - terrainGridWidth;
	startL = -terrainGridLength / 2.0 + terrainGridLength;
	terrainDL = glGenLists(1);

	glNewList(terrainDL, GL_COMPILE);

	//// Do lighting / materials
	glColorMaterial(GL_FRONT, GL_DIFFUSE);
	glEnable(GL_COLOR_MATERIAL);

	vIndex = 0;
	
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	//// Build strips
	for (i = 0; i < terrainGridLength - 1; i++)
	{
		glBegin(GL_TRIANGLE_STRIP);
		
		for (j = 0; j < terrainGridWidth; j++)
		{
			aux = 3*((i+1)*terrainGridWidth + j);
			aux_flat = (i+1) * terrainGridWidth + j;
			

			glNormal3f(
					terrainNormals[aux],
					terrainNormals[aux+1],
					terrainNormals[aux+2]);
			glVertex3f(
					startW +j + x_offset,
					terrainHeights[(i+1) * terrainGridWidth + (j)] + y_offset,
					startL - ((i)+1) + z_offset);

			vertex_count++;

			terrainVerticies[aux_flat][0] = startW + j + x_offset;
			terrainVerticies[aux_flat][2] = terrainHeights[(i+1) * terrainGridWidth +j] +
				y_offset;
			terrainVerticies[aux_flat][1] = startL - ((i)+1) + z_offset;

			aux = 3*(i*terrainGridWidth + j);
			aux_flat = i*terrainGridWidth + j;
			glNormal3f(
					terrainNormals[aux],
					terrainNormals[aux+1],
					terrainNormals[aux+2]);
			glVertex3f(
				startW + j + x_offset,
				terrainHeights[(i) * terrainGridWidth + j] + y_offset,
				startL - i + z_offset);
			
                        vertex_count++;
			
                        terrainVerticies[aux_flat][0] = startW + j + x_offset;
			terrainVerticies[aux_flat][2] = terrainHeights[i * terrainGridWidth +j] +
				y_offset;
			terrainVerticies[aux_flat][1] = startL - ((i)+1) + z_offset;

			
			terrainIndicies[index++] = vIndex;
			terrainIndicies[index++] = vIndex + 1;
			terrainIndicies[index++] = vIndex + terrainGridWidth + 1;

			terrainIndicies[index++] = vIndex + terrainGridWidth;
			terrainIndicies[index++] = vIndex + 1;
			terrainIndicies[index++] = vIndex + terrainGridWidth + 1;

			vIndex ++;
		}
                vIndex++;
		glEnd();
	}
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glEndList();

	return terrainDL;

}

It's really very close. However, there's a tear right down the middle
of my terrain, with all the points bunching up underneat it towards
the top-left. However, 95% of the terrain is fine. I'm pretty new to
this stuff, so this loop may be overkill. Can anyone lend insight into
my n00b errors? :)

On 8/22/05, matt stephure <stephure at gmail.com> wrote:
> Hi Gopi
> 
> My terrain/tri-mesh does not have a body associated with. I use
> dGeomSetBody(id,0) after the mesh creation.
> 
> However, in that line, I want that guard to fail, since it reads:
> if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact))
>   {
>             return;
>   }
> 
> If b2 (the terrain tri-mesh) is false, then it won't return, but
> continue to make contact joints. And it does. Almost always the
> position of the contact joints are 0,0,0.
> 
> Again, thanks for your help.
> 
> 
> 
> On 8/22/05, Gopi Prashanth <gprashanth at heavy-iron.com> wrote:
> > Does your tri-mesh have a body associated with it, if that is zero then you
> > will never have any collision at all... because...
> >   if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact))
> > will always fail...
> >
> > Let me know of that...
> >
> >
> > -----Original Message-----
> > From: matt stephure [mailto:stephure at gmail.com]
> > Sent: Monday, August 22, 2005 1:14 PM
> > To: Gopi Prashanth
> > Subject: Re: [ODE] Trimesh collision (Terrain)
> >
> >
> > Hi there,
> >
> > Thanks for your help! :) Below please find my callback function. I
> > hope the formatting isn't too terrible.
> >
> > Thanks again. I appreciate your time.
> >
> > static void nearCallback (void *data, dGeomID o1, dGeomID o2)
> > {
> >   int MAX_CONTACTS = 40;
> >   int i;
> >
> >   dBodyID b1 = dGeomGetBody(o1);
> >   dBodyID b2 = dGeomGetBody(o2);
> >
> >   Body * b1body = usWORLD->GetBodyByID( b1 );
> >   Body * b2body = usWORLD->GetBodyByID( b2 );
> >
> >
> >   // this means neither was found, bad news
> >   if( b1body == NULL && b2body == NULL )
> >   {
> >         cerr << __FILE__ << ":" << __LINE__ << " - Two null bodies in
> > collider." << endl;
> >         return;
> >   }
> >
> >   // don't collide things connected with a joint
> >   if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact))
> >   {
> >         return;
> >   }
> >
> >   // don't collide things within the same model
> >   if(b1body != NULL && b2body != NULL )
> >   {
> >         if( b1body->GetModelID() == b2body->GetModelID() )
> >         {
> >                 return;
> >         }
> >   }
> >
> >   dContact contact[MAX_CONTACTS];   // up to MAX_CONTACTS contacts per
> > box-box
> >
> >   for (i=0; i<MAX_CONTACTS; i++)
> >   {
> >     // this seems like a bad way to do this,
> >     // make sure the surface is not null furst.
> >     if( b1body->GetSurface() != NULL  )
> >     {
> >                 Surface * surf = b1body->GetSurface();
> >
> >                 if ( surf == NULL  )
> >                 {
> >                         cerr << "Error: Surface does not exist." << endl;
> >                         return;
> >                 }
> >
> >                 dSurfaceParameters * sp = &surf->GetSurfaceParameters();
> >
> >                 if ( sp == NULL )
> >                 {
> >                         cerr << "Found a NULL surface parameter object
> > inside collision
> > detection" << endl;
> >                         return;
> >                 }
> >
> >             contact[i].surface.mode = sp->mode;
> >                 contact[i].surface.mu = sp->mu;
> >         contact[i].surface.mu2 = sp->mu2;
> >         contact[i].surface.slip1 = sp->slip1;
> >         contact[i].surface.slip2 = sp->slip2;
> >         contact[i].surface.bounce = sp->bounce;
> >         contact[i].surface.bounce_vel = sp->bounce_vel;
> >
> >         Vector3 v = surf->GetFrictionDirection();
> >         contact[i].fdir1[0] = v.x;
> >         contact[i].fdir1[1] = inv.y;
> >         contact[i].fdir1[2] = v.z;
> >     }   // (b1body->GetSurface() != NULL)
> >
> >     else if ( b2body->GetSurface() != NULL  )
> >     {
> >                 Surface * surf = b2body->GetSurface();
> >
> >                 if ( surf == NULL  )
> >                 {
> >                         cerr << "Error: Surface does not exist." << endl;
> >                         return;
> >                 }
> >
> >                 dSurfaceParameters * sp = &surf->GetSurfaceParameters();
> >                 if ( sp == NULL )
> >                 {
> >                         cerr << "Found a NULL surface parameter object
> > inside collision
> > detection" << endl;
> >                         return;
> >                 }
> >
> >             contact[i].surface.mode = sp->mode;
> >                 contact[i].surface.mu = sp->mu;
> >         contact[i].surface.mu2 = sp->mu2;
> >         contact[i].surface.slip1 = sp->slip1;
> >         contact[i].surface.slip2 = sp->slip2;
> >         contact[i].surface.bounce = sp->bounce;
> >         contact[i].surface.bounce_vel = sp->bounce_vel;
> >
> >         Vector3 v = surf->GetFrictionDirection();
> >         contact[i].fdir1[0] = v.x;
> >         contact[i].fdir1[1] = v.y;
> >         contact[i].fdir1[2] = v.z;
> >     }
> >   }
> >
> >   // Generate the Contact Points for the Geoms in question
> >   if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom,
> > sizeof(dContact)))
> >   {
> >           dMatrix3 RI;
> >           dRSetIdentity(RI);
> >           const dReal ss[3] = {0.02,0.02,0.02};
> >
> >
> >           for (i=0; i<numc; i++)
> >           {
> >
> >                   // Create a (temporary) collision joint for each contact
> > point
> > from the two Geoms.
> >                   dJointID c = dJointCreateContact
> > (usWORLD->world_id,usWORLD->contact_group->GetGroupId(),contact+i);
> >
> >                   dJointAttach (c,b1,b2);
> >                   // the Geoms will be momentarily stuck together in the
> > collision
> > for one time step.
> >                   // Then the Joint will be destroyed, and the objects are
> > free to
> > move about again.
> > if (show_contacts){
> >
> >                              dw->DrawBox(contact[i].geom.pos,RI,ss);
> >                              printf("contact: %f %f %f\n",
> > contact[i].geom.pos[0],          contact[i].geom.pos[1],
> > contact[i].geom.pos[2]);
> >                 }
> >           }
> >   }
> > }
> >
> >
> > On 8/22/05, Gopi Prashanth <gprashanth at heavy-iron.com> wrote:
> > > Can you send me the nearCallBack function where you are handling the
> > > collision?
> > >
> >
> >
> > --
> > | Matt Stephure
> > | Software Developer
> > | Alberta Ingenuity Centre for Machine Learning
> > | stephure at gmail.com
> > +----------------------------------------------------------
> >
> 
> 
> --
> | Matt Stephure
> | Software Developer
> | Alberta Ingenuity Centre for Machine Learning
> | stephure at gmail.com
> +----------------------------------------------------------
> 


-- 
| Matt Stephure
| Software Developer
| Alberta Ingenuity Centre for Machine Learning
| stephure at gmail.com
+----------------------------------------------------------



More information about the ODE mailing list