void Model::loadRecursive(MeshPart& part, bool invert, std::vector<float>& vertex_data, const aiScene* scene, const aiNode* node) { //update transform matrix. notice that we also transpose it aiMatrix4x4 m = node->mTransformation; for (int j=0; j<4; ++j) for (int i=0; i<4; ++i) part.transform[j][i] = m[i][j]; // draw all meshes assigned to this node for (unsigned int n=0; n < node->mNumMeshes; ++n) { const struct aiMesh* mesh = scene->mMeshes[node->mMeshes[n]]; //apply_material(scene->mMaterials[mesh->mMaterialIndex]); part.first = vertex_data.size()/6; part.count = mesh->mNumFaces*6; //Allocate data vertex_data.reserve(vertex_data.size() + part.count*6); //Add the vertices from file for (unsigned int t = 0; t < mesh->mNumFaces; ++t) { const struct aiFace* face = &mesh->mFaces[t]; if(face->mNumIndices != 3) THROW_EXCEPTION("Only triangle meshes are supported"); for(unsigned int i = 0; i < face->mNumIndices; i++) { int index = face->mIndices[i]; //get Vertexes vertex_data.push_back(mesh->mVertices[index].x); vertex_data.push_back(mesh->mVertices[index].y); vertex_data.push_back(mesh->mVertices[index].z); //get Normals if (mesh->HasNormals()){ vertex_data.push_back(mesh->mNormals[index].x); vertex_data.push_back(mesh->mNormals[index].y); vertex_data.push_back(mesh->mNormals[index].z); } } } } // load all children for (unsigned int n = 0; n < node->mNumChildren; ++n) { part.children.push_back(MeshPart()); loadRecursive(part.children.back(), invert, vertex_data, scene, node->mChildren[n]); } }
void Model::loadRecursive(MeshPart& part, bool invert, std::vector<unsigned int>& indices, std::vector<Vertex>& vertex_data, const aiScene* scene, const aiNode* node) { std::cout << "loading one part" << std::endl; //update transform matrix. notice that we also transpose it aiMatrix4x4 m = node->mTransformation; for (int j=0; j<4; ++j) for (int i=0; i<4; ++i) part.transform[j][i] = m[i][j]; // draw all meshes assigned to this node for (unsigned int n=0; n < node->mNumMeshes; ++n) { std::cout << "\tloading mesh part " << n << std::endl; const struct aiMesh* mesh = scene->mMeshes[node->mMeshes[n]]; //apply_material(scene->mMaterials[mesh->mMaterialIndex]); applyMateriale(scene->mMaterials[mesh->mMaterialIndex], part.materiale); part.first = indices.size(); part.count = mesh->mNumFaces * 3; //Allocate data indices.reserve(part.first + part.count); vertex_data.reserve(vertex_data.size() + mesh->mNumVertices); for (unsigned int t = 0; t < mesh->mNumFaces; ++t) { const struct aiFace* face = &mesh->mFaces[t]; if(face->mNumIndices != 3) THROW_EXCEPTION("Only triangle meshes are supported"); for(unsigned int i = 0; i < face->mNumIndices; i++) { int index = face->mIndices[i]; indices.push_back(vertex_data.size() + index); } } for(unsigned int t = 0; t < mesh->mNumVertices; ++t){ Vertex v; unsigned int index = t; // set vertex position v.position = glm::vec3(mesh->mVertices[index].x, mesh->mVertices[index].y, mesh->mVertices[index].z); // compute bounding box max_dim.x = v.position.x < max_dim.x ? max_dim.x : v.position.x; max_dim.y = v.position.y < max_dim.y ? max_dim.y : v.position.y; max_dim.z = v.position.z < max_dim.z ? max_dim.z : v.position.z; min_dim.x = v.position.x > min_dim.x ? min_dim.x : v.position.x; min_dim.y = v.position.y > min_dim.y ? min_dim.y : v.position.y; min_dim.z = v.position.z > min_dim.z ? min_dim.z : v.position.z; // get normal if(mesh->HasNormals()) v.normal = glm::vec3(mesh->mNormals[index].x, mesh->mNormals[index].y, mesh->mNormals[index].z); // get uv coord if(mesh->HasTextureCoords(0)) v.texCoord = glm::vec2(mesh->mTextureCoords[0][index].x, mesh->mTextureCoords[0][index].y); vertex_data.push_back(v); } } // load all children for (unsigned int n = 0; n < node->mNumChildren; ++n) { part.children.push_back(MeshPart()); loadRecursive(part.children.back(), invert, indices, vertex_data, scene, node->mChildren[n]); } }
shared_ptr<Model> MakeBoxModel(Renderer* renderer, const BoxModelDesc& desc) { auto model = make_shared<Model>(); auto vbuffer = make_shared<VertexBuffer>(); shared_ptr<BaseVertexBufferData> vdata; if (desc.genNormals && desc.genColors) { vdata.reset(new VertexBufferData<VertexPositionNormalColor>( { // -X face { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT3(desc.colors[1]) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT3(desc.colors[0]) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT3(desc.colors[7]) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT3(desc.colors[6]) }, // +X face { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT3(desc.colors[5]) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT3(desc.colors[4]) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT3(desc.colors[3]) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT3(desc.colors[2]) }, // -Y face { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT3(desc.colors[1]) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT3(desc.colors[7]) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT3(desc.colors[3]) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT3(desc.colors[5]) }, // +Y face { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT3(desc.colors[2]) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT3(desc.colors[4]) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT3(desc.colors[0]) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT3(desc.colors[6]) }, // -Z face { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT3(desc.colors[3]) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT3(desc.colors[2]) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT3(desc.colors[1]) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT3(desc.colors[0]) }, // +Z face { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT3(desc.colors[7]) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT3(desc.colors[6]) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT3(desc.colors[5]) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT3(desc.colors[4]) } } )); vbuffer->Create(vdata, Usage::Immutable, "Box vertex buffer with normals and colors"); } else if (desc.genNormals) { vdata.reset(new VertexBufferData<VertexPositionNormal>( { // -X face { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(-1.0f, 0.0f, 0.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(-1.0f, 0.0f, 0.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(-1.0f, 0.0f, 0.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(-1.0f, 0.0f, 0.0f) }, // +X face { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(1.0f, 0.0f, 0.0f) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(1.0f, 0.0f, 0.0f) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(1.0f, 0.0f, 0.0f) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(1.0f, 0.0f, 0.0f) }, // -Y face { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, -1.0f, 0.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, -1.0f, 0.0f) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, -1.0f, 0.0f) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, -1.0f, 0.0f) }, // +Y face { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 1.0f, 0.0f) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 1.0f, 0.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 1.0f, 0.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 1.0f, 0.0f) }, // -Z face { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, -1.0f) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, -1.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, -1.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, -1.0f) }, // +Z face { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, 1.0f) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, 1.0f) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, 1.0f) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(0.0f, 0.0f, 1.0f) } } )); vbuffer->Create(vdata, Usage::Immutable, "Box vertex buffer with normals"); } else if (desc.genColors) { vdata.reset(new VertexBufferData<VertexPositionColor>( { { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(desc.colors[0]) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(desc.colors[1]) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(desc.colors[2]) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ), XMFLOAT3(desc.colors[3]) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(desc.colors[4]) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(desc.colors[5]) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(desc.colors[6]) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ), XMFLOAT3(desc.colors[7]) } } )); vbuffer->Create(vdata, Usage::Immutable, "Box vertex buffer with colors"); } else { vdata.reset(new VertexBufferData<VertexPosition>( { { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, -0.5f * desc.sizeZ) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, -0.5f * desc.sizeZ) }, { XMFLOAT3(0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ) }, { XMFLOAT3(0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ) }, { XMFLOAT3(-0.5f * desc.sizeX, 0.5f * desc.sizeY, 0.5f * desc.sizeZ) }, { XMFLOAT3(-0.5f * desc.sizeX, -0.5f * desc.sizeY, 0.5f * desc.sizeZ) } } )); vbuffer->Create(vdata, Usage::Immutable, "Box vertex buffer"); } // Create the mesh and mesh parts Mesh mesh; vector<MeshPart> meshParts; if (desc.genNormals) { meshParts.reserve(6); // -X face { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 0, 1, 2, 3 })); ibuffer->Create(idata, Usage::Immutable, "-X face"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 4, 0, 0); meshParts.emplace_back(meshPart); } // +X face { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 4, 5, 6, 7 })); ibuffer->Create(idata, Usage::Immutable, "+X face"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 4, 0, 0); meshParts.emplace_back(meshPart); } // -Y face { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 8, 9, 10, 11 })); ibuffer->Create(idata, Usage::Immutable, "-Y face"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 4, 0, 0); meshParts.emplace_back(meshPart); } // +Y face { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 12, 13, 14, 15 })); ibuffer->Create(idata, Usage::Immutable, "+Y face"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 4, 0, 0); meshParts.emplace_back(meshPart); } // -Z face { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 16, 17, 18, 19 })); ibuffer->Create(idata, Usage::Immutable, "-Z face"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 4, 0, 0); meshParts.emplace_back(meshPart); } // +Z face { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 20, 21, 22, 23 })); ibuffer->Create(idata, Usage::Immutable, "+Z face"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 4, 0, 0); meshParts.emplace_back(meshPart); } } else { meshParts.reserve(3); // Body { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1 })); ibuffer->Create(idata, Usage::Immutable, "Body"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 10, 0, 0); meshParts.emplace_back(meshPart); } // Top { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 6, 0, 4, 2 })); ibuffer->Create(idata, Usage::Immutable, "Top"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 4, 0, 0); meshParts.emplace_back(meshPart); } // Bottom { auto ibuffer = make_shared<IndexBuffer>(); shared_ptr<BaseIndexBufferData> idata; idata.reset(new IndexBufferData16({ 5, 3, 7, 1 })); ibuffer->Create(idata, Usage::Immutable, "Bottom"); auto meshPart = MeshPart(vbuffer, ibuffer, PrimitiveTopology::TriangleStrip, 4, 0, 0); meshParts.emplace_back(meshPart); } } mesh.SetMeshParts(meshParts); model->SetSingleMesh(mesh); return model; }