使用阵列网格

本教程将介绍使用 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组的PoolLinArray

  • ARRAY_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)