using Godot; using System; using System.Collections.Generic; using System.Linq; using static GameData; public partial class World : Node3D { public Dictionary tileMeshes; PackedScene layerPrefab = ResourceLoader.LoadLayerPrefab(); private Dictionary multiMeshes = new(); private Dictionary meshLibrary = new(); Layer[] map; Layer layerNode; // Called when the node enters the scene tree for the first time. public override void _Ready() { WFC.FillAdjacencies(); tileMeshes = ResourceLoader.LoadTiles(); foreach (var kvp in tileMeshes) { var temp = kvp.Value; meshLibrary[kvp.Key] = temp.Mesh; temp.QueueFree(); } foreach (var kvp in meshLibrary) { var mm = new MultiMesh(); mm.Mesh = kvp.Value; mm.TransformFormat = MultiMesh.TransformFormatEnum.Transform3D; var instance = new MultiMeshInstance3D(); instance.Multimesh = mm; AddChild(instance); multiMeshes[kvp.Key] = instance; } map = new Layer[ruinSize]; GenerateWorld(); GD.Print("World generated"); BuildMeshesForLayer(0); } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { if (Input.IsActionJustPressed("layer_up") && currentLayer > 0) currentLayer--; if (Input.IsActionJustPressed("layer_down") && currentLayer < ruinSize - 1) currentLayer++; if (currentLayer != visibleLayer) { BuildMeshesForLayer(currentLayer); visibleLayer = currentLayer; } } private void GenerateWorld() { DateTime now = DateTime.Now; for (int layer = 0; layer < ruinSize; layer++) { layerNode = layerPrefab.Instantiate(); AddChild(layerNode); layerNode.SetupLayer(layerSize, layer, tileMeshes); map[layer] = layerNode; } GD.Print("Time for map generation: " + (DateTime.Now - now).Seconds); } private void BuildMeshesForLayer(int layerIndex) { foreach (MultiMeshInstance3D mm in multiMeshes.Values) { mm.Multimesh.InstanceCount = 0; } Layer layer = map[layerIndex]; Dictionary> batches = new(); for (int x = 0; x < layerSize; x++) { for (int y = 0; y < layerSize; y++) { Tile tile = layer.tiles[x, y]; string key = tile.collapsedMesh; if (!batches.ContainsKey(key)) batches[key] = new List(); batches[key].Add(new Transform3D( Basis.Identity, tile.Position )); } } foreach (var kvp in batches) { MultiMesh mm = multiMeshes[kvp.Key].Multimesh; List list = kvp.Value; mm.InstanceCount = list.Count; for (int i = 0; i < list.Count; i++) { mm.SetInstanceTransform(i, list[i]); } } } }