Passing specific entities for narrowphase only
Passing specific entities for narrowphase only
Hello,
I have been working on a game that requires me to be able to go through objects that have spaces inside of them, sort of like a building with a hole in the middle, to achieve this I turned to Bepu, I was able to understand the main concepts of how you create entities out of models (for the complex collision body that the building would require), and also how to add my own handlers to the initialcollisiondetected event. The problem is that I already had implemented a Quadtree of my own to deal with some frustum culling and broadphase collision detection using bounding boxes so I didn't want to use Bepu for that, instead I was wondering if there's a way to pass 2 entities directly for narrow collision detection instead of creating a Space and calling update on every frame, the reason for this is simply because when things collide I am not looking for a real response rather than the "collision happened" information.
Thanks a lot in advance for taking the time to give me a reply, any help is highly appreciated.
I have been working on a game that requires me to be able to go through objects that have spaces inside of them, sort of like a building with a hole in the middle, to achieve this I turned to Bepu, I was able to understand the main concepts of how you create entities out of models (for the complex collision body that the building would require), and also how to add my own handlers to the initialcollisiondetected event. The problem is that I already had implemented a Quadtree of my own to deal with some frustum culling and broadphase collision detection using bounding boxes so I didn't want to use Bepu for that, instead I was wondering if there's a way to pass 2 entities directly for narrow collision detection instead of creating a Space and calling update on every frame, the reason for this is simply because when things collide I am not looking for a real response rather than the "collision happened" information.
Thanks a lot in advance for taking the time to give me a reply, any help is highly appreciated.
Re: Passing specific entities for narrowphase only
Yup!I was wondering if there's a way to pass 2 entities directly for narrow collision detection instead of creating a Space and calling update on every frame, the reason for this is simply because when things collide I am not looking for a real response rather than the "collision happened" information.
A NarrowPhasePair between two collidables can be obtained by calling NarrowPhaseHelper.GetPair(ref overlap). The overlap is the pair of objects involved. The narrow phase helper will look up which type of NarrowPhasePair to create and hand back an instance. For a pair created between any of the standard Collidables, the resulting NarrowPhasePair can be cast to a CollidablePairHandler to get more useful information like the Contacts property. (Note that the overlap is between the entity.CollisionInformation collidables as opposed to the entities themselves; the returned EntityCollidable is the entity's proxy in the collision detection pipeline.)
The NarrowPhasePair has an UpdateCollision method. This will update the state of the pair; for a CollidablePairHandler, the Contacts collection will be updated. If there exists a contact with nonnegative penetration depth, then the pair of objects is in collision. The contact data includes position, normal, depth, relative velocity and collision response impulses (unused if the pair's constraint isn't in a solver).
When a pair becomes irrelevant, its CleanUp method should be called and it should be given back to the factory that spawned it:
Code: Select all
pair.CleanUp();
pair.Factory.GiveBack(pair);
By the way, if you have immobile object like an environment mesh, it's best to use a StaticMesh rather than an Entity with a MobileMeshShape. This doesn't affect the above process much- the StaticMesh is itself a Collidable, so rather than putting the entity.CollisionInformation into the overlap, just put the StaticMesh instance itself into the overlap.I have been working on a game that requires me to be able to go through objects that have spaces inside of them, sort of like a building with a hole in the middle, to achieve this I turned to Bepu, I was able to understand the main concepts of how you create entities out of models (for the complex collision body that the building would require)
Re: Passing specific entities for narrowphase only
The NarrowPhase itself could also be modified slightly to do the management for you. The default implementation does more work than you need since it expects the existence of a collision solver, but a lot of it would carry over. At its core, it takes a list of overlaps and uses them to maintain a set of pairs.
Re: Passing specific entities for narrowphase only
wow thanks for the amazing and fast reply, I will be using static meshes then for my buildings and convex hulls for my main objects that are flying thought the static meshes, this now makes a lot more sense to me, an even though the process might be doing some extra overhead I don't feel it will be a problem since the calls done to this will be minimal, like 3 or 4 per tick (only checking against the main player).
Thanks again for the great support, I admire this engine and I hope to learn more about it to use it fully in the future (right now I am tied to deadlines).
Thanks again for the great support, I admire this engine and I hope to learn more about it to use it fully in the future (right now I am tied to deadlines).
Re: Passing specific entities for narrowphase only
Hey again, I stumbled upon another issue...
I ended up using MobileMeshShapes since my buildings are actually moving (such as asteroids or abandon space stations), so for every entity I make, I remove all events and then add my own handler to the "InitialCollisionDetected" which links an static function that changes a flag to true. I am extracting the EntityCollidables from the entities and creating an overlap from those, getting a NarrowPhasePair, calling update on it, passing my elapsed time in seconds (0.0166667 since my game is locked at 60 fps), cleaning it up, and then returning it to the factory, the thing is that is not calling the event even though it is obvious the collision has happened, I even tried changing the shape to box shapes with ridiculous sizes to see if was because of the vert and index data but it was not the case... the event was not being call still, in code it looks like this:
any help would be highly appreciated, thanks in advance.
I ended up using MobileMeshShapes since my buildings are actually moving (such as asteroids or abandon space stations), so for every entity I make, I remove all events and then add my own handler to the "InitialCollisionDetected" which links an static function that changes a flag to true. I am extracting the EntityCollidables from the entities and creating an overlap from those, getting a NarrowPhasePair, calling update on it, passing my elapsed time in seconds (0.0166667 since my game is locked at 60 fps), cleaning it up, and then returning it to the factory, the thing is that is not calling the event even though it is obvious the collision has happened, I even tried changing the shape to box shapes with ridiculous sizes to see if was because of the vert and index data but it was not the case... the event was not being call still, in code it looks like this:
Code: Select all
//First extract the entity collidables from the Entities
EntityCollidable A;
EntityCollidable B;
OwnerCollision.UpdateBepuBody(OwnerSpace.World, out A); // updates the World transform of the entity
TargetCollision.UpdateBepuBody(TargetSpace.World, out B);
CheckNarrowPhase(A, B); //finally check for collision in the narrow phase.
public void UpdateBepuBody(Matrix transform, out EntityCollidable Result)
{
if (m_BepuBody != null)
{
m_BepuBody.WorldTransform = transform;
Result = m_BepuBody.CollisionInformation;
return;
}
Result = null;
}
public void CheckNarrowPhase(EntityCollidable A, EntityCollidable B)
{
A.Events.InitialCollisionDetected += HandleCollision;
B.Events.InitialCollisionDetected += HandleCollision;
NarrowPhasePair Pair = NarrowPhaseHelper.GetPair(A, B);
Pair.UpdateCollision(Global.ElapsedSeconds);
Pair.CleanUp();
Pair.Factory.GiveBack(Pair);
}
public static void HandleCollision(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
{
CollisionHappened = true;
}
any help would be highly appreciated, thanks in advance.
Re: Passing specific entities for narrowphase only
Oops, I should have clarified- the deferred events (collision events with past tense names) can only occur in the presence of a deferred event dispatcher. This typically requires the regular space architecture supporting the pair.
Immediate events (collision events with present tense names) are called directly from the context of the pair update. No supporting systems are required. More information about the distinction between deferred and immediate events can be found here: http://bepuphysics.codeplex.com/wikipag ... umentation
It may be more convenient to just look at the contacts list on the pair, as well.
Immediate events (collision events with present tense names) are called directly from the context of the pair update. No supporting systems are required. More information about the distinction between deferred and immediate events can be found here: http://bepuphysics.codeplex.com/wikipag ... umentation
It may be more convenient to just look at the contacts list on the pair, as well.
Re: Passing specific entities for narrowphase only
Hey Thanks a lot again!
I changed the event handler from "InitialCollisionDetected" to "DetectingInitialCollision" and that did trigger!
Now question, should I use that event handler or should I use "PairTouching"?
I changed the event handler from "InitialCollisionDetected" to "DetectingInitialCollision" and that did trigger!
Now question, should I use that event handler or should I use "PairTouching"?
Re: Passing specific entities for narrowphase only
If you're creating a pair, updating it, and returning it to the pool every frame, both will fire every time. It just depends on what delegate signature you prefer at that point. In regular circumstances, pairs survive over multiple frames, so DetectingInitialCollision would be distinct from PairTouching.
You may find that the event handlers are not needed at all, though. The pair.Contacts list is just as informative and, by the looks of it, could be better suited for the job. To get access to the contacts list, cast the NarrowPhasePair to a CollidablePairHandler.
You may find that the event handlers are not needed at all, though. The pair.Contacts list is just as informative and, by the looks of it, could be better suited for the job. To get access to the contacts list, cast the NarrowPhasePair to a CollidablePairHandler.
Re: Passing specific entities for narrowphase only
Brilliant, that is also a bit faster than the event handler, simply looking if there are any contacts in the list, thank you so much for the help, I might have to come back to you later on about some sizing issues when creating the shapes for the entities since I am modifying their sizes at the content pipeline construction and in some models makes it look like the wrong body was created, still that's my pipeline issue not Bepu.
Thanks once again for the awesome support!
Thanks once again for the awesome support!
Re: Passing specific entities for narrowphase only
Hello again,
I was a bit confused about how to update the bounding boxes of my entities... and now I am confused all together since when I noticed that they are of volume 0 (min max both 0, 0, 0), what I don't understand now is that if I got the vertices and indices out of my collision model how come that the boxes living in the collision information have no dimensions, I have my own bounding box rendering method and I wanted to see if the shape position was correct and I stumbled upon this. Norbo you have been amazing, I hope you don't mind giving me some pointers again, thanks in advance!
I was a bit confused about how to update the bounding boxes of my entities... and now I am confused all together since when I noticed that they are of volume 0 (min max both 0, 0, 0), what I don't understand now is that if I got the vertices and indices out of my collision model how come that the boxes living in the collision information have no dimensions, I have my own bounding box rendering method and I wanted to see if the shape position was correct and I stumbled upon this. Norbo you have been amazing, I hope you don't mind giving me some pointers again, thanks in advance!
Re: Passing specific entities for narrowphase only
Ah!
I found the "UpdateBoundingBox()" and I figured I had to set the LocalPosition to the actual position of my entity, and now they draw and appear properly, meaning my mobile mesh shape is properly centered around my models, just to be safe! is there anything besides those 2 steps to set up the collision properly?
I found the "UpdateBoundingBox()" and I figured I had to set the LocalPosition to the actual position of my entity, and now they draw and appear properly, meaning my mobile mesh shape is properly centered around my models, just to be safe! is there anything besides those 2 steps to set up the collision properly?
Re: Passing specific entities for narrowphase only
Calling the UpdateBoundingBox method will set the collidable's world transform to that of its entity owner and calculate the bounding box. That world transform is sufficient for narrow phase tests.
Setting the local position is not needed unless you want to offset the effective origin of rotation. If you're running into the graphic being offset from the shape even when the collidable is in the right spot, it's running into shape recentering: http://bepuphysics.codeplex.com/wikipag ... ecentering
Setting the local position is not needed unless you want to offset the effective origin of rotation. If you're running into the graphic being offset from the shape even when the collidable is in the right spot, it's running into shape recentering: http://bepuphysics.codeplex.com/wikipag ... ecentering