我尝试通过相交平面拼接网格,但得到错误的结果。 我的代码(我按平面切割网格,从平面正面或负面计算钙面,然后在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;
}