(九)球体
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