Hello,
I was wondering if anyone could point me in the right direction to solve a problem I have.
I am trying to build Destructible geometry, at the moment I am trying to build a basic wall that is made up out of smaller blocks.
My end goal is that when the wall is hit in a certain spot, parts of it will break away (think explosions interacting with a brick wall).
So far I have tried using CompoundBody, CompoundColliables and the CompoundHelper to split the wall compound at specific locations, but I am struggling to get my head around just what is going on.
Does anyone have a solid understanding of the Compound classes that could help me, or is there a better way of doing this without compoundbodies?
Thank you in advance.
-Daniel
CompoundBodies and Destruction
Re: CompoundBodies and Destruction
CompoundShapes are indeed the way to do destruction if you want to have a set of movable bound-together indivisible 'atoms' which then split into smaller groups of movable bound-together atoms.So far I have tried using CompoundBody, CompoundColliables and the CompoundHelper to split the wall compound at specific locations, but I am struggling to get my head around just what is going on.
If you have a particular question about it, I could provide more detail.
[Side note: one of the big reasons behind the weird interface for splitting compounds is that CompoundShapes are designed to be immutable. The CompoundHelper was created to make splitting existing compound shapes into new separate compound shapes a little easier, but it's still a bit ugly.
The helper was actually created and used in a destruction prototype I created a while back, but I haven't yet gotten around to polishing it up. A proper destruction implementation would use a new mutable version of the compound shape with acceleration structure implementations which could handle changes in topology without garbage generation (like the default broad phase), and preferably with greater speed than a full top-down rebuild (like the default broad phase).]
If you want a piece of static geometry to simply blow up into a bunch of indivisible constituent pieces, splitting compounds isn't necessary. Just remove the original whole (mesh, compound, or whatever it happened to be) and spawn a bunch of individual 'debris' pieces in its place.is there a better way of doing this without compoundbodies?
Re: CompoundBodies and Destruction
Could please just give me an outline on splitting a compound. Is it possible to split on a specific shape in the compound? I saw that there was a mutableCompoundsDemo in the Demos download and I had a look through that, from this I got splitting at a half way point. What I really want to be able to do is say Box X is no longer part of the compound and is just a standard Box in the space.
I thought about switching out the mesh but I really want it to be dynamic, so depending on where it is hit is where it will break.
Thanks for the speedy reply.
-Daniel
I thought about switching out the mesh but I really want it to be dynamic, so depending on where it is hit is where it will break.
Thanks for the speedy reply.
-Daniel
Re: CompoundBodies and Destruction
The CompoundHelper.SplitCompound method takes a delegate which checks each child of the compound body and chooses whether to keep it in the original compound, or to put it into the new compound shape. Any function can be supplied, including one that checks for a specific shape.
For example, here's one that checks to see if a child uses the JorbleShape:
You won't be able to get a pure Box Entity type out of the SplitCompound method, though. It will always be a compound body, even if it only contains one BoxShape child. You can do extra manual processing to extract that if you want, but there's not much overhead in just letting it be a compound.
For example, here's one that checks to see if a child uses the JorbleShape:
Code: Select all
CompoundHelper.SplitCompound(x => x.CollisionInformation.Shape == JorbleShape, compound, out compound2);
Re: CompoundBodies and Destruction
Thank Norbo, I will give that a try. Would you be able to tell me how to hook it up to a collision event. Do I put it in the collision event for the whole compound or just the single compound shape entry?
Re: CompoundBodies and Destruction
Hooking it to a single child would require hooking an event to every child you wanted to break. It could be done this way, but it would involve extra annoyances.
I'd recommend just hooking it to the parent compound. Be sure to use a deferred event (past tense names) as opposed to an immediate event (present tense names); immediate events are fired during the actual execution of the collision pair handlers. More information about collision rules can be found in the collision rules documentation.
Note that collision events are not the only way to handle collisions; you could also just check the collision pairs of an entity (entity.CollisionInformation.Pairs) and check each pair's contacts list for contacts of nonnegative depth. If one exists, the objects are touching.
I'd recommend just hooking it to the parent compound. Be sure to use a deferred event (past tense names) as opposed to an immediate event (present tense names); immediate events are fired during the actual execution of the collision pair handlers. More information about collision rules can be found in the collision rules documentation.
Note that collision events are not the only way to handle collisions; you could also just check the collision pairs of an entity (entity.CollisionInformation.Pairs) and check each pair's contacts list for contacts of nonnegative depth. If one exists, the objects are touching.
Re: CompoundBodies and Destruction
Hi,
I attached the below Collision handler to the main compound shape and it works how I like. I want subsequent compounds that come from the split to also be able to split. Right now if I don't attach this handler to compounds that resulted from a split it works, but of course only once. If I do attach this handler the resulting compound falls through the floor.
I hope this is legible.
Thanks in advance.
-Daniel
I attached the below Collision handler to the main compound shape and it works how I like. I want subsequent compounds that come from the split to also be able to split. Right now if I don't attach this handler to compounds that resulted from a split it works, but of course only once. If I do attach this handler the resulting compound falls through the floor.
Code: Select all
void CompoundCollision(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
{
var otherEntityInformation = other as EntityCollidable;
//Don't do anything on collisions with the floor AND don't do anything with null tags, I use tags to keep track of my compounds
if (otherEntityInformation.Entity.Tag != ground.Tag && sender.Entity.Tag != null)
{
//get the compound that we just hit from the list of compounds using its entity.tag (hence why this tag can't be null)
var compound1 = Compounds[(int)sender.Entity.Tag] as Entity<CompoundCollidable>;
if (otherEntityInformation != null)
{
//Here I create to compounds,
//compound2 is made up of shapes that were within 2 units distance with the object that hit the main compound,
//compound3 is made up of shapes that didn't make it into compound2
Entity<CompoundCollidable> compound2, compound3;
CompoundHelper.SplitCompound(x => EuclidDist(x.Entry.LocalTransform.Position + compound1.Position, otherEntityInformation.Entity.Position) < 2, compound1, out compound2);
CompoundHelper.SplitCompound(x => EuclidDist(x.Entry.LocalTransform.Position + compound1.Position, otherEntityInformation.Entity.Position) >= 2, compound1, out compound3);
//if the split was successful
if (compound2 != null && compound3 != null)
{
//remove old compound
Space.Remove(compound1);
ModelDrawer.Remove(compound1);
//add compound2
Compounds.Add(compound2);
compound2.CollisionInformation.Entity.Tag = Compounds.Count - 1;
Space.Add(compound2);
ModelDrawer.Add(compound2);
//add compound3
Compounds.Add(compound3);
compound3.CollisionInformation.Entity.Tag = Compounds.Count - 1;
Space.Add(compound3);
ModelDrawer.Add(compound3);
//this is what causes the compound to fall through the floor.
compound3.CollisionInformation.Events.InitialCollisionDetected += CompoundCollision;
}
}
}
}
I hope this is legible.
Thanks in advance.
-Daniel
Re: CompoundBodies and Destruction
The following creates three compounds, not two.
The first line splits compound1 into compound1 and compound2. After the execution of the first line, compound1 contains only elements which have a distance of >= 2. The second line is unnecessary and compound1 should not be removed from the space.
Additionally, x.Entry.LocalTransform is the local transform. The local position of an entry must be transformed to world space if you want to add it to another world space position (i.e. the compound's position).
Chances are, the reason stuff falls through the ground is related. Note that empty compounds are not supported; they will likely result in crashes if they're present.
Also, watch out:
The Tag property is of type object. Setting an integer or any other value type to the property will result in boxing.
Code: Select all
CompoundHelper.SplitCompound(x => EuclidDist(x.Entry.LocalTransform.Position + compound1.Position, otherEntityInformation.Entity.Position) < 2, compound1, out compound2);
CompoundHelper.SplitCompound(x => EuclidDist(x.Entry.LocalTransform.Position + compound1.Position, otherEntityInformation.Entity.Position) >= 2, compound1, out compound3);
Additionally, x.Entry.LocalTransform is the local transform. The local position of an entry must be transformed to world space if you want to add it to another world space position (i.e. the compound's position).
Chances are, the reason stuff falls through the ground is related. Note that empty compounds are not supported; they will likely result in crashes if they're present.
Also, watch out:
Code: Select all
compound3.CollisionInformation.Entity.Tag = Compounds.Count - 1;
Re: CompoundBodies and Destruction
Ah, I have made these changes and it worked. I had a weird graphical thing where modeldrawer was still drawing the original compound whole so I simple removed and re-added it and it all works nicely.
Thank you.
Thank you.