diff --git a/sync.cc b/sync.cc index a68d015..1761677 100644 --- a/sync.cc +++ b/sync.cc @@ -65,9 +65,9 @@ float T_SyncData::T_VarHelper_::valueAt( const float et( ( segStarts[ s ] + seg.durations[ pid ] ) * units ); const float v0 = ( position - st ) / ( et - st ); float v = v0; - if ( seg.type != E_SyncSegment::LINEAR ) { + if ( seg.type != T_SyncSegment::LINEAR ) { v *= v0; - if ( seg.type == E_SyncSegment::SMOOTH ) { + if ( seg.type == T_SyncSegment::SMOOTH ) { v *= 3 - 2 * v0; } } diff --git a/sync.hh b/sync.hh index 079751f..8e7c6ef 100644 --- a/sync.hh +++ b/sync.hh @@ -4,25 +4,134 @@ #endif -enum class E_SyncSegment +// Definition of a single input - id & range +struct T_SyncInputDfn { - LINEAR , - RAMP , - SMOOTH , - //HERMITE + std::string identifier; + float min = -std::numeric_limits< float >::infinity( ), + max = std::numeric_limits< float >::infinity( ); + + T_SyncInputDfn( __rd__ std::string const& identifier , + __rd__ const float min , + __rd__ const float max ) noexcept + : identifier( identifier ) , min( min ) , max( max ) + { } +}; +using P_SyncInputDfn = std::unique_ptr< T_SyncInputDfn >; + +/*============================================================================*/ + +// Definition of UI overrides for inputs +struct T_SyncUIOverride +{ + enum E_Type { + FLOAT , VEC2 , VEC3 , VEC4 , INT , + COLOR , COLOR_GRADING , CAMERA + }; + + E_Type type; + std::vector< std::string > inputs; + bool enabled; +}; +using P_SyncUIOverride = std::unique_ptr< T_SyncUIOverride >; +using T_SyncUIOverrides = std::vector< P_SyncUIOverride >; + +// UI override sections +struct T_SyncUISection; +using P_SyncUISection = std::unique_ptr< T_SyncUISection >; +using T_SyncUISections = std::vector< P_SyncUISection >; +struct T_SyncUISection +{ + std::string title; + T_SyncUISections subsections; + T_SyncUIOverrides overrides; }; +/*============================================================================*/ + +// Segment of an input's curve struct T_SyncSegment { + enum E_SegmentType + { + LINEAR , + RAMP , + SMOOTH , + //HERMITE + }; + uint32_t nPoints; - E_SyncSegment type; + E_SegmentType type; std::vector< float > values; // nPoints items std::vector< uint32_t > durations; // nPoints - 1 items }; +// An input curve +struct T_SyncCurve +{ + std::string name; + std::vector< T_SyncSegment > segments; +}; + +// Pre-computed data for a curve +struct T_SyncCurveCache +{ + using T_SegRef = std::pair< uint32_t , uint32_t >; + + T_SyncCurve const* variable; + std::vector< T_SegRef > segRefs; + std::vector< float > segStarts; + + T_SyncCurveCache( + __rd__ T_SyncCurve const* const variable , + __rd__ const uint32_t duration , + __rd__ const uint32_t position ) noexcept; + + float valueAt( + __rd__ const float position , + __rd__ const float units ) const noexcept; +}; +using P_SyncCurveCache = std::unique_ptr< T_SyncCurveCache >; + +/*============================================================================*/ + +struct T_SyncManager +{ + float uDuration; // Duration - unit size + uint32_t iDuration; // Duration - total units + + float duration( ) const noexcept + { return uDuration * iDuration; } + + // Sync manager data for an input may include a definition, a curve, + // or both. The idea behind supporting "curve only" is that a curve may + // have been defined for an input that has been removed temporarily + // (e.g. because some include was commented out), in which case we don't + // want to waste it. + struct T_Data + { + P_SyncInputDfn definition; + P_SyncCurveCache curve; + bool overriden; + }; + + // Data and ID<->index map + std::vector< T_Data > data; + std::map< std::string , uint32_t > posMap; + + // Current time & values + float time; + std::vector< float > values; + + // Root of the UI's tree + T_SyncUISections uiRoot; + + void makeUI( ); +}; + +/*============================================================================*/ + using T_SyncVariable = std::vector< T_SyncSegment >; - - struct T_SyncData { T_SyncData( );