[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