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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
            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);
            }
Beispiel #6
0
    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);
    }