Overrides - Camera UI
Camera control using the input overrides panel works, although the controls are a bit too sensitive (and there's a risk of fucking things up with bad Up vectors)
This commit is contained in:
parent
b954f20e0e
commit
aa58b016c2
4 changed files with 165 additions and 19 deletions
83
camera.cc
83
camera.cc
|
@ -27,13 +27,13 @@ void T_Camera::camera(
|
|||
}
|
||||
|
||||
void T_Camera::camera(
|
||||
glm::vec3 const& lookAt ,
|
||||
glm::vec3 const& position ,
|
||||
glm::vec3 const& target ,
|
||||
glm::vec3 const& up ) noexcept
|
||||
{
|
||||
pos_ = position;
|
||||
up_ = up;
|
||||
lookAt_ = target;
|
||||
lookAt_ = lookAt;
|
||||
cvtVectorsToAngles( );
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ void T_Camera::cvtAnglesToVectors( ) noexcept
|
|||
void T_Camera::cvtVectorsToAngles( ) noexcept
|
||||
{
|
||||
dir_ = lookAt_ - pos_;
|
||||
distance_ = dir_.length( );
|
||||
distance_ = glm::length( dir_ );
|
||||
if ( distance_ == 0 ) {
|
||||
angles_ = glm::vec3( 0 );
|
||||
return;
|
||||
|
@ -71,7 +71,7 @@ void T_Camera::cvtVectorsToAngles( ) noexcept
|
|||
nAngles.z = atan2f( s1 * nDir.x - c1 * up.x ,
|
||||
c1 * up.y - s1 * nDir.y );
|
||||
|
||||
angles_ = nAngles * 360.f / float( M_PI );
|
||||
angles_ = nAngles * 180.f / float( M_PI );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
@ -121,24 +121,77 @@ void T_Camera::handleWheel(
|
|||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
void T_Camera::makeUI( ) noexcept
|
||||
T_Camera::T_Changes T_Camera::makeUI( ) noexcept
|
||||
{
|
||||
using namespace ImGui;
|
||||
|
||||
const bool changed[] = {
|
||||
DragFloat3( "Target" , &lookAt_.x ) ,
|
||||
DragFloat( "Distance" , &distance_ , .1f ,
|
||||
.1f , 1e8 , "%.1f" ) ,
|
||||
DragFloat3( "Angles" , &angles_.x , .01f , -180 , 180 ) ,
|
||||
|
||||
DragFloat( "FoV" , &fov_ , .01f , .01f , 179.9f )
|
||||
// What gets changed
|
||||
static const T_Changes changeFlags[] = {
|
||||
E_Changes::MATRIX ,
|
||||
{} ,
|
||||
E_Changes::MATRIX ,
|
||||
E_Changes::MATRIX ,
|
||||
{} ,
|
||||
E_Changes::MATRIX ,
|
||||
E_Changes::MATRIX ,
|
||||
{} ,
|
||||
E_Changes::FOV ,
|
||||
E_Changes::FOV ,
|
||||
};
|
||||
|
||||
// Which update gets called.
|
||||
enum E_ChangeCall_ {
|
||||
CC_NONE ,
|
||||
CC_FROM_VECTORS ,
|
||||
CC_FROM_ANGLES ,
|
||||
CC_FROM_FOV ,
|
||||
CC_FROM_NP ,
|
||||
};
|
||||
static const E_ChangeCall_ changeCalls[] = {
|
||||
CC_FROM_ANGLES ,
|
||||
CC_NONE ,
|
||||
CC_FROM_ANGLES ,
|
||||
CC_FROM_ANGLES ,
|
||||
CC_NONE ,
|
||||
CC_FROM_VECTORS ,
|
||||
CC_FROM_VECTORS ,
|
||||
CC_NONE ,
|
||||
CC_FROM_FOV ,
|
||||
CC_FROM_NP ,
|
||||
};
|
||||
|
||||
static_assert( sizeof( changeFlags ) / sizeof( T_Changes ) == sizeof( changeCalls ) / sizeof( E_ChangeCall_ ) ,
|
||||
"invalid configuration" );
|
||||
|
||||
// Changes (also draws the fields)
|
||||
const bool changed[] = {
|
||||
DragFloat3( "Target" , &lookAt_.x ) ,
|
||||
( Separator( ) , false ) ,
|
||||
DragFloat( "Distance" , &distance_ , .1f , .1f , 1e8 , "%.1f" ) ,
|
||||
DragFloat3( "Angles" , &angles_.x , .01f , -180 , 180 ) ,
|
||||
( Separator( ) , false ) ,
|
||||
DragFloat3( "Position" , &pos_.x ) ,
|
||||
DragFloat3( "Up vector" , &up_.x ) ,
|
||||
( Separator( ) , false ) ,
|
||||
DragFloat( "FoV" , &fov_ , .01f , .01f , 179.9f ) ,
|
||||
DragFloat( "Near plane" , &np_ , .00001f , .001f , 1e6f ) ,
|
||||
};
|
||||
|
||||
static_assert( sizeof( changeFlags ) / sizeof( T_Changes ) == sizeof( changed ) / sizeof( bool ) ,
|
||||
"invalid configuration" );
|
||||
|
||||
T_Changes changes;
|
||||
for ( unsigned i = 0 ; i < sizeof( changed ) / sizeof( bool ) ; i ++ ) {
|
||||
if ( changed[ i ] ) {
|
||||
#warning fix this shit
|
||||
// FIXME update( );
|
||||
break;
|
||||
switch ( changeCalls[ i ] ) {
|
||||
case CC_NONE: break;
|
||||
case CC_FROM_VECTORS: cvtVectorsToAngles( ); break;
|
||||
case CC_FROM_ANGLES: cvtAnglesToVectors( ); break;
|
||||
case CC_FROM_FOV: cvtFov2Np( ); break;
|
||||
case CC_FROM_NP: cvtNp2Fov( ); break;
|
||||
}
|
||||
changes = changes | changeFlags[ i ];
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
|
25
camera.hh
25
camera.hh
|
@ -62,10 +62,23 @@ struct T_Camera
|
|||
void camera( glm::vec3 const& lookAt ,
|
||||
glm::vec3 const& angles ,
|
||||
float distance ) noexcept;
|
||||
void camera( glm::vec3 const& position ,
|
||||
glm::vec3 const& target ,
|
||||
void camera( glm::vec3 const& lookAt ,
|
||||
glm::vec3 const& position ,
|
||||
glm::vec3 const& up ) noexcept;
|
||||
|
||||
glm::vec3 const& lookAt( ) const noexcept
|
||||
{ return lookAt_; }
|
||||
|
||||
glm::vec3 const& angles( ) const noexcept
|
||||
{ return angles_; }
|
||||
float distance( ) const noexcept
|
||||
{ return distance_; }
|
||||
|
||||
glm::vec3 const& position( ) const noexcept
|
||||
{ return pos_; }
|
||||
glm::vec3 const& upVector( ) const noexcept
|
||||
{ return up_; }
|
||||
|
||||
private:
|
||||
glm::vec3 lookAt_ = glm::vec3( 0 );
|
||||
glm::vec3 angles_ = glm::vec3( 0 );
|
||||
|
@ -84,7 +97,13 @@ struct T_Camera
|
|||
// UI & MOUSE CONTROLS
|
||||
|
||||
public:
|
||||
void makeUI( ) noexcept;
|
||||
enum class E_Changes {
|
||||
FOV ,
|
||||
MATRIX
|
||||
};
|
||||
using T_Changes = T_Flags< E_Changes >;
|
||||
|
||||
T_Changes makeUI( ) noexcept;
|
||||
|
||||
void handleDND(
|
||||
ImVec2 const& move ,
|
||||
|
|
|
@ -1124,5 +1124,72 @@ void T_CamOverride::makeEditWidgets(
|
|||
uint32_t& counter ,
|
||||
T_StringBuilder& sb ) noexcept
|
||||
{
|
||||
#warning implement the fuck
|
||||
auto& sinp( Globals::Sync( ).inputs( ) );
|
||||
|
||||
// Set field of view / near plane
|
||||
auto const& fc( *fovConfig_ );
|
||||
if ( fc.mode == FM_FOV ) {
|
||||
camera_.fieldOfView( sinp[ inputPos_[ fc.inputIndex ] ] );
|
||||
} else {
|
||||
camera_.nearPlane( sinp[ inputPos_[ fc.inputIndex ] ] );
|
||||
}
|
||||
|
||||
// Set camera parameters
|
||||
const glm::vec3 lookAt{ vectorFromInputs( *target_ ) };
|
||||
if ( camMode_ == CM_ANGLES ) {
|
||||
const glm::vec3 angles{ vectorFromInputs( *angles_ ) };
|
||||
const float distance{ sinp[ inputPos_[ *distance_ ] ] };
|
||||
camera_.camera( lookAt , angles , distance );
|
||||
} else {
|
||||
const glm::vec3 position{ vectorFromInputs( *position_ ) };
|
||||
const glm::vec3 up{ vectorFromInputs( *upVector_ ) };
|
||||
camera_.camera( lookAt , position , up );
|
||||
}
|
||||
|
||||
// Draw UI
|
||||
char const* const name( buildLabel( counter , sb ) );
|
||||
using namespace ImGui;
|
||||
PushItemWidth( 0 ); // Compensate for -1
|
||||
PushID( GetCurrentWindow( )->GetID( name ) );
|
||||
const auto changes{ camera_.makeUI( ) };
|
||||
PopID( );
|
||||
PopItemWidth( );
|
||||
|
||||
if ( changes & T_Camera::E_Changes::FOV ) {
|
||||
if ( fc.mode == FM_FOV ) {
|
||||
sinp[ inputPos_[ fc.inputIndex ] ] = camera_.fieldOfView( );
|
||||
} else {
|
||||
sinp[ inputPos_[ fc.inputIndex ] ] = camera_.nearPlane( );
|
||||
}
|
||||
}
|
||||
if ( changes & T_Camera::E_Changes::MATRIX ) {
|
||||
inputsFromVector( *target_ , camera_.lookAt( ) );
|
||||
if ( camMode_ == CM_ANGLES ) {
|
||||
inputsFromVector( *angles_ , camera_.angles( ) );
|
||||
sinp[ inputPos_[ *distance_ ] ] = camera_.distance( );
|
||||
} else {
|
||||
inputsFromVector( *position_ , camera_.position( ) );
|
||||
inputsFromVector( *upVector_ , camera_.upVector( ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 T_CamOverride::vectorFromInputs(
|
||||
T_VectorConfig_ const& vc ) noexcept
|
||||
{
|
||||
auto& sinp( Globals::Sync( ).inputs( ) );
|
||||
return glm::vec3{
|
||||
sinp[ inputPos_[ vc.x ] ] ,
|
||||
sinp[ inputPos_[ vc.y ] ] ,
|
||||
sinp[ inputPos_[ vc.z ] ] };
|
||||
}
|
||||
|
||||
void T_CamOverride::inputsFromVector(
|
||||
T_VectorConfig_ const& vc ,
|
||||
glm::vec3 const& v ) noexcept
|
||||
{
|
||||
auto& sinp( Globals::Sync( ).inputs( ) );
|
||||
sinp[ inputPos_[ vc.x ] ] = v.x;
|
||||
sinp[ inputPos_[ vc.y ] ] = v.y;
|
||||
sinp[ inputPos_[ vc.z ] ] = v.z;
|
||||
}
|
||||
|
|
|
@ -318,6 +318,13 @@ class T_CamOverride : public A_SyncOverride
|
|||
void makeEditWidgets(
|
||||
uint32_t& counter ,
|
||||
T_StringBuilder& sb ) noexcept override;
|
||||
|
||||
private:
|
||||
glm::vec3 vectorFromInputs(
|
||||
T_VectorConfig_ const& inputs ) noexcept;
|
||||
void inputsFromVector(
|
||||
T_VectorConfig_ const& inputs ,
|
||||
glm::vec3 const& vector ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue