In my scene, the walls and the floor are part of the same spatial loaded from a model file, and have a MeshCollisionShape attached to deal with physics, and the character spatial uses a BetterCharacterControl.
My issue is that later in my game I intend to implement the ability for the player to press against walls and other scenery. The only constraint is that the surface the player collides with must be vertical. How do I tell the difference between the player’s near constant collision with the floor and a wall when they are part of the same mesh?
OR is it a better idea to make the walls and floor separate meshes with their own collision objects?
In response to collision normal: for a BetterCharacterControl, which I’m led to believe is a capsule shape, would the collision normal from a collision with a vertical wall be completely horizontal all the time?
And I was going to go with separate meshes but I’m going to look into collision normals and see what I can do.
@leylandski said:
In response to collision normal: for a BetterCharacterControl, which I'm led to believe is a capsule shape, would the collision normal from a collision with a vertical wall be completely horizontal all the time?
And I was going to go with separate meshes but I’m going to look into collision normals and see what I can do.
It should be… unless your walls are not. I would still use a threshold (especially if walls will ever be angled).
Collision normals are very useful, but I’m still not convinced a single object for walls and floors is a good idea. I worry that if the character is simultaneously in contact with a wall and a floor, your app might get only one collision event, which would often be the floor. Worth testing, anyway.
I’m trying to achieve exactly this how to know whether my character hit a wall, stairs or floor. IT’s possible to get the collision normals this way but I don’t know how to proceed.
[java]CollisionResults results2 = new CollisionResults();
getGameLevel().collideWith((BoundingBox) ninjaNode.getWorldBound(),
results2);
for (int i = 0; i < results2.size(); i++) {
float dist = results2.getCollision(i).getDistance();
Vector3f pt = results2.getCollision(i).getContactPoint();
String party = results2.getCollision(i).getGeometry().getName();
int tri = results2.getCollision(i).getTriangleIndex();
Vector3f norm = results2.getCollision(i).getTriangle(new Triangle()).getNormal();
System.out.println(" The hit triangle #" + tri + " has a normal vector of " + norm);
}[/java]
The normal vectors that are written out appear arbitrary and I can’t see how to test whether it’s a floor, a stair or a wall even when I get the normals.
The normal vector of a floor is likely to point upward (0, +1, 0). The normal vector of wall is likely to point in the horizontal plane (x, 0, z). Stairs would include both sorts of normals.
The normal vector of a ceiling would likely point downward (0, -1, 0).
…thus the y-value of the normal vector tells you everything you want to know, as per sgold’s answer.
You still might want to tag your geometry in some way that you can find out what it is just in case you ever want to treat one type of floor differently than another or one wall (door versus wall) differently. There are a couple ways to do that: user data, or controls.