private IMesh BuildChunkMesh(Point2 offset, Point2 size) { IMesh batch = new RAMMesh(); size.ForEach(p => { var v = world.GetVoxel(p + new Point2(offset)); if (v == null) { return; } var mesh = meshProvider.GetMesh(v); if (mesh == null) { return; } var vWorld = Matrix.Scaling(new Vector3(world.VoxelSize.X)) * Matrix.Translation(((p.ToVector2() + new Vector2(0.5f)) * world.VoxelSize.X).ToXZ(v.Data.Height)); MeshBuilder.AppendMeshTo(meshProvider.GetMesh(v), batch, vWorld); }); var optimizer = new MeshOptimizer(); batch = optimizer.CreateOptimized(batch); return(batch); }
public void TestOptimizeMeshManyParts() { var b = new MeshBuilder(); b.AddBox(new Vector3(0, 0, 0), new Vector3(1, 1, 1)); var partMesh = b.CreateMesh(); var unoptimized = new RAMMesh(); for (int i = 0; i < 1000; i++) { MeshBuilder.AppendMeshTo(partMesh, unoptimized, Matrix.Translation(i, 0, 0)); } var optimizer = new MeshOptimizer(); var watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 10; i++) { var optimized = optimizer.CreateOptimized(unoptimized); Assert.AreEqual(1, optimized.GetCoreData().Parts.Count); } watch.Stop(); Console.WriteLine(watch.Elapsed.TotalMilliseconds / 10); }
public void TestOptimizeMesh() { //TODO: better test //var fileName = TWDir.GameData + "\\Core\\TileSet\\ts001sg001.obj"; var fileName = TWDir.GameData + "\\TileSet01\\GreyBrick_RoofX_01\\GreyBrick_RoofX_01.obj"; var mesh = MeshLoader.LoadMeshFromObj(new System.IO.FileInfo(fileName)); var optimizer = new MeshOptimizer(); var optimized = optimizer.CreateOptimized(mesh); }
private IMesh alterMesh(IMesh mesh, string texname, ITexture tex) { // Somewhat of a cheat, use the meshoptimizer to create a copy var copy = new MeshOptimizer().CreateOptimized(mesh); var mat = copy.GetCoreData().Parts.Where(p => p.MeshMaterial.Name == texname).FirstOrDefault(); if (mat == null) { throw new InvalidOperationException("Mesh does not contain material " + texname); } mat.MeshMaterial.DiffuseMap = tex; return(copy); }
public void Build() { IMesh mesh = new RAMMesh(); foreach (var ent in entities) { MeshBuilder.AppendMeshTo(ent.Mesh, mesh, ent.WorldMatrix); ent.Batched = true; ent.get <BatchInfo>().Batch = this; } var optimizer = new MeshOptimizer(); mesh = optimizer.CreateOptimized(mesh); element = TW.Graphics.AcquireRenderer().CreateMeshElement(mesh); }
private void SmoothMap() { foreach (KeyValuePair <Vector2Int, I_Tile> tile in m_Tiles) { tile.Value.SetTileLinks(); } List <KeyValuePair <List <E_Direction>, Vertex> > allCorners = new List <KeyValuePair <List <E_Direction>, Vertex> >(); List <MeshFilter> allWallsMeshes = new List <MeshFilter>(); for (int i = 0; i < m_Walls.Count; i++) { allWallsMeshes.AddRange(m_Walls[i].GetWallMesh()); allCorners.AddRange(m_Walls[i].GetCorners()); } List <Edge> edges = new List <Edge>(); for (int i = 0; i < allCorners.Count; i++) { List <E_Direction> directions = allCorners[i].Key; Vertex position = allCorners[i].Value; Vertex closestEastWest = position; Vertex closestNorthSouth = position; float closestEastWestDistance = -1; float closestNorthSouthDistance = -1; for (int direction = 0; direction < 2; direction++) { if (directions[direction] == E_Direction.North) { for (int j = 0; j < allCorners.Count; j++) { if (allCorners[j].Key.Contains(E_Direction.South)) { if (allCorners[j].Value.Position.x == position.Position.x && allCorners[j].Value.Position.z > position.Position.z) { float currentDistance = Vector3.Distance(allCorners[j].Value.Position, position.Position); if (closestNorthSouthDistance < 0 || closestNorthSouthDistance > currentDistance) { closestNorthSouthDistance = currentDistance; closestNorthSouth = allCorners[j].Value; } } } } } else if (directions[direction] == E_Direction.South) { for (int j = 0; j < allCorners.Count; j++) { if (allCorners[j].Key.Contains(E_Direction.North)) { if (allCorners[j].Value.Position.x == position.Position.x && allCorners[j].Value.Position.z < position.Position.z) { float currentDistance = Vector3.Distance(allCorners[j].Value.Position, position.Position); if (closestNorthSouthDistance < 0 || closestNorthSouthDistance > currentDistance) { closestNorthSouthDistance = currentDistance; closestNorthSouth = allCorners[j].Value; } } } } } else if (directions[direction] == E_Direction.East) { for (int j = 0; j < allCorners.Count; j++) { if (allCorners[j].Key.Contains(E_Direction.West)) { if (allCorners[j].Value.Position.z == position.Position.z && allCorners[j].Value.Position.x > position.Position.x) { float currentDistance = Vector3.Distance(allCorners[j].Value.Position, position.Position); if (closestEastWestDistance < 0 || closestEastWestDistance > currentDistance) { closestEastWestDistance = currentDistance; closestEastWest = allCorners[j].Value; } } } } } else if (directions[direction] == E_Direction.West) { for (int j = 0; j < allCorners.Count; j++) { if (allCorners[j].Key.Contains(E_Direction.East)) { if (allCorners[j].Value.Position.z == position.Position.z && allCorners[j].Value.Position.x < position.Position.x) { float currentDistance = Vector3.Distance(allCorners[j].Value.Position, position.Position); if (closestEastWestDistance < 0 || closestEastWestDistance > currentDistance) { closestEastWestDistance = currentDistance; closestEastWest = allCorners[j].Value; } } } } } } if (closestNorthSouthDistance >= 0 && closestEastWestDistance >= 0) { Edge northSouthEdge = new Edge(position, closestNorthSouth); Edge eastWestEdge = new Edge(position, closestEastWest); if (directions[3] == E_Direction.East && position.Position.z <closestNorthSouth.Position.z || directions[3] == E_Direction.West && position.Position.z> closestNorthSouth.Position.z) { northSouthEdge.FlipEdge(); } if (directions[2] == E_Direction.North && position.Position.x > closestEastWest.Position.x || directions[2] == E_Direction.South && position.Position.x < closestEastWest.Position.x) { eastWestEdge.FlipEdge(); } northSouthEdge.FirstVertex.NextVertex = northSouthEdge.SecondVertex; northSouthEdge.SecondVertex.PreviousVertex = northSouthEdge.FirstVertex; edges.Add(northSouthEdge); eastWestEdge.FirstVertex.NextVertex = eastWestEdge.SecondVertex; eastWestEdge.SecondVertex.PreviousVertex = eastWestEdge.FirstVertex; edges.Add(eastWestEdge); } } List <Vertex> allVertices = new List <Vertex>(); for (int i = 0; i < allCorners.Count; i++) { allVertices.Add(allCorners[i].Value); } List <Vertex> allVerticesToProcess = new List <Vertex>(); allVerticesToProcess.AddRange(allVertices); List <List <Vertex> > allLoops = new List <List <Vertex> >(); int security = 0; while (allVerticesToProcess.Count > 0 && security < 10000) { allLoops.Add(GetVertexLoop(allVerticesToProcess)); security++; } List <Vertex> externalPoints = new List <Vertex> { new Vertex(new Vector3(-10, 1, -10)), new Vertex(new Vector3(10 + m_MapSize.x, 1, -10)), new Vertex(new Vector3(10 + m_MapSize.x, 1, 10 + m_MapSize.y)), new Vertex(new Vector3(-10, 1, 10 + m_MapSize.y)) }; Mesh optimizedRoof = MeshOptimizer.GenerateOptimisedMesh(allVertices, externalPoints, allLoops); List <MeshFilter> allFloorsMeshes = new List <MeshFilter>(); for (int i = 0; i < m_Floors.Count; i++) { allFloorsMeshes.AddRange(m_Floors[i].GetWallMesh()); } CombineInstance[] combineWalls = new CombineInstance[allWallsMeshes.Count + 1]; for (int i = 0; i < allWallsMeshes.Count; i++) { combineWalls[i].mesh = allWallsMeshes[i].sharedMesh; combineWalls[i].transform = allWallsMeshes[i].transform.localToWorldMatrix; allWallsMeshes[i].gameObject.SetActive(false); } combineWalls[allWallsMeshes.Count].mesh = optimizedRoof; combineWalls[allWallsMeshes.Count].transform = transform.localToWorldMatrix; Mesh optimisedMesh = new Mesh(); optimisedMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; optimisedMesh.CombineMeshes(combineWalls); m_WallsMeshFilter.mesh = optimisedMesh; CombineInstance[] combineFloors = new CombineInstance[allFloorsMeshes.Count]; for (int i = 0; i < allFloorsMeshes.Count; i++) { combineFloors[i].mesh = allFloorsMeshes[i].sharedMesh; combineFloors[i].transform = allFloorsMeshes[i].transform.localToWorldMatrix; allFloorsMeshes[i].gameObject.SetActive(false); } m_FloorsMeshFilter.mesh = new Mesh(); m_FloorsMeshFilter.mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; m_FloorsMeshFilter.mesh.CombineMeshes(combineFloors); UserInterface.DisplayLoadingScreen(false); }