From 6085cbf7b28502598f84a0726b3e0e7e76b6e3aa Mon Sep 17 00:00:00 2001 From: Michael Hitchens Date: Fri, 20 Feb 2026 12:29:36 -0500 Subject: [PATCH] [glTF] Removed unused GltfLoader functions Adding new features to GltfLoader is difficult for two main reasons: 1. Many methods are untested so it's hard to understand what they do or know how to modify them correctly. 2. ResourceManager is optional, which creates two code paths through GltfLoader. This greatly increases cognitive burden. Since only LoadScene is used and LoadScene creates a ResourceManager, I suggest to: 1. Remove the unused public methods 2. Require a ResourceManager This should simplfy the class and make it easier to modify. --- include/ppx/scene/scene_gltf_loader.h | 108 ---- include/ppx/scene/scene_loader.h | 23 - src/ppx/scene/scene_gltf_loader.cpp | 719 ++++---------------------- 3 files changed, 91 insertions(+), 759 deletions(-) diff --git a/include/ppx/scene/scene_gltf_loader.h b/include/ppx/scene/scene_gltf_loader.h index 0e0320c35..03660f7f0 100644 --- a/include/ppx/scene/scene_gltf_loader.h +++ b/include/ppx/scene/scene_gltf_loader.h @@ -92,113 +92,6 @@ class GltfLoader int32_t GetNodeIndex(const std::string& name) const; int32_t GetSceneIndex(const std::string& name) const; - // --------------------------------------------------------------------------------------------- - // Loads a GLTF sampler, image, texture, or material - // - // These load functions create standalone objects that can be used - // outside of a scene. Caching is not used. - // - // --------------------------------------------------------------------------------------------- - ppx::Result LoadSampler( - grfx::Device* pDevice, - uint32_t samplerIndex, - scene::Sampler** ppTargetSampler); - - ppx::Result LoadSampler( - grfx::Device* pDevice, - const std::string& samplerName, - scene::Sampler** ppTargetSampler); - - ppx::Result LoadImage( - grfx::Device* pDevice, - uint32_t imageIndex, - scene::Image** ppTargetImage); - - ppx::Result LoadImage( - grfx::Device* pDevice, - const std::string& imageName, - scene::Image** ppTargetImage); - - ppx::Result LoadTexture( - grfx::Device* pDevice, - uint32_t textureIndex, - scene::Texture** ppTargetTexture); - - ppx::Result LoadTexture( - grfx::Device* pDevice, - const std::string& textureName, - scene::Texture** ppTargetTexture); - - ppx::Result LoadMaterial( - grfx::Device* pDevice, - uint32_t materialIndex, - scene::Material** ppTargetMaterial, - const scene::LoadOptions& loadOptions = scene::LoadOptions()); - - ppx::Result LoadMaterial( - grfx::Device* pDevice, - const std::string& materialName, - scene::Material** ppTargetMaterial, - const scene::LoadOptions& loadOptions = scene::LoadOptions()); - - // --------------------------------------------------------------------------------------------- - // Loads a GLTF mesh - // - // This function creates a standalone mesh that usable outside of a scene. - // - // Standalone meshes uses an internal scene::ResourceManager to - // manage its required objects. All required objects created as apart - // of the mesh loading will be managed by the mesh. The reasoning - // for this is because images, textures, and materials can be shared - // between primitive batches. - // - // Object sharing requires that the lifetime of an object to be managed - // by an external mechanism, scene::ResourceManager. When a mesh is - // destroyed, its destructor calls scene::ResourceManager::DestroyAll - // to destroy its reference to the shared objects. If afterwards a shared - // object has an external reference, the code holding the reference - // is responsible for the shared objct. - // - // activeVertexAttributes - specifies the attributes that the a mesh - // should be created with. If a GLTF file doesn't provide data for - // an attribute, an sensible default value is used - usually zeroes. - // - // --------------------------------------------------------------------------------------------- - ppx::Result LoadMesh( - grfx::Device* pDevice, - uint32_t meshIndex, - scene::Mesh** ppTargetMesh, - const scene::LoadOptions& loadOptions = scene::LoadOptions()); - - ppx::Result LoadMesh( - grfx::Device* pDevice, - const std::string& meshName, - scene::Mesh** ppTargetMesh, - const scene::LoadOptions& loadOptions = scene::LoadOptions()); - - // --------------------------------------------------------------------------------------------- - // Loads a GLTF node - // --------------------------------------------------------------------------------------------- - ppx::Result LoadNode( - grfx::Device* pDevice, - uint32_t nodeIndex, - scene::Node** ppTargetNode, - const scene::LoadOptions& loadOptions = scene::LoadOptions()); - - ppx::Result LoadNode( - grfx::Device* pDevice, - const std::string& nodeName, - scene::Node** ppTargetNode, - const scene::LoadOptions& loadOptions = scene::LoadOptions()); - - ppx::Result LoadNodeTransformOnly( - uint32_t nodeIndex, - scene::Node** ppTargetNode); - - ppx::Result LoadNodeTransformOnly( - const std::string& nodeName, - scene::Node** ppTargetNode); - // --------------------------------------------------------------------------------------------- // Loads a GLTF scene // @@ -248,7 +141,6 @@ class GltfLoader { grfx::Device* pDevice = nullptr; scene::MaterialFactory* pMaterialFactory = nullptr; - scene::VertexAttributeFlags requiredVertexAttributes = scene::VertexAttributeFlags::None(); scene::ResourceManager* pResourceManager = nullptr; MeshMaterialVertexAttributeMasks* pMeshMaterialVertexAttributeMasks = nullptr; bool transformOnly = false; diff --git a/include/ppx/scene/scene_loader.h b/include/ppx/scene/scene_loader.h index 160817837..a4bb35dbc 100644 --- a/include/ppx/scene/scene_loader.h +++ b/include/ppx/scene/scene_loader.h @@ -45,32 +45,9 @@ class LoadOptions return *this; } - // Returns true if the calling application requires a specific set of attrbutes - bool HasRequiredVertexAttributes() const { return (mRequiredVertexAttributes.mask != 0); } - - // Returns the attributes that the calling application rquires or none if attributes has not been set. - const scene::VertexAttributeFlags& GetRequiredAttributes() const { return mRequiredVertexAttributes; } - - // Set attributes required by calling allication. - LoadOptions& SetRequiredAttributes(const scene::VertexAttributeFlags& attributes) - { - mRequiredVertexAttributes = attributes; - return *this; - } - - // Clears required attributes (sets required attributs to none) - void ClearRequiredAttributes() { SetRequiredAttributes(scene::VertexAttributeFlags::None()); } - private: // Pointer to custom material factory for loader to use. scene::MaterialFactory* mMaterialFactory = nullptr; - - // Required attributes for meshes nodes, meshes - this should override - // whatever a loader is using to determine which vertex attributes to laod. - // If the source data doesn't provide data for an attribute, an sensible - // default value is used - usually zeroes. - // - scene::VertexAttributeFlags mRequiredVertexAttributes = scene::VertexAttributeFlags::None(); }; } // namespace scene diff --git a/src/ppx/scene/scene_gltf_loader.cpp b/src/ppx/scene/scene_gltf_loader.cpp index cae41664c..3a9fd5267 100644 --- a/src/ppx/scene/scene_gltf_loader.cpp +++ b/src/ppx/scene/scene_gltf_loader.cpp @@ -637,6 +637,9 @@ void GltfLoader::CalculateMeshMaterialVertexAttributeMasks( // Get required vertex attributes auto requiredVertexAttributes = pMaterialFactory->GetRequiredVertexAttributes(materialIdent); + // Disable vertex colors for now: some work is needed to handle format conversion. + requiredVertexAttributes.bits.colors = false; + // OR the masks outMasks[pGltfMesh] |= requiredVertexAttributes; } @@ -947,57 +950,25 @@ ppx::Result GltfLoader::LoadTextureInternal( scene::SamplerRef targetSampler = nullptr; scene::ImageRef targetImage = nullptr; - // Fetch if there's a resource manager... - if (!IsNull(loadParams.pResourceManager)) { - if (!IsNull(pGltfTexture->sampler)) { - auto ppxres = FetchSamplerInternal(loadParams, pGltfTexture->sampler, targetSampler); - if (Failed(ppxres)) { - return ppxres; - } - } - else { - constexpr auto kDefaultSamplerId = std::numeric_limits::max(); - if (!loadParams.pResourceManager->Find(kDefaultSamplerId, targetSampler)) { - if (ppx::Result ppxres = CreateDefaultSampler(*loadParams.pDevice, targetSampler); Failed(ppxres)) { - return ppxres; - } - loadParams.pResourceManager->Cache(kDefaultSamplerId, targetSampler); - } - } - - ppx::Result ppxres = FetchImageInternal(loadParams, pGltfTexture->image, targetImage); + if (!IsNull(pGltfTexture->sampler)) { + auto ppxres = FetchSamplerInternal(loadParams, pGltfTexture->sampler, targetSampler); if (Failed(ppxres)) { return ppxres; } } - // ...otherwise load! else { - scene::Sampler* pTargetSampler = nullptr; - auto ppxres = IsNull(pGltfTexture->sampler) ? CreateDefaultSampler(*loadParams.pDevice, &pTargetSampler) : LoadSamplerInternal(loadParams, pGltfTexture->sampler, &pTargetSampler); - if (Failed(ppxres)) { - return ppxres; - } - PPX_ASSERT_NULL_ARG(pTargetSampler); - - targetSampler = scene::MakeRef(pTargetSampler); - if (!targetSampler) { - delete pTargetSampler; - return ppx::ERROR_ALLOCATION_FAILED; - } - - // Load image - scene::Image* pTargetImage = nullptr; - ppxres = LoadImageInternal(loadParams, pGltfTexture->image, &pTargetImage); - if (Failed(ppxres)) { - return ppxres; + constexpr auto kDefaultSamplerId = std::numeric_limits::max(); + if (!loadParams.pResourceManager->Find(kDefaultSamplerId, targetSampler)) { + if (ppx::Result ppxres = CreateDefaultSampler(*loadParams.pDevice, targetSampler); Failed(ppxres)) { + return ppxres; + } + loadParams.pResourceManager->Cache(kDefaultSamplerId, targetSampler); } - PPX_ASSERT_NULL_ARG(pTargetImage); + } - targetImage = scene::MakeRef(pTargetImage); - if (!targetImage) { - delete pTargetImage; - return ppx::ERROR_ALLOCATION_FAILED; - } + ppx::Result ppxres = FetchImageInternal(loadParams, pGltfTexture->image, targetImage); + if (Failed(ppxres)) { + return ppxres; } // Create target object @@ -1074,26 +1045,9 @@ ppx::Result GltfLoader::LoadTextureViewInternal( // Required object scene::TextureRef targetTexture = nullptr; - // Fetch if there's a resource manager... - if (!IsNull(loadParams.pResourceManager)) { - auto ppxres = FetchTextureInternal(loadParams, pGltfTextureView->texture, targetTexture); - if (Failed(ppxres)) { - return ppxres; - } - } - // ...otherwise load! - else { - scene::Texture* pTargetTexture = nullptr; - auto ppxres = LoadTextureInternal(loadParams, pGltfTextureView->texture, &pTargetTexture); - if (Failed(ppxres)) { - return ppxres; - } - - targetTexture = scene::MakeRef(pTargetTexture); - if (!targetTexture) { - delete pTargetTexture; - return ppx::ERROR_ALLOCATION_FAILED; - } + auto ppxres = FetchTextureInternal(loadParams, pGltfTextureView->texture, targetTexture); + if (Failed(ppxres)) { + return ppxres; } // Set texture transform if needed @@ -1349,26 +1303,31 @@ ppx::Result GltfLoader::LoadMeshData( // Use cached object if possible bool hasCachedGeometry = false; - if (!IsNull(loadParams.pResourceManager)) { - if (loadParams.pResourceManager->Find(objectId, outMeshData)) { - PPX_LOG_INFO(" ...cache load mesh data (objectId=" << objectId << ") for GLTF mesh[" << gltfMeshIndex << "]: " << gltfObjectName); + if (loadParams.pResourceManager->Find(objectId, outMeshData)) { + PPX_LOG_INFO(" ...cache load mesh data (objectId=" << objectId << ") for GLTF mesh[" << gltfMeshIndex << "]: " << gltfObjectName); - // We don't return here like the other functions because we still need - // to process the primitives, instead we just set the flag to prevent - // geometry creation. - // - hasCachedGeometry = true; - } + // We don't return here like the other functions because we still need + // to process the primitives, instead we just set the flag to prevent + // geometry creation. + // + hasCachedGeometry = true; } // --------------------------------------------------------------------------------------------- + auto requiredVertexAttributesIter = loadParams.pMeshMaterialVertexAttributeMasks->find(pGltfMesh); + if (requiredVertexAttributesIter == loadParams.pMeshMaterialVertexAttributeMasks->end()) { + PPX_LOG_ERROR("pMeshMaterialVertexAttributeMasks missing entry for mesh" << pGltfMesh); + return ERROR_UNEXPECTED_NULL_ARGUMENT; // TODO better return code + } + scene::VertexAttributeFlags requiredVertexAttributes = requiredVertexAttributesIter->second; + // Target vertex formats auto targetPositionFormat = scene::kVertexPositionFormat; - auto targetTexCoordFormat = loadParams.requiredVertexAttributes.bits.texCoords ? scene::kVertexAttributeTexCoordFormat : grfx::FORMAT_UNDEFINED; - auto targetNormalFormat = loadParams.requiredVertexAttributes.bits.normals ? scene::kVertexAttributeNormalFormat : grfx::FORMAT_UNDEFINED; - auto targetTangentFormat = loadParams.requiredVertexAttributes.bits.tangents ? scene::kVertexAttributeTagentFormat : grfx::FORMAT_UNDEFINED; - auto targetColorFormat = loadParams.requiredVertexAttributes.bits.colors ? scene::kVertexAttributeColorFormat : grfx::FORMAT_UNDEFINED; + auto targetTexCoordFormat = requiredVertexAttributes.bits.texCoords ? scene::kVertexAttributeTexCoordFormat : grfx::FORMAT_UNDEFINED; + auto targetNormalFormat = requiredVertexAttributes.bits.normals ? scene::kVertexAttributeNormalFormat : grfx::FORMAT_UNDEFINED; + auto targetTangentFormat = requiredVertexAttributes.bits.tangents ? scene::kVertexAttributeTagentFormat : grfx::FORMAT_UNDEFINED; + auto targetColorFormat = requiredVertexAttributes.bits.colors ? scene::kVertexAttributeColorFormat : grfx::FORMAT_UNDEFINED; const uint32_t targetTexCoordElementSize = (targetTexCoordFormat != grfx::FORMAT_UNDEFINED) ? grfx::GetFormatDescription(targetTexCoordFormat)->bytesPerTexel : 0; const uint32_t targetNormalElementSize = (targetNormalFormat != grfx::FORMAT_UNDEFINED) ? grfx::GetFormatDescription(targetNormalFormat)->bytesPerTexel : 0; @@ -1557,16 +1516,16 @@ ppx::Result GltfLoader::LoadMeshData( // Create targetGeometry so we can repack gemetry data into position planar + packed vertex attributes. Geometry targetGeometry = {}; - const bool hasAttributes = (loadParams.requiredVertexAttributes.mask != 0); + const bool hasAttributes = (requiredVertexAttributes.mask != 0); // { GeometryCreateInfo createInfo = (hasAttributes ? GeometryCreateInfo::PositionPlanar() : GeometryCreateInfo::Planar()).IndexType(batch.repackedIndexType); // clang-format off - if (loadParams.requiredVertexAttributes.bits.texCoords) createInfo.AddTexCoord(targetTexCoordFormat); - if (loadParams.requiredVertexAttributes.bits.normals) createInfo.AddNormal(targetNormalFormat); - if (loadParams.requiredVertexAttributes.bits.tangents) createInfo.AddTangent(targetTangentFormat); - if (loadParams.requiredVertexAttributes.bits.colors) createInfo.AddColor(targetColorFormat); + if (requiredVertexAttributes.bits.texCoords) createInfo.AddTexCoord(targetTexCoordFormat); + if (requiredVertexAttributes.bits.normals) createInfo.AddNormal(targetNormalFormat); + if (requiredVertexAttributes.bits.tangents) createInfo.AddTangent(targetTangentFormat); + if (requiredVertexAttributes.bits.colors) createInfo.AddColor(targetColorFormat); // clang-format on auto ppxres = ppx::Geometry::Create(createInfo, &targetGeometry); @@ -1641,22 +1600,22 @@ ppx::Result GltfLoader::LoadMeshData( auto positions = UnpackFloat3s(*gltflAccessors.pPositions); std::vector texCoords; - if (loadParams.requiredVertexAttributes.bits.texCoords && !IsNull(gltflAccessors.pTexCoords)) { + if (requiredVertexAttributes.bits.texCoords && !IsNull(gltflAccessors.pTexCoords)) { PPX_ASSERT_MSG((texCoordFormat == targetTexCoordFormat), "GLTF: vertex tex coords sourceIndexTypeFormat is not supported"); texCoords = UnpackFloat2s(*gltflAccessors.pTexCoords); } std::vector normals; - if (loadParams.requiredVertexAttributes.bits.normals && !IsNull(gltflAccessors.pNormals)) { + if (requiredVertexAttributes.bits.normals && !IsNull(gltflAccessors.pNormals)) { PPX_ASSERT_MSG((normalFormat == targetNormalFormat), "GLTF: vertex normals format is not supported"); normals = UnpackFloat3s(*gltflAccessors.pNormals); } std::vector tangents; - if (loadParams.requiredVertexAttributes.bits.tangents && !IsNull(gltflAccessors.pTangents)) { + if (requiredVertexAttributes.bits.tangents && !IsNull(gltflAccessors.pTangents)) { PPX_ASSERT_MSG((tangentFormat == targetTangentFormat), "GLTF: vertex tangents format is not supported"); tangents = UnpackFloat4s(*gltflAccessors.pTangents); } std::vector colors; - if (loadParams.requiredVertexAttributes.bits.colors && !IsNull(gltflAccessors.pColors)) { + if (requiredVertexAttributes.bits.colors && !IsNull(gltflAccessors.pColors)) { PPX_ASSERT_MSG((colorFormat == targetColorFormat), "GLTF: vertex colors format is not supported"); colors = UnpackFloat3s(*gltflAccessors.pColors); } @@ -1666,16 +1625,16 @@ ppx::Result GltfLoader::LoadMeshData( TriMeshVertexData vertexData = {}; vertexData.position = positions[i]; - if (loadParams.requiredVertexAttributes.bits.normals && !normals.empty()) { + if (requiredVertexAttributes.bits.normals && !normals.empty()) { vertexData.normal = normals[i]; } - if (loadParams.requiredVertexAttributes.bits.tangents && !tangents.empty()) { + if (requiredVertexAttributes.bits.tangents && !tangents.empty()) { vertexData.tangent = tangents[i]; } - if (loadParams.requiredVertexAttributes.bits.colors && !colors.empty()) { + if (requiredVertexAttributes.bits.colors && !colors.empty()) { vertexData.color = colors[i]; } - if (loadParams.requiredVertexAttributes.bits.texCoords && !texCoords.empty()) { + if (requiredVertexAttributes.bits.texCoords && !texCoords.empty()) { vertexData.texCoord = texCoords[i]; } @@ -1783,7 +1742,7 @@ ppx::Result GltfLoader::LoadMeshData( // Create GPU mesh from geometry if we don't have cached geometry if (!hasCachedGeometry) { // Allocate mesh data - auto pTargetMeshData = new scene::MeshData(loadParams.requiredVertexAttributes, targetGpuBuffer); + auto pTargetMeshData = new scene::MeshData(requiredVertexAttributes, targetGpuBuffer); if (IsNull(pTargetMeshData)) { loadParams.pDevice->DestroyBuffer(targetGpuBuffer); return ppx::ERROR_ALLOCATION_FAILED; @@ -1795,22 +1754,19 @@ ppx::Result GltfLoader::LoadMeshData( // Set name outMeshData->SetName(gltfObjectName); - // Cache object if caching - if (!IsNull(loadParams.pResourceManager)) { - PPX_LOG_INFO(" ...caching mesh data (objectId=" << objectId << ") for GLTF mesh[" << gltfMeshIndex << "]: " << gltfObjectName); - loadParams.pResourceManager->Cache(objectId, outMeshData); - } + PPX_LOG_INFO(" ...caching mesh data (objectId=" << objectId << ") for GLTF mesh[" << gltfMeshIndex << "]: " << gltfObjectName); + loadParams.pResourceManager->Cache(objectId, outMeshData); } return ppx::SUCCESS; } ppx::Result GltfLoader::LoadMeshInternal( - const GltfLoader::InternalLoadParams& externalLoadParams, + const GltfLoader::InternalLoadParams& loadParams, const cgltf_mesh* pGltfMesh, scene::Mesh** ppTargetMesh) { - if (IsNull(externalLoadParams.pDevice) || IsNull(pGltfMesh) || IsNull(ppTargetMesh)) { + if (IsNull(loadParams.pDevice) || IsNull(pGltfMesh) || IsNull(ppTargetMesh)) { return ppx::ERROR_UNEXPECTED_NULL_ARGUMENT; } @@ -1821,120 +1777,49 @@ ppx::Result GltfLoader::LoadMeshInternal( const uint32_t gltfObjectIndex = static_cast(cgltf_mesh_index(mGltfData, pGltfMesh)); PPX_LOG_INFO("Loading GLTF mesh[" << gltfObjectIndex << "]: " << gltfObjectName); - // Create target mesh - scoped to prevent localLoadParams from leaking - scene::Mesh* pTargetMesh = nullptr; - // - { - // Copy the external load params so we can control the resource manager and vertex attributes. - // - auto localLoadParams = externalLoadParams; - localLoadParams.requiredVertexAttributes = scene::VertexAttributeFlags::None(); + for (cgltf_size primIdx = 0; primIdx < pGltfMesh->primitives_count; ++primIdx) { + const cgltf_primitive* pGltfPrimitive = &pGltfMesh->primitives[primIdx]; + const cgltf_material* pGltfMaterial = pGltfPrimitive->material; - // If a resource manager wasn't passed in, this means we're dealing with - // a standalone mesh which needs a local resource manager. So, we'll - // create one if that's the case. + // Yes, it's completely possible for GLTF primitives to have no material. + // For example, if you create a cube in Blender and export it without + // assigning a material to it. Obviously, this results in material being + // NULL. No need to load anything if it's NULL. // - std::unique_ptr localResourceManager; - if (IsNull(localLoadParams.pResourceManager)) { - localResourceManager = std::make_unique(); - if (!localResourceManager) { - return ppx::ERROR_ALLOCATION_FAILED; - } - - // Override resource manager - localLoadParams.pResourceManager = localResourceManager.get(); - } - - // Load materials for primitives and get required vertex attributes - for (cgltf_size primIdx = 0; primIdx < pGltfMesh->primitives_count; ++primIdx) { - const cgltf_primitive* pGltfPrimitive = &pGltfMesh->primitives[primIdx]; - const cgltf_material* pGltfMaterial = pGltfPrimitive->material; - - // Yes, it's completely possible for GLTF primitives to have no material. - // For example, if you create a cube in Blender and export it without - // assigning a material to it. Obviously, this results in material being - // NULL. No need to load anything if it's NULL. - // - if (IsNull(pGltfMaterial)) { - continue; - } - - // Fetch material since we'll always have a resource manager - scene::MaterialRef loadedMaterial; - // - auto ppxres = FetchMaterialInternal( - localLoadParams, - pGltfMaterial, - loadedMaterial); - if (ppxres) { - return ppxres; - } - - // Get material ident - const std::string materialIdent = loadedMaterial->GetIdentString(); - - // Get material's required vertex attributes - auto materialRequiredVertexAttributes = localLoadParams.pMaterialFactory->GetRequiredVertexAttributes(materialIdent); - localLoadParams.requiredVertexAttributes |= materialRequiredVertexAttributes; + if (IsNull(pGltfMaterial)) { + continue; } - // If we don't have a local resource manager, then it means we're loading in through a scene. - // If we're loading in through a scene, then we need to user the mesh data vertex attributes - // supplied to this function...if they were supplied. + // Load materials now since LoadMeshData assumes that the materials are in the ResourceManager. + scene::MaterialRef loadedMaterial; // - if (!localResourceManager && !IsNull(localLoadParams.pMeshMaterialVertexAttributeMasks)) { - auto it = localLoadParams.pMeshMaterialVertexAttributeMasks->find(pGltfMesh); - - // Keeps the local mesh's vertex attribute if search failed. - // - if (it != localLoadParams.pMeshMaterialVertexAttributeMasks->end()) { - localLoadParams.requiredVertexAttributes = (*it).second; - } - } - - // Override the local vertex attributes with loadParams has vertex attributes - if (externalLoadParams.requiredVertexAttributes.mask != 0) { - localLoadParams.requiredVertexAttributes = externalLoadParams.requiredVertexAttributes; + auto ppxres = FetchMaterialInternal( + loadParams, + pGltfMaterial, + loadedMaterial); + if (ppxres) { + return ppxres; } + } - // - // Disable vertex colors for now: some work is needed to handle format conversion. - // - localLoadParams.requiredVertexAttributes.bits.colors = false; - - // Load mesh data and batches - scene::MeshDataRef meshData = nullptr; - std::vector batches = {}; - // - { - auto ppxres = LoadMeshData( - localLoadParams, - pGltfMesh, - meshData, - batches); - if (Failed(ppxres)) { - return ppxres; - } + // Load mesh data and batches + scene::MeshDataRef meshData = nullptr; + std::vector batches = {}; + // + { + auto ppxres = LoadMeshData( + loadParams, + pGltfMesh, + meshData, + batches); + if (Failed(ppxres)) { + return ppxres; } + } - // Create target mesh - if (localResourceManager) { - // Allocate mesh with local resource manager - pTargetMesh = new scene::Mesh( - std::move(localResourceManager), - meshData, - std::move(batches)); - if (IsNull(pTargetMesh)) { - return ppx::ERROR_ALLOCATION_FAILED; - } - } - else { - // Allocate mesh - pTargetMesh = new scene::Mesh(meshData, std::move(batches)); - if (IsNull(pTargetMesh)) { - return ppx::ERROR_ALLOCATION_FAILED; - } - } + scene::Mesh* pTargetMesh = new scene::Mesh(meshData, std::move(batches)); + if (IsNull(pTargetMesh)) { + return ppx::ERROR_ALLOCATION_FAILED; } // Set name @@ -2035,26 +1920,9 @@ ppx::Result GltfLoader::LoadNodeInternal( // Required object scene::MeshRef targetMesh = nullptr; - // Fetch if there's a resource manager... - if (!IsNull(loadParams.pResourceManager)) { - auto ppxres = FetchMeshInternal(loadParams, pGltfMesh, targetMesh); - if (Failed(ppxres)) { - return ppxres; - } - } - // ...otherwise load! - else { - scene::Mesh* pTargetMesh = nullptr; - auto ppxres = LoadMeshInternal(loadParams, pGltfMesh, &pTargetMesh); - if (Failed(ppxres)) { - return ppxres; - } - - targetMesh = scene::MakeRef(pTargetMesh); - if (!targetMesh) { - delete pTargetMesh; - return ppx::ERROR_ALLOCATION_FAILED; - } + auto ppxres = FetchMeshInternal(loadParams, pGltfMesh, targetMesh); + if (Failed(ppxres)) { + return ppxres; } // Allocate node @@ -2495,410 +2363,6 @@ int32_t GltfLoader::GetSceneIndex(const std::string& name) const return index; } -ppx::Result GltfLoader::LoadSampler( - grfx::Device* pDevice, - uint32_t samplerIndex, - scene::Sampler** ppTargetSampler) -{ - if (IsNull(pDevice)) { - return ppx::ERROR_UNEXPECTED_NULL_ARGUMENT; - } - - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - if (samplerIndex >= static_cast(mGltfData->samplers_count)) { - return ppx::ERROR_OUT_OF_RANGE; - } - - auto pGltfSampler = &mGltfData->samplers[samplerIndex]; - if (IsNull(pGltfSampler)) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - GltfLoader::InternalLoadParams loadParams = {}; - loadParams.pDevice = pDevice; - - auto ppxres = LoadSamplerInternal( - loadParams, - pGltfSampler, - ppTargetSampler); - if (Failed(ppxres)) { - return ppxres; - } - - return ppx::SUCCESS; -} - -ppx::Result GltfLoader::LoadSampler( - grfx::Device* pDevice, - const std::string& samplerName, - scene::Sampler** ppTargetSampler) -{ - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - int32_t meshIndex = this->GetSamplerIndex(samplerName); - if (meshIndex < 0) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - return LoadSampler( - pDevice, - static_cast(meshIndex), - ppTargetSampler); -} - -ppx::Result GltfLoader::LoadImage( - grfx::Device* pDevice, - uint32_t imageIndex, - scene::Image** ppTargetImage) -{ - if (IsNull(pDevice)) { - return ppx::ERROR_UNEXPECTED_NULL_ARGUMENT; - } - - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - if (imageIndex >= static_cast(mGltfData->samplers_count)) { - return ppx::ERROR_OUT_OF_RANGE; - } - - auto pGltfImage = &mGltfData->images[imageIndex]; - if (IsNull(pGltfImage)) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - GltfLoader::InternalLoadParams loadParams = {}; - loadParams.pDevice = pDevice; - - auto ppxres = LoadImageInternal( - loadParams, - pGltfImage, - ppTargetImage); - if (Failed(ppxres)) { - return ppxres; - } - - return ppx::SUCCESS; -} - -ppx::Result GltfLoader::LoadImage( - grfx::Device* pDevice, - const std::string& imageName, - scene::Image** ppTargetImage) -{ - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - int32_t imageIndex = this->GetImageIndex(imageName); - if (imageIndex < 0) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - return LoadImage( - pDevice, - static_cast(imageIndex), - ppTargetImage); -} - -ppx::Result GltfLoader::LoadTexture( - grfx::Device* pDevice, - uint32_t textureIndex, - scene::Texture** ppTargetTexture) -{ - if (IsNull(pDevice)) { - return ppx::ERROR_UNEXPECTED_NULL_ARGUMENT; - } - - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - if (textureIndex >= static_cast(mGltfData->samplers_count)) { - return ppx::ERROR_OUT_OF_RANGE; - } - - auto pGltfTexture = &mGltfData->textures[textureIndex]; - if (IsNull(pGltfTexture)) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - GltfLoader::InternalLoadParams loadParams = {}; - loadParams.pDevice = pDevice; - - auto ppxres = LoadTextureInternal( - loadParams, - pGltfTexture, - ppTargetTexture); - if (Failed(ppxres)) { - return ppxres; - } - - return ppx::SUCCESS; -} - -ppx::Result GltfLoader::LoadTexture( - grfx::Device* pDevice, - const std::string& textureName, - scene::Texture** ppTargetTexture) -{ - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - int32_t textureIndex = this->GetTextureIndex(textureName); - if (textureIndex < 0) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - return LoadTexture( - pDevice, - static_cast(textureIndex), - ppTargetTexture); -} - -ppx::Result GltfLoader::LoadMaterial( - grfx::Device* pDevice, - uint32_t materialIndex, - scene::Material** ppTargetMaterial, - const scene::LoadOptions& loadOptions) -{ - if (IsNull(pDevice)) { - return ppx::ERROR_UNEXPECTED_NULL_ARGUMENT; - } - - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - if (materialIndex >= static_cast(mGltfData->samplers_count)) { - return ppx::ERROR_OUT_OF_RANGE; - } - - auto pGltfMaterial = &mGltfData->materials[materialIndex]; - if (IsNull(pGltfMaterial)) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - GltfLoader::InternalLoadParams loadParams = {}; - loadParams.pDevice = pDevice; - - auto ppxres = LoadMaterialInternal( - loadParams, - pGltfMaterial, - ppTargetMaterial); - if (Failed(ppxres)) { - return ppxres; - } - - return ppx::SUCCESS; -} - -ppx::Result GltfLoader::LoadMaterial( - grfx::Device* pDevice, - const std::string& materialName, - scene::Material** ppTargetMaterial, - const scene::LoadOptions& loadOptions) -{ - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - int32_t materialIndex = this->GetMaterialIndex(materialName); - if (materialIndex < 0) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - return LoadMaterial( - pDevice, - static_cast(materialIndex), - ppTargetMaterial, - loadOptions); -} - -ppx::Result GltfLoader::LoadMesh( - grfx::Device* pDevice, - uint32_t meshIndex, - scene::Mesh** ppTargetMesh, - const scene::LoadOptions& loadOptions) -{ - if (IsNull(pDevice)) { - return ppx::ERROR_UNEXPECTED_NULL_ARGUMENT; - } - - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - if (meshIndex >= static_cast(mGltfData->meshes_count)) { - return ppx::ERROR_OUT_OF_RANGE; - } - - auto pGltfMesh = &mGltfData->meshes[meshIndex]; - if (IsNull(pGltfMesh)) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - GltfLoader::InternalLoadParams loadParams = {}; - loadParams.pDevice = pDevice; - loadParams.pMaterialFactory = loadOptions.GetMaterialFactory(); - loadParams.requiredVertexAttributes = loadOptions.GetRequiredAttributes(); - - // Use default material factory if one wasn't supplied - if (IsNull(loadParams.pMaterialFactory)) { - loadParams.pMaterialFactory = &mDefaultMaterialFactory; - } - - auto ppxres = LoadMeshInternal( - loadParams, - pGltfMesh, - ppTargetMesh); - if (Failed(ppxres)) { - return ppxres; - } - - return ppx::SUCCESS; -} - -ppx::Result GltfLoader::LoadMesh( - grfx::Device* pDevice, - const std::string& meshName, - scene::Mesh** ppTargetMesh, - const scene::LoadOptions& loadOptions) -{ - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - int32_t meshIndex = this->GetMeshIndex(meshName); - if (meshIndex < 0) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - return LoadMesh( - pDevice, - static_cast(meshIndex), - ppTargetMesh, - loadOptions); -} - -ppx::Result GltfLoader::LoadNode( - grfx::Device* pDevice, - uint32_t nodeIndex, - scene::Node** ppTargetNode, - const scene::LoadOptions& loadOptions) -{ - if (IsNull(pDevice)) { - return ppx::ERROR_UNEXPECTED_NULL_ARGUMENT; - } - - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - if (nodeIndex >= static_cast(mGltfData->nodes_count)) { - return ppx::ERROR_OUT_OF_RANGE; - } - - auto pGltNode = &mGltfData->nodes[nodeIndex]; - if (IsNull(pGltNode)) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - GltfLoader::InternalLoadParams loadParams = {}; - loadParams.pDevice = pDevice; - loadParams.pMaterialFactory = loadOptions.GetMaterialFactory(); - loadParams.requiredVertexAttributes = loadOptions.GetRequiredAttributes(); - - // Use default material factory if one wasn't supplied - if (IsNull(loadParams.pMaterialFactory)) { - loadParams.pMaterialFactory = &mDefaultMaterialFactory; - } - - auto ppxres = LoadNodeInternal( - loadParams, - pGltNode, - ppTargetNode); - if (Failed(ppxres)) { - return ppxres; - } - - return SUCCESS; -} - -ppx::Result GltfLoader::LoadNode( - grfx::Device* pDevice, - const std::string& nodeName, - scene::Node** ppTargetNode, - const scene::LoadOptions& loadOptions) -{ - if (IsNull(pDevice)) { - return ppx::ERROR_UNEXPECTED_NULL_ARGUMENT; - } - - int32_t nodeIndex = this->GetNodeIndex(nodeName); - if (nodeIndex < 0) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - return LoadNode( - pDevice, - static_cast(nodeIndex), - ppTargetNode, - loadOptions); -} - -ppx::Result GltfLoader::LoadNodeTransformOnly( - uint32_t nodeIndex, - scene::Node** ppTargetNode) -{ - if (!HasGltfData()) { - return ppx::ERROR_SCENE_NO_SOURCE_DATA; - } - - if (nodeIndex >= static_cast(mGltfData->nodes_count)) { - return ppx::ERROR_OUT_OF_RANGE; - } - - auto pGltNode = &mGltfData->nodes[nodeIndex]; - if (IsNull(pGltNode)) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - GltfLoader::InternalLoadParams loadParams = {}; - loadParams.transformOnly = true; - - auto ppxres = LoadNodeInternal( - loadParams, - pGltNode, - ppTargetNode); - if (Failed(ppxres)) { - return ppxres; - } - - return SUCCESS; -} - -ppx::Result GltfLoader::LoadNodeTransformOnly( - const std::string& nodeName, - scene::Node** ppTargetNode) -{ - int32_t nodeIndex = this->GetNodeIndex(nodeName); - if (nodeIndex < 0) { - return ppx::ERROR_ELEMENT_NOT_FOUND; - } - - return LoadNodeTransformOnly( - static_cast(nodeIndex), - ppTargetNode); -} - ppx::Result GltfLoader::LoadScene( grfx::Device* pDevice, uint32_t sceneIndex, @@ -2925,7 +2389,6 @@ ppx::Result GltfLoader::LoadScene( GltfLoader::InternalLoadParams loadParams = {}; loadParams.pDevice = pDevice; loadParams.pMaterialFactory = loadOptions.GetMaterialFactory(); - loadParams.requiredVertexAttributes = loadOptions.GetRequiredAttributes(); // Use default material factory if one wasn't supplied if (IsNull(loadParams.pMaterialFactory)) {