Sequencer - Almost working support for overrides!

This commit is contained in:
Emmanuel BENOîT 2017-11-29 16:07:20 +01:00
parent 88333850b1
commit 14899a530d
5 changed files with 183 additions and 40 deletions

View file

@ -35,11 +35,15 @@ M_DECL_SOVUI( Float )
using namespace ImGui;
auto& ov{ dynamic_cast< T_Float& >( ovp ) };
char const* const label( BuildLabel_( counter , sb ) );
float v{ data[ 0 ] };
const bool changed( ov.slider( )
? SliderFloat( label , &data[ 0 ] , ov.min( ) , ov.max( ) ,
? SliderFloat( label , &v , ov.min( ) , ov.max( ) ,
ov.decimals( ) , ov.power( ) )
: DragFloat( label , &data[ 0 ] , ov.step( ) , ov.min( ) ,
: DragFloat( label , &v , ov.step( ) , ov.min( ) ,
ov.max( ) , ov.decimals( ) , ov.power( ) ) );
if ( changed ) {
data.set( 0 , v );
}
return changed;
}
@ -60,7 +64,7 @@ M_DECL_SOVUI( Float2 )
ov.max( ) , ov.decimals( ) , ov.power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 2 ; i ++ ) {
data[ i ] = v[ i ];
data.set( i , v[ i ] );
}
}
return changed;
@ -83,7 +87,7 @@ M_DECL_SOVUI( Float3 )
ov.max( ) , ov.decimals( ) , ov.power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 3 ; i ++ ) {
data[ i ] = v[ i ];
data.set( i ,v[ i ]);
}
}
return changed;
@ -106,7 +110,7 @@ M_DECL_SOVUI( Float4 )
ov.max( ) , ov.decimals( ) , ov.power( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 4 ; i ++ ) {
data[ i ] = v[ i ];
data.set( i ,v[ i ]);
}
}
return changed;
@ -126,7 +130,7 @@ M_DECL_SOVUI( Integer )
? SliderInt( label , &v , ov.min( ) , ov.max( ) )
: DragInt( label , &v , ov.step( ) , ov.min( ) , ov.max( ) ) );
if ( changed ) {
data[ 0 ] = v;
data.set( 0 ,v);
}
return changed;
}
@ -146,7 +150,7 @@ M_DECL_SOVUI( Integer2 )
: DragInt2( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 2 ; i ++ ) {
data[ i ] = v[ i ];
data.set( i ,v[ i ]);
}
}
return changed;
@ -167,7 +171,7 @@ M_DECL_SOVUI( Integer3 )
: DragInt3( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 3 ; i ++ ) {
data[ i ] = v[ i ];
data.set( i ,v[ i ]);
}
}
return changed;
@ -188,7 +192,7 @@ M_DECL_SOVUI( Integer4 )
: DragInt4( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) );
if ( changed ) {
for ( auto i = 0 ; i < 4 ; i ++ ) {
data[ i ] = v[ i ];
data.set( i ,v[ i ]);
}
}
return changed;
@ -214,7 +218,7 @@ M_DECL_SOVUI( ColorGrading )
if ( changed ) {
for ( auto i = 0 ; i < 3 ; i ++ ) {
data[ i ] = v[ i ];
data.set( i ,v[ i ]);
}
}
return changed;
@ -237,9 +241,9 @@ void InputsFromVector_(
A_SyncData& data ,
glm::vec3 const& v ) noexcept
{
data[ vc.x ] = v.x;
data[ vc.y ] = v.y;
data[ vc.z ] = v.z;
data.set( vc.x ,v.x);
data.set( vc.y ,v.y);
data.set( vc.z ,v.z);
}
/*------------------------------------------------------------------------------*/
@ -285,7 +289,7 @@ void T_MouseCam_::handleDragAndDrop(
InputsFromVector_( ov.target( ) , *data , cam.lookAt( ) );
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
InputsFromVector_( ov.angles( ) , *data , cam.angles( ) );
(*data)[ ov.distance( ) ] = cam.distance( );
data->set( ov.distance( ) ,cam.distance( ));
} else {
InputsFromVector_( ov.position( ) , *data , cam.position( ) );
InputsFromVector_( ov.up( ) , *data , cam.upVector( ) );
@ -308,15 +312,15 @@ void T_MouseCam_::handleWheel(
if ( modifiers & E_KbdMod::SHIFT ) {
auto const& fc( ov.fovConfig( ) );
if ( fc.mode == T_CamOverride::FM_FOV ) {
(*data)[ fc.inputIndex ] = cam.fieldOfView( );
data->set( fc.inputIndex ,cam.fieldOfView( ));
} else {
(*data)[ fc.inputIndex ] = cam.nearPlane( );
data->set( fc.inputIndex ,cam.nearPlane( ));
}
} else {
InputsFromVector_( ov.target( ) , *data , cam.lookAt( ) );
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
InputsFromVector_( ov.angles( ) , *data , cam.angles( ) );
(*data)[ ov.distance( ) ] = cam.distance( );
data->set( ov.distance( ) ,cam.distance( ));
} else {
InputsFromVector_( ov.position( ) , *data , cam.position( ) );
InputsFromVector_( ov.up( ) , *data , cam.upVector( ) );
@ -383,16 +387,16 @@ M_DECL_SOVUI( Camera )
// Update values
if ( changes & E_CameraChange::FOV ) {
if ( fc.mode == T_CamOverride::FM_FOV ) {
data[ fc.inputIndex ] = camera.fieldOfView( );
data.set( fc.inputIndex ,camera.fieldOfView( ));
} else {
data[ fc.inputIndex ] = camera.nearPlane( );
data.set( fc.inputIndex ,camera.nearPlane( ));
}
}
if ( changes & E_CameraChange::MATRIX ) {
InputsFromVector_( ov.target( ) , data , camera.lookAt( ) );
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
InputsFromVector_( ov.angles( ) , data , camera.angles( ) );
data[ ov.distance( ) ] = camera.distance( );
data.set( ov.distance( ) ,camera.distance( ));
} else {
InputsFromVector_( ov.position( ) , data , camera.position( ) );
InputsFromVector_( ov.up( ) , data , camera.upVector( ) );

View file

@ -15,7 +15,8 @@ namespace sov {
virtual ~A_SyncData( ) = 0;
virtual float operator[]( uint32_t index ) const noexcept = 0;
virtual float& operator[]( uint32_t index ) noexcept = 0;
virtual bool set( uint32_t index ,
float value ) noexcept = 0;
virtual T_OwnPtr< A_SyncData > clone( ) const noexcept = 0;
};

View file

@ -6,7 +6,9 @@
#include "ui.hh"
#include "ui-app.hh"
#include "ui-overrides.hh"
#include "ui-sequencer.hh"
#include "ui-sync.hh"
#include "ui-utilities.hh"
#include "ui-imgui-sdl.hh"
@ -145,6 +147,114 @@ bool T_ChangeDurationDialog_::onButton(
}
/*= T_PointData_ =============================================================*/
using T_TempCurveStorage_ = T_AutoArray< T_SyncCurve , 16 >;
class T_PointData_ : public sov::A_SyncData
{
private:
T_Optional< T_SyncTrackId > const& selId_;
T_Optional< uint32_t > const& selSegment_;
T_Optional< uint32_t > const& selPoint_;
T_TempCurveStorage_& cOriginals_;
T_TempCurveStorage_& cCopies_;
T_String useId_;
uint32_t useSegment_;
uint32_t usePoint_;
A_SyncOverride* ovr_;
public:
T_PointData_( T_Optional< T_SyncTrackId > const& selId ,
T_Optional< uint32_t > const& selSegment ,
T_Optional< uint32_t > const& selPoint ,
T_TempCurveStorage_& cOriginals ,
T_TempCurveStorage_& cCopies ) noexcept
: selId_( selId ) , selSegment_( selSegment ) ,
selPoint_( selPoint ) , cOriginals_( cOriginals ) ,
cCopies_( cCopies )
{ }
void use( ) noexcept;
float operator[]( uint32_t index ) const noexcept override;
bool set( uint32_t index , float value ) noexcept override;
T_OwnPtr< sov::A_SyncData > clone( ) const noexcept override;
};
/*----------------------------------------------------------------------------*/
void T_PointData_::use( ) noexcept
{
assert( selId_ && selSegment_ && selPoint_ );
assert( selId_->isOverride );
useId_ = selId_->id;
useSegment_ = *selSegment_;
usePoint_ = *selPoint_;
ovr_ = Common::Sync( ).getOverride( useId_ );
}
float T_PointData_::operator[](
const uint32_t index ) const noexcept
{
if ( !( selId_ && selSegment_ && selPoint_ && selId_->isOverride )
|| useId_ != selId_->id || useSegment_ != *selSegment_
|| usePoint_ != *selPoint_ ) {
return 0.f;
}
auto const& iNames{ ovr_->inputNames( ) };
if ( cCopies_.size( ) != iNames.size( )
|| cCopies_[ 0 ].name != iNames[ 0 ] ) {
auto const& curve{ *Common::Sync( ).getCurve( iNames[ index ] ) };
return curve.segments[ useSegment_ ].values[ usePoint_ ];
}
return cCopies_[ index ].segments[ useSegment_ ].values[ usePoint_ ];
}
bool T_PointData_::set(
const uint32_t index ,
const float value ) noexcept
{
if ( !( selId_ && selSegment_ && selPoint_ && selId_->isOverride )
|| useId_ != selId_->id || useSegment_ != *selSegment_
|| usePoint_ != *selPoint_ ) {
return false;
}
auto const& iNames{ ovr_->inputNames( ) };
const auto nn{ iNames.size( ) };
auto& sync{ Common::Sync( ) };
if ( cCopies_.size( ) != nn || cCopies_[ 0 ].name != iNames[ 0 ] ) {
cOriginals_.clear( );
cCopies_.clear( );
for ( auto i = 0u ; i < nn ; i ++ ) {
auto const* const c{ sync.getCurve( iNames[ i ] ) };
cOriginals_.add( *c );
cCopies_.add( *c );
}
}
cCopies_[ index ].segments[ useSegment_ ].values[ usePoint_ ] = value;
sync.setCurve( cCopies_[ index ] );
return true;
}
T_OwnPtr< sov::A_SyncData > T_PointData_::clone( ) const noexcept
{
auto ptr{ NewOwned< T_PointData_ >( selId_ , selSegment_ ,
selPoint_ , cOriginals_ , cCopies_ ) };
ptr->useId_ = useId_;
ptr->useSegment_ = useSegment_;
ptr->usePoint_ = usePoint_;
return ptr;
}
/*= T_SyncViewImpl_ ==========================================================*/
struct T_SyncViewImpl_
@ -322,8 +432,12 @@ struct T_SyncViewImpl_
// Original and copy of curve being modified
E_ChangeType selUpdate{ E_ChangeType::NONE };
T_AutoArray< T_SyncCurve , 16 > selUpdatingOriginals;
T_AutoArray< T_SyncCurve , 16 > selUpdatingCopies;
T_TempCurveStorage_ selUpdatingOriginals;
T_TempCurveStorage_ selUpdatingCopies;
// Override edition
T_PointData_ selEditor{ selId , selSegment , selPoint ,
selUpdatingOriginals , selUpdatingCopies };
// Sub-windows
E_SubWindow sub{ SW_NONE };
@ -1867,7 +1981,7 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
const uint32_t sid{ *selSegment };
const uint32_t pid{ *selPoint };
auto& sync{ Common::Sync( ) };
auto const* const ovr{ selId->isOverride
auto* const ovr{ selId->isOverride
? sync.getOverride( selId->id )
: nullptr };
auto const* const curve{ selUpdatingCopies.size( )
@ -1927,26 +2041,33 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
Separator( );
// This is here because the curve pointer might get fucked over by
// the override control
const auto canInsertBefore{ pid != 0
&& segment.durations[ pid - 1 ] > 1 };
const auto canInsertAfter{ pid != segment.durations.size( )
&& segment.durations[ pid ] > 1 };
const auto canDelete{ pid != 0 && pid != segment.durations.size( ) };
bool changed;
float value{ segment.values[ pid ] };
float value{ 0 };
if ( ovr ) {
// XXX override control
changed = false;
selEditor.use( );
uint32_t i{ 0 };
changed = (UI::Sync( ).uiFor( *ovr ))(
*ovr , selEditor , i , stringBuffer );
} else {
Text( "Value:" );
SameLine( 110 );
PushItemWidth( -1 );
value = segment.values[ pid ];
DragFloat( "##value" , &value , .01f , 0 , 0 , "%.6f" );
changed = IsItemActive( );
PopItemWidth( );
}
const bool canUseButtons{ !changed && selUpdate == E_ChangeType::NONE };
const auto canInsertBefore{ pid != 0
&& segment.durations[ pid - 1 ] > 1 };
const auto canInsertAfter{ pid != segment.durations.size( )
&& segment.durations[ pid ] > 1 };
if ( pid != 0 && pid != segment.durations.size( ) ) {
if ( canDelete ) {
Separator( );
Text( " " );
SameLine( 110 );
@ -1976,8 +2097,17 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
}
}
if ( changed ) {
if ( ovr && changed ) {
if ( selUpdate == E_ChangeType::NONE ) {
selUpdate = E_ChangeType::POINT_VALUE;
} else {
assert( selUpdate == E_ChangeType::POINT_VALUE );
}
} else if ( changed ) {
if ( selUpdate == E_ChangeType::NONE ) {
assert( selUpdatingOriginals.empty( ) );
assert( selUpdatingCopies.empty( ) );
selUpdatingOriginals.add( *curve );
selUpdatingCopies.add( *curve );
selUpdate = E_ChangeType::POINT_VALUE;
@ -1986,10 +2116,15 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
}
selUpdatingCopies[ 0 ].segments[ sid ].values[ pid ] = value;
sync.setCurve( selUpdatingCopies[ 0 ] );
} else if ( selUpdate == E_ChangeType::POINT_VALUE ) {
selUpdate = E_ChangeType::NONE;
sync.setCurve( selUpdatingOriginals[ 0 ] );
SyncEditor::ReplaceCurve( std::move( selUpdatingCopies[ 0 ] ) );
auto& undo{ dynamic_cast< T_UndoSyncChanges& >(
Common::Undo( ).add< T_UndoSyncChanges >( ) ) };
for ( auto i = 0u ; i < selUpdatingCopies.size( ) ; i ++ ) {
undo.curveReplacement( std::move( selUpdatingOriginals[ i ] ) ,
std::move( selUpdatingCopies[ i ] ) );
}
selUpdatingCopies.clear( );
selUpdatingOriginals.clear( );
}

View file

@ -20,7 +20,7 @@ class T_SyncInputData_ : public sov::A_SyncData
void setFromOverride( A_SyncOverride const& sov ) noexcept;
float operator[]( uint32_t index ) const noexcept override;
float& operator[]( uint32_t index ) noexcept override;
bool set( uint32_t index , float value ) noexcept override;
T_OwnPtr< sov::A_SyncData > clone( ) const noexcept override;
};
@ -46,10 +46,12 @@ float T_SyncInputData_::operator[](
return *ptr_[ index ];
}
float& T_SyncInputData_::operator[](
const uint32_t index ) noexcept
bool T_SyncInputData_::set(
const uint32_t index ,
const float value ) noexcept
{
return *ptr_[ index ];
*ptr_[ index ] = value;
return true;
}
T_OwnPtr< sov::A_SyncData > T_SyncInputData_::clone( ) const noexcept
@ -182,6 +184,7 @@ T_UISync::F_Override T_UISync::uiFor(
return rv ? *rv : []( A_SyncOverride& , sov::A_SyncData& ,
uint32_t& , T_StringBuilder& ) {
ImGui::Text( "(missing UI)" );
return false;
};
}

View file

@ -18,7 +18,7 @@ class T_UISync : public A_MouseCtrl
void makeOverridesWindow( );
using F_Override = std::function<
void( A_SyncOverride& , sov::A_SyncData& , uint32_t& ,
bool( A_SyncOverride& , sov::A_SyncData& , uint32_t& ,
T_StringBuilder& ) >;
F_Override uiFor( A_SyncOverride& target ) const noexcept;