use SkeletonMeshBuilder to show bone positions.

pull/1212/head
aoowweenn 2017-03-10 17:15:01 +08:00
parent ba357e74d2
commit 2d3dd1d40f
1 changed files with 243 additions and 187 deletions

View File

@ -41,23 +41,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER #ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
#include "DefaultIOSystem.h"
#include "MMDImporter.h" #include "MMDImporter.h"
#include "MMDPmxParser.h" #include "DefaultIOSystem.h"
#include "MMDPmdParser.h" #include "MMDPmdParser.h"
#include "MMDPmxParser.h"
#include "MMDVmdParser.h" #include "MMDVmdParser.h"
#include "SkeletonMeshBuilder.h"
//#include "IOStreamBuffer.h" //#include "IOStreamBuffer.h"
#include "ConvertToLHProcess.h" #include "ConvertToLHProcess.h"
#include <memory>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <assimp/ai_assert.h>
#include <assimp/scene.h>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include <memory>
static const aiImporterDesc desc = { static const aiImporterDesc desc = {"MMD Importer",
"MMD Importer",
"", "",
"", "",
"surfaces supported?", "surfaces supported?",
@ -66,8 +66,7 @@ static const aiImporterDesc desc = {
0, 0,
0, 0,
0, 0,
"pmx" "pmx"};
};
namespace Assimp { namespace Assimp {
@ -75,63 +74,58 @@ using namespace std;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Default constructor // Default constructor
MMDImporter::MMDImporter() : MMDImporter::MMDImporter()
m_Buffer(), : m_Buffer(),
//m_pRootObject( NULL ), // m_pRootObject( NULL ),
m_strAbsPath( "" ) m_strAbsPath("") {
{
DefaultIOSystem io; DefaultIOSystem io;
m_strAbsPath = io.getOsSeparator(); m_strAbsPath = io.getOsSeparator();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
MMDImporter::~MMDImporter() MMDImporter::~MMDImporter() {
{ // delete m_pRootObject;
//delete m_pRootObject; // m_pRootObject = NULL;
//m_pRootObject = NULL;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if file is an pmx file. // Returns true, if file is an pmx file.
bool MMDImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
{ bool checkSig) const {
if(!checkSig) //Check File Extension if (!checkSig) // Check File Extension
{ {
return SimpleExtensionCheck(pFile,"pmx"); return SimpleExtensionCheck(pFile, "pmx");
} } else // Check file Header
else //Check file Header
{ {
static const char *pTokens[] = { "PMX " }; static const char *pTokens[] = {"PMX "};
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 1 ); return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens,
1);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* MMDImporter::GetInfo () const const aiImporterDesc *MMDImporter::GetInfo() const { return &desc; }
{
return &desc;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// MMD import implementation // MMD import implementation
void MMDImporter::InternReadFile( const std::string &file, aiScene* pScene, IOSystem* pIOHandler) void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
{ IOSystem *pIOHandler) {
// Read file by istream // Read file by istream
std::filebuf fb; std::filebuf fb;
if( !fb.open(file, std::ios::in | std::ios::binary ) ) { if (!fb.open(file, std::ios::in | std::ios::binary)) {
throw DeadlyImportError( "Failed to open file " + file + "." ); throw DeadlyImportError("Failed to open file " + file + ".");
} }
std::istream fileStream( &fb ); std::istream fileStream(&fb);
// Get the file-size and validate it, throwing an exception when fails // Get the file-size and validate it, throwing an exception when fails
fileStream.seekg(0, fileStream.end); fileStream.seekg(0, fileStream.end);
size_t fileSize = fileStream.tellg(); size_t fileSize = fileStream.tellg();
fileStream.seekg(0, fileStream.beg); fileStream.seekg(0, fileStream.beg);
if( fileSize < sizeof(pmx::PmxModel) ) { if (fileSize < sizeof(pmx::PmxModel)) {
throw DeadlyImportError( file + " is too small." ); throw DeadlyImportError(file + " is too small.");
} }
pmx::PmxModel model; pmx::PmxModel model;
@ -141,17 +135,16 @@ void MMDImporter::InternReadFile( const std::string &file, aiScene* pScene, IOSy
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MMDImporter::CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene) void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
{ aiScene *pScene) {
if( pModel == NULL ) { if (pModel == NULL) {
return; return;
} }
aiNode *pNode = new aiNode; aiNode *pNode = new aiNode;
if ( !pModel->model_name.empty() ) { if (!pModel->model_name.empty()) {
pNode->mName.Set(pModel->model_name); pNode->mName.Set(pModel->model_name);
} } else {
else {
ai_assert(false); ai_assert(false);
} }
@ -159,22 +152,21 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pSc
std::cout << pScene->mRootNode->mName.C_Str() << std::endl; std::cout << pScene->mRootNode->mName.C_Str() << std::endl;
std::cout << pModel->index_count << std::endl; std::cout << pModel->index_count << std::endl;
/*
pNode = new aiNode; pNode = new aiNode;
pScene->mRootNode->addChildren(1, &pNode); pScene->mRootNode->addChildren(1, &pNode);
pScene->mRootNode->mNumChildren = 1;
pNode->mParent = pScene->mRootNode;
pNode->mName.Set(string(pModel->model_name) + string("_mesh")); pNode->mName.Set(string(pModel->model_name) + string("_mesh"));
// split mesh by materials // split mesh by materials
pNode->mNumMeshes = pModel->material_count; pNode->mNumMeshes = pModel->material_count;
pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
for( unsigned int index = 0; index < pNode->mNumMeshes; index++ ) { for (unsigned int index = 0; index < pNode->mNumMeshes; index++) {
pNode->mMeshes[index] = index; pNode->mMeshes[index] = index;
} }
pScene->mNumMeshes = pNode->mNumMeshes; pScene->mNumMeshes = pNode->mNumMeshes;
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
for( unsigned int i = 0, indexStart = 0; i < pScene->mNumMeshes; i++ ) { for (unsigned int i = 0, indexStart = 0; i < pScene->mNumMeshes; i++) {
const int indexCount = pModel->materials[i].index_count; const int indexCount = pModel->materials[i].index_count;
std::cout << pModel->materials[i].material_name << std::endl; std::cout << pModel->materials[i].material_name << std::endl;
@ -185,6 +177,67 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pSc
pScene->mMeshes[i]->mMaterialIndex = i; pScene->mMeshes[i]->mMaterialIndex = i;
indexStart += indexCount; indexStart += indexCount;
} }
*/
// create bones
aiBone *pBone = new aiBone[pModel->bone_count];
for (auto i = 0; i < pModel->bone_count; i++) {
pBone[i].mName = pModel->bones[i].bone_name;
}
// create node hierarchy for bone position
auto bone_root_index = 0; // Default root: Bone 0 "Body" / "全ての親"
aiNode **ppNode = new aiNode *[pModel->bone_count];
for (auto i = 0; i < pModel->bone_count; i++) {
ppNode[i] = new aiNode(pModel->bones[i].bone_name);
}
for (auto i = 0; i < pModel->bone_count; i++) {
const pmx::PmxBone &bone = pModel->bones[i];
std::cout << "Bone " << i << ":" << std::endl;
std::cout << bone.bone_name << std::endl;
std::cout << bone.bone_english_name << std::endl;
std::cout << "position " << bone.position[0] << " " << bone.position[1]
<< " " << bone.position[2] << std::endl;
std::cout << "parent_index " << bone.parent_index << std::endl;
std::cout << "level " << bone.level << std::endl;
std::cout << "bone_flag " << bone.bone_flag << std::endl;
std::cout << "offset " << bone.offset[0] << " " << bone.offset[1] << " "
<< bone.offset[2] << std::endl;
std::cout << "target_index" << bone.target_index << std::endl;
if (bone.parent_index < 0) {
pScene->mRootNode->addChildren(1, ppNode + i);
bone_root_index = i;
} else {
ppNode[bone.parent_index]->addChildren(1, ppNode + i);
aiVector3D v3 = aiVector3D(
bone.position[0] - pModel->bones[bone.parent_index].position[0],
bone.position[1] - pModel->bones[bone.parent_index].position[1],
bone.position[2] - pModel->bones[bone.parent_index].position[2]);
aiMatrix4x4::Translation(v3, ppNode[i]->mTransformation);
std::cout << ppNode[i]->mTransformation.a1 << ' '
<< ppNode[i]->mTransformation.a2 << ' '
<< ppNode[i]->mTransformation.a3 << ' '
<< ppNode[i]->mTransformation.a4 << ' '
<< ppNode[i]->mTransformation.b1 << ' '
<< ppNode[i]->mTransformation.b2 << ' '
<< ppNode[i]->mTransformation.b3 << ' '
<< ppNode[i]->mTransformation.b4 << ' '
<< ppNode[i]->mTransformation.c1 << ' '
<< ppNode[i]->mTransformation.c2 << ' '
<< ppNode[i]->mTransformation.c3 << ' '
<< ppNode[i]->mTransformation.c4 << ' '
<< ppNode[i]->mTransformation.d1 << ' '
<< ppNode[i]->mTransformation.d2 << ' '
<< ppNode[i]->mTransformation.d3 << ' '
<< ppNode[i]->mTransformation.d4 << ' ' << std::endl;
}
}
// use SkeletonMeshBuilder to generate bone vertices
SkeletonMeshBuilder dummyMeshbuild(pScene, ppNode[bone_root_index]);
// create textures, may be dummy? // create textures, may be dummy?
/* /*
@ -209,10 +262,11 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pSc
} }
*/ */
/*
// create materials // create materials
pScene->mNumMaterials = pModel->material_count; pScene->mNumMaterials = pModel->material_count;
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for( unsigned int i = 0; i < pScene->mNumMaterials; i++ ) { for (unsigned int i = 0; i < pScene->mNumMaterials; i++) {
pScene->mMaterials[i] = CreateMaterial(&pModel->materials[i], pModel); pScene->mMaterials[i] = CreateMaterial(&pModel->materials[i], pModel);
} }
@ -225,20 +279,20 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pSc
FlipWindingOrderProcess windingFlipper; FlipWindingOrderProcess windingFlipper;
windingFlipper.Execute(pScene); windingFlipper.Execute(pScene);
*/
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMesh* MMDImporter::CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount) aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
{ const int indexStart, const int indexCount) {
aiMesh *pMesh = new aiMesh; aiMesh *pMesh = new aiMesh;
pMesh->mNumVertices = indexCount; pMesh->mNumVertices = indexCount;
pMesh->mNumFaces = indexCount / 3; pMesh->mNumFaces = indexCount / 3;
pMesh->mFaces = new aiFace[ pMesh->mNumFaces ]; pMesh->mFaces = new aiFace[pMesh->mNumFaces];
for( unsigned int index = 0; index < pMesh->mNumFaces; index++ ) { for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
const int numIndices = 3; // trianglular face const int numIndices = 3; // trianglular face
pMesh->mFaces[index].mNumIndices = numIndices; pMesh->mFaces[index].mNumIndices = numIndices;
unsigned int *indices = new unsigned int[numIndices]; unsigned int *indices = new unsigned int[numIndices];
@ -248,26 +302,27 @@ aiMesh* MMDImporter::CreateMesh(const pmx::PmxModel* pModel, const int indexStar
pMesh->mFaces[index].mIndices = indices; pMesh->mFaces[index].mIndices = indices;
} }
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
pMesh->mTextureCoords[0] = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
pMesh->mNumUVComponents[0] = 2; pMesh->mNumUVComponents[0] = 2;
// additional UVs // additional UVs
for( int i = 1; i <= pModel->setting.uv; i++ ) { for (int i = 1; i <= pModel->setting.uv; i++) {
pMesh->mTextureCoords[i] = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mTextureCoords[i] = new aiVector3D[pMesh->mNumVertices];
pMesh->mNumUVComponents[i] = 4; pMesh->mNumUVComponents[i] = 4;
} }
for( int index = 0; index < indexCount; index++ ) { for (int index = 0; index < indexCount; index++) {
const pmx::PmxVertex *v = &pModel->vertices[pModel->indices[indexStart + index]]; const pmx::PmxVertex *v =
const float* position = v->position; &pModel->vertices[pModel->indices[indexStart + index]];
const float *position = v->position;
pMesh->mVertices[index].Set(position[0], position[1], position[2]); pMesh->mVertices[index].Set(position[0], position[1], position[2]);
const float* normal = v->normal; const float *normal = v->normal;
pMesh->mNormals[index].Set(normal[0], normal[1], normal[2]); pMesh->mNormals[index].Set(normal[0], normal[1], normal[2]);
pMesh->mTextureCoords[0][index].x = v->uv[0]; pMesh->mTextureCoords[0][index].x = v->uv[0];
pMesh->mTextureCoords[0][index].y = v->uv[1]; pMesh->mTextureCoords[0][index].y = v->uv[1];
for( int i = 1; i <= pModel->setting.uv; i++ ) { for (int i = 1; i <= pModel->setting.uv; i++) {
// TODO: wrong here? use quaternion transform? // TODO: wrong here? use quaternion transform?
pMesh->mTextureCoords[i][index].x = v->uva[i][0]; pMesh->mTextureCoords[i][index].x = v->uva[i][0];
pMesh->mTextureCoords[i][index].y = v->uva[i][1]; pMesh->mTextureCoords[i][index].y = v->uva[i][1];
@ -278,8 +333,8 @@ aiMesh* MMDImporter::CreateMesh(const pmx::PmxModel* pModel, const int indexStar
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMaterial* MMDImporter::CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel) aiMaterial *MMDImporter::CreateMaterial(const pmx::PmxMaterial *pMat,
{ const pmx::PmxModel *pModel) {
aiMaterial *mat = new aiMaterial(); aiMaterial *mat = new aiMaterial();
aiString name(pMat->material_english_name); aiString name(pMat->material_english_name);
mat->AddProperty(&name, AI_MATKEY_NAME); mat->AddProperty(&name, AI_MATKEY_NAME);
@ -299,7 +354,8 @@ aiMaterial* MMDImporter::CreateMaterial(const pmx::PmxMaterial* pMat, const pmx:
aiString texture_path(pModel->textures[pMat->diffuse_texture_index]); aiString texture_path(pModel->textures[pMat->diffuse_texture_index]);
mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
int mapping_uvwsrc = 0; int mapping_uvwsrc = 0;
mat->AddProperty(&mapping_uvwsrc, 1, AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0)); mat->AddProperty(&mapping_uvwsrc, 1,
AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0));
return mat; return mat;
} }