Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
using System; using System.Collections.Generic; using GamePlay; using R3; using Reflex.Attributes; using UnityEditor; using UnityEngine; using UnityEngine.UI; using VoxelMap; namespace UI { public class WorldMap : MonoBehaviour { private const int ColumnPerFrame = 1; private const string ClearHeight = "ClearHeight"; private const string UpdateHeight = "UpdateHeight"; private const string UpdateChunk = "UpdateChunk"; private static readonly int HeightBuffer = Shader.PropertyToID("HeightBuffer"); private static readonly int VertexBuffer = Shader.PropertyToID("VertexBuffer"); private static readonly int MapTexture = Shader.PropertyToID("MapTexture"); private static readonly int MeshPositionOffset = Shader.PropertyToID("MeshPositionOffset"); private static readonly int ChunkSize = Shader.PropertyToID("ChunkSize"); [SerializeField] private ComputeShader computeShader; [SerializeField] private RawImage mapImage; private MapProvider _mapProvider; private EntityContainerService _entityContainer; private ComputeBuffer _heightBuffer; private int _updateHeightKernel; private int _updateChunkKernel; private int _clearHeightKernel; [field: SerializeField] public CanvasGroup CanvasGroup { get; private set; } public RenderTexture MainTexture { get; private set; } private readonly Queue<(int x, int z)> _regeneratingColumns = new Queue<(int x, int z)>(); [Inject] private void Construct(MapProvider mapProvider) { _mapProvider = mapProvider; _heightBuffer = new ComputeBuffer(Chunk.ChunkSizeSquared, sizeof(uint)); _clearHeightKernel = computeShader.FindKernel(ClearHeight); _updateHeightKernel = computeShader.FindKernel(UpdateHeight); _updateChunkKernel = computeShader.FindKernel(UpdateChunk); computeShader.SetFloat(ChunkSize, Chunk.ChunkSize); } public void Initialize() { if (MainTexture != null) { MainTexture.Release(); } MainTexture = new RenderTexture(_mapProvider.Map.Width, _mapProvider.Map.Depth, 0, RenderTextureFormat.ARGB32) { enableRandomWrite = true, filterMode = FilterMode.Point }; MainTexture.Create(); mapImage.texture = MainTexture; _mapProvider.Map.ChunkUpdated.Subscribe(OnChunkUpdated).AddTo(_mapProvider.Map); _regeneratingColumns.Clear(); for (int x = 0; x < _mapProvider.Map.Width / Chunk.ChunkSize; x++) { for (var z = 0; z < _mapProvider.Map.Depth / Chunk.ChunkSize; z++) { _regeneratingColumns.Enqueue((x, z)); } } } private void Update() { if (_mapProvider.Map == null) { return; } for (var i = 0; i < Math.Min(_regeneratingColumns.Count, ColumnPerFrame); i++) { (int x, int z) = _regeneratingColumns.Dequeue(); RefreshChunkColumn(x, z); } } private void RefreshChunkColumn(int x, int z) { computeShader.SetBuffer(_clearHeightKernel, HeightBuffer, _heightBuffer); computeShader.Dispatch(_clearHeightKernel, Chunk.ChunkSize / 8, Chunk.ChunkSize / 8, 1); for (var y = 0; y < _mapProvider.Map.Height / Chunk.ChunkSize; y++) { int chunkIndex = GetChunkIndex(x, y, z); Chunk chunk = _mapProvider.Map.Chunks[chunkIndex]; if (chunk.Mesh.vertexCount == 0) { continue; } chunk.Mesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw; using GraphicsBuffer vertexBuffer = chunk.Mesh.GetVertexBuffer(0); int quadCount = chunk.Mesh.vertexCount / 4; computeShader.SetBuffer(_updateHeightKernel, VertexBuffer, vertexBuffer); computeShader.SetBuffer(_updateHeightKernel, HeightBuffer, _heightBuffer); computeShader.SetFloats(MeshPositionOffset, chunk.Position.x, chunk.Position.y, chunk.Position.z); computeShader.Dispatch(_updateHeightKernel, Mathf.Max(1, quadCount / 16), 1, 1); computeShader.SetBuffer(_updateChunkKernel, VertexBuffer, vertexBuffer); computeShader.SetBuffer(_updateChunkKernel, HeightBuffer, _heightBuffer); computeShader.SetTexture(_updateChunkKernel, MapTexture, MainTexture); computeShader.SetFloats(MeshPositionOffset, chunk.Position.x, chunk.Position.y, chunk.Position.z); computeShader.Dispatch(_updateChunkKernel, Mathf.Max(1, quadCount / 16), 1, 1); } } private void OnChunkUpdated(Chunk chunk) { _regeneratingColumns.Enqueue((chunk.Position.x / Chunk.ChunkSize, chunk.Position.z / Chunk.ChunkSize)); } private int GetChunkIndex(int x, int y, int z) { return x * (_mapProvider.Map.Height * _mapProvider.Map.Depth / Chunk.ChunkSizeSquared) + y * (_mapProvider.Map.Depth / Chunk.ChunkSize) + z; } private void OnDestroy() { _heightBuffer.Release(); MainTexture.Release(); } } }
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)