using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class CreateModelByVertices : MonoBehaviour
{
public int _resolution;
private GameObject _Root;
private MeshData[] _meshDatas;
private List<MeshFilter> _meshFilterList = new List<MeshFilter>();
[ContextMenu("生成Cube")]
public void CreateCube()
{
if (_Root != null)
DestroyImmediate(_Root);
_meshFilterList.Clear();
_meshDatas = GenerateFaces(_resolution);
_Root = new GameObject("Go");
foreach (var meshData in _meshDatas)
{
GameObject faceGo = new GameObject("face");
faceGo.transform.SetParent(_Root.transform);
var meshFilter = faceGo.AddComponent<MeshFilter>();
Mesh mesh = new Mesh();
mesh.vertices = meshData.vertices;
mesh.triangles = meshData.triangles;
meshFilter.mesh = mesh;
var meshRenderer = faceGo.AddComponent<MeshRenderer>();
meshRenderer.material = new Material(Shader.Find("Standard"));
_meshFilterList.Add(meshFilter);
}
}
[ContextMenu("变球")]
public void CreateSphere()
{
BuildSphere();
}
void BuildSphere()
{
for (int i = 0; i < _meshDatas.Length; i++)
{
StartCoroutine(ModifyVertices(_meshFilterList[i], _meshDatas[i]));
}
}
private void BuildOneFace(MeshFilter meshFilter, MeshData meshData)
{
Mesh mesh = new Mesh();
mesh.vertices = meshData.vertices;
mesh.triangles = meshData.triangles;
meshFilter.mesh = mesh;
}
IEnumerator ModifyVertices(MeshFilter meshFilter, MeshData meshData)
{
for (int i = 0; i < meshData.vertices.Length; i++)
{
meshData.vertices[i] = PointOnCubeToPointOnSphere(meshData.vertices[i]);
BuildOneFace(meshFilter, meshData);
yield return null;
}
}
public static Vector3 PointOnCubeToPointOnSphere(Vector3 p)
{
return p / Mathf.Sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
}
private MeshData CreateFace(Vector3 normal, int resolution)
{
Vector3 axisA = new Vector3(normal.y, normal.z, normal.x);
Vector3 axisB = Vector3.Cross(normal, axisA);
Vector3[] vertices = new Vector3[resolution * resolution];
int[] triangles = new int[(resolution - 1) * (resolution - 1) * 6];
int triIndex = 0;
for (int y = 0; y < resolution; y++)
{
for (int x = 0; x < resolution; x++)
{
int vertexIndex = x + y * resolution;
Vector2 t = new Vector2(x, y) / (resolution - 1f);
Vector3 point = normal + axisA * (2 * t.x - 1) + axisB * (2 * t.y - 1);
vertices[vertexIndex] = point;
if (x != resolution - 1 && y != resolution - 1)
{
triangles[triIndex + 0] = vertexIndex;
triangles[triIndex + 1] = vertexIndex + resolution + 1;
triangles[triIndex + 2] = vertexIndex + resolution;
triangles[triIndex + 3] = vertexIndex;
triangles[triIndex + 4] = vertexIndex + 1;
triangles[triIndex + 5] = vertexIndex + resolution + 1;
triIndex += 6;
}
}
}
return new MeshData(vertices, triangles);
}
private MeshData[] GenerateFaces(int resolution)
{
MeshData[] allMeshDatas = new MeshData[6];
Vector3[] faceNormals =
{
Vector3.up,
Vector3.down,
Vector3.left,
Vector3.right,
Vector3.forward,
Vector3.back,
};
for (int i = 0; i < faceNormals.Length; i++)
{
allMeshDatas[i] = CreateFace(faceNormals[i], resolution);
}
return allMeshDatas;
}
public class MeshData
{
public Vector3[] vertices;
public int[] triangles;
public MeshData(Vector3[] vertices, int[] triangles)
{
this.triangles = triangles;
this.vertices = vertices;
}
}
}
根据顶点创建Cube Sphere
最新推荐文章于 2024-01-19 16:23:09 发布