Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Object* LoadScene(fs::path path, float scale) {
- mLoadProgress = 0;
- Texture* brdfTexture = mScene->AssetManager()->LoadTexture("Assets/BrdfLut.png", false);
- Texture* whiteTexture = mScene->AssetManager()->LoadTexture("Assets/white.png");
- Texture* bumpTexture = mScene->AssetManager()->LoadTexture("Assets/bump.png", false);
- unordered_map<uint32_t, shared_ptr<Mesh>> meshes;
- unordered_map<uint32_t, shared_ptr<Material>> materials;
- const aiScene* aiscene = aiImportFile(path.string().c_str(), aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_FlipUVs | aiProcess_MakeLeftHanded);
- if (!aiscene) {
- cerr << "Failed to open " << path.string() << ": " << aiGetErrorString() << endl;
- return nullptr;
- }
- uint32_t meshCount = 0;
- queue<aiNode*> aiNodes;
- aiNodes.push(aiscene->mRootNode);
- while (!aiNodes.empty()){
- aiNode* node = aiNodes.front();
- aiNodes.pop();
- meshCount += node->mNumMeshes;
- for (uint32_t i = 0; i < node->mNumChildren; i++)
- aiNodes.push(node->mChildren[i]);
- }
- queue<pair<aiNode*, Object*>> nodes;
- nodes.push(make_pair(aiscene->mRootNode, nullptr));
- Object* root = nullptr;
- uint32_t meshNum = 0;
- uint32_t renderQueueOffset = 0;
- while(!nodes.empty()) {
- pair<aiNode*, Object*> nodepair = nodes.front();
- nodes.pop();
- aiNode* node = nodepair.first;
- aiVector3D s;
- aiQuaternion r;
- aiVector3D t;
- node->mTransformation.Decompose(s, r, t);
- t *= scale;
- shared_ptr<Object> nodeobj = make_shared<Object>(node->mName.C_Str());
- nodepair.second->AddChild(nodeobj.get());
- nodeobj->LocalPosition(t.x, t.y, t.z);
- nodeobj->LocalRotation(quaternion(r.x, r.y, r.z, r.w));
- nodeobj->LocalScale(s.x, s.y, s.z);
- mLoadedObjects.push_back(nodeobj);
- if (nodepair.first == aiscene->mRootNode)
- root = nodeobj.get();
- for (uint32_t i = 0; i < node->mNumMeshes; i++) {
- aiMesh* aimesh = aiscene->mMeshes[node->mMeshes[i]];
- aiMaterial* aimat = aiscene->mMaterials[aimesh->mMaterialIndex];
- mLoadProgress = (float)meshNum / (float)meshCount;
- if ((aimesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) == 0) continue;
- shared_ptr<Material>& material = materials[aimesh->mMaterialIndex];
- if (!material) {
- VkCullModeFlags cullMode = VK_CULL_MODE_FLAG_BITS_MAX_ENUM;
- BlendMode blendMode = BLEND_MODE_MAX_ENUM;
- bool twoSided = false;
- aiColor3D emissionFac;
- aiColor4D color;
- aiString matname, diffuse, normal, metalroughness, emission, occlusion, specgloss;
- aiString alphaMode;
- float metallic, roughness;
- aimat->Get(AI_MATKEY_NAME, matname);
- if (aimat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR, color) != aiReturn::aiReturn_SUCCESS)
- color.r = color.g = color.b = color.a = 1;
- if (aimat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR, metallic) != aiReturn::aiReturn_SUCCESS) metallic = 0.f;
- if (aimat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR, roughness) != aiReturn::aiReturn_SUCCESS) roughness = .5f;
- if (aimat->Get(AI_MATKEY_TWOSIDED, twoSided) == aiReturn::aiReturn_SUCCESS && twoSided) cullMode = VK_CULL_MODE_NONE;
- if (aimat->Get(AI_MATKEY_COLOR_EMISSIVE, emissionFac) != aiReturn::aiReturn_SUCCESS) emissionFac.r = emissionFac.g = emissionFac.b = 0;
- if (aimat->Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode) == aiReturn::aiReturn_SUCCESS && strcmp(alphaMode.C_Str(), "BLEND") == 0) blendMode = Alpha;
- aimat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS, specgloss);
- aimat->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE, &diffuse);
- aimat->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &metalroughness);
- aimat->GetTexture(aiTextureType_LIGHTMAP, 0, &occlusion);
- aimat->GetTexture(aiTextureType_NORMALS, 0, &normal);
- aimat->GetTexture(aiTextureType_EMISSIVE, 0, &emission);
- material = make_shared<Material>(matname.C_Str(), mPBRShader);
- material->CullMode(cullMode);
- material->BlendMode(blendMode);
- material->SetParameter("BrdfTexture", brdfTexture);
- material->SetParameter("Color", float4(color.r, color.g, color.b, color.a));
- material->SetParameter("Metallic", metallic);
- material->SetParameter("Roughness", roughness);
- material->SetParameter("EnvironmentTexture", mEnvironmentTexture);
- material->SetParameter("EnvironmentStrength", mEnvironmentStrength);
- if (twoSided) material->EnableKeyword("TWO_SIDED");
- if (diffuse != aiString("") && diffuse.C_Str()[0] != '*') {
- if (path.has_parent_path())
- diffuse = path.parent_path().string() + "/" + diffuse.C_Str();
- material->EnableKeyword("COLOR_MAP");
- material->SetParameter("MainTexture", mScene->AssetManager()->LoadTexture(diffuse.C_Str()));
- }
- if (specgloss != aiString("") && specgloss.C_Str()[0] != '*') {
- if (path.has_parent_path())
- specgloss = path.parent_path().string() + "/" + specgloss.C_Str();
- material->EnableKeyword("SPECGLOSS_MAP");
- material->SetParameter("SpecGlossTexture", mScene->AssetManager()->LoadTexture(specgloss.C_Str()));
- }
- if (normal != aiString("") && normal.C_Str()[0] != '*'){
- if (path.has_parent_path())
- normal = path.parent_path().string() + "/" + normal.C_Str();
- material->EnableKeyword("NORMAL_MAP");
- material->SetParameter("NormalTexture", mScene->AssetManager()->LoadTexture(normal.C_Str(), false));
- }
- if (occlusion != aiString("") && occlusion.C_Str()[0] != '*') {
- if (path.has_parent_path())
- occlusion = path.parent_path().string() + "/" + occlusion.C_Str();
- material->EnableKeyword("OCCLUSION_MAP");
- material->SetParameter("OcclusionTexture", mScene->AssetManager()->LoadTexture(occlusion.C_Str(), false));
- }
- if (emission != aiString("") && emission.C_Str()[0] != '*') {
- if (path.has_parent_path())
- emission = path.parent_path().string() + "/" + emission.C_Str();
- material->EnableKeyword("EMISSION");
- material->SetParameter("Emission", float3(emissionFac.r, emissionFac.g, emissionFac.b));
- material->SetParameter("EmissionTexture", mScene->AssetManager()->LoadTexture(emission.C_Str()));
- } else if (emissionFac.r > 0 || emissionFac.g > 0 || emissionFac.b > 0) {
- material->EnableKeyword("EMISSION");
- material->SetParameter("Emission", float3(emissionFac.r, emissionFac.g, emissionFac.b));
- material->SetParameter("EmissionTexture", mScene->AssetManager()->LoadTexture("Assets/white.png"));
- }
- material->RenderQueue(material->RenderQueue() + renderQueueOffset);
- mMaterials.push_back(material);
- renderQueueOffset++;
- }
- shared_ptr<Mesh>& mesh = meshes[node->mMeshes[i]];
- if (!mesh) {
- const aiMesh* aimesh = aiscene->mMeshes[node->mMeshes[i]];
- vector<Vertex> vertices(aimesh->mNumVertices);
- memset(vertices.data(), 0, sizeof(Vertex) * aimesh->mNumVertices);
- float3 mn, mx;
- // append vertices, keep track of bounding box
- for (uint32_t j = 0; j < aimesh->mNumVertices; j++) {
- Vertex& vertex = vertices[j];
- vertex.position = float3((float)aimesh->mVertices[j].x, (float)aimesh->mVertices[j].y, (float)aimesh->mVertices[j].z);
- if (aimesh->HasNormals()) vertex.normal = float3((float)aimesh->mNormals[j].x, (float)aimesh->mNormals[j].y, (float)aimesh->mNormals[j].z);
- if (aimesh->HasTangentsAndBitangents()) {
- vertex.tangent = float4((float)aimesh->mTangents[j].x, (float)aimesh->mTangents[j].y, (float)aimesh->mTangents[j].z, 1.f);
- float3 bt = float3((float)aimesh->mBitangents[j].x, (float)aimesh->mBitangents[j].y, (float)aimesh->mBitangents[j].z);
- vertex.tangent.w = dot(cross(vertex.tangent.xyz, vertex.normal), bt) > 0.f ? 1.f : -1.f;
- }
- if (aimesh->HasTextureCoords(0)) vertex.uv = float2((float)aimesh->mTextureCoords[0][j].x, (float)aimesh->mTextureCoords[0][j].y);
- vertex.position *= scale;
- float vp = .5f * (float)j / (float)aimesh->mNumVertices;
- mLoadProgress = ((float)meshNum + vp) / (float)meshCount;
- }
- bool use32bit = aimesh->mNumVertices > 0xFFFF;
- vector<uint16_t> indices16;
- vector<uint32_t> indices32;
- if (use32bit)
- for (uint32_t j = 0; j < aimesh->mNumFaces; j++) {
- const aiFace& f = aimesh->mFaces[j];
- if (f.mNumIndices == 0) continue;
- indices32.push_back(f.mIndices[0]);
- if (f.mNumIndices == 2) indices32.push_back(f.mIndices[1]);
- for (uint32_t j = 2; j < f.mNumIndices; j++) {
- indices32.push_back(f.mIndices[j - 1]);
- indices32.push_back(f.mIndices[j]);
- }
- float fp = .5f + .5f * (float)j / (float)aimesh->mNumFaces;
- mLoadProgress = ((float)meshNum + fp) / (float)meshCount;
- } else {
- for (uint32_t j = 0; j < aimesh->mNumFaces; j++) {
- const aiFace& f = aimesh->mFaces[j];
- if (f.mNumIndices == 0) continue;
- indices16.push_back(f.mIndices[0]);
- if (f.mNumIndices == 2) indices16.push_back(f.mIndices[1]);
- for (uint32_t j = 2; j < f.mNumIndices; j++) {
- indices16.push_back(f.mIndices[j - 1]);
- indices16.push_back(f.mIndices[j]);
- }
- float fp = .5f + .5f * (float)j / (float)aimesh->mNumFaces;
- mLoadProgress = ((float)meshNum + fp) / (float)meshCount;
- }
- }
- void* indices;
- VkIndexType indexType;
- uint32_t indexCount;
- if (use32bit) {
- indexCount = (uint32_t)indices32.size();
- indexType = VK_INDEX_TYPE_UINT32;
- indices = indices32.data();
- } else {
- indexCount = (uint32_t)indices16.size();
- indexType = VK_INDEX_TYPE_UINT16;
- indices = indices16.data();
- }
- // mesh = make_shared<Mesh>(aimesh->mName.C_Str(), mScene->DeviceManager(), aimesh, scale);
- mesh = make_shared<Mesh>(aimesh->mName.C_Str(), mScene->DeviceManager(),
- vertices.data(), indices, (uint32_t)vertices.size(), (uint32_t)sizeof(Vertex), indexCount, &Vertex::VertexInput, indexType);
- }
- shared_ptr<MeshRenderer> meshRenderer = make_shared<MeshRenderer>(node->mName.C_Str() + string(".") + aimesh->mName.C_Str());
- nodeobj.get()->AddChild(meshRenderer.get());
- meshRenderer->Mesh(mesh);
- meshRenderer->Material(material);
- mLoadedObjects.push_back(meshRenderer);
- meshNum++;
- }
- for (uint32_t i = 0; i < node->mNumChildren; i++)
- nodes.push(make_pair(node->mChildren[i], nodeobj.get()));
- }
- AABB aabb = root->BoundsHierarchy();
- root->LocalScale(.5f / fmaxf(fmaxf(aabb.mExtents.x, aabb.mExtents.y), aabb.mExtents.z));
- aabb = root->BoundsHierarchy();
- float3 offset = root->WorldPosition() - aabb.mCenter;
- offset.y += aabb.mExtents.y;
- root->LocalPosition(offset);
- mLoaded.emplace(path.string(), root);
- mLoading = false;
- return root;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement