Is there a ConcaveCollision?...

chcampb

19-06-2008 00:59:18

If i were to need a collision primitive that represented a hollow object, with a character standing on the inside of the object... for example, a hallway (:p) what would be the best way of achieving this?
My first attempt used CollisionPrimatives::ConvexHull, passing each main SceneNode in a list of modules, but this generates basically a cube for a hallway, and walking on the outside ceiling is not as much fun :(
I took a screenshot!
[/url]
The ConvexHull (since it's convex :D) wraps around the outside set of vertices, and leaves me without a collidable floor. The best way i can think to get around this and not do it by hand is to break the floor into a sub-entity floor and walls, then make a convexhull out of those... but that doesn't seem like an efficient way of doing things.

Really, all I need to know is the point at which a ray emitted from the character along the negative y axis passes through a polygon - any polygon - and i can work with it. It just seems like everything i try needs to use a custom feature (convexhulls here) and that isn't really what i need :(

chcampb

19-06-2008 06:26:58

There are a few other questions that I would need to know before breaking the mesh apart to use SubEntities... I have written a portion of code that illustrates what I'd like to do -
void BuildableObject::loadCollisionHull()
{
unsigned int i = 0;
unsigned int j = 0;
SceneNode *tempSceneNodePtr;
SceneNode *tempSubEntitySNPtr;
Entity *tempEntityPtr;
SubEntity *tempSubEntityPtr;
vector< OgreNewt::Collision* > tempConvexHullVector;
OgreNewt::Collision *tempCollisionPtr;
OgreNewt::Body *tempBodyPtr;

// we need to create a vector of ConvexHull collisions, then pass that vector to
// CollisionPrimitives::CompoundCollision, then create a body, then delete the vector
// of temporary collisions and start over
for(i=0; i < buildableObjModList.size(); ++i)
{
//
tempSceneNodePtr = buildableObjModList[i]->getSceneNode();
tempEntityPtr = static_cast<Entity*>(tempSceneNodePtr->getAttachedObject(0));

for(j=0; j < tempEntityPtr->getNumSubEntities(); ++j)
{
tempSubEntitySNPtr = sceneManagerPtr->getRootSceneNode()->createChildSceneNode("tempSN");
tempSubEntityPtr = tempEntityPtr->getSubEntity(j);
tempSubEntitySNPtr->attachObject(static_cast<Entity*>(tempSubEntityPtr));
tempCollisionPtr = new OgreNewt::CollisionPrimitives::ConvexHull(worldPtr,
tempSubEntitySNPtr,
tempSceneNodePtr->getOrientation(),
tempSceneNodePtr->getPosition());

tempConvexHullVector.push_back(tempCollisionPtr);
tempSubEntitySNPtr->removeAndDestroyAllChildren();
}

// create a ConvexHull out of the entity attached to the SceneNode of the module
tempCollisionPtr = new OgreNewt::CollisionPrimitives::CompoundCollision(worldPtr, tempConvexHullVector);
// create a Body that uses that ConvexHull
tempBodyPtr = new OgreNewt::Body(worldPtr, tempCollisionPtr);

// add the address of that body to our array of pointers to that body
collisionHullBodyList.push_back(tempBodyPtr);

// delete the vector of temporary ConvexHull objects
for(i=0; i < tempConvexHullVector.size(); ++i)
{
delete tempConvexHullVector[i];
}
}
}

But there are a few problems with this. First of all, I need a way to pass the SubEntity to the ConvexHull constructor - but the ConvexHull constructor only takes a SceneNode and immediately gets the first entity. Turns out you can't attach SubEntity objects to SceneNode objects, so the only other route would be to get the vertex data(?) and pass that. I'm completely in unknown territory here :'(
Second, once i get the actual code working, how does ogre split the Entity as it loads into SubEntitiy objects and SubMesh meshes? From what I understand it is either split by material or by connected sections of mesh... which is it?

Vectrex

19-06-2008 11:40:13

for static stuff like a hallway use the tree collider. It's per polygon.
For moving stuff you can use multiple convex/primative collision shapes in a 'compound collision'

chcampb

19-06-2008 15:05:43

it's not static :( it's a hallway that's the interior of, for example, a walk-around-able aircraft carrier or spaceship that will need to move relative to others of its type

[Edit]
As an update, i'm working on rewriting the code at http://www.ogre3d.org/wiki/index.php/RetrieveVertexData to take a submesh and ignore the indices, so that it would just get the cloud of vertices in the submesh - but i'm still not sure how to deal with shared vertices and all that, not to mention i'm still not sure how ogre knows which vertices in a mesh are parts of a submesh :( if i could pass the array of vertices of the submesh to the CollisionPrimitives::ConvexHull constructor, then build a compound collision using the vector of all ConvexHull objects created using the submeshes it should do what i'm expecting.

Also, why can't the trees move? Shouldn't the code that determines which polygons a ray intersects be the same as if you added the position offset for that object? :\

Vectrex

20-06-2008 16:40:30

it's not static :( it's a hallway that's the interior of, for example, a walk-around-able aircraft carrier or spaceship that will need to move relative to others of its type

[Edit]
As an update, i'm working on rewriting the code at http://www.ogre3d.org/wiki/index.php/RetrieveVertexData to take a submesh and ignore the indices, so that it would just get the cloud of vertices in the submesh - but i'm still not sure how to deal with shared vertices and all that, not to mention i'm still not sure how ogre knows which vertices in a mesh are parts of a submesh :( if i could pass the array of vertices of the submesh to the CollisionPrimitives::ConvexHull constructor, then build a compound collision using the vector of all ConvexHull objects created using the submeshes it should do what i'm expecting.

Also, why can't the trees move? Shouldn't the code that determines which polygons a ray intersects be the same as if you added the position offset for that object? :\



hmm, I suggest trying to use compound collisions with simple box primitives. If your scene is made from 'chunks' of geometry eg a wall piece, the floor, a door, when you load your scene you should have no trouble matching up simple boxes or convex hulls and adding them to a single compound collision for your ship.
How well this works I guess would be dependant on the complexity, but I recommend sticking with boxes if you don't need the extra collision detail.
I use OgreMax's .scene format in 3dsmax. So I use the userData properties it has so I can easily tag different objects with that kind of data. Eg whether to use a convex or box etc

walaber

22-06-2008 06:59:52

I realize that you want to have a moving ship with other moving items inside it, but will there ever be a situation in your program where you need to be simulating both simultaneously?

when inside the ship, couldn't you treat the ship as static, and only worry about motion of objects inside? and then when you are moving the ship in space, do you really care how objects are moving around inside?

I ask because what it sounds like you want to do will be very computationally expensive.

Vectrex

22-06-2008 13:15:27

this sounds like a job for the new portal scenemanager.
You could have 2 seperate area's, one moving ship with a portal on the doorways to a static part of the world which is inside the ship.
If you need the objects inside to react as if the ship really was moving you can feed the movement g forces from the moving ship to all the dynamic objects inside the static ship level area