Page 1 of 1

Advanced collision detection

Posted: Tue Apr 26, 2005 8:38 pm
by gaber

First I would like to say that this forum is great.

I have read anything that is to read about collision detection in this forum and I implemented collision detection between camera and objects sucesfully by using OgreODE library (sphere around camera and collision listener).

But now I have one slighly more difficult problem. Currently I only detect collisions between camera and simple objects, that already have defined geometry class (e.g. OgreODE::SphereGeometry, OgreODE::BoxGeometry, ...).
Now I want to detect collision between camera and mesh object, that looks like house (a room), that has a open door. Obviously I cannot apply OgreODE::BoxGeometry here, because I won't be able to enter through the door.

I see two possible ways for solution:
- create room from different walls, that all have geometry OgreODE::BoxGeometry and seek collisions. This is not good approach because it is not generic. Also for each new entity procedure should be repeated.

- create custom geometry by using OgreODE::TriangleMeshGeometry class. As I understand this class receives all triangles of mesh and it constructs geometry for it. When I will look for collisions in collision() method i can use same approach as before (AM I RIGHT?)? I would like to implement collisions with my room using this approach.

Now questions:
- how must be OgreODE::TriangleMeshGeometry used (Example)
- how can I get triangles, that are needed in constructor from entity (mesh)
- is there some better approach for this

Thanks a lot!


Posted: Tue Apr 26, 2005 8:41 pm
by jacmoe
All your questions (well, most of them I reckon) will be answered by you browsing the source code of the demos in OgreODE from ogreaddons. :)

monster has left that project to work on its successor - so don't expect a whole lot of support. :wink:

Posted: Tue Apr 26, 2005 8:42 pm
by Lucky_Luciano
You should look into OgreOpcode (I think it's part of OgreODE), this features per-polygon collision detection. Though, if you can, you should consider dividing your house into several "collision boxes" anyway. Per-polygon collision detection is slow, to say at the least...and might not be necessary for you.

Posted: Wed Apr 27, 2005 10:35 am
by gaber
Examples in OgreODE don't provide any information about TriangleMeshGeometry usage. There is only one reference in one example but realy no useful implementation.

This house collision detection is only a part of functionality that I need. I also need to detect collision for mesh objects that represent sand dunes and that have completely irregular shape. I looked at bezier patch demo because I might be able to decrease number of triangles with it. But again this example doesn't provide enough information for such solution.

Function createBezierPatch() returns object of type PatchMesh and maybe I should be able to get polygon list from list and even decrease it. This would off course mean that implementation of collision with triangles wouldn't be so consuming (slow) because there would be only approximation of mesh with less triangles. Is this possible?

Posted: Wed Apr 27, 2005 11:03 am
by gaber
Other possibility for finding collision between ball object and mesh object might be using IntersectionSceneQuery. When I attach camera a sphere geometry I also attach entity ball to it to have visual representation of my position if I use other camera node. So I could set query masks to only look for intersections between these movable objects but the problem is the following:

Code: Select all

IntersectionSceneQuery *intersectionQuery = mSceneMgr->createInterfaceQuery();
intersectionQuery->setQueryMask(MASK1 | MASK2);
IntersectionSceneQueryResult& queryResult = intersectionQuery->execute();
SceneQueryMovableIntersectionList intersectionList = queryResult.movables2movables;
std::list <SceneQueryMovableObjectsPair>::iterator it = intersectionList.begin();

while (it != intersectionList.end()) {
  MovableObject mo1 = it->first();
  MovableObject mo2 = it->second();

  //how should i find out now how much must increase y coordinate of camera node??

Posted: Wed Apr 27, 2005 11:10 am
by monster
Examples in OgreODE don't provide any information about TriangleMeshGeometry usage. There is only one reference in one example but realy no useful implementation.
Define "useful implementation". It creates a triangle mesh that things collide with. What are you expecting?

Posted: Wed Apr 27, 2005 11:13 am
by Craig
What about simply using an ODE object to detect the collision, and just ignore it. Then do whatever you want to do when the camera hits the door ?

Posted: Wed Apr 27, 2005 5:29 pm
by jacmoe
A simple and effective way of doing fast and efficient collision detection is the use of collison meshes - i.e. a simplified low polygon version of your level.

Posted: Thu Apr 28, 2005 4:48 pm
by gaber
I understand how it should be used but since I am workin with ogre I don't know how to do the following:
- get vertex points from mesh (i.e. custom dune mesh)
- get groups of 3 vertexes that create triangle for all mesh (all triangles)
- insert data into TriangleMeshGeometry

This off course applies if I am thinking correctly about how to do this.

What I meant with useful implementation is example of such case. But in fact in demos section of OgreODE there is only one reference to TriangleMeshGeometry that receives only one parameter space in constructor (I don't remember exactly because I am on different computer now) and this geometry is used for road.

Can you say something more about collision meshes. Do you mean by this that I should approximate my mesh with fewer vertexes. If so can you tell me how to get triangles from mesh and how to reduce their number. As I mentioned bezier surface should do exactly that but I implemented this only in MatLab till now and I cannot fully understand how could I apply example in Ogre demos to my problem.

If some questions are funny I apoligize because I really didn't work in ogre before and I am some kind of newbie.

Thanks for your replies.

Posted: Thu Apr 28, 2005 4:51 pm
by Kencho
Hmmm... if your problem is about retrieving geometry information from OGRE, then simply take a look to everything HardwareBuffer-related in the OGRE manual and the API documentation. You'll learn many things. Also taking a look to the snippets in the Wiki that refer to retrieving that info or constructing meshes manually will help you a lot.

So take a look first there ;)

Posted: Thu Apr 28, 2005 5:11 pm
by monster
I understand how it should be used but since I am workin with ogre I don't know how to do the following:
- get vertex points from mesh (i.e. custom dune mesh)
- get groups of 3 vertexes that create triangle for all mesh (all triangles)
- insert data into TriangleMeshGeometry

All this is taken care of for you by the entity informer.

In the trimesh simple scene the code that does it is;

Code: Select all

// Turn it into a triangle mesh static geometry
OgreOde::EntityInformer ei(entity,node->_getFullTransform());
The "push_back" business is just there to keep track of the geometry so the scene can delete it later, you don't have to worry about that.

Or in the racing car demo it's done here;

Code: Select all

OgreOde::EntityInformer ei(track_mesh);
_track = ei.createStaticTriangleMesh(_world->getDefaultSpace());
Once again the entity informer deals with all the vertex and index buffer stuff, so you don't have to worry about it. It feeds the vertex data to the TriangleMeshGeometry for you.

If you need more control then look at the source for that member function all it does is;

Code: Select all

TriangleMeshGeometry* EntityInformer::createStaticTriangleMesh(Space* space)
	assert(_vertex_count && (_index_count >= 6) && "Mesh must have some vertices and at least 6 indices (2 triangles)");

	return new TriangleMeshGeometry(_vertices,(int)_vertex_count,_indices,(int)_index_count,space);
Where those parameters are defined as;

Code: Select all

Vector3*	_vertices;
int*		_indices;
size_t		_vertex_count;
size_t		_index_count;
And are filled in by the EntityInformer when it's constructed. If you don't want to base your mesh on an entity then just do the same but create yout vertices, indices, etc, manually.


Posted: Thu Apr 28, 2005 11:04 pm
by jacmoe
gaber wrote:Do you mean by this that I should approximate my mesh with fewer vertexes.
Exactly! :)
A good way of doing it is to manually create a collision mesh from your level mesh.

Posted: Fri Apr 29, 2005 12:33 pm
by gaber

It works great :)
I guess that example realy describes how this should be made but it was so simple (few lines of code), that I didn't belive that so little is necessary to implement this feature. OgreOde is really cool. So currently my implementation supports custom object collisions with use of TriangleMeshGeometry.

Thanks but currently I really don't have performance issues with this so it works fast even if I didn't reduce polygon count. Off course when I will add greater number of entities this might change, but currently I use whole mesh plain.

I have only one more question:

I attached sphere geom to camera node when I move around. For visual representation also one ball entity is attached to it. But problem is that I don't have any body so gravity doesn't work. When I get to top of dune mesh and hit forward button I am walking in air. I removed body because someone said in forum that this must be done to move camera node with geometry around.
But if I attach body to geometry then I cannot move my camera node (it is stuck).

If I am thinking logicaly maybe this is because of friction. Maybe I should apply forces? Can I somehow enable that my camera node with geometry and possible entity will not walk in air (will be gravity enabled) and will also be able to move around at the same time.

Posted: Fri Apr 29, 2005 1:13 pm
by Kencho
I guess that it's not a problem of friction, but a problem of dynamics enabled. Haven't looked deeply into OgreOde, but in the ReferenceAppLayer the approach is to disable dynamics for the camera, and move it manually. When you collide, you're returned a vector with the furthest penetration between the bodies/geometries (I don't know which is exactly), and you just displace the camera in the opposite (substract the penetration vector from the camera position)

Just some ideas ;)