public void dfsChains(GameObject component) { List <Transform> properChildren = this.getProperChildren(component); bool previousSpheresExist = (properChildren.Count != component.transform.childCount); // Generate crossing for parent sphere Vector3[] parentCorners; // Cross a section through the middle of the sphere if it is a normal node. // If it's a leaf, cross a tiny section through its top side, so that the total mesh ends // with a corner. if (properChildren.Count == 0) { parentCorners = MeshGenerationUtils.generateQuadSection(this.container, component, MeshGenerationUtils.sphereRadius, .5f); } else if (component.Equals(this.parentSphere)) { parentCorners = MeshGenerationUtils.generateQuadSection(this.container, component, -MeshGenerationUtils.sphereRadius, .5f); } else { parentCorners = MeshGenerationUtils.generateQuadSection(this.container, component); } this.sphereCrosses.Add(component.GetInstanceID(), parentCorners); foreach (Transform child in properChildren) { dfsChains(child.gameObject); } if (properChildren.Count == 1) { // Populate linear path between parent sphere and child sphere with spheres if (!previousSpheresExist) { MeshGenerationUtils.generateParentChildSpheres(component, properChildren[0].gameObject); } // Get all child spheres, before adding other things to the hierarchy of the Transform. List <Transform> sphereChildren = getSphereChildren(component); // Place a quad in each of the spheres on the way from parent to child // In order to get the 4 points that the sphere contributes to creating the mesh. List <Vector3[]> meshPoints = generateQuadSections(component, sphereChildren); //Vector3[] parentPoints = List <Vector3> points = new List <Vector3> (); foreach (Vector3[] meshPoint in meshPoints) { points.AddRange(meshPoint); } Mesh m = MeshGenerationUtils.createConvexHullMesh(points); GameObject selection = MeshGenerationUtils.createGOFromMesh(MeshGenerationUtils.PARTIAL_MESH_NAME, this.container, m); meshes.Add(selection); // Create a mesh out of the corner points obtained in generateQuadSections //GameObject mesh = generateMesh (parentSphere, meshPoints); //meshes.Add (mesh); } }
/* * HC (Humphrey’s Classes) Smooth Algorithm - Reduces Shrinkage of Laplacian Smoother * * Where sv - original points * pv - previous points, * alpha [0..1] influences previous points pv, e.g. 0 * beta [0..1] e.g. > 0.5 */ public static Vector3[] hcFilter(Vector3[] sv, Vector3[] pv, int[] t, float alpha, float beta) { Vector3[] wv = new Vector3[sv.Length]; Vector3[] bv = new Vector3[sv.Length]; // Perform Laplacian Smooth wv = laplacianFilter(sv, t); // Compute Differences for (int i = 0; i < wv.Length; i++) { bv[i].x = wv[i].x - (alpha * sv[i].x + (1 - alpha) * sv[i].x); bv[i].y = wv[i].y - (alpha * sv[i].y + (1 - alpha) * sv[i].y); bv[i].z = wv[i].z - (alpha * sv[i].z + (1 - alpha) * sv[i].z); } List <int> adjacentIndexes = new List <int>(); float dx = 0.0f; float dy = 0.0f; float dz = 0.0f; for (int j = 0; j < bv.Length; j++) { adjacentIndexes.Clear(); // Find the bv neighboring vertices adjacentIndexes = MeshGenerationUtils.findAdjacentNeighborIndexes(sv, t, sv[j]); dx = 0.0f; dy = 0.0f; dz = 0.0f; for (int k = 0; k < adjacentIndexes.Count; k++) { dx += bv[adjacentIndexes[k]].x; dy += bv[adjacentIndexes[k]].y; dz += bv[adjacentIndexes[k]].z; } wv[j].x -= beta * bv[j].x + ((1 - beta) / adjacentIndexes.Count) * dx; wv[j].y -= beta * bv[j].y + ((1 - beta) / adjacentIndexes.Count) * dy; wv[j].z -= beta * bv[j].z + ((1 - beta) / adjacentIndexes.Count) * dz; } return(wv); }
public static Vector3[] generateQuadSection(GameObject container, GameObject sphere) { List <Vector3> quads = new List <Vector3> (); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 0)); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 10)); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 20)); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 30)); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 40)); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 50)); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 60)); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 70)); quads.AddRange(MeshGenerationUtils.generateQuadSection(container, sphere, 0, 1, 80)); return(quads.ToArray()); }
public void dfsSplits(GameObject component) { List <Transform> properChildren = this.getProperChildren(component); foreach (Transform child in properChildren) { dfsSplits(child.gameObject); } if (properChildren.Count > 1) { List <Vector3> points = new List <Vector3>(); foreach (Transform child in properChildren) { points.AddRange(this.sphereCrosses [child.gameObject.GetInstanceID()]); } points.AddRange(this.sphereCrosses[component.GetInstanceID()]); // Mesh mesh = MeshGenerationUtils.createMesh (points); Mesh m = MeshGenerationUtils.createConvexHullMesh(points); GameObject selection = MeshGenerationUtils.createGOFromMesh(MeshGenerationUtils.PARTIAL_MESH_NAME, this.container, m); meshes.Add(selection); } }
/* * Standard Laplacian Smooth Filter */ public static Vector3[] laplacianFilter(Vector3[] sv, int[] t) { Vector3[] wv = new Vector3[sv.Length]; List <Vector3> adjacentVertices = new List <Vector3>(); float dx = 0.0f; float dy = 0.0f; float dz = 0.0f; for (int vi = 0; vi < sv.Length; vi++) { // Find the sv neighboring vertices adjacentVertices = MeshGenerationUtils.findAdjacentNeighbors(sv, t, sv[vi]); if (adjacentVertices.Count != 0) { dx = 0.0f; dy = 0.0f; dz = 0.0f; //Debug.Log("Vertex Index Length = "+vertexIndexes.Length); // Add the vertices and divide by the number of vertices for (int j = 0; j < adjacentVertices.Count; j++) { dx += adjacentVertices[j].x; dy += adjacentVertices[j].y; dz += adjacentVertices[j].z; } wv[vi].x = dx / adjacentVertices.Count; wv[vi].y = dy / adjacentVertices.Count; wv[vi].z = dz / adjacentVertices.Count; } } return(wv); }
private List <Vector3[]> generateQuadSections(GameObject parentSphere, List <Transform> sphereChildren) { List <Vector3[]> allChildrenCorners = new List <Vector3[]>(); //TODO (cmocan): Defensive coding. Check dictionary first, and generate if it's not there. Vector3[] parentCorners = this.sphereCrosses[parentSphere.gameObject.GetInstanceID()]; allChildrenCorners.Add(parentCorners); foreach (Transform child in sphereChildren) { Vector3[] currChildCorners; if (this.sphereCrosses.ContainsKey(child.gameObject.GetInstanceID())) { currChildCorners = this.sphereCrosses [child.gameObject.GetInstanceID()]; } else { currChildCorners = MeshGenerationUtils.generateQuadSection(this.container, child.gameObject); } allChildrenCorners.Add(currChildCorners); } return(allChildrenCorners); }