public override InputGeometry Generate(double param0, double param1, double param2) { int numRays = GetParamValueInt(0, param0); InputGeometry input = new InputGeometry(numRays + 4); input.AddPoint(0, 0); // Center double x, y, r, e, step = 2 * Math.PI / numRays; for (int i = 0; i < numRays; i++) { e = Util.Random.NextDouble() * step * 0.7; r = (Util.Random.NextDouble() + 0.7) * 0.5; x = r * Math.Cos(i * step + e); y = r * Math.Sin(i * step + e); input.AddPoint(x, y, 2); input.AddSegment(0, i + 1, 2); } input.AddPoint(-1, -1, 1); // Box input.AddPoint(1, -1, 1); input.AddPoint(1, 1, 1); input.AddPoint(-1, 1, 1); numRays = input.Count; input.AddSegment(numRays - 1, numRays - 2, 1); input.AddSegment(numRays - 2, numRays - 3, 1); input.AddSegment(numRays - 3, numRays - 4, 1); input.AddSegment(numRays - 4, numRays - 1, 1); return(input); }
/// <summary> /// Read vertex information of the given line. /// </summary> /// <param name="data">The input geometry.</param> /// <param name="index">The current vertex index.</param> /// <param name="line">The current line.</param> /// <param name="attributes">Number of point attributes</param> /// <param name="marks">Number of point markers (0 or 1)</param> static void ReadVertex(InputGeometry data, int index, string[] line, int attributes, int marks) { double x = double.Parse(line[1], nfi); double y = double.Parse(line[2], nfi); int mark = 0; double[] attribs = attributes == 0 ? null : new double[attributes]; // Read the vertex attributes. for (int j = 0; j < attributes; j++) { if (line.Length > 3 + j) { attribs[j] = double.Parse(line[3 + j]); } } // Read a vertex marker. if (marks > 0 && line.Length > 3 + attributes) { mark = int.Parse(line[3 + attributes]); } data.AddPoint(x, y, mark, attribs); }
public static UnityEngine.Mesh Mesh(this Polygon this_, string name = "") { // Create geometry. InputGeometry geometry = this_.InputGeometry(); // Triangulate. TriangleNet.Mesh triangulatedMesh = new TriangleNet.Mesh(); triangulatedMesh.Triangulate(geometry); // Counts. int vertexCount = triangulatedMesh.vertices.Count; int triangleCount = triangulatedMesh.triangles.Count; // Debug.Log("Mesh.vertexCount ("+vertexCount+")"); // NumberOfInputPoints // Debug.Log("Mesh.triangleCount ("+triangleCount+")"); // NumberOfInputPoints // Mesh store. Vector3[] _vertices = new Vector3[vertexCount]; Vector2[] _uv = new Vector2[vertexCount]; Vector3[] _normals = new Vector3[vertexCount]; int[] _triangles = new int[triangleCount * 3]; foreach (KeyValuePair <int, TriangleNet.Data.Vertex> eachEntry in triangulatedMesh.vertices) { int index = eachEntry.Key; TriangleNet.Data.Vertex eachVertex = eachEntry.Value; _vertices[index] = new Vector3( (float)eachVertex.x, (float)eachVertex.y, 0.0f // As of 2D ); _uv[index] = _vertices[index]; _normals[index] = Vector3.forward; } int cursor = 0; foreach (KeyValuePair <int, TriangleNet.Data.Triangle> eachPair in triangulatedMesh.triangles) { TriangleNet.Data.Triangle eachTriangle = eachPair.Value; _triangles[cursor] = eachTriangle.P2; _triangles[cursor + 1] = eachTriangle.P1; _triangles[cursor + 2] = eachTriangle.P0; cursor += 3; } // Create / setup mesh. Mesh mesh = new Mesh(); mesh.vertices = _vertices; mesh.uv = _uv; mesh.normals = _normals; mesh.subMeshCount = 1; mesh.SetTriangles(_triangles, 0); mesh.name = name; return(mesh); }
/// <summary> /// Rebuild the input geometry. /// </summary> private InputGeometry Rebuild() { InputGeometry geometry = new InputGeometry(mesh.vertices.Count); foreach (var vertex in mesh.vertices.Values) { geometry.AddPoint(vertex.x, vertex.y, vertex.mark); } foreach (var segment in mesh.subsegs.Values) { geometry.AddSegment(segment.P0, segment.P1, segment.Boundary); } foreach (var hole in mesh.holes) { geometry.AddHole(hole.x, hole.y); } foreach (var region in mesh.regions) { geometry.AddRegion(region.point.x, region.point.y, region.id); } return(geometry); }
public void HandleNewInput(InputGeometry geometry) { // Reset labels lbNumVert2.Text = "-"; lbNumTri2.Text = "-"; lbNumSeg2.Text = "-"; lbNumVert.Text = geometry.Count.ToString(); lbNumSeg.Text = geometry.Segments.Count().ToString(); lbNumTri.Text = "0"; // Statistics labels lbAreaMin.Text = "-"; lbAreaMax.Text = "-"; lbEdgeMin.Text = "-"; lbEdgeMax.Text = "-"; lbAngleMin.Text = "-"; lbAngleMax.Text = "-"; // Quality labels lbQualAlphaMin.Text = "-"; lbQualAlphaAve.Text = "-"; lbQualAspectMin.Text = "-"; lbQualAspectAve.Text = "-"; angleHistogram1.SetData(null, null); }
public void HandleMeshImport(InputGeometry geometry, Mesh mesh) { // Previous mesh stats lbNumVert2.Text = "-"; lbNumTri2.Text = "-"; lbNumSeg2.Text = "-"; }
public static InputGeometry Read(string filename) { InputGeometry inputGeometry = null; FileReader.Read(filename, out inputGeometry); return(inputGeometry); }
private static void ReadVertex(InputGeometry data, int index, string[] line, int attributes, int marks) { double[] numArray; double num = double.Parse(line[1], FileReader.nfi); double num1 = double.Parse(line[2], FileReader.nfi); int num2 = 0; if (attributes == 0) { numArray = null; } else { numArray = new double[attributes]; } double[] numArray1 = numArray; for (int i = 0; i < attributes; i++) { if ((int)line.Length > 3 + i) { numArray1[i] = double.Parse(line[3 + i]); } } if (marks > 0 && (int)line.Length > 3 + attributes) { num2 = int.Parse(line[3 + attributes]); } data.AddPoint(num, num1, num2, numArray1); }
private void CreatePolygonMesh(Vector2d[] points, ref UnityEngine.Mesh mesh) { var inp = new InputGeometry(points.Length); int i = 0; foreach (var p in points) { var localMercPos = p - Tile.Rect.Center; inp.AddPoint(localMercPos.x, localMercPos.y); inp.AddSegment(i, (i + 1) % points.Length); i++; } var md = new MeshData(); CreateMesh(inp, md); //I want object center to be in the middle of object, not at the corner of the tile var center = ChangeToRelativePositions(md.Vertices); transform.localPosition = center; mesh.vertices = md.Vertices.ToArray(); mesh.triangles = md.Indices.ToArray(); mesh.SetUVs(0, md.UV); mesh.RecalculateNormals(); }
public override InputGeometry Generate(double param0, double param1, double param2) { // Number of points on the outer circle int n = GetParamValueInt(0, param0); int count, npoints; double radius = GetParamValueInt(1, param1); // Step size on the outer circle double h = 2 * Math.PI * radius / n; // Current radius and step size double r, dphi; InputGeometry input = new InputGeometry(n + 1); // Inner cirlce (radius = 1) r = 1; npoints = (int)(2 * Math.PI * r / h); dphi = 2 * Math.PI / npoints; for (int i = 0; i < npoints; i++) { input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 1); input.AddSegment(i, (i + 1) % npoints, 1); } count = input.Count; // Center cirlce r = (radius + 1) / 2.0; npoints = (int)(2 * Math.PI * r / h); dphi = 2 * Math.PI / npoints; for (int i = 0; i < npoints; i++) { input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 2); input.AddSegment(count + i, count + (i + 1) % npoints, 2); } count = input.Count; // Outer cirlce r = radius; npoints = (int)(2 * Math.PI * r / h); dphi = 2 * Math.PI / npoints; for (int i = 0; i < npoints; i++) { input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 3); input.AddSegment(count + i, count + (i + 1) % npoints, 3); } input.AddHole(0, 0); // Regions: |++++++|++++++|---| // r 1 0 input.AddRegion((r + 3.0) / 4.0, 0, 1); input.AddRegion((3 * r + 1.0) / 4.0, 0, 2); return(input); }
public static InputGeometry InputGeometry(this Polygon this_) { InputGeometry geometry = new InputGeometry(); int boundary; // Add points. boundary = 1; int pointIndexOffset = 0; this_.EnumeratePolygons((Polygon eachPolygon) => { // Add points. this_.EnumeratePoints((Vector2 eachPoint) => { geometry.AddPoint( (double)eachPoint.x, (double)eachPoint.y, boundary); }); this_.EnumerateEdges((EPPZ.Geometry.Edge eachEdge) => { int index_a = eachEdge.vertexA.index + pointIndexOffset; int index_b = eachEdge.vertexB.index + pointIndexOffset; geometry.AddSegment(index_a, index_b, boundary); }); pointIndexOffset += eachPolygon.vertexCount; // Track point offsets. boundary++; }); return geometry; }
/// <summary> /// Add a polygon ring to the geometry and make it a hole. /// </summary> /// <remarks> /// WARNING: This works for convex polygons, but not for non-convex regions in general. /// </remarks> /// <param name="points">List of points which make up the hole.</param> /// <param name="mark">Common boundary mark for all segments of the hole.</param> public static void AddRingAsHole(this InputGeometry geometry, IEnumerable <Point> points, int mark = 0) { // Save the current number of points. int N = geometry.Count; // Hole coordinates float x = 0.0f; float y = 0.0f; int m = 0; foreach (var pt in points) { x += pt.X; y += pt.Y; geometry.AddPoint(pt.X, pt.Y, pt.Boundary, pt.Attributes); m++; } for (int i = 0; i < m; i++) { geometry.AddSegment(N + i, N + ((i + 1) % m), mark); } geometry.AddHole(x / m, y / m); }
private int CreateRoofTriangulation(List <Vector3> corners, float height, MeshData data) { _mesh = new TriangleNet.Mesh(); var inp = new InputGeometry(corners.Count); for (int i = 0; i < corners.Count; i++) { var v = corners[i]; inp.AddPoint(v.x, v.z); inp.AddSegment(i, (i + 1) % corners.Count); } _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine; _mesh.Behavior.Quality = true; _mesh.Triangulate(inp); var vertsStartCount = data.Vertices.Count; data.Vertices.AddRange(corners.Select(x => new Vector3(x.x, height, x.z)).ToList()); foreach (var tri in _mesh.Triangles) { data.Indices.Add(vertsStartCount + tri.P1); data.Indices.Add(vertsStartCount + tri.P0); data.Indices.Add(vertsStartCount + tri.P2); } return(vertsStartCount); }
/// <summary> /// 调用该函数进行Triangleç½‘æ ¼åˆ’åˆ† /// </summary> public void Triangulate_Refine() { Out = false; _mesh = new Mesh(); InputGeometry input = FileReader.ReadPolyFile(File_Name); MP.QN_Ini = input.Count; if (MP.MinAngle_Tri > 0 && MP.MinAngle_Tri < 180) { _mesh.Behavior.MinAngle = MP.MinAngle_Tri; } try { _mesh.Triangulate(input); Out = true; } catch { } if (Out == false) { return; } else { Out = Refine(MP.MaxArea_Tri, MP.MaxAngle_Tri, MP.MinAngle_Tri, ref _mesh); } return; }
private static bool Triangulate_Refine(string File_Name, Mesh_Para MP) { bool Out = false; mesh = new Mesh(); input = FileReader.ReadPolyFile(File_Name); MP.QN_Ini = input.Count; if (MP.MinAngle_Tri > 0 && MP.MinAngle_Tri < 180) { mesh.Behavior.MinAngle = MP.MinAngle_Tri; } try { mesh.Triangulate(input); Out = true; } catch (System.Exception ex) { } if (Out == false) { return(Out); } else { Out = Refine(MP.MaxArea_Tri, MP.MaxAngle_Tri, MP.MinAngle_Tri); } return(Out); }
public WaterSurfacePolygon(List<Point> points) { mesh = new TriangleNet.Mesh(); mesh.Behavior.Quality = true; this.points = points; triangleNormals = new List<Point>(); trianglePlaneEquationDs = new List<double>(); InputGeometry geomtery = new InputGeometry(); for (int i = 0; i < points.Count; i++) { Point p = points[i]; if (i == 0) { minX = maxX = p.X; minY = maxY = p.Y; minZ = maxZ = p.Z; } else { minX = Math.Min(p.X, minX); maxX = Math.Max(p.X, maxX); minY = Math.Min(p.Y, minY); maxY = Math.Max(p.Y, maxY); minZ = Math.Min(p.Z, minZ); maxZ = Math.Max(p.Z, maxZ); } geomtery.AddPoint(p.X, p.Y, 0, p.Z); //add segments if (i > 0) { geomtery.AddSegment(i - 1, i, 0); } if (i == points.Count - 1) { geomtery.AddSegment(i, 0, 0); } } mesh.Triangulate(geomtery); triangles = new List<TriangleNet.Data.Triangle>(); foreach (TriangleNet.Data.Triangle tr in mesh.Triangles) { if (tr.P0 < points.Count && tr.P1 < points.Count && tr.P2 < points.Count) { triangles.Add(tr); } } calculateNormalsAndDs(); }
public void OnRenderObject(NavmeshBuild build) { if (mEnabled && mShow && build && build.HasInputData) { InputGeometry geom = build.InputGeom; DebugDraw.Bounds(geom.BoundsMin.ToUnityVector3(), geom.BoundsMax.ToUnityVector3(), Color.grey); } }
public Triangle_2D() { TriangleMesh = new TriangleNet.Mesh(); Geometry = new InputGeometry(); InnerHole = new List <List <Point> >(); InnerPolygon = new List <List <Point> >(); OuterPolygon = new List <List <Point> >(); }
private void WriteGeometry(InputGeometry geometry) { StreamWriter streamWriter = this.stream; int num = this.iteration; this.iteration = num + 1; streamWriter.WriteLine("#!G{0}", num); }
protected override GameObject CreateLayer(Tile tile, List <JSONObject> items) { var main = new GameObject("Landuse Layer"); var _meshes = new Dictionary <LanduseKind, MeshData>(); foreach (var geo in items.Where(x => Query(x))) { var kind = geo["properties"]["kind"].str.ConvertToLanduseType(); if (!FactorySettings.HasSettingsFor(kind) && !JustDrawEverythingFam) { continue; } //var typeSettings = FactorySettings.GetSettingsFor<LanduseSettings>(kind); if (!_meshes.ContainsKey(kind)) { _meshes.Add(kind, new MeshData()); } //foreach (var bb in geo["geometry"]["coordinates"].list) //{ var bb = geo["geometry"]["coordinates"].list[0]; //this is wrong but cant fix it now var count = bb.list.Count - 1; if (count < 3) { continue; } var inp = new InputGeometry(count); for (int i = 0; i < count; i++) { var c = bb.list[i]; var dotMerc = GM.LatLonToMeters(c[1].f, c[0].f); var localMercPos = dotMerc - tile.Rect.Center; inp.AddPoint(localMercPos.x, localMercPos.y); inp.AddSegment(i, (i + 1) % count); } CreateMesh(inp, _meshes[kind]); if (_meshes[kind].Vertices.Count > 64000) { CreateGameObject(kind, _meshes[kind], main.transform); _meshes[kind] = new MeshData(); } //} } foreach (var group in _meshes) { CreateGameObject(group.Key, group.Value, main.transform); } return(main); }
protected override GameObject CreateLayer(Tile tile, List<JSONObject> items) { var main = new GameObject("Earth Layer"); var meshes = new Dictionary<EarthType, MeshData>(); foreach (var geo in items.Where(x => Query(x))) { var kind = geo["properties"].HasField("kind") ? geo["properties"]["kind"].str.ConvertToEarthType() : EarthType.Earth; var typeSettings = FactorySettings.GetSettingsFor<EarthSettings>(kind); //if we dont have a setting defined for that, it'Ll be merged to "unknown" if (!FactorySettings.HasSettingsFor(kind)) kind = EarthType.Earth; if (!meshes.ContainsKey(kind)) meshes.Add(kind, new MeshData()); foreach (var bb in geo["geometry"]["coordinates"].list) { var jo = (bb.list[0].list[0].IsArray) ? bb.list[0] : bb; var count = jo.list.Count - 1; if (count < 3) continue; var inp = new InputGeometry(count); for (int i = 0; i < count; i++) { var c = jo.list[i]; var dotMerc = GM.LatLonToMeters(c[1].f, c[0].f); var localMercPos = dotMerc - tile.Rect.Center; inp.AddPoint(localMercPos.x, localMercPos.y); inp.AddSegment(i, (i + 1) % count); } //create mesh, actually just to get vertice&indices //filling last two parameters, horrible call yea CreateMesh(inp, meshes[kind]); //unity cant handle more than 65k on single mesh //so we'll finish current and start a new one if (meshes[kind].Vertices.Count > 64000) { CreateGameObject(kind, meshes[kind], main.transform); meshes[kind] = new MeshData(); } } } foreach (var group in meshes) { CreateGameObject(group.Key, group.Value, main.transform); } return main; }
private static ICollection <Triangle> Triangulate(InputGeometry input) { TriangleNet.Mesh mesh = new TriangleNet.Mesh(); mesh.Behavior.ConformingDelaunay = true; mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine; mesh.Behavior.Convex = false; mesh.Triangulate(input); return(mesh.Triangles); }
public static void Write(InputGeometry geometry, string filename) { using (StreamWriter writer = new StreamWriter(filename)) { WritePoints(writer, geometry.Points, geometry.Count); WriteSegments(writer, geometry.Segments); WriteHoles(writer, geometry.Holes); } }
public static void OnGUIButtons(NavmeshBuild build , NMGenConfig config , bool isInspector) { if (!build) { return; } if (build.HasBuildData) { // Not an option if the build is in progress. return; } if (isInspector) { EditorGUILayout.BeginHorizontal(); } if (GUILayout.Button("Clean")) { config.Clean(); config.ApplyDecimalLimits(); GUI.changed = true; } if (GUILayout.Button("Reset")) { config.Reset(); GUI.changed = true; } if (!isInspector) { GUILayout.Space(2 * MarginSize); } if (build.HasInputData) { if (GUILayout.Button("Derive")) { InputGeometry geom = build.InputGeom; config.Derive(geom.BoundsMin, geom.BoundsMax); config.ApplyDecimalLimits(); GUI.changed = true; } } if (isInspector) { EditorGUILayout.EndHorizontal(); } }
void frmGenerator_InputGenerated(object sender, EventArgs e) { this.input = sender as InputGeometry; if (input != null) { settings.CurrentFile = "tmp-" + DateTime.Now.ToString("HH-mm-ss"); HandleNewInput(); } }
/// <summary> /// /// </summary> /// <param name="filename"></param> /// <returns></returns> public InputGeometry Read(string filename) { ParseJson(filename); InputGeometry data = new InputGeometry(); if (json == null) { // TODO: Exception? return(data); } if (json.ContainsKey("config")) { } int count = 0; if (json.ContainsKey("points")) { var points = json["points"] as Dictionary <string, object>; if (points != null) { ReadPoints(data, points, ref count); } else { // TODO: Exception? return(data); } } if (json.ContainsKey("segments")) { var segments = json["segments"] as Dictionary <string, object>; if (segments != null) { ReadSegments(data, segments, count); } } if (json.ContainsKey("holes")) { var holes = json["holes"] as ArrayList; if (holes != null) { ReadHoles(data, holes); } } return(data); }
/// <summary> /// Writes an InputGeometry to a Triangle format .poly file. /// </summary> /// <param name="geometry">The InputGeometry to write.</param> /// <param name="filename">The filename.</param> /// <param name="compatibleMode">If true, indices will start at 1 (compatible with original C code).</param> public static void Write(InputGeometry geometry, string filename, bool compatibleMode = false) { OFFSET = compatibleMode ? 1 : 0; using (StreamWriter writer = new StreamWriter(filename)) { WritePoints(writer, geometry.Points, geometry.Count); WriteSegments(writer, geometry.Segments); WriteHoles(writer, geometry.Holes); } }
public static void Read(string filename, out InputGeometry geometry, out List <ITriangle> triangles) { triangles = null; FileReader.Read(filename, out geometry); string str = Path.ChangeExtension(filename, ".ele"); if (File.Exists(str) && geometry != null) { triangles = FileReader.ReadEleFile(str); } }
Mesh generateFaceMesh(ShapePoints shape) { var mesh = new Mesh(); var verts = new List <Vector3>(); var tris = new List <int>(); var uvs = new List <Vector2>(); var uv2 = new List <Vector2>(); var geometry = new InputGeometry(); for (int i = 0; i < shape.edge.Length; ++i) { var pt = shape.edge[i]; geometry.AddPoint(pt.x, pt.y); verts.Add(pt.p.AsVector3(-pt.groundness * _groundPull)); uvs.Add(pt.p); uv2.Add(new Vector2(pt.groundness * pt.groundness, 0)); geometry.AddSegment(i, (i + 1) % shape.edge.Length); } for (int i = 0; i < shape.interior.Length; ++i) { var pt = shape.interior[i]; geometry.AddPoint(pt.x, pt.y); verts.Add(pt.p.AsVector3(-pt.groundness * _groundPull + UnityEngine.Random.value * 0.4f)); uvs.Add(pt.p); uv2.Add(new Vector2(pt.groundness * pt.groundness, 0)); } var behave = new TriangleNet.Behavior(); behave.Algorithm = TriangleNet.TriangulationAlgorithm.Incremental; var meshRepresentation = new TriangleNet.Mesh(behave); meshRepresentation.Triangulate(geometry); foreach (var tri in meshRepresentation.Triangles) { tris.Add(tri.GetVertex(2).ID); tris.Add(tri.GetVertex(1).ID); tris.Add(tri.GetVertex(0).ID); } mesh.vertices = verts.ToArray(); mesh.triangles = tris.ToArray(); mesh.uv = uvs.ToArray(); mesh.uv2 = uv2.ToArray(); mesh.RecalculateNormals(); mesh.RecalculateBounds(); return(mesh); }
protected override IEnumerable <MonoBehaviour> Create(Tile tile, JSONObject geo) { var kind = geo["properties"]["kind"].str.ConvertToLanduseType(); if (!FactorySettings.HasSettingsFor(kind) && !JustDrawEverythingFam) { yield break; } var bb = geo["geometry"]["coordinates"].list[0]; //this is wrong but cant fix it now if (bb == null || bb.list == null) { yield break; } var count = bb.list.Count - 1; if (count < 3) { yield break; } var inp = new InputGeometry(count); for (var i = 0; i < count; i++) { var c = bb.list[i]; var dotMerc = GM.LatLonToMeters(c[1].f, c[0].f); var localMercPos = dotMerc - tile.Rect.Center; inp.AddPoint(localMercPos.x, localMercPos.y); inp.AddSegment(i, (i + 1) % count); } var landuse = new GameObject("Landuse").AddComponent <Landuse>(); var md = new MeshData(); var mesh = landuse.GetComponent <MeshFilter>().mesh; SetProperties(geo, landuse, kind); CreateMesh(inp, md); //I want object center to be in the middle of object, not at the corner of the tile var landuseCenter = ChangeToRelativePositions(md.Vertices); landuse.transform.localPosition = landuseCenter; mesh.vertices = md.Vertices.ToArray(); mesh.triangles = md.Indices.ToArray(); mesh.SetUVs(0, md.UV); mesh.RecalculateNormals(); yield return(landuse); }
private void UpdateTask() { if (!mTask.IsFinished) return; mLogger.Log(mTask.Messages); if (mTask.TaskState == BuildTaskState.Aborted) { FinalizeOnFail("Input geometry build failed.", true); return; } mGeometry = mTask.Result; mLogger.PostTrace("Completed input geometry build.", mTask.Messages, mContext.Build); mTask = null; mState = State.Finished; }
private void FinalizeOnFail(string message, bool postError) { if (mTask != null) { mTask.Abort(message); mTask = null; } if (postError) mLogger.PostError(message, mContext.Build); mBuilder = null; mGeometry = null; mAssets = new InputAssets(); mState = State.Finished; }
private void HandleInputGeom(NavmeshBuild build, int tx, int tz) { if (build.InputGeom != mLastGeom) { // Input geometry has changed. Clear debug object. mLastGeom = build.InputGeom; mDebugObject = null; } if (build.InputGeom == null) return; if (mDebugObject == null) { TileSetDefinition tdef = build.TileSetDefinition; Vector3 bmin; Vector3 bmax; tdef.GetTileBounds(tx, tz, true, out bmin, out bmax); Geom geom = new Geom(); geom.mesh = build.InputGeom.ExtractMesh(bmin.x, bmin.z, bmax.x, bmax.z, out geom.areas); mDebugObject = geom; } if (mDebugObject != null) { Geom geom = (Geom)mDebugObject; if (geom.mesh.triCount > 0) { DebugDraw.TriangleMesh(geom.mesh.verts , geom.mesh.tris, geom.areas, geom.mesh.triCount , true, 0.25f); } } }