예제 #1
0
 public AeroControl(Matrix3 mbase, Matrix3 mintens, Matrix3 maxtens, Vector3 position, Vector3 windspeed)
     : base(mbase, position, windspeed)
 {
     MaxTensor = maxtens;
     MinTensor = mintens;
     ControlSetting = 0.0f;
 }
예제 #2
0
 internal void updateforcefromtensor(RigidBody body, float duration, Matrix3 tensor)
 {
     Vector3 velocity = body.GetVelocity();
     velocity += WindSpeed;
     Vector3 bodyVel = body.GetTransform().TransformInverseDirection(velocity);
     Vector3 bodyForce = tensor.Transform(bodyVel);
     Vector3 force = body.GetTransform().TransformDirection(bodyForce);
     body.AddForceAtBodyPoint(force, Position);
 }
예제 #3
0
 public void SetInverse(Matrix3 m)
 {
     float t4 = m.data[0] * m.data[4];
     float t6 = m.data[0] * m.data[5];
     float t8 = m.data[1] * m.data[3];
     float t10 = m.data[2] * m.data[3];
     float t12 = m.data[1] * m.data[6];
     float t14 = m.data[2] * m.data[6];
     float t16 = (t4 * m.data[8] - t6 * m.data[7] - t8 * m.data[8] + t10 * m.data[7] + t12 * m.data[5] - t14 * m.data[4]);
     if (t16 == (float)0.0f) return;
     float t17 = 1.0f / t16;
     if (data == null) data = new float[9];
     data[0] = (m.data[4] * m.data[8] - m.data[5] * m.data[7]) * t17;
     data[1] = -(m.data[1] * m.data[8] - m.data[2] * m.data[7]) * t17;
     data[2] = (m.data[1] * m.data[5] - m.data[2] * m.data[4]) * t17;
     data[3] = -(m.data[3] * m.data[8] - m.data[5] * m.data[6]) * t17;
     data[4] = (m.data[0] * m.data[8] - t14) * t17;
     data[5] = -(t6 - t10) * t17;
     data[6] = (m.data[3] * m.data[7] - m.data[4] * m.data[6]) * t17;
     data[7] = -(m.data[0] * m.data[7] - t12) * t17;
     data[8] = (t4 - t8) * t17;
 }
예제 #4
0
 public void SetTranspose(Matrix3 m)
 {
     data[0] = m.data[0];
     data[1] = m.data[3];
     data[2] = m.data[6];
     data[3] = m.data[1];
     data[4] = m.data[4];
     data[5] = m.data[7];
     data[6] = m.data[2];
     data[7] = m.data[5];
     data[8] = m.data[8];
 }
예제 #5
0
 public static Matrix3 LinearInterpolate(Matrix3 a, Matrix3 b, float prop)
 {
     Matrix3 result = Matrix3.Identity;
     for (int i = 0; i < 9; i++)
     {
         result.data[i] = a.data[i] * (1 - prop) + b.data[i] * prop;
     }
     return result;
 }
예제 #6
0
 public void CalculateDerivedData()
 {
     Orientation.Normalize();
     TransformMatrix = _calculateTransformMatrix(Position, Orientation);
     InverseInertiaTensorWorld = _transformInertiaTensor(Orientation, InverseInertiaTensor, TransformMatrix);
 }
예제 #7
0
 static Matrix3 _transformInertiaTensor(Quaternion q, Matrix3 iitBody, Matrix4 rotmat)
 {
     float t4 = rotmat[0] * iitBody[0] + rotmat[1] * iitBody[3] + rotmat[2] * iitBody[6];
     float t9 = rotmat[0] * iitBody[1] + rotmat[1] * iitBody[4] + rotmat[2] * iitBody[7];
     float t14 = rotmat[0] * iitBody[2] + rotmat[1] * iitBody[5] + rotmat[2] * iitBody[8];
     float t28 = rotmat[4] * iitBody[0] + rotmat[5] * iitBody[3] + rotmat[6] * iitBody[6];
     float t33 = rotmat[4] * iitBody[1] + rotmat[5] * iitBody[4] + rotmat[6] * iitBody[7];
     float t38 = rotmat[4] * iitBody[2] + rotmat[5] * iitBody[5] + rotmat[6] * iitBody[8];
     float t52 = rotmat[8] * iitBody[0] + rotmat[9] * iitBody[3] + rotmat[10] * iitBody[6];
     float t57 = rotmat[8] * iitBody[1] + rotmat[9] * iitBody[4] + rotmat[10] * iitBody[7];
     float t62 = rotmat[8] * iitBody[2] + rotmat[9] * iitBody[5] + rotmat[10] * iitBody[8];
     Matrix3 iitWorld = Matrix3.Identity;
     iitWorld[0] = t4 * rotmat[0] + t9 * rotmat[1] + t14 * rotmat[2];
     iitWorld[1] = t4 * rotmat[4] + t9 * rotmat[5] + t14 * rotmat[6];
     iitWorld[2] = t4 * rotmat[8] + t9 * rotmat[9] + t14 * rotmat[10];
     iitWorld[3] = t28 * rotmat[0] + t33 * rotmat[1] + t38 * rotmat[2];
     iitWorld[4] = t28 * rotmat[4] + t33 * rotmat[5] + t38 * rotmat[6];
     iitWorld[5] = t28 * rotmat[8] + t33 * rotmat[9] + t38 * rotmat[10];
     iitWorld[6] = t52 * rotmat[0] + t57 * rotmat[1] + t62 * rotmat[2];
     iitWorld[7] = t52 * rotmat[4] + t57 * rotmat[5] + t62 * rotmat[6];
     iitWorld[8] = t52 * rotmat[8] + t57 * rotmat[9] + t62 * rotmat[10];
     return iitWorld;
 }
예제 #8
0
 void _checkInverseInertiaTensor(Matrix3 InverseInertiaTensor)
 {
 }
예제 #9
0
 public void SetInertiaTensor(Matrix3 inertiaTensor)
 {
     InverseInertiaTensor.SetInverse(inertiaTensor);
     _checkInverseInertiaTensor(InverseInertiaTensor);
 }
예제 #10
0
        internal Vector3 calculateFrictionImpulse(Matrix3[] inverseInertiaTensor)
        {
            Vector3 impulseContact = new Vector3();
            float inverseMass = Bodies[0].InverseMass;
            Matrix3 impulseToTorque = Matrix3.Identity;
            impulseToTorque.SetSkewSymmetric(RelativeContactPosition[0]);
            Matrix3 deltaVelWorld = impulseToTorque;
            deltaVelWorld *= inverseInertiaTensor[0];
            deltaVelWorld *= impulseToTorque;
            deltaVelWorld *= -1;
            if (Bodies[1] != null)
            {
                impulseToTorque.SetSkewSymmetric(RelativeContactPosition[1]);
                Matrix3 deltaVelWorld2 = impulseToTorque;
                deltaVelWorld2 *= inverseInertiaTensor[1];
                deltaVelWorld2 *= impulseToTorque;
                deltaVelWorld2 *= -1;
                deltaVelWorld += deltaVelWorld2;
                inverseMass += Bodies[1].InverseMass;
            }
            Matrix3 deltaVelocity = ContactToWorld.Transpose();
            deltaVelocity *= deltaVelWorld;
            deltaVelocity *= ContactToWorld;
            deltaVelocity[0] += inverseMass;
            deltaVelocity[4] += inverseMass;
            deltaVelocity[8] += inverseMass;
            Matrix3 impulseMatrix = deltaVelocity.Inverse();
            Vector3 velKill = new Vector3(DesiredDeltaVelocity, -ContactVelocity.Y, -ContactVelocity.Z);
            impulseContact = impulseMatrix.Transform(velKill);
            float planarImpulse = MathHelper.Sqrt(impulseContact.Y * impulseContact.Y +
                impulseContact.Z * impulseContact.Z
                );
            if (planarImpulse > impulseContact.X * Friction)
            {
                impulseContact.Y /= planarImpulse;
                impulseContact.Z /= planarImpulse;

                impulseContact.X = deltaVelocity[0] +
                    deltaVelocity[1] * Friction * impulseContact.Y +
                    deltaVelocity[2] * Friction * impulseContact.Z;
                impulseContact.X = DesiredDeltaVelocity / impulseContact.X;
                impulseContact.Y *= Friction * impulseContact.X;
                impulseContact.Z *= Friction * impulseContact.X;
            }
            return impulseContact;
        }
예제 #11
0
 internal Vector3 calculateFrictionlessImpulse(Matrix3[] inverseInertiaTensor)
 {
     Vector3 impulseContact = new Vector3();
     Vector3 deltaVelWorld = Vector3.Cross(RelativeContactPosition[0], ContactNormal);
     deltaVelWorld = inverseInertiaTensor[0].Transform(deltaVelWorld);
     deltaVelWorld = Vector3.Cross(deltaVelWorld, RelativeContactPosition[0]);
     float deltaVelocity = Vector3.Dot(deltaVelWorld, ContactNormal);
     deltaVelocity += Bodies[0].InverseMass;
     if (Bodies[1] != null)
     {
         Vector3 vdeltaVelWorld = Vector3.Cross(RelativeContactPosition[1], ContactNormal);
         vdeltaVelWorld = inverseInertiaTensor[1].Transform(vdeltaVelWorld);
         vdeltaVelWorld = Vector3.Cross(vdeltaVelWorld, RelativeContactPosition[1]);
         deltaVelocity += Vector3.Dot(vdeltaVelWorld, ContactNormal);
         deltaVelocity += Bodies[1].InverseMass;
     }
     impulseContact.X = DesiredDeltaVelocity / deltaVelocity;
     impulseContact.Y = 0;
     impulseContact.Z = 0;
     return impulseContact;
 }
예제 #12
0
 //void applyImpulse(Vector3 impulse, RigidBody body, Vector3 velocityChange, Vector3 rotationChange)
 //{
 //}
 internal void applyVelocityChange(Vector3[] velocityChange, Vector3[] rotationChange)
 {
     Matrix3[] inverseInertiaTensor = new Matrix3[2];
     inverseInertiaTensor[0] = Bodies[0].InverseInertiaTensorWorld;
     if (Bodies[1] != null)
         inverseInertiaTensor[1] = Bodies[1].InverseInertiaTensorWorld;
     Vector3 impulseContact;
     if (Friction == 0.0f)
     {
         impulseContact = calculateFrictionlessImpulse(inverseInertiaTensor);
     }
     else
     {
         impulseContact = calculateFrictionImpulse(inverseInertiaTensor);
     }
     Vector3 impulse = ContactToWorld.Transform(impulseContact);
     Vector3 impulsiveTorque = Vector3.Cross(RelativeContactPosition[0], impulse);
     rotationChange[0] = inverseInertiaTensor[0].Transform(impulsiveTorque);
     velocityChange[0] = new Vector3();
     velocityChange[0] += (impulse * Bodies[0].InverseMass);
     Bodies[0].AddVelocity(velocityChange[0]);
     Bodies[0].AddRotation(rotationChange[0]);
     if (Bodies[1] != null)
     {
         Vector3 impulsiveTorque2 = Vector3.Cross(impulse, RelativeContactPosition[1]);
         rotationChange[1] = inverseInertiaTensor[1].Transform(impulsiveTorque2);
         velocityChange[1] = new Vector3();
         velocityChange[1] += (impulse * -Bodies[1].InverseMass);
         Bodies[1].AddVelocity(velocityChange[1]);
         Bodies[1].AddRotation(rotationChange[1]);
     }
 }
예제 #13
0
 public static Vector3 Transform(Vector3 vector, Matrix3 matrix)
 {
     float[] data = matrix;
     return new Vector3(
         vector.X * data[0] + vector.Y * data[1] + vector.Z * data[2],
         vector.X * data[3] + vector.Y * data[4] + vector.Z * data[5],
         vector.X * data[6] + vector.Y * data[7] + vector.Z * data[8]
     );
 }
예제 #14
0
 public void SetInertiaTensor(Matrix3 matrix)
 {
     inverseInertiaTensor.SetInverse(matrix);
 }
예제 #15
0
 void addboat()
 {
     buoyancy = new Buoyancy(1.0f, 3.0f, 1.6f, 1000, new Disque.Math.Vector3(0, 0.5f, 0));
     sail = new Aero(new D.Matrix3(new float[]{ 0,0,0, 0,0,0, 0,0,-1.0f}), new D.Vector3(2.0f, 0, 0), windspeed);
     cube = new Cube(new Vector3(0, 30, 0), 3, 3, 3, Color.Blue, GraphicsDevice);
     drawables.Add(cube);
     body = new RigidBody();
     body.SetOrientation(new Disque.Math.Quaternion(1, 0, 0, 0));
     body.LinearDrag = 0.8f;
     body.AngularDrag = 0.8f;
     body.Position = new Disque.Math.Vector3(0, 1.6f, 0);
     body.Mass = 200;
     D.Matrix3 it = new D.Matrix3();
     it.SetBlockInertiaTensor(new D.Vector3(1.5f, 1.5f, 1.5f), 100.0f);
     body.BoundingSphere = new D.BoundingSphere(body.Position, 1.5f);
     body.SetInertiaTensor(it);
     body.CalculateDerivedData();
     body.SetAwake();
     body.SetCanSleep(true);
     body.ForceGenerators.Add(buoyancy);
     body.ForceGenerators.Add(sail);
     rbw.RigidBodies.Add(body);
 }
예제 #16
0
 public Aero(Matrix3 tensor, Vector3 position, Vector3 windspeed)
 {
     Tensor = tensor;
     Position = position;
     WindSpeed = windspeed;
 }