Advertisement
JontePonte

PURE AGONY!!

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