Terrain Collision.. how does it work?
by Dylan Sale · in Torque Game Engine · 11/29/2003 (4:53 am) · 18 replies
I am integrating ODE into torque and am at the stage where I want to add the terrain to the simulation.
I figured I would use the new TriMesh geometry class in ODE to make the collision geometry. However, this requires a list of triangles. How can I get the collision triangles (if indeed they are triangles and not just polys) out of the terrain? I have looked through the terrainCollision.cc file, but it is sparsely commented and I dont really know what it does.
I just dont get how it works. I looked through the documentation, but it seems that the collision stuff isnt documented (well, I couldnt find it, maybe im just stupid ;)
If anyone could help me get on track to getting a list of collision triangles for the terrain, youd be really helping me and everyone that wants ODE in Torque :D
Thanks,
Dylan
I figured I would use the new TriMesh geometry class in ODE to make the collision geometry. However, this requires a list of triangles. How can I get the collision triangles (if indeed they are triangles and not just polys) out of the terrain? I have looked through the terrainCollision.cc file, but it is sparsely commented and I dont really know what it does.
I just dont get how it works. I looked through the documentation, but it seems that the collision stuff isnt documented (well, I couldnt find it, maybe im just stupid ;)
If anyone could help me get on track to getting a list of collision triangles for the terrain, youd be really helping me and everyone that wants ODE in Torque :D
Thanks,
Dylan
About the author
#2
11/29/2003 (6:21 am)
Ok, ill give that a try. What are the differences with the poly lists? It doesnt really say in the comments for them.
#3
11/29/2003 (6:40 am)
I'm not quite sure, I have been using ConcretePolyList and my own derived Lists, because you can use it to render the contained polys and it gives you all the polys without any special proccessing steps. Apart from that, I have no experience with them. In the 1.2 version there are a few comments that might help.
#4
It's really very simple if you're not concerned about performance :P
11/29/2003 (11:19 am)
Dylan - I have working code to do this. I'll post it Monday (don't have it on me, go computer lab).It's really very simple if you're not concerned about performance :P
#6
11/30/2003 (12:38 pm)
It would seem something is borked in my setup (some sort of crazy transform bugs), but here's the code..// Set up collision stuff.
mSpace = dHashSpaceCreate(0);
mWorldTriangles = dGeomTriMeshDataCreate();
// Make some triangles...
Box3F worldBox(-5e2, -5e2, -1e3, 5e2, 5e2, 1e3);
ConcretePolyList cpl;
p->getContainer()->buildPolyList( worldBox,
TerrainObjectType | InteriorObjectType |
StaticShapeObjectType | StaticTSObjectType ,
&cpl);
int idxBound = cpl.mIndexList .size();
int vertBound = cpl.mVertexList.size();
dVector3 * verts = new dVector3[vertBound];
int * idx = new int[idxBound];
// Load vertices
for(U32 i=0; i<vertBound; i++)
{
verts[i][0] = cpl.mVertexList[i].x;
verts[i][1] = cpl.mVertexList[i].y;
verts[i][2] = cpl.mVertexList[i].z;
verts[i][3] = 0;
}
int idxCount=0;
int skipCount=0;
// Load indices
for(U32 i = 0; i<cpl.mPolyList.size(); i++)
{
if(cpl.mPolyList[i].vertexCount > 3)
{
Con::warnf("Skipping an %d-gon on an object @ %x(%s)!",
cpl.mPolyList[i].vertexCount,
cpl.mPolyList[i].object,
cpl.mPolyList[i].object->getClassName()
);
skipCount++;
continue;
}
for( U32 j=cpl.mPolyList[i].vertexCount+cpl.mPolyList[i].vertexStart;
j>cpl.mPolyList[i].vertexStart;
j-- )
idx[idxCount++] = cpl.mIndexList[j];
}
Con::printf("Set up world collision info, %d vertices and %d polygons.", vertBound, cpl.mPolyList.size());
dGeomTriMeshDataBuild(
mWorldTriangles,
verts, sizeof(dVector3), vertBound,
idx, idxCount/3, 3*sizeof(int)
);
#7
If you get your ODE stuff bouncing off world polies, I'll have incentive to clean this up, get it splitting polygons, and so on... ;)
11/30/2003 (12:40 pm)
You can easily get it to split n-gons into triangles; you'd need to add a little abstraction around the buffer builder. It helps that all n-gons returned through that PolyList stuff are planar.If you get your ODE stuff bouncing off world polies, I'll have incentive to clean this up, get it splitting polygons, and so on... ;)
#8
Is it some sort of pointer to the objects? (ie terrain etc)..
11/30/2003 (8:09 pm)
Wow! Thanks, ill try and add that in, see if i cant get it working. What is p (in p->getContainer()->buildPolyList)?Is it some sort of pointer to the objects? (ie terrain etc)..
#9
11/30/2003 (9:06 pm)
It's the pointer to the player for which I'm getting the collision info (ragdoll again)... Do tell me if you get trimesh collision working, it's been eluding me.
#10
Ive noticed that with spheres, they will collide, then roll, and when they get to the edge of the triangle (as seen with F9) they fall through, sometimes they bounce around a lot, then fly off. I cant tell you why though, I think it has something to do with the buildPolyList, or maybe the triangles are too big for trimesh? Im not getting any warnings in the console saying that it skipped any of them.
Thanks all the same, ill try and get this working more tomorrow.
12/01/2003 (2:42 am)
Ok.. so it sort of works... Seems there isnt a collision algorithm for the cappedcylinder with trimeshes yet, but boxes and spheres _sometimes_ collide with the terrain (ie, some triangle act like they donte exist, while others do), however, when they do collide, they collide consistently. Ive noticed that with spheres, they will collide, then roll, and when they get to the edge of the triangle (as seen with F9) they fall through, sometimes they bounce around a lot, then fly off. I cant tell you why though, I think it has something to do with the buildPolyList, or maybe the triangles are too big for trimesh? Im not getting any warnings in the console saying that it skipped any of them.
Thanks all the same, ill try and get this working more tomorrow.
#11
12/01/2003 (5:24 am)
BuildPolyList() doesn't always return *all* the polys in a mesh/terrainblock/interior/etc. In most cases it only returns the "forward" facing polys.
#12
Would it have anything to do with the Convex class?
EDIT..
Hmm, I just added this
Basically, (I think) it creates a convex and calls TerrainBlock::buildConvex to fill the convex structure up with all the points and whatnot, then it loops through the working list, filling up the polyList with the polys. Then it goes and does Bens code.
Cept it doesnt work.
the console printout says theres like 13000 verticies being added, (and there is a pause in the load), but objects wont collide with them :(
Just thought id let you know.
12/01/2003 (6:03 am)
Oh, ok, that would probably explain it. So how would I get all of the polys? I can feel that it is <-This-> close. :DWould it have anything to do with the Convex class?
EDIT..
Hmm, I just added this
ConcretePolyList cpl;
TerrainConvex* convex = new TerrainConvex;
buildConvex(worldBox,convex);
TerrainConvex* temp = convex;
CollisionWorkingList& wl = convex->getWorkingList();
for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext){
temp = static_cast<TerrainConvex*>(itr->mConvex);
temp->getPolyList(&cpl);
} Basically, (I think) it creates a convex and calls TerrainBlock::buildConvex to fill the convex structure up with all the points and whatnot, then it loops through the working list, filling up the polyList with the polys. Then it goes and does Bens code.
Cept it doesnt work.
the console printout says theres like 13000 verticies being added, (and there is a pause in the load), but objects wont collide with them :(
Just thought id let you know.
#13
I have a similar problem to yours, Dylan, except I don't seem to ever get collision. :)
12/01/2003 (8:10 am)
I'm not sure that's right, Matthew... If the normal isn't set I'm pretty sure you get all the polys.I have a similar problem to yours, Dylan, except I don't seem to ever get collision. :)
#14
Bah, Ill try again tomorrow.
12/01/2003 (8:33 am)
That code I posted wasnt working at all, so i removed it and replaced it with Bens code, now it is sorta working again :S It just seems like random terrain triangles are missing... But on the whole, it works ok.Bah, Ill try again tomorrow.
#15
Ah well, I guess thats it for the adventures of Torque, ODE and Dylan, until someone can figure out how to add world collisions.
Ill post the code I have as a resource, but its not very useful...
12/02/2003 (8:19 am)
I set it to render the PolyList generated from buildPolyList, and it is just a flat plane of triangles (even if the terrain is not flat). I then rendered the list that I got out from the trimesh in ODE and its the same as the ConcretePolyList. So I can say that i have no idea what is going on besides the fact that buildPolyList doesnt seem to be doing what it should be, and I dont know enough about this part of Torque to fix it, but the Trimesh seems to be getting made properly.Ah well, I guess thats it for the adventures of Torque, ODE and Dylan, until someone can figure out how to add world collisions.
Ill post the code I have as a resource, but its not very useful...
#17
12/02/2003 (10:22 am)
Hey Dylan, just drop it my way... I'll take a look at it, and if I can get Trimeshes working, I'll release a resource for it. No sense releasing something that doesn't work... :)
#18
1) a bug/problem: www.garagegames.com/mg/forums/result.thread.php?qt=8510
2) when a concretePolyList is filled with the TerrainBlock polys, the transform of the extracted polys (in the volume of the specified box) == the transform of the polyList is replaced with that of the terrain, which has a negative position (e.g. x/y: -1024/-1024), so the polys are rendered not on top and at the position of the TerrainBlock. This makes it look like the data is not correct. So, Dylan, I think the polys that you extracted might have been correct, they were just rendered at the wrong position. The buildPolyList method seems to way to go to get all the terrain polys (quite a huge number, though, if you get the whole data set).
03/24/2004 (4:02 pm)
Some things I noticed:1) a bug/problem: www.garagegames.com/mg/forums/result.thread.php?qt=8510
2) when a concretePolyList is filled with the TerrainBlock polys, the transform of the extracted polys (in the volume of the specified box) == the transform of the polyList is replaced with that of the terrain, which has a negative position (e.g. x/y: -1024/-1024), so the polys are rendered not on top and at the position of the TerrainBlock. This makes it look like the data is not correct. So, Dylan, I think the polys that you extracted might have been correct, they were just rendered at the wrong position. The buildPolyList method seems to way to go to get all the terrain polys (quite a huge number, though, if you get the whole data set).
Torque 3D Owner Stefan Rampp
//look for the TerrainBlock called "Terrain" here TerrainBlock *terrain = dynamic_cast<TerrainBlock*>(Sim::findObject("Terrain")); if(!terrain) { Con::printf("Terrain not found!"); return; } Box3F b = terrain->getBoundingBox(); ConcretePolyList list; //... or whatever PolyList you need terrain->buildPolyList(list, b, SphereF()); //fill the PolyListI haven't tried exactly this snippet, but I hoe it helps anyway.
Stefan.
Edit: typos.