Page 1 of 1
Creating a compound body in the latest BETA?
Posted: Tue Feb 22, 2011 11:53 pm
by Spankenstein
If I wanted to create a compound body from a model I used to collect all the triangles from the model and add them to the compound body.
How do I achieve the same thing with the latest BETA?
A triangle entity can be created from a model:
Code: Select all
Triangle tri = new Triangle(
model.ModelData.Triangles[0].A,
model.ModelData.Triangles[0].B,
model.ModelData.Triangles[0].C
);
but it can't be added to a compound body as it wants the data to derive from the EntityShape abstract class but the Triangle class isn't?!
The 'Shapes' property of a CompoundBody can't be cast to an Entity class either like in previous non BETA versions?
Re: Creating a compound body in the latest BETA?
Posted: Wed Feb 23, 2011 12:08 am
by Norbo
An Entity contains the dynamic information needed to simulate a rigid body. In v0.14.3 and before, all that data was wasted on the child entities; only their shape was used. In v0.15.0, the middleman was removed. A CompoundShape is constructed from multiple CollisionShapes, each associated with a local transformation.
Here's the v0.15.0 version of the CompoundBodiesDemo in the BEPUphysicsDemos project. You can compare it to the old version to see how things have changed.
Code: Select all
//Build the first body
var bodies = new List<DynamicCompoundEntry>()
{
new DynamicCompoundEntry(new SphereShape(.5f), new Vector3(0, 1, 0), 15),
new DynamicCompoundEntry(new ConeShape(2, .5f), new Vector3(1, 1, 0), 15),
new DynamicCompoundEntry(new SphereShape(.5f), new Vector3(-1, 1, 0), 15)
};
var cb1 = new CompoundBody(bodies);
//Build the second body
bodies = new List<DynamicCompoundEntry>()
{
new DynamicCompoundEntry(new BoxShape(1,1,1), new Vector3(0, 3, 0), 2),
new DynamicCompoundEntry(new BoxShape(1,1,1), new Vector3(1, 3.5f, 0), 2),
};
var cb2 = new CompoundBody(bodies);
bodies = new List<DynamicCompoundEntry>();
//Build the third Braum's-fry style body
for (int k = 0; k < 7; k++)
{
bodies.Add(new DynamicCompoundEntry(new BoxShape(1, 1, 1), new Vector3(-4 + k * .7f, 2 + .7f * k, 2 + k * .2f), 1));
}
var cb3 = new CompoundBody(bodies);
//Add them all to the space
Space.Add(cb3);
Space.Add(cb2);
Space.Add(cb1);
Note that CompoundBody is simply a convenience entity subclass. It's possible to directly construct a CompoundCollisionInformation and CompoundShape to provide to a non-prefab entity type (Entity<T>, MorphableEntity).
The Triangle class is another convenience entity subclass. The TriangleShape class is what you'd be looking for.
Re: Creating a compound body in the latest BETA?
Posted: Wed Feb 23, 2011 12:26 am
by Spankenstein
The same problem applies with the TriangleShape class though:
Code: Select all
int numTriangles = model.ModelData.Triangles.Length;
List<TriangleShape> triangles = new List<TriangleShape>(numTriangles);
//DynamicCompoundEntry d = new DynamicCompoundEntry();
for (int i = 0; i < numTriangles; ++i)
{
triangles.Add
(
new TriangleShape
(
model.ModelData.Triangles[i].A,
model.ModelData.Triangles[i].B,
model.ModelData.Triangles[i].C
)
);
}
CompoundBody body = new CompoundBody(triangles);
Argument 1: cannot convert from 'System.Collections.Generic.List<BEPUphysics.CollisionShapes.ConvexShapes.TriangleShape>' to
'System.Collections.Generic.IList<BEPUphysics.CollisionInformations.DynamicCompoundChildData>'
Or have I misunderstood you?
Re: Creating a compound body in the latest BETA?
Posted: Wed Feb 23, 2011 1:16 am
by Norbo
Each shape given to a CompoundShape is associated with a transformation using the CompoundShapeEntry struct. It cannot be constructed with a pure shape list because the shape list does not contain that transformation information.
The CompoundBody constructor has an additional constructor which takes DynamicCompoundEntry structs, which are a CompoundShapeEntry and physical data. This lets you define the physical characteristics of subbodies so that when the inertia tensor calculation is performed for the full body, it is closer to what you want.
There's yet another way to construct them too, using (Dynamic)CompoundChildData, which lets you control events, collision rules, and materials for children.
Re: Creating a compound body in the latest BETA?
Posted: Wed Feb 23, 2011 12:32 pm
by Spankenstein
If I create the compound body using a model's triangles:
Code: Select all
List<DynamicCompoundEntry> triangles = new List<DynamicCompoundEntry>(numTriangles);
for (int i = 0; i < numTriangles; ++i)
{
triangles.Add(
new DynamicCompoundEntry(
new TriangleShape(
model.ModelData.Triangles[i].A,
model.ModelData.Triangles[i].B,
model.ModelData.Triangles[i].C
),
100f
)
);
}
body = new CompoundBody(triangles);
then the triangles are arranged in an incorrect way that doesn't match the original model shape.
For example if I draw the original model triangles in red and the compound body created from the same triangles in white:
Code: Select all
public void Draw()
{
int numShapes = body.Shapes.Count;
for (int i = 0; i < numShapes; ++i)
{
// Compound body triangles
TriangleShape t = body.Shapes[i].Shape as TriangleShape;
game.WireShapeDrawer.DrawWireTriangle(t.VertexA, t.VertexB, t.VertexC, Color.White);
// Original model triangles
game.WireShapeDrawer.DrawWireTriangle(game.Models["Sphere"].ModelData.Triangles[i], Color.Red);
}
}
then the results are totally different:

Re: Creating a compound body in the latest BETA?
Posted: Wed Feb 23, 2011 10:20 pm
by Norbo
All convex shapes attempt to recenter to be on their local origin when constructed. This is a property desired by other systems. However, shapes which recenter themselves have a constructor which outputs their previous center. You could use that constructor, and use the center as the entry's transform.
You could also use the TriangleShape's empty constructor and assign the positions directly. This will prevent the system from recentering the shape, but this could produce errors in the inertia tensor calculation later. If you take this approach, it would be a good idea to create and use your own inertia tensor for the entity (you could just use an inertia tensor computed for a box or sphere of roughly the same dimensions; it will probably be close enough).
It's not going to be this annoying forever, though. Right now, the focus is on getting every big feature (re)implemented. That part of the process is very nearly done, and the next step will be bugfixes, code cleanup and usability enhancements. Dynamic triangle meshes are also in the plans for v0.16.0.
Re: Creating a compound body in the latest BETA?
Posted: Fri Feb 25, 2011 11:09 pm
by Spankenstein
As all triangles are centered around the world origin regardless of whether they belong to a compound body, I've tried some alternatives for some my triangle barriers.
I can't use a parameterless constructor for the 'Triangle' class:
However, I can with the TriangleShape class:
Code: Select all
TriangleShape tri = new TriangleShape();
tri.VertexA = p0;
tri.VertexB = p2;
tri.VertexC = p1;
but I can't add a 'TriangleShape' class to the space
Code: Select all
space.Add(tri); // Error: Argument 1: cannot convert from 'BEPUphysics.CollisionShapes.ConvexShapes.TriangleShape' to 'BEPUphysics.ISpaceObject'

Re: Creating a compound body in the latest BETA?
Posted: Fri Feb 25, 2011 11:44 pm
by Norbo
Right, a TriangleShape is a purely local-space geometry object. It can't exist in the space by itself; it's used to define the geometry of other objects, like entities.
-An entity is a rigid body, which has the dynamic simulation stuff in it. Entities can be added to the space.
-An entity has a CollisionInformation, which is the is collision object associated with the entity. When an entity is added to the space, the CollisionInformation lives in the BroadPhase to find collision pairs, which are then tested in the narrow phase.
-A CollisionInformation has a CollisionShape, which is local, reusable geometry data. Multiple CollisionInformations can use the same CollisionShape. A collision shape, since it only defines local space information, cannot exist by itself in a space.
But again, there is a constructor on the TriangleShape that tells you what its position should be. You can use that position as a offset transform when making a compound body entry.
Also, making an actual Triangle convenience-entity will automatically reposition it such that it is in the proper location in world space (though this doesn't help when making a CompoundBody).
Re: Creating a compound body in the latest BETA?
Posted: Fri Feb 25, 2011 11:54 pm
by Spankenstein
I understand what you are saying but I used to be able to create a Triangle and add it to the Space and it would be where I positioned it. In the BETA it is now centered around the world origin.
You suggested a parameterless constructor for TriangleShape, but what can be done so the Triangle class keeps its original vertex positions and doesn't recenter? (There is no constructor that passes out its previous center)
Re: Creating a compound body in the latest BETA?
Posted: Sat Feb 26, 2011 12:30 am
by Norbo
The TriangleShape parameterless constructor allows you to specify vertices directly by setting the vertex properties. No recentering will occur, but again, that recentering is valuable. Such a non-recentered TriangleShape can be used to construct an Entity (without using the Triangle prefab entity type), though the inertia tensor will not be computed correctly.
A Triangle entity (the convenience subclass of Entity) automatically positions itself such that the vertices are in the correct world location, even though they are recentered in local space. This is done internally by using the TriangleShape constructor that outputs the position, and then setting the entity's own position to that position.
Re: Creating a compound body in the latest BETA?
Posted: Sat Feb 26, 2011 12:44 am
by Spankenstein
Maybe because it is late, and it is Friday, I am now more confused and still can't construct any correctly positioned triangle that can be added to the space.
Norbo wrote:The TriangleShape parameterless constructor allows you to specify vertices directly by setting the vertex properties. No recentering will occur, but again, that recentering is valuable. Such a non-recentered TriangleShape can be used to construct an Entity (without using the Triangle prefab entity type), though the inertia tensor will not be computed correctly.
How can the TriangleShape be used to construct an Entity?
Norbo wrote:
A Triangle entity (the convenience subclass of Entity) automatically positions itself such that the vertices are in the correct world location, even though they are recentered in local space. This is done internally by using the TriangleShape constructor that outputs the position, and then setting the entity's own position to that position.
I create a Triangle and its vertices are not in the correct place due to the centering around the origin. If I wish to center the triangle around its original point then I would need to compute the triangle center from the original vertex positions? There are a lot of ways of computing a triangle center and not all of them accurate depending on the triangle type. It just doesn't make sense for me to go down this route.
I'd better get some sleep, maybe this will make more sense in the morning.
Re: Creating a compound body in the latest BETA?
Posted: Sat Feb 26, 2011 2:19 am
by Norbo
Here's a simple example using the 'convenience' triangle class. This is an entity.
Triangle t = new Triangle(new Vector3(15, 10, 0), new Vector3(16, 10, 0), new Vector3(15, 10, 1));
If you then immediately check the position of the entity, you see {X:15.33333 Y:10 Z:0.3333333}.
The vertices, having been recentered, are:
{X:-0.333334 Y:0 Z:-0.3333333}
{X:0.666666 Y:0 Z:-0.3333333}
{X:-0.333334 Y:0 Z:0.6666666}
Those vertices are the
local vertices. In the next beta, this will become more obvious with both LocalVertex and Vertex properties. The current Vertex properties (and the future LocalVertex properties) are simply a wrapper over the TriangleShape's properties.
Transforming those local positions into world space using the entity's position (and orientation, if it were rotated):
{X:15 Y:10 Z:0}
{X:16 Y:10 Z:0}
{X:15 Y:10 Z:1}
Which are the original world space vertex locations.
Here's how you could make an entity without using the prefab, while still having the same behavior:
Code: Select all
Vector3 center;
TriangleShape tShape = new TriangleShape(new Vector3(15, 10, 0), new Vector3(16, 10, 0), new Vector3(15, 10, 1), out center);
var t = new Entity<ConvexCollisionInformation<TriangleShape>>(new ConvexCollisionInformation<TriangleShape>(tShape));
t.Position = center;
That's basically what the Triangle convenience class does internally. You could also use the MorphableEntity if you wanted.
There are a lot of ways of computing a triangle center and not all of them accurate depending on the triangle type.
Fortunately, you never have to worry about how to compute it; just use what the engine provides, when necessary. However, in case you're curious: for the purposes of the engine, the center is simply the average of each world-space vertex. The actual technical requirement for convex shapes is that they intersect/contain their local origin, and do so in a consistent manner. The average of the vertices produces an acceptable result.
Re: Creating a compound body in the latest BETA?
Posted: Tue Mar 15, 2011 9:32 pm
by Spankenstein
Creating a triangle works the same in the latest version:
Code: Select all
triangles[0] = new TriangleShape(); // 0, 1, 2
triangles[0].VertexA = p0;
triangles[0].VertexB = p1;
triangles[0].VertexC = p2;
triangles[1] = new TriangleShape(); // 1, 3, 2
triangles[1].VertexA = p1;
triangles[1].VertexB = p3;
triangles[1].VertexC = p2;
triangles[0].Sidedness = BEPUphysics.CollisionShapes.ConvexShapes.TriangleSidedness.Counterclockwise;
triangles[1].Sidedness = BEPUphysics.CollisionShapes.ConvexShapes.TriangleSidedness.Counterclockwise;
but adding the triangle to space doesn't work the same way:
Code: Select all
game.Space.Add(new Entity<ConvexCollisionInformation<TriangleShape>>(new ConvexCollisionInformation<TriangleShape>(triangles[0])));
game.Space.Add(new Entity<ConvexCollisionInformation<TriangleShape>>(new ConvexCollisionInformation<TriangleShape>(triangles[1])));
How can a TriangleShape be correctly added to the space?
Re: Creating a compound body in the latest BETA?
Posted: Tue Mar 15, 2011 10:01 pm
by Norbo
Changing ConvexCollisionInformation to ConvexCollidable should work. Every class previously using "CollisionInformation" in their name should now be moved over to Collidable.
Re: Creating a compound body in the latest BETA?
Posted: Tue Mar 15, 2011 10:33 pm
by Spankenstein
That solved it. Thanks
