need some explanation

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
sueds
Posts: 43
Joined: Tue Feb 05, 2008 10:40 am

need some explanation

Post by sueds »

hello,

I'm having some problem understanding collision filter. I'm trying to make a camera collision a ray start from the character to the camera ( where I want to set a box) but I don't know how to make the ray reacting both with the camera and the level but allow the camera to go though walls. Do i need to use non collidable entities ?

I'm making a third person camera but my problem is that I don't know how to set it up. Because I want some interaction with crate and level but I need to be sure there is something under his feet to allow it to jump. So I was thinking using a capsule and a ray below the capsule but will collide with wall ? I wonder if the capsule is non physically simulated I could use it to go through wall and hit box and physic elements ? there are just few question I haven't time to try it since I'm wrestling to get ragdoll working !

anyway I'm going to try out few solution but I really need to understand differences between filter and way to enable or disable collision between certain objects.

cheers
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: need some explanation

Post by Norbo »

Generally speaking, the collision filters can be thought of as a set of groups- in this case, 64 of them. Each entity can belong to any number of these groups, and if two entities come into contact and any of their groups match, they can collide. By default, the collision filter is set to the maximum value for an unsigned 64 bit integer, in other words, 64 1's. This means it belongs to every collision group and will collide with any entity that is part of any collision group. The Entity.setCollisionFilter method can be used to set individual bits in the filter without having to bother with the powers of 2 conversion. By setting an individual bit to off in the filter, you remove that entity from that group, possibly preventing collisions between that entity and another which doesn't match any of its enabled collision groups. You can quickly remove an entity from all collision groups by setting its filter to 0, which corresponds to all bits being disabled. The operation used for determining if two collision filters 'match' is a simple bitwise AND, syntactically & in C#.

The nonCollidableEntities field can be used for pairwise intangibility so that you don't need to mess with the collision filters if it's only two objects that you want to be intangible to each toher, like an upper and lower leg. Once you've added an entity to another entity's nonCollidableEntities list, they will no longer interact (note that you don't need to do it both ways, one entity having the other in its nonCollidableEntities list will prevent the collision, but having it in both doesn't cause any harm).

In terms of using this to your advantage during raycasting (such as only testing against a certain collision filter during a ray cast) you can collect all of the entities that your ray hits, and then check each one to see if it matches your collision filter or other requirement.

If you choose to use nondynamic objects, they will happily scoot through other objects and walls regardless of their collision filters. Nondynamic objects do not undergo collision response impulses, so it will be up to the objects they hit to decide how to react based on collision filters and such. Two nondynamic objects 'colliding' with each other will not register any collision response either.

Also, instead of space.rayCast, you can call raycast on individual objects or groups of objects (the broadphase or individual StaticTriangleGroups, for example). This might be a useful shortcut for avoiding ray hits that you don't need or want.

For an example chase-cam, you can check out the modifications made in v0.5 in the Camera class. The vehicle camera is third person and follows the vehicle, and it will get closer if something obstructs the view via a raycast. I didn't give it any sort of margin, so it sometimes looks like you can see through the ground because of nearclipping (you are basically perfectly aligned with the triangle, so you can see above and below it), but that's easy enough to change. It also wouldn't be too hard to rework it so that it doesn't get blocked by certain collision filters, or by specific entities. I believe I already ignore the car's compound body in such a manner.




There's also something a little nitpicky that you might notice; setting an entity's isTangible field to false doesn't prevent the formation of controllers, it only prevents its collision response. In this way, you can use an intangible entity to detect things by checking its controller list. Pairwise intangibility and collision filters, on the other hand, work by preventing the formation of controllers. In this way, perhaps it would be better to refer to "isTangible = false" as "isCollisionlessDetector = true" or something along those lines.
sueds
Posts: 43
Joined: Tue Feb 05, 2008 10:40 am

Re: need some explanation

Post by sueds »

you confuse me again ! I'm going to check the vehicle.
I would like to know in your opinion what would be the best choice fr a tps camera? I try to find paper about how to build a character class but I didn't find any. My main problem is how to check the landscape ( stair for example) and colliding with other object with a smooth movement. ( maybe it's sound confusing).

I check the character code and it's seems that you are using xna frameworks ray ? Does bepu can interact with xna framework collision system ? How can I check all the entities with a single ray using the toolbox ?
what is the use of raycastable container ?


cheers
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: need some explanation

Post by Norbo »

For a third person camera, I find putting a ray origin at the character's 'head' and casting backwards along some direction modified by the mouse to be a good solution. This is what is used for the vehicle's camera. From the raycast you can get the distance along the ray to the impact site (if any). The camera is then placed at the character's head plus the direction of the ray times this distance, with any margins added in that you'd like.

(Quick terminology note: When I say "time of impact," I mean the distance along a raycast or swept collision detection to the hit point. This distance is generally in units of the ray's length. For swept collision detection, this will be between 0 and 1. Past that, no collision is returned.)

Character controllers are a fairly wide topic. Generally speaking, you have a character that is 'supported' by something. For a dynamic character this support is physical impulses, for a nondynamic character it operates on a position/velocity level. You can use a ray to detect supports below the object, or use the swept collision test (one of the Toolbox.areObjectsColliding overrides) with a whole entity shape.

For purposes of minimizing the number of entities that I check for support, I create a detector entity encompassing the support ray/convex cast- this is simply a dynamic entity whose isTangible flag has been set to false and is unaffected by gravity. It is moved to the correct position and has its momentum managed so that it either follows the object its 'attached' to (the character or vehicle) or so that it is zero. This keeps strange things from happening when the intangible shape gets pushed by something like an Explosion, or other force that doesn't care that it is intangible.

For a dynamic controller, movement and such is all done through impulses. A nondynamic based controller will be a little more hacky (yet probably simpler math-wise), but you will have absolute control over the type of movement it can undergo. For these, one possible method is naively pushing your character along your desired movement direction and then performing collision detection on its surroundings (you could use the broadphase's getEntities(BoundingBox) method to gather up the candidates and the areObjectsColliding methods to test). Based on the tests, you would then shove the character back into a valid nonintersecting state.

This blind shove forward can work fine in many instances. However, it has its share of problems; if a player pushes their way into an acute angled corner, they could get stuck without doing a little extra work to push the character back appropriately. You might also miss collisions entirely if your character is moving at 500 meters per second. A nice solution to these problems is to just use the swept collision detection method mentioned earlier (a Toolbox.areObjectsColliding override). Using the character's movement as the sweep direction (and the opposing object's velocity as its sweep direction if you wanted to get fancy), you can find the earliest time of impact from the candidates. The character's final position for that frame would be its original position plus the velocity times this earliest time of impact.

If you resort to the blind method, there is a small issue you'll have to deal with in addition to those inherent to the concept. I have forgotten to add in a getPenetrationDepth-style function to toolbox, despite using such functionality extensively in collision detection. This will be in v0.6.0. So, instead of getting a nice penetration vector, you will have to use an alternate method. One such method is to check if the character is in collision with something at the end of its velocity- if it is, check if it would be at half that distance along the velocity, if it is, check at 1/4th along the velocity, if it isn't, check the midpoint of 1/4 and 1/2, and so on. This bisection technique will work with purely boolean collision detection methods to find the time of impact. This, conveniently, will also take care of the 'angled corner' problem. There are some robustness issues due to floating point you might encounter, but overall it is workable with some tweaks. This isn't the only available method either; if you need more information about these sort of techniques, just let me know.

I use the Ray for storage purposes; its just a convenience, as it stores the necessary values. Some methods do use Bounding shapes from the XNA framework and other assorted things, so yes, there is some amount of interaction.

You can use the space's broadphase's raycast method to find all entity-ray intersections. If you want to include all raycastable containers (which is an interface simply implemented by other types of object which can be ray casted against, like the StaticTriangleGroup), you can either cycle through them manually or just use space.rayCast to test everything (including entities) at once.
Post Reply