feat(project): refresh sample scenes and Nahida assets

This commit is contained in:
2026-04-19 00:29:32 +08:00
parent f4fef59b2f
commit 1405ef6a29
59 changed files with 432 additions and 2614 deletions

View File

@@ -1,12 +1,14 @@
#include <gtest/gtest.h>
#include <XCEngine/Components/AudioListenerComponent.h>
#include <XCEngine/Components/AudioSourceComponent.h>
#include <XCEngine/Components/BoxColliderComponent.h>
#include <XCEngine/Scene/Scene.h>
#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/RigidbodyComponent.h>
#include <XCEngine/Components/TransformComponent.h>
#include <XCEngine/Core/Asset/ResourceManager.h>
#include <XCEngine/Core/Math/Vector3.h>
@@ -320,10 +322,50 @@ TEST_F(SceneTest, OnGameObjectDestroyed_Event) {
GameObject* go = testScene->CreateGameObject("TestObject");
testScene->DestroyGameObject(go);
EXPECT_TRUE(eventFired);
}
TEST_F(SceneTest, OnComponentAdded_Event) {
bool eventFired = false;
GameObject* eventGameObject = nullptr;
Component* eventComponent = nullptr;
GameObject* go = testScene->CreateGameObject("TestObject");
testScene->OnComponentAdded().Subscribe(
[&](GameObject* gameObject, Component* component) {
eventFired = true;
eventGameObject = gameObject;
eventComponent = component;
});
TestComponent* component = go->AddComponent<TestComponent>();
EXPECT_TRUE(eventFired);
EXPECT_EQ(eventGameObject, go);
EXPECT_EQ(eventComponent, component);
}
TEST_F(SceneTest, OnComponentRemoved_Event) {
bool eventFired = false;
GameObject* eventGameObject = nullptr;
Component* eventComponent = nullptr;
GameObject* go = testScene->CreateGameObject("TestObject");
TestComponent* component = go->AddComponent<TestComponent>();
testScene->OnComponentRemoved().Subscribe(
[&](GameObject* gameObject, Component* removedComponent) {
eventFired = true;
eventGameObject = gameObject;
eventComponent = removedComponent;
});
EXPECT_TRUE(go->RemoveComponent(component));
EXPECT_TRUE(eventFired);
EXPECT_EQ(eventGameObject, go);
EXPECT_EQ(eventComponent, component);
}
TEST_F(SceneTest, Save_And_Load) {
GameObject* go = testScene->CreateGameObject("SavedObject");
go->GetTransform()->SetLocalPosition(XCEngine::Math::Vector3(1.0f, 2.0f, 3.0f));
@@ -399,6 +441,12 @@ TEST_F(SceneTest, Save_And_Load_PreservesHierarchyAndComponents) {
light->SetRange(12.0f);
light->SetSpotAngle(45.0f);
light->SetCastsShadows(true);
light->SetOverridesDirectionalShadowSettings(true);
light->SetDirectionalShadowReceiverDepthBias(0.0020f);
light->SetDirectionalShadowNormalBiasScale(1.5f);
light->SetDirectionalShadowStrength(0.7f);
light->SetDirectionalShadowDepthBiasFactor(3.0f);
light->SetDirectionalShadowDepthBiasUnits(5);
GameObject* child = testScene->CreateGameObject("Main Camera", parent);
child->GetTransform()->SetLocalPosition(Vector3(1.0f, 2.0f, 3.0f));
@@ -440,6 +488,12 @@ TEST_F(SceneTest, Save_And_Load_PreservesHierarchyAndComponents) {
EXPECT_FLOAT_EQ(loadedLight->GetRange(), 12.0f);
EXPECT_FLOAT_EQ(loadedLight->GetSpotAngle(), 45.0f);
EXPECT_TRUE(loadedLight->GetCastsShadows());
EXPECT_TRUE(loadedLight->GetOverridesDirectionalShadowSettings());
EXPECT_FLOAT_EQ(loadedLight->GetDirectionalShadowReceiverDepthBias(), 0.0020f);
EXPECT_FLOAT_EQ(loadedLight->GetDirectionalShadowNormalBiasScale(), 1.5f);
EXPECT_FLOAT_EQ(loadedLight->GetDirectionalShadowStrength(), 0.7f);
EXPECT_FLOAT_EQ(loadedLight->GetDirectionalShadowDepthBiasFactor(), 3.0f);
EXPECT_EQ(loadedLight->GetDirectionalShadowDepthBiasUnits(), 5);
auto* loadedCamera = loadedChild->GetComponent<CameraComponent>();
ASSERT_NE(loadedCamera, nullptr);
@@ -468,6 +522,12 @@ TEST_F(SceneTest, SerializeToString_And_DeserializeFromString_PreservesHierarchy
light->SetIntensity(4.0f);
light->SetRange(20.0f);
light->SetCastsShadows(true);
light->SetOverridesDirectionalShadowSettings(true);
light->SetDirectionalShadowReceiverDepthBias(0.0030f);
light->SetDirectionalShadowNormalBiasScale(2.25f);
light->SetDirectionalShadowStrength(0.65f);
light->SetDirectionalShadowDepthBiasFactor(3.75f);
light->SetDirectionalShadowDepthBiasUnits(7);
GameObject* child = testScene->CreateGameObject("Child Camera", parent);
child->SetTag("MainCamera");
@@ -511,6 +571,12 @@ TEST_F(SceneTest, SerializeToString_And_DeserializeFromString_PreservesHierarchy
EXPECT_FLOAT_EQ(loadedLight->GetIntensity(), 4.0f);
EXPECT_FLOAT_EQ(loadedLight->GetRange(), 20.0f);
EXPECT_TRUE(loadedLight->GetCastsShadows());
EXPECT_TRUE(loadedLight->GetOverridesDirectionalShadowSettings());
EXPECT_FLOAT_EQ(loadedLight->GetDirectionalShadowReceiverDepthBias(), 0.0030f);
EXPECT_FLOAT_EQ(loadedLight->GetDirectionalShadowNormalBiasScale(), 2.25f);
EXPECT_FLOAT_EQ(loadedLight->GetDirectionalShadowStrength(), 0.65f);
EXPECT_FLOAT_EQ(loadedLight->GetDirectionalShadowDepthBiasFactor(), 3.75f);
EXPECT_EQ(loadedLight->GetDirectionalShadowDepthBiasUnits(), 7);
auto* loadedCamera = loadedChild->GetComponent<CameraComponent>();
ASSERT_NE(loadedCamera, nullptr);
@@ -521,6 +587,53 @@ TEST_F(SceneTest, SerializeToString_And_DeserializeFromString_PreservesHierarchy
EXPECT_TRUE(loadedCamera->IsPrimary());
}
TEST_F(SceneTest, SerializeToString_And_DeserializeFromString_PreservesPhysicsComponents) {
GameObject* dynamicBody = testScene->CreateGameObject("DynamicBody");
dynamicBody->GetTransform()->SetLocalPosition(Vector3(5.0f, 6.0f, 7.0f));
auto* rigidbody = dynamicBody->AddComponent<RigidbodyComponent>();
rigidbody->SetBodyType(XCEngine::Physics::PhysicsBodyType::Kinematic);
rigidbody->SetMass(2.5f);
rigidbody->SetLinearDamping(0.25f);
rigidbody->SetAngularDamping(0.5f);
rigidbody->SetUseGravity(false);
rigidbody->SetEnableCCD(true);
auto* boxCollider = dynamicBody->AddComponent<BoxColliderComponent>();
boxCollider->SetTrigger(true);
boxCollider->SetCenter(Vector3(1.0f, 2.0f, 3.0f));
boxCollider->SetSize(Vector3(2.0f, 3.0f, 4.0f));
boxCollider->SetStaticFriction(0.8f);
boxCollider->SetDynamicFriction(0.3f);
boxCollider->SetRestitution(0.4f);
const std::string serialized = testScene->SerializeToString();
Scene loadedScene;
loadedScene.DeserializeFromString(serialized);
GameObject* loadedObject = loadedScene.Find("DynamicBody");
ASSERT_NE(loadedObject, nullptr);
auto* loadedRigidbody = loadedObject->GetComponent<RigidbodyComponent>();
ASSERT_NE(loadedRigidbody, nullptr);
EXPECT_EQ(loadedRigidbody->GetBodyType(), XCEngine::Physics::PhysicsBodyType::Kinematic);
EXPECT_FLOAT_EQ(loadedRigidbody->GetMass(), 2.5f);
EXPECT_FLOAT_EQ(loadedRigidbody->GetLinearDamping(), 0.25f);
EXPECT_FLOAT_EQ(loadedRigidbody->GetAngularDamping(), 0.5f);
EXPECT_FALSE(loadedRigidbody->GetUseGravity());
EXPECT_TRUE(loadedRigidbody->GetEnableCCD());
auto* loadedBoxCollider = loadedObject->GetComponent<BoxColliderComponent>();
ASSERT_NE(loadedBoxCollider, nullptr);
EXPECT_TRUE(loadedBoxCollider->IsTrigger());
EXPECT_EQ(loadedBoxCollider->GetCenter(), Vector3(1.0f, 2.0f, 3.0f));
EXPECT_EQ(loadedBoxCollider->GetSize(), Vector3(2.0f, 3.0f, 4.0f));
EXPECT_FLOAT_EQ(loadedBoxCollider->GetStaticFriction(), 0.8f);
EXPECT_FLOAT_EQ(loadedBoxCollider->GetDynamicFriction(), 0.3f);
EXPECT_FLOAT_EQ(loadedBoxCollider->GetRestitution(), 0.4f);
}
TEST_F(SceneTest, SerializeToString_And_DeserializeFromString_PreservesUUIDs) {
GameObject* parent = testScene->CreateGameObject("Parent");
GameObject* child = testScene->CreateGameObject("Child", parent);