Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
使用 ArrayMesh¶
本教程将介绍使用 ArrayMesh 的基础知识。
To do so, we will use the function add_surface_from_arrays(), which takes up to five parameters. The first two are required, while the last three are optional.
第一个参数是 PrimitiveType
(图元类型),这是 OpenGL 中的概念,用于指示 GPU 如何根据给定的顶点来安排图元,即它们表示的是三角形、线、还是点等等。可选项见 Mesh.PrimitiveType。
The second parameter, arrays
, is the actual Array that stores the mesh information. The array is a normal Godot array that
is constructed with empty brackets []
. It stores a Packed**Array
(e.g. PackedVector3Array,
PackedInt32Array, etc.) for each type of information that will be used to build the surface.
Common elements of arrays
are listed below, together with the position they must have within arrays
.
See Mesh.ArrayType for a full list.
索引 |
Mesh.ArrayType 枚举 |
数组类型 |
---|---|---|
0 |
|
|
1 |
|
|
2 |
|
PackedFloat32Array 或 PackedFloat64Array 4 个浮点数组。 前 3 个浮点数确定切线,最后一个浮点数确定副法线方向,即 -1 或 1。 |
3 |
|
|
4 |
|
|
5 |
|
|
10 |
|
PackedFloat32Array of groups of 4 floats or PackedInt32Array of groups of 4 ints. Each group lists indexes of 4 bones that affects a given vertex. |
11 |
|
PackedFloat32Array or PackedFloat64Array of groups of 4 floats. Each float lists the amount of weight the corresponding bone in |
12 |
|
在大多数情况下,创建网格时,我们通过顶点位置来定义网格。因此,顶点数组(位于索引 0 处)通常是必需的,而索引数组(位于索引 12 处)是可选的,只有在它被包含时才会使用。也可以只创建索引数组而不创建顶点数组,但这超出了本教程的范围。事实上,我们根本不会使用索引数组。
All the other arrays carry information about the vertices. They are optional and will only be used if included. Some of these arrays (e.g. ARRAY_COLOR
)
use one entry per vertex to provide extra information about vertices. They must have the same size as the vertex array. Other arrays (e.g. ARRAY_TANGENT
) use
four entries to describe a single vertex. These must be exactly four times larger than the vertex array.
For normal usage, the last three parameters in add_surface_from_arrays() are typically left empty.
Setting up the ArrayMesh¶
In the editor, create a MeshInstance3D and add an ArrayMesh to it in the Inspector. Normally, adding an ArrayMesh in the editor is not useful, but in this case it allows us to access the ArrayMesh from code without creating one.
Next, add a script to the MeshInstance3D.
在 _ready()
下创建一个新的数组。
var surface_array = []
var surfaceArray = new Godot.Collections.Array();
这将是保存表面信息的数组——将保存表面需要的所有数据数组。Godot 希望它的大小是 Mesh.ARRAY_MAX
,所以要相应地调整。
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
var surfaceArray = new Godot.Collections.Array();
surfaceArray.Resize((int)Mesh.ArrayType.Max);
接下来, 为你将使用的每种数据类型创建数组.
var verts = PackedVector3Array()
var uvs = PackedVector2Array()
var normals = PackedVector3Array()
var indices = PackedInt32Array()
var verts = new List<Vector3>();
var uvs = new List<Vector2>();
var normals = new List<Vector3>();
var indices = new List<int>();
一旦你用几何体填充了你的数据数组, 就可以通过将每个数组添加到 surface_array
, 然后提交到网格中来创建网格.
surface_array[Mesh.ARRAY_VERTEX] = verts
surface_array[Mesh.ARRAY_TEX_UV] = uvs
surface_array[Mesh.ARRAY_NORMAL] = normals
surface_array[Mesh.ARRAY_INDEX] = indices
# No blendshapes, lods, or compression used.
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array)
surfaceArray[(int)Mesh.ArrayType.Vertex] = verts.ToArray();
surfaceArray[(int)Mesh.ArrayType.TexUV] = uvs.ToArray();
surfaceArray[(int)Mesh.ArrayType.Normal] = normals.ToArray();
surfaceArray[(int)Mesh.ArrayType.Index] = indices.ToArray();
var arrMesh = Mesh as ArrayMesh;
if (arrMesh != null)
{
// No blendshapes, lods, or compression used.
arrMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, surfaceArray);
}
备注
在这个例子中,使用了 Mesh.PRIMITIVE_TRIANGLES
,但你也可以使用网格所提供的任何图元类型。
把这些放到一起,完整的代码是这样的:
extends MeshInstance3D
func _ready():
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
# PackedVector**Arrays for mesh construction.
var verts = PackedVector3Array()
var uvs = PackedVector2Array()
var normals = PackedVector3Array()
var indices = PackedInt32Array()
#######################################
## Insert code here to generate mesh ##
#######################################
# Assign arrays to surface array.
surface_array[Mesh.ARRAY_VERTEX] = verts
surface_array[Mesh.ARRAY_TEX_UV] = uvs
surface_array[Mesh.ARRAY_NORMAL] = normals
surface_array[Mesh.ARRAY_INDEX] = indices
# Create mesh surface from mesh array.
# No blendshapes, lods, or compression used.
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array)