Mesh API v2 の罠

今更ながらに Mesh API v2 と呼ばれるものを触ってみたけど、初っ端から罠に引っかかった。

v2 では、頂点データの配列を別々に渡すのではなく、インターリーブされたものとして渡す。なので、一つの頂点データがどういう構造になっているかを伝えてやらねばならないのだが、以下はダメ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct Vertex
{
public Vector3 BeginPos;
public Vector3 EndPos;
public Vector4 Adjuster;
public Color Color;
public Vector3 Normal0;
public Vector4 Normal1;
}
public static VertexAttributeDescriptor[] Layout = new[]{
new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.TexCoord1, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.TexCoord2, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4),
};

何故か。

一日悩んで、諦めた。と言うのも、使っていた場所が Runtime ではなく、Editor 拡張だったから。

Asset としての Mesh をいじる場合は、シリアライズしたりする必要もあって、従来の API を使うべきなのでは?と思ったのだ。マニュアルにそうしろとは書いてなかったが(伏線)。

飯食って、そろそろ寝るかと落ち着いた時に、「まさか」と思って試したらうまくいったのが次のコード。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct Vertex
{
public Vector3 BeginPos;
public Vector3 Normal0;
public Vector4 Normal1;
public Vector3 EndPos;
public Vector4 Adjuster;
public Color Color;
}
public static VertexAttributeDescriptor[] Layout = new[]{
new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.TexCoord1, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.TexCoord2, VertexAttributeFormat.Float32, 4),
};

違うのは、 VertexAttribute の順番。これを、おそらく enum VertexAttribute の定義順に合わせた。

それなら最初に言ってくれよ……。マニュアルにそうしろとは書いてなかった(回収)。

まあ、でもこれ、 Unity というより、グラフィックの API 側の都合のような気はする。最近はとんと、直接 API に触れることもなくなったので、「オマエがヌルいだけじゃねーか」と言われれば、「はい」としか(‘A’)