Files
EVEngine/test/editor_lighting_target.cpp
T
西风逍遥游andCursor 24502babef Nest satellite packages under their host modules.
Keep CMake module names and trim switches, but stop flattening editing/editor and runtime bridges as top-level src/modules directories. Parent scans skip nested facets so runtime-3d can drop authoring by directory leaf.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 17:56:12 +08:00

107 lines
4.4 KiB
C++

#include "graphics/lighting/editing/LightingTarget.h"
#include "daynight/DayNight.h"
#include "graphics/Light.h"
#include "weather/Weather.h"
#include "zeroerr/assert.h"
#include "zeroerr/unittest.h"
using namespace eve::lighting_editing;
using namespace eve::editing;
namespace {
SelectionSnapshot selection(const LightingPropertyTargetBase& target) {
SelectionSnapshot result;
result.items.push_back({SelectionDomain::Scene, TargetId(target.targetId()), StableId("lighting"),
target.describe().type});
return result;
}
void set(LightingPropertyTargetBase& target, const char* path, EditorValue value) {
auto operation = target.makeSet(selection(target), PropertyPath(path), value, PropertySetMode::Absolute);
REQUIRE(operation.ok());
REQUIRE(target.applyDomainOperation(operation.value()).ok());
}
} // namespace
TEST_CASE("editor.lighting.light3d_properties_validate_snapshot_and_apply_runtime") {
Light3DDocumentTarget document("key-light");
set(document, "light.type", "dir");
set(document, "transform.direction", EditorValue::Array{0.0, -1.0, 0.0});
set(document, "light.color", EditorValue::Array{1.0, 0.8, 0.6, 1.0});
set(document, "light.intensity", 4.0);
set(document, "shadow.cast", true);
set(document, "shadow.strength", 0.75);
CHECK(document.validate().empty());
eve::graphics::Light3D* light = eve::graphics::Light3D::createLight();
REQUIRE(light);
Light3DRuntimeApplier applier;
REQUIRE(applier.apply(document, light).ok());
CHECK_EQ(light->getType(), "dir");
CHECK_EQ(light->getDirY(), -1.f);
CHECK_EQ(light->data()->intensity, 4.f);
CHECK(light->getCastShadow());
CHECK_EQ(light->getShadowStrength(), 0.75f);
const EditorValue snapshot = document.snapshotValue();
Light3DDocumentTarget restored("restored-light");
REQUIRE(restored.loadSnapshot(snapshot).ok());
CHECK_EQ(restored.snapshotValue(), snapshot);
}
TEST_CASE("editor.lighting.light3d_rejects_zero_direction_before_runtime_mutation") {
Light3DDocumentTarget document("invalid-light");
set(document, "transform.direction", EditorValue::Array{0.0, 0.0, 0.0});
REQUIRE(!document.validate().empty());
eve::graphics::Light3D* light = eve::graphics::Light3D::createLight();
REQUIRE(light);
light->setPosition(9.f, 8.f, 7.f);
const auto rejected = Light3DRuntimeApplier{}.apply(document, light);
CHECK_EQ(static_cast<int>(rejected.code()), static_cast<int>(EditorStatus::Rejected));
CHECK_EQ(light->getX(), 9.f);
}
TEST_CASE("editor.lighting.environment_applies_daynight_and_weather_modes") {
EnvironmentDocumentTarget daynightDocument("sky");
set(daynightDocument, "environment.mode", "daynight");
set(daynightDocument, "daynight.time", 18.5);
set(daynightDocument, "daynight.speed", 2.0);
set(daynightDocument, "daynight.turbidity", 6.0);
set(daynightDocument, "environment.exposure", 1.8);
eve::daynight::DayNight daynight;
EnvironmentRuntimeApplier applier;
REQUIRE(applier.applyDayNight(daynightDocument, &daynight).ok());
CHECK_EQ(daynight.getTimeOfDay(), 18.5f);
CHECK_EQ(daynight.getSpeed(), 2.f);
CHECK_EQ(daynight.getTurbidity(), 6.f);
CHECK_EQ(daynight.getSkyExposure(), 1.8f);
EnvironmentDocumentTarget weatherDocument("weather");
set(weatherDocument, "environment.mode", "weather");
set(weatherDocument, "weather.preset", "storm");
set(weatherDocument, "weather.intensity", 0.9);
set(weatherDocument, "weather.wind-speed", 20.0);
set(weatherDocument, "weather.lightning", true);
eve::weather::Weather weather;
REQUIRE(applier.applyWeather(weatherDocument, &weather).ok());
CHECK_EQ(weather.getPreset(), "storm");
CHECK_EQ(weather.getIntensity(), 0.9f);
CHECK_EQ(weather.getWindSpeed(), 20.f);
CHECK(weather.isLightningEnabled());
CHECK_EQ(static_cast<int>(applier.applyDayNight(weatherDocument, &daynight).code()),
static_cast<int>(EditorStatus::Rejected));
}
TEST_CASE("editor.lighting.environment_detects_multiple_environment_owners") {
EnvironmentDocumentTarget document("owners");
set(document, "environment.mode", "daynight");
set(document, "weather.environment-enabled", true);
const auto diagnostics = document.validate();
REQUIRE_EQ(diagnostics.size(), size_t{1});
CHECK_EQ(diagnosticRule(diagnostics.front()).value(), "editor.environment.multiple-owners");
}