I just pulled down the development version. Looks like it's fixed.
I've also came across 2 other bugs earlier this week that I fixed, but haven't notified you of yet. I'll let you know here in the forums, but for future reference, do you prefer I just fill out a bug report?
Bug #1
Stack overflow when assigning to MorphableEntity.CollisionInformation.
The problem is the "get" accessor refers to its own CollisionInformation property.
Code: Select all
public new EntityCollidable CollisionInformation
{
get
{
return CollisionInformation;
}
set
{
SetCollisionInformation(value);
}
}
I believe the intention was to call the base class's version. As such I believe changing the code to what follows is what you intended.
Code: Select all
public new EntityCollidable CollisionInformation
{
get
{
return base.CollisionInformation;
}
set
{
SetCollisionInformation(value);
}
}
Bug #2
Null reference exception in EntityCollidable.IsActive.
During my game play, it appears I get into a state where the narrow phase system is attempting to remove stale overlaps from a previous frame. The problem is that the system still has a reference to the collision information, but my code does not. By this time I've already destroyed the entity, so when the narrow phase runs this code:
Code: Select all
void RemoveStaleOverlaps()
{
//Remove stale objects.
//TODO: This could benefit from a custom data structure (a tiny amount).
//TODO: This could possibly be done with a computation spreading approach.
//Problem: Consider a collision pair that has contacts one frame, and in the next, no longer even has a broad phase overlap.
//It will receive no update, and the collision pair will still have a contact in it.
//Collision solver will operate on permanently out of date information.
//One possible solution requires that the user of the narrow phase object checks its age, and if it's out of date, ignore it.
//In a subsequent frame, the system will get rid of it. This has an advantage of lowering the (somewhat tiny) per frame cost of removal management.
//Additionally, in highly chaotic situations where collisions are constantly being created/destroyed, spreading out the computations
//smooths the work out a bit.
for (int i = narrowPhasePairs.Count - 1; i >= 0; i--)
{
INarrowPhasePair narrowPhaseObject = narrowPhasePairs[i];
if (narrowPhaseObject.NeedsUpdate &&
//Overlap will not be refreshed if entries are inactive, but shouldn't remove narrow phase pair.
==> (narrowPhaseObject.BroadPhaseOverlap.entryA.IsActive || narrowPhaseObject.BroadPhaseOverlap.entryB.IsActive))
{
narrowPhasePairs[i] = narrowPhasePairs[narrowPhasePairs.Count - 1];
narrowPhasePairs.RemoveAt(narrowPhasePairs.Count - 1);
OnRemovePair(narrowPhaseObject);
}
else
narrowPhaseObject.NeedsUpdate = true;
}
}
...it crashes because either of the broad phase entries (entryA or entryB) doesn't have an entity anymore.
I worked around this problem, by simply returning false in EntityCollidable.IsActive if the entity itself was null. It doesn't seem to cause any bad behavior, but it doesn't seem like the proper fix either. It feel clunky. Hopefully you'll know of a better fix.
Here's the callstack for reference:
Code: Select all
BEPUphysics.dll!BEPUphysics.Collidables.MobileCollidables.EntityCollidable.IsActive.get() Line 87 C#
BEPUphysics.dll!BEPUphysics.NarrowPhaseSystems.NarrowPhase.RemoveStaleOverlaps() Line 258 + 0x29 bytes C#
BEPUphysics.dll!BEPUphysics.NarrowPhaseSystems.NarrowPhase.UpdateSingleThreaded() Line 235 + 0x8 bytes C#
BEPUphysics.dll!BEPUphysics.MultithreadedProcessingStage.Update() Line 59 + 0xb bytes C#
BEPUphysics.dll!BEPUphysics.Space.DoTimeStep() Line 398 + 0x15 bytes C#
BEPUphysics.dll!BEPUphysics.Space.Update(float dt) Line 430 + 0x8 bytes C#
Let me know if you need additional information!
Thanks for the engine! So far so good.