diff --git a/cocos/3d/CCBundle3D.cpp b/cocos/3d/CCBundle3D.cpp index b683e93e84..f8dbc9ff76 100644 --- a/cocos/3d/CCBundle3D.cpp +++ b/cocos/3d/CCBundle3D.cpp @@ -216,73 +216,24 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeD else mtlPath = fullPath.substr(0, fullPath.find_last_of("\\/") + 1).c_str(); - ObjLoader::shapes_t shapes; - auto ret = ObjLoader::LoadObj(shapes, fullPath.c_str(), mtlPath.c_str()); + std::vector shapes; + std::vector materials; + auto ret = tinyobj::LoadObj(shapes, materials, fullPath.c_str(), mtlPath.c_str()); if (ret.empty()) { //fill data - MeshData* meshdata = new (std::nothrow) 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(unsigned int 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); - + //convert material 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) - { + for (auto& material : materials) { NMaterialData materialdata; NTextureData tex; - tex.filename = it.material.diffuse_texname.empty() ? it.material.diffuse_texname : dir + it.material.diffuse_texname; + tex.filename = material.diffuse_texname.empty() ? material.diffuse_texname : dir + material.diffuse_texname; tex.type = NTextureData::Usage::Diffuse; tex.wrapS = GL_CLAMP_TO_EDGE; tex.wrapT = GL_CLAMP_TO_EDGE; @@ -290,19 +241,91 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeD sprintf(str, "%d", i++); materialdata.textures.push_back(tex); materialdata.id = str; + material.name = str; materialdatas.materials.push_back(materialdata); - - meshdata->subMeshIndices.push_back(it.mesh.indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), it.mesh.indices)); - meshdata->subMeshIds.push_back(str); - auto node = new (std::nothrow) NodeData(); - auto modelnode = new (std::nothrow) ModelData(); - modelnode->matrialId = str; - modelnode->subMeshId = str; - node->id = it.name; - node->modelNodeDatas.push_back(modelnode); - nodedatas.nodes.push_back(node); } + + //convert mesh + i = 0; + for (auto& shape : shapes) { + auto mesh = shape.mesh; + MeshData* meshdata = new (std::nothrow) MeshData(); + MeshVertexAttrib attrib; + attrib.size = 3; + attrib.type = GL_FLOAT; + + if (mesh.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 (mesh.normals.size()) + { + hasnormal = true; + attrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_NORMAL; + attrib.attribSizeBytes = attrib.size * sizeof(float);; + meshdata->attribs.push_back(attrib); + } + if (mesh.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 = mesh.positions.size() / 3; + for(unsigned int k = 0; k < vertexNum; k++) + { + meshdata->vertex.push_back(mesh.positions[k * 3]); + meshdata->vertex.push_back(mesh.positions[k * 3 + 1]); + meshdata->vertex.push_back(mesh.positions[k * 3 + 2]); + + if (hasnormal) + { + meshdata->vertex.push_back(mesh.normals[k * 3]); + meshdata->vertex.push_back(mesh.normals[k * 3 + 1]); + meshdata->vertex.push_back(mesh.normals[k * 3 + 2]); + } + + if (hastex) + { + meshdata->vertex.push_back(mesh.texcoords[k * 2]); + meshdata->vertex.push_back(mesh.texcoords[k * 2 + 1]); + } + } + + //split into submesh according to material + std::map > subMeshMap; + for (size_t k = 0; k < mesh.material_ids.size(); k++) { + int id = mesh.material_ids[k]; + size_t idx = k * 3; + subMeshMap[id].push_back(mesh.indices[idx]); + subMeshMap[id].push_back(mesh.indices[idx + 1]); + subMeshMap[id].push_back(mesh.indices[idx + 2]); + } + + auto node = new (std::nothrow) NodeData(); + node->id = shape.name; + for (auto& submesh : subMeshMap) { + meshdata->subMeshIndices.push_back(submesh.second); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), submesh.second)); + sprintf(str, "%d", i++); + meshdata->subMeshIds.push_back(str); + + auto modelnode = new (std::nothrow) ModelData(); + modelnode->matrialId = submesh.first == -1 ? "" : materials[submesh.first].name; + modelnode->subMeshId = str; + node->modelNodeDatas.push_back(modelnode); + } + nodedatas.nodes.push_back(node); + meshdatas.meshDatas.push_back(meshdata); + } + return true; } CCLOG("warning: load %s file error: %s", fullPath.c_str(), ret.c_str());