Exemple #1
0
    public void Split(Vector3 localPlaneNormal, Vector3 localPlaneDir, Vector3 localPointStart, Vector3 localPointEnd, int faceStart, int faceEnd, bool fillCut)
    {
        Debug.LogFormat("Split Point {0} {1} Face {2} {3} Normal {4}", localPointStart, localPointEnd, faceStart, faceEnd, localPlaneNormal);

        Clear();

        planeNormal = localPlaneNormal;
        planeDir    = localPlaneDir;

        indexStart = faceStart;
        indexEnd   = faceEnd;
        pointStart = localPointStart;
        pointEnd   = localPointEnd;

        // 剪切范围
        Vector3 center = (pointEnd + pointStart) / 2f;

        if (localPlaneNormal == Vector3.zero)
        {
            localPlaneNormal = Vector3.up;
        }

        bool[] vertexAbovePlane = new bool[vertices.Count];

        for (int i = 0; i < vertices.Count; i++)
        {
            Vector3 vertex = vertices[i];

            bool abovePlane = Vector3.Dot(vertex - pointEnd, localPlaneNormal) >= 0.0f;

            vertexAbovePlane [i] = abovePlane;
        }

        // remove
        int triangleCount = indices.Count / 3;

        for (int i = 0; i < triangleCount; i++)
        {
            int index0 = indices [i * 3 + 0];
            int index1 = indices [i * 3 + 1];
            int index2 = indices [i * 3 + 2];

            bool above0 = vertexAbovePlane [index0];
            bool above1 = vertexAbovePlane [index1];
            bool above2 = vertexAbovePlane [index2];

            if ((above0 && above1 && above2) || (!above0 && !above1 && !above2))
            {
                // 保持不变
                //Debug.LogFormat(" old {0} {1} {2}", index0, index1, index2);
            }
            else
            {
                Vector3 v0 = vertices [index0];
                Vector3 v1 = vertices [index1];
                Vector3 v2 = vertices [index2];

                float a1 = Vector3.Dot(v0 - pointEnd, localPlaneNormal);
                float a2 = Vector3.Dot(v1 - pointEnd, localPlaneNormal);
                float a3 = Vector3.Dot(v2 - pointEnd, localPlaneNormal);


                // 切割点在tri上投影
                Vector3 fN    = Vector3.Cross(v1 - v0, v2 - v0).normalized;
                Vector3 projS = MathUtils.LineIntersectPlane(fN, v0, planeDir, pointStart);
                Vector3 projE = MathUtils.LineIntersectPlane(fN, v0, planeDir, pointEnd);

                bool InS = MathUtils.PointInTriangle(v0, v1, v2, projS);
                bool InE = MathUtils.PointInTriangle(v0, v1, v2, projE);

                bool b1 = MathUtils.LineIntersect(v0, v1, projS, projE);
                bool b2 = MathUtils.LineIntersect(v0, v2, projS, projE);
                bool b3 = MathUtils.LineIntersect(v1, v2, projS, projE);

                //Debug.LogFormat ("Face {0} intersection {1} {2} {3}", i, b1, b2, b3);
                if (!InS && !InE && !b1 && !b2 && !b3)
                {
                    // 不相交
                    tri_backlist.Add(i);
                }
                else
                {
                    // 检查到切割范围内?
                    float d0 = MathUtils.PointDistPlane(planeDir, center, v0);
                    float d1 = MathUtils.PointDistPlane(planeDir, center, v1);
                    float d2 = MathUtils.PointDistPlane(planeDir, center, v2);

                    if (d0 > 1 && d1 > 1 && d2 > 1)
                    {
                        tri_backlist.Add(i);
                    }
                }
            }
        }

        IList <Vector3> cutEdges;

        AssignTriangles(vertexAbovePlane, localPointStart, localPlaneNormal, out cutEdges);

        if (fillCut)
        {
            cutEdges.Clear();
            cutEdges.Add(pointStart);
            cutEdges.Add(pointStart + planeDir);
            cutEdges.Add(pointStart + planeDir);
            cutEdges.Add(pointEnd + planeDir);
            cutEdges.Add(pointEnd + planeDir);
            cutEdges.Add(pointEnd);
            cutEdges.Add(pointEnd);
            cutEdges.Add(pointStart);

            FillCutEdges(cutEdges, localPlaneNormal);
        }
        // update mesh & mass springs
        softbody.SetMesh(GetNewMesh(), _vertices1, _vertices2, _tris);
    }