Overrides - Camera configuration

Camera overrides read their configuration from the script and make sure
that it is valid.
This commit is contained in:
Emmanuel BENOîT 2017-11-20 10:05:09 +01:00
parent 1078ff67b5
commit b954f20e0e
4 changed files with 404 additions and 1 deletions

View file

@ -63,7 +63,7 @@ struct T_Camera
glm::vec3 const& angles , glm::vec3 const& angles ,
float distance ) noexcept; float distance ) noexcept;
void camera( glm::vec3 const& position , void camera( glm::vec3 const& position ,
glm::vec3 const& directionOrTarget , glm::vec3 const& target ,
glm::vec3 const& up ) noexcept; glm::vec3 const& up ) noexcept;
private: private:

View file

@ -86,6 +86,11 @@
(int "Correction steps" raymarcher-correction (int "Correction steps" raymarcher-correction
(min 0) (max 100) (slider)) (min 0) (max 100) (slider))
) )
(camera "Camera"
(near-plane camera-nearplane)
(position camera-pos-x camera-pos-y camera-pos-z)
(up camera-up-x camera-up-y camera-up-z)
(look-at camera-lookat-x camera-lookat-y camera-lookat-z))
(float "Fog" fog (float "Fog" fog
(min 0) (max 1) (step .000005) (decimals 5)) (min 0) (max 1) (step .000005) (decimals 5))
) )

View file

@ -328,6 +328,135 @@ bool CgSetUnit_( T_SRDParserData const& data )
return true; return true;
} }
/*------------------------------------------------------------------------------*/
using SP_Cam = T_SharedPtr< T_CamOverride >;
bool EnterCam_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
SP_Cam ptr{ NewShared< T_CamOverride >( input[ 1 ].stringValue( ) ) };
ptr->location( ) = input[ 0 ].location( );
*( data.targetData ) = std::move( ptr );
return true;
}
bool ExitCam_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
auto& ov( data.currentData->value< SP_Cam >( ) );
auto& parent( data.targetData->value< SP_Section >( ) );
if ( !ov->isFovConfigured( ) ) {
data.errors.add( "field of view or near plane missing" , input[ 0 ] );
}
if ( !ov->isTargetConfigured( ) ) {
data.errors.add( "target vector missing" , input[ 0 ] );
}
if ( !ov->checkValidConfig( ) ) {
data.errors.add( "invalid camera configuration" , input[ 0 ] );
}
parent->overrides.add( ov.makeOwned( ) );
return true;
}
bool CamSetFov_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
auto& ov( data.currentData->value< SP_Cam >( ) );
const auto s{ ov->setFieldOfView( input[ 1 ].stringValue( ) ) };
if ( s == T_CamOverride::S_DEF ) {
data.errors.add( "field of view or near plane already set" , input[ 0 ] );
} else if ( s == T_CamOverride::S_INPUTS ) {
data.errors.add( "input already in use" , input[ 1 ] );
}
return true;
}
bool CamSetNP_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
auto& ov( data.currentData->value< SP_Cam >( ) );
const auto s{ ov->setNearPlane( input[ 1 ].stringValue( ) ) };
if ( s == T_CamOverride::S_DEF ) {
data.errors.add( "field of view or near plane already set" , input[ 0 ] );
} else if ( s == T_CamOverride::S_INPUTS ) {
data.errors.add( "input already in use" , input[ 1 ] );
}
return true;
}
bool CamSetTarget_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
auto& ov( data.currentData->value< SP_Cam >( ) );
const auto s{ ov->setTarget( input[ 1 ].stringValue( ) ,
input[ 2 ].stringValue( ) ,
input[ 3 ].stringValue( ) ) };
if ( s == T_CamOverride::S_DEF ) {
data.errors.add( "camera target already set" , input[ 0 ] );
} else if ( s == T_CamOverride::S_INPUTS ) {
data.errors.add( "inputs already in use" , input[ 1 ] );
}
return true;
}
bool CamSetPosition_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
auto& ov( data.currentData->value< SP_Cam >( ) );
const auto s{ ov->setPositionVector( input[ 1 ].stringValue( ) ,
input[ 2 ].stringValue( ) , input[ 3 ].stringValue( ) ) };
if ( s == T_CamOverride::S_DEF ) {
data.errors.add( "camera position already set" , input[ 0 ] );
} else if ( s == T_CamOverride::S_INPUTS ) {
data.errors.add( "inputs already in use" , input[ 1 ] );
}
return true;
}
bool CamSetUpVector_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
auto& ov( data.currentData->value< SP_Cam >( ) );
const auto s{ ov->setUpVector( input[ 1 ].stringValue( ) ,
input[ 2 ].stringValue( ) , input[ 3 ].stringValue( ) ) };
if ( s == T_CamOverride::S_DEF ) {
data.errors.add( "'up' vector already set" , input[ 0 ] );
} else if ( s == T_CamOverride::S_INPUTS ) {
data.errors.add( "inputs already in use" , input[ 1 ] );
}
return true;
}
bool CamSetAngles_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
auto& ov( data.currentData->value< SP_Cam >( ) );
const auto s{ ov->setAngles( input[ 1 ].stringValue( ) ,
input[ 2 ].stringValue( ) , input[ 3 ].stringValue( ) ) };
if ( s == T_CamOverride::S_DEF ) {
data.errors.add( "camera angles already set" , input[ 0 ] );
} else if ( s == T_CamOverride::S_INPUTS ) {
data.errors.add( "inputs already in use" , input[ 1 ] );
}
return true;
}
bool CamSetDistance_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
auto& ov( data.currentData->value< SP_Cam >( ) );
const auto s{ ov->setDistance( input[ 1 ].stringValue( ) ) };
if ( s == T_CamOverride::S_DEF ) {
data.errors.add( "camera distance already set" , input[ 0 ] );
} else if ( s == T_CamOverride::S_INPUTS ) {
data.errors.add( "input already in use" , input[ 1 ] );
}
return true;
}
} // namespace } // namespace
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
@ -398,6 +527,10 @@ ebcl::T_SRDParserConfig sov::GetParserConfig( )
<< EnterContext( "color-grading" ) << EnterContext( "color-grading" )
<< OnEnter( EnterColorGrading_ ) << OnEnter( EnterColorGrading_ )
<< OnExit( AddColorGrading_ ) ) << OnExit( AddColorGrading_ ) )
// Camera controls
<< ( Rule() << "camera" << Text( ) << EnterContext( "camera" )
<< OnEnter( EnterCam_ )
<< OnExit( ExitCam_ ) )
; ;
// Floating point control parameters // Floating point control parameters
@ -424,6 +557,22 @@ ebcl::T_SRDParserConfig sov::GetParserConfig( )
<< ( Rule() << "unit" << Numeric( ) << CgSetUnit_ ) << ( Rule() << "unit" << Numeric( ) << CgSetUnit_ )
; ;
// Camera controls
defs.context( "camera" )
<< ( Rule() << "fov" << Word() << CamSetFov_ )
<< ( Rule() << "near-plane" << Word() << CamSetNP_ )
//
<< ( Rule() << ( Alt() << "target" << "look-at" )
<< ( SRD::Times( 3 ) << Word() )
<< CamSetTarget_ )
//
<< ( Rule() << "position" << ( SRD::Times( 3 ) << Word() ) << CamSetPosition_ )
<< ( Rule() << "up" << ( SRD::Times( 3 ) << Word() ) << CamSetUpVector_ )
//
<< ( Rule() << "angles" << ( SRD::Times( 3 ) << Word() ) << CamSetAngles_ )
<< ( Rule() << "distance" << Word() << CamSetDistance_ )
;
return T_SRDParserConfig{ defs }; return T_SRDParserConfig{ defs };
} }
@ -838,3 +987,142 @@ bool T_ColorGrading::setUnit(
assert( v != 0 ); assert( v != 0 );
M_SETOPT_( unit_ , v ); M_SETOPT_( unit_ , v );
} }
/*= T_CamOverride ==============================================================*/
T_CamOverride::T_CamOverride(
T_String const& title ) noexcept
: A_SyncOverride( "cam" , title ) ,
camMode_( CM_INVALID )
{}
/*------------------------------------------------------------------------------*/
T_CamOverride::E_SetState T_CamOverride::setFieldOfView(
T_String const& input ) noexcept
{
if ( fovConfig_ ) {
return S_DEF;
}
if ( inputs_.contains( input ) ) {
return S_INPUTS;
}
fovConfig_.setNew( FM_FOV , inputs_.size( ) );
inputs_.add( input );
return S_OK;
}
T_CamOverride::E_SetState T_CamOverride::setNearPlane(
T_String const& input ) noexcept
{
if ( fovConfig_ ) {
return S_DEF;
}
if ( inputs_.contains( input ) ) {
return S_INPUTS;
}
fovConfig_.setNew( FM_NEARPLANE , inputs_.size( ) );
inputs_.add( input );
return S_OK;
}
/*------------------------------------------------------------------------------*/
T_CamOverride::E_SetState T_CamOverride::setTarget(
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept
{
return setVector( target_ , inX , inY , inZ );
}
/*------------------------------------------------------------------------------*/
T_CamOverride::E_SetState T_CamOverride::setUpVector(
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept
{
return setVector( upVector_ , inX , inY , inZ );
}
T_CamOverride::E_SetState T_CamOverride::setPositionVector(
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept
{
return setVector( position_ , inX , inY , inZ );
}
/*------------------------------------------------------------------------------*/
T_CamOverride::E_SetState T_CamOverride::setAngles(
T_String const& in1 ,
T_String const& in2 ,
T_String const& in3 ) noexcept
{
return setVector( angles_ , in1 , in2 , in3 );
}
T_CamOverride::E_SetState T_CamOverride::setDistance(
T_String const& input ) noexcept
{
if ( distance_ ) {
return S_DEF;
}
if ( inputs_.contains( input ) ) {
return S_INPUTS;
}
distance_ = inputs_.size( );
inputs_.add( input );
return S_OK;
}
/*------------------------------------------------------------------------------*/
bool T_CamOverride::checkValidConfig( ) noexcept
{
if ( camMode_ != CM_INVALID ) {
return true;
}
if ( angles_ && distance_ && !( position_ || upVector_ ) ) {
camMode_ = CM_ANGLES;
} else if ( position_ && upVector_ && !( angles_ || distance_ ) ) {
camMode_ = CM_VECTORS;
}
return ( camMode_ != CM_INVALID );
}
/*------------------------------------------------------------------------------*/
T_CamOverride::E_SetState T_CamOverride::setVector(
T_Optional< T_VectorConfig_ >& vector ,
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept
{
if ( vector ) {
return S_DEF;
}
if ( inputs_.contains( inX ) || inputs_.contains( inY ) || inputs_.contains( inZ ) ) {
return S_INPUTS;
}
const uint32_t s( inputs_.size( ) );
vector.setNew( s , s+1 , s+2 );
inputs_.add( inX );
inputs_.add( inY );
inputs_.add( inZ );
return S_OK;
}
/*------------------------------------------------------------------------------*/
void T_CamOverride::makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept
{
#warning implement the fuck
}

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "sync.hh" #include "sync.hh"
#include "camera.hh"
namespace sov { namespace sov {
@ -211,6 +212,115 @@ class T_ColorGrading : public A_SyncOverride
}; };
/*= CAMERA CONTROLS ============================================================*/
class T_CamOverride : public A_SyncOverride
{
public:
enum E_SetState {
S_OK , // Inputs were set
S_DEF , // Duplicate definition
S_INPUTS , // Duplicate inputs
};
private:
enum E_CamMode_ {
CM_INVALID ,
CM_ANGLES ,
CM_VECTORS
};
enum E_FovMode_ {
FM_INVALID ,
FM_FOV ,
FM_NEARPLANE ,
};
struct T_FovConfig_
{
E_FovMode_ mode;
uint32_t inputIndex;
T_FovConfig_( E_FovMode_ mode , uint32_t idx ) noexcept
: mode( mode ) , inputIndex( idx )
{ assert( mode != FM_INVALID ); }
};
struct T_VectorConfig_
{
uint32_t x , y , z;
T_VectorConfig_( uint32_t x , uint32_t y , uint32_t z ) noexcept
: x(x),y(y),z(z)
{}
};
T_Optional< T_FovConfig_ > fovConfig_;
T_Optional< T_VectorConfig_ > target_;
T_Optional< T_VectorConfig_ > upVector_;
T_Optional< T_VectorConfig_ > position_;
T_Optional< T_VectorConfig_ > angles_;
T_Optional< uint32_t > distance_;
E_CamMode_ camMode_;
T_Camera camera_;
public:
T_CamOverride( T_String const& title ) noexcept;
E_SetState setFieldOfView(
T_String const& input ) noexcept;
E_SetState setNearPlane(
T_String const& input ) noexcept;
E_SetState setTarget(
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept;
E_SetState setUpVector(
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept;
E_SetState setPositionVector(
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept;
E_SetState setAngles(
T_String const& in1 ,
T_String const& in2 ,
T_String const& in3 ) noexcept;
E_SetState setDistance(
T_String const& input ) noexcept;
bool isFovConfigured( ) const noexcept
{ return fovConfig_; }
bool isTargetConfigured( ) const noexcept
{ return target_; }
bool checkValidConfig( ) noexcept;
T_Camera& camData( ) noexcept
{ return camera_; }
T_Camera const& camData( ) const noexcept
{ return camera_; }
private:
E_SetState setVector(
T_Optional< T_VectorConfig_ >& vector ,
T_String const& inX ,
T_String const& inY ,
T_String const& inZ ) noexcept;
protected:
void makeEditWidgets(
uint32_t& counter ,
T_StringBuilder& sb ) noexcept override;
};
/*= PARSER CONFIGURATION =======================================================*/ /*= PARSER CONFIGURATION =======================================================*/
// Get a parser configuration that will be able to parse UI override definitions. // Get a parser configuration that will be able to parse UI override definitions.