Some improvements on tile instancing.

WorldChunkRefactoring
Martin Felis 2023-11-04 19:15:26 +01:00
parent 0663263bb7
commit 928ddd3937
4 changed files with 55 additions and 14 deletions

File diff suppressed because one or more lines are too long

View File

@ -23,6 +23,7 @@ script = ExtResource( 1 )
[node name="Mesh" type="MeshInstance" parent="." groups=["GameGeometry"]] [node name="Mesh" type="MeshInstance" parent="." groups=["GameGeometry"]]
transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, -2.5, 0 ) transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, -2.5, 0 )
visible = false
mesh = ExtResource( 3 ) mesh = ExtResource( 3 )
material/0 = ExtResource( 2 ) material/0 = ExtResource( 2 )

View File

@ -1,16 +1,20 @@
using System.Diagnostics;
using System.Linq; using System.Linq;
using Godot; using Godot;
using Godot.Collections; using Godot.Collections;
public class TileInstanceManager : Spatial public class TileInstanceManager : Spatial
{ {
private readonly Array<SceneTileChunk> _sceneTileChunks = new();
private MultiMeshInstance _tileMultiMeshInstance;
private ImageTexture _viewTileTypeTexture;
private World _world;
// other members // other members
[Export] public bool ShowHexTiles; [Export] public bool ShowHexTiles;
[Export] public Vector2 ViewCenterPlaneCoord; [Export] public Vector2 ViewCenterPlaneCoord;
private World _world;
private readonly Array<SceneTileChunk> _sceneTileChunks = new();
private ImageTexture _viewTileTypeTexture;
// ui elements // ui elements
// scene nodes // scene nodes
@ -26,6 +30,9 @@ public class TileInstanceManager : Spatial
_world = GetNode<World>(World); _world = GetNode<World>(World);
_world.Connect("OnTilesChanged", this, nameof(HandleWorldTileChange)); _world.Connect("OnTilesChanged", this, nameof(HandleWorldTileChange));
_tileMultiMeshInstance = (MultiMeshInstance)FindNode("TileMultiMeshInstance");
Debug.Assert(_tileMultiMeshInstance != null);
} }
@ -35,7 +42,7 @@ public class TileInstanceManager : Spatial
private SceneTileChunk CreateSceneTileChunk(Vector2 chunkIndex) private SceneTileChunk CreateSceneTileChunk(Vector2 chunkIndex)
{ {
var sceneTileChunk = new SceneTileChunk(chunkIndex); var sceneTileChunk = new SceneTileChunk(chunkIndex, _tileMultiMeshInstance);
foreach (var hexTile3D in sceneTileChunk.TileNodes) foreach (var hexTile3D in sceneTileChunk.TileNodes)
{ {
@ -87,10 +94,10 @@ public class TileInstanceManager : Spatial
sceneTileChunk.ChunkIndex = chunkIndex; sceneTileChunk.ChunkIndex = chunkIndex;
if (ShowHexTiles) // if (ShowHexTiles)
foreach (var tile3D in sceneTileChunk.TileNodes) // foreach (var tile3D in sceneTileChunk.TileNodes)
tile3D.Transform = new Transform(Basis.Identity.Scaled(Vector3.One * 0.95f), // tile3D.Transform = new Transform(Basis.Identity.Scaled(Vector3.One * 0.95f),
tile3D.Transform.origin); // tile3D.Transform.origin);
_sceneTileChunks.Add(sceneTileChunk); _sceneTileChunks.Add(sceneTileChunk);
} }
@ -119,14 +126,15 @@ public class TileInstanceManager : Spatial
private class SceneTileChunk : Spatial private class SceneTileChunk : Spatial
{ {
private Vector2 _chunkIndex = Vector2.Inf;
private readonly PackedScene _hexTile3DScene = GD.Load<PackedScene>("res://scenes/HexTile3D.tscn"); private readonly PackedScene _hexTile3DScene = GD.Load<PackedScene>("res://scenes/HexTile3D.tscn");
private readonly MultiMeshInstance _multiMeshInstance;
private readonly HexGrid HexGrid = new(); private readonly HexGrid HexGrid = new();
private readonly Array<int> TileInstanceIndices = new();
public readonly Array<HexTile3D> TileNodes = new(); public readonly Array<HexTile3D> TileNodes = new();
private Vector2 _chunkIndex = Vector2.Inf;
public SceneTileChunk(Vector2 chunkIndex) public SceneTileChunk(Vector2 chunkIndex, MultiMeshInstance multiMeshInstance)
{ {
var chunkSize = global::World.ChunkSize; var chunkSize = global::World.ChunkSize;
@ -144,6 +152,18 @@ public class TileInstanceManager : Spatial
AddChild(tile3D); AddChild(tile3D);
} }
_multiMeshInstance = multiMeshInstance;
var chunkTileCount = global::World.ChunkSize * global::World.ChunkSize;
foreach (var i in Enumerable.Range(0, chunkTileCount))
TileInstanceIndices.Add(_multiMeshInstance.Multimesh.InstanceCount + i);
_multiMeshInstance.Multimesh.InstanceCount += chunkTileCount;
_multiMeshInstance.Multimesh.VisibleInstanceCount = _multiMeshInstance.Multimesh.InstanceCount;
GD.Print("VisibleInstanceCount = " + _multiMeshInstance.Multimesh.VisibleInstanceCount);
ChunkIndex = chunkIndex; ChunkIndex = chunkIndex;
} }
@ -158,6 +178,22 @@ public class TileInstanceManager : Spatial
chunkTransform.origin = new Vector3(chunkOriginPlaneCoord.x, 0, chunkOriginPlaneCoord.y); chunkTransform.origin = new Vector3(chunkOriginPlaneCoord.x, 0, chunkOriginPlaneCoord.y);
Transform = chunkTransform; Transform = chunkTransform;
_chunkIndex = value; _chunkIndex = value;
var tileOrientation = new Basis(Vector3.Up, 90f * Mathf.Pi / 180f);
GD.Print("Updating transforms for instances of chunk " + value);
foreach (var i in Enumerable.Range(0, TileInstanceIndices.Count))
{
var column = i % global::World.ChunkSize;
var row = i / global::World.ChunkSize;
var tilePlaneCoord =
HexGrid.GetHexCenterFromOffset(new Vector2(column, row));
_multiMeshInstance.Multimesh.SetInstanceTransform(TileInstanceIndices[i],
new Transform(tileOrientation,
chunkTransform.origin + new Vector3(tilePlaneCoord.x, 0, tilePlaneCoord.y)));
}
} }
} }
} }

View File

@ -296,6 +296,7 @@ public class World : Spatial
if (oldState != GenerationState.Done && State == GenerationState.Done) if (oldState != GenerationState.Done && State == GenerationState.Done)
{ {
UpdateWorldViewTexture(); UpdateWorldViewTexture();
EmitSignal("OnTilesChanged", _removedChunkIndices.ToArray(), _addedChunkIndices.ToArray()); EmitSignal("OnTilesChanged", _removedChunkIndices.ToArray(), _addedChunkIndices.ToArray());
} }
} }