按平面拼接网格

时间:2016-01-20 05:21:28

标签: unity3d mesh

我尝试通过相交平面拼接网格,但得到错误的结果。 我的代码(我按平面切割网格,从平面正面或负面计算钙面,然后在separte数组中创建相应的顶点(负面和正面),如果三角形属于两边,那么我计算交叉点并构建新的三角形:

public void SliceIt()
{
    Mesh mesh = GetComponent<MeshFilter>().sharedMesh;
    gameObject.name = "v1";

    Vector3[] vertices = mesh.vertices;

    Mesh cutplanemesh = cutplane.GetComponent<MeshFilter>().sharedMesh;
    Vector3[] cutplanevertices = cutplanemesh.vertices;

    p1 = cutplane.TransformPoint(cutplanevertices[40]);
    p2 = cutplane.TransformPoint(cutplanevertices[20]);
    p3 = cutplane.TransformPoint(cutplanevertices[0]);
    var myplane = new Plane(p1, p2, p3);


    Vector3[] vertics = mesh.vertices;
    int[] triangles = mesh.triangles;
    var side = new bool[vertics.Length];
    for (var i = vertics.Length - 1; i >= 0; i--)
    {
        vertics[i] = transform.TransformPoint(vertics[i]);
        side[i] = myplane.GetSide((vertics[i]));
    }
    var verticsPositive = new List<Vector3>();
    var verticsNegative = new List<Vector3>();
    var trianglesPositive = new List<int>();
    var trianglesNegative = new List<int>();

    for (var trix = triangles.Length - 3; trix >= 0; trix -= 3)
    {
        var index0 = triangles[trix];
        var index1 = triangles[trix + 1];
        var index2 = triangles[trix + 2];

        var point0 = vertics[index0];
        var point1 = vertics[index1];
        var point2 = vertics[index2];

        Debug.Log(point0 + " " + point1 + " " + point2);

        if (side[index1] != side[index2] || side[index0] != side[index1] || side[index2] != side[index0])
        {

            if (side[index0] == side[index1])
                Intersect(point0, point1, point2, myplane, side[index0], verticsPositive, verticsNegative, trianglesPositive, trianglesNegative);
            else if (side[index0] == side[index2])
                Intersect(point0, point2, point1, myplane, side[index0], verticsPositive, verticsNegative, trianglesPositive, trianglesNegative);
            else if (side[index1] == side[index2])
                Intersect(point1, point2, point0, myplane, side[index1], verticsPositive, verticsNegative, trianglesPositive, trianglesNegative);
        }
        else
        {
            if (side[index1])
            {
                trianglesPositive.Add(verticsPositive.Count + 2);
                trianglesPositive.Add(verticsPositive.Count + 1);
                trianglesPositive.Add(verticsPositive.Count + 0);

                verticsPositive.Add(point2);
                verticsPositive.Add(point1);
                verticsPositive.Add(point0);
            }
            else
            {
                trianglesNegative.Add(verticsNegative.Count + 2);
                trianglesNegative.Add(verticsNegative.Count + 1);
                trianglesNegative.Add(verticsNegative.Count + 0);

                verticsNegative.Add(point2);
                verticsNegative.Add(point1);
                verticsNegative.Add(point0);
            }
        }
    }

    var go1 = new GameObject();
    go1.name = "positive";
    var meshFilter = go1.AddComponent<MeshFilter>();
    go1.AddComponent<MeshRenderer>();
    var meshPositive = new Mesh();
    meshPositive.vertices = verticsPositive.ToArray();
    meshPositive.triangles = trianglesPositive.ToArray();
    meshPositive.RecalculateBounds();
    meshPositive.RecalculateNormals();
    meshFilter.sharedMesh = meshPositive;

    var go2 = new GameObject();
    go2.name = "negative";
    var meshFilter2 = go2.AddComponent<MeshFilter>();
    go2.AddComponent<MeshRenderer>();
    var meshNegative = new Mesh();
    meshNegative.vertices = verticsNegative.ToArray();
    meshNegative.triangles = trianglesNegative.ToArray();
    meshNegative.RecalculateBounds();
    meshNegative.RecalculateNormals();
    meshFilter2.sharedMesh = meshNegative;
}

public void Intersect(Vector3 point0, Vector3 point1, Vector3 point2, Plane myplane, bool side, List<Vector3> verticsPositive, List<Vector3> verticsNegative, List<int> trianglesPositive,
 List<int> trianglesNegative)
{
    Vector3 pointIntersection1 = Vector3.zero;
    var vector1 = point2 - point0;
    var isIntersect1 = Math3d.LinePlaneIntersection(out pointIntersection1, point0, vector1, myplane.normal, p1);
    Debug.Log("isIntersect " + isIntersect1 + " pointIntersection" + pointIntersection1);

    Vector3 pointIntersection2 = Vector3.zero;
    var vector2 = point2 - point1;
    var isIntersect2 = Math3d.LinePlaneIntersection(out pointIntersection2, point1, vector2, myplane.normal, p1);
    Debug.Log("isIntersect2 " + isIntersect1 + " pointIntersection2" + pointIntersection1);

    if (side)
    {
        trianglesPositive.Add(verticsPositive.Count);
        trianglesPositive.Add(verticsPositive.Count + 1);
        trianglesPositive.Add(verticsPositive.Count + 2);

        verticsPositive.Add(point0);
        verticsPositive.Add(point1);
        verticsPositive.Add(pointIntersection1);

        trianglesPositive.Add(verticsPositive.Count);
        trianglesPositive.Add(verticsPositive.Count + 1);
        trianglesPositive.Add(verticsPositive.Count + 2);

        verticsPositive.Add(point0);
        verticsPositive.Add(pointIntersection1);
        verticsPositive.Add(pointIntersection2);
    }
    else
    {
        trianglesNegative.Add(verticsNegative.Count);
        trianglesNegative.Add(verticsNegative.Count + 1);
        trianglesNegative.Add(verticsNegative.Count + 2);

        verticsNegative.Add(point0);
        verticsNegative.Add(point1);
        verticsNegative.Add(pointIntersection1);

        trianglesNegative.Add(verticsNegative.Count);
        trianglesNegative.Add(verticsNegative.Count + 1);
        trianglesNegative.Add(verticsNegative.Count + 2);

        verticsNegative.Add(point0);
        verticsNegative.Add(pointIntersection1);
        verticsNegative.Add(pointIntersection2);
    }
}

   public static bool LinePlaneIntersection(out Vector3 intersection, Vector3 linePoint, Vector3 lineVec, Vector3 planeNormal, Vector3 planePoint)
{
    float length;
    float dotNumerator;
    float dotDenominator;
    Vector3 vector;
    intersection = Vector3.zero;

    dotNumerator = Vector3.Dot((planePoint - linePoint), planeNormal);
    dotDenominator = Vector3.Dot(lineVec, planeNormal);

    if (dotDenominator != 0.0f)
    {
        length = dotNumerator / dotDenominator;

        vector = SetVectorLength(lineVec, length);

        intersection = linePoint + vector;

        return true;
    }

    else
        return false;
}

0 个答案:

没有答案