diff --git a/control.cc b/control.cc index 5e1be37..50f4914 100644 --- a/control.cc +++ b/control.cc @@ -1,5 +1,6 @@ #include "externals.hh" #include "control.hh" +#include "globals.hh" #include "sync.hh" using namespace cops; @@ -124,7 +125,8 @@ OPLoadInput::OPLoadInput( void OPLoadInput::execute( __rw__ T_Context& ctx ) const { - ctx.opStack.push_back( ctx.sync->valueOf( input , *( ctx.time ) ) ); + const auto i( Globals::Sync( ).inputPos( input ) ); + ctx.opStack.push_back( Globals::Sync( ).inputs( )[ i ] ); } diff --git a/demo.cc b/demo.cc index 3c62500..513aafe 100644 --- a/demo.cc +++ b/demo.cc @@ -1,5 +1,7 @@ #include "externals.hh" #include "demo.hh" +#include "sync.hh" +#include "globals.hh" T_Demo::T_Demo( __rd__ const uint32_t width , @@ -43,21 +45,19 @@ void T_Demo::makeUI( ) void T_Demo::render( ) { + auto& sync( Globals::Sync( ) ); if ( playing ) { const float time = SDL_GetTicks( ) * 1e-3; if ( playingPrevious ) { - const float adv = time - lastFrame; - position = std::min( adv + position , sync.duration( ) ); - if ( position >= sync.duration( ) ) { - playing = false; - } + sync.timeDelta( time - lastFrame ); + playing = !sync.finished( ); } lastFrame = time; } playingPrevious = playing; raymarcher->render( ); - dof->render( position , sync ); + dof->render( ); bloom->render( ); combine->render( ); fxaa->render( ); diff --git a/demo.hh b/demo.hh index e3dec2c..ecb0652 100644 --- a/demo.hh +++ b/demo.hh @@ -41,8 +41,6 @@ struct T_Demo const uint32_t width; const uint32_t height; - T_SyncData sync; - float position = 0; bool playing = false; std::unique_ptr< T_Raymarcher > raymarcher; diff --git a/dof.cc b/dof.cc index 437758a..9cd506e 100644 --- a/dof.cc +++ b/dof.cc @@ -3,6 +3,7 @@ #include "profiling.hh" #include "globals.hh" #include "odbg.hh" +#include "sync.hh" namespace { @@ -37,9 +38,7 @@ T_DoFPass::T_DoFPass( "fullscreen.v.glsl" , "dof-pass2.f.glsl" }); } -void T_DoFPass::render( - __rd__ const float position , - __rd__ T_SyncData const& ) +void T_DoFPass::render( ) { PSTART( ); enum { @@ -112,7 +111,7 @@ void T_DoFPass::render( } ); T_Context ctx; - ctx.store( "time" , position ); + ctx.store( "time" , Globals::Sync( ).time( ) ); ctx.store( "width" , imageInput_.width( ) ); ctx.store( "height" , imageInput_.height( ) ); program.execute( ctx ); diff --git a/dof.hh b/dof.hh index 7c5164d..ffd74ce 100644 --- a/dof.hh +++ b/dof.hh @@ -16,9 +16,7 @@ struct T_DoFPass T_DoFPass( __rw__ T_Texture& imageInput , __rw__ T_Texture& depthInput ); - void render( - __rd__ const float position , - __rd__ T_SyncData const& sync ); + void render( ); void makeUI( ); T_Texture& output( ) { return txOutput_; } diff --git a/globals.cc b/globals.cc index b776ba1..a9e41c1 100644 --- a/globals.cc +++ b/globals.cc @@ -7,11 +7,13 @@ #include "shaders.hh" #include "window.hh" #include "odbg.hh" +#include "sync.hh" std::unique_ptr< T_FilesWatcher > Globals::watcher_; std::unique_ptr< T_Window > Globals::window_; std::unique_ptr< T_Profiler > Globals::profiler_; +std::unique_ptr< T_SyncManager > Globals::sync_; std::unique_ptr< T_TextureManager > Globals::textures_; std::unique_ptr< T_ShaderManager > Globals::shaders_; std::unique_ptr< T_OutputDebugger > Globals::odbg_; @@ -22,6 +24,7 @@ void Globals::Init( ) watcher_ = std::make_unique< T_FilesWatcher >( ); window_ = std::make_unique< T_Window >( ); profiler_ = std::make_unique< T_Profiler >( ); + sync_ = std::make_unique< T_SyncManager >( ); textures_ = std::make_unique< T_TextureManager >( ); shaders_ = std::make_unique< T_ShaderManager >( ); odbg_ = std::make_unique< T_OutputDebugger >( ); diff --git a/globals.hh b/globals.hh index 4b567e4..d67f3f0 100644 --- a/globals.hh +++ b/globals.hh @@ -10,6 +10,7 @@ struct T_Profiler; struct T_TextureManager; struct T_ShaderManager; struct T_OutputDebugger; +struct T_SyncManager; struct Globals @@ -20,6 +21,7 @@ struct Globals static T_FilesWatcher& Watcher( ) { return *watcher_; } static T_Window& Window( ) { return *window_; } static T_Profiler& Profiler( ) { return *profiler_; } + static T_SyncManager& Sync( ) { return *sync_; } static T_TextureManager& Textures( ) { return *textures_; } static T_ShaderManager& Shaders( ) { return *shaders_; } static T_OutputDebugger& ODbg( ) { return *odbg_; } @@ -28,6 +30,7 @@ struct Globals static std::unique_ptr< T_FilesWatcher > watcher_; static std::unique_ptr< T_Window > window_; static std::unique_ptr< T_Profiler > profiler_; + static std::unique_ptr< T_SyncManager > sync_; static std::unique_ptr< T_ShaderManager > shaders_; static std::unique_ptr< T_TextureManager > textures_; static std::unique_ptr< T_OutputDebugger > odbg_; diff --git a/main.cc b/main.cc index 2137092..20a3a53 100644 --- a/main.cc +++ b/main.cc @@ -182,11 +182,12 @@ void T_Main::makeUI( ) if ( demo ) { ImGui::Separator( ); - const float duration( demo->sync.duration( ) ); - if ( ImGui::SliderFloat( "" , &demo->position , 0 , duration , "%.1fs" ) - && demo->position > duration ) { - demo->position = duration; - demo->playing = false; + auto& sync( Globals::Sync( ) ); + const float duration( sync.duration( ) ); + float time( sync.time( ) ); + if ( ImGui::SliderFloat( "" , &time , 0 , duration , "%.1fs" ) ) { + sync.setTime( time ); + demo->playing = demo->playing && ! sync.finished( ); } ImGui::SameLine( ); if ( ImGui::Button( demo->playing ? "Stop" : "Play" ) ) { diff --git a/sync.cc b/sync.cc index 84b2543..48717d9 100644 --- a/sync.cc +++ b/sync.cc @@ -13,6 +13,7 @@ void T_SyncTime::setDuration( time = std::min( time , duration( ) ); } + /*= T_SyncCurves =============================================================*/ void T_SyncCurves::clear( ) @@ -329,144 +330,3 @@ void T_SyncManager::displayOvControls( } } #endif - -/*============================================================================*/ - -const T_SyncVariable T_SyncData::MissingVariable_{ }; - -T_SyncData::T_SyncData( ) - : T_SyncData( 60 * 60 , 1. / 60 ) -{ } - -T_SyncData::T_SyncData( - __rd__ const uint32_t duration , - __rd__ const float units ) noexcept - : duration_( duration ) , units_( units ) -{ } - - -T_SyncData::T_VarHelper_::T_VarHelper_( - __rw__ T_SyncVariable&& v , - __rd__ const uint32_t duration , - __rd__ const uint32_t position ) noexcept - : variable( std::move( v ) ) , position( position ) -{ - const auto n( variable.size( ) ); - uint32_t s = 0; - for ( auto i = 0u ; i < n ; i ++ ) { - auto const& v( variable[ i ] ); - assert( v.nPoints >= 2 ); - assert( v.durations.size( ) == v.nPoints - 1 ); - - const auto nd( v.nPoints - 1 ); - for ( auto j = 0u ; j < nd ; j ++ ) { - segStarts.push_back( s ); - segRefs.push_back( std::make_pair( i , j ) ); - s += v.durations[ j ]; - if ( s > duration ) { - return; - } - } - } -} - - -float T_SyncData::T_VarHelper_::valueAt( - __rd__ const float position , - __rd__ const float units ) const noexcept -{ - // Find segment - const auto tu( uint32_t( floor( position / units ) ) ); - uint32_t s( 0 ); - for ( auto ss : segStarts ) { - if ( ss > tu ) { - break; - } - s ++; - } - assert( s > 0 ); - s --; - const auto sid( segRefs[ s ].first ); - auto const& seg( variable[ sid ] ); - const auto pid( segRefs[ s ].second ); - - // Interpolation factor - const float st( segStarts[ s ] * units ); - const float et( ( segStarts[ s ] + seg.durations[ pid ] ) * units ); - const float v0 = ( position - st ) / ( et - st ); - float v = v0; - if ( seg.type != T_SyncSegment::LINEAR ) { - v *= v0; - if ( seg.type == T_SyncSegment::SMOOTH ) { - v *= 3 - 2 * v0; - } - } - - const float sv( seg.values[ pid ] ); - const float ev( seg.values[ pid + 1 ] ); - return v * ( ev - sv ) + sv; -} - - -void T_SyncData::setSyncVariable( - __rd__ std::string const& name , - __rw__ T_SyncVariable&& variable ) noexcept -{ - variables_.erase( name ); - if ( !variable.empty( ) ) { - variables_.emplace( name , T_VarHelper_{ - std::move( variable ) , duration_ , - uint32_t( variables_.size( ) ) - } ); - } -} - - -T_SyncVariable const& T_SyncData::variable( - __rd__ std::string const& name ) const noexcept -{ - auto pos( variables_.find( name ) ); - if ( pos == variables_.end( ) ) { - return MissingVariable_; - } - return pos->second.variable; -} - -uint32_t T_SyncData::offsetOf( - __rd__ std::string const& name ) const noexcept -{ - auto pos( variables_.find( name ) ); - if ( pos == variables_.end( ) ) { - return 0xffffffff; - } - return pos->second.position; -} - - -float T_SyncData::valueOf( - __rd__ std::string const& name , - __rd__ const float time ) const noexcept -{ - assert( time >= 0 ); - - auto pos( variables_.find( name ) ); - if ( pos == variables_.end( ) ) { - return 0; - } - return pos->second.valueAt( std::min( duration_ * units_ , time ) , units_ ); -} - - -void T_SyncData::computeValues( - __rd__ const float time , - __wr__ std::vector< float >& values ) const noexcept -{ - assert( time >= 0 ); - values.resize( variables_.size( ) ); - auto vit( values.begin( ) ); - const float t( std::min( duration_ * units_ , time ) ); - for ( auto const& var : variables_ ) { - *vit = var.second.valueAt( t , units_ ); - vit ++; - } -} diff --git a/sync.hh b/sync.hh index 08f04f5..93f2d11 100644 --- a/sync.hh +++ b/sync.hh @@ -7,8 +7,8 @@ // Duration and current playing time struct T_SyncTime { - float uDuration = 1e-3f; // Duration - unit size - uint32_t iDuration = 1; // Duration - total units + float uDuration = 1.f / 60.f; // Duration - unit size + uint32_t iDuration = 3600; // Duration - total units float time = 0; void setDuration( @@ -157,6 +157,14 @@ struct T_SyncManager bool finished( ) const noexcept { return time_.time >= time_.duration( ); } + // --------------------------------------------------------------------- + // Value access + + uint32_t inputPos( __rd__ std::string const& name ) const noexcept + { return values_.indexOf( name ); } + std::vector< float > const& inputs( ) const noexcept + { return values_.values; } + // --------------------------------------------------------------------- void updateCurveCaches( ); @@ -264,59 +272,3 @@ struct T_SyncManager __rw__ T_SyncUIOverrides& overrides ); }; #endif - -/*============================================================================*/ - -using T_SyncVariable = std::vector< T_SyncSegment >; -struct T_SyncData -{ - T_SyncData( ); - T_SyncData( - __rd__ const uint32_t duration , - __rd__ const float units ) noexcept; - - float duration( ) const noexcept - { return duration_ * units_; } - - void setSyncVariable( - __rd__ std::string const& name , - __rw__ T_SyncVariable&& variable ) noexcept; - - T_SyncVariable const& variable( - __rd__ std::string const& name ) const noexcept; - uint32_t offsetOf( - __rd__ std::string const& name ) const noexcept; - - float valueOf( - __rd__ std::string const& variable , - __rd__ const float time ) const noexcept; - - void computeValues( - __rd__ const float time , - __wr__ std::vector< float >& values ) const noexcept; - - private: - static const T_SyncVariable MissingVariable_; - - // Caching structure used to access segments - using T_SegRef_ = std::pair< uint32_t , uint32_t >; - struct T_VarHelper_ - { - T_SyncVariable variable; - std::vector< T_SegRef_ > segRefs; - std::vector< float > segStarts; - uint32_t position; - - T_VarHelper_( - __rw__ T_SyncVariable&& variable , - __rd__ const uint32_t duration , - __rd__ const uint32_t position ) noexcept; - float valueAt( - __rd__ const float position , - __rd__ const float units ) const noexcept; - }; - - uint32_t duration_; - float units_; - std::unordered_map< std::string , T_VarHelper_ > variables_; -};