示例#1
0
        public static bool ClosestPoints(ISupportMappable support1, ISupportMappable support2, ref JMatrix orientation1,
            ref JMatrix orientation2, ref JVector position1, ref JVector position2,
            out JVector p1, out JVector p2, out JVector normal)
        {
            VoronoiSimplexSolver simplexSolver = simplexSolverPool.GetNew();
            simplexSolver.Reset();

            p1 = p2 = JVector.Zero;

            JVector r = position1 - position2;
            JVector w, v;

            JVector supVertexA;
            JVector rn,vn;

            rn = JVector.Negate(r);

            SupportMapTransformed(support1, ref orientation1, ref position1, ref rn, out supVertexA);

            JVector supVertexB;
            SupportMapTransformed(support2, ref orientation2, ref position2, ref r, out supVertexB);

            v = supVertexA - supVertexB;

            normal = JVector.Zero;

            int maxIter = 15;

            float distSq = v.LengthSquared();
            float epsilon = 0.00001f;

            while ((distSq > epsilon) && (maxIter-- != 0))
            {
                vn = JVector.Negate(v);
                SupportMapTransformed(support1, ref orientation1, ref position1, ref vn, out supVertexA);
                SupportMapTransformed(support2, ref orientation2, ref position2, ref v, out supVertexB);
                w = supVertexA - supVertexB;

                if (!simplexSolver.InSimplex(w)) simplexSolver.AddVertex(w, supVertexA, supVertexB);
                if (simplexSolver.Closest(out v))
                {
                    distSq = v.LengthSquared();
                    normal = v;
                }
                else distSq = 0.0f;
            }

            simplexSolver.ComputePoints(out p1, out p2);

            if (normal.LengthSquared() > JMath.Epsilon * JMath.Epsilon)
                normal.Normalize();

            simplexSolverPool.GiveBack(simplexSolver);

            return true;
        }
示例#2
0
 public static void Absolute(ref JMatrix matrix,out JMatrix result)
 {
     result.M11 = Math.Abs(matrix.M11);
     result.M12 = Math.Abs(matrix.M12);
     result.M13 = Math.Abs(matrix.M13);
     result.M21 = Math.Abs(matrix.M21);
     result.M22 = Math.Abs(matrix.M22);
     result.M23 = Math.Abs(matrix.M23);
     result.M31 = Math.Abs(matrix.M31);
     result.M32 = Math.Abs(matrix.M32);
     result.M33 = Math.Abs(matrix.M33);
 }
示例#3
0
        /// <summary>
        /// Gets the axis aligned bounding box of the orientated shape. This includes
        /// the whole shape.
        /// </summary>
        /// <param name="orientation">The orientation of the shape.</param>
        /// <param name="box">The axis aligned bounding box of the shape.</param>
        public override void GetBoundingBox(ref JMatrix orientation, out JBBox box)
        {
            JBBox helpBox = JBBox.LargeBox;
            int length = this.Prepare(ref helpBox);

            box = JBBox.SmallBox;

            for (int i = 0; i < length; i++)
            {
                this.SetCurrentShape(i);
                base.GetBoundingBox(ref orientation, out helpBox);
                JBBox.CreateMerged(ref box, ref helpBox, out box);
            }
        }
示例#4
0
 /// <summary>
 /// Creates a quaternion from a matrix.
 /// </summary>
 /// <param name="matrix">A matrix representing an orientation.</param>
 /// <param name="result">JQuaternion representing an orientation.</param>
 public static void CreateFromMatrix(ref JMatrix matrix, out JQuaternion result)
 {
     float num8 = (matrix.M11 + matrix.M22) + matrix.M33;
     if (num8 > 0f)
     {
         float num = (float)Math.Sqrt((double)(num8 + 1f));
         result.W = num * 0.5f;
         num = 0.5f / num;
         result.X = (matrix.M23 - matrix.M32) * num;
         result.Y = (matrix.M31 - matrix.M13) * num;
         result.Z = (matrix.M12 - matrix.M21) * num;
     }
     else if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33))
     {
         float num7 = (float)Math.Sqrt((double)(((1f + matrix.M11) - matrix.M22) - matrix.M33));
         float num4 = 0.5f / num7;
         result.X = 0.5f * num7;
         result.Y = (matrix.M12 + matrix.M21) * num4;
         result.Z = (matrix.M13 + matrix.M31) * num4;
         result.W = (matrix.M23 - matrix.M32) * num4;
     }
     else if (matrix.M22 > matrix.M33)
     {
         float num6 = (float)Math.Sqrt((double)(((1f + matrix.M22) - matrix.M11) - matrix.M33));
         float num3 = 0.5f / num6;
         result.X = (matrix.M21 + matrix.M12) * num3;
         result.Y = 0.5f * num6;
         result.Z = (matrix.M32 + matrix.M23) * num3;
         result.W = (matrix.M31 - matrix.M13) * num3;
     }
     else
     {
         float num5 = (float)Math.Sqrt((double)(((1f + matrix.M33) - matrix.M11) - matrix.M22));
         float num2 = 0.5f / num5;
         result.X = (matrix.M31 + matrix.M13) * num2;
         result.Y = (matrix.M32 + matrix.M23) * num2;
         result.Z = 0.5f * num5;
         result.W = (matrix.M12 - matrix.M21) * num2;
     }
 }
示例#5
0
 public static JQuaternion CreateFromMatrix(JMatrix matrix)
 {
     JQuaternion result;
     JQuaternion.CreateFromMatrix(ref matrix, out result);
     return result;
 }
示例#6
0
 /// <summary>
 /// Multiply a matrix by a scalefactor.
 /// </summary>
 /// <param name="matrix1">The matrix.</param>
 /// <param name="scaleFactor">The scale factor.</param>
 /// <param name="result">A JMatrix multiplied by the scale factor.</param>
 public static void Multiply(ref JMatrix matrix1, float scaleFactor, out JMatrix result)
 {
     float num = scaleFactor;
     result.M11 = matrix1.M11 * num;
     result.M12 = matrix1.M12 * num;
     result.M13 = matrix1.M13 * num;
     result.M21 = matrix1.M21 * num;
     result.M22 = matrix1.M22 * num;
     result.M23 = matrix1.M23 * num;
     result.M31 = matrix1.M31 * num;
     result.M32 = matrix1.M32 * num;
     result.M33 = matrix1.M33 * num;
 }
示例#7
0
        /// <summary>
        /// Transforms the bounding box into the space given by orientation and position.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="orientation"></param>
        /// <param name="result"></param>
        internal void InverseTransform(ref JVector position, ref JMatrix orientation)
        {
            JVector.Subtract(ref Max, ref position, out Max);
            JVector.Subtract(ref Min, ref position, out Min);

            JVector center;
            JVector.Add(ref Max, ref Min, out center);
            center.X *= 0.5f; center.Y *= 0.5f; center.Z *= 0.5f;

            JVector halfExtents;
            JVector.Subtract(ref Max, ref Min, out halfExtents);
            halfExtents.X *= 0.5f; halfExtents.Y *= 0.5f; halfExtents.Z *= 0.5f;

            JVector.TransposedTransform(ref center, ref orientation, out center);

            JMatrix abs; JMath.Absolute(ref orientation, out abs);
            JVector.TransposedTransform(ref halfExtents, ref abs, out halfExtents);

            JVector.Add(ref center, ref halfExtents, out Max);
            JVector.Subtract(ref center, ref halfExtents, out Min);
        }
示例#8
0
 /// <summary>
 /// Creates the transposed matrix.
 /// </summary>
 /// <param name="matrix">The matrix which should be transposed.</param>
 /// <param name="result">The transposed JMatrix.</param>
 public static void Transpose(ref JMatrix matrix, out JMatrix result)
 {
     result.M11 = matrix.M11;
     result.M12 = matrix.M21;
     result.M13 = matrix.M31;
     result.M21 = matrix.M12;
     result.M22 = matrix.M22;
     result.M23 = matrix.M32;
     result.M31 = matrix.M13;
     result.M32 = matrix.M23;
     result.M33 = matrix.M33;
 }
示例#9
0
        private static void SupportMapTransformed(ISupportMappable support, ref JMatrix orientation, ref JVector position, ref JVector direction, out JVector result)
        {
            //JVector.Transform(ref direction, ref invOrientation, out result);
            //support.SupportMapping(ref result, out result);
            //JVector.Transform(ref result, ref orientation, out result);
            //JVector.Add(ref result, ref position, out result);

            result.X = ((direction.X * orientation.M11) + (direction.Y * orientation.M12)) + (direction.Z * orientation.M13);
            result.Y = ((direction.X * orientation.M21) + (direction.Y * orientation.M22)) + (direction.Z * orientation.M23);
            result.Z = ((direction.X * orientation.M31) + (direction.Y * orientation.M32)) + (direction.Z * orientation.M33);

            support.SupportMapping(ref result, out result);

            float x = ((result.X * orientation.M11) + (result.Y * orientation.M21)) + (result.Z * orientation.M31);
            float y = ((result.X * orientation.M12) + (result.Y * orientation.M22)) + (result.Z * orientation.M32);
            float z = ((result.X * orientation.M13) + (result.Y * orientation.M23)) + (result.Z * orientation.M33);

            result.X = position.X + x;
            result.Y = position.Y + y;
            result.Z = position.Z + z;
        }
示例#10
0
        /// <summary>
        /// Checks if given point is within a shape.
        /// </summary>
        /// <param name="support">The supportmap implementation representing the shape.</param>
        /// <param name="orientation">The orientation of the shape.</param>
        /// <param name="invOrientation">The inverse orientation of the shape.</param>
        /// <param name="position">The position of the shape.</param>
        /// <param name="point">The point to check.</param>
        /// <returns>Returns true if the point is within the shape, otherwise false.</returns>
        public static bool Pointcast(ISupportMappable support, ref JMatrix orientation,ref JVector position,ref JVector point)
        {
            JVector arbitraryPoint;

            SupportMapTransformed(support, ref orientation, ref position, ref point, out arbitraryPoint);
            JVector.Subtract(ref point, ref arbitraryPoint, out arbitraryPoint);

            JVector r; support.SupportCenter(out r);
            JVector.Transform(ref r, ref orientation, out r);
            JVector.Add(ref position, ref r, out r);
            JVector.Subtract(ref point, ref r, out r);

            JVector x = point;
            JVector w, p;
            float VdotR;

            JVector v; JVector.Subtract(ref x, ref arbitraryPoint, out v);
            float dist = v.LengthSquared();
            float epsilon = 0.0001f;

            int maxIter = MaxIterations;

            VoronoiSimplexSolver simplexSolver = simplexSolverPool.GetNew();

            simplexSolver.Reset();

            while ((dist > epsilon) && (maxIter-- != 0))
            {
                SupportMapTransformed(support, ref orientation, ref position, ref v, out p);
                JVector.Subtract(ref x, ref p, out w);

                float VdotW = JVector.Dot(ref v, ref w);

                if (VdotW > 0.0f)
                {
                    VdotR = JVector.Dot(ref v, ref r);

                    if (VdotR >= -(JMath.Epsilon * JMath.Epsilon)) { simplexSolverPool.GiveBack(simplexSolver); return false; }
                    else simplexSolver.Reset();
                }
                if (!simplexSolver.InSimplex(w)) simplexSolver.AddVertex(w, x, p);

                if (simplexSolver.Closest(out v)) dist = v.LengthSquared();
                else dist = 0.0f;
            }

            simplexSolverPool.GiveBack(simplexSolver);
            return true;
        }
示例#11
0
        /// <summary>
        /// Uses the supportMapping to calculate the bounding box. Should be overidden
        /// to make this faster.
        /// </summary>
        /// <param name="orientation">The orientation of the shape.</param>
        /// <param name="box">The resulting axis aligned bounding box.</param>
        public virtual void GetBoundingBox(ref JMatrix orientation, out JBBox box)
        {
            // I don't think that this can be done faster.
            // 6 is the minimum number of SupportMap calls.

            JVector vec = JVector.Zero;

            vec.Set(orientation.M11, orientation.M21, orientation.M31);
            SupportMapping(ref vec, out vec);
            box.Max.X = orientation.M11 * vec.X + orientation.M21 * vec.Y + orientation.M31 * vec.Z;

            vec.Set(orientation.M12, orientation.M22, orientation.M32);
            SupportMapping(ref vec, out vec);
            box.Max.Y = orientation.M12 * vec.X + orientation.M22 * vec.Y + orientation.M32 * vec.Z;

            vec.Set(orientation.M13, orientation.M23, orientation.M33);
            SupportMapping(ref vec, out vec);
            box.Max.Z = orientation.M13 * vec.X + orientation.M23 * vec.Y + orientation.M33 * vec.Z;

            vec.Set(-orientation.M11, -orientation.M21, -orientation.M31);
            SupportMapping(ref vec, out vec);
            box.Min.X = orientation.M11 * vec.X + orientation.M21 * vec.Y + orientation.M31 * vec.Z;

            vec.Set(-orientation.M12, -orientation.M22, -orientation.M32);
            SupportMapping(ref vec, out vec);
            box.Min.Y = orientation.M12 * vec.X + orientation.M22 * vec.Y + orientation.M32 * vec.Z;

            vec.Set(-orientation.M13, -orientation.M23, -orientation.M33);
            SupportMapping(ref vec, out vec);
            box.Min.Z = orientation.M13 * vec.X + orientation.M23 * vec.Y + orientation.M33 * vec.Z;
        }
示例#12
0
        public static float CalculateMassInertia(Shape shape, out JVector centerOfMass,
            out JMatrix inertia)
        {
            float mass = 0.0f;
            centerOfMass = JVector.Zero; inertia = JMatrix.Zero;

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

            // build a triangle hull around the shape
            List<JVector> hullTriangles = new List<JVector>();
            shape.MakeHull(ref hullTriangles, 3);

            // create inertia of tetrahedron with vertices at
            // (0,0,0) (1,0,0) (0,1,0) (0,0,1)
            float a = 1.0f / 60.0f, b = 1.0f / 120.0f;
            JMatrix C = new JMatrix(a, b, b, b, a, b, b, b, a);

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

                JMatrix A = new JMatrix(column0.X, column1.X, column2.X,
                    column0.Y, column1.Y, column2.Y,
                    column0.Z, column1.Z, column2.Z);

                float detA = A.Determinant();

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

                JVector tetrahedronCOM = (1.0f / 4.0f) * (hullTriangles[i + 0] + hullTriangles[i + 1] + hullTriangles[i + 2]);
                float tetrahedronMass = (1.0f / 6.0f) * detA;

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

            inertia = JMatrix.Multiply(JMatrix.Identity, inertia.Trace()) - inertia;
            centerOfMass = centerOfMass * (1.0f / mass);

            float x = centerOfMass.X;
            float y = centerOfMass.Y;
            float z = centerOfMass.Z;

            // now translate the inertia by the center of mass
            JMatrix t = new JMatrix(
                -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));

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

            return mass;
        }
示例#13
0
        /// <summary>
        /// Checks two shapes for collisions.
        /// </summary>
        /// <param name="support1">The SupportMappable implementation of the first shape to test.</param>
        /// <param name="support2">The SupportMappable implementation of the seconds shape to test.</param>
        /// <param name="orientation1">The orientation of the first shape.</param>
        /// <param name="orientation2">The orientation of the second shape.</param>
        /// <param name="position1">The position of the first shape.</param>
        /// <param name="position2">The position of the second shape</param>
        /// <param name="point">The pointin world coordinates, where collision occur.</param>
        /// <param name="normal">The normal pointing from body2 to body1.</param>
        /// <param name="penetration">Estimated penetration depth of the collision.</param>
        /// <returns>Returns true if there is a collision, false otherwise.</returns>
        public static bool Detect(ISupportMappable support1, ISupportMappable support2, ref JMatrix orientation1,
             ref JMatrix orientation2, ref JVector position1, ref JVector position2,
             out JVector point, out JVector normal, out float penetration)
        {
            // Used variables
            JVector temp1, temp2;
            JVector v01, v02, v0;
            JVector v11, v12, v1;
            JVector v21, v22, v2;
            JVector v31, v32, v3;
            JVector v41, v42, v4;
            JVector mn;

            // Initialization of the output
            point = normal = JVector.Zero;
            penetration = 0.0f;

            //JVector right = JVector.Right;

            // Get the center of shape1 in world coordinates -> v01
            support1.SupportCenter(out v01);
            JVector.Transform(ref v01, ref orientation1, out v01);
            JVector.Add(ref position1, ref v01, out v01);

            // Get the center of shape2 in world coordinates -> v02
            support2.SupportCenter(out v02);
            JVector.Transform(ref v02, ref orientation2, out v02);
            JVector.Add(ref position2, ref v02, out v02);

            // v0 is the center of the minkowski difference
            JVector.Subtract(ref v02, ref v01, out v0);

            // Avoid case where centers overlap -- any direction is fine in this case
            if (v0.IsNearlyZero()) v0 = new JVector(0.00001f, 0, 0);

            // v1 = support in direction of origin
            mn = v0;
            JVector.Negate(ref v0, out normal);

            SupportMapTransformed(support1, ref orientation1, ref position1, ref mn, out v11);
            SupportMapTransformed(support2, ref orientation2, ref position2, ref normal, out v12);
            JVector.Subtract(ref v12, ref v11, out v1);

            if (JVector.Dot(ref v1, ref normal) <= 0.0f) return false;

            // v2 = support perpendicular to v1,v0
            JVector.Cross(ref v1, ref v0, out normal);

            if (normal.IsNearlyZero())
            {
                JVector.Subtract(ref v1, ref v0, out normal);

                normal.Normalize();

                point = v11;
                JVector.Add(ref point, ref v12, out point);
                JVector.Multiply(ref point, 0.5f, out point);

                JVector.Subtract(ref v12, ref v11, out temp1);
                penetration = JVector.Dot(ref temp1, ref normal);

                //point = v11;
                //point2 = v12;
                return true;
            }

            JVector.Negate(ref normal, out mn);
            SupportMapTransformed(support1, ref orientation1, ref position1, ref mn, out v21);
            SupportMapTransformed(support2, ref orientation2, ref position2, ref normal, out v22);
            JVector.Subtract(ref v22, ref v21, out v2);

            if (JVector.Dot(ref v2, ref normal) <= 0.0f) return false;

            // Determine whether origin is on + or - side of plane (v1,v0,v2)
            JVector.Subtract(ref v1, ref v0, out temp1);
            JVector.Subtract(ref v2, ref v0, out temp2);
            JVector.Cross(ref temp1, ref temp2, out normal);

            float dist = JVector.Dot(ref normal, ref v0);

            // If the origin is on the - side of the plane, reverse the direction of the plane
            if (dist > 0.0f)
            {
                JVector.Swap(ref v1, ref v2);
                JVector.Swap(ref v11, ref v21);
                JVector.Swap(ref v12, ref v22);
                JVector.Negate(ref normal, out normal);
            }

            int phase2 = 0;
            int phase1 = 0;
            bool hit = false;

            // Phase One: Identify a portal
            while (true)
            {
                if (phase1 > MaximumIterations) return false;

                phase1++;

                // Obtain the support point in a direction perpendicular to the existing plane
                // Note: This point is guaranteed to lie off the plane
                JVector.Negate(ref normal, out mn);
                SupportMapTransformed(support1, ref orientation1, ref position1, ref mn, out v31);
                SupportMapTransformed(support2, ref orientation2, ref position2, ref normal, out v32);
                JVector.Subtract(ref v32, ref v31, out v3);

                if (JVector.Dot(ref v3, ref normal) <= 0.0f)
                {
                    return false;
                }

                // If origin is outside (v1,v0,v3), then eliminate v2 and loop
                JVector.Cross(ref v1, ref v3, out temp1);
                if (JVector.Dot(ref temp1, ref v0) < 0.0f)
                {
                    v2 = v3;
                    v21 = v31;
                    v22 = v32;
                    JVector.Subtract(ref v1, ref v0, out temp1);
                    JVector.Subtract(ref v3, ref v0, out temp2);
                    JVector.Cross(ref temp1, ref temp2, out normal);
                    continue;
                }

                // If origin is outside (v3,v0,v2), then eliminate v1 and loop
                JVector.Cross(ref v3, ref v2, out temp1);
                if (JVector.Dot(ref temp1, ref v0) < 0.0f)
                {
                    v1 = v3;
                    v11 = v31;
                    v12 = v32;
                    JVector.Subtract(ref v3, ref v0, out temp1);
                    JVector.Subtract(ref v2, ref v0, out temp2);
                    JVector.Cross(ref temp1, ref temp2, out normal);
                    continue;
                }

                // Phase Two: Refine the portal
                // We are now inside of a wedge...
                while (true)
                {
                    phase2++;

                    // Compute normal of the wedge face
                    JVector.Subtract(ref v2, ref v1, out temp1);
                    JVector.Subtract(ref v3, ref v1, out temp2);
                    JVector.Cross(ref temp1, ref temp2, out normal);

                    // Can this happen???  Can it be handled more cleanly?
                    if (normal.IsNearlyZero()) return true;

                    normal.Normalize();

                    // Compute distance from origin to wedge face
                    float d = JVector.Dot(ref normal, ref v1);

                    // If the origin is inside the wedge, we have a hit
                    if (d >= 0 && !hit)
                    {
                        // HIT!!!
                        hit = true;
                    }

                    // Find the support point in the direction of the wedge face
                    JVector.Negate(ref normal, out mn);
                    SupportMapTransformed(support1, ref orientation1, ref position1, ref mn, out v41);
                    SupportMapTransformed(support2, ref orientation2, ref position2, ref normal, out v42);
                    JVector.Subtract(ref v42, ref v41, out v4);

                    JVector.Subtract(ref v4, ref v3, out temp1);
                    float delta = JVector.Dot(ref temp1, ref normal);
                    penetration = JVector.Dot(ref v4, ref normal);

                    // If the boundary is thin enough or the origin is outside the support plane for the newly discovered vertex, then we can terminate
                    if (delta <= CollideEpsilon || penetration <= 0.0f || phase2 > MaximumIterations)
                    {

                        if (hit)
                        {
                            JVector.Cross(ref v1, ref v2, out temp1);
                            float b0 = JVector.Dot(ref temp1, ref v3);
                            JVector.Cross(ref v3, ref v2, out temp1);
                            float b1 = JVector.Dot(ref temp1, ref v0);
                            JVector.Cross(ref v0, ref v1, out temp1);
                            float b2 = JVector.Dot(ref temp1, ref v3);
                            JVector.Cross(ref v2, ref v1, out temp1);
                            float b3 = JVector.Dot(ref temp1, ref v0);

                            float sum = b0 + b1 + b2 + b3;

                            if (sum <= 0)
                            {
                                b0 = 0;
                                JVector.Cross(ref v2, ref v3, out temp1);
                                b1 = JVector.Dot(ref temp1, ref normal);
                                JVector.Cross(ref v3, ref v1, out temp1);
                                b2 = JVector.Dot(ref temp1, ref normal);
                                JVector.Cross(ref v1, ref v2, out temp1);
                                b3 = JVector.Dot(ref temp1, ref normal);

                                sum = b1 + b2 + b3;
                            }

                            float inv = 1.0f / sum;

                            JVector.Multiply(ref v01, b0, out point);
                            JVector.Multiply(ref v11, b1, out temp1);
                            JVector.Add(ref point, ref temp1, out point);
                            JVector.Multiply(ref v21, b2, out temp1);
                            JVector.Add(ref point, ref temp1, out point);
                            JVector.Multiply(ref v31, b3, out temp1);
                            JVector.Add(ref point, ref temp1, out point);

                            JVector.Multiply(ref v02, b0, out temp2);
                            JVector.Add(ref temp2, ref point, out point);
                            JVector.Multiply(ref v12, b1, out temp1);
                            JVector.Add(ref point, ref temp1, out point);
                            JVector.Multiply(ref v22, b2, out temp1);
                            JVector.Add(ref point, ref temp1, out point);
                            JVector.Multiply(ref v32, b3, out temp1);
                            JVector.Add(ref point, ref temp1, out point);

                            JVector.Multiply(ref point, inv * 0.5f, out point);

                        }

                        // Compute the barycentric coordinates of the origin
                        return hit;
                    }

                    ////// Compute the tetrahedron dividing face (v4,v0,v1)
                    //JVector.Cross(ref v4, ref v1, out temp1);
                    //float d1 = JVector.Dot(ref temp1, ref v0);

                    ////// Compute the tetrahedron dividing face (v4,v0,v2)
                    //JVector.Cross(ref v4, ref v2, out temp1);
                    //float d2 = JVector.Dot(ref temp1, ref v0);

                    // Compute the tetrahedron dividing face (v4,v0,v3)
                    JVector.Cross(ref v4, ref v0, out temp1);
                    float dot = JVector.Dot(ref temp1, ref v1);

                    if (dot >= 0.0f)
                    {
                        dot = JVector.Dot(ref temp1, ref v2);

                        if (dot >= 0.0f)
                        {
                            // Inside d1 & inside d2 ==> eliminate v1
                            v1 = v4;
                            v11 = v41;
                            v12 = v42;
                        }
                        else
                        {
                            // Inside d1 & outside d2 ==> eliminate v3
                            v3 = v4;
                            v31 = v41;
                            v32 = v42;
                        }
                    }
                    else
                    {
                        dot = JVector.Dot(ref temp1, ref v3);

                        if (dot >= 0.0f)
                        {
                            // Outside d1 & inside d3 ==> eliminate v2
                            v2 = v4;
                            v21 = v41;
                            v22 = v42;
                        }
                        else
                        {
                            // Outside d1 & outside d3 ==> eliminate v1
                            v1 = v4;
                            v11 = v41;
                            v12 = v42;
                        }
                    }

                }
            }
        }
示例#14
0
        private static void SupportMapTransformed(ISupportMappable support,
            ref JMatrix orientation, ref JVector position, ref JVector direction, out JVector result)
        {
            // THIS IS *THE* HIGH FREQUENCY CODE OF THE COLLLISION PART OF THE ENGINE

            result.X = ((direction.X * orientation.M11) + (direction.Y * orientation.M12)) + (direction.Z * orientation.M13);
            result.Y = ((direction.X * orientation.M21) + (direction.Y * orientation.M22)) + (direction.Z * orientation.M23);
            result.Z = ((direction.X * orientation.M31) + (direction.Y * orientation.M32)) + (direction.Z * orientation.M33);

            support.SupportMapping(ref result, out result);

            float x = ((result.X * orientation.M11) + (result.Y * orientation.M21)) + (result.Z * orientation.M31);
            float y = ((result.X * orientation.M12) + (result.Y * orientation.M22)) + (result.Z * orientation.M32);
            float z = ((result.X * orientation.M13) + (result.Y * orientation.M23)) + (result.Z * orientation.M33);

            result.X = position.X + x;
            result.Y = position.Y + y;
            result.Z = position.Z + z;
        }
示例#15
0
        /// <summary>
        /// Transforms a vector by the transposed of the given Matrix.
        /// </summary>
        /// <param name="position">The vector to transform.</param>
        /// <param name="matrix">The transform matrix.</param>
        /// <param name="result">The transformed vector.</param>
        public static void TransposedTransform(ref JVector position, ref JMatrix matrix, out JVector result)
        {
            float num0 = ((position.X * matrix.M11) + (position.Y * matrix.M12)) + (position.Z * matrix.M31);
            float num1 = ((position.X * matrix.M21) + (position.Y * matrix.M22)) + (position.Z * matrix.M23);
            float num2 = ((position.X * matrix.M31) + (position.Y * matrix.M32)) + (position.Z * matrix.M33);

            result.X = num0;
            result.Y = num1;
            result.Z = num2;
        }
示例#16
0
 public static JVector Transform(JVector position, JMatrix matrix)
 {
     JVector result;
     JVector.Transform(ref position, ref matrix, out result);
     return result;
 }
示例#17
0
        static JMatrix()
        {
            Zero = new JMatrix();

            Identity = new JMatrix();
            Identity.M11 = 1.0f;
            Identity.M22 = 1.0f;
            Identity.M33 = 1.0f;

            InternalIdentity = Identity;
        }
示例#18
0
        /// <summary>
        /// Gets the axis aligned bounding box of the orientated shape. This includes
        /// the whole shape.
        /// </summary>
        /// <param name="orientation">The orientation of the shape.</param>
        /// <param name="box">The axis aligned bounding box of the shape.</param>
        public override void GetBoundingBox(ref JMatrix orientation, out JBBox box)
        {
            box = boundings;

            #region Expand Spherical
            box.Min.X -= sphericalExpansion;
            box.Min.Y -= sphericalExpansion;
            box.Min.Z -= sphericalExpansion;
            box.Max.X += sphericalExpansion;
            box.Max.Y += sphericalExpansion;
            box.Max.Z += sphericalExpansion;
            #endregion

            box.Transform(ref orientation);
        }
示例#19
0
 public void Rotate(JMatrix orientation, JVector center)
 {
     for (int i = 0; i < points.Count; i++)
     {
         points[i].position = JVector.Transform(points[i].position - center, orientation);
     }
 }
示例#20
0
        /// <summary>
        /// Constraints two bodies to always have the same relative
        /// orientation to each other. Combine the AngleConstraint with a PointOnLine
        /// Constraint to get a prismatic joint.
        /// </summary>
        public FixedAngle(RigidBody body1, RigidBody body2)
            : base(body1, body2)
        {
            initialOrientation1 = body1.orientation;
            initialOrientation2 = body2.orientation;

            //orientationDifference = body1.orientation * body2.invOrientation;
            //orientationDifference = JMatrix.Transpose(orientationDifference);
        }
示例#21
0
        // see: btSubSimplexConvexCast.cpp
        /// <summary>
        /// Checks if a ray definied through it's origin and direction collides
        /// with a shape.
        /// </summary>
        /// <param name="support">The supportmap implementation representing the shape.</param>
        /// <param name="orientation">The orientation of the shape.</param>
        /// <param name="invOrientation">The inverse orientation of the shape.</param>
        /// <param name="position">The position of the shape.</param>
        /// <param name="origin">The origin of the ray.</param>
        /// <param name="direction">The direction of the ray.</param>
        /// <param name="fraction">The fraction which gives information where at the 
        /// ray the collision occured. The hitPoint is calculated by: origin+friction*direction.</param>
        /// <param name="normal">The normal from the ray collision.</param>
        /// <returns>Returns true if the ray hit the shape, false otherwise.</returns>
        public static bool Raycast(ISupportMappable support, ref JMatrix orientation, ref JMatrix invOrientation,
            ref JVector position,ref JVector origin,ref JVector direction, out float fraction, out JVector normal)
        {
            VoronoiSimplexSolver simplexSolver = simplexSolverPool.GetNew();
            simplexSolver.Reset();

            normal = JVector.Zero;
            fraction = float.MaxValue;

            float lambda = 0.0f;

            JVector r = direction;
            JVector x = origin;
            JVector w, p, v;

            JVector arbitraryPoint;
            SupportMapTransformed(support, ref orientation, ref position, ref r, out arbitraryPoint);
            JVector.Subtract(ref x, ref arbitraryPoint, out v);

            int maxIter = MaxIterations;

            float distSq = v.LengthSquared();
            float epsilon = 0.000001f;

            float VdotR;

            while ((distSq > epsilon) && (maxIter-- != 0))
            {
                SupportMapTransformed(support, ref orientation, ref position, ref v, out p);
                JVector.Subtract(ref x, ref p, out w);

                float VdotW = JVector.Dot(ref v, ref w);

                if (VdotW > 0.0f)
                {
                    VdotR = JVector.Dot(ref v, ref r);

                    if (VdotR >= -JMath.Epsilon)
                    {
                        simplexSolverPool.GiveBack(simplexSolver);
                        return false;
                    }
                    else
                    {
                        lambda = lambda - VdotW / VdotR;
                        JVector.Multiply(ref r, lambda, out x);
                        JVector.Add(ref origin, ref x, out x);
                        JVector.Subtract(ref x, ref p, out w);
                        normal = v;
                    }
                }
                if (!simplexSolver.InSimplex(w)) simplexSolver.AddVertex(w, x, p);
                if (simplexSolver.Closest(out v)) { distSq = v.LengthSquared();  }
                else distSq = 0.0f;
            }

            #region Retrieving hitPoint

            // Giving back the fraction like this *should* work
            // but is inaccurate against large objects:
            // fraction = lambda;

            JVector p1, p2;
            simplexSolver.ComputePoints(out p1, out p2);

            p2 = p2 - origin;
            fraction = p2.Length() / direction.Length();

            #endregion

            if (normal.LengthSquared() > JMath.Epsilon * JMath.Epsilon)
                normal.Normalize();

            simplexSolverPool.GiveBack(simplexSolver);

            return true;
        }
示例#22
0
 /// <summary>
 /// Creates a new instance of the TransformedShape struct.
 /// </summary>
 /// <param name="shape">The shape.</param>
 /// <param name="orientation">The orientation this shape should have.</param>
 /// <param name="position">The position this shape should have.</param>
 public TransformedShape(Shape shape, JMatrix orientation, JVector position)
 {
     this.position = position;
     this.orientation = orientation;
     JMatrix.Transpose(ref orientation, out invOrientation);
     this.shape = shape;
     this.boundingBox = new JBBox();
     UpdateBoundingBox();
 }
示例#23
0
        /// <summary>
        /// Gets the axis aligned bounding box of the orientated shape.
        /// </summary>
        /// <param name="orientation">The orientation of the shape.</param>
        /// <param name="box">The axis aligned bounding box of the shape.</param>
        public override void GetBoundingBox(ref JMatrix orientation, out JBBox box)
        {
            JMatrix abs; JMath.Absolute(ref orientation, out abs);
            JVector temp;
            JVector.Transform(ref halfSize, ref abs, out temp);

            box.Max = temp;
            JVector.Negate(ref temp, out box.Min);
        }
示例#24
0
 public static JMatrix Transpose(JMatrix matrix)
 {
     JMatrix result;
     JMatrix.Transpose(ref matrix, out result);
     return result;
 }
示例#25
0
        /// <summary>
        /// Gets the axis aligned bounding box of the orientated shape. (Inlcuding all
        /// 'sub' shapes)
        /// </summary>
        /// <param name="orientation">The orientation of the shape.</param>
        /// <param name="box">The axis aligned bounding box of the shape.</param>
        public override void GetBoundingBox(ref JMatrix orientation, out JBBox box)
        {
            box.Min = mInternalBBox.Min;
            box.Max = mInternalBBox.Max;

            JVector localHalfExtents = 0.5f * (box.Max - box.Min);
            JVector localCenter = 0.5f * (box.Max + box.Min);

            JVector center;
            JVector.Transform(ref localCenter, ref orientation, out center);

            JMatrix abs; JMath.Absolute(ref orientation, out abs);
            JVector temp;
            JVector.Transform(ref localHalfExtents, ref abs, out temp);

            box.Max = center + temp;
            box.Min = center - temp;
        }
示例#26
0
 /// <summary>
 /// Calculates the bounding box of the sphere.
 /// </summary>
 /// <param name="orientation">The orientation of the shape.</param>
 /// <param name="box">The resulting axis aligned bounding box.</param>
 public override void GetBoundingBox(ref JMatrix orientation, out JBBox box)
 {
     box.Min.X = -radius;
     box.Min.Y = -radius;
     box.Min.Z = -radius;
     box.Max.X = radius;
     box.Max.Y = radius;
     box.Max.Z = radius;
 }
示例#27
0
        public void Transform(ref JMatrix orientation)
        {
            JVector halfExtents = 0.5f * (Max - Min);
            JVector center = 0.5f * (Max + Min);

            JVector.Transform(ref center, ref orientation, out center);

            JMatrix abs; JMath.Absolute(ref orientation, out abs);
            JVector.Transform(ref halfExtents, ref abs, out halfExtents);

            Max = center + halfExtents;
            Min = center - halfExtents;
        }
示例#28
0
        /// <summary>
        /// Called once before iteration starts.
        /// </summary>
        /// <param name="timestep">The 5simulation timestep</param>
        public override void PrepareForIteration(float timestep)
        {
            effectiveMass = body1.invInertiaWorld;

            softnessOverDt = softness / timestep;

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

            JMatrix.Inverse(ref effectiveMass, out effectiveMass);

            JMatrix q = JMatrix.Transpose(orientation) * body1.orientation;
            JVector axis;

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

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

            float angle = (float)Math.Atan2(r, t - 1);
            axis = new JVector(x, y, z) * angle;

            if (r != 0.0f) axis = axis * (1.0f / r);

            bias = axis * biasFactor * (-1.0f / timestep);

            // Apply previous frame solution as initial guess for satisfying the constraint.
            if (!body1.IsStatic) body1.angularVelocity += JVector.Transform(accumulatedImpulse, body1.invInertiaWorld);
        }
示例#29
0
 /// <summary>
 /// Constraints two bodies to always have the same relative
 /// orientation to each other. Combine the AngleConstraint with a PointOnLine
 /// Constraint to get a prismatic joint.
 /// </summary>
 public FixedAngle(RigidBody body1)
     : base(body1, null)
 {
     orientation = body1.orientation;
 }
示例#30
0
 public static JMatrix Multiply(JMatrix matrix1, float scaleFactor)
 {
     JMatrix result;
     JMatrix.Multiply(ref matrix1, scaleFactor, out result);
     return result;
 }