//Draws a polygon given a list of Vector3 that is a closed shape public GameObject dropPolygon(List <Vector3> shape, float height, Material material, GOUVMappingStyle uvMappingStyle) { GameObject polygon = new GameObject("Polygon"); MeshFilter filter = polygon.AddComponent <MeshFilter>(); MeshRenderer renderer = polygon.AddComponent <MeshRenderer>(); Poly2Mesh.Polygon poly = new Poly2Mesh.Polygon(); poly.outside = shape; GOMesh goMesh = Poly2Mesh.CreateMeshInBackground(poly); goMesh.uvMappingStyle = uvMappingStyle; goMesh.ApplyUV(shape); if (height > 0) { goMesh = SimpleExtruder.SliceExtrudePremesh(goMesh, height, 4f, 4f, 10f); } Mesh mesh = goMesh.ToSubmeshes(); filter.sharedMesh = mesh; renderer.material = material; polygon.AddComponent <MeshCollider> (); return(polygon); }
public static GOMesh PreloadLine(GOFeature feature) { if (feature.convertedGeometry.Count == 2 && feature.convertedGeometry[0].Equals(feature.convertedGeometry[1])) { return(null); } GOMesh preMesh = new GOMesh(); GOLineMesh lineMesh = new GOLineMesh(feature.convertedGeometry); lineMesh.width = feature.renderingOptions.lineWidth; preMesh = lineMesh.CreatePremesh(); if (feature.height > 0) { float h = feature.height; if (GOMap.GOLink) { h += GOFeature.BuildingElevationOffset; } preMesh = SimpleExtruder.SliceExtrudePremesh(preMesh, h + Noise(), 4f, 4f, 10f); } if (feature.renderingOptions.outlineWidth > 0) { lineMesh.width = feature.renderingOptions.lineWidth + feature.layer.defaultRendering.outlineWidth; preMesh.secondaryMesh = lineMesh.CreatePremesh(); } return(preMesh); }
private GOMesh MergeTempPolys(float distance) { foreach (GOTempPolyNew temp in polys) { AddPolygon(temp, temp.normal); } if (distance != 0f) { Push(distance); } if (bufIndices.Count == 0) { return(null); } GOMesh mesh = new GOMesh(); mesh.vertices = bufVertices.ToArray(); mesh.normals = bufNormals.ToArray(); mesh.uv = bufUVs.ToArray(); mesh.triangles = bufIndices.ToArray(); return(mesh); }
public static GOMesh SliceExtrudePremesh(GOMesh mesh, float height, float topSectionH, float bottomSectionH, float sliceHeight) { if (height < sliceHeight) { return(ExtrudePremesh(mesh, height)); } int numberOfSlices = (int)Mathf.Ceil((height) / sliceHeight); sliceHeight = height / numberOfSlices; List <Matrix4x4> extrusion = new List <Matrix4x4> (); for (int i = numberOfSlices; i > -1; i--) { Vector3 pos = Vector3.zero; pos.y = (i - 1) * sliceHeight; Matrix4x4 mat = Matrix4x4.TRS(pos + new Vector3(0, sliceHeight, 0), Quaternion.identity, Vector3.one); extrusion.Add(mat); } mesh.sliceHeight = sliceHeight; GOMeshExtrusion.ExtrudeMesh(mesh, mesh, extrusion.ToArray(), false); // FixPremeshUV (mesh,height); return(mesh); }
//Draws a line given a list of vector 3 public GameObject dropLine(List <Vector3> polyline, float witdh, float height, Material material, GOUVMappingStyle uvMappingStyle, bool curved = false) { GameObject line = new GameObject("Polyline"); MeshFilter filter = line.AddComponent <MeshFilter>(); MeshRenderer renderer = line.AddComponent <MeshRenderer>(); GOLineMesh lineMesh = new GOLineMesh(polyline, curved); lineMesh.width = witdh; lineMesh.load(line); GOMesh goMesh = lineMesh.CreatePremesh(); goMesh.uvMappingStyle = uvMappingStyle; if (height > 0) { goMesh = SimpleExtruder.SliceExtrudePremesh(goMesh, height, 4f, 4f, 10f); } filter.sharedMesh = goMesh.ToMesh(); renderer.material = material; line.AddComponent <MeshCollider> (); return(line); }
/// <summary> /// [ALAN GRANT] Create data for a Mesh in background containing just the FIRST triangle in the given Polygon. /// (This is a much easier task since we can skip triangulation.) /// </summary> /// <returns>The freshly minted mesh.</returns> /// <param name="polygon">Polygon you want to make a triangle of.</param> public static GOMesh CreateTriangleInBackground(Polygon polygon) { // long profileID = Profiler.Enter("Poly2Mesh.CreateTriangle"); if (fullDebug) { Debug.Log("Poly2Mesh.CreateTriangle 1"); } // Create the vertex array Vector3[] vertices = new Vector3[3]; vertices[0] = polygon.outside[0]; vertices[1] = polygon.outside[1]; vertices[2] = polygon.outside[2]; // Create the indices array int[] indices = new int[3] { 0, 1, 2 }; if (fullDebug) { Debug.Log("Poly2Mesh.CreateTriangle 2"); } // Create the UV list, by looking up the closest point for each in our poly Vector2[] uv = null; if (polygon.outsideUVs != null) { uv = new Vector2[3]; for (int i = 0; i < 3; i++) { uv[i] = polygon.ClosestUV(vertices[i]); } } if (fullDebug) { Debug.Log("Poly2Mesh.CreateTriangle 3"); } // Create the mesh if (fullDebug) { Debug.Log("Poly2Mesh.CreateTriangle 4"); } GOMesh preMesh = new GOMesh(); preMesh.vertices = vertices; preMesh.triangles = indices; preMesh.uv = uv; if (fullDebug) { Debug.Log("Poly2Mesh.CreateTriangle 5"); } // Profiler.Exit(profileID); return(preMesh); }
public GameObject CreateRoofFromPreloaded(GOFeature feature, GOMesh premesh, GameObject parent) { GameObject roof = GameObject.Instantiate(feature.goTile.featurePrototype, parent.transform); MeshFilter filter = roof.GetComponent <MeshFilter>(); filter.mesh = premesh.ToMesh(); return(roof); }
public GOMesh addEdge(GOMesh mesh, Vector3 center, bool flip) { List <Vector3> vertices = mesh.vertices.ToList(); List <int> roadTriangles = mesh.triangles.ToList(); List <Vector2> uvs = mesh.uv.ToList(); // Vector3 center = lastSegment.center; Vector3 normal = Vector3.down; //lastSegment.getNormal(); center = goFeature.goTile.altitudeToPoint(center); int edgeResolution = 10; // odd number only int vertsCount = mesh.vertices.Count(); vertices.Add(center); int indexOfCenter = vertices.IndexOf(center); Vector3 tangent; if (!flip) { tangent = (geometry[1] - geometry[0]).normalized; } else { tangent = (geometry [geometry.Count - 1] - geometry [geometry.Count - 2]).normalized; } List <Vector3> points = FindPoints(center, tangent, normal, width, edgeResolution, flip); vertices.AddRange(points); for (int i = 1; i <= points.Count; i++) { roadTriangles.Add(i + vertsCount); roadTriangles.Add(i + vertsCount - 1); roadTriangles.Add(indexOfCenter); } uvs.Add(new Vector2(0.5f, 0.5f)); for (int i = 0; i < edgeResolution; i++) { float n = i == edgeResolution - 1? i / (float)edgeResolution : i - 1 / (float)edgeResolution; float u = Mathf.Sin(180 * n * Mathf.Deg2Rad) / edgeResolution; float v = Mathf.Cos(180 * n * Mathf.Deg2Rad) / 2; uvs.Add(new Vector2(u, v)); } mesh.vertices = vertices.ToArray(); mesh.triangles = roadTriangles.ToArray(); mesh.uv = uvs.ToArray(); return(mesh); }
public GameObject CreateRoofFromPreloaded(GOMesh premesh) { GameObject roof = new GameObject(); MeshFilter filter = roof.AddComponent <MeshFilter>(); roof.AddComponent(typeof(MeshRenderer)); filter.mesh = premesh.ToMesh(); return(roof); }
public GOMesh CreatePremesh() { UpdateVertices(); GOMesh premesh = new GOMesh(); premesh.vertices = vertices; premesh.triangles = triangles; premesh.uv = uvs; return(premesh); }
public Mesh groundMesh() { updateVertices(); GOMesh goMesh = flatTerrainMesh(); if (goMesh == null) { return(null); } return(goMesh.ToMesh()); }
public static GOMesh PreloadLine(GOFeature feature) { if (feature.convertedGeometry.Count == 2 && feature.convertedGeometry[0].Equals(feature.convertedGeometry[1])) { return(null); } GOMesh preMesh = new GOMesh(); GOLineMesh lineMesh = new GOLineMesh(feature, true); lineMesh.width = feature.renderingOptions.lineWidth * feature.goTile.worldScale; preMesh = lineMesh.CreatePremesh(); feature.isLoop = lineMesh.isLoop; // GORoad road = new GORoad (feature, 25, 1, 0); // road.computeRoad (); // preMesh = road.goMesh; if (feature.goTile.useElevation && feature.height == 0) { feature.height += GOFeature.RoadsHeightForElevation; } if (feature.height > 0) { float h = feature.height * feature.goTile.worldScale; if (feature.goTile.useElevation) { h += GOFeature.BuildingElevationOffset; } preMesh = SimpleExtruder.ExtrudePremesh(preMesh, h + Noise(), false); } if (feature.renderingOptions.outlineWidth > 0 && !feature.goTile.useElevation) { lineMesh.width = (feature.renderingOptions.lineWidth + feature.layer.defaultRendering.outlineWidth) * feature.goTile.worldScale; preMesh.secondaryMesh = lineMesh.CreatePremesh(); if (feature.height > 0) { float h = feature.height * feature.goTile.worldScale; if (feature.goTile.useElevation) { h += GOFeature.BuildingElevationOffset; } preMesh.secondaryMesh = SimpleExtruder.ExtrudePremesh(preMesh.secondaryMesh, h + Noise(), false); } } return(preMesh); }
public static GOMesh ExtrudePremesh(GOMesh mesh, float height) { Matrix4x4 [] extrusionPath = new Matrix4x4 [2]; Matrix4x4 a = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one); Matrix4x4 b = Matrix4x4.TRS(Vector3.zero + new Vector3(0, height, 0), Quaternion.identity, Vector3.one); extrusionPath [0] = b; extrusionPath [1] = a; GOMeshExtrusion.ExtrudeMesh(mesh, mesh, extrusionPath, false); mesh.sliceHeight = height; // FixPremeshUV (mesh,height); return(mesh); }
public GOMesh flatTerrainMesh() { GOMesh mesh = new GOMesh(); mesh.vertices = vertices.ToArray(); mesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 }; mesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) }; return(mesh); }
//Outlined polygons are flat by nature and surrounded by an Outline just like roads public static GOMesh PreloadOutlinedPolygon(GOFeature feature) { if (feature.convertedGeometry == null) { return(null); } if (feature.convertedGeometry.Count == 2 && feature.convertedGeometry[0].Equals(feature.convertedGeometry[1])) { return(null); } GOMesh fillMesh = PreloadPolygon(feature); GOMesh outlineMesh = PreloadLine(feature); fillMesh.secondaryMesh = outlineMesh; return(fillMesh); }
public GOMesh CreatePremesh() { UpdateVertices(); GOMesh premesh = new GOMesh(); premesh.vertices = vertices; premesh.triangles = triangles; premesh.uv = uvs; if (!isLoop && goFeature != null) { premesh = addEdge(premesh, geometry [geometry.Count - 1], true); premesh = addEdge(premesh, geometry [0], false); } return(premesh); }
public GOMesh ProjectFeature(GOFeature feature, GOMesh terrainMesh, float distance) { Vector3[] vertices = terrainMesh.vertices; int[] triangles = terrainMesh.triangles; GOTempPolyNew poly; ComputeFeatureRanges(feature); for (int i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; Vector3 v1 = feature.goTile.position + vertices [i1]; Vector3 v2 = feature.goTile.position + vertices [i2]; Vector3 v3 = feature.goTile.position + vertices [i3]; Vector3 side1 = v2 - v1; Vector3 side2 = v3 - v1; Vector3 normal = Vector3.Cross(side1, side2).normalized; poly = new GOTempPolyNew(v1, v2, v3); poly.normal = normal; poly.indices.AddRange(new int[] { i1, i2, i3 }); poly.xRange = xRange; poly.zRange = zRange; // Profiler.BeginSample ("Wrap Polygon"); poly = poly.WrapPolygon(feature.convertedGeometry.ToArray(), terrainMesh); // Profiler.EndSample (); if (poly == null) { continue; } polys.Add(poly); } return(MergeTempPolys(distance)); }
public static GOMesh PreloadMesh() { if (bufIndices.Count == 0) { return(null); } GOMesh mesh = new GOMesh(); mesh.vertices = bufVertices.ToArray(); mesh.normals = bufNormals.ToArray(); mesh.uv = bufTexCoords.ToArray(); mesh.triangles = bufIndices.ToArray(); bufVertices.Clear(); bufNormals.Clear(); bufTexCoords.Clear(); bufIndices.Clear(); return(mesh); }
private static void FixPremeshUV(GOMesh mesh, float sliceH) { var newUvs = new Vector2[mesh.vertices.Length]; // Debug.Log (sliceH); Vector3 clippedPart = Vector3.zero; Vector3[] vertices = mesh.vertices; Vector3 vertex; Vector3 normal; for (var v = 0; v < vertices.Length; v++) { vertex = vertices[v]; // normal = new Vector3 (0.1f,0,0.1f); float textureSlice = 0.25f; //a quarter of image float sliceHOriginal = 10f; clippedPart.x = textureSlice * (sliceHOriginal / sliceH); // This gives a vector pointing up the roof: //Vector3 vAxis = Vector3.Scale(normal, new Vector3(-1, 0, -1)).normalized; Vector3 vAxisProto = Vector3.Scale(vertex, new Vector3(1, 1, 1)); // This will make the u axis perpendicular to the v axis (ie. parallel to the roof edge) Vector3 uAxis = new Vector3(vAxisProto.z, 0, -vAxisProto.x); // I originally used vAxis here, but changed to position.y so you get more predticable alignment at edges. // Set eaveHeight to the y coordinate of the bottom edge of the roof. // var uv = new Vector2(Vector3.Dot(vertex, uAxis), vertex.y) ; Vector2 uv = new Vector2(Vector3.Dot(vertex, vAxisProto) * clippedPart.x + clippedPart.z, vertex.y * clippedPart.x + clippedPart.y); //var uv = new Vector2(Vector3.Dot(vertex, uAxis), vertex.y * clippedPart.x + clippedPart.y) ; newUvs[v] = uv; } mesh.uv = newUvs; }
private static void FixPremeshUV(GOMesh mesh, float height) { var newUvs = new Vector2[mesh.vertices.Length]; Vector3 clippedPart = Vector3.zero; Vector3[] vertices = mesh.vertices; Vector3 vertex; Vector3 neg = new Vector3(-1, 0, -1); Vector3 uAxis = Vector3.zero; Vector2 uv = Vector3.zero; float textureSlice = 0.25f; //a quarter of image float formula = textureSlice * (mesh.heightOriginal / mesh.sliceHeight) / 10; for (var v = 0; v < vertices.Length; v++) { vertex = vertices[v]; // if (vertex.y == height) { // newUvs[v] = new Vector2(vertex.x, vertex.z)*0.1f; // continue; // } clippedPart.x = formula; Vector3 vAxis = neg.normalized; // This will make the u axis perpendicular to the v axis (ie. parallel to the roof edge) uAxis.x = vAxis.z; uAxis.z = -vAxis.x; uv.x = Vector3.Dot(vertex, uAxis) * clippedPart.x + clippedPart.z; uv.y = vertex.y * clippedPart.x + clippedPart.y; newUvs[v] = uv; } mesh.uv = newUvs; }
public GOTempPolyNew WrapPolygon(Vector3[] convertedGeometry, GOMesh terrainMesh) { bool[] positive = new bool[vertices.Count]; int positiveCount = 0; for (int i = 0; i < vertices.Count; i++) { positive [i] = ContainsPoint2D(convertedGeometry, vertices[i]); if (positive [i]) { positiveCount++; } } if (positiveCount == 0) { return(null); // Fully outside the shape } return(this); // Return all polygon that are partially inside the shape }
public static GOMesh CreateGrid (float size, int resolution) { resolution++; GOMesh goMesh = new GOMesh (); float factor = (size / (resolution - 1)); List<Vector3> vertices = new List<Vector3> (); List<int> triangles = new List<int> (); List<Vector2> uv = new List<Vector2> (); for (int i = 0; i < resolution; i++) { for (int j = 0; j < resolution; j++) { Vector3 vert = new Vector3 (factor * j, 0, factor * i) + new Vector3 (-size/2, 0 , -size/2); vertices.Add (vert); uv.Add (new Vector2 (vert.x,vert.z)/ (size/4)) ; if (i == 0 || j == 0) { continue; } List<int> tris = new List<int> { resolution * (i-1) + (j-1), resolution*i + (j-1), resolution * i + j, resolution*(i-1) +j, resolution * (i-1) + (j-1), resolution * i + j, }; triangles.AddRange (tris); } } goMesh.vertices = vertices.ToArray (); goMesh.triangles = triangles.ToArray (); goMesh.uv = uv.ToArray (); return goMesh; }
public static void ProjectFeature(GOFeature feature, GOMesh terrainMesh, float maxAngle) { Profiler.BeginSample("Project feature"); Vector3[] vertices = terrainMesh.vertices; int[] triangles = terrainMesh.triangles; GOTempPoly poly; for (int i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; Vector3 v1 = feature.goTile.position + vertices [i1]; Vector3 v2 = feature.goTile.position + vertices [i2]; Vector3 v3 = feature.goTile.position + vertices [i3]; Vector3 side1 = v2 - v1; Vector3 side2 = v3 - v1; Vector3 normal = Vector3.Cross(side1, side2).normalized; //// // if( Vector3.Angle(-Vector3.forward, normal) >= maxAngle ) // continue; // poly = new GOTempPoly(v1, v2, v3); poly = GOTempPoly.WrapPolygon(poly, feature.convertedGeometry.ToArray(), terrainMesh); if (poly == null) { continue; } AddPolygon(poly, normal); } Profiler.EndSample(); }
public static GOMesh SliceExtrudePremesh(GOMesh mesh, float height, float topSectionH, float bottomSectionH, float sliceHeight) { if (height < sliceHeight) { return(ExtrudePremesh(mesh, height)); } int numberOfSlices = (int)Mathf.Ceil((height) / sliceHeight); sliceHeight = height / numberOfSlices; mesh.sliceHeight = sliceHeight; mesh.heightOriginal = sliceHeight; List <Matrix4x4> extrusion = new List <Matrix4x4> (); for (int i = numberOfSlices; i > -1; i--) { float h = sliceHeight; Vector3 pos = Vector3.zero; pos.y = (i - 1) * h; Matrix4x4 mat = Matrix4x4.TRS(pos + new Vector3(0, h, 0), Quaternion.identity, Vector3.one); extrusion.Add(mat); if (numberOfSlices % 2 == 0 && i == 1 && mesh.uvMappingStyle == GOUVMappingStyle.TopFitSidesSliced) { extrusion.Add(mat); } } GOMeshExtrusion.ExtrudeMesh(mesh, mesh, extrusion.ToArray(), false); //FixPremeshUV (mesh, height); return(mesh); }
public static GOMesh Preload3DPolygon(GOFeature feature) { if (feature.convertedGeometry == null) { return(null); } if (feature.convertedGeometry.Count == 2 && feature.convertedGeometry[0].Equals(feature.convertedGeometry[1])) { return(null); } List <Vector3> clean = feature.convertedGeometry.Distinct().ToList(); if (clean == null || clean.Count <= 2) { return(null); } GOFeature3DMeshBuilderNew b = new GOFeature3DMeshBuilderNew(); GOMesh preMesh = b.ProjectFeature(feature, feature.goTile.goMesh, 0); return(preMesh); }
public static GOMesh PreloadPolygon(GOFeature feature) { if (feature.convertedGeometry == null) { return(null); } if (feature.convertedGeometry.Count == 2 && feature.convertedGeometry[0].Equals(feature.convertedGeometry[1])) { return(null); } List <Vector3> clean = feature.convertedGeometry.Distinct().ToList(); if (clean == null || clean.Count <= 2) { return(null); } Poly2Mesh.Polygon poly = new Poly2Mesh.Polygon(); poly.outside = feature.convertedGeometry; if (feature.clips != null) { foreach (List <Vector3> clipVerts in feature.clips) { poly.holes.Add(clipVerts); } } GOMesh goMesh = null; goMesh = Poly2Mesh.CreateMeshInBackground(poly); if (goMesh != null) { goMesh.uvMappingStyle = feature.layer.uvMappingStyle; goMesh.ApplyUV(feature.convertedGeometry); goMesh.Y = feature.y; if (feature.goTile.useElevation) { feature.ComputeHighestAltitude(); } if (feature.height > 0) { feature.height *= feature.goTile.worldScale; goMesh.secondaryMesh = new GOMesh(goMesh); float h = feature.height; if (feature.goTile.useElevation) { h += GOFeature.BuildingElevationOffset; } h += Noise(); goMesh.separateTop = feature.renderingOptions.hasRoof; if (feature.layer.slicedExtrusion) { goMesh = SimpleExtruder.SliceExtrudePremesh(goMesh, h, 4f, 4f, 10f * feature.goTile.worldScale); } else { goMesh = SimpleExtruder.ExtrudePremesh(goMesh, h); } } if (feature.height < feature.layer.colliderHeight) { float h = feature.layer.colliderHeight; h *= feature.goTile.worldScale; if (feature.goTile.useElevation) { h += GOFeature.BuildingElevationOffset; } goMesh.secondaryMesh = new GOMesh(goMesh); goMesh.secondaryMesh = SimpleExtruder.SliceExtrudePremesh(goMesh.secondaryMesh, h, 4f, 4f, 10f * feature.goTile.worldScale); } } return(goMesh); }
public static GOMesh PreloadPolygon(GOFeature feature) { if (feature.convertedGeometry == null) { return(null); } if (feature.convertedGeometry.Count == 2 && feature.convertedGeometry[0].Equals(feature.convertedGeometry[1])) { return(null); } List <Vector3> clean = feature.convertedGeometry.Distinct().ToList(); if (clean == null || clean.Count <= 2) { return(null); } Poly2Mesh.Polygon poly = new Poly2Mesh.Polygon(); poly.outside = feature.convertedGeometry; if (feature.clips != null) { foreach (List <Vector3> clipVerts in feature.clips) { poly.holes.Add(clipVerts); } } GOMesh preMesh = null; preMesh = Poly2Mesh.CreateMeshInBackground(poly); if (preMesh != null) { // if (feature.layer.layerType != GOLayer.GOLayerType.Buildings) { Vector2[] uvs = new Vector2[preMesh.vertices.Length]; Vector3[] vertices = preMesh.vertices; for (int i = 0; i < uvs.Length; i++) { uvs [i] = new Vector2(vertices [i].x, vertices [i].z) * 0.01f; } preMesh.uv = uvs; // } if (feature.goTile.useElevation) { feature.ComputeHighestAltitude(); } // feature.height += GOFeature.BuildingElevationOffset; if (feature.height > 0) { feature.height *= feature.goTile.worldScale; preMesh.secondaryMesh = new GOMesh(preMesh); float h = feature.height; if (feature.goTile.useElevation) { h += GOFeature.BuildingElevationOffset; } h += Noise(); preMesh.separateTop = feature.renderingOptions.hasRoof; preMesh = SimpleExtruder.SliceExtrudePremesh(preMesh, h, 4f, 4f, 10f * feature.goTile.worldScale); } } return(preMesh); }
public virtual IEnumerator CreatePolygon (GOTile tile, bool delayedLoad) { Profiler.BeginSample ("[GOFeature] CreatePolygon ALLOC"); GOFeatureMeshBuilder builder = new GOFeatureMeshBuilder(this); Profiler.EndSample (); Profiler.BeginSample ("[GOFeature] CreatePolygon Material"); //Materials Material material = tile.GetMaterial(renderingOptions,builder.center); Material roofMat = renderingOptions.roofMaterial; if (sort != 0) { if (material) material.renderQueue = -(int)sort; if (roofMat) roofMat.renderQueue = -(int)sort; } Profiler.EndSample (); Profiler.BeginSample ("[GOFeature] CreatePolygon Center"); //Group buildings by center coordinates if (layer.layerType == GOLayer.GOLayerType.Buildings && defaultRendering) { GameObject centerContainer = tile.findNearestCenter(builder.center,parent,material); parent = centerContainer; material = centerContainer.GetComponent<GOMatHolder> ().material; } Profiler.EndSample(); if (!layer.useRealHeight) { height = renderingOptions.polygonHeight; } int offset = 0; float trueHeight = height; #if GOLINK if (GOMap.GOLink) { trueHeight += BuildingElevationOffset; //[GOLINK] GOTerrain link (This requires GOTerrain! https://www.assetstore.unity3d.com/#!/content/84198) if (tile.map.goTerrain != null) { offset = BuildingElevationOffset; if (y < offset) y = tile.map.goTerrain.FindAltitudeForVector(builder.center)-offset; } } #endif Profiler.BeginSample ("[GOFeature] CreatePolygon MESH"); GameObject polygon = null; if (preloadedMeshData != null) polygon = builder.BuildPolygonFromPreloaded(this); else if (tile.map.mapType == GOMap.GOMapType.MapzenJson) //ONLY FOR JSON polygon = builder.BuildPolygon(layer,trueHeight+offset); Profiler.EndSample (); if (polygon == null) yield break; polygon.name = name; polygon.transform.parent = parent.transform; //Layer mask if (layer.useLayerMask == true) { tile.AddObjectToLayerMask (layer, polygon); } if (renderingOptions.tag.Length > 0) { polygon.tag = renderingOptions.tag; } if (layer.useRealHeight && roofMat != null) { Profiler.BeginSample ("[GOFeature] CreatePolygon ROOF"); GameObject roof; if (preloadedMeshData != null && preloadedMeshData.secondaryMesh != null) roof = builder.CreateRoofFromPreloaded (preloadedMeshData.secondaryMesh); else roof = builder.CreateRoof(); roof.name = "roof"; roof.transform.parent = polygon.transform; roof.GetComponent<MeshRenderer> ().material = roofMat; roof.transform.position = new Vector3 (roof.transform.position.x,trueHeight+0.11f,roof.transform.position.z); roof.tag = polygon.tag; roof.layer = polygon.layer; Profiler.EndSample (); } Profiler.BeginSample ("[GOFeature] TRANSFORM"); Vector3 pos = polygon.transform.position; pos.y = y; if (layer.layerType == GOLayer.GOLayerType.Buildings) y += GOFeatureMeshBuilder.Noise (); polygon.transform.position = pos; polygon.transform.localPosition = pos; GOFeatureBehaviour fb = polygon.AddComponent<GOFeatureBehaviour> (); fb.goFeature = this; builder.meshRenderer.material = material; if (layer.OnFeatureLoad != null) { layer.OnFeatureLoad.Invoke(builder.mesh,layer,kind, builder.center); } Profiler.EndSample (); preloadedMeshData = null; if (delayedLoad) yield return null; }
public GOMesh elevatedTerrainMesh() { GODEMTexture2D terrainTex = getTerrainData(); GODEMTexture2D normalTex = getNormalsData(); GOMesh terrainMesh = new GOMesh(); terrainMesh.name = "Elevated terrain - " + name; Vector3[] vertices; Vector3[] normals; Color[] colors; Vector2 offset = Vector2.zero; vertices = new Vector3[(((int)resolution.x + 1) * ((int)resolution.y + 1))]; colors = new Color[vertices.Length]; normals = new Vector3[vertices.Length]; Vector2[] uv = new Vector2[vertices.Length]; float stepSizeWidth = tileSize.x / resolution.x; float stepSizeHeight = tileSize.y / resolution.y; for (int v = 0, z = 0; z < (int)resolution.y + 1; z++) { for (int x = 0; x < (int)resolution.x + 1; x++) { Color32 c32 = terrainTex.calculateColor(new Vector2(x, z), offset, resolution); float height = terrainTex.ConvertColorToAltitude(c32); height = height * elevationMultiplier; vertices[v] = new Vector3(x * stepSizeWidth + offset.x, height, z * stepSizeHeight + offset.y); vertices [v] -= new Vector3(tileSize.x / 2, 0, tileSize.y / 2); colors [v] = c32; if (normalTex != null) { Color32 c32Normal = normalTex.calculateColor(new Vector2(x, z), offset, resolution); normals [v] = new Vector3(c32Normal.r, c32Normal.g, c32Normal.b); } else { normals [v] = Vector3.up; } uv[v] = new Vector2(x / resolution.x, z / resolution.y); v++; } } for (int v = 0, z = 0; z < (int)resolution.y + 1; z++) { for (int x = 0; x < (int)resolution.x + 1; x++) { if (topTile != null && topTile.goMesh != null && z == (int)resolution.y) { int pos = x; vertices [v] = TrasformVectorReferences(this, topTile, topTile.goMesh.vertices[pos]); } if (leftTile != null && leftTile.goMesh != null && x == 0) { int pos = (z + 1) * (int)resolution.x + z; vertices [v] = TrasformVectorReferences(this, leftTile, leftTile.goMesh.vertices[pos]); } if (rightTile != null && rightTile.goMesh != null && x == (int)resolution.x) { int pos = z * ((int)resolution.x + 1); vertices [v] = TrasformVectorReferences(this, rightTile, rightTile.goMesh.vertices[pos]); } if (bottomTile != null && bottomTile.goMesh != null && z == 0) { int pos = bottomTile.goMesh.vertices.Count() - ((int)resolution.x + 1) + x; vertices [v] = TrasformVectorReferences(this, bottomTile, bottomTile.goMesh.vertices[pos]); } v++; } } int[] triangles = new int[((int)resolution.x) * ((int)resolution.y) * 2 * 3]; float[] heightCheck = new float [6]; for (int v = 0, t = 0, z = 0; z < (int)resolution.y; z++, t++) { for (int x = 0; x < (int)resolution.x; x++, v += 6, t++) { triangles [v] = t; triangles [v + 1] = t + (int)resolution.x + 1; triangles [v + 2] = t + 1; triangles [v + 3] = t + 1; triangles [v + 4] = t + (int)resolution.x + 1; triangles [v + 5] = t + (int)resolution.x + 2; //Checks spike map errors heightCheck[0] = vertices [triangles [v]].y; heightCheck[1] = vertices [triangles [v + 1]].y; heightCheck[2] = vertices [triangles [v + 2]].y; heightCheck[3] = vertices [triangles [v + 3]].y; heightCheck[4] = vertices [triangles [v + 4]].y; heightCheck[5] = vertices [triangles [v + 5]].y; float mean = 0.0f; float meanAbs = 0.0f; float standardDeviation = 0.0f; foreach (float height in heightCheck) { mean += height / 6.0f; meanAbs += Mathf.Abs(height) / 6.0f; standardDeviation += (height * height); } standardDeviation = standardDeviation / 6.0f; float variance = standardDeviation; standardDeviation = Mathf.Sqrt(variance); float newMean = 0.0f; int meanCount = 0; for (int i = 0; i < heightCheck.Count(); i++) { if (variance > 100 && Mathf.Abs(heightCheck [i]) > standardDeviation + meanAbs) { // CreateDebugSphere ( vertices[triangles[v+i]] + Vector3.up,"spikes STD" + standardDeviation + " " + variance,10,null); } else { meanCount++; newMean += heightCheck [i]; } } newMean = newMean / meanCount; for (int i = 0; i < heightCheck.Count(); i++) { if (variance > 200 && Mathf.Abs(heightCheck [i]) > standardDeviation + meanAbs) { vertices [triangles [v + i]] = new Vector3(vertices [triangles [v + i]].x, newMean, vertices [triangles [v + i]].z); } } } } terrainMesh.vertices = vertices; terrainMesh.normals = normals; terrainMesh.uv = uv; terrainMesh.triangles = triangles; goMesh = terrainMesh; return(goMesh); }
public virtual IEnumerator CreatePolygon(GOTile tile, bool delayedLoad) { // // if (layer.layerType == GOLayer.GOLayerType.Buildings && name != "Whitehall Building Annex") // yield break; Profiler.BeginSample("[GOFeature] CreatePolygon ALLOC"); GOFeatureMeshBuilder builder = new GOFeatureMeshBuilder(this); this.featureCenter = new Vector3(2, builder.center.y, 8); //new Vector3 (builder.center.x, builder.center.y, builder.center.z); Profiler.EndSample(); Material material = null; Material roofMat = null; if (layer.layerType == GOLayer.GOLayerType.Buildings && defaultRendering && renderingOptions.materials.Length != 0) { Profiler.BeginSample("[GOFeature] CreatePolygon Center"); GOCenterContainer centerContainer = tile.findNearestCenter(builder.center, parent); Profiler.EndSample(); if (centerContainer.material == null) { Profiler.BeginSample("[GOFeature] CreatePolygon Material"); centerContainer.material = tile.GetMaterial(renderingOptions, builder.center); centerContainer.secondaryMaterial = renderingOptions.roofMaterial; Profiler.EndSample(); } material = centerContainer.material; roofMat = centerContainer.secondaryMaterial; } else { Profiler.BeginSample("[GOFeature] CreatePolygon Material"); //Materials material = tile.GetMaterial(renderingOptions, builder.center); roofMat = renderingOptions.roofMaterial; Profiler.EndSample(); } if (sort != 0) { if (material) { material.renderQueue = -(int)sort; } if (roofMat) { roofMat.renderQueue = -(int)sort; } } if (!layer.useRealHeight) { height = renderingOptions.polygonHeight; } float offset = 0; float trueHeight = height; if (goTile.useElevation && layer.layerType == GOLayer.GOLayerType.Buildings) { trueHeight += BuildingElevationOffset; offset = BuildingElevationOffset; if (y < offset) { y = highestAltitudeVertex - offset + 0.5f; } // y = goTile.altitudeForPoint(builder.center)-offset+0.5f; } Profiler.BeginSample("[GOFeature] CreatePolygon MESH"); GameObject polygon = null; if (preloadedMeshData != null) { polygon = builder.BuildPolygonFromPreloaded(this, parent); } Profiler.EndSample(); if (polygon == null) { yield break; } polygon.name = name; //Layer mask if (layer.useLayerMask == true) { tile.AddObjectToLayerMask(layer, polygon); } if (renderingOptions.tag.Length > 0) { polygon.tag = renderingOptions.tag; } if (renderingOptions.hasRoof) { Material[] mats = new Material[2]; mats [0] = material; mats [1] = roofMat; MeshRenderer mr = polygon.GetComponent <MeshRenderer> (); mr.shadowCastingMode = layer.castShadows; mr.materials = mats; } else { builder.meshRenderer.material = material; builder.meshRenderer.shadowCastingMode = layer.castShadows; } Profiler.BeginSample("[GOFeature] TRANSFORM"); Vector3 pos = polygon.transform.position; pos.y = y; if (layer.layerType == GOLayer.GOLayerType.Buildings) { y += GOFeatureMeshBuilder.Noise(); } polygon.transform.position = pos; polygon.transform.localPosition = pos; if (goTile.addGoFeatureComponents) { GOFeatureBehaviour fb = polygon.AddComponent <GOFeatureBehaviour> (); fb.goFeature = this; } if (layer.OnFeatureLoad != null) { layer.OnFeatureLoad.Invoke(this, polygon); } Profiler.EndSample(); preloadedMeshData = null; if (delayedLoad) { yield return(null); } }