using Godot; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; public class WorldChunk : Spatial { // ui elements // scene nodes private MeshInstance PlaneRectMesh; // resources // exports [Export] public Texture TileTypeMap; [Export] public Texture NavigationMap; [Export] public Texture HeightMap; [Export] public int Size = 32; [Export] public Vector2 ChunkAddress; [Export] public bool ShowTextureOverlay { get { return _showTextureOverlay; } set { if (PlaneRectMesh != null) { PlaneRectMesh.Visible = value; } } } // signals // delegate void OnCoordClicked(Vector2 world_pos); // other members public Rect2 PlaneRect; public Color DebugColor = Colors.White; public Viewport TileTypeOffscreenViewport; public bool NoiseTextureCheckerboardOverlay = true; private TextureRect _heightmapRect; private SpatialMaterial _rectMaterial = new SpatialMaterial(); private bool _showTextureOverlay = false; public WorldChunk() { } public WorldChunk(int size) { SetSize(size); } public void SetSize(int size) { Size = size; if (TileTypeOffscreenViewport != null) { TileTypeOffscreenViewport.Size = Vector2.One * size; } } // other members public void SaveToFile(String chunkName) { Image image = new Image(); image.CreateFromData(Size, Size, false, Image.Format.Rgba8, TileTypeMap.GetData().GetData()); image.SavePng(chunkName + "_tileType.png"); image.CreateFromData(Size, Size, false, Image.Format.Rgba8, NavigationMap.GetData().GetData()); image.SavePng(chunkName + "_navigationMap.png"); image.CreateFromData(Size, Size, false, Image.Format.Rgba8, HeightMap.GetData().GetData()); image.SavePng(chunkName + "_heightMap.png"); } public void LoadFromFile(String chunkName) { } // Called when the node enters the scene tree for the first time. public override void _Ready() { PlaneRectMesh = (MeshInstance)FindNode("PlaneRectMesh"); Debug.Assert(PlaneRectMesh != null); if (PlaneRectMesh.Visible) { _showTextureOverlay = true; } Transform planeRectTransform = Transform.Identity; planeRectTransform = planeRectTransform.Scaled(new Vector3(PlaneRect.Size.x, 0.125f, PlaneRect.Size.y)); planeRectTransform.origin.x = PlaneRect.GetCenter().x; planeRectTransform.origin.z = PlaneRect.GetCenter().y; PlaneRectMesh.Transform = planeRectTransform; // PlaneRectMesh.MaterialOverride = new SpatialMaterial(); // ((SpatialMaterial)PlaneRectMesh.MaterialOverride).AlbedoColor = DebugColor; // ((SpatialMaterial)PlaneRectMesh.MaterialOverride).FlagsTransparent = true; TileTypeOffscreenViewport = (Viewport)FindNode("TileTypeOffscreenViewport"); TileTypeOffscreenViewport.Size = Vector2.One * Size; Debug.Assert(TileTypeOffscreenViewport != null); _heightmapRect = (TextureRect)FindNode("HeightmapTexture"); } public void SetHeightmap(Texture texture) { GD.Print("Setting HeightmapRect Texture: " + _heightmapRect + " with size " + _heightmapRect.GetSize()); _heightmapRect.Texture = texture; } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(float delta) { Texture tileTypeTexture = TileTypeOffscreenViewport.GetTexture(); if (NoiseTextureCheckerboardOverlay) { Image tileTypeImage = tileTypeTexture.GetData(); tileTypeImage.Lock(); foreach (int i in Enumerable.Range(0, Size)) { foreach (int j in Enumerable.Range(0, Size)) { Vector2 textureCoord = new Vector2(i, j); Color baseColor = tileTypeImage.GetPixelv(textureCoord); if ((i + j) % 2 == 0) { tileTypeImage.SetPixelv(textureCoord, baseColor); } else { tileTypeImage.SetPixelv(textureCoord, baseColor * 0.6f); } } } tileTypeImage.Unlock(); ImageTexture imageTexture = new ImageTexture(); imageTexture.CreateFromImage(tileTypeImage, (uint) 0); tileTypeTexture = imageTexture; } _rectMaterial.AlbedoTexture = tileTypeTexture; _rectMaterial.FlagsTransparent = true; // _rectMaterial.AlbedoTexture = _heightmapRect.Texture; _rectMaterial.Uv1Scale = new Vector3(-3, -2, 1); _rectMaterial.Uv1Offset = Vector3.One * 2; //RectMaterial.Uv1Triplanar = true; PlaneRectMesh.SetSurfaceMaterial(0, _rectMaterial); TileTypeOffscreenViewport.RenderTargetUpdateMode = Viewport.UpdateMode.Once; PlaneRectMesh.MaterialOverride = null; } }