mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 00:49:19 +02:00
Merge pull request #60 from jakubg1/dev
Improve the light blinking algorithm
This commit is contained in:
@@ -418,69 +418,50 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
|
|||||||
// case ls_Off: ustalenie czasu migotania, t<1s (f>1Hz), np. 0.1 => t=0.1 (f=10Hz)
|
// case ls_Off: ustalenie czasu migotania, t<1s (f>1Hz), np. 0.1 => t=0.1 (f=10Hz)
|
||||||
// case ls_On: ustalenie wypełnienia ułamkiem, np. 1.25 => zapalony przez 1/4 okresu
|
// case ls_On: ustalenie wypełnienia ułamkiem, np. 1.25 => zapalony przez 1/4 okresu
|
||||||
// case ls_Blink: ustalenie częstotliwości migotania, f<1Hz (t>1s), np. 2.2 => f=0.2Hz (t=5s)
|
// case ls_Blink: ustalenie częstotliwości migotania, f<1Hz (t>1s), np. 2.2 => f=0.2Hz (t=5s)
|
||||||
float modeintegral, modefractional;
|
|
||||||
for (int idx = 0; idx < iNumLights; ++idx) {
|
for (int idx = 0; idx < iNumLights; ++idx) {
|
||||||
|
float modeintegral;
|
||||||
|
const float modefractional = std::modf(std::abs(lsLights[idx]), &modeintegral);
|
||||||
|
const auto mode = static_cast<TLightState>(modeintegral);
|
||||||
|
if (mode == ls_Dark || mode == ls_Home)
|
||||||
|
continue; // light threshold modes don't use timers
|
||||||
|
|
||||||
modefractional = std::modf( std::abs( lsLights[ idx ] ), &modeintegral );
|
float &opacity { m_lightopacities[ idx ] };
|
||||||
|
float &timer { m_lighttimers[ idx ] };
|
||||||
if( modeintegral >= ls_Dark ) {
|
// Phase logic
|
||||||
// light threshold modes don't use timers
|
float ontime =
|
||||||
continue;
|
modefractional < 0.01f ? fOnTime :
|
||||||
}
|
mode == ls_Off ? modefractional * 0.5f :
|
||||||
auto const mode { static_cast<int>( modeintegral ) };
|
mode == ls_On ? modefractional * (fOnTime + fOffTime) :
|
||||||
|
mode == ls_Blink ? 0.5f / modefractional :
|
||||||
auto &opacity { m_lightopacities[ idx ] };
|
fOnTime; // fallback
|
||||||
auto &timer { m_lighttimers[ idx ] };
|
float offtime =
|
||||||
if( ( modeintegral < ls_Blink ) && ( modefractional < 0.01f ) ) {
|
modefractional < 0.01f ? fOffTime :
|
||||||
// simple flip modes
|
mode == ls_Off ? modefractional * 0.5f :
|
||||||
auto const transitiontime { ( m_transition ? std::min( 0.65f, std::min( fOnTime, fOffTime ) * 0.45f ) : 0.01f ) };
|
mode == ls_On ? (1 - modefractional) * (fOnTime + fOffTime) :
|
||||||
|
mode == ls_Blink ? 0.5f / modefractional :
|
||||||
switch( mode ) {
|
fOffTime; // fallback
|
||||||
case ls_Off: {
|
// Determine whether the light is currently on and update the timers
|
||||||
// reduce to zero
|
bool on = false;
|
||||||
timer = std::max<float>( 0.f, timer - timedelta );
|
if ((mode == ls_Off || mode == ls_On) && modefractional < 0.01f)
|
||||||
break;
|
on = mode == ls_On;
|
||||||
}
|
|
||||||
case ls_On: {
|
|
||||||
// increase to max value
|
|
||||||
timer = std::min<float>( transitiontime, timer + timedelta );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opacity = timer / transitiontime;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
// blink modes
|
timer = fmod(timer + timedelta, ontime + offtime); // 0..(ontime+offtime)
|
||||||
auto const ontime { (
|
const float time = fmod(timer + ( lsLights[ idx ] > 0.f ? 0.f : 0.5f ), ontime + offtime); // time with correction for phase shift for negative light values
|
||||||
( mode == ls_Blink ) ? ( ( modefractional < 0.01f ) ? fOnTime : ( 1.f / modefractional ) * 0.5f ) :
|
on = time < ontime;
|
||||||
( mode == ls_Off ) ? modefractional * 0.5f :
|
|
||||||
( mode == ls_On ) ? modefractional * ( fOnTime + fOffTime ) :
|
|
||||||
fOnTime ) }; // fallback
|
|
||||||
auto const offtime { (
|
|
||||||
( mode == ls_Blink ) ? ( ( modefractional < 0.01f ) ? fOffTime : ontime ) :
|
|
||||||
( mode == ls_Off ) ? ontime :
|
|
||||||
( mode == ls_On ) ? ( fOnTime + fOffTime ) - ontime :
|
|
||||||
fOffTime ) }; // fallback
|
|
||||||
auto const transitiontime { ( m_transition ? std::min(0.65f, std::min( ontime, offtime ) * 0.45f ) : 0.01f ) };
|
|
||||||
|
|
||||||
timer = fmod(timer + timedelta * ( lsLights[ idx ] > 0.f ? 1.f : -1.f ), ontime + offtime);
|
|
||||||
// set opacity depending on blink stage
|
|
||||||
if( timer < ontime ) {
|
|
||||||
// blink on
|
|
||||||
opacity = clamp( timer / transitiontime, 0.f, 1.f );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// blink off
|
|
||||||
opacity = 1.f - clamp( ( timer - ontime ) / transitiontime, 0.f, 1.f );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// Update the light brightness
|
||||||
|
const float transitionontime = std::min(0.25f, std::min(ontime, offtime) * 0.95f);
|
||||||
|
const float transitionofftime = std::min(0.45f, std::min(ontime, offtime) * 0.95f);
|
||||||
|
if (on)
|
||||||
|
opacity += m_transition ? timedelta / transitionontime : 1.f; // increase to max value
|
||||||
|
else
|
||||||
|
opacity -= m_transition ? timedelta / transitionofftime : 1.f; // reduce to zero
|
||||||
|
// Clamp the opacity
|
||||||
|
opacity = clamp(opacity, 0.f, 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość
|
// Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość
|
||||||
for (auto entry : m_animlist) {
|
for (const auto entry : m_animlist) {
|
||||||
if (!entry->evDone) // jeśli jest bez eventu
|
if (!entry->evDone) // jeśli jest bez eventu
|
||||||
entry->UpdateModel(); // przeliczenie animacji każdego submodelu
|
entry->UpdateModel(); // przeliczenie animacji każdego submodelu
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user