使用阵列网格¶
本教程将介绍使用 ArrayMesh
为此,我们将使用函数 add_surface_from_arrays() ,最多需要四个参数。前两个是必需的,后两个是可选的。
第一个是 PrimitiveType
,这是一个OpenGL概念,它指示GPU如何根据给定的顶点排列基本体,无论它是三角形、直线、点等。可以在 Mesh 类引用页。
第二个是存储网格信息的实际数组。数组是一个普通的godot数组,由空括号构成 []
. 它存储了一个 Pool**Array
(例如,poolvector3array、poolintarray等)用于各种类型的信息。
ARRAY_VERTEX
=0池向量3数组或池向量2数组ARRAY_NORMAL
=1池向量3数组ARRAY_TANGENT
=2 4个浮点数组的池数组。前3个浮点数决定切线,最后一个双正态方向为-1或1。ARRAY_COLOR
=3池氯阵列ARRAY_TEX_UV
=4池向量2数组或池向量3数组ARRAY_TEX_UV2
=5池向量2数组或池向量3数组ARRAY_BONES
=6 4个浮点组的PoolRealArray或4个int组的PoolLinArrayARRAY_WEIGHTS
=7 4个浮点数组的池数组ARRAY_INDEX
=8_poolintarray
始终需要顶点数组。所有其他选项都是可选的,仅在包含时使用。
除索引数组外,每个数组都需要与顶点数组具有相同数量的元素。对于像切线这样的数组,元素是一组4个浮点。所以数组大小将是顶点数组大小的四倍,但它们的元素数相同
索引数组是唯一的。
第三个参数是网格要使用的混合变形数组。虽然本教程不介绍使用Blendshapes,但可以在从数组创建曲面时指定它们。
最后一个参数是compress标志,它指定要用一半的位存储哪些数组。这些值可以在arrayFormat下的visualserver的classref中找到。//我想我可以链接到这个
对于正常使用,最好将最后两个参数留空。
ArrayMesh¶
添加一个 ArrayMesh 到一个网格实例。通常,在编辑器中添加一个arraymesh是不有用的,但在这种情况下,它允许AS从代码中访问arraymesh而不创建代码。
接下来,将脚本添加到MeshInstance。
下 _ready()
,创建新数组。
var arr = []
这将是我们保存曲面信息的数组,它将保存曲面所需的所有数据数组。戈多希望它的大小 Mesh.ARRAY_MAX
,因此相应地调整大小。
var arr = []
arr.resize(Mesh.ARRAY_MAX)
接下来,为您将使用的每个数据类型创建数组。
var verts = PoolVector3Array()
var uvs = PoolVector2Array()
var normals = PoolVector3Array()
var indices = PoolIntArray()
使用几何图形填充数据数组后,可以通过将每个数组添加到 surface_array
然后致力于网格。
arr[Mesh.ARRAY_VERTEX] = verts
arr[Mesh.ARRAY_TEX_UV] = uvs
arr[Mesh.ARRAY_NORMAL] = normals
arr[Mesh.ARRAY_INDEX] = indices
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) # No blendshapes or compression used
注解
在这个例子中,我们使用 Mesh.PRIMITIVE_TRIANGLES
,但可以使用网格中可用的任何基本类型。
将完整的代码组合起来如下:
extends MeshInstance
func _ready():
var arr = []
arr.resize(Mesh.ARRAY_MAX)
# PoolVectorXXArrays for mesh construction
var verts = PoolVector3Array()
var uvs = PoolVector2Array()
var normals = PoolVector3Array()
var indices = PoolIntArray()
#######################################
## Insert code here to generate mesh ##
#######################################
# Assign arrays to mesh array
arr[Mesh.ARRAY_VERTEX] = verts
arr[Mesh.ARRAY_TEX_UV] = uvs
arr[Mesh.ARRAY_NORMAL] = normals
arr[Mesh.ARRAY_INDEX] = indices
# create mesh surface from mesh array
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) # No blendshapes or compression used
中间的代码可以是您想要的任何代码。下面我们将介绍一些可以在中间进行的示例代码。
生成几何图形¶
下面是生成球体的示例代码。虽然代码是在gdscript中呈现的,但是对于生成代码的方法没有特定的godot。这个实现与数组网格没有特别的关系,只是生成一个球体的一般方法。如果您在理解过程几何时遇到困难,或者希望了解更多关于过程几何的信息,您可以使用任何在线教程。
extends MeshInstance
var rings = 50
var radial_segments = 50
var height = 1
var radius = 1
func _ready():
##Set up the PoolVectorXXArrays
# Vertex indices
var thisrow = 0
var prevrow = 0
var point = 0
# Loop over rings
for i in range(rings+1):
var v = float(i) / (rings)
var w = sin(PI * v)
var y = cos(PI * v)
# Loop over segments in ring
for j in range(radial_segments):
var u = float(j) / (radial_segments)
var x = sin(u * PI * 2.0)
var z = cos(u * PI * 2.0)
var vert = Vector3(x * radius * w, y, z * radius * w)
verts.append(vert)
normals.append(vert.normalized())
uvs.append(Vector2(u, v))
point += 1
# Create triangles in ring using indices
if (i>0 and j>0):
indices.append(prevrow + j - 1)
indices.append(prevrow + j)
indices.append(thisrow + j - 1)
indices.append(prevrow + j)
indices.append(thisrow + j)
indices.append(thisrow + j - 1)
if (i>0):
indices.append(prevrow + radial_segments - 1)
indices.append(prevrow)
indices.append(thisrow + radial_segments - 1)
indices.append(prevrow)
indices.append(prevrow + radial_segments)
indices.append(thisrow + radial_segments - 1)
prevrow = thisrow
thisrow = point
##Commit to the ArrayMesh
结合上面的代码,该代码将生成一个球体。
当使用arraymesh生成几何图形时,您需要了解每个数组中的内容,然后您可以按照任何语言/引擎的教程将其转换为godot。
储蓄¶
最后,godot提供了使用 ResourceSaver 类。当您希望生成一个网格,然后在以后使用它而不必重新生成时,这是非常有用的。
# Saves mesh to a .tres file with compression enabled
ResourceSaver.save("res://sphere.tres", mesh, 32)