void ExtrudeEdge() { pb_Face sourceFace = lastExtrudedFace; // fetch a random perimeter edge connected to the last face extruded List <pb_WingedEdge> wings = pb_WingedEdge.GetWingedEdges(pb); IEnumerable <pb_WingedEdge> sourceWings = wings.Where(x => x.face == sourceFace); List <pb_Edge> nonManifoldEdges = sourceWings.Where(x => x.opposite == null).Select(y => y.edge.local).ToList(); int rand = (int)Random.Range(0, nonManifoldEdges.Count); pb_Edge sourceEdge = nonManifoldEdges[rand]; // get the direction this edge should extrude in Vector3 dir = ((pb.vertices[sourceEdge.x] + pb.vertices[sourceEdge.y]) * .5f) - sourceFace.distinctIndices.Average(x => pb.vertices[x]); dir.Normalize(); // this will be populated with the extruded edge pb_Edge[] extrudedEdges; // perform extrusion pb.Extrude(new pb_Edge[] { sourceEdge }, 0f, false, true, out extrudedEdges); // get the last extruded face lastExtrudedFace = pb.faces.Last(); // translate the vertices- pb.TranslateVertices(extrudedEdges[0].ToArray(), dir * distance); // rebuild mesh with new geometry added by extrude pb.ToMesh(); // rebuild mesh normals, textures, collisions, etc pb.Refresh(); }
/** * Do the thing. Return a pb_ActionResult indicating the success/failure of action. */ public override pb_ActionResult DoAction() { #if !UNITY_4_6 && !UNITY_4_7 ShadowCastingMode shadowMode = (ShadowCastingMode)pb_PreferencesInternal.GetInt("pb_CreateShadowObject_shadowMode", (int)ShadowCastingMode.ShadowsOnly); #endif float extrudeDistance = pb_PreferencesInternal.GetFloat("pb_CreateShadowObject_volumeSize", .08f); ExtrudeMethod extrudeMethod = (ExtrudeMethod)pb_PreferencesInternal.GetInt("pb_CreateShadowObject_extrudeMethod", (int)ExtrudeMethod.FaceNormal); foreach (pb_Object pb in selection) { pb_Object shadow = GetShadowObject(pb); if (shadow == null) { continue; } foreach (pb_Face f in shadow.faces) { f.ReverseIndices(); f.manualUV = true; } shadow.Extrude(shadow.faces, extrudeMethod, extrudeDistance); shadow.ToMesh(); shadow.Refresh(); shadow.Optimize(); #if !UNITY_4_6 && !UNITY_4_7 MeshRenderer mr = shadow.gameObject.GetComponent <MeshRenderer>(); mr.shadowCastingMode = shadowMode; if (shadowMode == ShadowCastingMode.ShadowsOnly) { mr.receiveShadows = false; } #endif Collider collider = shadow.GetComponent <Collider>(); while (collider != null) { GameObject.DestroyImmediate(collider); collider = shadow.GetComponent <Collider>(); } } // This is necessary! Otherwise the pb_Editor will be working with caches from // outdated meshes and throw errors. pb_Editor.Refresh(); return(new pb_ActionResult(Status.Success, "Create Shadow Object")); }
private void Start() { audioSource = GetComponent <AudioSource>(); if (audioSource.clip == null) { missingClipWarning.SetActive(value: true); } ico = pb_ShapeGenerator.IcosahedronGenerator(icoRadius, icoSubdivisions); pb_Face[] faces = ico.faces; pb_Face[] array = faces; foreach (pb_Face pb_Face in array) { pb_Face.material = material; } ico.Extrude(faces, ExtrudeMethod.IndividualFaces, startingExtrusion); ico.ToMesh(); ico.Refresh(); outsides = new FaceRef[faces.Length]; Dictionary <int, int> lookup = ico.sharedIndices.ToDictionary(); for (int j = 0; j < faces.Length; j++) { outsides[j] = new FaceRef(faces[j], pb_Math.Normal(ico, faces[j]), ico.sharedIndices.AllIndicesWithValues(lookup, faces[j].distinctIndices).ToArray()); } original_vertices = new Vector3[ico.vertices.Length]; Array.Copy(ico.vertices, original_vertices, ico.vertices.Length); displaced_vertices = ico.vertices; icoMesh = ico.msh; icoTransform = ico.transform; faces_length = outsides.Length; icoPosition = icoTransform.position; waveform.positionCount = 1024; if (bounceWaveform) { waveform.transform.parent = icoTransform; } audioSource.Play(); }
private void ExtrudeEdge() { pb_Face sourceFace = lastExtrudedFace; List <pb_WingedEdge> wingedEdges = pb_WingedEdge.GetWingedEdges(pb); IEnumerable <pb_WingedEdge> source = wingedEdges.Where((pb_WingedEdge x) => x.face == sourceFace); List <pb_Edge> list = (from x in source where x.opposite == null select x into y select y.edge.local).ToList(); int index = Random.Range(0, list.Count); pb_Edge pb_Edge = list[index]; Vector3 a = (pb.vertices[pb_Edge.x] + pb.vertices[pb_Edge.y]) * 0.5f - sourceFace.distinctIndices.Average((int x) => pb.vertices[x]); a.Normalize(); pb.Extrude(new pb_Edge[1] { pb_Edge }, 0f, extrudeAsGroup: false, enableManifoldExtrude: true, out pb_Edge[] extrudedEdges); lastExtrudedFace = pb.faces.Last(); pb.SetSelectedEdges(extrudedEdges); pb.TranslateVertices(pb.SelectedTriangles, a * distance); pb.ToMesh(); pb.Refresh(); }
/** * Creates the icosphere, and loads all the cache information. */ void Start() { audioSource = GetComponent <AudioSource>(); if (audioSource.clip == null) { missingClipWarning.SetActive(true); } // Create a new icosphere. ico = pb_ShapeGenerator.IcosahedronGenerator(icoRadius, icoSubdivisions); // Shell is all the faces on the new icosphere. pb_Face[] shell = ico.faces; // Materials are set per-face on pb_Object meshes. pb_Objects will automatically // condense the mesh to the smallest set of subMeshes possible based on materials. #if !PROTOTYPE foreach (pb_Face f in shell) { f.SetMaterial(material); } #else ico.gameObject.GetComponent <MeshRenderer>().sharedMaterial = material; #endif pb_Face[] connectingFaces; // Extrude all faces on the icosphere by a small amount. The third boolean parameter // specifies that extrusion should treat each face as an individual, not try to group // all faces together. ico.Extrude(shell, startingExtrusion, false, out connectingFaces); // ToMesh builds the mesh positions, submesh, and triangle arrays. Call after adding // or deleting vertices, or changing face properties. ico.ToMesh(); // Refresh builds the normals, tangents, and UVs. ico.Refresh(); outsides = new FaceRef[shell.Length]; Dictionary <int, int> lookup = ico.sharedIndices.ToDictionary(); // Populate the outsides[] cache. This is a reference to the tops of each extruded column, including // copies of the sharedIndices. for (int i = 0; i < shell.Length; ++i) { outsides[i] = new FaceRef(shell[i], pb_Math.Normal(ico, shell[i]), ico.sharedIndices.AllIndicesWithValues(lookup, shell[i].distinctIndices).ToArray() ); } // Store copy of positions array un-modified original_vertices = new Vector3[ico.vertices.Length]; System.Array.Copy(ico.vertices, original_vertices, ico.vertices.Length); // displaced_vertices should mirror icosphere mesh vertices. displaced_vertices = ico.vertices; icoMesh = ico.msh; icoTransform = ico.transform; faces_length = (float)outsides.Length; // Build the waveform ring. icoPosition = icoTransform.position; waveform.SetVertexCount(WAVEFORM_SAMPLES); if (bounceWaveform) { waveform.transform.parent = icoTransform; } audioSource.Play(); }
/** * Creates the icosphere, and loads all the cache information. */ void Start() { audioSource = GetComponent<AudioSource>(); if( audioSource.clip == null ) missingClipWarning.SetActive(true); // Create a new icosphere. ico = pb_ShapeGenerator.IcosahedronGenerator(icoRadius, icoSubdivisions); // Shell is all the faces on the new icosphere. pb_Face[] shell = ico.faces; // Materials are set per-face on pb_Object meshes. pb_Objects will automatically // condense the mesh to the smallest set of subMeshes possible based on materials. foreach(pb_Face f in shell) f.SetMaterial( material ); pb_Face[] connectingFaces; // Extrude all faces on the icosphere by a small amount. The third boolean parameter // specifies that extrusion should treat each face as an individual, not try to group // all faces together. ico.Extrude(shell, startingExtrusion, false, out connectingFaces); // ToMesh builds the mesh positions, submesh, and triangle arrays. Call after adding // or deleting vertices, or changing face properties. ico.ToMesh(); // Refresh builds the normals, tangents, and UVs. ico.Refresh(); outsides = new FaceRef[shell.Length]; Dictionary<int, int> lookup = ico.sharedIndices.ToDictionary(); // Populate the outsides[] cache. This is a reference to the tops of each extruded column, including // copies of the sharedIndices. for(int i = 0; i < shell.Length; ++i) outsides[i] = new FaceRef( shell[i], pb_Math.Normal(ico, shell[i]), ico.sharedIndices.AllIndicesWithValues(lookup, shell[i].distinctIndices).ToArray() ); // Store copy of positions array un-modified original_vertices = new Vector3[ico.vertices.Length]; System.Array.Copy(ico.vertices, original_vertices, ico.vertices.Length); // displaced_vertices should mirror icosphere mesh vertices. displaced_vertices = ico.vertices; icoMesh = ico.msh; icoTransform = ico.transform; faces_length = (float)outsides.Length; // Build the waveform ring. icoPosition = icoTransform.position; waveform.SetVertexCount(WAVEFORM_SAMPLES); if( bounceWaveform ) waveform.transform.parent = icoTransform; audioSource.Play(); }
public static void Extrude(this pb_Object pb, pb_Face[] faces) { pb.Extrude(faces, EXTRUDE_DISTANCE); }