Add backpack editor startup scene

This commit is contained in:
2026-03-28 19:26:08 +08:00
parent a519fdab7d
commit eb5de3e3d4
16 changed files with 471 additions and 39 deletions

View File

@@ -5,17 +5,32 @@
#include <XCEngine/Components/CameraComponent.h>
#include <XCEngine/Components/GameObject.h>
#include <XCEngine/Components/LightComponent.h>
#include <XCEngine/Components/MeshFilterComponent.h>
#include <XCEngine/Components/MeshRendererComponent.h>
#include <XCEngine/Components/TransformComponent.h>
#include <XCEngine/Core/Asset/ResourceManager.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Resources/Mesh/MeshLoader.h>
#include <filesystem>
#include <fstream>
#include <sstream>
#ifdef _WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#endif
using namespace XCEngine::Components;
using namespace XCEngine::Math;
namespace {
std::filesystem::path GetRepositoryRoot() {
return std::filesystem::path(__FILE__).parent_path().parent_path().parent_path();
}
class TestComponent : public Component {
public:
TestComponent() = default;
@@ -505,4 +520,118 @@ TEST_F(SceneTest, Save_ContainsHierarchyAndComponentEntries) {
std::filesystem::remove(scenePath);
}
TEST_F(SceneTest, SaveAndLoad_PreservesMeshComponentPaths) {
GameObject* meshObject = testScene->CreateGameObject("Backpack");
auto* meshFilter = meshObject->AddComponent<MeshFilterComponent>();
auto* meshRenderer = meshObject->AddComponent<MeshRendererComponent>();
meshFilter->SetMeshPath("Assets/Models/backpack/backpack.obj");
meshRenderer->SetMaterialPath(0, "Assets/Materials/backpack.mat");
meshRenderer->SetCastShadows(false);
meshRenderer->SetReceiveShadows(true);
meshRenderer->SetRenderLayer(4);
const std::filesystem::path scenePath = GetTempScenePath("test_scene_mesh_components.xc");
testScene->Save(scenePath.string());
Scene loadedScene;
loadedScene.Load(scenePath.string());
GameObject* loadedObject = loadedScene.Find("Backpack");
ASSERT_NE(loadedObject, nullptr);
auto* loadedMeshFilter = loadedObject->GetComponent<MeshFilterComponent>();
auto* loadedMeshRenderer = loadedObject->GetComponent<MeshRendererComponent>();
ASSERT_NE(loadedMeshFilter, nullptr);
ASSERT_NE(loadedMeshRenderer, nullptr);
EXPECT_EQ(loadedMeshFilter->GetMeshPath(), "Assets/Models/backpack/backpack.obj");
ASSERT_EQ(loadedMeshRenderer->GetMaterialCount(), 1u);
EXPECT_EQ(loadedMeshRenderer->GetMaterialPath(0), "Assets/Materials/backpack.mat");
EXPECT_FALSE(loadedMeshRenderer->GetCastShadows());
EXPECT_TRUE(loadedMeshRenderer->GetReceiveShadows());
EXPECT_EQ(loadedMeshRenderer->GetRenderLayer(), 4u);
std::filesystem::remove(scenePath);
}
TEST(Scene_ProjectSample, MainSceneLoadsBackpackMeshAsset) {
namespace fs = std::filesystem;
XCEngine::Resources::ResourceManager& resourceManager = XCEngine::Resources::ResourceManager::Get();
resourceManager.Initialize();
struct ResourceManagerGuard {
XCEngine::Resources::ResourceManager* manager = nullptr;
~ResourceManagerGuard() {
if (manager != nullptr) {
manager->Shutdown();
}
}
} resourceManagerGuard{ &resourceManager };
struct CurrentPathGuard {
fs::path previousPath;
~CurrentPathGuard() {
if (!previousPath.empty()) {
fs::current_path(previousPath);
}
}
} currentPathGuard{ fs::current_path() };
const fs::path repositoryRoot = GetRepositoryRoot();
const fs::path projectRoot = repositoryRoot / "project";
const fs::path mainScenePath = projectRoot / "Assets" / "Scenes" / "Main.xc";
const fs::path assimpDllPath = repositoryRoot / "engine" / "third_party" / "assimp" / "bin" / "assimp-vc143-mt.dll";
const fs::path backpackMeshPath = projectRoot / "Assets" / "Models" / "backpack" / "backpack.obj";
ASSERT_TRUE(fs::exists(mainScenePath));
ASSERT_TRUE(fs::exists(assimpDllPath));
ASSERT_TRUE(fs::exists(backpackMeshPath));
#ifdef _WIN32
struct DllGuard {
HMODULE module = nullptr;
~DllGuard() {
if (module != nullptr) {
FreeLibrary(module);
}
}
} dllGuard;
dllGuard.module = LoadLibraryW(assimpDllPath.wstring().c_str());
ASSERT_NE(dllGuard.module, nullptr);
#endif
fs::current_path(projectRoot);
ASSERT_NE(resourceManager.GetLoader(XCEngine::Resources::ResourceType::Mesh), nullptr);
XCEngine::Resources::MeshLoader meshLoader;
const XCEngine::Resources::LoadResult directMeshLoadResult =
meshLoader.Load("Assets/Models/backpack/backpack.obj");
ASSERT_TRUE(directMeshLoadResult)
<< "MeshLoader failed: " << directMeshLoadResult.errorMessage.CStr();
const auto directMeshHandle =
resourceManager.Load<XCEngine::Resources::Mesh>("Assets/Models/backpack/backpack.obj");
ASSERT_NE(directMeshHandle.Get(), nullptr);
ASSERT_TRUE(directMeshHandle->IsValid());
ASSERT_GT(directMeshHandle->GetVertexCount(), 0u);
Scene loadedScene;
loadedScene.Load(mainScenePath.string());
GameObject* backpackObject = loadedScene.Find("BackpackMesh");
ASSERT_NE(backpackObject, nullptr);
auto* meshFilter = backpackObject->GetComponent<MeshFilterComponent>();
auto* meshRenderer = backpackObject->GetComponent<MeshRendererComponent>();
ASSERT_NE(meshFilter, nullptr);
ASSERT_NE(meshRenderer, nullptr);
ASSERT_NE(meshFilter->GetMesh(), nullptr);
EXPECT_TRUE(meshFilter->GetMesh()->IsValid());
EXPECT_GT(meshFilter->GetMesh()->GetVertexCount(), 0u);
EXPECT_GT(meshFilter->GetMesh()->GetSections().Size(), 0u);
EXPECT_GT(meshFilter->GetMesh()->GetMaterials().Size(), 0u);
EXPECT_EQ(meshFilter->GetMeshPath(), "Assets/Models/backpack/backpack.obj");
}
} // namespace