mirror of https://github.com/axmolengine/axmol.git
obj loader work
This commit is contained in:
parent
05b13b8c38
commit
1e961e00b7
|
@ -23,6 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "3d/CCBundle3D.h"
|
||||
#include "3d/CCObjLoader.h"
|
||||
|
||||
#include "base/ccMacros.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
|
@ -213,6 +214,100 @@ bool Bundle3D::load(const std::string& path)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Bundle3D::loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeDatas& nodedatas, const std::string& fullPath, const char* mtl_basepath)
|
||||
{
|
||||
meshdatas.resetData();
|
||||
materialdatas.resetData();
|
||||
nodedatas.resetData();
|
||||
|
||||
ObjLoader::shapes_t shapes;
|
||||
auto ret = ObjLoader::LoadObj(shapes, fullPath.c_str(), mtl_basepath);
|
||||
if (ret.empty())
|
||||
{
|
||||
//fill data
|
||||
MeshData* meshdata = new MeshData();
|
||||
MeshVertexAttrib attrib;
|
||||
attrib.size = 3;
|
||||
attrib.type = GL_FLOAT;
|
||||
if (shapes.positions.size())
|
||||
{
|
||||
attrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_POSITION;
|
||||
attrib.attribSizeBytes = attrib.size * sizeof(float);
|
||||
meshdata->attribs.push_back(attrib);
|
||||
|
||||
}
|
||||
bool hasnormal = false, hastex = false;
|
||||
if (shapes.normals.size())
|
||||
{
|
||||
hasnormal = true;
|
||||
attrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_NORMAL;
|
||||
attrib.attribSizeBytes = attrib.size * sizeof(float);;
|
||||
meshdata->attribs.push_back(attrib);
|
||||
}
|
||||
if (shapes.texcoords.size())
|
||||
{
|
||||
hastex = true;
|
||||
attrib.size = 2;
|
||||
attrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_TEX_COORD;
|
||||
attrib.attribSizeBytes = attrib.size * sizeof(float);
|
||||
meshdata->attribs.push_back(attrib);
|
||||
}
|
||||
auto vertexNum = shapes.positions.size() / 3;
|
||||
for(auto i = 0; i < vertexNum; i++)
|
||||
{
|
||||
meshdata->vertex.push_back(shapes.positions[i * 3]);
|
||||
meshdata->vertex.push_back(shapes.positions[i * 3 + 1]);
|
||||
meshdata->vertex.push_back(shapes.positions[i * 3 + 2]);
|
||||
|
||||
if (hasnormal)
|
||||
{
|
||||
meshdata->vertex.push_back(shapes.normals[i * 3]);
|
||||
meshdata->vertex.push_back(shapes.normals[i * 3 + 1]);
|
||||
meshdata->vertex.push_back(shapes.normals[i * 3 + 2]);
|
||||
}
|
||||
|
||||
if (hastex)
|
||||
{
|
||||
meshdata->vertex.push_back(shapes.texcoords[i * 2]);
|
||||
meshdata->vertex.push_back(shapes.texcoords[i * 2 + 1]);
|
||||
}
|
||||
}
|
||||
meshdatas.meshDatas.push_back(meshdata);
|
||||
|
||||
NMaterialData materialdata;
|
||||
int i = 0;
|
||||
char str[20];
|
||||
std::string dir = "";
|
||||
auto last = fullPath.rfind("/");
|
||||
if (last != -1)
|
||||
dir = fullPath.substr(0, last + 1);
|
||||
|
||||
for (const auto& it : shapes.shapes)
|
||||
{
|
||||
NTextureData tex;
|
||||
tex.filename = dir + it.material.diffuse_texname;
|
||||
tex.type = NTextureData::Usage::Diffuse;
|
||||
|
||||
sprintf(str, "%d", i++);
|
||||
materialdata.textures.push_back(tex);
|
||||
materialdata.id = str;
|
||||
materialdatas.materials.push_back(materialdata);
|
||||
|
||||
meshdata->subMeshIndices.push_back(it.mesh.indices);
|
||||
meshdata->subMeshIds.push_back(str);
|
||||
|
||||
auto modelnode = new ModelNodeData();
|
||||
modelnode->matrialId = str;
|
||||
modelnode->subMeshId = str;
|
||||
modelnode->id = it.name;
|
||||
nodedatas.nodes.push_back(modelnode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
CCLOG("load %s file error: %s", fullPath.c_str(), ret.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
|
||||
{
|
||||
|
|
|
@ -102,6 +102,9 @@ public:
|
|||
virtual bool loadNodes(NodeDatas& nodedatas);
|
||||
//since 3.3, to support reskin
|
||||
virtual bool loadMaterials(MaterialDatas& materialdatas);
|
||||
|
||||
//load .obj file
|
||||
static bool loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeDatas& nodedatas, const std::string& fullPath, const char* mtl_basepath = nullptr);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -105,6 +105,20 @@ struct NodeDatas
|
|||
{
|
||||
std::vector<NodeData*> skeleton; //skeleton
|
||||
std::vector<NodeData*> nodes; // nodes, CCNode, Sprite3D or part of Sprite3D
|
||||
|
||||
void resetData()
|
||||
{
|
||||
for(auto& it : skeleton)
|
||||
{
|
||||
delete it;
|
||||
}
|
||||
skeleton.clear();
|
||||
for(auto& it : nodes)
|
||||
{
|
||||
delete it;
|
||||
}
|
||||
nodes.clear();
|
||||
}
|
||||
};
|
||||
|
||||
/**mesh data*/
|
||||
|
|
|
@ -114,40 +114,33 @@ bool Sprite3D::loadFromObj(const std::string& path)
|
|||
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path);
|
||||
std::string key = fullPath + "#";
|
||||
|
||||
//.mtl file directory
|
||||
std::string dir = "";
|
||||
auto last = fullPath.rfind("/");
|
||||
if (last != -1)
|
||||
dir = fullPath.substr(0, last + 1);
|
||||
|
||||
ObjLoader::shapes_t shapes;
|
||||
std::string errstr = ObjLoader::LoadObj(shapes, fullPath.c_str(), dir.c_str());
|
||||
if (!errstr.empty())
|
||||
return false;
|
||||
|
||||
//convert to mesh and material
|
||||
std::vector<std::vector<unsigned short> > submeshIndices;
|
||||
std::vector<std::string> matnames;
|
||||
std::string texname;
|
||||
for (auto it = shapes.shapes.begin(); it != shapes.shapes.end(); it++)
|
||||
MeshDatas meshdatas;
|
||||
MaterialDatas materialdatas;
|
||||
NodeDatas nodeDatas;
|
||||
bool ret = Bundle3D::loadObj(meshdatas, materialdatas, nodeDatas, fullPath);
|
||||
if (ret)
|
||||
{
|
||||
submeshIndices.push_back((*it).mesh.indices);
|
||||
|
||||
texname = (*it).material.diffuse_texname;
|
||||
if (!texname.empty())
|
||||
texname = dir + (*it).material.diffuse_texname;
|
||||
matnames.push_back(texname);
|
||||
for( int i = 0 ; i < meshdatas.meshDatas.size() ; i++ )
|
||||
{
|
||||
MeshData* meshData= meshdatas.meshDatas[i];
|
||||
if(meshData)
|
||||
{
|
||||
Mesh* mesh = Mesh::create(*meshData);
|
||||
_meshes.pushBack(mesh);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < nodeDatas.nodes.size(); i++ )
|
||||
{
|
||||
NodeData* nodeData= nodeDatas.nodes[i];
|
||||
if(nodeData)
|
||||
{
|
||||
createNode(nodeData, this, materialdatas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_mesh = Mesh::create(shapes.positions, shapes.normals, shapes.texcoords, submeshIndices);
|
||||
_mesh->retain();
|
||||
if (_mesh == nullptr)
|
||||
return false;
|
||||
//add mesh to cache
|
||||
MeshCache::getInstance()->addMesh(key, _mesh);
|
||||
// //add mesh to cache
|
||||
// MeshCache::getInstance()->addMesh(key, _mesh);
|
||||
|
||||
genMaterials(key, matnames);
|
||||
|
||||
genGLProgramState();
|
||||
|
||||
return true;
|
||||
|
@ -356,8 +349,11 @@ void Sprite3D::createNode(NodeData* nodedata, Node* root, const MaterialDatas& m
|
|||
{
|
||||
_subMeshStates.pushBack(subMeshState);
|
||||
subMeshState->setSubMesh(getSubMesh(modelNodeData->subMeshId));
|
||||
auto skin = MeshSkin::create(_skeleton, modelNodeData->bones, modelNodeData->invBindPose);
|
||||
subMeshState->setSkin(skin);
|
||||
if (_skeleton && modelNodeData->bones.size())
|
||||
{
|
||||
auto skin = MeshSkin::create(_skeleton, modelNodeData->bones, modelNodeData->invBindPose);
|
||||
subMeshState->setSkin(skin);
|
||||
}
|
||||
|
||||
if (modelNodeData->matrialId == "" && matrialdatas.materials.size())
|
||||
{
|
||||
|
@ -434,10 +430,10 @@ void Sprite3D::genMaterials(const std::string& keyprefix, const std::vector<std:
|
|||
subMeshState->setTexture(tex);
|
||||
_subMeshStates.pushBack(subMeshState);
|
||||
|
||||
//add to cache
|
||||
sprintf(str, "submesh%d", index);
|
||||
std::string submeshkey = keyprefix + std::string(str);
|
||||
Sprite3DMaterialCache::getInstance()->addSprite3DMaterial(submeshkey, tex);
|
||||
// //add to cache
|
||||
// sprintf(str, "submesh%d", index);
|
||||
// std::string submeshkey = keyprefix + std::string(str);
|
||||
// Sprite3DMaterialCache::getInstance()->addSprite3DMaterial(submeshkey, tex);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue