@@ -51,8 +51,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5151#include < assimp/ai_assert.h>
5252#include < assimp/scene.h>
5353#include < assimp/Importer.hpp>
54+ #include < assimp/CreateAnimMesh.h>
5455
5556
57+ #include < streambuf>
5658#include < iomanip>
5759#include < memory>
5860#include < sstream>
@@ -68,6 +70,15 @@ static constexpr aiImporterDesc desc = { "MMD Importer",
6870 0 ,
6971 " pmx" };
7072
73+ namespace {
74+ struct membuf : std::streambuf
75+ {
76+ membuf (char * begin, char * end) {
77+ this ->setg (begin, begin, end);
78+ }
79+ };
80+ }
81+
7182namespace Assimp {
7283
7384using namespace std ;
@@ -163,6 +174,85 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
163174 indexStart += indexCount;
164175 }
165176
177+ {
178+ int morphTotal = 0 ;
179+ for (int morphNo = 0 ; morphNo < pModel->morph_count ; morphNo++) {
180+ const auto & morph = pModel->morphs [morphNo];
181+ if (morph.morph_type != pmx::MorphType::Vertex) {
182+ continue ;
183+ }
184+ if (morph.morph_name .length () <= 0 ) {
185+ continue ;
186+ }
187+ morphTotal++;
188+ }
189+
190+ int indexStart = 0 ;
191+ int indexNext = 0 ;
192+ for (unsigned int i = 0 ; i < pScene->mNumMeshes ; i++) {
193+ const unsigned int indexCount = pModel->materials [i].index_count ;
194+ indexStart = indexNext;
195+ indexNext += indexCount;
196+
197+ auto * aim = pScene->mMeshes [i];
198+ if (aim->mNumAnimMeshes == 0 ) {
199+ aim->mNumAnimMeshes = (unsigned int )morphTotal;
200+ aim->mAnimMeshes = new aiAnimMesh * [aim->mNumAnimMeshes ];
201+ }
202+
203+ int currentMorph = 0 ;
204+ for (int morphNo = 0 ; morphNo < pModel->morph_count ; morphNo++) {
205+
206+ const auto & morph = pModel->morphs [morphNo];
207+ if (morph.morph_type != pmx::MorphType::Vertex) {
208+ continue ;
209+ }
210+ if (morph.morph_name .length () <= 0 ) {
211+ continue ;
212+ }
213+
214+ int c = currentMorph;
215+ currentMorph++;
216+
217+ aim->mAnimMeshes [c] = Assimp::aiCreateAnimMesh (aim);
218+ aiAnimMesh& aiAnimMesh = *(aim->mAnimMeshes [c]);
219+ for (unsigned int v = 0 ; v < aiAnimMesh.mNumVertices ; ++v) {
220+ aiAnimMesh.mVertices [v] = aim->mVertices [v];
221+ }
222+
223+ // vrm
224+ aiAnimMesh.mName = morph.morph_name ;
225+
226+ if (morph.vertex_offsets .get () != nullptr ) {
227+ for (int vertexId = 0 ; vertexId < morph.offset_count ; vertexId++) {
228+ const auto & ver = morph.vertex_offsets [vertexId];
229+ const int targetIndex = ver.vertex_index ;
230+
231+ int bFoundCount = false ;
232+ for (unsigned int uu = 0 ; uu < indexCount; ++uu) {
233+ if (pModel->indices [indexStart + uu] == targetIndex) {
234+ ++bFoundCount;
235+ if (uu < aiAnimMesh.mNumVertices ) {
236+ aiAnimMesh.mVertices [uu].Set (
237+ -morph.vertex_offsets [vertexId].position_offset [0 ],
238+ morph.vertex_offsets [vertexId].position_offset [1 ],
239+ -morph.vertex_offsets [vertexId].position_offset [2 ]);
240+
241+ aiAnimMesh.mVertices [uu] += aim->mVertices [uu];
242+ }
243+ }
244+ }
245+ if (bFoundCount == 0 ) {
246+ continue ;
247+ }
248+
249+ aiAnimMesh.mWeight = 1 .f ;
250+ }
251+ }
252+ }
253+ }
254+ } // morph end
255+
166256 // create node hierarchy for bone position
167257 std::unique_ptr<aiNode *[]> ppNode (new aiNode *[pModel->bone_count ]);
168258 for (auto i = 0 ; i < pModel->bone_count ; i++) {
@@ -174,6 +264,11 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
174264
175265 if (bone.parent_index < 0 ) {
176266 pScene->mRootNode ->addChildren (1 , ppNode.get () + i);
267+ aiVector3D v3 = aiVector3D (
268+ bone.position [0 ],
269+ bone.position [1 ],
270+ bone.position [2 ]);
271+ aiMatrix4x4::Translation (v3, ppNode[i]->mTransformation );
177272 } else {
178273 ppNode[bone.parent_index ]->addChildren (1 , ppNode.get () + i);
179274
@@ -322,7 +417,11 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
322417aiMaterial *MMDImporter::CreateMaterial (const pmx::PmxMaterial *pMat,
323418 const pmx::PmxModel *pModel) {
324419 aiMaterial *mat = new aiMaterial ();
325- aiString name (pMat->material_english_name );
420+ // aiString name(pMat->material_english_name);
421+ aiString name (pMat->material_name );
422+ if (pMat->material_name .size () == 0 ) {
423+ name = pMat->material_english_name ;
424+ }
326425 mat->AddProperty (&name, AI_MATKEY_NAME);
327426
328427 aiColor3D diffuse (pMat->diffuse [0 ], pMat->diffuse [1 ], pMat->diffuse [2 ]);
0 commit comments