[ODE] - dHeightfield 0.1b -

gl gl at ntlworld.com
Wed Mar 12 13:26:01 2003


Hi,

the uploaded filename was wrong - the link should work now.
--
gl

----- Original Message -----
From: "Max" <madmax@red-falcon.net>
To: "gl" <gl@ntlworld.com>
Sent: Wednesday, March 12, 2003 8:06 PM
Subject: Re: [ODE] - dHeightfield 0.1b -


> Hello gl,
> I get a 404 "page not found" if I try to download the file.
> Is that just me ?
>
> max
>
> 12.03.2003 19:23:53, "gl" <gl@ntlworld.com> wrote:
>
> >
> >A bout of illness later, I've finally got something for you to play with.
> >
> >http://r-i-l.net/_files/ODE/dHeightfield0.1b.zip
> >
> >Right now it only implements sphere collision, but I should have my ray
> >collider in soon.  I've also included skeleton code for other geoms, so
if
> >anybody can implement those, please do!  I know Fabian has been working
on
> >boxes - cylinders would be really handy too.
> >
> >Details of how it works are in the dHeighfield header - here's a quick
> >overview:
> >
> >1) Build the dHeightfield static lib (VC6 workspace included), then
include
> >dHeightfield.h in your project and link with the lib.
> >
> >2) You supply a terrain_tile struct (blech, bad name, will change for
next
> >release) for each of your heightfields/tiles (or you can break a large
> >heightfield up into collider tiles for performance if you like).
> >
> >When a geom's AABB overlaps the heightfield's, it requests the triangles
for
> >all the quads this AABB potentially intersects (in 2D) from the app via a
> >callback function.  For effeciency I decided to use a single callback,
where
> >you fill in each 'patch' vertex only once, and then fill out a face index
> >array (just like indexed rendering).  You can also supply face normals if
> >you don't want them auto-generated.  I've pasted my own tri callback code
to
> >get you started (at the end).
> >
> >Internally I'm using a vertex/face cache per tile, to avoid having to
> >allocate memory all the time, and to reuse cached stuff wherever
possible.
> >
> >I ended up using Pierre's suggested method (closest point in tri) for the
> >sphere collider - it gives you a guaranteed max 1 contact per triangle,
> >which also makes estimating how many contacts to allow easier.  This is
> >important because if you don't allow enough contacts in a dense
heightfield,
> >spheres can actually fall through it!  I've written it so that deep
> >penetrations are kicked out, as they are with planes, so you can get away
> >with relatively few contacts, but some odd things can happen as a result
> >(balance away).
> >
> >Fabian, I haven't tested how this compares performance wise with your
> >method, as I never got the edges to work - perhaps you can give it a
shot?
> >(I'll send you the code I got working, so maybe you can fix the few
> >outstanding problems).
> >
> >Let me know suggestions etc.
> >--
> >gl
> >
>
>// ------------------------------------------------------------------------
-
> >-------------------------------
> >void ODETriCallback (terrain_tile *tile,
> >      unsigned minx_vertex, unsigned maxx_vertex,
> >      unsigned miny_vertex, unsigned maxy_vertex,
> >      dVector3 *vertices,
> >      hf_face  *faces)
> > {
> > world_tile &wtile = *(world_tile*)tile;
> >
> > unsigned min_x = wtile.WorldHeightmapIndexX + minx_vertex;
> > unsigned max_x = wtile.WorldHeightmapIndexX + maxx_vertex;
> > unsigned min_y = wtile.WorldHeightmapIndexY + miny_vertex;
> > unsigned max_y = wtile.WorldHeightmapIndexY + maxy_vertex;
> >
> > wtile.WorldHeightmap->Open(true);
> > dVector3 *vertex = vertices;
> >
> > // fill the collider-allocated vertex array from sample heights:
> > //  find the position of the first bottom/left sample
> > vec3 tile_pos = vec3(wtile.WorldPosition().x - tile->x_halfsize,
> >       wtile.WorldPosition().y,
> >       wtile.WorldPosition().z - tile->y_halfsize);
> > tile_pos.x += (minx_vertex * tile->sample_spacing);
> > tile_pos.z += (miny_vertex * tile->sample_spacing);
> >
> > float vert_z = tile_pos.z;
> > for(unsigned y=min_y; y<=max_y; y++)
> >  {
> >  float vert_x = tile_pos.x;
> >  for(unsigned x=min_x; x<=max_x; x++)
> >   {
> >   float height = (wtile.WorldHeightmap->GetHeight(x,y) / 255.f) - 0.5f;
> >   height     *= wtile.WorldScale();
> >
> >   (*vertex)[0] = vert_x;
> >   (*vertex)[1] = height;
> >   (*vertex)[2] = vert_z;
> >   vertex++;
> >
> >   vert_x += tile->sample_spacing;
> >   }
> >  vert_z += tile->sample_spacing;
> >  }
> >
> > wtile.WorldHeightmap->Close();
> >
> > // and fill the face index array  (using |\| quad layout in my case)
> > const unsigned x_quads  = (max_x - min_x);
> > const unsigned y_quads  = (max_y - min_y);
> > const unsigned row   = x_quads + 1;
> > unsigned    row_start = 0;
> > for(y=0; y<y_quads; y++)
> >  {
> >  unsigned quad = row_start;
> >  for(unsigned x=0; x<x_quads; x++)
> >   {
> >   faces->index[0] = quad;
> >   faces->index[1] = quad + row;
> >   faces->index[2] = quad + 1;
> >   faces++;
> >
> >   faces->index[0] = quad + row;
> >   faces->index[1] = quad + row + 1;
> >   faces->index[2] = quad + 1;
> >   faces++;
> >
> >   quad++;
> >   }
> >  row_start += row;
> >  }
> > }
> >
> >_______________________________________________
> >ODE mailing list
> >ODE@q12.org
> >http://q12.org/mailman/listinfo/ode
> >
>
>
>
>
>