public void MeshValidation_IsSplitFace_ConfirmsValidFaces([ValueSource("k_IndexCounts")] int indexCount) { var points = new Vector3[indexCount]; var indices = new int[(indexCount - 1) * 3]; for (int i = 0; i < indexCount; i++) { float travel = ((i + 1) / (float)indexCount) * Mathf.PI * 2f; points[i] = new Vector3(Mathf.Cos(travel), 0f, Mathf.Sin(travel)); } for (int i = 1; i < indexCount - 1; i++) { indices[(i - 1) * 3 + 0] = 0; indices[(i - 1) * 3 + 1] = i; indices[(i - 1) * 3 + 2] = (i + 1) % indexCount; } var shape = ProBuilderMesh.Create(points, new Face[] { new Face(indices) }); Assume.That(shape, Is.Not.Null); var face = shape.faces.First(); Assume.That(face, Is.Not.Null); Assume.That(face.edgesInternal, Has.Length.EqualTo(indexCount)); Assert.That(MeshValidation.ContainsNonContiguousTriangles(shape, face), Is.False); }
void Initialize() { Vector3[] points = new Vector3[UVLength * UVLength]; Face[] faces = new Face[(UVLength - 1) * (UVLength - 1)]; float xThreshold = (edgeLength) / UVLength; for (int i = 0; i < points.Length; i++) { points[i] = new Vector3(center.x + (xThreshold * (i % UVLength)), center.y, center.z + (xThreshold * (i / UVLength))); } int j = 0; for (int i = 0; i < points.Length - UVLength; i++) { if (i % UVLength != UVLength - 1) { faces[j] = new Face(new int[] { i, i + 1, i + UVLength, i + 1, i + UVLength + 1, i + UVLength }); j++; } } ground = ProBuilderMesh.Create(points, faces); ground.CenterPivot(new int[] { 0, UVLength - 1, UVLength * (UVLength - 1), (UVLength * UVLength) - 1 }); ground.Refresh(); MeshRenderer meshRend = ground.GetComponent <MeshRenderer>(); meshRend.material = fogMaterial; ground.transform.position = center; ground.gameObject.layer = 9; ground.gameObject.name = "fog"; ground.gameObject.AddComponent <MeshCollider>(); ground.transform.Rotate(new Vector3(180f, 0, 0)); ground.transform.localScale = (new Vector3(1 / 3f, 1 / 3f, 1 / 3f)); }
public static ProBuilderMesh MeshRoadNetwork(RoadNetwork roadNet) { var(vertices, faces) = CalcVerticesAndFaces(roadNet); ProBuilderMesh roadMesh = ProBuilderMesh.Create(vertices, faces); roadMesh.GetComponent <Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; return(roadMesh); }
/// <summary> /// Break a ProBuilder mesh into multiple meshes if it's vertex count is greater than maxVertexCount. /// </summary> /// <returns></returns> internal static List <ProBuilderMesh> SplitByMaxVertexCount(IList <Vertex> vertices, IList <Face> faces, IList <SharedVertex> sharedVertices, IList <SharedVertex> sharedTextures, uint maxVertexCount = ProBuilderMesh.maxVertexCount) { uint vertexCount = (uint)vertices.Count; uint meshCount = System.Math.Max(1u, vertexCount / maxVertexCount); var submeshCount = faces.Max(x => x.submeshIndex) + 1; if (meshCount < 2) { return new List <ProBuilderMesh>() { ProBuilderMesh.Create(vertices, faces, sharedVertices, sharedTextures, new Material[submeshCount]) } } ; var sharedVertexLookup = new Dictionary <int, int>(); SharedVertex.GetSharedVertexLookup(sharedVertices, sharedVertexLookup); var sharedTextureLookup = new Dictionary <int, int>(); SharedVertex.GetSharedVertexLookup(sharedTextures, sharedTextureLookup); var meshes = new List <ProBuilderMesh>(); var mv = new List <Vertex>(); var mf = new List <Face>(); var remap = new Dictionary <int, int>(); foreach (var face in faces) { if (mv.Count + face.distinctIndexes.Count > maxVertexCount) { // finalize mesh meshes.Add(CreateMeshFromSplit(mv, mf, sharedVertexLookup, sharedTextureLookup, remap, new Material[submeshCount])); mv.Clear(); mf.Clear(); remap.Clear(); } foreach (int i in face.distinctIndexes) { mv.Add(vertices[i]); remap.Add(i, mv.Count - 1); } mf.Add(face); } if (mv.Any()) { meshes.Add(CreateMeshFromSplit(mv, mf, sharedVertexLookup, sharedTextureLookup, remap, new Material[submeshCount])); } return(meshes); } }
public override ProBuilderMesh Build(bool isPreview = false) { var positions = InternalUtility.StringToVector3Array(verts); if (positions.Length % 4 == 0) { return(ProBuilderMesh.CreateInstanceWithPoints( InternalUtility.StringToVector3Array(verts) )); } return(ProBuilderMesh.Create()); }
public void CreateMeshes(List <Vector3> poss) { var filter = GetComponent <MeshFilter>(); // Add a new uninitialized pb_Object var mesh = gameObject.AddComponent <ProBuilderMesh>(); var pb = ProBuilderMesh.Create(); pb.CreateShapeFromPolygon(poss, 0f, false); MeshRenderer meshRenderer = pb.GetComponent <MeshRenderer>(); meshRenderer.material = mat; }
/* * Method was made for testing the data that was stored * in each individual level piece (gameObject) */ IEnumerator spawnBack() { yield return(new WaitForSeconds(0.1f)); GameObject level = new GameObject("[LOADED LEVEL]"); foreach (LevelPiece data in levelPieces) { List <Vertex> vertices = new List <Vertex>(); foreach (Vector3 position in data.vertices) { Vertex newPoint = new Vertex(); newPoint.position = position; vertices.Add(newPoint); } List <Face> faces = new List <Face>(); foreach (ArrayPacker face in data.faces) { faces.Add(new Face(face.array)); } List <SharedVertex> sharedVertices = new List <SharedVertex>(); foreach (ArrayPacker shared in data.sharedVertices) { sharedVertices.Add(new SharedVertex(shared.array)); } ProBuilderMesh pbMesh = ProBuilderMesh.Create(vertices, faces, sharedVertices); GameObject generatedObject = pbMesh.gameObject; generatedObject.transform.position = offset + data.position; generatedObject.transform.rotation = data.rotation; MaterialMapping mapping = MaterialMapping.GetMaterialMappingFromName(levelMaterials, data.materialName); if (mapping != null) { generatedObject.GetComponent <Renderer>().sharedMaterial = mapping.material; } else { generatedObject.GetComponent <Renderer>().sharedMaterial = fallbackLevelMaterial; } generatedObject.AddComponent <MeshCollider>(); generatedObject.transform.parent = level.transform; } }
static ActionResult MenuBooleanOperation(BooleanOperation operation, ProBuilderMesh lhs, ProBuilderMesh rhs) { if (lhs == null || rhs == null) { return(new ActionResult(ActionResult.Status.Failure, "Must Select 2 Objects")); } string op_string = operation == BooleanOperation.Union ? "Union" : (operation == BooleanOperation.Subtract ? "Subtract" : "Intersect"); ProBuilderMesh[] sel = new ProBuilderMesh[] { lhs, rhs }; UndoUtility.RecordSelection(sel, op_string); UnityEngine.ProBuilder.Csg.Model result; switch (operation) { case BooleanOperation.Union: result = Boolean.Union(lhs.gameObject, rhs.gameObject); break; case BooleanOperation.Subtract: result = Boolean.Subtract(lhs.gameObject, rhs.gameObject); break; default: result = Boolean.Intersect(lhs.gameObject, rhs.gameObject); break; } var materials = result.materials.ToArray(); ProBuilderMesh pb = ProBuilderMesh.Create(); pb.GetComponent <MeshFilter>().sharedMesh = (Mesh)result; pb.GetComponent <MeshRenderer>().sharedMaterials = materials; MeshImporter importer = new MeshImporter(pb.gameObject); importer.Import(new MeshImportSettings() { quads = true, smoothing = true, smoothingAngle = 1f }); pb.Rebuild(); pb.CenterPivot(null); Selection.objects = new Object[] { pb.gameObject }; return(new ActionResult(ActionResult.Status.Success, op_string)); }
public void CreateBoundary() { var boundaryPoints = Config.BoundaryGeoData.GetPathInStreamingAssets().GetBoundaryPoints().AddTileIntersectionPoints(); // Create vertices var wallVertices = new List <Vector3>(); for (int p = 0; p < boundaryPoints.Length - 1; p++) { var point0 = boundaryPoints[p]; var point1 = boundaryPoints[p + 1]; wallVertices.Add(point0); wallVertices.Add(point1); wallVertices.Add(new Vector3(point0.x, point0.y + Config.BoundaryHeight, point0.z)); wallVertices.Add(new Vector3(point1.x, point1.y + Config.BoundaryHeight, point1.z)); } // Create faces var faces = new List <Face>(); for (int f = 0; f < wallVertices.Count - 3; f += 4) { var faceVertices = new int[] { f, f + 1, f + 2, f + 1, f + 3, f + 2 }; faces.Add(new Face(faceVertices)); } var wall = ProBuilderMesh.Create(wallVertices, faces); Normals.CalculateNormals(wall); Normals.CalculateTangents(wall); Smoothing.ApplySmoothingGroups(wall, faces, 30); wall.ToMesh(); wall.Refresh(); EditorMeshUtility.Optimize(wall); var meshRenderer = wall.GetComponent <MeshRenderer>(); meshRenderer.material = Config.BoundaryMaterial; meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; meshRenderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; wall.gameObject.name = wall.name = Path.GetFileNameWithoutExtension(Config.BoundaryGeoData).Replace('_', ' '); wall.transform.SetParent(null, true); }
static ProBuilderMesh CreateMeshFromSplit(List <Vertex> vertices, List <Face> faces, Dictionary <int, int> sharedVertexLookup, Dictionary <int, int> sharedTextureLookup, Dictionary <int, int> remap, Material[] materials) { // finalize mesh var sv = new Dictionary <int, int>(); var st = new Dictionary <int, int>(); foreach (var f in faces) { for (int i = 0, c = f.indexesInternal.Length; i < c; i++) { f.indexesInternal[i] = remap[f.indexesInternal[i]]; } f.InvalidateCache(); } foreach (var kvp in remap) { int v; if (sharedVertexLookup.TryGetValue(kvp.Key, out v)) { sv.Add(kvp.Value, v); } if (sharedTextureLookup.TryGetValue(kvp.Key, out v)) { st.Add(kvp.Value, v); } } return(ProBuilderMesh.Create( vertices, faces, SharedVertex.ToSharedVertices(sv), st.Any() ? SharedVertex.ToSharedVertices(st) : null, materials)); }
private ProBuilderMesh GetShadowObject(ProBuilderMesh mesh) { if (mesh == null || mesh.name.Contains("-ShadowVolume")) { return(null); } for (int i = 0; i < mesh.transform.childCount; i++) { Transform t = mesh.transform.GetChild(i); if (t.name.Equals(string.Format("{0}-ShadowVolume", mesh.name))) { ProBuilderMesh shadow = t.GetComponent <ProBuilderMesh>(); if (shadow != null) { Undo.RecordObject(shadow, "Update Shadow Object"); Face[] faces = new Face[mesh.faceCount]; for (int nn = 0; nn < mesh.faceCount; nn++) { faces[nn] = new Face(mesh.faces[nn]); } shadow.RebuildWithPositionsAndFaces(mesh.positions, faces); return(shadow); } } } ProBuilderMesh newShadowMesh = ProBuilderMesh.Create(); newShadowMesh.ToMesh(); newShadowMesh.CopyFrom(mesh); newShadowMesh.name = string.Format("{0}-ShadowVolume", mesh.name); newShadowMesh.transform.SetParent(mesh.transform, false); Undo.RegisterCreatedObjectUndo(newShadowMesh.gameObject, "Create Shadow Object"); return(newShadowMesh); }
// Extrude en utilisant le probuilder mesh public void Extrude(List <HalfEdge> face, float height) { Vector3[] facePoints = PointsPositionInFaces(face); int[] triangles = Triangulate(face); WingedEdgeMap.PrintArray(triangles); if (Vector3.Cross(facePoints[triangles[1]] - facePoints[triangles[0]], facePoints[triangles[2]] - facePoints[triangles[1]]).y <= 0f) { Array.Reverse(triangles); } WingedEdgeMap.PrintArray(triangles); ProBuilderMesh poly = ProBuilderMesh.Create(facePoints, new Face[] { new Face(triangles) }); poly.Extrude(poly.faces, ExtrudeMethod.FaceNormal, height); poly.ToMesh(); MeshRenderer mr = poly.GetComponent <MeshRenderer>(); mr.material = mat; poly.Refresh(); }
private ProBuilderMesh OnPolygon_PB(XmlReader reader) { List <Vector3> localOutlines = new List <Vector3>(); List <List <Vector3> > localHoles = new List <List <Vector3> >(); while (isEndElement(reader, "Polygon") == false && isEndElement(reader, "PolygonPatch") == false) { reader.Read(); if (isStartElement(reader, "exterior")) { // pos 목록을 localExterior에 모두 등록. exterior는 1개를 초과하지 않음. localOutlines = new List <Vector3>(); while (isEndElement(reader, "exterior") == false) { reader.Read(); if (isStartElement(reader, "pos")) { reader.Read(); Vector3 unityVector3d = GetPos3D(reader); localOutlines.Add(unityVector3d); } else if (isStartElement(reader, "posList")) { reader.Read(); localOutlines = GetPosList3D(reader); } } } if (isStartElement(reader, "interior")) { localHoles.Add(new List <Vector3>()); while (isEndElement(reader, "interior") == false) { reader.Read(); if (isStartElement(reader, "pos")) { reader.Read(); Vector3 unityVector3d = GetPos3D(reader); localHoles.Last().Add(unityVector3d); } else if (isStartElement(reader, "posList")) { reader.Read(); //var lastHole = localHoles.Last(); //lastHole = GetPosList3D(reader); int lastHoleIdx = localHoles.Count; localHoles[lastHoleIdx - 1] = GetPosList3D(reader); } } } } outLines.Add(localOutlines); for (int i = 0; i < localHoles.Count(); i++) { outLines.Add(localHoles[i]); } var polygon_pb = ProBuilderMesh.Create(); IList <IList <Vector3> > localHoles_pb = new List <IList <Vector3> >(localHoles); polygon_pb.CreateShapeFromPolygon(localOutlines, 0, false, localHoles_pb); return(polygon_pb); //Poly2Mesh.Polygon polygon = new Poly2Mesh.Polygon(); //polygon.outside = localOutlines; //polygon.holes = localHoles; //return polygon; }
public void Generate() { switch (ShapeType) { case ShapeTypes.Wythoff: var wythoff = new WythoffPoly(PolyType, PrismP, PrismQ); wythoff.BuildFaces(); poly = new ConwayPoly(wythoff); break; case ShapeTypes.Johnson: poly = JohnsonPoly.Build(JohnsonPolyType, PrismP); break; case ShapeTypes.Grid: poly = Grids.Grids.MakeGrid(GridType, GridShape, PrismP, PrismQ); break; } if (ApplyOp) { var o1 = new OpParams { valueA = op1Amount1, valueB = op1Amount2, facesel = op1Facesel }; poly = poly.ApplyOp(op1, o1); } if (PreCanonicalize) { poly = poly.Canonicalize(0.01, 0.01); } if (Canonicalize) { poly = poly.Canonicalize(0.01, 0.01); } if (ApplyOp) { var o2 = new OpParams { valueA = op2Amount1, valueB = op2Amount2, facesel = op2Facesel }; poly = poly.ApplyOp(op2, o2); var o3 = new OpParams { valueA = op3Amount1, valueB = op3Amount2, facesel = op3Facesel }; poly = poly.ApplyOp(op3, o3); } var points = poly.ListVerticesByPoints().ToList(); if (JitterAmount > 0) { for (int i = 0; i < points.Count(); i++) { var point = points[i]; points[i] = new Vector3( point.x + Random.value * JitterAmount, point.y + Random.value * JitterAmount, point.z + Random.value * JitterAmount ); } } var faceIndices = poly.ListFacesByVertexIndices(); // This whole mess is because I can't find a way to regenerate // a probuilder mesh and therefore have to continually create/destroy gameobjects // (which is a mess in edit mode) // If anyone can explain how to simply take an existing probuilder object clear it // and pass in a list of Vector3's and lists of ordered indexes for faces // then please do. if (pbmesh != null && pbmesh.gameObject != null) { if (Application.isPlaying) { Destroy(pbmesh.gameObject); } else { var go = pbmesh.gameObject; UnityEditor.EditorApplication.delayCall += () => { DestroyImmediate(go); }; } } var colors = Enumerable.Range(0, 8).Select(x => Colors.Evaluate(((x / 8f) * ColorRange + ColorOffset) % 1)).ToArray(); pbmesh = ProBuilderMesh.Create(points, new List <Face>()); var faces = new List <PBFace>(); for (var i = 0; i < faceIndices.Length; i++) { var face = faceIndices[i]; var result = AppendElements.CreatePolygon(pbmesh, face, false); if (result != null) { pbmesh.SetFaceColor(result, colors[(int)poly.FaceRoles[i]]); faces.Add(result); } } if (faces.Count < 1 || pbmesh == null) { return; } pbmesh.SetMaterial(faces, material); pbmesh.ToMesh(); pbmesh.Refresh(); }
private void GenerateBuilding() { //Randomize height and width height = Random.Range(heigthMin, heightMax); width = Random.Range(widthMin, widthMax); var mainVertices = new Vector3[] { genCoords, genCoords + new Vector3(width, 0f), genCoords + new Vector3(0f, height), genCoords + new Vector3(width, height) }; var mainFace = new Face(new int[] { 1, 0, 3, 0, 2, 3 }); var faces = new List <Face> { mainFace }; var doorFace = CreateDoor(ref mainVertices); faces.Add(doorFace); var windowFaces = CreateWindows(ref mainVertices); faces.AddRange(windowFaces); var mesh = ProBuilderMesh.Create(mainVertices, faces); mesh.GetComponent <MeshRenderer>().sharedMaterials = new[] { wallMaterial, windowMaterial, doorMaterial }; mainFace.submeshIndex = 0; doorFace.submeshIndex = 2; var uvs = new List <Vector4>(); mesh.GetUVs(0, uvs); //Set UV for main face //mainFace.manualUV = true; //var mainFaceIndexes = mainFace.distinctIndexes; // uvs[mainFaceIndexes[0]] = new Vector4(1.18f, 0f); // uvs[mainFaceIndexes[1]] = new Vector4(0.82f, 0f); // uvs[mainFaceIndexes[2]] = new Vector4(1.18f, 1f); // uvs[mainFaceIndexes[3]] = new Vector4(0.82f, 1f); mainFace.uv = new AutoUnwrapSettings { scale = new Vector2(0.1f, 0.1f) }; //Set UV for all window faces foreach (var face in windowFaces) { face.submeshIndex = 1; //Window material face.manualUV = true; //Set UV coords var wIndexes = face.distinctIndexes; uvs[wIndexes[0]] = new Vector4(0.78f, 0.18f); uvs[wIndexes[1]] = new Vector4(0.22f, 0.18f); uvs[wIndexes[2]] = new Vector4(0.78f, 0.82f); uvs[wIndexes[3]] = new Vector4(0.22f, 0.82f); } mesh.SetUVs(0, uvs); //Materials overlap, extrude the windows a bit mesh.Extrude(windowFaces, ExtrudeMethod.FaceNormal, 0.01f); mesh.Extrude(new List <Face> { doorFace }, ExtrudeMethod.FaceNormal, 0.01f); mesh.ToMesh(); mesh.Refresh(); buildingsGenerated++; genCoords += new Vector3(0, 0, -30); //Move camera backwards to see the building var camera = FindObjectOfType <Camera>(); camera.transform.position += new Vector3(0, 0, -30); }