Skip to content

Commit

Permalink
manage time cycle in ambience module
Browse files Browse the repository at this point in the history
  • Loading branch information
aduermael authored and gdevillele committed Jan 12, 2024
1 parent 53cda6d commit 80e34c7
Show file tree
Hide file tree
Showing 2 changed files with 318 additions and 120 deletions.
218 changes: 212 additions & 6 deletions lua/modules/ambience.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
local ambience = {}

cycleTickListener = nil

local default = {
sky = {
skyColor = Color(0, 168, 255),
Expand All @@ -17,7 +19,7 @@ local default = {
sun = {
color = Color(255, 247, 204),
intensity = 1.000000,
rotation = Number3(1.061161, 3.089219, 0.000000),
rotation = Rotation(1.061161, 3.089219, 0.000000),
},
ambient = {
color = nil,
Expand Down Expand Up @@ -118,7 +120,7 @@ ambience.dawn = {
sun = {
color = Color(255, 163, 127),
intensity = 1.000000,
rotation = Number3(0.624828, 2.111841, 0.000000),
rotation = Rotation(0.624828, 2.111841, 0.000000),
},
ambient = {
skyLightFactor = 0.100000,
Expand All @@ -144,7 +146,7 @@ ambience.noon = {
sun = {
color = Color(255, 247, 204),
intensity = 1.000000,
rotation = Number3(1.061161, 3.089219, 0.000000),
rotation = Rotation(1.061161, 3.089219, 0.000000),
},
ambient = {
skyLightFactor = 0.100000,
Expand All @@ -170,7 +172,7 @@ ambience.dusk = {
sun = {
color = Color(211, 127, 255),
intensity = 1.000000,
rotation = Number3(0.624827, 4.188794, 0.000000),
rotation = Rotation(0.624827, 4.188794, 0.000000),
},
ambient = {
skyLightFactor = 0.100000,
Expand All @@ -196,7 +198,7 @@ ambience.midnight = {
sun = {
color = Color(27, 7, 76),
intensity = 1.000000,
rotation = Number3(0.816814, 4.712389, 0.000000),
rotation = Rotation(0.816814, 4.712389, 0.000000),
},
ambient = {
skyLightFactor = 0.100000,
Expand All @@ -212,7 +214,7 @@ sun.Type = LightType.Directional
World:AddChild(sun)
ambience.sun = sun

ambience.set = function(_, config)
function applyConfig(config)
-- SKY
Sky.LightColor = config.sky.lightColor or default.sky.lightColor
Sky.SkyColor = config.sky.skyColor or default.sky.skyColor
Expand All @@ -233,6 +235,210 @@ ambience.set = function(_, config)
Light.Ambient.DirectionalLightFactor = config.ambient.dirLightFactor or default.ambient.dirLightFactor
end

function lerp(a, b, t)
return a * (1 - t) + b * t
end

function lerpConfigs(config1, config2, v)
-- SKY

local c = Color(0, 0, 0)

c:Lerp(config1.sky.lightColor or default.sky.lightColor, config2.sky.lightColor or default.sky.lightColor, v)
Sky.LightColor = c

c:Lerp(config1.sky.skyColor or default.sky.skyColor, config2.sky.skyColor or default.sky.skyColor, v)
Sky.SkyColor = c
-- Sky.SkyColor:Lerp(config1.sky.skyColor or default.sky.skyColor, config2.sky.skyColor or default.sky.skyColor, v)

c:Lerp(
config1.sky.horizonColor or default.sky.horizonColor,
config2.sky.horizonColor or default.sky.horizonColor,
v
)
Sky.HorizonColor = c

c:Lerp(config1.sky.abyssColor or default.sky.abyssColor, config2.sky.abyssColor or default.sky.abyssColor, v)
Sky.AbyssColor = c

-- FOG
c:Lerp(config1.fog.color or default.fog.color, config2.fog.color or default.fog.color, v)
Fog.Color = c
Fog.Near = lerp(config1.fog.near or default.fog.near, config2.fog.near or default.fog.near, v)
Fog.Far = lerp(config1.fog.far or default.fog.far, config2.fog.far or default.fog.far, v)

-- SUN
c:Lerp(config1.sun.color or default.sun.color, config2.sun.color or default.sun.color, v)
sun.Color = c
sun.Intensity =
lerp(config1.sun.intensity or default.sun.intensity, config2.sun.intensity or default.sun.intensity, v)

sun.Rotation:Lerp(config1.sun.rotation or default.sun.rotation, config2.sun.rotation or default.sun.rotation, v)

Light.Ambient.SkyLightFactor = lerp(
config1.ambient.skyLightFactor or default.ambient.skyLightFactor,
config2.ambient.skyLightFactor or default.ambient.skyLightFactor,
v
)
Light.Ambient.DirectionalLightFactor = lerp(
config1.ambient.dirLightFactor or default.ambient.dirLightFactor,
config2.ambient.dirLightFactor or default.ambient.dirLightFactor,
v
)
end

ambience.set = function(_, config)
ambience:stopCycle()
applyConfig(config)
end

local defaultCycleAmbiences = {
{
config = ambience.noon,
duration = 10.0, -- in seconds
-- cross-fade with next ambience (total time == fadeOut + next ambience's fadeIn)
fadeOut = 5.0, -- optional, duration * 0.5 by default
fadeIn = 5.0, -- optional, duration * 0.5 by default
},
{
config = ambience.dusk,
duration = 3.0,
},
{
config = ambience.midnight,
duration = 4.0,
},
{
config = ambience.dawn,
duration = 3.0,
},
}

local defaultCycleConfig = {
internalTick = true,
}

ambience.startCycle = function(_, ambiences, config)
ambience:stopCycle()

conf = require("config")
config = conf:merge(defaultCycleConfig, config)

if ambiences == nil then
ambiences = defaultCycleAmbiences
end

local totalTime = 0.0

for _, ambience in ipairs(ambiences) do
if ambience.fadeIn == nil or ambience.fadeOut == nil then
ambience.fadeIn = ambience.duration * 0.5
ambience.fadeOut = ambience.duration * 0.5
end
totalTime = totalTime + ambience.duration
end

local nbAmbiences = #ambiences
local currentAmbience
local previousAmbience
local nextAmbience
local t = 0.0
local subT = 0.0 -- t, in current ambience
local cursor = 0.0 -- t, in current ambience
local fadeDuration
local v

local cycle = {}

cycle.addTime = function(self, dt)
t = t + dt
self:setTime(t)
end

cycle.setTime = function(_, newT)
t = newT % totalTime

cursor = 0.0
for i, ambience in ipairs(ambiences) do
if t > cursor + ambience.duration then
cursor = cursor + ambience.duration
else
subT = t - cursor
currentAmbience = ambiences[i]
if i > 1 then
previousAmbience = ambiences[i - 1]
else
previousAmbience = ambiences[nbAmbiences]
end
if i < nbAmbiences then
nextAmbience = ambiences[i + 1]
else
nextAmbience = ambiences[1]
end
break
end
end

-- while t > currentAmbience.duration do
-- t = t - currentAmbience.duration
-- currentAmbienceIndex = currentAmbienceIndex + 1
-- if currentAmbienceIndex > nbAmbiences then
-- currentAmbienceIndex = 1
-- end
-- currentAmbience = ambiences[currentAmbienceIndex]
-- i = currentAmbienceIndex + 1
-- if i > nbAmbiences then
-- i = 1
-- end
-- nextAmbience = ambiences[i]
-- i = currentAmbienceIndex - 1
-- if i < 1 then
-- i = nbAmbiences
-- end
-- previousAmbience = ambiences[i]
-- end

if subT < currentAmbience.fadeIn then
fadeDuration = previousAmbience.fadeOut + currentAmbience.fadeIn
v = (previousAmbience.fadeOut + subT) / fadeDuration
lerpConfigs(previousAmbience.config, currentAmbience.config, v)
elseif subT > currentAmbience.duration - currentAmbience.fadeOut then
fadeDuration = currentAmbience.fadeOut + nextAmbience.fadeIn
v = (subT - (currentAmbience.duration - currentAmbience.fadeOut)) / fadeDuration
lerpConfigs(currentAmbience.config, nextAmbience.config, v)
else
applyConfig(currentAmbience.config)
end
end

if config.internalTick then
cycleTickListener = LocalEvent:Listen(LocalEvent.Name.Tick, function(dt)
cycle:addTime(dt)
end)
end

return cycle
end

ambience.stopCycle = function()
if cycleTickListener ~= nil then
cycleTickListener:Remove()
cycleTickListener = nil
end
end

ambience.pauseCycle = function()
if cycleTickListener ~= nil then
cycleTickListener:Pause()
end
end

ambience.resumeCycle = function()
if cycleTickListener ~= nil then
cycleTickListener:Resume()
end
end

ambience:set(ambience.noon)

return ambience
Loading

0 comments on commit 80e34c7

Please sign in to comment.