Advertisement
JontePonte

PURE AGONY!! Part 2

Sep 22nd, 2024
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.39 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using Unity.Mathematics;
  5. using Unity.Collections;
  6. using static UnityEditor.PlayerSettings;
  7.  
  8. public class MeshGenerator : MonoBehaviour
  9. {
  10.     public static Vector3Int chunkDimensions = new Vector3Int(32, 32, 32);
  11.  
  12.     public Material material;
  13.  
  14.     public int brushSize;
  15.     public float brushStrength;
  16.  
  17.     public int LOD;
  18.     public int maxLOD;
  19.     int lod;
  20.  
  21.     [Header("Noise Settings")]
  22.     public float heightMultiplier;
  23.     public float frequency;
  24.     public float lacunarity;
  25.     public float persistance;
  26.     public int octaves;
  27.     public float density;
  28.  
  29.     [Header("")]
  30.     public bool autoUpdate;
  31.     public string executionTime;
  32.  
  33.     float[][] voxelGrid;
  34.  
  35.     List<Vector3> vertices;
  36.     Dictionary<Vector3, int> vertDictionary;
  37.  
  38.     List<int> indices;
  39.  
  40.     int[] caseToNumpolys;
  41.     int[][] triTable;
  42.  
  43.     public static Vector3Int[] cornerOffsets;
  44.  
  45.     Camera cam;
  46.  
  47.     Noise noise;
  48.  
  49.     public GameObject ChunkObject(Vector2Int position)
  50.     {
  51.         GameObject chunk = new GameObject("Chunk");
  52.         chunk.AddComponent<MeshFilter>().mesh = ChunkMesh(position);
  53.         chunk.AddComponent<MeshRenderer>().material = material;
  54.  
  55.         return chunk;
  56.     }
  57.  
  58.     public Mesh ChunkMesh(Vector2Int position)
  59.     {
  60.         NativeArray<float> noiseMap2D = noise.FractalNoiseMap();
  61.         NativeArray<float> noiseMap3D = noise.Fractal3DNoiseMap();
  62.  
  63.         CreateVoxelGrid(noiseMap2D, noiseMap3D);
  64.  
  65.         for (int z = 0, i = 0; z < chunkDimensions.z; z += lod)
  66.         {
  67.             for (int y = 0; y < chunkDimensions.y; y += lod)
  68.             {
  69.                 for (int x = 0; x < chunkDimensions.x; x += lod, i++)
  70.                 {
  71.                     AddVertices(i, new Vector3Int(x, y, z));
  72.                 }
  73.             }
  74.         }
  75.  
  76.         noiseMap2D.Dispose();
  77.         noiseMap3D.Dispose();
  78.  
  79.         Mesh mesh = new Mesh();
  80.         mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
  81.  
  82.         mesh.vertices = vertices.ToArray();
  83.         mesh.triangles = indices.ToArray();
  84.  
  85.         mesh.RecalculateNormals();
  86.  
  87.         return mesh;
  88.     }
  89.  
  90.     public void EditorMesh()
  91.     {
  92.         Initialize();
  93.  
  94.         float startTime = Time.realtimeSinceStartup;
  95.  
  96.         Mesh mesh = ChunkMesh(Vector2Int.zero);
  97.  
  98.         executionTime = ((Time.realtimeSinceStartup - startTime) * 1000f) + "ms";
  99.  
  100.         if (GameObject.Find("Mesh") == null)
  101.         {
  102.             GameObject obj = new GameObject("Mesh");
  103.             obj.transform.parent = transform;
  104.             obj.AddComponent<MeshFilter>().mesh = mesh;
  105.             obj.AddComponent<MeshRenderer>().material = material;
  106.             obj.AddComponent<MeshCollider>();
  107.         }
  108.  
  109.         else
  110.         {
  111.             var mf = GameObject.Find("Mesh").GetComponent<MeshFilter>();
  112.             var collider = GameObject.Find("Mesh").GetComponent<MeshCollider>();
  113.  
  114.             mf.mesh = mesh;
  115.             collider.sharedMesh = null;
  116.             collider.sharedMesh = mesh;
  117.         }
  118.     }
  119.  
  120.     private void Start()
  121.     {
  122.         Initialize();
  123.     }
  124.  
  125.     private void Update()
  126.     {
  127.         if (Input.GetKeyDown(KeyCode.Space))
  128.         {
  129.             EditorMesh();
  130.         }
  131.  
  132.         //if (Input.GetMouseButton(1))
  133.         //{
  134.         //    Ray ray = cam.ScreenPointToRay(Input.mousePosition);
  135.  
  136.         //    if (Physics.Raycast(ray, out RaycastHit hit))
  137.         //    {
  138.         //        ModifyTerrain(new Vector3Int((int)hit.point.x, (int)hit.point.y, (int)hit.point.z), true, hit.collider.gameObject);
  139.         //    }
  140.         //}
  141.  
  142.         //if (Input.GetMouseButton(0))
  143.         //{
  144.         //    Ray ray = cam.ScreenPointToRay(Input.mousePosition);
  145.  
  146.         //    if (Physics.Raycast(ray, out RaycastHit hit))
  147.         //    {
  148.         //        ModifyTerrain(new Vector3Int((int)hit.point.x, (int)hit.point.y, (int)hit.point.z), false, hit.collider.gameObject);
  149.         //    }
  150.         //}
  151.     }
  152.  
  153.     void Initialize()
  154.     {
  155.         caseToNumpolys = Tables.caseToNumPolys;
  156.         triTable = Tables.triTable;
  157.  
  158.         cam = Camera.main;
  159.  
  160.         vertices = new();
  161.         vertDictionary = new();
  162.  
  163.         indices = new();
  164.  
  165.         lod = LOD == 0 ? 1 : LOD * 2;
  166.  
  167.         cornerOffsets = new Vector3Int[]
  168.         {
  169.             new Vector3Int(0, 0, 0),
  170.             new Vector3Int(0, 1 * lod, 0),
  171.             new Vector3Int(1 * lod, 1 * lod, 0),
  172.             new Vector3Int(1 * lod, 0, 0),
  173.             new Vector3Int(0, 0, 1 * lod),
  174.             new Vector3Int(0, 1 * lod, 1 * lod),
  175.             new Vector3Int(1 * lod, 1 * lod, 1 * lod),
  176.             new Vector3Int(1 * lod, 0, 1 * lod),
  177.  
  178.         };
  179.  
  180.         noise = new Noise(frequency, persistance, lacunarity, octaves, lod);
  181.     }
  182.  
  183.     void AddVertices(int index, Vector3Int pos)
  184.     {
  185.         float[] voxelData = voxelGrid[index];
  186.  
  187.         int triCase = Utils.CalculateCase(voxelData);
  188.         int[] edges = triTable[triCase];
  189.  
  190.         for (int j = 0, i = 0; j < caseToNumpolys[triCase]; j++, i += 3)
  191.         {
  192.             for (int h = 0; h < 3; h++)
  193.             {
  194.                 Vector3 vertex = GetEdgePosition(edges[i + (2 - h)], voxelData, pos);
  195.  
  196.                 if (vertDictionary.ContainsKey(vertex))
  197.                 {
  198.                     indices.Add(vertDictionary[vertex]);
  199.                 }
  200.  
  201.                 else
  202.                 {
  203.                     vertices.Add(vertex);
  204.                     indices.Add(vertices.Count - 1);
  205.  
  206.                     vertDictionary.Add(vertex, vertices.Count - 1);
  207.                 }
  208.             }
  209.         }
  210.     }
  211.  
  212.     Vector3 GetEdgePosition(int edge, float[] voxelData, Vector3Int pos)
  213.     {
  214.         int x = pos.x;
  215.         int y = pos.y;
  216.         int z = pos.z;
  217.  
  218.         switch (edge)
  219.         {
  220.             case 0: return Utils.GetInterpolatedEdgePosition(x, y, z, voxelData[0], voxelData[1], 0, 1, 0);
  221.             case 1: return Utils.GetInterpolatedEdgePosition(x, y + (1 * lod), z, voxelData[1], voxelData[2], 1, 0, 0);
  222.             case 2: return Utils.GetInterpolatedEdgePosition(x + (1 * lod), y, z, voxelData[3], voxelData[2], 0, 1, 0);
  223.             case 3: return Utils.GetInterpolatedEdgePosition(x, y, z, voxelData[0], voxelData[3], 1, 0, 0);
  224.  
  225.             case 4: return Utils.GetInterpolatedEdgePosition(x, y, z + (1 * lod), voxelData[4], voxelData[5], 0, 1, 0);
  226.             case 5: return Utils.GetInterpolatedEdgePosition(x, y + (1 * lod), z + (1 * lod), voxelData[5], voxelData[6], 1, 0, 0);
  227.             case 6: return Utils.GetInterpolatedEdgePosition(x + (1 * lod), y, z + (1 * lod), voxelData[7], voxelData[6], 0, 1, 0);
  228.             case 7: return Utils.GetInterpolatedEdgePosition(x, y, z + (1 * lod), voxelData[4], voxelData[7], 1, 0, 0);
  229.  
  230.             case 8: return Utils.GetInterpolatedEdgePosition(x, y, z, voxelData[0], voxelData[4], 0, 0, 1);
  231.             case 9: return Utils.GetInterpolatedEdgePosition(x, y + (1 * lod), z, voxelData[1], voxelData[5], 0, 0, 1);
  232.             case 10: return Utils.GetInterpolatedEdgePosition(x + (1 * lod), y + (1 * lod), z, voxelData[2], voxelData[6], 0, 0, 1);
  233.             case 11: return Utils.GetInterpolatedEdgePosition(x + (1 * lod), y, z, voxelData[3], voxelData[7], 0, 0, 1);
  234.  
  235.             default: throw new ArgumentOutOfRangeException(nameof(edge), "Invalid edge index: " + edge);
  236.         }
  237.     }
  238.  
  239.     private void ModifyTerrain(Vector3Int vertex, bool addTerrain, GameObject chunk)
  240.     {
  241.         for (int zOffset = -brushSize; zOffset <= brushSize; zOffset++)
  242.         {
  243.             for (int yOffset = -brushSize; yOffset <= brushSize; yOffset++)
  244.             {
  245.                 for (int xOffset = -brushSize; xOffset <= brushSize; xOffset++)
  246.                 {
  247.                     bool xOutOfRange = vertex.x + xOffset < 0 || vertex.x + xOffset > chunkDimensions.x - 1;
  248.                     bool yOutOfRange = vertex.y + yOffset < 0 || vertex.y + yOffset > chunkDimensions.y - 1;
  249.                     bool zOutOfRange = vertex.z + zOffset < 0 || vertex.z + zOffset > chunkDimensions.z - 1;
  250.  
  251.                     if (xOutOfRange || yOutOfRange || zOutOfRange)
  252.                     {
  253.                         continue;
  254.                     }
  255.  
  256.                     float[] voxel = voxelGrid[Utils.VoxelIndex(vertex.x + xOffset, vertex.y + yOffset, vertex.z + zOffset)];
  257.  
  258.                     for (int i = 0; i < 8; i++)
  259.                     {
  260.                         int x = vertex.x + xOffset + cornerOffsets[i].x;
  261.                         int y = vertex.y + yOffset + cornerOffsets[i].y;
  262.                         int z = vertex.z + zOffset + cornerOffsets[i].z;
  263.  
  264.                         float dist = Vector3.Distance(vertex, new Vector3(x, y, z));
  265.  
  266.                         if (dist < brushSize)
  267.                         {
  268.                             voxel[i] = addTerrain ? voxel[i] + brushStrength : voxel[i] - brushStrength;
  269.                         }
  270.                     }
  271.                 }
  272.             }
  273.         }
  274.  
  275.         chunk.GetComponent<MeshFilter>().mesh = ChunkMesh(new Vector2Int((int)chunk.transform.position.x, (int)chunk.transform.position.z));
  276.     }
  277.  
  278.     public void CreateVoxelGrid(NativeArray<float> noiseMap2D, NativeArray<float> noiseMap3D)
  279.     {
  280.         voxelGrid = new float[chunkDimensions.x * chunkDimensions.y * chunkDimensions.z / (lod * lod * lod)][];
  281.  
  282.         for (int z = 0, i = 0; z < chunkDimensions.z; z+=lod)
  283.         {
  284.             for (int y = 0; y < chunkDimensions.y; y += lod)
  285.             {
  286.                 for (int x = 0; x < chunkDimensions.x; x += lod, i++)
  287.                 {                    
  288.                     CreateVoxel(new Vector3Int(x, y, z), i, noiseMap2D, noiseMap3D);
  289.                 }
  290.             }
  291.         }
  292.     }
  293.  
  294.     public void CreateVoxel(Vector3Int pos, int index, NativeArray<float> noiseMap2D, NativeArray<float> noiseMap3D)
  295.     {
  296.         voxelGrid[index] = new float[8];
  297.  
  298.         int noise2DIndex = ((pos.x / lod) + ((pos.z / lod) * chunkDimensions.x)) * 8;
  299.  
  300.         for (int i = 0; i < 8; i++)
  301.         {
  302.             Vector3Int cornerPos = pos + cornerOffsets[i];
  303.  
  304.             voxelGrid[index][i] = (-cornerPos.y + noiseMap2D[noise2DIndex + i] * heightMultiplier); //* density + //noiseMap3D[(index * 8) + i];
  305.  
  306.             if(index < 1000)
  307.             {
  308.                 Debug.Log(noise2DIndex + ": " + (-cornerPos.y + noiseMap2D[noise2DIndex + i] * heightMultiplier));
  309.             }
  310.         }
  311.     }
  312. }
  313.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement