自由研究

Unityでメッシュをさわるノウハウ

投稿日:

ヒマなので覚書。ウラを取っていない経験則なので話半分で読んでください。
あと、3Dの基本概念とUnity固有の話の区別が付いていないのでごめんなさい。

Meshクラスの基本

Unityでポリゴンをガッツリいじろうと思うとMeshクラスを読む必要がある。
可動モデルの場合、SkinnedMeshRendererクラスのBakeMeshを使ってベイクしてやるとボーン変形後の情報を持ったメッシュが取れる。
可動させないならSkinnedMeshRenderer.sharedMeshで良いと思う。

だいたい以下のメンバーを読むことになる。

  • Mesh.vertices(頂点一覧)
  • Mesh.triangles(三角形を形成する頂点のインデクス)
  • Mesh.uv(UVマップ上の頂点の座標)

ポリゴンの読み方

Mesh.trianglesはヘンな構成で、配列の要素3個で三角形をつくる。例えば{0,1,2,1,2,3}という配列の場合、最初の3つ「0,1,2」が1つ目の三角形、次の3つ「1,2,3」が2つ目の三角形になる。数字は、Mesh.verticesの添字に使う。

なので簡単には、以下のようなコードで三角形の座標を取得できる。

for (int i = 0; i < mesh.triangles.Length; i += 3)
{
Vector3 A = mesh.vertices[mesh.triangles[i]];
Vector3 B = mesh.vertices[mesh.triangles[i + 1]];
Vector3 C = mesh.vertices[mesh.triangles[i + 2]];
/* 三角形ABCへの処理*/
}

しかしこのコードには実用上いくつか問題がある。

マテリアルを気にするならMesh.trianglesを使ってはいけない

Mesh.trianglesは、マテリアルの区別なく全ての三角形を返す。
したがって、これで取り出した情報はマテリアルと紐付けられない。
Meshクラスは、サブメッシュという区分けでマテリアルを区別している。
サブメッシュ単位の三角形を取得するmesh.GetTriangles関数を使って、マテリアルごとに三角形を処理すると良い。引数としてサブメッシュ番号を指定する。
サブメッシュの個数は、mesh.subMeshCountから取得できる。
マテリアル自身はRenderer.materials配列から取得できる。配列の添字はサブメッシュ番号と一致する。

Meshクラスの配列を直接読んではいけない

理由は知らないけど、verticesなどの配列は、書き込みはもちろん読み込みすら馬鹿みたいに重い。
for文の中で毎回参照なんてやっているととてもマトモな速度では動いてくれなくなる。
したがって一度ローカルにおいてしまって、そこから読み出すと良い。

以上をもとに、マテリアルごと、かつ常識的な速度で動作するように改造したコードは以下のとおり。

Vector3[] meshVertices = mesh.vertices;

for (int subMesh = 0; subMesh < mesh.subMeshCount; subMesh++) {
int[] submeshTriangles = mesh.GetTriangles(subMesh);
for (int i = 0; i < submeshTriangles.Length; i += 3)
{
Vector3 A = meshVertices[submeshTriangles[i]];
Vector3 B = meshVertices[submeshTriangles[i + 1]];
Vector3 C = meshVertices[submeshTriangles[i + 2]];
/* 三角形ABCへの処理*/
}
}

とにかくMeshクラスのメンバへのアクセスは異様に重たいので、配列を個々にアクセスするような真似は避けて作業しないといけない。
ほんだらまた。

-自由研究

執筆者:


comment

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

no image

MagicaVoxelでUnity用の人間モデルを作ろう(東北ずん子配布もあるよ)

もくじ1 概要1.1 目標1.2 手順1.3 作成モデル2 MagicaVoxel2.1 パーツ分割2.2 出力3 Blender3.1 インポート3.2 モデルの初期調整3.2.1 重複する頂点の削 …

no image

コラボカフェとコメントと私

こんにちは!バーチャルYoutuber大好きぎんしゃりさんです! きょう、以前書いたキズナアイコラボカフェの記事にコメントが来たのでご紹介して、それに関わるお話をしていきますね。 元記事の要約 前回の …

no image

例え話をしないC言語のポインタの説明

もくじ1 まえおき2 Hello, Worldより簡単に2.1 サンプルコード2.2 変数の置き場所2.3 変数が入っているところを見てみる3 C言語とメモリ3.1 変数cの「まわり」を見てみる3.2 …

no image

あみだくじはどれぐらいランダムか

あみだくじ。 紙とペンがあればすぐに作ることができるお手軽な抽選方法として知られています。 なにか物事を決めたいとき、あみだくじを使うという人も多いのではないでしょうか。 ふと思ったんですが、あみだく …

no image

DCEXPO2017に行ってきました

10/27~29にかけて、お台場の日本科学未来館で開催されたデジタルコンテンツエキスポ2017を見に行ってきました。 どれも見ごたえのある展示ばかりで、非常に面白かったのでいくつか紹介したいと思います …