はじめに
Assimpを使ってFBXモデルを読み込んだときに、「モデルが変な方向を向いてる」ということはありませんか?
アニメーションがないモデルでは、意図しない回転が起きることがあります。
実は、アニメーションの有無によってAssimpの読み込みフラグを切り替えることで、解決できる場合があります。
この記事ではその具体的な方法を紹介します。
2025-06-19
Assimpを使ってFBXモデルを読み込んだときに、「モデルが変な方向を向いてる」ということはありませんか?
アニメーションがないモデルでは、意図しない回転が起きることがあります。
実は、アニメーションの有無によってAssimpの読み込みフラグを切り替えることで、解決できる場合があります。
この記事ではその具体的な方法を紹介します。
アニメーションがないモデルを読み込むとき、aiProcess_PreTransformVerticesのフラグをつけると上手くいくことがあります。
このフラグは、モデル内のノード階層(親子関係)やボーンの情報を削除し、全ての頂点に最終的な変換行列を適用します。
つまり、途中で回転やスケーリングが入っているノード構造でも、全部一つの空間に統合するので、意図しない回転の影響を受けにくくなります。
ただし、この処理を行なうとボーン・階層構造・アニメーションの情報は失われます
なので、アニメーションがないモデルにのみ適用しましょう。
以下のコードは、私が実際にアニメーションがないモデルを読み込んでいるときのものです。
const aiScene* scene = importer.ReadFile(fbxFilePath.narrow(),
aiProcess_Triangulate
| aiProcess_JoinIdenticalVertices
| aiProcess_LimitBoneWeights
| aiProcess_ImproveCacheLocality
| aiProcess_FlipUVs
| aiProcess_ConvertToLeftHanded
| aiProcess_PreTransformVertices
);
アニメーションがあるモデルの時は先程紹介した aiProcess_PreTransformVertices のフラグを使わずに読み込みます。
このフラグを使ってしまうと、アニメーションに必要なボーン構造や階層構造が失われてしまうからです。
以下は、私がアニメーション付きのFBXモデルを読み込む際に使用しているフラグ設定です。
const aiScene* scene = importer.ReadFile(fbxFilePath.narrow(),
aiProcess_Triangulate
| aiProcess_JoinIdenticalVertices
| aiProcess_LimitBoneWeights
| aiProcess_ImproveCacheLocality
| aiProcess_FlipUVs
| aiProcess_ConvertToLeftHanded
);
アニメーションの有無で読み込みフラグを自動で変えたい、という場合は scene->HasAnimation() を使うことで実装できます。
仮のシーン「tempScene」でアニメーションの有無を確認し、読み込みフラグをif文を使って切り替えます。
const aiScene* tempScene = importer.ReadFile(fbxFilePath.narrow(),
aiProcess_Triangulate
| aiProcess_JoinIdenticalVertices
| aiProcess_LimitBoneWeights
| aiProcess_ImproveCacheLocality
| aiProcess_FlipUVs
| aiProcess_ConvertToLeftHanded
);
if (!tempScene)
{
throw std::runtime_error("FBXファイルのロードに失敗しました");
}
// アニメーション:有 -> tempSceneと同じフラグ
if (tempScene->HasAnimations())
{
scene = importer.ReadFile(fbxFilePath.narrow(),
aiProcess_Triangulate
| aiProcess_JoinIdenticalVertices
| aiProcess_LimitBoneWeights
| aiProcess_ImproveCacheLocality
| aiProcess_FlipUVs
| aiProcess_ConvertToLeftHanded
);
}
// アニメーション:無 -> aiProcess_PreTransformVerticesを追加
else
{
scene = importer.ReadFile(fbxFilePath.narrow(),
aiProcess_Triangulate
| aiProcess_JoinIdenticalVertices
| aiProcess_LimitBoneWeights
| aiProcess_ImproveCacheLocality
| aiProcess_FlipUVs
| aiProcess_ConvertToLeftHanded
| aiProcess_PreTransformVertices
);
}
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)
{
Console << U"Assimp読み込みエラー:" << Unicode::FromUTF8(importer.GetErrorString());
return;
}
アニメーションの有無によって、Assimpの読み込みフラグを切り替えることで、回転のトラブルを回避できることを紹介しました。
このほかにもAssimpに関する記事をいくつか投稿しているので、ぜひ他の記事もチェックしてみてください!