Overrides - Camera configuration
Camera overrides read their configuration from the script and make sure that it is valid.
This commit is contained in:
parent
1078ff67b5
commit
b954f20e0e
4 changed files with 404 additions and 1 deletions
|
@ -63,7 +63,7 @@ struct T_Camera
|
|||
glm::vec3 const& angles ,
|
||||
float distance ) noexcept;
|
||||
void camera( glm::vec3 const& position ,
|
||||
glm::vec3 const& directionOrTarget ,
|
||||
glm::vec3 const& target ,
|
||||
glm::vec3 const& up ) noexcept;
|
||||
|
||||
private:
|
||||
|
|
5
demo.srd
5
demo.srd
|
@ -86,6 +86,11 @@
|
|||
(int "Correction steps" raymarcher-correction
|
||||
(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
|
||||
(min 0) (max 1) (step .000005) (decimals 5))
|
||||
)
|
||||
|
|
288
syncoverrides.cc
288
syncoverrides.cc
|
@ -328,6 +328,135 @@ bool CgSetUnit_( T_SRDParserData const& data )
|
|||
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
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
@ -398,6 +527,10 @@ ebcl::T_SRDParserConfig sov::GetParserConfig( )
|
|||
<< EnterContext( "color-grading" )
|
||||
<< OnEnter( EnterColorGrading_ )
|
||||
<< OnExit( AddColorGrading_ ) )
|
||||
// Camera controls
|
||||
<< ( Rule() << "camera" << Text( ) << EnterContext( "camera" )
|
||||
<< OnEnter( EnterCam_ )
|
||||
<< OnExit( ExitCam_ ) )
|
||||
;
|
||||
|
||||
// Floating point control parameters
|
||||
|
@ -424,6 +557,22 @@ ebcl::T_SRDParserConfig sov::GetParserConfig( )
|
|||
<< ( 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 };
|
||||
}
|
||||
|
||||
|
@ -838,3 +987,142 @@ bool T_ColorGrading::setUnit(
|
|||
assert( v != 0 );
|
||||
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
|
||||
}
|
||||
|
|
110
syncoverrides.hh
110
syncoverrides.hh
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "sync.hh"
|
||||
#include "camera.hh"
|
||||
|
||||
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 =======================================================*/
|
||||
|
||||
// Get a parser configuration that will be able to parse UI override definitions.
|
||||
|
|
Loading…
Reference in a new issue