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