demotool/sync.cc

216 lines
5 KiB
C++

#include "externals.hh"
#include "sync.hh"
void T_SyncManager::makeUI( )
{
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
if ( wOverrides ) {
ImGui::SetNextWindowSize( ImVec2( 300 , dspSize.y - 300 ) ,
ImGuiSetCond_Once );
ImGui::SetNextWindowPos( ImVec2( 0 , 150 ) ,
ImGuiSetCond_Once );
ImGui::Begin( "Input overrides" );
displayOvSections( uiRoot , true );
ImGui::End( );
}
if ( wCurves ) {
ImGui::SetNextWindowSize( ImVec2( dspSize.x , 150 ) ,
ImGuiSetCond_Once );
ImGui::SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) ,
ImGuiSetCond_Once );
ImGui::Begin( "Curve editor" );
// XXX contents
ImGui::End( );
}
}
void T_SyncManager::displayOvSections(
__rw__ T_SyncUISections& sections ,
__rd__ const bool topLevel )
{
for ( auto& s : sections ) {
const bool display( topLevel
? ImGui::CollapsingHeader( s->title.c_str( ) )
: ImGui::TreeNode( s->title.c_str( ) ) );
if ( !display ) {
continue;
}
displayOvSections( s->subsections );
if ( s->subsections.size( ) && s->overrides.size( ) ) {
ImGui::Separator( );
}
displayOvControls( s->overrides );
if ( !topLevel ) {
ImGui::TreePop( );
}
}
}
void T_SyncManager::displayOvControls(
__rw__ T_SyncUIOverrides& overrides )
{
for ( auto& o : overrides ) {
// XXX enable override checkbox should be selected and disabled
// if there is no curve
const bool changed( ImGui::Checkbox( "" , &o->enabled ) );
if ( changed ) {
// XXX mark the inputs as coming from the UI / the curves
}
ImGui::SameLine( );
switch ( o->type ) {
case T_SyncUIOverride::FLOAT:
case T_SyncUIOverride::VEC2:
case T_SyncUIOverride::VEC3:
case T_SyncUIOverride::VEC4:
case T_SyncUIOverride::INT:
case T_SyncUIOverride::COLOR:
case T_SyncUIOverride::COLOR_GRADING:
case T_SyncUIOverride::CAMERA:
break;
}
}
}
/*============================================================================*/
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 ++;
}
}