engine: sync editor rendering and ui changes

This commit is contained in:
2026-04-08 16:09:15 +08:00
parent 31756847ab
commit 162f1cc12e
153 changed files with 4454 additions and 2990 deletions

View File

@@ -103,6 +103,20 @@ bool ContainsSpriteKind(
});
}
const SceneViewportOverlayLinePrimitive* FindLineStartingAt(
const SceneViewportOverlayFrameData& frameData,
const Math::Vector3& position) {
const auto matchesPosition = [&position](const SceneViewportOverlayLinePrimitive& line) {
return (line.startWorld - position).SqrMagnitude() <= 1e-4f;
};
const auto it = std::find_if(
frameData.worldLines.begin(),
frameData.worldLines.end(),
matchesPosition);
return it != frameData.worldLines.end() ? &(*it) : nullptr;
}
TEST(SceneViewportOverlayProviderRegistryTest, AppendsProvidersInRegistrationOrder) {
EditorContext context;
context.GetSceneManager().NewScene("Overlay Provider Registry");
@@ -186,10 +200,89 @@ TEST(SceneViewportOverlayProviderRegistryTest, LightProviderBuildsSceneIconAndSe
provider->AppendOverlay(buildContext, frameData);
ASSERT_EQ(frameData.worldSprites.size(), 1u);
EXPECT_EQ(frameData.worldSprites[0].textureKind, SceneViewportOverlaySpriteTextureKind::Light);
EXPECT_EQ(frameData.worldSprites[0].textureKind, SceneViewportOverlaySpriteTextureKind::DirectionalLight);
ASSERT_EQ(frameData.handleRecords.size(), 1u);
EXPECT_EQ(frameData.handleRecords[0].entityId, lightEntity->GetID());
EXPECT_GT(frameData.worldLines.size(), 0u);
const SceneViewportOverlayLinePrimitive* connectorLine =
FindLineStartingAt(frameData, lightEntity->GetTransform()->GetPosition());
ASSERT_NE(connectorLine, nullptr);
EXPECT_GT(connectorLine->endWorld.z, connectorLine->startWorld.z);
}
TEST(SceneViewportOverlayProviderRegistryTest, LightProviderBuildsSelectedPointLightHelper) {
EditorContext context;
context.GetSceneManager().NewScene("Point Light Overlay Provider");
auto* lightEntity = context.GetSceneManager().CreateEntity("PointLight");
ASSERT_NE(lightEntity, nullptr);
lightEntity->GetTransform()->SetPosition(Math::Vector3(0.0f, 0.0f, 12.0f));
auto* light = lightEntity->AddComponent<Components::LightComponent>();
ASSERT_NE(light, nullptr);
light->SetLightType(Components::LightType::Point);
light->SetRange(3.5f);
const SceneViewportOverlayData overlay = CreateValidOverlay();
const std::vector<uint64_t> selectedObjectIds = { lightEntity->GetID() };
const SceneViewportOverlayBuildContext buildContext =
CreateBuildContext(context, overlay, selectedObjectIds);
auto provider = CreateSceneViewportLightOverlayProvider();
ASSERT_NE(provider, nullptr);
SceneViewportOverlayFrameData frameData = {};
frameData.overlay = overlay;
provider->AppendOverlay(buildContext, frameData);
ASSERT_EQ(frameData.worldSprites.size(), 1u);
EXPECT_EQ(frameData.worldSprites[0].textureKind, SceneViewportOverlaySpriteTextureKind::PointLight);
ASSERT_EQ(frameData.handleRecords.size(), 1u);
EXPECT_EQ(frameData.handleRecords[0].entityId, lightEntity->GetID());
EXPECT_EQ(frameData.worldLines.size(), 96u);
EXPECT_NEAR(
(frameData.worldLines[0].startWorld - lightEntity->GetTransform()->GetPosition()).Magnitude(),
light->GetRange(),
1e-3f);
}
TEST(SceneViewportOverlayProviderRegistryTest, LightProviderBuildsSelectedSpotLightHelper) {
EditorContext context;
context.GetSceneManager().NewScene("Spot Light Overlay Provider");
auto* lightEntity = context.GetSceneManager().CreateEntity("SpotLight");
ASSERT_NE(lightEntity, nullptr);
lightEntity->GetTransform()->SetPosition(Math::Vector3(0.0f, 0.0f, 6.0f));
auto* light = lightEntity->AddComponent<Components::LightComponent>();
ASSERT_NE(light, nullptr);
light->SetLightType(Components::LightType::Spot);
light->SetRange(4.0f);
light->SetSpotAngle(30.0f);
const SceneViewportOverlayData overlay = CreateValidOverlay();
const std::vector<uint64_t> selectedObjectIds = { lightEntity->GetID() };
const SceneViewportOverlayBuildContext buildContext =
CreateBuildContext(context, overlay, selectedObjectIds);
auto provider = CreateSceneViewportLightOverlayProvider();
ASSERT_NE(provider, nullptr);
SceneViewportOverlayFrameData frameData = {};
frameData.overlay = overlay;
provider->AppendOverlay(buildContext, frameData);
ASSERT_EQ(frameData.worldSprites.size(), 1u);
EXPECT_EQ(frameData.worldSprites[0].textureKind, SceneViewportOverlaySpriteTextureKind::SpotLight);
ASSERT_EQ(frameData.handleRecords.size(), 1u);
EXPECT_EQ(frameData.handleRecords[0].entityId, lightEntity->GetID());
EXPECT_EQ(frameData.worldLines.size(), 37u);
const SceneViewportOverlayLinePrimitive* connectorLine =
FindLineStartingAt(frameData, lightEntity->GetTransform()->GetPosition());
ASSERT_NE(connectorLine, nullptr);
EXPECT_GT(connectorLine->endWorld.z, connectorLine->startWorld.z);
}
TEST(SceneViewportOverlayProviderRegistryTest, TransformGizmoProviderBuildsOverlayFromFormalState) {
@@ -247,7 +340,7 @@ TEST(
EXPECT_EQ(frameData.worldSprites.size(), 2u);
EXPECT_EQ(frameData.handleRecords.size(), 2u);
EXPECT_TRUE(ContainsSpriteKind(frameData, SceneViewportOverlaySpriteTextureKind::Camera));
EXPECT_TRUE(ContainsSpriteKind(frameData, SceneViewportOverlaySpriteTextureKind::Light));
EXPECT_TRUE(ContainsSpriteKind(frameData, SceneViewportOverlaySpriteTextureKind::DirectionalLight));
EXPECT_GT(frameData.worldLines.size(), 12u);
}