MeshDataToolの使用

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

MeshDataToolは、ArrayMeshを使用して配列を直接変更するほど高速ではありません。ただし、ArrayMeshよりも多くの情報とメッシュを操作するツールを提供します。 MeshDataToolを使用すると、特定のメッシュアルゴリズムに必要なFace(面)やEdge(エッジ/辺)などのArrayMeshでは使用できないメッシュデータが計算されます。この追加情報が必要ない場合は、ArrayMeshを使用することをお勧めします。

注釈

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

例として、ArrayMeshチュートリアル で生成されたメッシュを変形するプロセスを見てみましょう。

メッシュが mesh という名前のArrayMeshに保存されていると仮定します。次に、create_from_surface() を呼び出して、mesh からMeshDataToolを初期化します。 MeshDataToolで初期化されたデータが既にある場合、create_from_surface() を呼び出すとデータがクリアされます。または、MeshDataToolを再利用する前に、自分で `` clear()`` を呼び出すことができます

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

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

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

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

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

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

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

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

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

最後に、commit_to_surface() はArrayMeshに新しいサーフェスを追加します。したがって、既存のArrayMeshを動的に更新する場合は、新しいサーフェスを追加する前に既存のサーフェスを削除してください。

mesh.surface_remove(0) # Deletes the first surface of the mesh.
mdt.commit_to_surface(mesh)

以下は、新しい法線と頂点の色で完全な脈動するブロブを作成する完全な例です。

extends MeshInstance

var sn = OpenSimplexNoise.new()
var mdt = MeshDataTool.new()

func _ready():
    sn.period = 0.7

    mdt.create_from_surface(mesh, 0)

    for i in range(mdt.get_vertex_count()):
        var vertex = mdt.get_vertex(i).normalized()
        # Push out vertex by noise.
        vertex = vertex * (sn.get_noise_3dv(vertex) * 0.5 + 0.75)
        mdt.set_vertex(i, vertex)

    # Calculate 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 vertex position using vertex index.
        var ap = mdt.get_vertex(a)
        var bp = mdt.get_vertex(b)
        var cp = mdt.get_vertex(c)
        # Calculate face normal.
        var n = (bp - cp).cross(ap - bp).normalized()
        # Add face normal to current vertex normal.
        # 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 vertices one last time to normalize normals and
    # set color to normal.
    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.surface_remove(0)
    mdt.commit_to_surface(mesh)