Collsion impact force and more :)

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Collsion impact force and more :)

Post by Danthekilla »

Hey Norbo, I am currently adding in some more collision sounds and particle spats based on impact speed between objects. Since I am doing this I thought that I should fix up my system for calculating collision forces... As it was bad and very inaccurate.

My current system uses this code to approximate the collision force.

Code: Select all

        
private void GenerateCollisionData(ref int in_Count, ref float in_Strength, ref Vector3 in_Norm, ref Vector3 in_Pos)
        {
            in_Count = 0;
            in_Strength = 0;
            in_Norm = Vector3.Zero;
            in_Pos = Vector3.Zero;

            for (int i = 0; i < Bodys[0].collisionPairs.Count; i++)
            {
                LastKnownFriction = Bodys[0].collisionPairs[i].dynamicFriction;
                for (int j = 0; j < Bodys[0].collisionPairs[i].contacts.Count; j++)
                {
                    if (Bodys[0].collisionPairs[i].colliderA.mass == Bodys[0].mass)
                        in_Norm -= Bodys[0].collisionPairs[i].contacts[j].normal;
                    else
                        in_Norm += Bodys[0].collisionPairs[i].contacts[j].normal;

                        in_Strength += Bodys[0].collisionPairs[i].contacts[j].penetrationDepth;
                        in_Pos += Bodys[0].collisionPairs[i].contacts[j].position;
                    in_Count++;
                }
            }

            if (in_Count <= 0) return;

            in_Norm /= in_Count;
            in_Strength /= in_Count;
            in_Pos /= in_Count;
        }
This has many issues such as.
1, too slow to run on 100's of objects per frame
2, there is up too a 100ms delay between hitting something and this detecting it
3, horribly inaccurate
4, sometimes doesn’t work at all

I need a system where i can get the collision force (mass * speed) of 2 colliding objects immediately and accurately while still being fast enough to run every frame on 50+ objects, I imagine that i could get the direction of the 2 traveling objects and work out a difference of direction and somehow multiple that with their speeds..? So that if they were going in the same direction and tapped into each other it would return a very diff result to going in opposite directions and colliding.

Also i need to remove part of a static tri mesh during runtime... is this possible or should i convert all those objects to convex hulls and remove them like that? (Or would multiple static tri meshes be faster?)

How you can shed some light on this Norbo :)

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

Re: Collsion impact force and more :)

Post by Norbo »

I need a system where i can get the collision force of 2 colliding objects immediately and accurately while still being fast enough to run every frame on 50+ objects
Fortunately, the engine calculates this and makes it available in each contact's penetrationConstraint's normalForce property.
To efficiently access this, you could add a listener to the entity's EventHandlerContactCreatedImmediate or EventHandlerContactCreated type events (entity.eventManager.addEventHook). The difference is that the Immediate version will be called while the engine is running in a multithreaded context (and would require locking to access shared resources), and provide you an actual Contact object to look at. The deferred event EventHandlerContactCreated will give you the basic data of the contact (not its normalForce directly) and its collision pair, and will execute from a safer single threaded context after the engine is finished working. You can still retrieve the normalForce indirectly by looking at the provided collisionPair and looking at the contacts in its contact list.

If you only want to be notified about the initial impact, you can use the EventHandlerInitialCollisionDetected(Immediate) event. You can search the provided CollisionPair for contact data like above. If there's more than one contact, you can just add the normalForce from each contact together.

If you want to implement a 'rolling' noise or other sustained contact noise, you can use the EventHandlerCollisionPairColliding(Immediate) type. This is called every time the collision pair is updated and it has at least one contact point. You can search the provided collision pair to determine contact data like above.
Also i need to remove part of a static tri mesh during runtime... is this possible or should i convert all those objects to convex hulls and remove them like that? (Or would multiple static tri meshes be faster?)
It depends; having 1-5(?) StaticTriangleGroups would probably be fine. Going over that might start pointlessly eating time on the Xbox, though the best way to know would be to test it. Adding/removing a single entity can be cheaper than adding/removing a whole StaticTriangleGroup as well (if there are things that are in danger of colliding with it at the time of addition/removal).

If there are more than a few such things, and if they are convex anyway, I would probably recommend going with ConvexHulls. Otherwise, StaticTriangleGroups will probably be fine.

(And once again, the collision system rewrite that makes the StaticTriangleGroup into a first class broadphase citizen will alleviate pretty much all of its corner case issues like this one :))
Post Reply