123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using KairoEngine.Core;
- using KairoEngine.Chunks;
- using KairoEngine.NoiseUtilities;
- using KairoEngine.UniverseGenerator;
- using Sirenix.OdinInspector;
- using UniRx;
- namespace KairoEngine.TerrainEngine
- {
- [HideMonoScript]
- public class ChunkTerrainGenerator : MonoBehaviour
- {
- public MarchingCubes4 marchingCubes3;
- public MarchingCubes2 marchingCubes2;
- public Vector3 voxelSize = new Vector3(1f, 1f, 1f);
- public Vector3Int chunkSize = new Vector3Int(16, 16, 16);
- public Vector3Int chunkLimit = new Vector3Int(2, 1, 2);
- //public float noiseMultiplier = 1.5f;
- [InlineEditor(InlineEditorObjectFieldModes.Foldout)] public PlanetTemplate planetTemplate;
- public ChunkSystem<BlockBase> chunkSystem;
- [Button("Generate"), ButtonGroup("Buttons")]
- void CreateChunks()
- {
- if(planetTemplate == null)
- {
- Debug.LogError("Missing planet template", this.gameObject);
- return;
- }
- DestroyTerrain();
- Debug.Log("Starting chunk generation");
- chunkSystem = new ChunkSystem<BlockBase>(chunkSize,voxelSize, true);
- for (int x = 0; x < chunkLimit.x; x++) {
- for (int z = 0; z < chunkLimit.z; z++) {
- for (int y = 0; y < chunkLimit.y; y++) {
- Vector3 chunkGlobalPos = new Vector3(x * chunkSize.x * voxelSize.x, y * chunkSize.y * voxelSize.y, z * chunkSize.z * voxelSize.z);
- Vector3Int chunkPos = new Vector3Int(x * chunkSize.x, y * chunkSize.y, z * chunkSize.z);
- chunkSystem.CreateChunk(chunkGlobalPos, chunkPos, (Chunk<BlockBase> c, Vector3Int pos) => new BlockBase(0, 0));
- GenerateChunkTerrain(chunkGlobalPos);
- }
- }
- }
- for (int x = 0; x < chunkLimit.x; x++) {
- for (int z = 0; z < chunkLimit.z; z++) {
- for (int y = 0; y < chunkLimit.y; y++) {
- //Vector3Int chunkPos = new Vector3Int(x * chunkSize.x, y * chunkSize.y, z * chunkSize.z);
- Vector3 chunkPos = new Vector3(x * chunkSize.x * voxelSize.x, y * chunkSize.y * voxelSize.y, z * chunkSize.z * voxelSize.z);
- if(marchingCubes3 != null) marchingCubes3.Generate(chunkSystem, chunkPos);
- //else if(marchingCubes2 != null) marchingCubes2.Generate(chunkSystem, chunkPos);
- }
- }
- }
- #if UNITY_EDITOR
- UpdateEditor ();
- #endif
- }
- void GenerateChunkTerrain(Vector3 initialPos)
- {
- float width = (float)(chunkLimit.x * chunkSize.x * voxelSize.x);
- float height = (float)(chunkLimit.y * chunkSize.y * voxelSize.y);
- float length = (float)(chunkLimit.z * chunkSize.z * voxelSize.z);
- for (int x = 0; x < chunkSize.x; x++) {
- for (int z = 0; z < chunkSize.z; z++) {
- for (int y = 0; y < chunkSize.y; y++) {
- // Get a terrain height using regular old Perlin noise.
- Vector3 pos = initialPos + new Vector3(x * voxelSize.x, y * voxelSize.y, z * voxelSize.z);
- // Old example noise:
- //float thisHeight = height * Mathf.PerlinNoise((float)pos.x / width * noiseMultiplier + 0.001f, (float)pos.z / length * noiseMultiplier + 0.001f);
- float elevation = planetTemplate.SamplePoint((float)pos.x / width, (float)pos.z / length);
- float thisHeight = height * elevation;
- uint code = planetTemplate.SamplePointCode((float)pos.x / width, (float)pos.z / length, elevation);
- BlockBase block = new BlockBase(code, (uint)Mathf.FloorToInt(thisHeight / voxelSize.y));
- chunkSystem.SetBlock(pos, block);
- }
- }
- }
- }
- void UpdateEditor ()
- {
- Timer.ExecuteRealTime(50, () => {
- if(marchingCubes3 != null)
- {
- marchingCubes3.UpdateFinishedJobs();
- if(!marchingCubes3.IsGeneratorDone()) UpdateEditor();
- }
- });
- }
- [Button("Destroy"), ButtonGroup("Buttons")]
- private void DestroyTerrain()
- {
- var childTransforms = this.gameObject.transform.GetComponentsInChildren<Transform>();
- if(childTransforms.Length > 0) Debug.Log($"Destroying {childTransforms.Length - 1} terrain objects");
- for (int i = 0; i < childTransforms.Length; i++)
- {
- if(childTransforms[i] == this.transform) continue;
- #if UNITY_EDITOR
- DestroyImmediate(childTransforms[i].gameObject);
- #else
- Destroy(childTransforms[i].gameObject);
- #endif
- }
- }
- }
- }
|