UI - Refactoring progress
(see previous log message)
This commit is contained in:
parent
c465a38306
commit
30699ee8df
5 changed files with 201 additions and 166 deletions
121
camera.cc
121
camera.cc
|
@ -78,124 +78,3 @@ void T_Camera::cvtVectorsToAngles( ) noexcept
|
|||
|
||||
angles_ = nAngles * 180.f / float( M_PI );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
void T_Camera::handleDragAndDrop(
|
||||
ImVec2 const& move ,
|
||||
T_KeyboardModifiers modifiers ,
|
||||
T_MouseButtons buttons ) noexcept
|
||||
{
|
||||
if ( move.x == 0 || move.y == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float fdx( move.x * .1f * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f ) );
|
||||
const float fdy( move.y * .1f * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f ) );
|
||||
|
||||
if ( ( buttons & E_MouseButton::LEFT ) && ( modifiers & E_KeyboardModifier::SHIFT ) ) {
|
||||
// Left mouse button, shift - move camera
|
||||
const auto side( glm::normalize( glm::cross( up_ , dir_ ) ) );
|
||||
lookAt_ += .1f * ( side * fdx + up_ * fdy );
|
||||
} else if ( buttons & E_MouseButton::LEFT ) {
|
||||
// Left mouse button, no shift - change yaw/pitch
|
||||
updateAngle( angles_.y , fdx );
|
||||
updateAngle( angles_.x , fdy );
|
||||
} else if ( buttons & E_MouseButton::RIGHT ) {
|
||||
// Right mouse button - change roll
|
||||
updateAngle( angles_.z , fdx );
|
||||
}
|
||||
cvtAnglesToVectors( );
|
||||
}
|
||||
|
||||
void T_Camera::handleWheel(
|
||||
const float wheel ,
|
||||
T_KeyboardModifiers modifiers ,
|
||||
T_MouseButtons /* buttons */ ) noexcept
|
||||
{
|
||||
const float delta( wheel * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f) );
|
||||
if ( modifiers & E_KeyboardModifier::SHIFT ) {
|
||||
fov_ = std::max( 1.f , std::min( 179.f , fov_ + delta ) );
|
||||
cvtFov2Np( );
|
||||
} else {
|
||||
distance_ = std::max( .01f , distance_ - delta );
|
||||
cvtAnglesToVectors( );
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
T_Camera::T_Changes T_Camera::makeUI( ) noexcept
|
||||
{
|
||||
using namespace ImGui;
|
||||
|
||||
// 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 ] ) {
|
||||
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;
|
||||
}
|
||||
|
|
53
camera.hh
53
camera.hh
|
@ -15,7 +15,7 @@
|
|||
* - position, direction and up vectors
|
||||
* Modifying one of the sets updates the other.
|
||||
*/
|
||||
struct T_Camera : public virtual A_MouseCtrl
|
||||
struct T_Camera
|
||||
{
|
||||
T_Camera( ) noexcept;
|
||||
|
||||
|
@ -40,18 +40,17 @@ struct T_Camera : public virtual A_MouseCtrl
|
|||
|
||||
float fieldOfView( ) const noexcept
|
||||
{ return fov_; }
|
||||
float& fieldOfView( ) noexcept
|
||||
{ return fov_; }
|
||||
float nearPlane( ) const noexcept
|
||||
{ return np_; }
|
||||
float& nearPlane( ) noexcept
|
||||
{ return np_; }
|
||||
|
||||
private:
|
||||
float fov_ = 90.f;
|
||||
float np_;
|
||||
|
||||
void cvtFov2Np( ) noexcept
|
||||
{ np_ = 2 * tanf( M_PI * ( 180.f - fov_ ) / 360.f ); }
|
||||
void cvtNp2Fov( ) noexcept
|
||||
{ fov_ = 180.f - atanf( .5 * np_ ) * 360.f / M_PI; }
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// POSITION AND ORIENTATION
|
||||
|
@ -66,16 +65,31 @@ struct T_Camera : public virtual A_MouseCtrl
|
|||
|
||||
glm::vec3 const& lookAt( ) const noexcept
|
||||
{ return lookAt_; }
|
||||
glm::vec3& lookAt( ) noexcept
|
||||
{ return lookAt_; }
|
||||
|
||||
glm::vec3 const& angles( ) const noexcept
|
||||
{ return angles_; }
|
||||
glm::vec3& angles( ) noexcept
|
||||
{ return angles_; }
|
||||
float distance( ) const noexcept
|
||||
{ return distance_; }
|
||||
float& distance( ) noexcept
|
||||
{ return distance_; }
|
||||
|
||||
glm::vec3 const& position( ) const noexcept
|
||||
{ return pos_; }
|
||||
glm::vec3& position( ) noexcept
|
||||
{ return pos_; }
|
||||
glm::vec3 const& upVector( ) const noexcept
|
||||
{ return up_; }
|
||||
glm::vec3& upVector( ) noexcept
|
||||
{ return up_; }
|
||||
|
||||
glm::vec3 const& direction( ) const noexcept
|
||||
{ return dir_; }
|
||||
glm::vec3& direction( ) noexcept
|
||||
{ return dir_; }
|
||||
|
||||
private:
|
||||
glm::vec3 lookAt_ = glm::vec3( 0 );
|
||||
|
@ -88,28 +102,15 @@ struct T_Camera : public virtual A_MouseCtrl
|
|||
|
||||
glm::mat3x3 rotMat_;
|
||||
|
||||
void cvtAnglesToVectors( ) noexcept;
|
||||
void cvtVectorsToAngles( ) noexcept;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// UI & MOUSE CONTROLS
|
||||
// CONVERSION
|
||||
|
||||
public:
|
||||
enum class E_Changes {
|
||||
FOV ,
|
||||
MATRIX
|
||||
};
|
||||
using T_Changes = T_Flags< E_Changes >;
|
||||
|
||||
T_Changes makeUI( ) noexcept;
|
||||
|
||||
void handleDragAndDrop(
|
||||
ImVec2 const& move ,
|
||||
T_KeyboardModifiers modifiers ,
|
||||
T_MouseButtons buttons ) noexcept override;
|
||||
void handleWheel(
|
||||
float wheel ,
|
||||
T_KeyboardModifiers modifiers ,
|
||||
T_MouseButtons buttons ) noexcept override;
|
||||
void cvtFov2Np( ) noexcept
|
||||
{ np_ = 2 * tanf( M_PI * ( 180.f - fov_ ) / 360.f ); }
|
||||
void cvtNp2Fov( ) noexcept
|
||||
{ fov_ = 180.f - atanf( .5 * np_ ) * 360.f / M_PI; }
|
||||
|
||||
void cvtAnglesToVectors( ) noexcept;
|
||||
void cvtVectorsToAngles( ) noexcept;
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "ui-colorgrading.hh"
|
||||
#include "ui-overrides.hh"
|
||||
#include "ui-sync.hh"
|
||||
#include "ui-utilities.hh"
|
||||
|
||||
#include <imgui_internal.h>
|
||||
|
||||
|
@ -263,7 +264,7 @@ void InputsFromVector_(
|
|||
|
||||
struct T_MouseCam_ : public virtual A_MouseCtrl
|
||||
{
|
||||
T_Camera& camera;
|
||||
T_CameraMouseControl camera;
|
||||
T_CamOverride& ov;
|
||||
|
||||
T_MouseCam_( T_Camera& cam ,
|
||||
|
@ -299,13 +300,14 @@ void T_MouseCam_::handleDragAndDrop(
|
|||
|
||||
auto& sinp( sync.inputs( ) );
|
||||
auto const& ovip{ ov.inputPositions( ) };
|
||||
InputsFromVector_( ov.target( ) , ovip , camera.lookAt( ) );
|
||||
auto& cam{ camera.camera };
|
||||
InputsFromVector_( ov.target( ) , ovip , cam.lookAt( ) );
|
||||
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
|
||||
InputsFromVector_( ov.angles( ) , ovip , camera.angles( ) );
|
||||
sinp[ ovip[ ov.distance( ) ] ] = camera.distance( );
|
||||
InputsFromVector_( ov.angles( ) , ovip , cam.angles( ) );
|
||||
sinp[ ovip[ ov.distance( ) ] ] = cam.distance( );
|
||||
} else {
|
||||
InputsFromVector_( ov.position( ) , ovip , camera.position( ) );
|
||||
InputsFromVector_( ov.up( ) , ovip , camera.upVector( ) );
|
||||
InputsFromVector_( ov.position( ) , ovip , cam.position( ) );
|
||||
InputsFromVector_( ov.up( ) , ovip , cam.upVector( ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,22 +325,23 @@ void T_MouseCam_::handleWheel(
|
|||
camera.handleWheel( wheel , modifiers , buttons );
|
||||
|
||||
auto& sinp( sync.inputs( ) );
|
||||
auto& cam{ camera.camera };
|
||||
auto const& ovip{ ov.inputPositions( ) };
|
||||
if ( modifiers & E_KeyboardModifier::SHIFT ) {
|
||||
auto const& fc( ov.fovConfig( ) );
|
||||
if ( fc.mode == T_CamOverride::FM_FOV ) {
|
||||
sinp[ ovip[ fc.inputIndex ] ] = camera.fieldOfView( );
|
||||
sinp[ ovip[ fc.inputIndex ] ] = cam.fieldOfView( );
|
||||
} else {
|
||||
sinp[ ovip[ fc.inputIndex ] ] = camera.nearPlane( );
|
||||
sinp[ ovip[ fc.inputIndex ] ] = cam.nearPlane( );
|
||||
}
|
||||
} else {
|
||||
InputsFromVector_( ov.target( ) , ovip , camera.lookAt( ) );
|
||||
InputsFromVector_( ov.target( ) , ovip , cam.lookAt( ) );
|
||||
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
|
||||
InputsFromVector_( ov.angles( ) , ovip , camera.angles( ) );
|
||||
sinp[ ovip[ ov.distance( ) ] ] = camera.distance( );
|
||||
InputsFromVector_( ov.angles( ) , ovip , cam.angles( ) );
|
||||
sinp[ ovip[ ov.distance( ) ] ] = cam.distance( );
|
||||
} else {
|
||||
InputsFromVector_( ov.position( ) , ovip , camera.position( ) );
|
||||
InputsFromVector_( ov.up( ) , ovip , camera.upVector( ) );
|
||||
InputsFromVector_( ov.position( ) , ovip , cam.position( ) );
|
||||
InputsFromVector_( ov.up( ) , ovip , cam.upVector( ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -389,7 +392,7 @@ M_DECL_SOVUI( Camera )
|
|||
PushID( GetCurrentWindow( )->GetID( name ) );
|
||||
const bool handlerChanged{ Checkbox( "Mouse control" , &mouseHandler ) };
|
||||
Separator( );
|
||||
const auto changes{ camera.makeUI( ) };
|
||||
const auto changes{ CameraUI( camera ) };
|
||||
PopID( );
|
||||
PopItemWidth( );
|
||||
|
||||
|
@ -403,14 +406,14 @@ M_DECL_SOVUI( Camera )
|
|||
}
|
||||
|
||||
// Update values
|
||||
if ( changes & T_Camera::E_Changes::FOV ) {
|
||||
if ( changes & E_CameraChange::FOV ) {
|
||||
if ( fc.mode == T_CamOverride::FM_FOV ) {
|
||||
sinp[ ovip[ fc.inputIndex ] ] = camera.fieldOfView( );
|
||||
} else {
|
||||
sinp[ ovip[ fc.inputIndex ] ] = camera.nearPlane( );
|
||||
}
|
||||
}
|
||||
if ( changes & T_Camera::E_Changes::MATRIX ) {
|
||||
if ( changes & E_CameraChange::MATRIX ) {
|
||||
InputsFromVector_( ov.target( ) , ovip , camera.lookAt( ) );
|
||||
if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) {
|
||||
InputsFromVector_( ov.angles( ) , ovip , camera.angles( ) );
|
||||
|
|
124
ui-utilities.cc
124
ui-utilities.cc
|
@ -1,4 +1,6 @@
|
|||
#include "externals.hh"
|
||||
#include "c-utilities.hh"
|
||||
#include "camera.hh"
|
||||
#include "ui-utilities.hh"
|
||||
|
||||
#include <imgui_internal.h>
|
||||
|
@ -57,3 +59,125 @@ void ImGui::ToolbarSeparator( ) noexcept
|
|||
VerticalSeparator( );
|
||||
SameLine( );
|
||||
}
|
||||
|
||||
|
||||
/*= T_CameraMouseControl =======================================================*/
|
||||
|
||||
void T_CameraMouseControl::handleDragAndDrop(
|
||||
ImVec2 const& move ,
|
||||
T_KeyboardModifiers modifiers ,
|
||||
T_MouseButtons buttons ) noexcept
|
||||
{
|
||||
if ( move.x == 0 || move.y == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float fdx( move.x * .1f * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f ) );
|
||||
const float fdy( move.y * .1f * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f ) );
|
||||
|
||||
if ( ( buttons & E_MouseButton::LEFT ) && ( modifiers & E_KeyboardModifier::SHIFT ) ) {
|
||||
// Left mouse button, shift - move camera
|
||||
const auto side( normalize( cross( camera.upVector( ) , camera.direction( ) ) ) );
|
||||
camera.lookAt( ) += .1f * ( side * fdx + camera.upVector( ) * fdy );
|
||||
} else if ( buttons & E_MouseButton::LEFT ) {
|
||||
// Left mouse button, no shift - change yaw/pitch
|
||||
updateAngle( camera.angles( ).y , fdx );
|
||||
updateAngle( camera.angles( ).x , fdy );
|
||||
} else if ( buttons & E_MouseButton::RIGHT ) {
|
||||
// Right mouse button - change roll
|
||||
updateAngle( camera.angles( ).z , fdx );
|
||||
}
|
||||
camera.cvtAnglesToVectors( );
|
||||
}
|
||||
|
||||
void T_CameraMouseControl::handleWheel(
|
||||
const float wheel ,
|
||||
T_KeyboardModifiers modifiers ,
|
||||
T_MouseButtons /* buttons */ ) noexcept
|
||||
{
|
||||
const float delta( wheel * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f) );
|
||||
if ( modifiers & E_KeyboardModifier::SHIFT ) {
|
||||
camera.fieldOfView( ) = ImClamp( camera.fieldOfView( ) + delta , 1.f , 179.f );
|
||||
camera.cvtFov2Np( );
|
||||
} else {
|
||||
camera.distance( ) = std::max( .01f , camera.distance( ) - delta );
|
||||
camera.cvtAnglesToVectors( );
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
T_CameraChanges CameraUI( T_Camera& camera ) noexcept
|
||||
{
|
||||
using namespace ImGui;
|
||||
|
||||
// What gets changed
|
||||
static const T_CameraChanges changeFlags[] = {
|
||||
E_CameraChange::MATRIX ,
|
||||
{} ,
|
||||
E_CameraChange::MATRIX ,
|
||||
E_CameraChange::MATRIX ,
|
||||
{} ,
|
||||
E_CameraChange::MATRIX ,
|
||||
E_CameraChange::MATRIX ,
|
||||
{} ,
|
||||
E_CameraChange::FOV ,
|
||||
E_CameraChange::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( IM_ARRAYSIZE( changeFlags ) == IM_ARRAYSIZE( changeCalls ) ,
|
||||
"invalid configuration" );
|
||||
|
||||
// Changes (also draws the fields)
|
||||
const bool changed[] = {
|
||||
DragFloat3( "Target" , &camera.lookAt( ).x ) ,
|
||||
( Separator( ) , false ) ,
|
||||
DragFloat( "Distance" , &camera.distance( ) , .1f , .1f , 1e8 , "%.1f" ) ,
|
||||
DragFloat3( "Angles" , &camera.angles( ).x , .01f , -180 , 180 ) ,
|
||||
( Separator( ) , false ) ,
|
||||
DragFloat3( "Position" , &camera.position( ).x ) ,
|
||||
DragFloat3( "Up vector" , &camera.upVector( ).x ) ,
|
||||
( Separator( ) , false ) ,
|
||||
DragFloat( "FoV" , &camera.fieldOfView( ) , .01f , .01f , 179.9f ) ,
|
||||
DragFloat( "Near plane" , &camera.nearPlane( ) , .00001f , .001f , 1e6f ) ,
|
||||
};
|
||||
|
||||
static_assert( IM_ARRAYSIZE( changeFlags ) == IM_ARRAYSIZE( changed ) ,
|
||||
"invalid configuration" );
|
||||
|
||||
T_CameraChanges changes;
|
||||
for ( unsigned i = 0 ; i < IM_ARRAYSIZE( changed ) ; i ++ ) {
|
||||
if ( changed[ i ] ) {
|
||||
switch ( changeCalls[ i ] ) {
|
||||
case CC_NONE: break;
|
||||
case CC_FROM_VECTORS: camera.cvtVectorsToAngles( ); break;
|
||||
case CC_FROM_ANGLES: camera.cvtAnglesToVectors( ); break;
|
||||
case CC_FROM_FOV: camera.cvtFov2Np( ); break;
|
||||
case CC_FROM_NP: camera.cvtNp2Fov( ); break;
|
||||
}
|
||||
changes = changes | changeFlags[ i ];
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
#ifndef REAL_BUILD
|
||||
# include "externals.hh"
|
||||
#endif
|
||||
#include "ui-mousectrl.hh"
|
||||
|
||||
|
||||
/*= UI UTILITIES =============================================================*/
|
||||
|
||||
|
@ -47,3 +46,32 @@ namespace ImGui {
|
|||
err_ , __FILE__ , __LINE__ ); \
|
||||
abort( ); \
|
||||
})
|
||||
|
||||
|
||||
/*= CAMERA ===================================================================*/
|
||||
|
||||
struct T_Camera;
|
||||
|
||||
struct T_CameraMouseControl : public A_MouseCtrl
|
||||
{
|
||||
T_Camera& camera;
|
||||
|
||||
explicit T_CameraMouseControl( T_Camera& cam ) : camera( cam ) {}
|
||||
|
||||
void handleDragAndDrop(
|
||||
ImVec2 const& move ,
|
||||
T_KeyboardModifiers modifiers ,
|
||||
T_MouseButtons buttons ) noexcept override;
|
||||
void handleWheel(
|
||||
float wheel ,
|
||||
T_KeyboardModifiers modifiers ,
|
||||
T_MouseButtons buttons ) noexcept override;
|
||||
};
|
||||
|
||||
enum class E_CameraChange {
|
||||
FOV ,
|
||||
MATRIX
|
||||
};
|
||||
using T_CameraChanges = T_Flags< E_CameraChange >;
|
||||
|
||||
T_CameraChanges CameraUI( T_Camera& camera ) noexcept;
|
||||
|
|
Loading…
Reference in a new issue