public void Awake() { Stopwatch sw = Stopwatch.StartNew(); Vector3[] points = ori.mesh.vertices; if (useEight) { EightBlockTree eightTree = new EightBlockTree(); points = eightTree.Build(points, 5); } QuickHull3D hull = new QuickHull3D(); hull.Build(points); Vector3[] vertices = hull.GetVertices(); int[] faceIndices = hull.GetFaces(); Mesh mesh = new Mesh { vertices = vertices, triangles = faceIndices }; col.mesh = mesh; sw.Stop(); Debug.Log(sw.Elapsed); }
private Mesh CalcMesh(string _path, bool _useEightBlocks, int _blockLv) { var oriMesh = AssetDatabase.LoadAssetAtPath <GameObject>(_path); List <Vector3> allPoints = new List <Vector3>(1024); foreach (var mesh in oriMesh.GetComponentsInChildren <SkinnedMeshRenderer>()) { allPoints.AddRange(mesh.sharedMesh.vertices); } foreach (var mesh in oriMesh.GetComponentsInChildren <MeshFilter>()) { allPoints.AddRange(mesh.sharedMesh.vertices); } Vector3[] points = allPoints.ToArray(); AppendLogLine(_path); AppendLogLine(" Ori Vertexs:", points.Length.ToString()); if (_useEightBlocks) { EightBlockTree eightTree = new EightBlockTree(); points = eightTree.Build(points, _blockLv); AppendLogLine(" EightBlockTree Vertexs:", points.Length.ToString()); } QuickHull3D hull = new QuickHull3D(); hull.Build(points); Vector3[] vertices = hull.GetVertices(); int[] faceIndices = hull.GetFaces(); Mesh newMesh = new Mesh { vertices = vertices, triangles = faceIndices }; AppendLogLine(" End vertices:", vertices.Length.ToString()); AppendLogLine(" End faceIndices:", faceIndices.Length.ToString()); return(newMesh); }
public void Evaluate(int SpreadMax) { if (this.FPinInVector.PinIsChanged) { List <Point3d> points = new List <Point3d>(); #region Initialize List for (int i = 0; i < this.FPinInVector.SliceCount; i++) { double x, y, z; this.FPinInVector.GetValue3D(i, out x, out y, out z); points.Add(new Point3d(x, y, z)); } #endregion #region Compute Hull QuickHull3D q = new QuickHull3D(); q.build(points.ToArray()); Point3d[] vertices = q.getVertices(); int[][] faces = q.getFaces(); #endregion #region Output this.FPinOutVertices.SliceCount = vertices.Length; for (int i = 0; i < vertices.Length; i++) { this.FPinOutVertices.SetValue3D(i, vertices[i].x, vertices[i].y, vertices[i].z); } this.FPinOutIndices.SliceCount = faces.Length * 3; int idx = 0; for (int i = 0; i < faces.Length; i++) { this.FPinOutIndices.SetValue(idx, faces[i][0]); this.FPinOutIndices.SetValue(idx + 1, faces[i][1]); this.FPinOutIndices.SetValue(idx + 2, faces[i][2]); idx += 3; } #endregion } }
/** * Run for a simple demonstration of QuickHull3D. */ public static void main(string[] args) { // x y z coordinates of 6 points Point3d[] points = new Point3d[] { new Point3d(0.0, 0.0, 0.0), new Point3d(1.0, 0.5, 0.0), new Point3d(2.0, 0.0, 0.0), new Point3d(0.5, 0.5, 0.5), new Point3d(0.0, 0.0, 2.0), new Point3d(0.1, 0.2, 0.3), new Point3d(0.0, 2.0, 0.0), }; QuickHull3D hull = new QuickHull3D(); hull.build(points); // System.out.println ("Vertices:"); // Point3d[] vertices = hull.getVertices(); // for (int i=0; i<vertices.Length; i++) // { // Point3d pnt = vertices[i]; // System.out.println (pnt.x + " " + pnt.y + " " + pnt.z); // } // System.out.println ("Faces:"); // int[][] faceIndices = hull.getFaces(); // // for (int i=0; i<vertices.Length; i++) // { // for (int k=0; k<faceIndices[i].Length; k++) // { // System.out.print (faceIndices[i][k] + " "); // } // System.out.println (""); // } }
void Start() { MeshFilter[] meshFilters = GetComponentsInChildren <MeshFilter>(); //包括了自己所以要跳过 CombineInstance[] combine = new CombineInstance[meshFilters.Length - 1]; Material[] mats = new Material[meshFilters.Length - 1]; Matrix4x4 matrix = transform.worldToLocalMatrix; int index = 0; for (int i = 1; i < meshFilters.Length; i++) { MeshFilter mf = meshFilters[i]; MeshRenderer mr = meshFilters[i].GetComponent <MeshRenderer>(); if (mr == null) { continue; } combine[index].mesh = mf.sharedMesh; combine[index].transform = matrix * mf.transform.localToWorldMatrix; mr.enabled = false; mats[index] = mr.sharedMaterial; index++; } MeshFilter thisMeshFilter = GetComponent <MeshFilter>(); Mesh mesh = new Mesh { name = "Combined" }; thisMeshFilter.mesh = mesh; mesh.CombineMeshes(combine, false); MeshRenderer thisMeshRenderer = GetComponent <MeshRenderer>(); thisMeshRenderer.sharedMaterials = mats; thisMeshRenderer.enabled = true; MeshCollider thisMeshCollider = GetComponent <MeshCollider>(); if (thisMeshCollider != null) { Stopwatch sw = Stopwatch.StartNew(); Vector3[] points = mesh.vertices; EightBlockTree eightTree = new EightBlockTree(); points = eightTree.Build(points, 8); QuickHull3D hull = new QuickHull3D(); hull.Build(points); Vector3[] vertices = hull.GetVertices(); int[] faceIndices = hull.GetFaces(); Mesh colMesh = new Mesh { vertices = vertices, triangles = faceIndices }; sw.Stop(); Debug.Log(sw.Elapsed); thisMeshCollider.sharedMesh = colMesh; } else { thisMeshCollider = gameObject.AddComponent <MeshCollider>(); thisMeshCollider.sharedMesh = mesh; thisMeshCollider.convex = true; } }
private void GenerateConvexHull(Hull hull, Vector3[] meshVertices, int[] meshIndices, Mesh destMesh) { // Generate array of input points int totalFaces = hull.selectedFaces.Count; Point3d[] inputPoints = new Point3d[totalFaces * 3]; for (int i = 0; i < hull.selectedFaces.Count; i++) { int faceIndex = hull.selectedFaces[i]; Vector3 p0 = meshVertices[meshIndices[faceIndex * 3]]; Vector3 p1 = meshVertices[meshIndices[faceIndex * 3 + 1]]; Vector3 p2 = meshVertices[meshIndices[faceIndex * 3 + 2]]; inputPoints[i * 3] = new Point3d(p0.x, p0.y, p0.z); inputPoints[i * 3 + 1] = new Point3d(p1.x, p1.y, p1.z); inputPoints[i * 3 + 2] = new Point3d(p2.x, p2.y, p2.z); } // Calculate the convex hull QuickHull3D qHull = new QuickHull3D(); try { qHull.build(inputPoints); } catch (System.Exception) { Debug.LogError("Could not generate hull for " + this.name + "'s '" + hull.name + "' (input " + inputPoints.Length + " points)"); } // Get calculated hull vertices and indices Point3d[] hullVertices = qHull.getVertices(); int[][] hullFaceIndices = qHull.getFaces(); hull.numColliderFaces = hullFaceIndices.Length; Debug.Log("Calculated collider for '" + hull.name + "' has " + hullFaceIndices.Length + " faces"); if (hullFaceIndices.Length >= 256) { hull.hasColliderError = true; return; } // Convert to dest vertices Vector3[] destVertices = new Vector3[hullVertices.Length]; for (int i = 0; i < destVertices.Length; i++) { destVertices[i] = new Vector3((float)hullVertices[i].x, (float)hullVertices[i].y, (float)hullVertices[i].z); } // Convert to dest incices List <int> destIndices = new List <int>(); for (int i = 0; i < hullFaceIndices.Length; i++) { int faceVerts = hullFaceIndices[i].Length; for (int j = 1; j < faceVerts - 1; j++) { destIndices.Add(hullFaceIndices[i][0]); destIndices.Add(hullFaceIndices[i][j]); destIndices.Add(hullFaceIndices[i][j + 1]); } } int[] destIndicesArray = new int[destIndices.Count]; for (int i = 0; i < destIndices.Count; i++) { destIndicesArray[i] = destIndices[i]; } // Push to collision mesh hull.collisionMesh.vertices = destVertices; hull.collisionMesh.triangles = destIndicesArray; hull.collisionMesh.RecalculateBounds(); }