using System.Collections.Generic; using UnityEngine; public class PlaneGenerator : MonoBehaviour { public Material material; public float noiseLevel = 0.1f; private const int pqsResolution = 16; private const int sphereRadius = 10; private readonly int[] matrixRotate0 = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; // поворот на 0 градусов private readonly int[] matrixRotateX = { 1, 0, 0, 0, 0, -1, 0, 1, 0 }; // поворот на 90 градусов вокруг X private readonly int[] matrixRotateX1 = { 1, 0, 0, 0, 0, 1, 0, -1, 0 }; // поворот на -90 градусов вокруг X private readonly int[] matrixRotateX2 = { 1, 0, 0, 0, -1, 0, 0, 0, -1 }; // поворот на 180 градусов вокруг X private readonly int[] matrixRotateY = { 0, 0, 1, 0, 1, 0, -1, 0, 0 }; // поворот на 90 градусов вокруг Y private readonly int[] matrixRotateY1 = { 0, 0, -1, 0, 1, 0, 1, 0, 0 }; // поворот на -90 градусов вокруг Y private readonly int[] matrixRotateZ = { 0, -1, 0, 1, 0, 0, 0, 0, 1 }; // поворот на 90 градусов вокруг Z private readonly int[] matrixRotateZ1 = { 0, 1, 0, -1, 0, 0, 0, 0, 1 }; // поворот на -90 градусов вокруг Z private List quads; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { BuildRootQuads(); UpdateMeshes(); } // Update is called once per frame void Update() { } private void BuildRootQuads() { quads = new List { BuildQuad("quadY", matrixRotate0), BuildQuad("quadY1", matrixRotateX2), BuildQuad("quadZ", matrixRotateX), BuildQuad("quadZ1", matrixRotateX1), BuildQuad("quadX", matrixRotateZ), BuildQuad("quadX1", matrixRotateZ1) }; } private Quad BuildQuad(string name, int[] matrix) { var (vertices, uv) = CreateVertices(); RotateWithMatrix(vertices, matrix); var triangles = CreateTriangles(); return new Quad { Name = name, Vertices = vertices, Triangles = triangles, Uv = uv }; } private void UpdateMeshes() { foreach (var quad in quads) { CreateMesh(quad.Name, quad.Vertices, quad.Uv, quad.Triangles); } } private (Vector3[] vertices, Vector2[] uv) CreateVertices() { var half = sphereRadius / 2f; var vertices = new Vector3[(pqsResolution + 1) * (pqsResolution + 1)]; Vector2[] uv = new Vector2[(pqsResolution + 1) * (pqsResolution + 1)]; for (int x = 0, vertex = 0; x < pqsResolution + 1; x++) { for (int z = 0; z < pqsResolution + 1; z++, vertex++) { vertices[vertex] = new Vector3(half - (float)x / pqsResolution * sphereRadius, half, half - (float)z / pqsResolution * sphereRadius); uv[vertex] = new Vector2((float)x / pqsResolution, (float)z / pqsResolution); } } return (vertices, uv); } private int[] CreateTriangles() { var triangles = new int[(pqsResolution) * (pqsResolution) * 6]; int triangle = 0; for (int x = 1, vertex = 0; x(); meshFilter.mesh.vertices = vertices; meshFilter.mesh.triangles = triangles; meshFilter.mesh.uv = uv; mesh.GetComponent().sharedMesh = meshFilter.mesh; meshFilter.mesh.RecalculateBounds(); meshFilter.mesh.RecalculateNormals(); mesh.GetComponent().material = material; } private void RotateWithMatrix(Vector3[] vertices, int[] matrix) { Vector3 v; for (int x = 0, vertex = 0; x < pqsResolution + 1; x++) { for (int z = 0; z < pqsResolution + 1; z++, vertex++) { v = vertices[vertex]; vertices[vertex].x = v.x * matrix[0] + v.y * matrix[1] + v.z * matrix[2]; vertices[vertex].y = v.x * matrix[3] + v.y * matrix[4] + v.z * matrix[5]; vertices[vertex].z = v.x * matrix[6] + v.y * matrix[7] + v.z * matrix[8]; //vertices[vertex] = Vector3.Normalize(vertices[vertex]); } } } private float GetNoise(float x, float y) { return 1 + Mathf.PerlinNoise(x, y) * noiseLevel; } private void AddHeights(Vector3[] vertices) { for (int x = 0, vertex = 0; x < pqsResolution + 1; x++) { for (int z = 0; z < pqsResolution + 1; z++, vertex++) { var noise = 1; // GetNoise(vertices[vertex].x, vertices[vertex].y); vertices[vertex] = noise * sphereRadius * vertices[vertex]; } } vertices[pqsResolution + 3] *= 2f; } }