Cube
Posted llstart-new0201
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cube相关的知识,希望对你有一定的参考价值。
1.概述
Unity自带cube模型,但是此文实现,分基础版和完善版。基础版不进行顶点法线计算,完善版会进行法线计算,结果会跟自带cube比较接近。
2.基础版Cube
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 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.name = MeshName;
mesh.vertices = Vertices;
mesh.triangles = Triangles;
mesh.uv = Uvs;
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 Cube代码
代码即为定义八个顶点,然后依次设置三角形即可。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreateCube : CreateMeshBase
{
public float halfLength = 5;
protected override string MeshName
{
get
{
return "Cube Mesh";
}
}
protected override Vector3[] Vertices
{
get
{
Vector3[] vertices = new Vector3[8];
vertices[0] = new Vector3(-halfLength, -halfLength, -halfLength);
vertices[1] = new Vector3(halfLength, -halfLength, -halfLength);
vertices[2] = new Vector3(halfLength, -halfLength, halfLength);
vertices[3] = new Vector3(-halfLength, -halfLength, halfLength);
vertices[4] = new Vector3(-halfLength, halfLength, -halfLength);
vertices[5] = new Vector3(halfLength, halfLength, -halfLength);
vertices[6] = new Vector3(halfLength, halfLength, halfLength);
vertices[7] = new Vector3(-halfLength, halfLength, halfLength);
return vertices;
}
}
protected override int[] Triangles
{
get
{
int[] triangles = new int[36]
{
0,1,3,
3,1,2,
4,6,5,
4,7,6,
1,6,2,
1,5,6,
0,3,4,
4,3,7,
0,4,1,
1,4,5,
3,2,6,
3,6,7
};
return triangles;
}
}
}
3.完善版Cube
3.1 基础版Cube的问题
基础版Cube由于三个面公用一个顶点,导致此顶点处的法线和切线无法定义,所以需要分离顶点。这样顶点位置存在三个相互重合的点,每个点只跟自己对应的平面产生关系。
3.2 完善版Cube顶点
新Cube生成方法实在基础版基础上生成的,但是定点数由8个变成36个,即根据基础版的三角形数组生成。如下所示
protected override Vector3[] Vertices
{
get
{
Vector3[] vertices = new Vector3[8];
vertices[0] = new Vector3(-halfLength, -halfLength, -halfLength);
vertices[1] = new Vector3(halfLength, -halfLength, -halfLength);
vertices[2] = new Vector3(halfLength, -halfLength, halfLength);
vertices[3] = new Vector3(-halfLength, -halfLength, halfLength);
vertices[4] = new Vector3(-halfLength, halfLength, -halfLength);
vertices[5] = new Vector3(halfLength, halfLength, -halfLength);
vertices[6] = new Vector3(halfLength, halfLength, halfLength);
vertices[7] = new Vector3(-halfLength, halfLength, halfLength);
int[] triangles = new int[36]
{
0,3,1,
3,2,1,
4,5,6,
4,6,7,
1,2,6,
1,6,5,
0,4,3,
4,7,3,
0,1,4,
1,5,4,
3,6,2,
3,7,6
};
cubeVertices = new Vector3[36];
for (int i = 0; i < cubeVertices.Length; i++)
{
cubeVertices[i] = vertices[triangles[i]];
}
return cubeVertices;
}
}
3.3 三角形数组
根据3.2生成的新的顶点数组,此时三角形数组值即为其索引,如下所示:
protected override int[] Triangles
{
get
{
/*int[] triangles = new int[36]
{
0,1,3,
3,1,2,
4,6,5,
4,7,6,
1,6,2,
1,5,6,
0,3,4,
4,3,7,
0,4,1,
1,4,5,
3,2,6,
3,6,7
};*/
int[] triangles = new int[36];
for (int i = 0; i < triangles.Length; i++)
{
triangles[i] = i;
}
return triangles;
}
}
3.4 法线数组
基础版cube看起来与unity自带的相比比较奇怪,这是因为没有设置顶点的法向。由于基础版公用顶点,所以法线无法定义,所以新版本法线则比较容易。如下所示:
protected override Vector3[] Normals
{
get
{
Vector3[] normals = new Vector3[36];
for (int i = 0; i < normals.Length - 2; i+=3)
{
Vector3 normal = Vector3.Cross(cubeVertices[i + 1] - cubeVertices[i], cubeVertices[i + 2] - cubeVertices[i]);
for (int j = 0; j < 3; j++)
{
normals[i + j] = normal;
}
}
return normals;
}
}
3.5 完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreateNewCube : CreateMeshBase
{
public float halfLength = 5;
private Vector3[] cubeVertices = new Vector3[36];
protected override string MeshName
{
get
{
return "Cube Mesh";
}
}
protected override Vector3[] Vertices
{
get
{
Vector3[] vertices = new Vector3[8];
vertices[0] = new Vector3(-halfLength, -halfLength, -halfLength);
vertices[1] = new Vector3(halfLength, -halfLength, -halfLength);
vertices[2] = new Vector3(halfLength, -halfLength, halfLength);
vertices[3] = new Vector3(-halfLength, -halfLength, halfLength);
vertices[4] = new Vector3(-halfLength, halfLength, -halfLength);
vertices[5] = new Vector3(halfLength, halfLength, -halfLength);
vertices[6] = new Vector3(halfLength, halfLength, halfLength);
vertices[7] = new Vector3(-halfLength, halfLength, halfLength);
int[] triangles = new int[36]
{
0,3,1,
3,2,1,
4,5,6,
4,6,7,
1,2,6,
1,6,5,
0,4,3,
4,7,3,
0,1,4,
1,5,4,
3,6,2,
3,7,6
};
cubeVertices = new Vector3[36];