diff --git a/Axiom/Assets/AssetCooker.cpp b/Axiom/Assets/AssetCooker.cpp index 5489a97a..00196ffb 100644 --- a/Axiom/Assets/AssetCooker.cpp +++ b/Axiom/Assets/AssetCooker.cpp @@ -92,13 +92,56 @@ CookMeshAsset(const std::filesystem::path &ContentRoot, return std::nullopt; } - const auto Scene = LoadBasicMeshAsset(SourcePath); + const auto Scene = LoadBasicMeshAssetFromSource(SourcePath); if (!Scene.has_value()) { A_CORE_WARN("AssetCooker: failed to import source mesh '{}'", SourcePath.string()); return std::nullopt; } + MeshSceneData CookedScene = *Scene; + std::vector MaterialAssetPaths(CookedScene.Instances.size()); + const std::string AssetStem = RelativeAssetPath.stem().generic_string(); + for (size_t InstanceIndex = 0; InstanceIndex < CookedScene.Instances.size(); + ++InstanceIndex) { + auto &Instance = CookedScene.Instances[InstanceIndex]; + if (!Instance.Material) { + continue; + } + + std::string TextureAssetPath; + if (Instance.Material->BaseColorTexture && + Instance.Material->BaseColorTexture->IsValid()) { + const std::filesystem::path RelativeTexturePath = + std::filesystem::path("Generated/MeshTextures") / + (AssetStem + "__" + std::to_string(InstanceIndex)); + const auto TextureEntry = CookTextureAsset( + ContentRoot, RelativeTexturePath, *Instance.Material->BaseColorTexture); + if (TextureEntry.has_value()) { + TextureAssetPath = TextureEntry->RelativePath; + } + } else if (!Instance.Material->TextureAssetPath.empty()) { + const auto TextureEntry = + CookTextureAsset(ContentRoot, Instance.Material->TextureAssetPath); + if (TextureEntry.has_value()) { + TextureAssetPath = TextureEntry->RelativePath; + } + } + + const std::filesystem::path RelativeMaterialPath = + std::filesystem::path("Generated/MeshMaterials") / + (AssetStem + "__" + std::to_string(InstanceIndex)); + const auto MaterialEntry = CookMaterialAsset( + ContentRoot, RelativeMaterialPath, + {.BaseColorFactor = Instance.Material->BaseColorFactor, + .Metallic = Instance.Material->Metallic, + .Roughness = Instance.Material->Roughness, + .TextureAssetPath = TextureAssetPath}); + if (MaterialEntry.has_value()) { + MaterialAssetPaths[InstanceIndex] = MaterialEntry->RelativePath; + } + } + const std::filesystem::path CookedRelativePath = BuildCookedMeshRelativePath(RelativeAssetPath); const std::filesystem::path CookedAbsolutePath = ContentRoot / CookedRelativePath; @@ -110,8 +153,20 @@ CookMeshAsset(const std::filesystem::path &ContentRoot, return std::nullopt; } - if (!SaveCookedMeshAsset(CookedAbsolutePath, ToCookedMeshSceneData(*Scene), - Asset)) { + CookedMeshSceneData BinaryScene; + BinaryScene.Instances.reserve(CookedScene.Instances.size()); + for (size_t InstanceIndex = 0; InstanceIndex < CookedScene.Instances.size(); + ++InstanceIndex) { + const auto &Instance = CookedScene.Instances[InstanceIndex]; + BinaryScene.Instances.push_back({ + .Name = Instance.Name, + .MaterialAssetPath = MaterialAssetPaths[InstanceIndex], + .Mesh = Instance.Mesh, + .Transform = Instance.Transform, + }); + } + + if (!SaveCookedMeshAsset(CookedAbsolutePath, BinaryScene, Asset)) { return std::nullopt; } @@ -140,7 +195,6 @@ CookMeshAsset(const std::filesystem::path &ContentRoot, std::optional CookTextureAsset(const std::filesystem::path &ContentRoot, const std::filesystem::path &RelativeAssetPath) { - const AssetId Asset = AssetIdFromRelativePath(RelativeAssetPath); const std::filesystem::path SourcePath = ContentRoot / RelativeAssetPath; const auto SourceHash = HashFileContents(SourcePath); if (!SourceHash.has_value()) { @@ -156,8 +210,22 @@ CookTextureAsset(const std::filesystem::path &ContentRoot, return std::nullopt; } + return CookTextureAsset(ContentRoot, RelativeAssetPath, *Texture); +} + +std::optional +CookTextureAsset(const std::filesystem::path &ContentRoot, + const std::filesystem::path &RelativeTexturePath, + const TextureSourceData &Texture) { + const AssetId Asset = AssetIdFromRelativePath(RelativeTexturePath); + if (!Texture.IsValid()) { + A_CORE_WARN("AssetCooker: invalid generated texture '{}'", + RelativeTexturePath.string()); + return std::nullopt; + } + const std::filesystem::path CookedRelativePath = - BuildCookedTextureRelativePath(RelativeAssetPath); + BuildCookedTextureRelativePath(RelativeTexturePath); const std::filesystem::path CookedAbsolutePath = ContentRoot / CookedRelativePath; std::error_code Ec; std::filesystem::create_directories(CookedAbsolutePath.parent_path(), Ec); @@ -167,7 +235,7 @@ CookTextureAsset(const std::filesystem::path &ContentRoot, return std::nullopt; } - if (!SaveCookedTextureAsset(CookedAbsolutePath, *Texture, Asset)) { + if (!SaveCookedTextureAsset(CookedAbsolutePath, Texture, Asset)) { return std::nullopt; } @@ -176,13 +244,17 @@ CookTextureAsset(const std::filesystem::path &ContentRoot, AssetCookManifest Manifest = LoadAssetCookManifest(ManifestPath).value_or(AssetCookManifest{}); + const uint64_t SourceHash = HashString(std::to_string(Texture.Width) + "|" + + std::to_string(Texture.Height) + "|" + + std::to_string(Texture.Pixels.size())); + AssetCookManifestEntry Entry{ .Id = Asset, .Kind = AssetKind::Texture, - .RelativePath = RelativeAssetPath.generic_string(), + .RelativePath = RelativeTexturePath.generic_string(), .CookedPath = CookedRelativePath.generic_string(), .FormatVersion = kCookedTextureFormatVersion, - .SourceHash = *SourceHash, + .SourceHash = SourceHash, }; UpsertManifestEntry(Manifest, Entry); diff --git a/Axiom/Assets/AssetCooker.h b/Axiom/Assets/AssetCooker.h index c60c0da5..bf130e56 100644 --- a/Axiom/Assets/AssetCooker.h +++ b/Axiom/Assets/AssetCooker.h @@ -2,6 +2,7 @@ #include "Assets/AssetCookManifest.h" #include "Assets/CookedMaterialAsset.h" +#include "Renderer/Material.h" #include #include @@ -20,6 +21,13 @@ std::optional CookTextureAsset(const std::filesystem::path &ContentRoot, const std::filesystem::path &RelativeAssetPath); +// Writes generated cooked texture state under Content/Cooked and updates the +// cook manifest for the provided logical texture path. +std::optional +CookTextureAsset(const std::filesystem::path &ContentRoot, + const std::filesystem::path &RelativeTexturePath, + const TextureSourceData &Texture); + // Writes generated cooked material state under Content/Cooked and updates the // cook manifest for the provided logical material path. std::optional diff --git a/Axiom/Assets/CookedAssetRuntime.cpp b/Axiom/Assets/CookedAssetRuntime.cpp index 3d50c21b..8dc588b5 100644 --- a/Axiom/Assets/CookedAssetRuntime.cpp +++ b/Axiom/Assets/CookedAssetRuntime.cpp @@ -58,7 +58,7 @@ LoadCookedMeshAssetIfAvailable(const std::filesystem::path &Path) { return std::nullopt; } - return ToRuntimeMeshSceneData(*CookedScene); + return ToRuntimeMeshSceneData(*CookedScene, *ContentRoot); } TextureSourceDataRef diff --git a/Axiom/Assets/CookedMeshAsset.cpp b/Axiom/Assets/CookedMeshAsset.cpp index 05b29b1a..c44c8246 100644 --- a/Axiom/Assets/CookedMeshAsset.cpp +++ b/Axiom/Assets/CookedMeshAsset.cpp @@ -1,5 +1,8 @@ #include "CookedMeshAsset.h" +#include "Assets/CookedAssetRuntime.h" +#include "Assets/CookedMaterialAsset.h" +#include "Assets/MeshAsset.h" #include "Core/Log.h" #include @@ -21,6 +24,16 @@ struct FileHeader { }; struct InstanceHeader { + uint32_t NameLength; + uint32_t MaterialAssetPathLength; + uint32_t VertexCount; + uint32_t IndexCount; + std::array BoundsMin; + std::array BoundsMax; + std::array Transform; +}; + +struct InstanceHeaderV1 { uint32_t NameLength; uint32_t VertexCount; uint32_t IndexCount; @@ -31,6 +44,7 @@ struct InstanceHeader { static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_copyable_v); +static_assert(std::is_trivially_copyable_v); template bool WriteValue(std::ofstream &Stream, const T &Value) { @@ -87,6 +101,8 @@ bool SaveCookedMeshAsset(const std::filesystem::path &Path, for (const auto &Instance : Scene.Instances) { const InstanceHeader InstanceMeta{ .NameLength = static_cast(Instance.Name.size()), + .MaterialAssetPathLength = + static_cast(Instance.MaterialAssetPath.size()), .VertexCount = static_cast(Instance.Mesh.Vertices.size()), .IndexCount = static_cast(Instance.Mesh.Indices.size()), .BoundsMin = {Instance.Mesh.BoundsMin.x, Instance.Mesh.BoundsMin.y, @@ -105,6 +121,14 @@ bool SaveCookedMeshAsset(const std::filesystem::path &Path, return false; } + if (!Instance.MaterialAssetPath.empty()) { + Stream.write(Instance.MaterialAssetPath.data(), + static_cast( + Instance.MaterialAssetPath.size())); + if (!Stream.good()) + return false; + } + if (!Instance.Mesh.Vertices.empty()) { Stream.write( reinterpret_cast(Instance.Mesh.Vertices.data()), @@ -145,7 +169,7 @@ LoadCookedMeshAsset(const std::filesystem::path &Path) { return std::nullopt; } - if (Header.Version != kCookedMeshFormatVersion) { + if (Header.Version != 1 && Header.Version != kCookedMeshFormatVersion) { A_CORE_WARN("CookedMeshAsset: unsupported version {} in '{}'", Header.Version, Path.string()); return std::nullopt; @@ -157,7 +181,21 @@ LoadCookedMeshAsset(const std::filesystem::path &Path) { for (uint32_t InstanceIndex = 0; InstanceIndex < Header.InstanceCount; ++InstanceIndex) { InstanceHeader InstanceMeta{}; - if (!ReadValue(Stream, InstanceMeta)) { + if (Header.Version == 1) { + InstanceHeaderV1 LegacyMeta{}; + if (!ReadValue(Stream, LegacyMeta)) { + A_CORE_WARN("CookedMeshAsset: failed to read instance header from '{}'", + Path.string()); + return std::nullopt; + } + InstanceMeta.NameLength = LegacyMeta.NameLength; + InstanceMeta.MaterialAssetPathLength = 0; + InstanceMeta.VertexCount = LegacyMeta.VertexCount; + InstanceMeta.IndexCount = LegacyMeta.IndexCount; + InstanceMeta.BoundsMin = LegacyMeta.BoundsMin; + InstanceMeta.BoundsMax = LegacyMeta.BoundsMax; + InstanceMeta.Transform = LegacyMeta.Transform; + } else if (!ReadValue(Stream, InstanceMeta)) { A_CORE_WARN("CookedMeshAsset: failed to read instance header from '{}'", Path.string()); return std::nullopt; @@ -172,6 +210,16 @@ LoadCookedMeshAsset(const std::filesystem::path &Path) { return std::nullopt; } + if (Header.Version >= 2 && InstanceMeta.MaterialAssetPathLength > 0) { + Instance.MaterialAssetPath.resize(InstanceMeta.MaterialAssetPathLength); + Stream.read(Instance.MaterialAssetPath.data(), + static_cast( + Instance.MaterialAssetPath.size())); + if (!Stream.good()) { + return std::nullopt; + } + } + Instance.Mesh.Vertices.resize(InstanceMeta.VertexCount); if (InstanceMeta.VertexCount > 0) { Stream.read(reinterpret_cast(Instance.Mesh.Vertices.data()), @@ -209,6 +257,7 @@ CookedMeshSceneData ToCookedMeshSceneData(const MeshSceneData &Scene) { for (const auto &Instance : Scene.Instances) { Out.Instances.push_back({ .Name = Instance.Name, + .MaterialAssetPath = {}, .Mesh = Instance.Mesh, .Transform = Instance.Transform, }); @@ -216,14 +265,31 @@ CookedMeshSceneData ToCookedMeshSceneData(const MeshSceneData &Scene) { return Out; } -MeshSceneData ToRuntimeMeshSceneData(const CookedMeshSceneData &Scene) { +MeshSceneData ToRuntimeMeshSceneData(const CookedMeshSceneData &Scene, + const std::filesystem::path &ContentRoot) { MeshSceneData Out; Out.Instances.reserve(Scene.Instances.size()); for (const auto &Instance : Scene.Instances) { + auto Material = std::make_shared(); + if (!Instance.MaterialAssetPath.empty()) { + const auto CookedMaterial = + LoadCookedMaterialAssetIfAvailable(ContentRoot / + Instance.MaterialAssetPath); + if (CookedMaterial.has_value()) { + Material->BaseColorFactor = CookedMaterial->BaseColorFactor; + Material->Metallic = CookedMaterial->Metallic; + Material->Roughness = CookedMaterial->Roughness; + Material->TextureAssetPath = CookedMaterial->TextureAssetPath; + if (!CookedMaterial->TextureAssetPath.empty()) { + Material->BaseColorTexture = + LoadTextureFromFile(ContentRoot / CookedMaterial->TextureAssetPath); + } + } + } Out.Instances.push_back({ .Name = Instance.Name, .Mesh = Instance.Mesh, - .Material = std::make_shared(), + .Material = std::move(Material), .Transform = Instance.Transform, }); } diff --git a/Axiom/Assets/CookedMeshAsset.h b/Axiom/Assets/CookedMeshAsset.h index c11d6740..8297393f 100644 --- a/Axiom/Assets/CookedMeshAsset.h +++ b/Axiom/Assets/CookedMeshAsset.h @@ -10,11 +10,12 @@ namespace Axiom::Assets { -constexpr uint32_t kCookedMeshFormatVersion = 1; +constexpr uint32_t kCookedMeshFormatVersion = 2; struct CookedMeshSceneData { struct InstanceData { std::string Name; + std::string MaterialAssetPath; MeshData Mesh; glm::mat4 Transform{1.0f}; }; @@ -30,6 +31,7 @@ std::optional LoadCookedMeshAsset(const std::filesystem::path &Path); CookedMeshSceneData ToCookedMeshSceneData(const MeshSceneData &Scene); -MeshSceneData ToRuntimeMeshSceneData(const CookedMeshSceneData &Scene); +MeshSceneData ToRuntimeMeshSceneData(const CookedMeshSceneData &Scene, + const std::filesystem::path &ContentRoot); } // namespace Axiom::Assets diff --git a/Axiom/Assets/MeshAsset.cpp b/Axiom/Assets/MeshAsset.cpp index cdefd488..332d4258 100644 --- a/Axiom/Assets/MeshAsset.cpp +++ b/Axiom/Assets/MeshAsset.cpp @@ -524,7 +524,9 @@ std::optional LoadBasicMeshAsset(const std::filesystem::path &Pat if (!CookedScene.has_value()) { return std::nullopt; } - return ToRuntimeMeshSceneData(*CookedScene); + const auto ContentRoot = FindContentRootForPath(Path); + return ToRuntimeMeshSceneData(*CookedScene, + ContentRoot.value_or(Path.parent_path())); } if (auto CookedScene = LoadCookedMeshAssetIfAvailable(Path); diff --git a/Axiom/Assets/SceneFile.cpp b/Axiom/Assets/SceneFile.cpp index 3a0697bc..03c93ff0 100644 --- a/Axiom/Assets/SceneFile.cpp +++ b/Axiom/Assets/SceneFile.cpp @@ -4,7 +4,9 @@ #include "Assets/MeshAsset.h" #include "Core/Log.h" +#include #include +#include #include #include @@ -46,6 +48,44 @@ std::string SerializeVec3(const glm::vec3 &V) { return S.str(); } +std::string SanitizeGeneratedAssetToken(std::string_view Value) { + std::string Out; + Out.reserve(Value.size()); + for (const char Character : Value) { + if ((Character >= 'a' && Character <= 'z') || + (Character >= 'A' && Character <= 'Z') || + (Character >= '0' && Character <= '9')) { + Out.push_back(Character); + } else { + Out.push_back('_'); + } + } + + while (!Out.empty() && Out.back() == '_') { + Out.pop_back(); + } + + if (Out.empty()) { + return "mesh"; + } + return Out; +} + +std::string BuildGeneratedAssetChildId(std::string_view RootObjectId, + std::string_view InstanceName, + size_t InstanceIndex) { + return std::string(RootObjectId) + "__asset_" + std::to_string(InstanceIndex) + + "_" + SanitizeGeneratedAssetToken(InstanceName); +} + +std::string ResolveGeneratedAssetChildDisplayName(std::string_view InstanceName, + size_t InstanceIndex) { + if (!InstanceName.empty()) { + return std::string(InstanceName); + } + return "Mesh " + std::to_string(InstanceIndex + 1); +} + std::filesystem::path ResolveContentRootForScenePath( const std::filesystem::path &ScenePath) { if (const auto ContentRoot = FindContentRootForPath(ScenePath); @@ -69,8 +109,13 @@ const char *KindStr(EditorSceneItemKind K) { void SerializeSceneItemsFlat( std::ostringstream &Out, const std::vector &Items, + const std::unordered_map &DetailsById, const std::string &ParentId, bool &First) { for (const auto &Item : Items) { + const auto DetailsIt = DetailsById.find(Item.Id); + if (DetailsIt != DetailsById.end() && DetailsIt->second.IsGeneratedAssetChild) { + continue; + } if (!First) Out << ",\n"; First = false; Out << " {\"id\":" << EscStr(Item.Id) @@ -78,7 +123,192 @@ void SerializeSceneItemsFlat( << ",\"displayName\":" << EscStr(Item.DisplayName) << ",\"kind\":\"" << KindStr(Item.Kind) << "\"" << ",\"visible\":" << (Item.Visible ? "true" : "false") << "}"; - SerializeSceneItemsFlat(Out, Item.Children, Item.Id, First); + SerializeSceneItemsFlat(Out, Item.Children, DetailsById, Item.Id, First); + } +} + +EditorSceneItem *FindSceneItemMutable(std::vector &Items, + std::string_view ObjectId) { + for (auto &Item : Items) { + if (Item.Id == ObjectId) { + return &Item; + } + if (auto *Found = FindSceneItemMutable(Item.Children, ObjectId)) { + return Found; + } + } + return nullptr; +} + +glm::mat4 BuildTransformMatrix(const EditorTransformDetails &Transform) { + glm::mat4 Matrix(1.0f); + Matrix = glm::translate(Matrix, Transform.Location); + Matrix = glm::rotate(Matrix, glm::radians(Transform.RotationDegrees.y), + glm::vec3(0.0f, 1.0f, 0.0f)); + Matrix = glm::rotate(Matrix, glm::radians(Transform.RotationDegrees.x), + glm::vec3(1.0f, 0.0f, 0.0f)); + Matrix = glm::rotate(Matrix, glm::radians(Transform.RotationDegrees.z), + glm::vec3(0.0f, 0.0f, 1.0f)); + Matrix = glm::scale(Matrix, Transform.Scale); + return Matrix; +} + +EditorTransformDetails DecomposeMatrix(const glm::mat4 &Matrix) { + const glm::vec3 Location = glm::vec3(Matrix[3]); + glm::vec3 Col0 = glm::vec3(Matrix[0]); + glm::vec3 Col1 = glm::vec3(Matrix[1]); + glm::vec3 Col2 = glm::vec3(Matrix[2]); + const float ScaleX = glm::length(Col0); + const float ScaleY = glm::length(Col1); + const float ScaleZ = glm::length(Col2); + if (ScaleX > 0.0f) Col0 /= ScaleX; + if (ScaleY > 0.0f) Col1 /= ScaleY; + if (ScaleZ > 0.0f) Col2 /= ScaleZ; + const float AngleX = glm::degrees(glm::asin(glm::clamp(-Col2.y, -1.0f, 1.0f))); + const float AngleY = glm::degrees(glm::atan(Col2.x, Col2.z)); + const float AngleZ = glm::degrees(glm::atan(Col0.y, Col1.y)); + return EditorTransformDetails{ + .Location = Location, + .RotationDegrees = {AngleX, AngleY, AngleZ}, + .Scale = {ScaleX, ScaleY, ScaleZ}, + }; +} + +void ExpandMeshAssetIntoScene(EditorSceneState &State, std::string_view RootObjectId, + const MeshSceneData &SceneData, + std::string_view AssetPath) { + auto DetailsIt = State.ObjectDetailsById.find(std::string(RootObjectId)); + if (DetailsIt == State.ObjectDetailsById.end()) { + return; + } + + EditorObjectDetails &RootDetails = DetailsIt->second; + RootDetails.IsGeneratedAssetChild = false; + RootDetails.GeneratedFromAssetRootId = std::nullopt; + RootDetails.AssetRelativePath = std::string(AssetPath); + + auto *RootItem = FindSceneItemMutable(State.Items, RootObjectId); + if (RootItem == nullptr) { + return; + } + + std::vector GeneratedChildIds; + for (const auto &[ObjectId, Details] : State.ObjectDetailsById) { + if (Details.IsGeneratedAssetChild && + Details.GeneratedFromAssetRootId.has_value() && + *Details.GeneratedFromAssetRootId == RootObjectId) { + GeneratedChildIds.push_back(ObjectId); + } + } + + for (const std::string &ChildId : GeneratedChildIds) { + State.ObjectDetailsById.erase(ChildId); + State.MeshInstances.erase( + std::remove_if(State.MeshInstances.begin(), State.MeshInstances.end(), + [&](const EditorSceneMeshInstance &Instance) { + return Instance.ObjectId == ChildId; + }), + State.MeshInstances.end()); + } + + RootItem->Children.erase( + std::remove_if( + RootItem->Children.begin(), RootItem->Children.end(), + [&](const EditorSceneItem &Child) { + const auto It = State.ObjectDetailsById.find(Child.Id); + return It == State.ObjectDetailsById.end() || + (It->second.IsGeneratedAssetChild && + It->second.GeneratedFromAssetRootId.has_value() && + *It->second.GeneratedFromAssetRootId == RootObjectId); + }), + RootItem->Children.end()); + + State.MeshInstances.erase( + std::remove_if(State.MeshInstances.begin(), State.MeshInstances.end(), + [&](const EditorSceneMeshInstance &Instance) { + return Instance.ObjectId == RootObjectId; + }), + State.MeshInstances.end()); + + if (SceneData.Instances.size() == 1) { + const auto &First = SceneData.Instances.front(); + RootDetails.Material = First.Material + ? std::optional( + EditorMaterialProperties{ + .BaseColorFactor = + First.Material->BaseColorFactor, + .Metallic = First.Material->Metallic, + .Roughness = First.Material->Roughness, + .TextureAssetPath = + First.Material->TextureAssetPath + .empty() + ? std::nullopt + : std::optional( + First.Material + ->TextureAssetPath), + }) + : std::nullopt; + State.MeshInstances.push_back({ + .ObjectId = std::string(RootObjectId), + .Mesh = First.Mesh, + .Material = First.Material, + .RenderPath = MeshRenderPath::Graphics, + .Transform = glm::mat4(1.0f), + .AssetRelativePath = std::string(AssetPath), + }); + return; + } + + RootDetails.Material = std::nullopt; + + for (size_t InstanceIndex = 0; InstanceIndex < SceneData.Instances.size(); + ++InstanceIndex) { + const auto &SourceInstance = SceneData.Instances[InstanceIndex]; + const std::string ChildId = BuildGeneratedAssetChildId( + RootObjectId, SourceInstance.Name, InstanceIndex); + State.ObjectDetailsById[ChildId] = EditorObjectDetails{ + .ObjectId = ChildId, + .DisplayName = ResolveGeneratedAssetChildDisplayName( + SourceInstance.Name, InstanceIndex), + .Kind = EditorSceneItemKind::Mesh, + .Visible = RootDetails.Visible, + .IsGeneratedAssetChild = true, + .SupportsTransform = true, + .TransformReadOnly = true, + .Transform = DecomposeMatrix(SourceInstance.Transform), + .Material = SourceInstance.Material + ? std::optional( + EditorMaterialProperties{ + .BaseColorFactor = + SourceInstance.Material->BaseColorFactor, + .Metallic = SourceInstance.Material->Metallic, + .Roughness = + SourceInstance.Material->Roughness, + .TextureAssetPath = + SourceInstance.Material->TextureAssetPath + .empty() + ? std::nullopt + : std::optional( + SourceInstance.Material + ->TextureAssetPath), + }) + : std::nullopt, + .GeneratedFromAssetRootId = std::string(RootObjectId), + }; + RootItem->Children.push_back({ + .Id = ChildId, + .DisplayName = ResolveGeneratedAssetChildDisplayName( + SourceInstance.Name, InstanceIndex), + .Kind = EditorSceneItemKind::Mesh, + .Visible = RootDetails.Visible, + }); + State.MeshInstances.push_back({ + .ObjectId = ChildId, + .Mesh = SourceInstance.Mesh, + .Material = SourceInstance.Material, + .RenderPath = MeshRenderPath::Graphics, + .Transform = SourceInstance.Transform, + }); } } @@ -91,36 +321,57 @@ void SerializeSceneItemsFlat( bool SaveSceneToFile(const std::filesystem::path &Path, const EditorSceneState &Scene) { const std::filesystem::path ContentRoot = ResolveContentRootForScenePath(Path); - - // Build per-object asset path lookup from MeshInstances. std::unordered_map AssetPathByObjectId; - for (const auto &Inst : Scene.MeshInstances) { - if (!Inst.AssetRelativePath.empty()) { - AssetPathByObjectId[Inst.ObjectId] = Inst.AssetRelativePath; + for (const auto &[ObjectId, Details] : Scene.ObjectDetailsById) { + if (!Details.AssetRelativePath.empty()) { + AssetPathByObjectId.emplace(ObjectId, Details.AssetRelativePath); + } + } + for (const auto &Instance : Scene.MeshInstances) { + if (!Instance.AssetRelativePath.empty()) { + AssetPathByObjectId[Instance.ObjectId] = Instance.AssetRelativePath; + } + } + bool HasImplicitGlobalMeshAsset = false; + for (const auto &Instance : Scene.MeshInstances) { + const auto DetailsIt = Scene.ObjectDetailsById.find(Instance.ObjectId); + if (DetailsIt == Scene.ObjectDetailsById.end() || + DetailsIt->second.IsGeneratedAssetChild) { + continue; + } + if (AssetPathByObjectId.find(Instance.ObjectId) == AssetPathByObjectId.end()) { + HasImplicitGlobalMeshAsset = true; + break; } } std::ostringstream Out; Out << "{\n"; Out << " \"version\": 1,\n"; - Out << " \"meshAsset\": \"basicmesh.glb\",\n"; + Out << " \"meshAsset\": " + << EscStr(HasImplicitGlobalMeshAsset ? "basicmesh.glb" : "") << ",\n"; // Flat node list (scene tree + parent links) Out << " \"nodes\": [\n"; bool FirstNode = true; - SerializeSceneItemsFlat(Out, Scene.Items, "", FirstNode); + SerializeSceneItemsFlat(Out, Scene.Items, Scene.ObjectDetailsById, "", FirstNode); Out << "\n ],\n"; // Object details (transforms, visibility, mesh name mapping) Out << " \"objects\": [\n"; bool FirstObj = true; for (const auto &[Id, Details] : Scene.ObjectDetailsById) { + if (Details.IsGeneratedAssetChild) { + continue; + } if (!FirstObj) Out << ",\n"; FirstObj = false; Out << " {\"id\":" << EscStr(Id) << ",\"displayName\":" << EscStr(Details.DisplayName) << ",\"kind\":\"" << KindStr(Details.Kind) << "\"" << ",\"visible\":" << (Details.Visible ? "true" : "false") + << ",\"isGeneratedAssetChild\":" + << (Details.IsGeneratedAssetChild ? "true" : "false") << ",\"supportsTransform\":" << (Details.SupportsTransform ? "true" : "false") << ",\"transformReadOnly\":" << (Details.TransformReadOnly ? "true" : "false"); if (Details.Transform.has_value()) { @@ -131,6 +382,10 @@ bool SaveSceneToFile(const std::filesystem::path &Path, if (Details.ScriptClass.has_value()) { Out << ",\"scriptClass\":" << EscStr(*Details.ScriptClass); } + if (Details.GeneratedFromAssetRootId.has_value()) { + Out << ",\"generatedFromAssetRootId\":" + << EscStr(*Details.GeneratedFromAssetRootId); + } if (Details.Kind == EditorSceneItemKind::Mesh) { const auto AssetIt = AssetPathByObjectId.find(Id); if (AssetIt != AssetPathByObjectId.end()) { @@ -168,10 +423,14 @@ bool SaveSceneToFile(const std::filesystem::path &Path, Out << " \"meshNameToObjectId\": {\n"; bool FirstMesh = true; for (const auto &Instance : Scene.MeshInstances) { + const auto DetailsIt = Scene.ObjectDetailsById.find(Instance.ObjectId); + if (DetailsIt == Scene.ObjectDetailsById.end() || + DetailsIt->second.IsGeneratedAssetChild) { + continue; + } // We stored the display name as the mesh source name via ResolveStartupObjectId // Look up the display name from ObjectDetailsById - const auto It = Scene.ObjectDetailsById.find(Instance.ObjectId); - if (It == Scene.ObjectDetailsById.end()) continue; + const auto It = DetailsIt; if (!FirstMesh) Out << ",\n"; FirstMesh = false; Out << " " << EscStr(It->second.DisplayName) << ": " << EscStr(Instance.ObjectId); @@ -376,10 +635,12 @@ LoadSceneFromFile(const std::filesystem::path &Path) { std::string DisplayName; EditorSceneItemKind Kind{EditorSceneItemKind::Folder}; bool Visible{true}; + bool IsGeneratedAssetChild{false}; bool SupportsTransform{false}; bool TransformReadOnly{true}; std::optional Transform; std::optional ScriptClass; + std::optional GeneratedFromAssetRootId; std::string AssetRelativePath; std::string MaterialAssetPath; std::string TextureAssetPath; @@ -420,6 +681,7 @@ LoadSceneFromFile(const std::filesystem::path &Path) { if (K == "displayName") { auto V = P.ParseString(); if (V) Data.DisplayName = *V; return true; } if (K == "kind") { auto V = P.ParseString(); if (V) Data.Kind = KindFromStr(*V); return true; } if (K == "visible") { auto V = P.ParseBool(); if (V) Data.Visible = *V; return true; } + if (K == "isGeneratedAssetChild") { auto V = P.ParseBool(); if (V) Data.IsGeneratedAssetChild = *V; return true; } if (K == "supportsTransform"){ auto V = P.ParseBool(); if (V) Data.SupportsTransform = *V; return true; } if (K == "transformReadOnly"){ auto V = P.ParseBool(); if (V) Data.TransformReadOnly = *V; return true; } if (K == "location") { @@ -451,6 +713,11 @@ LoadSceneFromFile(const std::filesystem::path &Path) { if (P.Peek() == 'n') { P.ParseNull(); } else { auto V = P.ParseString(); if (V) Data.ScriptClass = *V; } return true; } + if (K == "generatedFromAssetRootId") { + P.SkipWs(); + if (P.Peek() == 'n') { P.ParseNull(); } else { auto V = P.ParseString(); if (V) Data.GeneratedFromAssetRootId = *V; } + return true; + } if (K == "assetRelativePath") { auto V = P.ParseString(); if (V) Data.AssetRelativePath = *V; return true; } @@ -543,11 +810,14 @@ LoadSceneFromFile(const std::filesystem::path &Path) { Details.DisplayName = Data.DisplayName; Details.Kind = Data.Kind; Details.Visible = Data.Visible; + Details.IsGeneratedAssetChild = Data.IsGeneratedAssetChild; Details.SupportsTransform = Data.SupportsTransform; Details.TransformReadOnly = Data.TransformReadOnly; Details.Transform = Data.Transform; Details.ScriptClass = Data.ScriptClass; Details.Light = Data.Light; + Details.GeneratedFromAssetRootId = Data.GeneratedFromAssetRootId; + Details.AssetRelativePath = Data.AssetRelativePath; State.ObjectDetailsById[Id] = std::move(Details); } @@ -559,25 +829,12 @@ LoadSceneFromFile(const std::filesystem::path &Path) { if (Data.Kind != EditorSceneItemKind::Mesh || Data.AssetRelativePath.empty()) continue; CookMeshAsset(ContentRoot, Data.AssetRelativePath); const auto FullPath = ContentRoot / Data.AssetRelativePath; - const auto SceneData = LoadBasicMeshAsset(FullPath); + auto SceneData = LoadBasicMeshAsset(FullPath); if (!SceneData.has_value() || SceneData->Instances.empty()) { A_CORE_WARN("SceneFile: failed to load asset '{}' for object '{}'", Data.AssetRelativePath, ObjId); continue; } - glm::mat4 Transform = SceneData->Instances[0].Transform; - const auto DetailsIt = State.ObjectDetailsById.find(ObjId); - if (DetailsIt != State.ObjectDetailsById.end() && - DetailsIt->second.Transform.has_value()) { - const auto &T = *DetailsIt->second.Transform; - glm::mat4 M(1.0f); - M = glm::translate(M, T.Location); - M = glm::rotate(M, glm::radians(T.RotationDegrees.y), {0,1,0}); - M = glm::rotate(M, glm::radians(T.RotationDegrees.x), {1,0,0}); - M = glm::rotate(M, glm::radians(T.RotationDegrees.z), {0,0,1}); - M = glm::scale(M, T.Scale); - Transform = M; - } auto Material = SceneData->Instances[0].Material; if (!Data.MaterialAssetPath.empty()) { const auto CookedMaterial = @@ -609,14 +866,9 @@ LoadSceneFromFile(const std::filesystem::path &Path) { Material->TextureAssetPath = Data.TextureAssetPath; } } - State.MeshInstances.push_back({ - .ObjectId = ObjId, - .Mesh = SceneData->Instances[0].Mesh, - .Material = std::move(Material), - .RenderPath = MeshRenderPath::Graphics, - .Transform = Transform, - .AssetRelativePath = Data.AssetRelativePath, - }); + if (SceneData->Instances.size() == 1 && Material != SceneData->Instances[0].Material) { + SceneData->Instances[0].Material = std::move(Material); + } // Propagate textureAssetPath into ObjectDetails so inspector shows it. { const auto DetailsIt = State.ObjectDetailsById.find(ObjId); @@ -644,6 +896,7 @@ LoadSceneFromFile(const std::filesystem::path &Path) { } } } + ExpandMeshAssetIntoScene(State, ObjId, *SceneData, Data.AssetRelativePath); LoadedByAssetPath.insert(ObjId); } @@ -664,13 +917,7 @@ LoadSceneFromFile(const std::filesystem::path &Path) { if (DetailsIt != State.ObjectDetailsById.end() && DetailsIt->second.Transform.has_value()) { const auto &T = *DetailsIt->second.Transform; - glm::mat4 M(1.0f); - M = glm::translate(M, T.Location); - M = glm::rotate(M, glm::radians(T.RotationDegrees.y), {0,1,0}); - M = glm::rotate(M, glm::radians(T.RotationDegrees.x), {1,0,0}); - M = glm::rotate(M, glm::radians(T.RotationDegrees.z), {0,0,1}); - M = glm::scale(M, T.Scale); - Transform = M; + Transform = BuildTransformMatrix(T); } State.MeshInstances.push_back({ diff --git a/Axiom/Renderer/Vulkan/VulkanRendererTypes.h b/Axiom/Renderer/Vulkan/VulkanRendererTypes.h index f9882db6..3b80f0f4 100644 --- a/Axiom/Renderer/Vulkan/VulkanRendererTypes.h +++ b/Axiom/Renderer/Vulkan/VulkanRendererTypes.h @@ -10,7 +10,7 @@ #include namespace Axiom { -constexpr uint32_t MaxMeshSubmissionsPerFrame = 64; +constexpr uint32_t MaxMeshSubmissionsPerFrame = 256; constexpr uint32_t TimestampQueryCount = 4; struct ComputePushConstants { diff --git a/Axiom/Session/EditorSession.cpp b/Axiom/Session/EditorSession.cpp index 2084cce2..e2560eb5 100644 --- a/Axiom/Session/EditorSession.cpp +++ b/Axiom/Session/EditorSession.cpp @@ -178,6 +178,44 @@ bool IsWhitespace(char Value) { Value == '\f' || Value == '\v'; } +std::string SanitizeGeneratedAssetToken(std::string_view Value) { + std::string Out; + Out.reserve(Value.size()); + for (const char Character : Value) { + if ((Character >= 'a' && Character <= 'z') || + (Character >= 'A' && Character <= 'Z') || + (Character >= '0' && Character <= '9')) { + Out.push_back(Character); + } else { + Out.push_back('_'); + } + } + + while (!Out.empty() && Out.back() == '_') { + Out.pop_back(); + } + + if (Out.empty()) { + return "mesh"; + } + return Out; +} + +std::string BuildGeneratedAssetChildId(std::string_view RootObjectId, + std::string_view InstanceName, + size_t InstanceIndex) { + return std::string(RootObjectId) + "__asset_" + std::to_string(InstanceIndex) + + "_" + SanitizeGeneratedAssetToken(InstanceName); +} + +std::string ResolveGeneratedAssetChildDisplayName(std::string_view InstanceName, + size_t InstanceIndex) { + if (!InstanceName.empty()) { + return std::string(InstanceName); + } + return "Mesh " + std::to_string(InstanceIndex + 1); +} + glm::mat4 BuildTransformMatrix(const EditorTransformDetails &Transform) { glm::mat4 Matrix(1.0f); Matrix = glm::translate(Matrix, Transform.Location); @@ -616,6 +654,151 @@ void EditorSession::RemoveSceneObject(std::string_view ObjectId) { m_State.Scene.MeshInstances.end()); } +void EditorSession::RemoveGeneratedAssetChildren(std::string_view RootObjectId) { + Instance *Root = FindInstanceById(m_SceneRoot.get(), RootObjectId); + if (Root == nullptr) { + return; + } + + std::vector GeneratedChildIds; + for (Instance *Child : Root->GetChildren()) { + const auto DetailsIt = m_State.Scene.ObjectDetailsById.find(Child->GetName()); + if (DetailsIt == m_State.Scene.ObjectDetailsById.end()) { + continue; + } + if (!DetailsIt->second.IsGeneratedAssetChild || + !DetailsIt->second.GeneratedFromAssetRootId.has_value() || + *DetailsIt->second.GeneratedFromAssetRootId != RootObjectId) { + continue; + } + GeneratedChildIds.push_back(Child->GetName()); + } + + for (const std::string &ChildId : GeneratedChildIds) { + Instance *Child = FindInstanceById(m_SceneRoot.get(), ChildId); + if (Child == nullptr) { + continue; + } + for (const std::string &DescendantId : CollectDescendantIds(Child)) { + RemoveSceneObject(DescendantId); + ClearSelectionsForObject(DescendantId); + } + Child->Destroy(); + } +} + +void EditorSession::ExpandMeshAssetIntoScene(std::string_view RootObjectId, + const MeshSceneData &SceneData, + std::string_view AssetPath) { + auto DetailsIt = m_State.Scene.ObjectDetailsById.find(std::string(RootObjectId)); + if (DetailsIt == m_State.Scene.ObjectDetailsById.end()) { + return; + } + + Instance *Root = FindInstanceById(m_SceneRoot.get(), RootObjectId); + if (Root == nullptr) { + return; + } + + RemoveGeneratedAssetChildren(RootObjectId); + + m_State.Scene.MeshInstances.erase( + std::remove_if(m_State.Scene.MeshInstances.begin(), + m_State.Scene.MeshInstances.end(), + [&](const EditorSceneMeshInstance &Instance) { + return Instance.ObjectId == RootObjectId; + }), + m_State.Scene.MeshInstances.end()); + + EditorObjectDetails &RootDetails = DetailsIt->second; + RootDetails.IsGeneratedAssetChild = false; + RootDetails.GeneratedFromAssetRootId = std::nullopt; + RootDetails.AssetRelativePath = std::string(AssetPath); + + if (SceneData.Instances.size() == 1) { + const auto &First = SceneData.Instances.front(); + m_State.Scene.MeshInstances.push_back(EditorSceneMeshInstance{ + .ObjectId = std::string(RootObjectId), + .Mesh = First.Mesh, + .Material = First.Material, + .RenderPath = MeshRenderPath::Graphics, + .Transform = glm::mat4(1.0f), + .AssetRelativePath = std::string(AssetPath), + }); + + if (First.Material) { + RootDetails.Material = EditorMaterialProperties{ + .BaseColorFactor = First.Material->BaseColorFactor, + .Metallic = First.Material->Metallic, + .Roughness = First.Material->Roughness, + .TextureAssetPath = First.Material->TextureAssetPath.empty() + ? std::nullopt + : std::optional( + First.Material->TextureAssetPath), + }; + } + SyncItemsFromTree(); + return; + } + + RootDetails.Material = std::nullopt; + + for (size_t InstanceIndex = 0; InstanceIndex < SceneData.Instances.size(); + ++InstanceIndex) { + const auto &SourceInstance = SceneData.Instances[InstanceIndex]; + const std::string ChildId = BuildGeneratedAssetChildId( + RootObjectId, SourceInstance.Name, InstanceIndex); + const std::string ChildDisplayName = ResolveGeneratedAssetChildDisplayName( + SourceInstance.Name, InstanceIndex); + const EditorTransformDetails ChildLocalTransform = + DecomposeMatrix(SourceInstance.Transform); + + m_State.Scene.ObjectDetailsById[ChildId] = EditorObjectDetails{ + .ObjectId = ChildId, + .DisplayName = ChildDisplayName, + .Kind = EditorSceneItemKind::Mesh, + .Visible = RootDetails.Visible, + .IsGeneratedAssetChild = true, + .SupportsTransform = true, + .TransformReadOnly = true, + .Transform = ChildLocalTransform, + .Material = SourceInstance.Material + ? std::optional( + EditorMaterialProperties{ + .BaseColorFactor = + SourceInstance.Material->BaseColorFactor, + .Metallic = SourceInstance.Material->Metallic, + .Roughness = + SourceInstance.Material->Roughness, + .TextureAssetPath = + SourceInstance.Material->TextureAssetPath + .empty() + ? std::nullopt + : std::optional( + SourceInstance.Material + ->TextureAssetPath), + }) + : std::nullopt, + .GeneratedFromAssetRootId = std::string(RootObjectId), + }; + + Instance *Child = CreateInstanceForTemplate("Mesh", ChildId); + if (Child != nullptr) { + Child->SetParent(Root); + } + + m_State.Scene.MeshInstances.push_back(EditorSceneMeshInstance{ + .ObjectId = ChildId, + .Mesh = SourceInstance.Mesh, + .Material = SourceInstance.Material, + .RenderPath = MeshRenderPath::Graphics, + .Transform = SourceInstance.Transform, + }); + } + + SyncItemsFromTree(); +} + void EditorSession::ClearSelectionsForObject(std::string_view ObjectId) { for (auto It = m_State.SelectedObjectIds.begin(); It != m_State.SelectedObjectIds.end();) { @@ -1517,31 +1700,10 @@ void EditorSession::HandleCommand(const QueuedEditorCommand &QueuedCommand, } const auto &First = SceneData->Instances[0]; - - auto MeshIt = std::find_if( - m_State.Scene.MeshInstances.begin(), m_State.Scene.MeshInstances.end(), - [&](const EditorSceneMeshInstance &I) { return I.ObjectId == Command.ObjectId; }); - if (MeshIt == m_State.Scene.MeshInstances.end()) { - // Object was created at runtime (CreateObject) and has no instance yet — add one now. - m_State.Scene.MeshInstances.push_back(EditorSceneMeshInstance{.ObjectId = Command.ObjectId}); - MeshIt = m_State.Scene.MeshInstances.end() - 1; - } - - MeshIt->Mesh = First.Mesh; - MeshIt->Material = First.Material; - MeshIt->AssetRelativePath = Command.AssetPath; - - // Sync material properties on object details so the inspector reflects the new asset's material. - if (First.Material) { - auto DetailsIt = m_State.Scene.ObjectDetailsById.find(Command.ObjectId); - if (DetailsIt != m_State.Scene.ObjectDetailsById.end()) { - DetailsIt->second.Material = EditorMaterialProperties{ - .BaseColorFactor = First.Material->BaseColorFactor, - .Metallic = First.Material->Metallic, - .Roughness = First.Material->Roughness, - }; - } - } + (void)First; + ExpandMeshAssetIntoScene(Command.ObjectId, *SceneData, Command.AssetPath); + RecomputeSubtreeWorldTransforms( + FindInstanceById(m_SceneRoot.get(), Command.ObjectId)); A_CORE_INFO("SetMeshAsset: assigned '{}' to object '{}'", Command.AssetPath, Command.ObjectId); diff --git a/Axiom/Session/EditorSession.h b/Axiom/Session/EditorSession.h index ebbfb675..cd5026ac 100644 --- a/Axiom/Session/EditorSession.h +++ b/Axiom/Session/EditorSession.h @@ -71,6 +71,7 @@ struct EditorObjectDetails { std::string DisplayName; EditorSceneItemKind Kind{EditorSceneItemKind::Mesh}; bool Visible{true}; + bool IsGeneratedAssetChild{false}; bool SupportsTransform{false}; bool TransformReadOnly{true}; std::optional Transform; // local-space @@ -78,6 +79,8 @@ struct EditorObjectDetails { std::optional ScriptClass; // C# script class name (Actors only) std::optional Light; // Light objects only std::optional Material; // Mesh objects only + std::optional GeneratedFromAssetRootId; + std::string AssetRelativePath; // content-relative path when assigned directly to this object }; enum class EditorUserPresenceState { Connected, Away, Disconnected }; @@ -205,6 +208,10 @@ class EditorSession final : public IEditorCommandSink { void RemoveSceneObject(std::string_view ObjectId); void ClearSelectionsForObject(std::string_view ObjectId); void PruneInvalidSelections(); + void RemoveGeneratedAssetChildren(std::string_view RootObjectId); + void ExpandMeshAssetIntoScene(std::string_view RootObjectId, + const MeshSceneData &SceneData, + std::string_view AssetPath); // Instance tree management void InitSceneRoot(); Instance *FindWorldFolder() const; diff --git a/Content/Cooked/AssetCookManifest.json b/Content/Cooked/AssetCookManifest.json index 5eb52fbb..618010e1 100644 --- a/Content/Cooked/AssetCookManifest.json +++ b/Content/Cooked/AssetCookManifest.json @@ -1,9 +1,218 @@ { "entries": [ - {"assetId":6124137011624734461,"kind":"mesh","relativePath":"basicmesh.glb","cookedPath":"Cooked/basicmesh.wmesh","formatVersion":1,"sourceHash":10769525362242101033}, + {"assetId":6124137011624734461,"kind":"mesh","relativePath":"basicmesh.glb","cookedPath":"Cooked/basicmesh.wmesh","formatVersion":2,"sourceHash":10769525362242101033}, {"assetId":18232260332646399803,"kind":"material","relativePath":"Generated/Materials/crate-1","cookedPath":"Cooked/Generated/Materials/crate-1.wmat","formatVersion":1,"sourceHash":7889859340775370464}, {"assetId":813026631983381292,"kind":"texture","relativePath":"Engine/tf2 coconut.jpg","cookedPath":"Cooked/Engine/tf2 coconut.wtex","formatVersion":1,"sourceHash":2819454596902807771}, - {"assetId":13913950202207721753,"kind":"mesh","relativePath":"sponza_atrium_3.glb","cookedPath":"Cooked/sponza_atrium_3.wmesh","formatVersion":1,"sourceHash":13152113367551948137}, - {"assetId":5770549793718642602,"kind":"mesh","relativePath":"structure.glb","cookedPath":"Cooked/structure.wmesh","formatVersion":1,"sourceHash":11410644714278776383} + {"assetId":13913950202207721753,"kind":"mesh","relativePath":"sponza_atrium_3.glb","cookedPath":"Cooked/sponza_atrium_3.wmesh","formatVersion":2,"sourceHash":13152113367551948137}, + {"assetId":5770549793718642602,"kind":"mesh","relativePath":"structure.glb","cookedPath":"Cooked/structure.wmesh","formatVersion":1,"sourceHash":11410644714278776383}, + {"assetId":8949008766911302915,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__0","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__0.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6406691723554709426,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__0","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__0.wmat","formatVersion":1,"sourceHash":12105348316115371814}, + {"assetId":2047440963454411317,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__1","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__1.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":338408498823845738,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__1","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__1.wmat","formatVersion":1,"sourceHash":11937650793961544448}, + {"assetId":2609070077096360103,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__2","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__2.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":2082388146543210735,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__2","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__2.wmat","formatVersion":1,"sourceHash":16410775011811095777}, + {"assetId":12144441902023958388,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__3","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__3.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":17527947539543232506,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__3","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__3.wmat","formatVersion":1,"sourceHash":3416732856032483136}, + {"assetId":14935625733198014204,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__4","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__4.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":2917609430187082044,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__4","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__4.wmat","formatVersion":1,"sourceHash":2122964563376366127}, + {"assetId":8000510243179873760,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__5","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__5.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1833647933708458171,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__5","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__5.wmat","formatVersion":1,"sourceHash":431772422916233084}, + {"assetId":15108022691734276197,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__6","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__6.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":13270350426872169045,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__6","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__6.wmat","formatVersion":1,"sourceHash":1613934549528476018}, + {"assetId":15426782677142257150,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__7","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__7.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":11133723940075140816,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__7","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__7.wmat","formatVersion":1,"sourceHash":1920503734990514352}, + {"assetId":935055086319286039,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__8","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__8.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":9878873497959639324,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__8","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__8.wmat","formatVersion":1,"sourceHash":17514446031319777689}, + {"assetId":6989572634075200210,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__9","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__9.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":15772495388093143928,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__9","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__9.wmat","formatVersion":1,"sourceHash":14637193827494394025}, + {"assetId":9599674849738750772,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__10","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__10.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":2896645638468082733,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__10","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__10.wmat","formatVersion":1,"sourceHash":17362250718079553547}, + {"assetId":14616201166244300419,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__11","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__11.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":5182902489092553603,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__11","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__11.wmat","formatVersion":1,"sourceHash":14699062389568748940}, + {"assetId":13318269828404021151,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__12","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__12.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1381354933644706323,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__12","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__12.wmat","formatVersion":1,"sourceHash":2067503673473807703}, + {"assetId":418041667898929635,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__13","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__13.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":7335716352758067924,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__13","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__13.wmat","formatVersion":1,"sourceHash":3443891746728836002}, + {"assetId":11460860277751759961,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__14","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__14.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":10303325347291496521,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__14","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__14.wmat","formatVersion":1,"sourceHash":11468274840462287699}, + {"assetId":57118869757405117,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__15","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__15.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":4318461462746769796,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__15","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__15.wmat","formatVersion":1,"sourceHash":1988328698587556133}, + {"assetId":5070985410898534162,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__16","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__16.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":13980165142181086485,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__16","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__16.wmat","formatVersion":1,"sourceHash":4937683144631245473}, + {"assetId":536335246703651284,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__17","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__17.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":7387032219278094511,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__17","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__17.wmat","formatVersion":1,"sourceHash":2852633945460346414}, + {"assetId":15686379171003262801,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__18","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__18.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":8720650190583489158,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__18","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__18.wmat","formatVersion":1,"sourceHash":15463314947407387625}, + {"assetId":1412843259362631608,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__19","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__19.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":5685564747107029388,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__19","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__19.wmat","formatVersion":1,"sourceHash":9445146940921157142}, + {"assetId":9192472894437067434,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__20","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__20.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6894865326422565929,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__20","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__20.wmat","formatVersion":1,"sourceHash":14062335024188840592}, + {"assetId":6639126766486840204,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__21","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__21.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":9141098151863153504,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__21","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__21.wmat","formatVersion":1,"sourceHash":7625158974550489513}, + {"assetId":16584590773156486040,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__22","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__22.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":11986908085456801312,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__22","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__22.wmat","formatVersion":1,"sourceHash":9746980511802920792}, + {"assetId":16912923655458696876,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__23","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__23.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":75998186172291003,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__23","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__23.wmat","formatVersion":1,"sourceHash":3761010161796409630}, + {"assetId":16916866212321513280,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__24","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__24.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":12353471030465543246,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__24","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__24.wmat","formatVersion":1,"sourceHash":9327000674952958699}, + {"assetId":2374162152453047656,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__25","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__25.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":10315655477725643010,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__25","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__25.wmat","formatVersion":1,"sourceHash":13800637962277353069}, + {"assetId":6231828774228086012,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__26","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__26.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1489882246957632078,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__26","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__26.wmat","formatVersion":1,"sourceHash":1914889437746598852}, + {"assetId":14835781405174517290,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__27","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__27.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":15777561656369557976,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__27","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__27.wmat","formatVersion":1,"sourceHash":3741971524521780286}, + {"assetId":12365111798863810594,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__28","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__28.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1487016160038041592,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__28","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__28.wmat","formatVersion":1,"sourceHash":16847151654528284207}, + {"assetId":4816640343485796455,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__29","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__29.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":5736582587947684968,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__29","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__29.wmat","formatVersion":1,"sourceHash":3110976458674466213}, + {"assetId":2335489473499343915,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__30","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__30.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":9309213505028262097,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__30","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__30.wmat","formatVersion":1,"sourceHash":6855991421574206476}, + {"assetId":14294178196105835203,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__31","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__31.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":17061688190034129669,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__31","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__31.wmat","formatVersion":1,"sourceHash":11800299738552449015}, + {"assetId":11849761624884880228,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__32","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__32.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":4251901682895947253,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__32","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__32.wmat","formatVersion":1,"sourceHash":926952403814070686}, + {"assetId":11968440148746543500,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__33","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__33.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":12421151130816866460,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__33","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__33.wmat","formatVersion":1,"sourceHash":13849620051997181063}, + {"assetId":9413999610432788887,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__34","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__34.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":13377664948097222989,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__34","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__34.wmat","formatVersion":1,"sourceHash":6745908713292237972}, + {"assetId":3206050910767936484,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__35","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__35.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":884509795584781669,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__35","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__35.wmat","formatVersion":1,"sourceHash":13770668752275295155}, + {"assetId":6560012162369303788,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__36","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__36.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":4560151726280134650,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__36","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__36.wmat","formatVersion":1,"sourceHash":8466891692858494164}, + {"assetId":639270548772163740,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__37","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__37.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":17922609879183352666,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__37","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__37.wmat","formatVersion":1,"sourceHash":4184171774617991775}, + {"assetId":17555800433981341095,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__38","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__38.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":10100035789257866383,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__38","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__38.wmat","formatVersion":1,"sourceHash":16606266445749377162}, + {"assetId":11420437435638758274,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__39","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__39.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":4050580276738303960,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__39","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__39.wmat","formatVersion":1,"sourceHash":15102528717865983540}, + {"assetId":11306607703883254382,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__40","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__40.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":8858843042684904766,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__40","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__40.wmat","formatVersion":1,"sourceHash":13741552318892389879}, + {"assetId":12460855100054038388,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__41","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__41.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":9631852698186271261,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__41","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__41.wmat","formatVersion":1,"sourceHash":588546811845668699}, + {"assetId":3254376880908665827,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__42","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__42.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":16203075113385007226,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__42","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__42.wmat","formatVersion":1,"sourceHash":6413442546387661798}, + {"assetId":9013002783490148122,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__43","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__43.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6530180347153082594,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__43","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__43.wmat","formatVersion":1,"sourceHash":10492985162459293085}, + {"assetId":3548548975956987037,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__44","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__44.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":929704761341936123,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__44","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__44.wmat","formatVersion":1,"sourceHash":775071552424960229}, + {"assetId":12949756596101087740,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__45","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__45.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":12493647735195381543,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__45","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__45.wmat","formatVersion":1,"sourceHash":9139502168056263364}, + {"assetId":7668103232490655480,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__46","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__46.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":3516490016846387337,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__46","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__46.wmat","formatVersion":1,"sourceHash":7930211813925214123}, + {"assetId":7760219078526813804,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__47","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__47.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":9233051403786368865,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__47","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__47.wmat","formatVersion":1,"sourceHash":13377665289041716221}, + {"assetId":952881265951366713,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__48","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__48.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":17259416390395138510,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__48","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__48.wmat","formatVersion":1,"sourceHash":10128547069958724922}, + {"assetId":9958318104475448220,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__49","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__49.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":11108836736635882916,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__49","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__49.wmat","formatVersion":1,"sourceHash":14622359694189615963}, + {"assetId":15478161406022928727,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__50","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__50.wtex","formatVersion":1,"sourceHash":13834509895381492195}, + {"assetId":9089107162248191790,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__50","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__50.wmat","formatVersion":1,"sourceHash":13483825194474164463}, + {"assetId":3072345739054193766,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__51","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__51.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":17465508359896384865,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__51","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__51.wmat","formatVersion":1,"sourceHash":16978121369089822570}, + {"assetId":7268203633730872137,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__52","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__52.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":3244402830141628456,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__52","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__52.wmat","formatVersion":1,"sourceHash":5353180470586327978}, + {"assetId":12748113197778075258,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__53","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__53.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":16306434343215284634,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__53","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__53.wmat","formatVersion":1,"sourceHash":7447515478019148808}, + {"assetId":4519313381700649372,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__54","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__54.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":998295677570452009,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__54","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__54.wmat","formatVersion":1,"sourceHash":12355589836418080625}, + {"assetId":157030763324087685,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__55","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__55.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":5789132488689622967,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__55","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__55.wmat","formatVersion":1,"sourceHash":16892589328850450973}, + {"assetId":9166456867916392735,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__56","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__56.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":18054864403564059647,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__56","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__56.wmat","formatVersion":1,"sourceHash":5829632433907177469}, + {"assetId":11006535976202166325,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__57","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__57.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":5730670853493317779,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__57","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__57.wmat","formatVersion":1,"sourceHash":13505299453285165148}, + {"assetId":12129955814755625773,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__58","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__58.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1732882884677843463,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__58","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__58.wmat","formatVersion":1,"sourceHash":538972629376551351}, + {"assetId":8327526667649131927,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__59","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__59.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":16064301680766859049,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__59","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__59.wmat","formatVersion":1,"sourceHash":528110843448922099}, + {"assetId":1904484066334468700,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__60","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__60.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":3045438415191816439,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__60","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__60.wmat","formatVersion":1,"sourceHash":9108640508261734035}, + {"assetId":7736993864853341099,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__61","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__61.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":16314920960340782341,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__61","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__61.wmat","formatVersion":1,"sourceHash":915934276284787436}, + {"assetId":5383388308933643833,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__62","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__62.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6923143004171991324,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__62","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__62.wmat","formatVersion":1,"sourceHash":3482299694309499429}, + {"assetId":8428097613701717203,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__63","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__63.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":11883505219019110422,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__63","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__63.wmat","formatVersion":1,"sourceHash":6832124729437712248}, + {"assetId":16919978094734787135,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__64","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__64.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":7493961902870723016,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__64","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__64.wmat","formatVersion":1,"sourceHash":17964375059061294257}, + {"assetId":11978365854394189157,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__65","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__65.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":9703569224552357746,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__65","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__65.wmat","formatVersion":1,"sourceHash":5915094414860838624}, + {"assetId":18402512700998817142,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__66","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__66.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":17913129048379707209,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__66","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__66.wmat","formatVersion":1,"sourceHash":8409928813853797007}, + {"assetId":13094775716748457230,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__67","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__67.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":16052493459987036767,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__67","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__67.wmat","formatVersion":1,"sourceHash":13838582871554607396}, + {"assetId":9420110106818975442,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__68","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__68.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":14249256068688134670,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__68","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__68.wmat","formatVersion":1,"sourceHash":5251816322602559214}, + {"assetId":11665770550954512744,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__69","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__69.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":15892041888065753741,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__69","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__69.wmat","formatVersion":1,"sourceHash":4805949336775480751}, + {"assetId":9436205051216976025,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__70","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__70.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":14942587649695695571,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__70","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__70.wmat","formatVersion":1,"sourceHash":3404472943720160873}, + {"assetId":4021034824484642372,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__71","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__71.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":16133487766062081595,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__71","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__71.wmat","formatVersion":1,"sourceHash":4901093357586403455}, + {"assetId":1162139202324819048,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__72","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__72.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":18400739809462618767,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__72","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__72.wmat","formatVersion":1,"sourceHash":11202574233412256705}, + {"assetId":2419795551060346878,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__73","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__73.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":12004174778239393697,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__73","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__73.wmat","formatVersion":1,"sourceHash":11085349085811421204}, + {"assetId":17658336077506810347,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__74","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__74.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6830953916348626798,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__74","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__74.wmat","formatVersion":1,"sourceHash":16191336209829419681}, + {"assetId":11270128962196775149,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__75","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__75.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1438750279709290240,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__75","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__75.wmat","formatVersion":1,"sourceHash":5122982235709189413}, + {"assetId":4246832261388970769,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__76","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__76.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":10585462442248717742,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__76","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__76.wmat","formatVersion":1,"sourceHash":6651055802267303058}, + {"assetId":11236147002407908713,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__77","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__77.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6278905015285581392,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__77","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__77.wmat","formatVersion":1,"sourceHash":12058946091763468861}, + {"assetId":6385561491663638508,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__78","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__78.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":11833017377497455644,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__78","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__78.wmat","formatVersion":1,"sourceHash":15746208370710709652}, + {"assetId":5774460084544343272,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__79","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__79.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6449228353247814594,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__79","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__79.wmat","formatVersion":1,"sourceHash":5581722757693394212}, + {"assetId":12363407856602167113,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__80","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__80.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":7825203658809297879,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__80","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__80.wmat","formatVersion":1,"sourceHash":3883641405705167589}, + {"assetId":10411425554735263391,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__81","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__81.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":18212675864156437195,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__81","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__81.wmat","formatVersion":1,"sourceHash":10338313927153405416}, + {"assetId":16222585198370233502,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__82","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__82.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6341542026414383172,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__82","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__82.wmat","formatVersion":1,"sourceHash":10985747164797825642}, + {"assetId":6276292986914166204,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__83","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__83.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":9297787003665117867,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__83","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__83.wmat","formatVersion":1,"sourceHash":987993751301634973}, + {"assetId":3524126900194724051,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__84","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__84.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1368142407168599961,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__84","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__84.wmat","formatVersion":1,"sourceHash":1573590478991570099}, + {"assetId":8379936892125882364,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__85","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__85.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":17615425434727149779,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__85","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__85.wmat","formatVersion":1,"sourceHash":15021837972009510944}, + {"assetId":5370529907106783966,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__86","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__86.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":3307378166964972138,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__86","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__86.wmat","formatVersion":1,"sourceHash":16414512736408610493}, + {"assetId":11435685726260663774,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__87","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__87.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1601912636468888724,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__87","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__87.wmat","formatVersion":1,"sourceHash":2836131640602896348}, + {"assetId":1914623039437072610,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__88","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__88.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6896494829003407116,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__88","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__88.wmat","formatVersion":1,"sourceHash":3677809703873982172}, + {"assetId":4113860169957569099,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__89","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__89.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6410752746425559445,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__89","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__89.wmat","formatVersion":1,"sourceHash":794871690607076599}, + {"assetId":16292226204569430461,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__90","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__90.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":12546584266307313070,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__90","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__90.wmat","formatVersion":1,"sourceHash":17304015300532786011}, + {"assetId":1161113871088196371,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__91","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__91.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":13140657335267704776,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__91","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__91.wmat","formatVersion":1,"sourceHash":10993084337399955276}, + {"assetId":2153231978189338291,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__92","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__92.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":7574761956857896106,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__92","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__92.wmat","formatVersion":1,"sourceHash":15347192330358828181}, + {"assetId":14593766337526508589,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__93","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__93.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":12588103244075146374,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__93","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__93.wmat","formatVersion":1,"sourceHash":11879179696935072141}, + {"assetId":6530629928095013992,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__94","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__94.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":15112736952776741626,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__94","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__94.wmat","formatVersion":1,"sourceHash":7690582110283420096}, + {"assetId":18081150503426162446,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__95","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__95.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":1994779334733726980,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__95","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__95.wmat","formatVersion":1,"sourceHash":3660925423700951973}, + {"assetId":10480157717321104301,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__96","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__96.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":4087356689680254175,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__96","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__96.wmat","formatVersion":1,"sourceHash":4973025491254526861}, + {"assetId":3901345578842322117,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__97","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__97.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":2419053644206384395,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__97","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__97.wmat","formatVersion":1,"sourceHash":15030832607098163724}, + {"assetId":5743276401868917762,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__98","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__98.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":10793103097143920867,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__98","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__98.wmat","formatVersion":1,"sourceHash":11605956222055713613}, + {"assetId":17840664353554127551,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__99","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__99.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":6429394278380673583,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__99","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__99.wmat","formatVersion":1,"sourceHash":521088494192120068}, + {"assetId":3968184785818211594,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__100","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__100.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":15000008075878416251,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__100","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__100.wmat","formatVersion":1,"sourceHash":14785741697486435488}, + {"assetId":15229175004894892839,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__101","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__101.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":12140336635836207652,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__101","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__101.wmat","formatVersion":1,"sourceHash":3586948860202070916}, + {"assetId":16670649961235633850,"kind":"texture","relativePath":"Generated/MeshTextures/sponza_atrium_3__102","cookedPath":"Cooked/Generated/MeshTextures/sponza_atrium_3__102.wtex","formatVersion":1,"sourceHash":1136906439044749114}, + {"assetId":5457201860838636531,"kind":"material","relativePath":"Generated/MeshMaterials/sponza_atrium_3__102","cookedPath":"Cooked/Generated/MeshMaterials/sponza_atrium_3__102.wmat","formatVersion":1,"sourceHash":6145656221699350966}, + {"assetId":1545219856950675401,"kind":"material","relativePath":"Generated/MeshMaterials/basicmesh__0","cookedPath":"Cooked/Generated/MeshMaterials/basicmesh__0.wmat","formatVersion":1,"sourceHash":17385510028530011617}, + {"assetId":15423180035666698351,"kind":"material","relativePath":"Generated/MeshMaterials/basicmesh__1","cookedPath":"Cooked/Generated/MeshMaterials/basicmesh__1.wmat","formatVersion":1,"sourceHash":5263286426569856486}, + {"assetId":2002519743011508280,"kind":"material","relativePath":"Generated/MeshMaterials/basicmesh__2","cookedPath":"Cooked/Generated/MeshMaterials/basicmesh__2.wmat","formatVersion":1,"sourceHash":5263286426569856486} ] } diff --git a/Content/Cooked/Generated/MeshMaterials/basicmesh__0.wmat b/Content/Cooked/Generated/MeshMaterials/basicmesh__0.wmat new file mode 100644 index 00000000..3ce0aad4 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/basicmesh__0.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/basicmesh__1.wmat b/Content/Cooked/Generated/MeshMaterials/basicmesh__1.wmat new file mode 100644 index 00000000..5a77f630 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/basicmesh__1.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/basicmesh__2.wmat b/Content/Cooked/Generated/MeshMaterials/basicmesh__2.wmat new file mode 100644 index 00000000..fcb57d6c Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/basicmesh__2.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__0.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__0.wmat new file mode 100644 index 00000000..25eeb76f Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__0.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__1.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__1.wmat new file mode 100644 index 00000000..db84b520 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__1.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__10.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__10.wmat new file mode 100644 index 00000000..f94724b9 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__10.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__100.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__100.wmat new file mode 100644 index 00000000..0182fbdb Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__100.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__101.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__101.wmat new file mode 100644 index 00000000..349554d9 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__101.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__102.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__102.wmat new file mode 100644 index 00000000..8e3b617d Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__102.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__11.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__11.wmat new file mode 100644 index 00000000..dfa597df Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__11.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__12.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__12.wmat new file mode 100644 index 00000000..37c42af1 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__12.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__13.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__13.wmat new file mode 100644 index 00000000..d85c9cf1 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__13.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__14.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__14.wmat new file mode 100644 index 00000000..b398947f Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__14.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__15.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__15.wmat new file mode 100644 index 00000000..c1d33b0d Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__15.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__16.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__16.wmat new file mode 100644 index 00000000..b64afd25 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__16.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__17.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__17.wmat new file mode 100644 index 00000000..1cb073f0 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__17.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__18.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__18.wmat new file mode 100644 index 00000000..3f8a37ae Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__18.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__19.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__19.wmat new file mode 100644 index 00000000..027a56d0 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__19.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__2.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__2.wmat new file mode 100644 index 00000000..93689ede Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__2.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__20.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__20.wmat new file mode 100644 index 00000000..72e71989 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__20.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__21.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__21.wmat new file mode 100644 index 00000000..3ff42ddf Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__21.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__22.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__22.wmat new file mode 100644 index 00000000..81fba3e4 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__22.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__23.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__23.wmat new file mode 100644 index 00000000..05a2eb6b Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__23.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__24.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__24.wmat new file mode 100644 index 00000000..4fa28f22 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__24.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__25.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__25.wmat new file mode 100644 index 00000000..61f61733 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__25.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__26.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__26.wmat new file mode 100644 index 00000000..8f66e7be Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__26.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__27.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__27.wmat new file mode 100644 index 00000000..7aa715a6 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__27.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__28.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__28.wmat new file mode 100644 index 00000000..31e4ed94 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__28.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__29.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__29.wmat new file mode 100644 index 00000000..10d4948d Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__29.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__3.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__3.wmat new file mode 100644 index 00000000..05273e21 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__3.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__30.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__30.wmat new file mode 100644 index 00000000..b9e1c2c6 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__30.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__31.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__31.wmat new file mode 100644 index 00000000..939a9be4 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__31.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__32.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__32.wmat new file mode 100644 index 00000000..bcd7ca52 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__32.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__33.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__33.wmat new file mode 100644 index 00000000..97530525 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__33.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__34.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__34.wmat new file mode 100644 index 00000000..1f7c8e5f Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__34.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__35.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__35.wmat new file mode 100644 index 00000000..9d037974 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__35.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__36.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__36.wmat new file mode 100644 index 00000000..d936eea2 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__36.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__37.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__37.wmat new file mode 100644 index 00000000..9f4d006b Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__37.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__38.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__38.wmat new file mode 100644 index 00000000..03152322 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__38.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__39.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__39.wmat new file mode 100644 index 00000000..d0a4a1bc Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__39.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__4.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__4.wmat new file mode 100644 index 00000000..152bad3f Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__4.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__40.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__40.wmat new file mode 100644 index 00000000..98579a9b Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__40.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__41.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__41.wmat new file mode 100644 index 00000000..d99a12df Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__41.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__42.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__42.wmat new file mode 100644 index 00000000..f7aeb58d Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__42.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__43.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__43.wmat new file mode 100644 index 00000000..8bedad0b Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__43.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__44.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__44.wmat new file mode 100644 index 00000000..19919deb Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__44.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__45.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__45.wmat new file mode 100644 index 00000000..cb31ba19 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__45.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__46.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__46.wmat new file mode 100644 index 00000000..d8b1650e Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__46.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__47.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__47.wmat new file mode 100644 index 00000000..23354c56 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__47.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__48.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__48.wmat new file mode 100644 index 00000000..d812194f Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__48.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__49.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__49.wmat new file mode 100644 index 00000000..79a9b2bc Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__49.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__5.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__5.wmat new file mode 100644 index 00000000..7a86c162 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__5.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__50.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__50.wmat new file mode 100644 index 00000000..a7f313f0 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__50.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__51.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__51.wmat new file mode 100644 index 00000000..9c766481 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__51.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__52.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__52.wmat new file mode 100644 index 00000000..3a62f704 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__52.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__53.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__53.wmat new file mode 100644 index 00000000..89df7890 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__53.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__54.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__54.wmat new file mode 100644 index 00000000..016bd8bd Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__54.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__55.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__55.wmat new file mode 100644 index 00000000..3c453fda Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__55.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__56.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__56.wmat new file mode 100644 index 00000000..7ea5dc95 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__56.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__57.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__57.wmat new file mode 100644 index 00000000..9316cb72 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__57.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__58.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__58.wmat new file mode 100644 index 00000000..e11c0019 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__58.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__59.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__59.wmat new file mode 100644 index 00000000..8cd8173e Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__59.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__6.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__6.wmat new file mode 100644 index 00000000..25d171dd Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__6.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__60.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__60.wmat new file mode 100644 index 00000000..965d84a9 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__60.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__61.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__61.wmat new file mode 100644 index 00000000..c03e02c8 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__61.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__62.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__62.wmat new file mode 100644 index 00000000..32410374 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__62.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__63.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__63.wmat new file mode 100644 index 00000000..4d22aa6b Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__63.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__64.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__64.wmat new file mode 100644 index 00000000..71e5f331 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__64.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__65.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__65.wmat new file mode 100644 index 00000000..eaa45d12 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__65.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__66.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__66.wmat new file mode 100644 index 00000000..0ffad662 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__66.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__67.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__67.wmat new file mode 100644 index 00000000..819233b4 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__67.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__68.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__68.wmat new file mode 100644 index 00000000..2600dd16 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__68.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__69.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__69.wmat new file mode 100644 index 00000000..7deef02d Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__69.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__7.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__7.wmat new file mode 100644 index 00000000..1e9ad0e5 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__7.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__70.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__70.wmat new file mode 100644 index 00000000..91767cc9 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__70.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__71.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__71.wmat new file mode 100644 index 00000000..cc7f2a69 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__71.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__72.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__72.wmat new file mode 100644 index 00000000..9020695c Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__72.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__73.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__73.wmat new file mode 100644 index 00000000..ce0a5635 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__73.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__74.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__74.wmat new file mode 100644 index 00000000..e542db15 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__74.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__75.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__75.wmat new file mode 100644 index 00000000..a0298657 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__75.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__76.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__76.wmat new file mode 100644 index 00000000..5526986f Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__76.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__77.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__77.wmat new file mode 100644 index 00000000..9f2dd1c9 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__77.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__78.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__78.wmat new file mode 100644 index 00000000..ff5c43ca Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__78.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__79.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__79.wmat new file mode 100644 index 00000000..19b8208e Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__79.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__8.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__8.wmat new file mode 100644 index 00000000..46546861 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__8.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__80.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__80.wmat new file mode 100644 index 00000000..4ab1f10a Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__80.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__81.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__81.wmat new file mode 100644 index 00000000..65bab0e7 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__81.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__82.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__82.wmat new file mode 100644 index 00000000..05dfe7fe Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__82.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__83.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__83.wmat new file mode 100644 index 00000000..d9aba57e Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__83.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__84.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__84.wmat new file mode 100644 index 00000000..101630a7 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__84.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__85.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__85.wmat new file mode 100644 index 00000000..838092c3 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__85.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__86.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__86.wmat new file mode 100644 index 00000000..7a0a03a6 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__86.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__87.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__87.wmat new file mode 100644 index 00000000..934b0f71 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__87.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__88.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__88.wmat new file mode 100644 index 00000000..c4f90887 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__88.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__89.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__89.wmat new file mode 100644 index 00000000..0d02186d Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__89.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__9.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__9.wmat new file mode 100644 index 00000000..4376877d Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__9.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__90.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__90.wmat new file mode 100644 index 00000000..8ab6c684 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__90.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__91.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__91.wmat new file mode 100644 index 00000000..db9afe7e Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__91.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__92.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__92.wmat new file mode 100644 index 00000000..a3e46639 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__92.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__93.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__93.wmat new file mode 100644 index 00000000..4640f010 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__93.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__94.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__94.wmat new file mode 100644 index 00000000..2325705b Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__94.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__95.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__95.wmat new file mode 100644 index 00000000..20eafdc3 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__95.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__96.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__96.wmat new file mode 100644 index 00000000..42b11f6d Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__96.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__97.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__97.wmat new file mode 100644 index 00000000..135356aa Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__97.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__98.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__98.wmat new file mode 100644 index 00000000..952ce344 Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__98.wmat differ diff --git a/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__99.wmat b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__99.wmat new file mode 100644 index 00000000..4b1f87bc Binary files /dev/null and b/Content/Cooked/Generated/MeshMaterials/sponza_atrium_3__99.wmat differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__0.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__0.wtex new file mode 100644 index 00000000..498f0b5d Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__0.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__1.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__1.wtex new file mode 100644 index 00000000..e0796539 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__1.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__10.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__10.wtex new file mode 100644 index 00000000..74c34d16 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__10.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__100.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__100.wtex new file mode 100644 index 00000000..faea765d Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__100.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__101.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__101.wtex new file mode 100644 index 00000000..cbd2dd85 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__101.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__102.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__102.wtex new file mode 100644 index 00000000..769e702d Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__102.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__11.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__11.wtex new file mode 100644 index 00000000..86af9894 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__11.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__12.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__12.wtex new file mode 100644 index 00000000..e73f66e4 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__12.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__13.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__13.wtex new file mode 100644 index 00000000..5a6178a1 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__13.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__14.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__14.wtex new file mode 100644 index 00000000..e7683501 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__14.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__15.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__15.wtex new file mode 100644 index 00000000..7ba34ff9 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__15.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__16.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__16.wtex new file mode 100644 index 00000000..5ae3273a Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__16.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__17.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__17.wtex new file mode 100644 index 00000000..7065b7e8 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__17.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__18.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__18.wtex new file mode 100644 index 00000000..e82baf52 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__18.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__19.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__19.wtex new file mode 100644 index 00000000..39bf84b9 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__19.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__2.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__2.wtex new file mode 100644 index 00000000..6862e332 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__2.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__20.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__20.wtex new file mode 100644 index 00000000..74a33353 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__20.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__21.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__21.wtex new file mode 100644 index 00000000..4bb53e0f Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__21.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__22.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__22.wtex new file mode 100644 index 00000000..251167e7 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__22.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__23.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__23.wtex new file mode 100644 index 00000000..7bfcaca6 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__23.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__24.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__24.wtex new file mode 100644 index 00000000..b8dd9e85 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__24.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__25.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__25.wtex new file mode 100644 index 00000000..22c378ce Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__25.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__26.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__26.wtex new file mode 100644 index 00000000..3025f050 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__26.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__27.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__27.wtex new file mode 100644 index 00000000..c83fd8ac Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__27.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__28.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__28.wtex new file mode 100644 index 00000000..1179e9ad Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__28.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__29.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__29.wtex new file mode 100644 index 00000000..fd8404b6 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__29.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__3.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__3.wtex new file mode 100644 index 00000000..34eb7158 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__3.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__30.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__30.wtex new file mode 100644 index 00000000..f2bc7236 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__30.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__31.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__31.wtex new file mode 100644 index 00000000..ba99596a Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__31.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__32.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__32.wtex new file mode 100644 index 00000000..d9d2b29f Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__32.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__33.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__33.wtex new file mode 100644 index 00000000..6a566952 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__33.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__34.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__34.wtex new file mode 100644 index 00000000..aa41c87e Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__34.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__35.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__35.wtex new file mode 100644 index 00000000..7fdaa577 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__35.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__36.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__36.wtex new file mode 100644 index 00000000..73ca0889 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__36.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__37.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__37.wtex new file mode 100644 index 00000000..e85c247e Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__37.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__38.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__38.wtex new file mode 100644 index 00000000..98e35e66 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__38.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__39.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__39.wtex new file mode 100644 index 00000000..bcd85419 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__39.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__4.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__4.wtex new file mode 100644 index 00000000..899d4584 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__4.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__40.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__40.wtex new file mode 100644 index 00000000..2a695e77 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__40.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__41.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__41.wtex new file mode 100644 index 00000000..51f5dc93 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__41.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__42.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__42.wtex new file mode 100644 index 00000000..23132605 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__42.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__43.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__43.wtex new file mode 100644 index 00000000..0625cad6 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__43.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__44.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__44.wtex new file mode 100644 index 00000000..5297fb7c Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__44.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__45.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__45.wtex new file mode 100644 index 00000000..b8ee6b63 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__45.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__46.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__46.wtex new file mode 100644 index 00000000..38f1bd70 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__46.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__47.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__47.wtex new file mode 100644 index 00000000..d2c91892 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__47.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__48.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__48.wtex new file mode 100644 index 00000000..9a9bad09 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__48.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__49.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__49.wtex new file mode 100644 index 00000000..19544909 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__49.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__5.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__5.wtex new file mode 100644 index 00000000..1e024582 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__5.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__50.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__50.wtex new file mode 100644 index 00000000..8a3e3cbe Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__50.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__51.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__51.wtex new file mode 100644 index 00000000..6d113455 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__51.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__52.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__52.wtex new file mode 100644 index 00000000..32f9694f Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__52.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__53.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__53.wtex new file mode 100644 index 00000000..22ae0424 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__53.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__54.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__54.wtex new file mode 100644 index 00000000..66b68919 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__54.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__55.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__55.wtex new file mode 100644 index 00000000..df31012c Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__55.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__56.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__56.wtex new file mode 100644 index 00000000..631d0881 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__56.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__57.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__57.wtex new file mode 100644 index 00000000..878aed1f Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__57.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__58.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__58.wtex new file mode 100644 index 00000000..4f0716e5 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__58.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__59.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__59.wtex new file mode 100644 index 00000000..c2e86f97 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__59.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__6.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__6.wtex new file mode 100644 index 00000000..b86493d4 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__6.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__60.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__60.wtex new file mode 100644 index 00000000..dca04e42 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__60.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__61.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__61.wtex new file mode 100644 index 00000000..9b9f8344 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__61.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__62.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__62.wtex new file mode 100644 index 00000000..00acafcf Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__62.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__63.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__63.wtex new file mode 100644 index 00000000..92b02938 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__63.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__64.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__64.wtex new file mode 100644 index 00000000..2c6d8e6b Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__64.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__65.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__65.wtex new file mode 100644 index 00000000..a710e1fb Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__65.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__66.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__66.wtex new file mode 100644 index 00000000..7eb02021 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__66.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__67.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__67.wtex new file mode 100644 index 00000000..ffbb9334 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__67.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__68.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__68.wtex new file mode 100644 index 00000000..9cdfedd8 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__68.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__69.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__69.wtex new file mode 100644 index 00000000..07c046df Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__69.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__7.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__7.wtex new file mode 100644 index 00000000..a4ad4535 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__7.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__70.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__70.wtex new file mode 100644 index 00000000..551d7865 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__70.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__71.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__71.wtex new file mode 100644 index 00000000..04cf3dc7 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__71.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__72.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__72.wtex new file mode 100644 index 00000000..e7d1c0c9 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__72.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__73.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__73.wtex new file mode 100644 index 00000000..f0ec6f61 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__73.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__74.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__74.wtex new file mode 100644 index 00000000..cfd3dfce Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__74.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__75.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__75.wtex new file mode 100644 index 00000000..8d9b586e Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__75.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__76.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__76.wtex new file mode 100644 index 00000000..b5e2439f Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__76.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__77.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__77.wtex new file mode 100644 index 00000000..0acd1f0d Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__77.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__78.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__78.wtex new file mode 100644 index 00000000..738e4646 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__78.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__79.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__79.wtex new file mode 100644 index 00000000..fcf7e19a Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__79.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__8.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__8.wtex new file mode 100644 index 00000000..9248c056 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__8.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__80.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__80.wtex new file mode 100644 index 00000000..de4cc05b Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__80.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__81.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__81.wtex new file mode 100644 index 00000000..8d619a56 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__81.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__82.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__82.wtex new file mode 100644 index 00000000..0e4c909a Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__82.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__83.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__83.wtex new file mode 100644 index 00000000..705a473b Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__83.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__84.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__84.wtex new file mode 100644 index 00000000..8c299d38 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__84.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__85.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__85.wtex new file mode 100644 index 00000000..14c0987e Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__85.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__86.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__86.wtex new file mode 100644 index 00000000..46b064ee Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__86.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__87.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__87.wtex new file mode 100644 index 00000000..758694d3 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__87.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__88.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__88.wtex new file mode 100644 index 00000000..5041e1e5 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__88.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__89.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__89.wtex new file mode 100644 index 00000000..90854ab8 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__89.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__9.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__9.wtex new file mode 100644 index 00000000..3af079ce Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__9.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__90.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__90.wtex new file mode 100644 index 00000000..b1b41a67 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__90.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__91.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__91.wtex new file mode 100644 index 00000000..7c59f275 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__91.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__92.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__92.wtex new file mode 100644 index 00000000..d82f6d9d Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__92.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__93.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__93.wtex new file mode 100644 index 00000000..f2edcc3c Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__93.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__94.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__94.wtex new file mode 100644 index 00000000..e219dff2 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__94.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__95.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__95.wtex new file mode 100644 index 00000000..6fd839de Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__95.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__96.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__96.wtex new file mode 100644 index 00000000..11a1d85e Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__96.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__97.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__97.wtex new file mode 100644 index 00000000..26fc03ba Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__97.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__98.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__98.wtex new file mode 100644 index 00000000..bd2e1d0c Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__98.wtex differ diff --git a/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__99.wtex b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__99.wtex new file mode 100644 index 00000000..90b77c04 Binary files /dev/null and b/Content/Cooked/Generated/MeshTextures/sponza_atrium_3__99.wtex differ diff --git a/Content/Cooked/basicmesh.wmesh b/Content/Cooked/basicmesh.wmesh index dab7e6da..843c3885 100644 Binary files a/Content/Cooked/basicmesh.wmesh and b/Content/Cooked/basicmesh.wmesh differ diff --git a/Content/Cooked/sponza_atrium_3.wmesh b/Content/Cooked/sponza_atrium_3.wmesh index 48b0f813..37339303 100644 Binary files a/Content/Cooked/sponza_atrium_3.wmesh and b/Content/Cooked/sponza_atrium_3.wmesh differ diff --git a/Content/scene.json b/Content/scene.json new file mode 100644 index 00000000..0c290bb6 --- /dev/null +++ b/Content/scene.json @@ -0,0 +1,19 @@ +{ + "version": 1, + "meshAsset": "", + "nodes": [ + {"id":"world","parentId":null,"displayName":"World","kind":"Folder","visible":true}, + {"id":"lighting","parentId":"world","displayName":"Lighting","kind":"Folder","visible":true}, + {"id":"directional-light","parentId":"lighting","displayName":"DirectionalLight","kind":"Light","visible":true}, + {"id":"Mesh","parentId":"world","displayName":"Mesh","kind":"Mesh","visible":true} + ], + "objects": [ + {"id":"world","displayName":"World","kind":"Folder","visible":true,"isGeneratedAssetChild":false,"supportsTransform":false,"transformReadOnly":true}, + {"id":"lighting","displayName":"Lighting","kind":"Folder","visible":true,"isGeneratedAssetChild":false,"supportsTransform":false,"transformReadOnly":true}, + {"id":"Mesh","displayName":"Mesh","kind":"Mesh","visible":true,"isGeneratedAssetChild":false,"supportsTransform":true,"transformReadOnly":false,"location":[7.00839,0,-7.33693],"rotationDegrees":[-0,0,0],"scale":[1,1,1],"assetRelativePath":"sponza_atrium_3.glb"}, + {"id":"directional-light","displayName":"DirectionalLight","kind":"Light","visible":true,"isGeneratedAssetChild":false,"supportsTransform":true,"transformReadOnly":false,"location":[0.70909,7.39407,-8],"rotationDegrees":[-45,30,0],"scale":[1,1,1],"lightColor":[1,0.98,0.92],"lightIntensity":4,"lightDirection":[0.35,0.7,0.2]} + ], + "meshNameToObjectId": { + + } +} diff --git a/Tests/CookedAssetTests.cpp b/Tests/CookedAssetTests.cpp index 894e3046..947813b1 100644 --- a/Tests/CookedAssetTests.cpp +++ b/Tests/CookedAssetTests.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -99,8 +100,15 @@ TEST(CookedAssetTests, CookMeshAssetWritesManifestAndCookedLookupResolves) { const auto Manifest = Axiom::Assets::LoadAssetCookManifest( ContentRoot / "Cooked" / "AssetCookManifest.json"); ASSERT_TRUE(Manifest.has_value()); - ASSERT_EQ(Manifest->Entries.size(), 1u); - EXPECT_EQ(Manifest->Entries[0].Id.Value, Entry->Id.Value); + ASSERT_FALSE(Manifest->Entries.empty()); + const auto MeshIt = std::find_if( + Manifest->Entries.begin(), Manifest->Entries.end(), + [&](const Axiom::Assets::AssetCookManifestEntry &Existing) { + return Existing.Id.Value == Entry->Id.Value; + }); + ASSERT_NE(MeshIt, Manifest->Entries.end()); + EXPECT_EQ(MeshIt->Kind, Axiom::Assets::AssetKind::Mesh); + EXPECT_GT(Manifest->Entries.size(), 1u); const Axiom::Assets::CookedAssetSource Cooked(ContentRoot); const auto Resolved = Cooked.Resolve(Entry->Id); @@ -112,6 +120,33 @@ TEST(CookedAssetTests, CookMeshAssetWritesManifestAndCookedLookupResolves) { EXPECT_FALSE(Loaded->Instances.empty()); } +TEST(CookedAssetTests, LoadBasicMeshAssetPrefersSourceWhenCookedMeshWouldDropMaterials) { + const auto TempRoot = MakeUniqueTempRoot("sponza-materials"); + const auto ContentRoot = TempRoot / "Content"; + EnsureTempDirectory(ContentRoot); + + CopyFileChecked(std::filesystem::path(AXIOM_CONTENT_DIR) / "sponza_atrium_3.glb", + ContentRoot / "sponza_atrium_3.glb"); + + const auto Entry = Axiom::Assets::CookMeshAsset( + ContentRoot, std::filesystem::path("sponza_atrium_3.glb")); + ASSERT_TRUE(Entry.has_value()); + + const auto Loaded = + Axiom::Assets::LoadBasicMeshAsset(ContentRoot / "sponza_atrium_3.glb"); + ASSERT_TRUE(Loaded.has_value()); + ASSERT_FALSE(Loaded->Instances.empty()); + + const auto It = std::find_if( + Loaded->Instances.begin(), Loaded->Instances.end(), + [](const Axiom::MeshSceneData::MeshInstanceData &Instance) { + return Instance.Material != nullptr && + Instance.Material->BaseColorTexture != nullptr && + Instance.Material->BaseColorTexture->IsValid(); + }); + EXPECT_NE(It, Loaded->Instances.end()); +} + TEST(CookedAssetTests, CookTextureAssetWritesManifestAndCookedLookupResolves) { const auto TempRoot = MakeUniqueTempRoot("texture-manifest"); const auto ContentRoot = TempRoot / "Content"; diff --git a/Tests/SceneLifecycleTests.cpp b/Tests/SceneLifecycleTests.cpp index e85421ff..4758abd5 100644 --- a/Tests/SceneLifecycleTests.cpp +++ b/Tests/SceneLifecycleTests.cpp @@ -7,6 +7,7 @@ #include +#include #include namespace { @@ -64,6 +65,36 @@ const T *FindEvent(const std::vector &Events) { return nullptr; } +size_t CountGeneratedChildrenForRoot(const Axiom::EditorSession &Session, + const std::string &RootObjectId) { + size_t Count = 0; + for (const auto &[ObjectId, Details] : Session.GetState().Scene.ObjectDetailsById) { + if (Details.IsGeneratedAssetChild && + Details.GeneratedFromAssetRootId.has_value() && + *Details.GeneratedFromAssetRootId == RootObjectId) { + ++Count; + } + } + return Count; +} + +std::filesystem::path WriteSingleMeshObj(const std::filesystem::path &ContentRoot, + std::string_view RelativePath = "singlemesh.obj") { + const auto AbsolutePath = ContentRoot / std::filesystem::path(RelativePath); + std::filesystem::create_directories(AbsolutePath.parent_path()); + std::ofstream Out(AbsolutePath); + Out << "o SingleMesh\n" + "v 0 0 0\n" + "v 1 0 0\n" + "v 0 1 0\n" + "vn 0 0 1\n" + "vt 0 0\n" + "vt 1 0\n" + "vt 0 1\n" + "f 1/1/1 2/2/1 3/3/1\n"; + return AbsolutePath; +} + } // namespace // --------------------------------------------------------------------------- @@ -144,14 +175,21 @@ TEST(SceneLifecycleTests, CreateFolderHasNoTransform) { TEST(SceneLifecycleTests, CreateMeshObjectAddsMeshWithAssetAndTransform) { EnsureLogInitialized(); + const auto TempRoot = + std::filesystem::temp_directory_path() / "wraithengine-single-mesh-create-test"; + std::error_code RemoveError; + std::filesystem::remove_all(TempRoot, RemoveError); + std::filesystem::create_directories(TempRoot / "Content"); + WriteSingleMeshObj(TempRoot / "Content"); + Axiom::EditorSession Session = MakeWorldSession(); - Session.SetContentDir(AXIOM_CONTENT_DIR); + Session.SetContentDir(TempRoot / "Content"); RecordingSubscriber Subscriber; Session.Subscribe(&Subscriber); Session.Submit(MakeContext(), {.Payload = Axiom::CreateMeshObjectCommand{ - .AssetPath = "basicmesh.glb", + .AssetPath = "singlemesh.obj", .Location = glm::vec3(1.0f, 2.0f, 3.0f), .RotationDegrees = glm::vec3(0.0f, 45.0f, 0.0f), .Scale = glm::vec3(1.5f, 1.5f, 1.5f), @@ -166,7 +204,7 @@ TEST(SceneLifecycleTests, CreateMeshObjectAddsMeshWithAssetAndTransform) { const auto *MeshChanged = FindEvent(Subscriber.Events); ASSERT_NE(MeshChanged, nullptr); EXPECT_EQ(MeshChanged->ObjectId, Created->ObjectId); - EXPECT_EQ(MeshChanged->AssetPath, "basicmesh.glb"); + EXPECT_EQ(MeshChanged->AssetPath, "singlemesh.obj"); const auto *TransformChanged = FindEvent(Subscriber.Events); @@ -201,7 +239,7 @@ TEST(SceneLifecycleTests, CreateMeshObjectAddsMeshWithAssetAndTransform) { return I.ObjectId == Created->ObjectId; }); ASSERT_NE(It, Instances.end()); - EXPECT_EQ(It->AssetRelativePath, "basicmesh.glb"); + EXPECT_EQ(It->AssetRelativePath, "singlemesh.obj"); EXPECT_NE(It->Material, nullptr); const auto *Ack = FindEvent(Subscriber.Events); @@ -226,6 +264,47 @@ TEST(SceneLifecycleTests, CreateMeshObjectRejectsInvalidAssetPath) { ASSERT_EQ(FindEvent(Subscriber.Events), nullptr); } +TEST(SceneLifecycleTests, CreateMeshObjectExpandsMultiMeshAssetIntoGeneratedChildren) { + EnsureLogInitialized(); + Axiom::EditorSession Session = MakeWorldSession(); + Session.SetContentDir(AXIOM_CONTENT_DIR); + RecordingSubscriber Subscriber; + Session.Subscribe(&Subscriber); + + Session.Submit(MakeContext(), + {.Payload = Axiom::CreateMeshObjectCommand{ + .AssetPath = "sponza_atrium_3.glb", + }}); + Session.Tick(); + + ASSERT_EQ(FindEvent(Subscriber.Events), nullptr); + const auto *Created = FindEvent(Subscriber.Events); + ASSERT_NE(Created, nullptr); + + const auto *RootDetails = Session.FindObjectDetails(Created->ObjectId); + ASSERT_NE(RootDetails, nullptr); + EXPECT_EQ(RootDetails->AssetRelativePath, "sponza_atrium_3.glb"); + + const Axiom::EditorSceneItem *RootItem = Session.FindSceneItem(Created->ObjectId); + ASSERT_NE(RootItem, nullptr); + EXPECT_GT(RootItem->Children.size(), 1u); + EXPECT_EQ(CountGeneratedChildrenForRoot(Session, Created->ObjectId), + RootItem->Children.size()); + + const auto RootMeshInstance = std::find_if( + Session.GetState().Scene.MeshInstances.begin(), + Session.GetState().Scene.MeshInstances.end(), + [&](const Axiom::EditorSceneMeshInstance &Instance) { + return Instance.ObjectId == Created->ObjectId; + }); + EXPECT_EQ(RootMeshInstance, Session.GetState().Scene.MeshInstances.end()); + + const auto *ChildDetails = Session.FindObjectDetails(RootItem->Children.front().Id); + ASSERT_NE(ChildDetails, nullptr); + EXPECT_TRUE(ChildDetails->IsGeneratedAssetChild); + EXPECT_TRUE(ChildDetails->TransformReadOnly); +} + TEST(SceneLifecycleTests, CreateWithUnknownTemplateIdIsRejected) { Axiom::EditorSession Session = MakeWorldSession(); RecordingSubscriber Subscriber; @@ -1108,8 +1187,15 @@ TEST(SceneLifecycleTests, SetMeshAsset_CreatesInstanceForRuntimeCreatedMesh) { // A mesh created via CreateObject has no MeshInstance entry yet. // SetMeshAsset must create the entry rather than silently dropping the command. EnsureLogInitialized(); + const auto TempRoot = + std::filesystem::temp_directory_path() / "wraithengine-single-mesh-assign-test"; + std::error_code RemoveError; + std::filesystem::remove_all(TempRoot, RemoveError); + std::filesystem::create_directories(TempRoot / "Content"); + WriteSingleMeshObj(TempRoot / "Content"); + Axiom::EditorSession Session(Axiom::SessionId{1}); - Session.SetContentDir(AXIOM_CONTENT_DIR); + Session.SetContentDir(TempRoot / "Content"); RecordingSubscriber Subscriber; Session.Subscribe(&Subscriber); @@ -1127,7 +1213,7 @@ TEST(SceneLifecycleTests, SetMeshAsset_CreatesInstanceForRuntimeCreatedMesh) { Session.Submit(MakeContext(), {.Payload = Axiom::SetMeshAssetCommand{ .ObjectId = NewId, - .AssetPath = "basicmesh.glb", + .AssetPath = "singlemesh.obj", }}); Session.Tick(); @@ -1143,7 +1229,7 @@ TEST(SceneLifecycleTests, SetMeshAsset_CreatesInstanceForRuntimeCreatedMesh) { return I.ObjectId == NewId; }); ASSERT_NE(It, Instances.end()); - EXPECT_EQ(It->AssetRelativePath, "basicmesh.glb"); + EXPECT_EQ(It->AssetRelativePath, "singlemesh.obj"); } TEST(SceneLifecycleTests, SetMeshAsset_CooksMeshAssetManifestEntry) { @@ -1189,6 +1275,99 @@ TEST(SceneLifecycleTests, SetMeshAsset_CooksMeshAssetManifestEntry) { ".wmesh"); } +TEST(SceneLifecycleTests, SetMeshAsset_ReplacesGeneratedChildrenWhenSwitchingToSingleMesh) { + EnsureLogInitialized(); + const auto TempRoot = + std::filesystem::temp_directory_path() / "wraithengine-multimesh-switch-test"; + std::error_code RemoveError; + std::filesystem::remove_all(TempRoot, RemoveError); + std::filesystem::create_directories(TempRoot / "Content"); + std::filesystem::copy_file( + std::filesystem::path(AXIOM_CONTENT_DIR) / "sponza_atrium_3.glb", + TempRoot / "Content" / "sponza_atrium_3.glb", + std::filesystem::copy_options::overwrite_existing); + WriteSingleMeshObj(TempRoot / "Content"); + + Axiom::EditorSession Session = MakeWorldSession(); + Session.SetContentDir(TempRoot / "Content"); + RecordingSubscriber Subscriber; + Session.Subscribe(&Subscriber); + + Session.Submit(MakeContext(), + {.Payload = Axiom::CreateObjectCommand{.TemplateId = "Mesh"}}); + Session.Tick(); + const auto *Created = FindEvent(Subscriber.Events); + ASSERT_NE(Created, nullptr); + const std::string RootObjectId = Created->ObjectId; + Subscriber.Events.clear(); + + Session.Submit(MakeContext(2), + {.Payload = Axiom::SetMeshAssetCommand{ + .ObjectId = RootObjectId, + .AssetPath = "sponza_atrium_3.glb", + }}); + Session.Tick(); + + const size_t GeneratedCount = + CountGeneratedChildrenForRoot(Session, RootObjectId); + ASSERT_GT(GeneratedCount, 1u); + + Session.Submit(MakeContext(3), + {.Payload = Axiom::SetMeshAssetCommand{ + .ObjectId = RootObjectId, + .AssetPath = "singlemesh.obj", + }}); + Session.Tick(); + + EXPECT_EQ(CountGeneratedChildrenForRoot(Session, RootObjectId), 0u); + const Axiom::EditorSceneItem *RootItem = Session.FindSceneItem(RootObjectId); + ASSERT_NE(RootItem, nullptr); + EXPECT_TRUE(RootItem->Children.empty()); + + const auto RootMeshInstance = std::find_if( + Session.GetState().Scene.MeshInstances.begin(), + Session.GetState().Scene.MeshInstances.end(), + [&](const Axiom::EditorSceneMeshInstance &Instance) { + return Instance.ObjectId == RootObjectId; + }); + ASSERT_NE(RootMeshInstance, Session.GetState().Scene.MeshInstances.end()); + EXPECT_EQ(RootMeshInstance->AssetRelativePath, "singlemesh.obj"); +} + +TEST(SceneLifecycleTests, DeleteMultiMeshRootRemovesGeneratedChildren) { + EnsureLogInitialized(); + Axiom::EditorSession Session = MakeWorldSession(); + Session.SetContentDir(AXIOM_CONTENT_DIR); + RecordingSubscriber Subscriber; + Session.Subscribe(&Subscriber); + + Session.Submit(MakeContext(), + {.Payload = Axiom::CreateMeshObjectCommand{ + .AssetPath = "sponza_atrium_3.glb", + }}); + Session.Tick(); + + const auto *Created = FindEvent(Subscriber.Events); + ASSERT_NE(Created, nullptr); + const std::string RootObjectId = Created->ObjectId; + const Axiom::EditorSceneItem *RootItemBefore = Session.FindSceneItem(RootObjectId); + ASSERT_NE(RootItemBefore, nullptr); + ASSERT_FALSE(RootItemBefore->Children.empty()); + const std::string ChildObjectId = RootItemBefore->Children.front().Id; + Subscriber.Events.clear(); + + Session.Submit(MakeContext(2), + {.Payload = Axiom::DeleteObjectCommand{ + .ObjectId = RootObjectId, + }}); + Session.Tick(); + + EXPECT_EQ(Session.FindSceneItem(RootObjectId), nullptr); + EXPECT_EQ(Session.FindObjectDetails(RootObjectId), nullptr); + EXPECT_EQ(Session.FindSceneItem(ChildObjectId), nullptr); + EXPECT_EQ(Session.FindObjectDetails(ChildObjectId), nullptr); +} + TEST(SceneLifecycleTests, SetMaterialTexture_CooksTextureAssetManifestEntry) { EnsureLogInitialized(); @@ -1259,10 +1438,7 @@ TEST(SceneLifecycleTests, SceneFile_SaveLoadRoundTripsCookedMaterialState) { std::error_code RemoveError; std::filesystem::remove_all(TempRoot, RemoveError); std::filesystem::create_directories(TempRoot / "Content" / "Engine"); - std::filesystem::copy_file( - std::filesystem::path(AXIOM_CONTENT_DIR) / "basicmesh.glb", - TempRoot / "Content" / "basicmesh.glb", - std::filesystem::copy_options::overwrite_existing); + WriteSingleMeshObj(TempRoot / "Content"); std::filesystem::copy_file( std::filesystem::path(AXIOM_CONTENT_DIR) / "Engine" / "tf2 coconut.jpg", TempRoot / "Content" / "Engine" / "tf2 coconut.jpg", @@ -1303,7 +1479,7 @@ TEST(SceneLifecycleTests, SceneFile_SaveLoadRoundTripsCookedMaterialState) { .Material = Mat, .RenderPath = Axiom::MeshRenderPath::Graphics, .Transform = glm::mat4(1.0f), - .AssetRelativePath = "basicmesh.glb", + .AssetRelativePath = "singlemesh.obj", }}; const auto ScenePath = TempRoot / "Content" / "scene.json"; @@ -1321,3 +1497,78 @@ TEST(SceneLifecycleTests, SceneFile_SaveLoadRoundTripsCookedMaterialState) { EXPECT_EQ(*DetailsIt->second.Material->TextureAssetPath, "Engine/tf2 coconut.jpg"); } + +TEST(SceneLifecycleTests, SceneFile_SaveLoadRegeneratesMultiMeshChildrenWithoutDuplicatingThem) { + EnsureLogInitialized(); + + const auto TempRoot = + std::filesystem::temp_directory_path() / "wraithengine-multimesh-scene-test"; + std::error_code RemoveError; + std::filesystem::remove_all(TempRoot, RemoveError); + std::filesystem::create_directories(TempRoot / "Content"); + std::filesystem::copy_file( + std::filesystem::path(AXIOM_CONTENT_DIR) / "sponza_atrium_3.glb", + TempRoot / "Content" / "sponza_atrium_3.glb", + std::filesystem::copy_options::overwrite_existing); + + Axiom::EditorSceneState Scene; + Scene.Items = {{ + .Id = "sponza-root", + .DisplayName = "Sponza", + .Kind = Axiom::EditorSceneItemKind::Mesh, + .Visible = true, + .Children = {{ + .Id = "sponza-root__asset_0_Object_4", + .DisplayName = "Object_4", + .Kind = Axiom::EditorSceneItemKind::Mesh, + .Visible = true, + }}, + }}; + Scene.ObjectDetailsById["sponza-root"] = Axiom::EditorObjectDetails{ + .ObjectId = "sponza-root", + .DisplayName = "Sponza", + .Kind = Axiom::EditorSceneItemKind::Mesh, + .Visible = true, + .SupportsTransform = true, + .TransformReadOnly = false, + .Transform = Axiom::EditorTransformDetails{}, + .AssetRelativePath = "sponza_atrium_3.glb", + }; + Scene.ObjectDetailsById["sponza-root__asset_0_Object_4"] = + Axiom::EditorObjectDetails{ + .ObjectId = "sponza-root__asset_0_Object_4", + .DisplayName = "Object_4", + .Kind = Axiom::EditorSceneItemKind::Mesh, + .Visible = true, + .IsGeneratedAssetChild = true, + .SupportsTransform = true, + .TransformReadOnly = true, + .Transform = Axiom::EditorTransformDetails{}, + .GeneratedFromAssetRootId = std::string("sponza-root"), + }; + + const auto ScenePath = TempRoot / "Content" / "scene.json"; + ASSERT_TRUE(Axiom::Assets::SaveSceneToFile(ScenePath, Scene)); + + const auto Loaded = Axiom::Assets::LoadSceneFromFile(ScenePath); + ASSERT_TRUE(Loaded.has_value()); + const auto RootDetailsIt = Loaded->ObjectDetailsById.find("sponza-root"); + ASSERT_NE(RootDetailsIt, Loaded->ObjectDetailsById.end()); + EXPECT_EQ(RootDetailsIt->second.AssetRelativePath, "sponza_atrium_3.glb"); + + size_t GeneratedCount = 0; + for (const auto &[ObjectId, Details] : Loaded->ObjectDetailsById) { + if (Details.IsGeneratedAssetChild && + Details.GeneratedFromAssetRootId.has_value() && + *Details.GeneratedFromAssetRootId == "sponza-root") { + ++GeneratedCount; + } + } + EXPECT_GT(GeneratedCount, 1u); + + const auto LoadedRootItem = std::find_if( + Loaded->Items.begin(), Loaded->Items.end(), + [](const Axiom::EditorSceneItem &Item) { return Item.Id == "sponza-root"; }); + ASSERT_NE(LoadedRootItem, Loaded->Items.end()); + EXPECT_EQ(LoadedRootItem->Children.size(), GeneratedCount); +}