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/CCBundle3D.h"
|
||||||
|
#include "3d/CCObjLoader.h"
|
||||||
|
|
||||||
#include "base/ccMacros.h"
|
#include "base/ccMacros.h"
|
||||||
#include "platform/CCFileUtils.h"
|
#include "platform/CCFileUtils.h"
|
||||||
|
@ -214,6 +215,100 @@ bool Bundle3D::load(const std::string& path)
|
||||||
return ret;
|
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)
|
bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
|
||||||
{
|
{
|
||||||
meshdata->resetData();
|
meshdata->resetData();
|
||||||
|
|
|
@ -103,6 +103,9 @@ public:
|
||||||
//since 3.3, to support reskin
|
//since 3.3, to support reskin
|
||||||
virtual bool loadMaterials(MaterialDatas& materialdatas);
|
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:
|
protected:
|
||||||
|
|
||||||
bool loadJson(const std::string& path);
|
bool loadJson(const std::string& path);
|
||||||
|
|
|
@ -105,6 +105,20 @@ struct NodeDatas
|
||||||
{
|
{
|
||||||
std::vector<NodeData*> skeleton; //skeleton
|
std::vector<NodeData*> skeleton; //skeleton
|
||||||
std::vector<NodeData*> nodes; // nodes, CCNode, Sprite3D or part of Sprite3D
|
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*/
|
/**mesh data*/
|
||||||
|
|
|
@ -114,39 +114,32 @@ bool Sprite3D::loadFromObj(const std::string& path)
|
||||||
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path);
|
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path);
|
||||||
std::string key = fullPath + "#";
|
std::string key = fullPath + "#";
|
||||||
|
|
||||||
//.mtl file directory
|
MeshDatas meshdatas;
|
||||||
std::string dir = "";
|
MaterialDatas materialdatas;
|
||||||
auto last = fullPath.rfind("/");
|
NodeDatas nodeDatas;
|
||||||
if (last != -1)
|
bool ret = Bundle3D::loadObj(meshdatas, materialdatas, nodeDatas, fullPath);
|
||||||
dir = fullPath.substr(0, last + 1);
|
if (ret)
|
||||||
|
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
submeshIndices.push_back((*it).mesh.indices);
|
for( int i = 0 ; i < meshdatas.meshDatas.size() ; i++ )
|
||||||
|
{
|
||||||
texname = (*it).material.diffuse_texname;
|
MeshData* meshData= meshdatas.meshDatas[i];
|
||||||
if (!texname.empty())
|
if(meshData)
|
||||||
texname = dir + (*it).material.diffuse_texname;
|
{
|
||||||
matnames.push_back(texname);
|
Mesh* mesh = Mesh::create(*meshData);
|
||||||
|
_meshes.pushBack(mesh);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_mesh = Mesh::create(shapes.positions, shapes.normals, shapes.texcoords, submeshIndices);
|
for(int i = 0; i < nodeDatas.nodes.size(); i++ )
|
||||||
_mesh->retain();
|
{
|
||||||
if (_mesh == nullptr)
|
NodeData* nodeData= nodeDatas.nodes[i];
|
||||||
return false;
|
if(nodeData)
|
||||||
//add mesh to cache
|
{
|
||||||
MeshCache::getInstance()->addMesh(key, _mesh);
|
createNode(nodeData, this, materialdatas);
|
||||||
|
}
|
||||||
genMaterials(key, matnames);
|
}
|
||||||
|
}
|
||||||
|
// //add mesh to cache
|
||||||
|
// MeshCache::getInstance()->addMesh(key, _mesh);
|
||||||
|
|
||||||
genGLProgramState();
|
genGLProgramState();
|
||||||
|
|
||||||
|
@ -356,8 +349,11 @@ void Sprite3D::createNode(NodeData* nodedata, Node* root, const MaterialDatas& m
|
||||||
{
|
{
|
||||||
_subMeshStates.pushBack(subMeshState);
|
_subMeshStates.pushBack(subMeshState);
|
||||||
subMeshState->setSubMesh(getSubMesh(modelNodeData->subMeshId));
|
subMeshState->setSubMesh(getSubMesh(modelNodeData->subMeshId));
|
||||||
|
if (_skeleton && modelNodeData->bones.size())
|
||||||
|
{
|
||||||
auto skin = MeshSkin::create(_skeleton, modelNodeData->bones, modelNodeData->invBindPose);
|
auto skin = MeshSkin::create(_skeleton, modelNodeData->bones, modelNodeData->invBindPose);
|
||||||
subMeshState->setSkin(skin);
|
subMeshState->setSkin(skin);
|
||||||
|
}
|
||||||
|
|
||||||
if (modelNodeData->matrialId == "" && matrialdatas.materials.size())
|
if (modelNodeData->matrialId == "" && matrialdatas.materials.size())
|
||||||
{
|
{
|
||||||
|
@ -434,10 +430,10 @@ void Sprite3D::genMaterials(const std::string& keyprefix, const std::vector<std:
|
||||||
subMeshState->setTexture(tex);
|
subMeshState->setTexture(tex);
|
||||||
_subMeshStates.pushBack(subMeshState);
|
_subMeshStates.pushBack(subMeshState);
|
||||||
|
|
||||||
//add to cache
|
// //add to cache
|
||||||
sprintf(str, "submesh%d", index);
|
// sprintf(str, "submesh%d", index);
|
||||||
std::string submeshkey = keyprefix + std::string(str);
|
// std::string submeshkey = keyprefix + std::string(str);
|
||||||
Sprite3DMaterialCache::getInstance()->addSprite3DMaterial(submeshkey, tex);
|
// Sprite3DMaterialCache::getInstance()->addSprite3DMaterial(submeshkey, tex);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue