diff --git a/Scripts/StandaloneMovementController.cpp b/Scripts/StandaloneMovementController.cpp index 73e4304..7631e76 100644 --- a/Scripts/StandaloneMovementController.cpp +++ b/Scripts/StandaloneMovementController.cpp @@ -27,6 +27,18 @@ ControllerState& getState(int id) { return g_states[id]; } +void bindSettings(ScriptContext& ctx) { + ctx.AutoSetting("moveTuning", moveTuning); + ctx.AutoSetting("lookTuning", lookTuning); + ctx.AutoSetting("capsuleTuning", capsuleTuning); + ctx.AutoSetting("gravityTuning", gravityTuning); + ctx.AutoSetting("enableMouseLook", enableMouseLook); + ctx.AutoSetting("requireMouseButton", requireMouseButton); + ctx.AutoSetting("enforceCollider", enforceCollider); + ctx.AutoSetting("enforceRigidbody", enforceRigidbody); + ctx.AutoSetting("showDebug", showDebug); +} + void ensureComponents(ScriptContext& ctx, float height, float radius) { if (!ctx.object) return; if (enforceCollider) { @@ -46,15 +58,7 @@ void ensureComponents(ScriptContext& ctx, float height, float radius) { } // namespace extern "C" void Script_OnInspector(ScriptContext& ctx) { - ctx.AutoSetting("moveTuning", moveTuning); - ctx.AutoSetting("lookTuning", lookTuning); - ctx.AutoSetting("capsuleTuning", capsuleTuning); - ctx.AutoSetting("gravityTuning", gravityTuning); - ctx.AutoSetting("enableMouseLook", enableMouseLook); - ctx.AutoSetting("requireMouseButton", requireMouseButton); - ctx.AutoSetting("enforceCollider", enforceCollider); - ctx.AutoSetting("enforceRigidbody", enforceRigidbody); - ctx.AutoSetting("showDebug", showDebug); + bindSettings(ctx); ImGui::TextUnformatted("Standalone Movement Controller"); ImGui::Separator(); @@ -77,6 +81,7 @@ extern "C" void Script_OnInspector(ScriptContext& ctx) { void Begin(ScriptContext& ctx, float /*deltaTime*/) { if (!ctx.object) return; + bindSettings(ctx); ControllerState& state = getState(ctx.object->id); if (!state.initialized) { state.pitch = ctx.object->rotation.x; diff --git a/src/Rendering.cpp b/src/Rendering.cpp index b7cc4d4..aa3054f 100644 --- a/src/Rendering.cpp +++ b/src/Rendering.cpp @@ -1097,71 +1097,86 @@ void Renderer::renderSceneInternal(const Camera& camera, const std::vector lights; - lights.reserve(10); + lights.reserve(kMaxLights); + + struct LightCandidate { + LightUniform light; + float distSq = 0.0f; + int id = 0; + }; + std::vector candidates; + candidates.reserve(sceneObjects.size()); for (const auto& obj : sceneObjects) { - if (!obj.enabled) continue; - if (obj.light.enabled && obj.type == ObjectType::DirectionalLight) { + if (!obj.enabled || !obj.light.enabled) continue; + if (obj.type == ObjectType::DirectionalLight) { LightUniform l; l.type = 0; l.dir = forwardFromRotation(obj); l.color = obj.light.color; l.intensity = obj.light.intensity; lights.push_back(l); - if (lights.size() >= 10) break; + if (lights.size() >= kMaxLights) break; + } else if (obj.type == ObjectType::SpotLight) { + LightUniform l; + l.type = 2; + l.pos = obj.position; + l.dir = forwardFromRotation(obj); + l.color = obj.light.color; + l.intensity = obj.light.intensity; + l.range = obj.light.range; + l.inner = glm::cos(glm::radians(obj.light.innerAngle)); + l.outer = glm::cos(glm::radians(obj.light.outerAngle)); + LightCandidate c; + c.light = l; + glm::vec3 delta = obj.position - camera.position; + c.distSq = glm::dot(delta, delta); + c.id = obj.id; + candidates.push_back(c); + } else if (obj.type == ObjectType::PointLight) { + LightUniform l; + l.type = 1; + l.pos = obj.position; + l.color = obj.light.color; + l.intensity = obj.light.intensity; + l.range = obj.light.range; + LightCandidate c; + c.light = l; + glm::vec3 delta = obj.position - camera.position; + c.distSq = glm::dot(delta, delta); + c.id = obj.id; + candidates.push_back(c); + } else if (obj.type == ObjectType::AreaLight) { + LightUniform l; + l.type = 3; // area + l.pos = obj.position; + l.dir = forwardFromRotation(obj); // plane normal + l.color = obj.light.color; + l.intensity = obj.light.intensity; + float sizeHint = glm::max(obj.light.size.x, obj.light.size.y); + l.range = (obj.light.range > 0.0f) ? obj.light.range : glm::max(sizeHint * 2.0f, 1.0f); + l.areaSize = obj.light.size; + l.areaFade = glm::clamp(obj.light.edgeFade, 0.0f, 1.0f); + LightCandidate c; + c.light = l; + glm::vec3 delta = obj.position - camera.position; + c.distSq = glm::dot(delta, delta); + c.id = obj.id; + candidates.push_back(c); } } - if (lights.size() < 10) { - for (const auto& obj : sceneObjects) { - if (!obj.enabled) continue; - if (obj.light.enabled && obj.type == ObjectType::SpotLight) { - LightUniform l; - l.type = 2; - l.pos = obj.position; - l.dir = forwardFromRotation(obj); - l.color = obj.light.color; - l.intensity = obj.light.intensity; - l.range = obj.light.range; - l.inner = glm::cos(glm::radians(obj.light.innerAngle)); - l.outer = glm::cos(glm::radians(obj.light.outerAngle)); - lights.push_back(l); - if (lights.size() >= 10) break; - } - } - } - if (lights.size() < 10) { - for (const auto& obj : sceneObjects) { - if (!obj.enabled) continue; - if (obj.light.enabled && obj.type == ObjectType::PointLight) { - LightUniform l; - l.type = 1; - l.pos = obj.position; - l.color = obj.light.color; - l.intensity = obj.light.intensity; - l.range = obj.light.range; - lights.push_back(l); - if (lights.size() >= 10) break; - } - } - } - if (lights.size() < 10) { - for (const auto& obj : sceneObjects) { - if (!obj.enabled) continue; - if (obj.light.enabled && obj.type == ObjectType::AreaLight) { - LightUniform l; - l.type = 3; // area - l.pos = obj.position; - l.dir = forwardFromRotation(obj); // plane normal - l.color = obj.light.color; - l.intensity = obj.light.intensity; - float sizeHint = glm::max(obj.light.size.x, obj.light.size.y); - l.range = (obj.light.range > 0.0f) ? obj.light.range : glm::max(sizeHint * 2.0f, 1.0f); - l.areaSize = obj.light.size; - l.areaFade = glm::clamp(obj.light.edgeFade, 0.0f, 1.0f); - lights.push_back(l); - if (lights.size() >= 10) break; - } + + if (lights.size() < kMaxLights && !candidates.empty()) { + std::sort(candidates.begin(), candidates.end(), + [](const LightCandidate& a, const LightCandidate& b) { + if (a.distSq != b.distSq) return a.distSq < b.distSq; + return a.id < b.id; + }); + for (const auto& c : candidates) { + if (lights.size() >= kMaxLights) break; + lights.push_back(c.light); } }