1.概述
球體比較復雜,涉及到極點位置會出現聚集的問題,本文采用常規方法繪制球體,然后借鑒他人的方法,通過正八面體拆分的方法生成球體mesh。
2.常規方法
常規方法就是通過極坐標系,分別計算球體表面的坐標,然后依次生成三角形。問題在於當划分較細時,球體兩端的網格會比較細,比較聚集。
2.1 基類
using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))] public class CreateMeshBase : MonoBehaviour { MeshFilter meshFilter; protected Mesh mesh; protected virtual Vector3[] Vertices { get; } protected virtual int[] Triangles { get; } protected virtual Vector3[] Normals { get; } protected virtual Vector4[] Tangents { get; } protected virtual Vector2[] Uvs { get; } protected virtual string MeshName { get; } protected virtual void Start() { GetMeshFilter(); } protected virtual void Reset() { GetMeshFilter(); } protected virtual void OnValidate() { GetMeshFilter(); } void GetMeshFilter() { if (meshFilter == null) { meshFilter = GetComponent<MeshFilter>(); mesh = new Mesh(); } mesh.triangles = null; mesh.uv = null; mesh.vertices = null; mesh.tangents = null; mesh.name = MeshName; mesh.vertices = Vertices; mesh.triangles = Triangles; mesh.uv = Uvs; mesh.normals = Normals; mesh.tangents = Tangents; meshFilter.mesh = mesh; } private void OnDrawGizmos() { if (Vertices == null) return; Gizmos.color = Color.red; Gizmos.DrawSphere(Vector3.zero, 0.5f); Gizmos.color = Color.blue; for (int i = 0; i < Vertices.Length; i++) { Gizmos.DrawSphere(Vertices[i], 0.3f); } } }
2.2 球體mesh
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CreateSphere : CreateMeshBase { public float radius = 10; public int horizontalSize = 10; public int verticalSize = 10; protected override string MeshName { get { return "Sphere mesh"; } } protected override Vector3[] Vertices { get { Vector3[] vertices = new Vector3[(horizontalSize + 1) * (verticalSize + 1)]; float horizontalDelta = 2 * Mathf.PI / horizontalSize; float verticalDelta = 2 * Mathf.PI / verticalSize; for (int i = 0; i < verticalSize + 1; i++) { float rad = i * verticalDelta; float subRadius = radius * Mathf.Sin(rad); float y = radius * Mathf.Cos(rad); for (int j = 0; j < horizontalSize; j++) { int index = i * (horizontalSize + 1) + j; float x = subRadius * Mathf.Cos(j * horizontalDelta); float z = subRadius * Mathf.Sin(j * horizontalDelta); vertices[index] = new Vector3(x, y, z); } } return vertices; } } protected override int[] Triangles { get { int[] triangles = new int[horizontalSize * verticalSize * 2 * 3]; for (int i = 0; i < verticalSize; i++) { for (int j = 0; j < horizontalSize; j++) { int index = (i * horizontalSize + j) * 6; triangles[index] = i * (horizontalSize + 1) + j + 1; triangles[index + 2] = i * (horizontalSize + 1) + j; triangles[index + 1