示例#1
0
        /// <summary>
        /// Multiply a matrix by a scalefactor.
        /// </summary>
        /// <param name="matrix1">The matrix.</param>
        /// <param name="scaleFactor">The scale factor.</param>
        /// <returns>A JMatrix multiplied by the scale factor.</returns>
        #region public static JMatrix Multiply(JMatrix matrix1, FP scaleFactor)
        public static TSMatrix Multiply(TSMatrix matrix1, FP scaleFactor)
        {
            TSMatrix result;

            TSMatrix.Multiply(ref matrix1, scaleFactor, out result);
            return(result);
        }
示例#2
0
        /// <summary>
        /// Subtracts two matrices.
        /// </summary>
        /// <param name="value1">The first matrix.</param>
        /// <param name="value2">The second matrix.</param>
        /// <returns>The difference of both values.</returns>
        #region public static JMatrix operator -(JMatrix value1, JMatrix value2)
        public static TSMatrix operator -(TSMatrix value1, TSMatrix value2)
        {
            TSMatrix result; TSMatrix.Multiply(ref value2, -FP.One, out value2);

            TSMatrix.Add(ref value1, ref value2, out result);
            return(result);
        }
示例#3
0
        /// <summary>
        /// Gets the determinant of the matrix.
        /// </summary>
        /// <returns>The determinant of the matrix.</returns>
        #region public FP Determinant()
        //public FP Determinant()
        //{
        //    return M11 * M22 * M33 -M11 * M23 * M32 -M12 * M21 * M33 +M12 * M23 * M31 + M13 * M21 * M32 - M13 * M22 * M31;
        //}
        #endregion

        /// <summary>
        /// Multiply two matrices. Notice: matrix multiplication is not commutative.
        /// </summary>
        /// <param name="matrix1">The first matrix.</param>
        /// <param name="matrix2">The second matrix.</param>
        /// <returns>The product of both matrices.</returns>
        #region public static JMatrix Multiply(JMatrix matrix1, JMatrix matrix2)
        public static TSMatrix Multiply(TSMatrix matrix1, TSMatrix matrix2)
        {
            TSMatrix result;

            TSMatrix.Multiply(ref matrix1, ref matrix2, out result);
            return(result);
        }
示例#4
0
        /// <summary>
        /// Recalculates the axis aligned bounding box and the inertia
        /// values in world space.
        /// </summary>
        public virtual void Update()
        {
            if (isParticle)
            {
                this.inertia        = TSMatrix.Zero;
                this.invInertia     = this.invInertiaWorld = TSMatrix.Zero;
                this.invOrientation = this.orientation = TSMatrix.Identity;
                this.boundingBox    = shape.boundingBox;
                TSVector.Add(ref boundingBox.min, ref this.position, out boundingBox.min);
                TSVector.Add(ref boundingBox.max, ref this.position, out boundingBox.max);

                angularVelocity.MakeZero();
            }
            else
            {
                // Given: Orientation, Inertia
                TSMatrix.Transpose(ref orientation, out invOrientation);
                this.Shape.GetBoundingBox(ref orientation, out boundingBox);
                TSVector.Add(ref boundingBox.min, ref this.position, out boundingBox.min);
                TSVector.Add(ref boundingBox.max, ref this.position, out boundingBox.max);


                if (!isStatic)
                {
                    TSMatrix.Multiply(ref invOrientation, ref invInertia, out invInertiaWorld);
                    TSMatrix.Multiply(ref invInertiaWorld, ref orientation, out invInertiaWorld);
                }
            }
        }
        /// <summary>
        /// Called once before iteration starts.
        /// </summary>
        /// <param name="timestep">The 5simulation timestep</param>
        public override void PrepareForIteration(FP timestep)
        {
            effectiveMass = body1.invInertiaWorld + body2.invInertiaWorld;

            softnessOverDt = softness / timestep;

            effectiveMass.M11 += softnessOverDt;
            effectiveMass.M22 += softnessOverDt;
            effectiveMass.M33 += softnessOverDt;

            TSMatrix.Inverse(ref effectiveMass, out effectiveMass);

            TSMatrix orientationDifference;

            TSMatrix.Multiply(ref initialOrientation1, ref initialOrientation2, out orientationDifference);
            TSMatrix.Transpose(ref orientationDifference, out orientationDifference);

            TSMatrix q = orientationDifference * body2.invOrientation * body1.orientation;
            TSVector axis;

            FP x = q.M32 - q.M23;
            FP y = q.M13 - q.M31;
            FP z = q.M21 - q.M12;

            FP r = TSMath.Sqrt(x * x + y * y + z * z);
            FP t = q.M11 + q.M22 + q.M33;

            FP angle = FP.Atan2(r, t - 1);

            axis = new TSVector(x, y, z) * angle;

            if (r != FP.Zero)
            {
                axis = axis * (FP.One / r);
            }

            bias = axis * biasFactor * (-FP.One / timestep);

            // Apply previous frame solution as initial guess for satisfying the constraint.
            if (!body1.IsStatic)
            {
                body1.angularVelocity += TSVector.Transform(accumulatedImpulse, body1.invInertiaWorld);
            }
            if (!body2.IsStatic)
            {
                body2.angularVelocity += TSVector.Transform(-FP.One * accumulatedImpulse, body2.invInertiaWorld);
            }
        }
示例#6
0
        /// <summary>
        /// Calculates the inertia of the shape relative to the center of mass.
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="centerOfMass"></param>
        /// <param name="inertia">Returns the inertia relative to the center of mass, not to the origin</param>
        /// <returns></returns>
        #region  public static FP CalculateMassInertia(Shape shape, out JVector centerOfMass, out JMatrix inertia)
        public static FP CalculateMassInertia(Shape shape, out TSVector centerOfMass,
                                              out TSMatrix inertia)
        {
            FP mass = FP.Zero;

            centerOfMass = TSVector.zero; inertia = TSMatrix.Zero;

            if (shape is Multishape)
            {
                throw new ArgumentException("Can't calculate inertia of multishapes.", "shape");
            }

            // build a triangle hull around the shape
            List <TSVector> hullTriangles = new List <TSVector>();

            shape.MakeHull(ref hullTriangles, 3);

            // create inertia of tetrahedron with vertices at
            // (0,0,0) (1,0,0) (0,1,0) (0,0,1)
            FP       a = FP.One / (60 * FP.One), b = FP.One / (120 * FP.One);
            TSMatrix C = new TSMatrix(a, b, b, b, a, b, b, b, a);

            for (int i = 0; i < hullTriangles.Count; i += 3)
            {
                TSVector column0 = hullTriangles[i + 0];
                TSVector column1 = hullTriangles[i + 1];
                TSVector column2 = hullTriangles[i + 2];

                TSMatrix A = new TSMatrix(column0.x, column1.x, column2.x,
                                          column0.y, column1.y, column2.y,
                                          column0.z, column1.z, column2.z);

                FP detA = A.Determinant();

                // now transform this canonical tetrahedron to the target tetrahedron
                // inertia by a linear transformation A
                TSMatrix tetrahedronInertia = TSMatrix.Multiply(A * C * TSMatrix.Transpose(A), detA);

                TSVector tetrahedronCOM  = (FP.One / (4 * FP.One)) * (hullTriangles[i + 0] + hullTriangles[i + 1] + hullTriangles[i + 2]);
                FP       tetrahedronMass = (FP.One / (6 * FP.One)) * detA;

                inertia      += tetrahedronInertia;
                centerOfMass += tetrahedronMass * tetrahedronCOM;
                mass         += tetrahedronMass;
            }

            inertia      = TSMatrix.Multiply(TSMatrix.Identity, inertia.Trace()) - inertia;
            centerOfMass = centerOfMass * (FP.One / mass);

            FP x = centerOfMass.x;
            FP y = centerOfMass.y;
            FP z = centerOfMass.z;

            // now translate the inertia by the center of mass
            TSMatrix t = new TSMatrix(
                -mass * (y * y + z * z), mass * x * y, mass * x * z,
                mass * y * x, -mass * (z * z + x * x), mass * y * z,
                mass * z * x, mass * z * y, -mass * (x * x + y * y));

            TSMatrix.Add(ref inertia, ref t, out inertia);

            return(mass);
        }
示例#7
0
        /// <summary>
        /// Multiplies two matrices.
        /// </summary>
        /// <param name="value1">The first matrix.</param>
        /// <param name="value2">The second matrix.</param>
        /// <returns>The product of both values.</returns>
        #region public static JMatrix operator *(JMatrix value1,JMatrix value2)
        public static TSMatrix operator *(TSMatrix value1, TSMatrix value2)
        {
            TSMatrix result; TSMatrix.Multiply(ref value1, ref value2, out result);

            return(result);
        }
示例#8
0
 private void UpdateInvInertiaWorld()
 {
     TSMatrix.Multiply(ref invOrientation, ref invInertia, out invInertiaWorld);
     TSMatrix.Multiply(ref invInertiaWorld, ref orientation, out invInertiaWorld);
 }