Compound Body entity with boxes. Incorrect local transform.

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Spankenstein
Posts: 249
Joined: Wed Nov 17, 2010 1:49 pm

Compound Body entity with boxes. Incorrect local transform.

Post by Spankenstein »

I've created a compound bound from a series of boxes:

Code: Select all

            int numVoxels = voxelAnimator.VoxelSettings.Length;

            List<CompoundShapeEntry> boxes = new List<CompoundShapeEntry>(numVoxels); 

            for (int i = 0; i < numVoxels; ++i)
            {
                BoxShape box = new BoxShape(
                    voxelAnimator.VoxelSettings[i].Size,
                    voxelAnimator.VoxelSettings[i].Size,
                    voxelAnimator.VoxelSettings[i].Size
                    );

                boxes.Add(
                    new CompoundShapeEntry(
                        box,
                        voxelAnimator.VoxelSettings[i].Position
                    )
                );
            }

            entity = new CompoundBody(boxes);
The problem is that when I draw the original voxels and the white compound body they are not in the same place:

Image

How can I make sure the compound body is centered correctly?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Compound Body entity with boxes. Incorrect local transf

Post by Norbo »

The Position of the CompoundBody immediately after construction is the offset that needs to be applied to the graphic.

It's also possible to get the data from the CompoundShape constructor if you were making one to re-use with multiple entities (it has an out parameter in one of its constructors for the computed center position).
Spankenstein
Posts: 249
Joined: Wed Nov 17, 2010 1:49 pm

Re: Compound Body entity with boxes. Incorrect local transf

Post by Spankenstein »

I'm using the compound body world transform to transform the voxel positions:

Code: Select all

            int numQuadrangles = voxelAnimator.Quadrangles.Length;

            for (int i = 0; i < numQuadrangles; ++i)
            {
                quadrangles[i].Transform(entity.WorldTransform);
            }
Are you saying that I need to apply an offset of:

Code: Select all

Matrix.CreateTranslation(-ComputedCenter())
giving:

Code: Select all

quadrangles[i].Transform(Matrix.CreateTranslation(-ComputedCenter()) * entity.WorldTransform);
each frame. Wouldn't that upset other calculations based on the entity position?

Also, BoxShape doesn't provide a constructor with an out parameter like TriangleShape does?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Compound Body entity with boxes. Incorrect local transf

Post by Norbo »

Yes, create a transform that essentially recenters the graphic to the origin of the compound before applying the entity's world transform. It shouldn't cause any problems; it's just changing the location at which the graphic is located. It never affects the physics in any way, and only reads from the physics system at initialization once.
Also, BoxShape doesn't provide a constructor with an out parameter like TriangleShape does?
Correct; BoxShapes (and some other ones like SphereShape, ConeShape, etc.) are built already centered. If it had an out parameter, it would always be Vector3.Zero. Only shapes that require recentering have an out parameter.
Spankenstein
Posts: 249
Joined: Wed Nov 17, 2010 1:49 pm

Re: Compound Body entity with boxes. Incorrect local transf

Post by Spankenstein »

It shouldn't cause any problems; it's just changing the location at which the graphic is located. It never affects the physics in any way, and only reads from the physics system at initialization once.
The problem is that I just can't get my head around it. For example, if I create a Compound Body made from one cube with a position at the origin:

Code: Select all

            BoxShape box = new BoxShape(1f, 1f, 1f);
            boxes.Add(new CompoundShapeEntry(box, Vector3.Zero));
The compound body position is not centered around the origin, even though it's world transform translation is (0, 0 ,0). Why would this be the case?!
Correct; BoxShapes (and some other ones like SphereShape, ConeShape, etc.) are built already centered. If it had an out parameter, it would always be Vector3.Zero. Only shapes that require recentering have an out parameter.
So what can I use to recenter the compound body around the origin permanently?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Compound Body entity with boxes. Incorrect local transf

Post by Norbo »

Code: Select all

           var boxes = new List<CompoundShapeEntry>();
            BoxShape box = new BoxShape(1f, 1f, 1f);
            boxes.Add(new CompoundShapeEntry(box, Vector3.Zero));
            CompoundBody body = new CompoundBody(boxes);
Using that, body.Position is Vector3.Zero, as expected. Additionally, body.WorldTransform.Translation is also Vector3.Zero, as expected- the WorldTransform property is just a convenience property that uses the Position and Orientation(Matrix).

Code: Select all

            var boxes = new List<CompoundShapeEntry>();
            BoxShape box = new BoxShape(1f, 1f, 1f);
            boxes.Add(new CompoundShapeEntry(box, new Vector3(1, 1, 1)));
            CompoundBody body = new CompoundBody(boxes);
Note the different local translation on the CompoundShapeEntry. If you look at the body.Position on this version, it says (1,1,1), since that's the location of the center of the compound shape (which, in this example, is a single shape at (1,1,1)). Internally, the CompoundShape stores the BoxShape with a local transformation with translation of (0,0,0), since the subshape is perfectly aligned with the compound local origin (because it's the only shape).

Code: Select all

            var boxes = new List<CompoundShapeEntry>();
            boxes.Add(new CompoundShapeEntry(new BoxShape(1f, 1f, 1f), new Vector3(1, 1, 0)));
            boxes.Add(new CompoundShapeEntry(new BoxShape(1f, 1f, 1f), new Vector3(-1, 1, 0)));
            CompoundBody body = new CompoundBody(boxes);
The above shows a two-box body. The body.Position is now (0,1,0), since that's the weighted average of the locations of the shapes. The internal local transformations of the box shapes in the compound shape are (1,0,0) and (-1,0,0).

So let's imagine you had a graphic that was created such that its local origin was at (0,0,0) and the box shape models were positioned at (1,1,0) and (-1,1,0). If the compound didn't move and you just directly rendered the graphic without transforming it using the entity's position, the shapes would match.

However, because the entity's transform now includes an offset, you need to apply the reverse offset to the graphic to realign them. In other words, apply a local transform of -InitialCenterOffset (where InitialCenterOffset = body.Position right after initialization) before applying entity.WorldTransform.
Spankenstein
Posts: 249
Joined: Wed Nov 17, 2010 1:49 pm

Re: Compound Body entity with boxes. Incorrect local transf

Post by Spankenstein »

Thanks for taking the time to explain. I understand what is going on now.
Post Reply