Page 1 of 1

Aligning graphic to a predefined physics shape

Posted: Mon Mar 25, 2013 4:50 pm
by purple
I have a problem when trying to align a 3D model to physics model - model gets rotated to it's horizontal postition. I use SuspensionCarDemo2 example which has predefined physics shapes and I do not want to create the collision shape from the model because I work with high-poly meshes.

Here is a shape to which I want the model to be attached:

Code: Select all

var wheel = new Cylinder(suspensionLeg.Position + new Vector3(leftSide ? -horizontalWheelOffset : horizontalWheelOffset, -suspensionLeg.HalfHeight, 0), .2f, .3f, 5f);
Is there a way to align my model to the Cylinder shape?

Re: Aligning graphic to a predefined physics shape

Posted: Mon Mar 25, 2013 5:04 pm
by Norbo
Yes; you will need to apply a local transform before the entity world transform, like so:

Code: Select all

modelWorldTransform = localGraphicalTransform * entity.WorldTransform;
The goal of the localGraphicalTransform in the above is to bring the graphical model into alignment with the entity in local space. In other words, without applying any world transform, both have the same orientation and they're nicely aligned. Then, when the entity.WorldTransform is applied, the resulting graphical transform will be consistent.

So, if your graphical model is rotated 90 degrees off from what it should be, the localGraphicalTransform would be something like Matrix.CreateRotationY(MathHelper.PiOver2). If it needed to be rotated and translated, it would look something like Matrix.CreateRotationY(MathHelper.PiOver2) * Matrix.CreateTranslation(new Vector3(1,5,2)).

Re: Aligning graphic to a predefined physics shape

Posted: Mon Mar 25, 2013 6:30 pm
by purple
I am not quite sure how to do what you've written. Where do I put and access these properties?
Here's my code adjusted to work with BEPUphysics:

Code: Select all

 void AddBackWheel(Vector3 suspensionOffset, BEPUphysics.Entities.Entity body, bool leftSide)
        {
            var suspensionLeg = new Box(body.Position + suspensionOffset, 0.25f, 0.8f, 0.25f, 10);
            const float horizontalWheelOffset = 0.2f;

            var wheel = new BEPUphysics.Entities.Prefabs.Cylinder(suspensionLeg.Position + new Vector3(leftSide ? -horizontalWheelOffset : horizontalWheelOffset, -suspensionLeg.HalfHeight, 0), .2f, .3f, 5f);            
            GameObject3D modelForWheel = new GameObject3D(new FileModel("wheelRim"), new BlinnPhong { DiffuseColor = new Color(30, 30, 30), SpecularIntensity = 0.3f, SpecularPower = 200 });
            

            var wheelEntity = (RigidBody)modelForWheel.AddComponent<RigidBody>();
            wheelEntity.Entity = wheel;
                        
            wheel.CollisionInformation.LocalPosition = wheel.Position;
            
            wheel.Material.KineticFriction = 2.5f;
            wheel.Material.StaticFriction = 2.5f;
            wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);

Re: Aligning graphic to a predefined physics shape

Posted: Mon Mar 25, 2013 7:27 pm
by Norbo
'modelWorldTransform' is the matrix used to transform your graphical model. It's a stand-in for whatever your system calls it; it's completely separate from BEPUphysics and is dependent on your rendering system. Presumably, somewhere in the renderer, the model's world transform (or something equivalent) is changed; that is the 'modelWorldTransform'.

'localGraphicalTransform' is another such external matrix. BEPUphysics is not aware of it. Its purpose is just to align the graphical model with the collision shape. The exact form, location, and use of the transform is dependent on your rendering system.

The entity.WorldTransform is just a convenience property of the Entity class which returns the 4x4 matrix representation of the entity's position and orientation.

Re: Aligning graphic to a predefined physics shape

Posted: Mon Mar 25, 2013 9:05 pm
by purple
I understand it now, unfortunately it seems that trying to turn the model in my engine doesn't work. Which is render engine's problem not BEPUphysics.

Code: Select all

modelForWheel.Transform.Rotate(new Vector3(0, 0, 90), Space.Local);
Thanks for your explanation.