Advertisement
Guest User

Untitled

a guest
Dec 8th, 2019
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.62 KB | None | 0 0
  1. Object* LoadScene(fs::path path, float scale) {
  2.     mLoadProgress = 0;
  3.    
  4.     Texture* brdfTexture  = mScene->AssetManager()->LoadTexture("Assets/BrdfLut.png", false);
  5.     Texture* whiteTexture = mScene->AssetManager()->LoadTexture("Assets/white.png");
  6.     Texture* bumpTexture  = mScene->AssetManager()->LoadTexture("Assets/bump.png", false);
  7.  
  8.     unordered_map<uint32_t, shared_ptr<Mesh>> meshes;
  9.     unordered_map<uint32_t, shared_ptr<Material>> materials;
  10.  
  11.     const aiScene* aiscene = aiImportFile(path.string().c_str(), aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_FlipUVs  | aiProcess_MakeLeftHanded);
  12.     if (!aiscene) {
  13.         cerr << "Failed to open " << path.string() <<  ": " << aiGetErrorString() << endl;
  14.         return nullptr;
  15.     }
  16.  
  17.     uint32_t meshCount = 0;
  18.     queue<aiNode*> aiNodes;
  19.     aiNodes.push(aiscene->mRootNode);
  20.     while (!aiNodes.empty()){
  21.         aiNode* node = aiNodes.front();
  22.         aiNodes.pop();
  23.         meshCount += node->mNumMeshes;
  24.         for (uint32_t i = 0; i < node->mNumChildren; i++)
  25.             aiNodes.push(node->mChildren[i]);
  26.     }
  27.    
  28.     queue<pair<aiNode*, Object*>> nodes;
  29.     nodes.push(make_pair(aiscene->mRootNode, nullptr));
  30.     Object* root = nullptr;
  31.  
  32.     uint32_t meshNum = 0;
  33.     uint32_t renderQueueOffset = 0;
  34.  
  35.     while(!nodes.empty()) {
  36.         pair<aiNode*, Object*> nodepair = nodes.front();
  37.         nodes.pop();
  38.  
  39.         aiNode* node = nodepair.first;
  40.  
  41.         aiVector3D s;
  42.         aiQuaternion r;
  43.         aiVector3D t;
  44.         node->mTransformation.Decompose(s, r, t);
  45.  
  46.         t *= scale;
  47.        
  48.         shared_ptr<Object> nodeobj = make_shared<Object>(node->mName.C_Str());
  49.         nodepair.second->AddChild(nodeobj.get());
  50.         nodeobj->LocalPosition(t.x, t.y, t.z);
  51.         nodeobj->LocalRotation(quaternion(r.x, r.y, r.z, r.w));
  52.         nodeobj->LocalScale(s.x, s.y, s.z);
  53.         mLoadedObjects.push_back(nodeobj);
  54.  
  55.         if (nodepair.first == aiscene->mRootNode)
  56.             root = nodeobj.get();
  57.  
  58.         for (uint32_t i = 0; i < node->mNumMeshes; i++) {
  59.             aiMesh* aimesh = aiscene->mMeshes[node->mMeshes[i]];
  60.             aiMaterial* aimat = aiscene->mMaterials[aimesh->mMaterialIndex];
  61.  
  62.             mLoadProgress = (float)meshNum / (float)meshCount;
  63.  
  64.             if ((aimesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) == 0) continue;
  65.  
  66.             shared_ptr<Material>& material = materials[aimesh->mMaterialIndex];
  67.             if (!material) {
  68.                 VkCullModeFlags cullMode = VK_CULL_MODE_FLAG_BITS_MAX_ENUM;
  69.                 BlendMode blendMode = BLEND_MODE_MAX_ENUM;
  70.                 bool twoSided = false;
  71.                 aiColor3D emissionFac;
  72.                 aiColor4D color;
  73.                 aiString matname, diffuse, normal, metalroughness, emission, occlusion, specgloss;
  74.                 aiString alphaMode;
  75.                 float metallic, roughness;
  76.                 aimat->Get(AI_MATKEY_NAME, matname);
  77.                 if (aimat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR, color) != aiReturn::aiReturn_SUCCESS)
  78.                     color.r = color.g = color.b = color.a = 1;
  79.                 if (aimat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR, metallic) != aiReturn::aiReturn_SUCCESS) metallic = 0.f;
  80.                 if (aimat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR, roughness) != aiReturn::aiReturn_SUCCESS) roughness = .5f;
  81.                 if (aimat->Get(AI_MATKEY_TWOSIDED, twoSided) == aiReturn::aiReturn_SUCCESS && twoSided) cullMode = VK_CULL_MODE_NONE;
  82.                 if (aimat->Get(AI_MATKEY_COLOR_EMISSIVE, emissionFac) != aiReturn::aiReturn_SUCCESS) emissionFac.r = emissionFac.g = emissionFac.b = 0;
  83.                 if (aimat->Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode) == aiReturn::aiReturn_SUCCESS && strcmp(alphaMode.C_Str(), "BLEND") == 0) blendMode = Alpha;
  84.                 aimat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS, specgloss);
  85.  
  86.                 aimat->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE, &diffuse);
  87.                 aimat->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &metalroughness);
  88.                 aimat->GetTexture(aiTextureType_LIGHTMAP, 0, &occlusion);
  89.                 aimat->GetTexture(aiTextureType_NORMALS, 0, &normal);
  90.                 aimat->GetTexture(aiTextureType_EMISSIVE, 0, &emission);
  91.  
  92.                 material = make_shared<Material>(matname.C_Str(), mPBRShader);
  93.                 material->CullMode(cullMode);
  94.                 material->BlendMode(blendMode);
  95.                 material->SetParameter("BrdfTexture", brdfTexture);
  96.                 material->SetParameter("Color", float4(color.r, color.g, color.b, color.a));
  97.                 material->SetParameter("Metallic", metallic);
  98.                 material->SetParameter("Roughness", roughness);
  99.                 material->SetParameter("EnvironmentTexture", mEnvironmentTexture);
  100.                 material->SetParameter("EnvironmentStrength", mEnvironmentStrength);
  101.                 if (twoSided) material->EnableKeyword("TWO_SIDED");
  102.  
  103.                 if (diffuse != aiString("") && diffuse.C_Str()[0] != '*') {
  104.                     if (path.has_parent_path())
  105.                         diffuse = path.parent_path().string() + "/" + diffuse.C_Str();
  106.                     material->EnableKeyword("COLOR_MAP");
  107.                     material->SetParameter("MainTexture", mScene->AssetManager()->LoadTexture(diffuse.C_Str()));
  108.                 }
  109.                 if (specgloss != aiString("") && specgloss.C_Str()[0] != '*') {
  110.                     if (path.has_parent_path())
  111.                         specgloss = path.parent_path().string() + "/" + specgloss.C_Str();
  112.                     material->EnableKeyword("SPECGLOSS_MAP");
  113.                     material->SetParameter("SpecGlossTexture", mScene->AssetManager()->LoadTexture(specgloss.C_Str()));
  114.                 }
  115.                 if (normal != aiString("") && normal.C_Str()[0] != '*'){
  116.                     if (path.has_parent_path())
  117.                         normal = path.parent_path().string() + "/" + normal.C_Str();
  118.                     material->EnableKeyword("NORMAL_MAP");
  119.                     material->SetParameter("NormalTexture", mScene->AssetManager()->LoadTexture(normal.C_Str(), false));
  120.                 }
  121.                 if (occlusion != aiString("") && occlusion.C_Str()[0] != '*') {
  122.                     if (path.has_parent_path())
  123.                         occlusion = path.parent_path().string() + "/" + occlusion.C_Str();
  124.                     material->EnableKeyword("OCCLUSION_MAP");
  125.                     material->SetParameter("OcclusionTexture", mScene->AssetManager()->LoadTexture(occlusion.C_Str(), false));
  126.                 }
  127.                 if (emission != aiString("") && emission.C_Str()[0] != '*') {
  128.                     if (path.has_parent_path())
  129.                         emission = path.parent_path().string() + "/" + emission.C_Str();
  130.                     material->EnableKeyword("EMISSION");
  131.                     material->SetParameter("Emission", float3(emissionFac.r, emissionFac.g, emissionFac.b));
  132.                     material->SetParameter("EmissionTexture", mScene->AssetManager()->LoadTexture(emission.C_Str()));
  133.                 } else if (emissionFac.r > 0 || emissionFac.g > 0 || emissionFac.b > 0) {
  134.                     material->EnableKeyword("EMISSION");
  135.                     material->SetParameter("Emission", float3(emissionFac.r, emissionFac.g, emissionFac.b));
  136.                     material->SetParameter("EmissionTexture", mScene->AssetManager()->LoadTexture("Assets/white.png"));
  137.                 }
  138.  
  139.                 material->RenderQueue(material->RenderQueue() + renderQueueOffset);
  140.                 mMaterials.push_back(material);
  141.                 renderQueueOffset++;
  142.             }
  143.  
  144.             shared_ptr<Mesh>& mesh = meshes[node->mMeshes[i]];
  145.             if (!mesh) {
  146.                 const aiMesh* aimesh = aiscene->mMeshes[node->mMeshes[i]];
  147.                 vector<Vertex> vertices(aimesh->mNumVertices);
  148.                 memset(vertices.data(), 0, sizeof(Vertex) * aimesh->mNumVertices);
  149.  
  150.                 float3 mn, mx;
  151.  
  152.                 // append vertices, keep track of bounding box
  153.                 for (uint32_t j = 0; j < aimesh->mNumVertices; j++) {
  154.                     Vertex& vertex = vertices[j];
  155.  
  156.                     vertex.position = float3((float)aimesh->mVertices[j].x, (float)aimesh->mVertices[j].y, (float)aimesh->mVertices[j].z);
  157.                     if (aimesh->HasNormals()) vertex.normal = float3((float)aimesh->mNormals[j].x, (float)aimesh->mNormals[j].y, (float)aimesh->mNormals[j].z);
  158.                     if (aimesh->HasTangentsAndBitangents()) {
  159.                         vertex.tangent = float4((float)aimesh->mTangents[j].x, (float)aimesh->mTangents[j].y, (float)aimesh->mTangents[j].z, 1.f);
  160.                         float3 bt = float3((float)aimesh->mBitangents[j].x, (float)aimesh->mBitangents[j].y, (float)aimesh->mBitangents[j].z);
  161.                         vertex.tangent.w = dot(cross(vertex.tangent.xyz, vertex.normal), bt) > 0.f ? 1.f : -1.f;
  162.                     }
  163.                     if (aimesh->HasTextureCoords(0)) vertex.uv = float2((float)aimesh->mTextureCoords[0][j].x, (float)aimesh->mTextureCoords[0][j].y);
  164.                     vertex.position *= scale;
  165.  
  166.                     float vp = .5f * (float)j / (float)aimesh->mNumVertices;
  167.                     mLoadProgress = ((float)meshNum + vp) / (float)meshCount;
  168.                 }
  169.  
  170.                 bool use32bit = aimesh->mNumVertices > 0xFFFF;
  171.                 vector<uint16_t> indices16;
  172.                 vector<uint32_t> indices32;
  173.  
  174.                 if (use32bit)
  175.                     for (uint32_t j = 0; j < aimesh->mNumFaces; j++) {
  176.                         const aiFace& f = aimesh->mFaces[j];
  177.                         if (f.mNumIndices == 0) continue;
  178.                         indices32.push_back(f.mIndices[0]);
  179.                         if (f.mNumIndices == 2) indices32.push_back(f.mIndices[1]);
  180.                         for (uint32_t j = 2; j < f.mNumIndices; j++) {
  181.                             indices32.push_back(f.mIndices[j - 1]);
  182.                             indices32.push_back(f.mIndices[j]);
  183.                         }
  184.                         float fp = .5f + .5f * (float)j / (float)aimesh->mNumFaces;
  185.                         mLoadProgress = ((float)meshNum + fp) / (float)meshCount;
  186.                     } else {
  187.                         for (uint32_t j = 0; j < aimesh->mNumFaces; j++) {
  188.                             const aiFace& f = aimesh->mFaces[j];
  189.                             if (f.mNumIndices == 0) continue;
  190.                             indices16.push_back(f.mIndices[0]);
  191.                             if (f.mNumIndices == 2) indices16.push_back(f.mIndices[1]);
  192.                             for (uint32_t j = 2; j < f.mNumIndices; j++) {
  193.                                 indices16.push_back(f.mIndices[j - 1]);
  194.                                 indices16.push_back(f.mIndices[j]);
  195.                             }
  196.                             float fp = .5f + .5f * (float)j / (float)aimesh->mNumFaces;
  197.                             mLoadProgress = ((float)meshNum + fp) / (float)meshCount;
  198.                         }
  199.                     }
  200.  
  201.                 void* indices;
  202.                 VkIndexType indexType;
  203.                 uint32_t indexCount;
  204.                 if (use32bit) {
  205.                     indexCount = (uint32_t)indices32.size();
  206.                     indexType = VK_INDEX_TYPE_UINT32;
  207.                     indices = indices32.data();
  208.                 } else {
  209.                     indexCount = (uint32_t)indices16.size();
  210.                     indexType = VK_INDEX_TYPE_UINT16;
  211.                     indices = indices16.data();
  212.                 }
  213.  
  214.                 // mesh = make_shared<Mesh>(aimesh->mName.C_Str(), mScene->DeviceManager(), aimesh, scale);
  215.                 mesh = make_shared<Mesh>(aimesh->mName.C_Str(), mScene->DeviceManager(),
  216.                     vertices.data(), indices, (uint32_t)vertices.size(), (uint32_t)sizeof(Vertex), indexCount, &Vertex::VertexInput, indexType);
  217.             }
  218.  
  219.             shared_ptr<MeshRenderer> meshRenderer = make_shared<MeshRenderer>(node->mName.C_Str() + string(".") + aimesh->mName.C_Str());
  220.             nodeobj.get()->AddChild(meshRenderer.get());
  221.             meshRenderer->Mesh(mesh);
  222.             meshRenderer->Material(material);
  223.             mLoadedObjects.push_back(meshRenderer);
  224.  
  225.             meshNum++;
  226.         }
  227.  
  228.         for (uint32_t i = 0; i < node->mNumChildren; i++)
  229.             nodes.push(make_pair(node->mChildren[i], nodeobj.get()));
  230.     }
  231.  
  232.     AABB aabb = root->BoundsHierarchy();
  233.     root->LocalScale(.5f / fmaxf(fmaxf(aabb.mExtents.x, aabb.mExtents.y), aabb.mExtents.z));
  234.     aabb = root->BoundsHierarchy();
  235.     float3 offset = root->WorldPosition() - aabb.mCenter;
  236.     offset.y += aabb.mExtents.y;
  237.     root->LocalPosition(offset);
  238.  
  239.     mLoaded.emplace(path.string(), root);
  240.  
  241.     mLoading = false;
  242.     return root;
  243. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement