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.

MeshDataToolの使用

MeshDataTool はジオメトリの生成には使用されません。しかしメッシュをテッセレーションしたり、簡略化したり、または変形するスクリプトを作成する場合など、ジオメトリを動的に変更するのに役立ちます。

The MeshDataTool is not as fast as altering arrays directly using ArrayMesh. However, it provides more information and tools to work with meshes than the ArrayMesh does. When the MeshDataTool is used, it calculates mesh data that is not available in ArrayMeshes such as faces and edges, which are necessary for certain mesh algorithms. If you do not need this extra information then it may be better to use an ArrayMesh.

注釈

MeshDataToolは、PrimitiveType Mesh.PRIMITIVE_TRIANGLES を使用するメッシュでのみ使用できます。

We initialize the MeshDataTool from an ArrayMesh by calling create_from_surface(). If there is already data initialized in the MeshDataTool, calling create_from_surface() will clear it for you. Alternatively, you can call clear() yourself before re-using the MeshDataTool.

以下の例では mesh という ArrayMesh がすでに作成されているものとします。メッシュ生成の例については ArrayMesh チュートリアル を参照してください。

var mdt = MeshDataTool.new()
mdt.create_from_surface(mesh, 0)

create_from_surface() は、ArrayMesh の頂点配列を使用して、エッジ用と面用の2つの追加配列を計算し、合計3つの配列を作成します。

エッジは、任意の2つの頂点間の接続です。エッジ配列の各エッジには、それが構成する2つの頂点への参照と、それが含まれる最大2つの面が含まれます。

面は3つの頂点とそれに対応する3つの辺で構成される三角形です。面配列の各面には、その面を構成する3つの頂点と3つの辺への参照が含まれています。

頂点配列には各頂点に接続されたエッジ、面、法線、色、接線、UV、UV2、ボーン、およびウェイトの情報が含まれます。

これらの配列から情報にアクセスするには、get _****() 形式の関数を使用します:

mdt.get_vertex_count() # Returns the number of vertices in the vertex array.
mdt.get_vertex_faces(0) # Returns an array of faces that contain vertex[0].
mdt.get_face_normal(1) # Calculates and returns the face normal of the second face.
mdt.get_edge_vertex(10, 1) # Returns the second vertex comprising the edge at index 10.

これらの関数で何をするかはあなた次第です。一般的な使用例は、すべての頂点を反復処理し、何らかの方法で変換することです。

for i in range(mdt.get_vertex_count()):
    var vert = mdt.get_vertex(i)
    vert *= 2.0 # Scales the vertex by doubling its size.
    mdt.set_vertex(i, vert)

これらの変更は ArrayMesh 上では実行されません。既存の ArrayMesh を動的に更新する場合は、まず既存のサーフェスを削除してから、 commit_to_surface() を使用して新しいサーフェスを追加します。

mesh.clear_surfaces() # Deletes all of the mesh's surfaces.
mdt.commit_to_surface(mesh)

以下は mesh と呼ばれる球状メッシュを、法線と頂点カラーが更新されたランダムに変形された塊に変換するサンプルです。ベース メッシュの生成方法については ArrayMeshチュートリアル を参照してください。

extends MeshInstance3D

var fnl = FastNoiseLite.new()
var mdt = MeshDataTool.new()

func _ready():
    fnl.frequency = 0.7

    mdt.create_from_surface(mesh, 0)

    for i in range(mdt.get_vertex_count()):
        var vertex = mdt.get_vertex(i).normalized()
        # Scale the vertices using noise.
        vertex = vertex * (fnl.get_noise_3dv(vertex) * 0.5 + 0.75)
        mdt.set_vertex(i, vertex)

    # Calculate the vertex normals, face-by-face.
    for i in range(mdt.get_face_count()):
        # Get the index in the vertex array.
        var a = mdt.get_face_vertex(i, 0)
        var b = mdt.get_face_vertex(i, 1)
        var c = mdt.get_face_vertex(i, 2)
        # Get the vertex position using the vertex index.
        var ap = mdt.get_vertex(a)
        var bp = mdt.get_vertex(b)
        var cp = mdt.get_vertex(c)
        # Calculate the normal of the face.
        var n = (bp - cp).cross(ap - bp).normalized()
        # Add this face normal to the current vertex normals.
        # This will not result in perfect normals, but it will be close.
        mdt.set_vertex_normal(a, n + mdt.get_vertex_normal(a))
        mdt.set_vertex_normal(b, n + mdt.get_vertex_normal(b))
        mdt.set_vertex_normal(c, n + mdt.get_vertex_normal(c))

    # Run through the vertices one last time to normalize their normals and
    # set the vertex colors to these new normals.
    for i in range(mdt.get_vertex_count()):
        var v = mdt.get_vertex_normal(i).normalized()
        mdt.set_vertex_normal(i, v)
        mdt.set_vertex_color(i, Color(v.x, v.y, v.z))

    mesh.clear_surfaces()
    mdt.commit_to_surface(mesh)