2 #include "AssimpReader.h"
4 #include <LibQtGeoViewerCore/SceneMain.h>
6 #include "../FileUtil.h"
8 #include <C2/util/string_util.h>
9 #include <LibGeo/Path.h>
11 #include <assimp/Importer.hpp>
12 #include <assimp/scene.h>
13 #include <assimp/postprocess.h>
14 #include "AssimpUtil.h"
20 bool AssimpReader::Load(SceneMain& scene, const std::string& filename)
22 unsigned int ai_option =
23 aiProcess_JoinIdenticalVertices;
25 Assimp::Importer importer;
26 const aiScene* ai_scene = importer.ReadFile(filename, ai_option);
30 std::string dirpath = lib_geo::Path::GetParentDirPath(filename);
33 std::map<int, MeshBuf*> AiToLGMesh;
35 bool HasAnimation = (ai_scene->mNumAnimations > 0);
37 GeomObject* geom = scene.CreateNewGeometry();
38 for (unsigned int i = 0; i < ai_scene->mNumMeshes; ++i)
40 aiMesh* mesh = ai_scene->mMeshes[i];
41 MeshBuf* mbuf = geom->CreateNewMeshBuf();
45 lib_geo::BaseMesh& mesh_dst = mbuf->m_Mesh;
47 geom->m_Name = mesh->mName.C_Str();
48 if (geom->m_Name.empty())
50 std::ostringstream oss;
51 oss << FileUtil::GetFileTitle(filename) << "-" << i;
52 geom->m_Name = oss.str();
55 AssimpUtil::CopyAIVerts(mesh_dst, mesh);
56 AssimpUtil::CopyAIFaces(mesh_dst, mesh);
57 AssimpUtil::CopyMaterials(geom, mbuf, ai_scene, scene, dirpath);
59 ResetBone(geom, bone_map, mesh);
61 if (!mesh_dst.HasNormal())
63 mesh_dst.CreateNormalsEachVerts();
64 mesh_dst.UpdateNormal();
68 geom->m_BoneAnimation.m_SrcVertPos = mesh_dst.m_Verts;
71 SetBoneToGeom(ai_scene, bone_map, geom);
73 ApplyASTransform(ai_scene->mRootNode, ai_scene->mRootNode->mTransformation, AiToLGMesh);
77 const aiAnimation* anim = ai_scene->mAnimations[0];
78 for (unsigned int j = 0; j < anim->mNumChannels; ++j)
80 aiNodeAnim* ch = anim->mChannels[j];
81 Bone* bone = bone_map.Bones[ch->mNodeName.C_Str()];
85 SetKeyToBone(ch, bone);
89 geom->InitializeBufferCommon();
90 geom->m_FileFormat = GeomFileFormat::XFile;
91 geom->m_FilePath = filename;
93 for (auto& mb : AiToLGMesh)
95 mb.second->UpdateBBox();
96 mb.second->ResetIniBBox();
99 scene.UpdateTransform();
101 scene.ReportDoneEditGeometry();
106 void AssimpReader::ApplyASTransform(aiNode* n, aiMatrix4x4& t, std::map<int, MeshBuf*>& AiToLGMesh)
108 for (int i = 0; i < n->mNumMeshes; ++i)
110 std::map<int, MeshBuf*>::iterator& mp = AiToLGMesh.find(n->mMeshes[i]);
111 if (mp == AiToLGMesh.end())
115 ae::ConvertMat(m, t);
116 mp->second->m_Mesh.ApplyTransform(m);
119 for (int i = 0; i < n->mNumChildren; ++i)
121 aiNode* cn = n->mChildren[i];
122 ApplyASTransform(cn, t * cn->mTransformation, AiToLGMesh);
126 void AssimpReader::SetKeyToBone(aiNodeAnim* ch, Bone* bone)
128 //
\83t
\83@
\83C
\83\8b\83t
\83H
\81[
\83}
\83b
\83g
\82Ì
\8ed
\97l
\82Æ
\82µ
\82Ä
\82Í,
\91®
\90«
\82²
\82Æ
\82É
\83L
\81[
\97v
\91f
\90\94\82ª
\88Ù
\82È
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
\82ª,
129 //
\90§
\8cä
\82ª
\96Ê
\93|
\82È
\82Ì
\82Å
\88ê
\92v
\82µ
\82Ä
\82¢
\82é
\82Æ
\82¢
\82¤
\91O
\92ñ
\82Å
\8f\88\97\9d\82ð
\8dì
\82Á
\82Ä
\82¢
\82é.
130 int num_key = AssimpUtil::GetNumKeyOfFrame(ch);
131 bone->m_Translate.resize(num_key);
132 bone->m_Scale.resize(num_key);
133 bone->m_Rotate.resize(num_key);
135 for (unsigned int k = 0; k < ch->mNumPositionKeys; ++k)
137 ae::ConvertVec(bone->m_Translate[k], ch->mPositionKeys[k].mValue);
140 for (unsigned int k = 0; k < ch->mNumScalingKeys; ++k)
142 ae::ConvertVec(bone->m_Scale[k], ch->mScalingKeys[k].mValue);
145 for (unsigned int k = 0; k < ch->mNumRotationKeys; ++k)
147 ae::AiQuatToLmQuat(bone->m_Rotate[k], ch->mRotationKeys[k].mValue);
151 void AssimpReader::ResetBone(GeomObject* geom, BoneMap& bone_map, aiMesh* mesh)
153 geom->m_BoneAnimation.m_Bones.resize(mesh->mNumBones);
154 for (unsigned int j = 0; j < mesh->mNumBones; ++j)
156 const aiBone* s_bone = mesh->mBones[j];
157 Bone& d_bone = geom->m_BoneAnimation.m_Bones[j];
158 d_bone.m_Name = s_bone->mName.C_Str();
160 ConvertBoneWeight(s_bone, d_bone);
163 ae::ConvertMat(offset, s_bone->mOffsetMatrix);
164 d_bone.SetOffset(offset);
166 bone_map.Bones[d_bone.m_Name] = &d_bone;
170 void AssimpReader::ConvertBoneWeight(const aiBone* s_bone, geom::Bone& d_bone)
172 d_bone.m_Weights.resize(s_bone->mNumWeights);
173 for (unsigned int k = 0; k < s_bone->mNumWeights; ++k)
175 BoneWeight& bw = d_bone.m_Weights[k];
176 aiVertexWeight& vw = s_bone->mWeights[k];
177 bw.m_Vid = vw.mVertexId;
178 bw.m_Weight = vw.mWeight;
182 void AssimpReader::SetBoneToGeom(const aiScene* ai_scene, geom::BoneMap& bone_map, geom::GeomObject* geom)
184 const aiNode* root = ai_scene->mRootNode;
185 for (unsigned int j = 0; j < root->mNumChildren; ++j)
187 aiNode* n = root->mChildren[j];
188 for (unsigned int k = 0; k < n->mNumChildren; ++k)
190 aiNode* nc = n->mChildren[k];
191 Bone* b_root = bone_map.Bones[nc->mName.C_Str()];
195 bone_map.Bones[nc->mName.C_Str()] = b_root;
196 b_root->m_Name = nc->mName.C_Str();
197 geom->m_BoneAnimation.m_Bones.push_back(b_root);
200 BoneNode* br = new BoneNode();
201 geom->m_BoneAnimation.m_RootNodes.push_back(br);
204 ae::ConvertMat(br->m_Transform, n->mTransformation);
206 std::set<aiNode*> passed;
207 AssimpUtil::CreateBoneTree(bone_map, br, nc, passed);
212 void AssimpReader::LoadAnimation(const aiScene* ai_scene, BoneMap& bone_map)
214 const aiAnimation* anim = ai_scene->mAnimations[0];
215 for (unsigned int j = 0; j < anim->mNumChannels; ++j)
217 aiNodeAnim* ch = anim->mChannels[j];
218 Bone* bone = bone_map.Bones[ch->mNodeName.C_Str()];
222 int num_key = AssimpUtil::GetNumKeyOfFrame(ch);
224 //
\83t
\83@
\83C
\83\8b\83t
\83H
\81[
\83}
\83b
\83g
\82Ì
\8ed
\97l
\82Æ
\82µ
\82Ä
\82Í,
\91®
\90«
\82²
\82Æ
\82É
\83L
\81[
\97v
\91f
\90\94\82ª
\88Ù
\82È
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
\82ª,
225 //
\90§
\8cä
\82ª
\96Ê
\93|
\82È
\82Ì
\82Å
\88ê
\92v
\82µ
\82Ä
\82¢
\82é
\82Æ
\82¢
\82¤
\91O
\92ñ
\82Å
\8f\88\97\9d\82ð
\8dì
\82Á
\82Ä
\82¢
\82é.
226 bone->m_Translate.resize(num_key);
227 bone->m_Scale.resize(num_key);
228 bone->m_Rotate.resize(num_key);
230 for (unsigned int k = 0; k < ch->mNumPositionKeys; ++k)
232 ae::ConvertVec(bone->m_Translate[k], ch->mPositionKeys[k].mValue);
235 for (unsigned int k = 0; k < ch->mNumScalingKeys; ++k)
237 ae::ConvertVec(bone->m_Scale[k], ch->mScalingKeys[k].mValue);
240 for (unsigned int k = 0; k < ch->mNumRotationKeys; ++k)
242 ae::AiQuatToLmQuat(bone->m_Rotate[k], ch->mRotationKeys[k].mValue);
245 bone->m_KeyIdxOffset = GetNumMinusKeyFrames(ch);
249 // 0
\95b
\96¢
\96\9e\82Ì
\83L
\81[
\83t
\83\8c\81[
\83\80\90\94\82ð
\90\94\82¦
\82é
250 int AssimpReader::GetNumMinusKeyFrames(const aiNodeAnim* ch) const
252 for (unsigned int i = 0; i < ch->mNumPositionKeys; ++i)
254 if(ch->mPositionKeys[i].mTime >= 0)
258 //
\91S
\83t
\83\8c\81[
\83\80\82ª0
\95b
\96¢
\96\9e
261 return ch->mNumPositionKeys;