public static bool RayIntersectsTriangle(Vector3 origin,
                                                 Vector3 dir,
                                                 Vector3 vert0,
                                                 Vector3 vert1,
                                                 Vector3 vert2,
                                                 ref float distance,
                                                 ref Vector3 normal)
        {
            float det;

            ObiVectorMath.Subtract(vert0, vert1, ref tv1);
            ObiVectorMath.Subtract(vert0, vert2, ref tv2);

            ObiVectorMath.Cross(dir, tv2, ref tv4);
            det = Vector3.Dot(tv1, tv4);

            if (det < Mathf.Epsilon)
            {
                return(false);
            }

            ObiVectorMath.Subtract(vert0, origin, ref tv3);

            float u = Vector3.Dot(tv3, tv4);

            if (u < 0f || u > det)
            {
                return(false);
            }

            ObiVectorMath.Cross(tv3, tv1, ref tv4);

            float v = Vector3.Dot(dir, tv4);

            if (v < 0f || u + v > det)
            {
                return(false);
            }

            distance = Vector3.Dot(tv2, tv4) * (1f / det);
            ObiVectorMath.Cross(tv1, tv2, ref normal);

            return(true);
        }
        public void UpdateSkinning(ObiActor actor)
        {
            GetSlaveMeshIfNeeded();
            ObiClothBase masterCloth = m_Master.GetComponent <ObiClothBase>();

            if (skinMap.bound && slaveMesh != null && masterCloth.isLoaded)
            {
                var solver = masterCloth.solver;

                Matrix4x4 s2l;
                if (gameObject == m_Master.gameObject)
                {
                    s2l = m_Master.renderMatrix * solver.transform.localToWorldMatrix;
                }
                else
                {
                    s2l = transform.worldToLocalMatrix * solver.transform.localToWorldMatrix;
                }

                slavePositions = slaveMesh.vertices;
                slaveNormals   = slaveMesh.normals;
                slaveTangents  = slaveMesh.tangents;

                Vector3 skinnedPos     = Vector3.zero;
                Vector3 skinnedNormal  = Vector3.zero;
                Vector3 skinnedTangent = Vector3.zero;

                for (int i = 0; i < skinMap.skinnedVertices.Count; ++i)
                {
                    var data        = skinMap.skinnedVertices[i];
                    int firstVertex = data.masterTriangleIndex;

                    int t1 = masterCloth.clothBlueprintBase.deformableTriangles[firstVertex];
                    int t2 = masterCloth.clothBlueprintBase.deformableTriangles[firstVertex + 1];
                    int t3 = masterCloth.clothBlueprintBase.deformableTriangles[firstVertex + 2];

                    // get solver indices for each particle:
                    int s1 = masterCloth.solverIndices[t1];
                    int s2 = masterCloth.solverIndices[t2];
                    int s3 = masterCloth.solverIndices[t3];

                    // get master particle positions/normals:
                    Vector3 p1 = solver.renderablePositions[s1];
                    Vector3 p2 = solver.renderablePositions[s2];
                    Vector3 p3 = solver.renderablePositions[s3];

                    Vector3 n1 = solver.normals[s1];
                    Vector3 n2 = solver.normals[s2];
                    Vector3 n3 = solver.normals[s3];

                    ObiVectorMath.BarycentricInterpolation(p1, p2, p3, n1, n2, n3, data.position.barycentricCoords, data.position.height, ref skinnedPos);

                    ObiVectorMath.BarycentricInterpolation(p1, p2, p3, n1, n2, n3, data.normal.barycentricCoords, data.normal.height, ref skinnedNormal);

                    ObiVectorMath.BarycentricInterpolation(p1, p2, p3, n1, n2, n3, data.tangent.barycentricCoords, data.tangent.height, ref skinnedTangent);

                    // update slave data arrays:
                    slavePositions[data.slaveIndex] = s2l.MultiplyPoint3x4(skinnedPos);
                    slaveNormals[data.slaveIndex]   = s2l.MultiplyVector(skinnedNormal - skinnedPos);

                    Vector3 tangent = s2l.MultiplyVector(skinnedTangent - skinnedPos);
                    slaveTangents[data.slaveIndex] = new Vector4(tangent.x, tangent.y, tangent.z, slaveTangents[data.slaveIndex].w);
                }

                slaveMesh.vertices = slavePositions;
                slaveMesh.normals  = slaveNormals;
                slaveMesh.tangents = slaveTangents;
                slaveMesh.RecalculateBounds();
            }
        }