Fixes rotation bug with GUI
This commit is contained in:
@@ -207,7 +207,10 @@ namespace fgl::engine::gui
|
||||
|
||||
void drawObject( GameObject& game_object )
|
||||
{
|
||||
ImGui::InputText( "Name", &( game_object.getName() ) );
|
||||
static std::string name_input_temp { "" };
|
||||
name_input_temp = game_object.getName();
|
||||
ImGui::InputText( "Name", &name_input_temp );
|
||||
if ( game_object.getName() != name_input_temp ) game_object.setName( name_input_temp );
|
||||
|
||||
// Transform - Position
|
||||
dragFloat3( "Position", game_object.getTransform().translation.vec() );
|
||||
|
||||
@@ -18,35 +18,40 @@ namespace fgl::engine::gui
|
||||
enum Axis
|
||||
{
|
||||
Pitch = 0,
|
||||
Roll = 1,
|
||||
Yaw = 2
|
||||
Yaw = 1,
|
||||
Roll = 2
|
||||
};
|
||||
|
||||
float dat[ 3 ] { rot.pitch(), rot.roll(), rot.yaw() };
|
||||
const float c_dat[ 3 ] { dat[ Pitch ], dat[ Roll ], dat[ Yaw ] };
|
||||
glm::vec3 dat { rot.euler() };
|
||||
const glm::vec3 c_dat { dat };
|
||||
|
||||
constexpr float speed { 0.01f };
|
||||
|
||||
ImGui::DragFloat3( label, dat, speed );
|
||||
assert( &dat.x + 1 == &dat.y );
|
||||
assert( &dat.y + 1 == &dat.z );
|
||||
|
||||
const float diff[ 3 ] { c_dat[ Pitch ] - dat[ Pitch ], c_dat[ Roll ] - dat[ Roll ], c_dat[ Yaw ] - dat[ Yaw ] };
|
||||
ImGui::DragFloat3( label, &dat.x, speed );
|
||||
|
||||
const glm::vec3 diff { c_dat - dat };
|
||||
constexpr float epsilon { std::numeric_limits< float >::epsilon() };
|
||||
const bool changed[ 3 ] { diff[ Pitch ] > epsilon || diff[ Pitch ]< -epsilon, diff[ Roll ] > epsilon
|
||||
|| diff[ Roll ]< -epsilon, diff[ Yaw ] > epsilon || diff[ Yaw ] < -epsilon };
|
||||
|
||||
const glm::vec< 3, bool > changed_high { glm::greaterThanEqual( diff, glm::vec3( epsilon ) ) };
|
||||
const glm::vec< 3, bool > changed_low { glm::lessThanEqual( diff, glm::vec3( -epsilon ) ) };
|
||||
const glm::vec< 3, bool > changed { changed_high || changed_low };
|
||||
|
||||
if ( changed[ Pitch ] )
|
||||
{
|
||||
rot.pitch() += diff[ Pitch ];
|
||||
rot.pitch() = dat[ Pitch ];
|
||||
}
|
||||
|
||||
if ( changed[ Roll ] )
|
||||
{
|
||||
rot.roll() += diff[ Roll ];
|
||||
rot.roll() = dat[ Roll ];
|
||||
}
|
||||
|
||||
if ( changed[ Yaw ] )
|
||||
{
|
||||
rot.yaw() += diff[ Yaw ];
|
||||
rot.yaw() = dat[ Yaw ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace fgl::engine
|
||||
|
||||
std::vector< GameObjectComponentPtr > components {};
|
||||
|
||||
std::string name {};
|
||||
std::string m_name {};
|
||||
|
||||
explicit GameObject( GameObjectID obj_id ) : m_id( obj_id ) {}
|
||||
|
||||
@@ -137,7 +137,9 @@ namespace fgl::engine
|
||||
GameObjectID getId() const { return m_id; }
|
||||
|
||||
//! Returns the name of the game object. If no name is set then the name of the model is used.
|
||||
std::string& getName() { return name; }
|
||||
const std::string& getName() const { return m_name; }
|
||||
|
||||
void setName( const std::string& name ) { m_name = name; }
|
||||
|
||||
// void drawImGui();
|
||||
};
|
||||
|
||||
@@ -467,7 +467,10 @@ namespace fgl::engine
|
||||
static_cast< float >( translation[ 1 ] ),
|
||||
static_cast< float >( translation[ 2 ] ) );
|
||||
|
||||
obj.getName() = node.name;
|
||||
if ( node.name.empty() )
|
||||
obj.setName( "Unnamed Game Object" );
|
||||
else
|
||||
obj.setName( node.name );
|
||||
|
||||
this->game_objects.emplace_back( std::move( obj ) );
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
Rotation::Rotation() : glm::quat( 1.0f, 0.0f, 0.0f, 0.0f )
|
||||
{}
|
||||
|
||||
@@ -50,13 +49,18 @@ namespace fgl::engine
|
||||
return glm::atan( y, x );
|
||||
}
|
||||
|
||||
inline glm::vec3 eulerAngles( const glm::quat& quat )
|
||||
{
|
||||
return { pitch( quat ), roll( quat ), yaw( quat ) };
|
||||
}
|
||||
|
||||
// Because of how glm does stuff. We need to invert the roll.
|
||||
Rotation::Rotation( const float pitch, const float roll, const float yaw ) :
|
||||
glm::quat( buildQuat( { pitch, roll, yaw } ) )
|
||||
{
|
||||
FGL_ASSERT( ::fgl::engine::pitch( *this ) - pitch < glm::epsilon< float >() );
|
||||
FGL_ASSERT( ::fgl::engine::yaw( *this ) - yaw < glm::epsilon< float >() );
|
||||
FGL_ASSERT( ::fgl::engine::roll( *this ) - roll < glm::epsilon< float >() );
|
||||
FGL_ASSERT( ::fgl::engine::roll( *this ) - roll < glm::epsilon< float >() );
|
||||
}
|
||||
|
||||
RotationModifier< RotationModifierType::Roll > Rotation::roll()
|
||||
@@ -89,6 +93,127 @@ namespace fgl::engine
|
||||
return ConstRotationModifier< RotationModifierType::Yaw >( *this );
|
||||
}
|
||||
|
||||
template < RotationModifierType ModifierType, bool is_const >
|
||||
Rotation& RotationModifier< ModifierType, is_const >::operator+=( const float scalar )
|
||||
{
|
||||
if constexpr ( is_const )
|
||||
{
|
||||
// We should never be in this function if we are attempting to modify a const rotation
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
const glm::quat modifier { glm::angleAxis( scalar, getModifierAxis< ModifierType >() ) };
|
||||
|
||||
switch ( ModifierType )
|
||||
{
|
||||
case Pitch:
|
||||
[[fallthrough]];
|
||||
case Roll:
|
||||
rot = static_cast< glm::quat >( rot ) * modifier; // local
|
||||
break;
|
||||
case Yaw:
|
||||
rot = modifier * static_cast< glm::quat >( rot ); // global
|
||||
break;
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
|
||||
return rot;
|
||||
}
|
||||
}
|
||||
|
||||
template < RotationModifierType ModifierType, bool is_const >
|
||||
Rotation& RotationModifier< ModifierType, is_const >::operator-=( const float scalar )
|
||||
{
|
||||
if constexpr ( is_const )
|
||||
{
|
||||
// We should never be in this function if we are attempting to modify a const rotation
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto modifier { glm::angleAxis( -scalar, getModifierAxis< ModifierType >() ) };
|
||||
|
||||
switch ( ModifierType )
|
||||
{
|
||||
case Pitch:
|
||||
[[fallthrough]];
|
||||
case Roll:
|
||||
rot = static_cast< glm::quat >( rot ) * modifier; // local
|
||||
break;
|
||||
case Yaw:
|
||||
rot = modifier * static_cast< glm::quat >( rot ); // global
|
||||
break;
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
return rot;
|
||||
}
|
||||
}
|
||||
|
||||
template < RotationModifierType ModifierType, bool is_const >
|
||||
Rotation& RotationModifier< ModifierType, is_const >::operator=( const float scalar )
|
||||
{
|
||||
if constexpr ( is_const )
|
||||
{
|
||||
// We should never be in this function if we are attempting to modify a const rotation
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
glm::vec3 euler { ::fgl::engine::eulerAngles( rot ) };
|
||||
|
||||
switch ( ModifierType )
|
||||
{
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
case Pitch:
|
||||
euler.x = scalar;
|
||||
break;
|
||||
case Roll:
|
||||
euler.y = scalar;
|
||||
break;
|
||||
case Yaw:
|
||||
euler.z = scalar;
|
||||
break;
|
||||
}
|
||||
|
||||
rot = { euler };
|
||||
|
||||
return rot;
|
||||
}
|
||||
}
|
||||
|
||||
template < RotationModifierType ModifierType, bool is_const >
|
||||
FGL_FORCE_INLINE_FLATTEN inline RotationModifier< ModifierType, is_const >::operator float() const
|
||||
{
|
||||
return value();
|
||||
}
|
||||
|
||||
template < RotationModifierType ModifierType, bool is_const >
|
||||
float RotationModifier< ModifierType, is_const >::value() const
|
||||
{
|
||||
switch ( ModifierType )
|
||||
{
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
case Pitch:
|
||||
return glm::pitch( rot );
|
||||
case Roll:
|
||||
return glm::roll( rot );
|
||||
case Yaw:
|
||||
return glm::yaw( rot );
|
||||
}
|
||||
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
|
||||
glm::vec3 Rotation::euler() const
|
||||
{
|
||||
return { pitch(), roll(), yaw() };
|
||||
}
|
||||
|
||||
Rotation& Rotation::operator=( const Rotation& rotation )
|
||||
{
|
||||
glm::quat::operator=( rotation );
|
||||
@@ -135,4 +260,11 @@ namespace fgl::engine
|
||||
return Rotation( glm::normalize( static_cast< glm::quat >( *this ) * static_cast< glm::quat >( other ) ) );
|
||||
}
|
||||
|
||||
template class RotationModifier< RotationModifierType::Pitch, false >;
|
||||
template class RotationModifier< RotationModifierType::Roll, false >;
|
||||
template class RotationModifier< RotationModifierType::Yaw, false >;
|
||||
template class RotationModifier< RotationModifierType::Pitch, true >;
|
||||
template class RotationModifier< RotationModifierType::Roll, true >;
|
||||
template class RotationModifier< RotationModifierType::Yaw, true >;
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -70,6 +70,8 @@ namespace fgl::engine
|
||||
RotationModifier< RotationModifierType::Yaw > yaw();
|
||||
ConstRotationModifier< RotationModifierType::Yaw > yaw() const;
|
||||
|
||||
glm::vec3 euler() const;
|
||||
|
||||
Rotation& operator=( const Rotation& rotation );
|
||||
Rotation& operator=( const glm::quat& rotation );
|
||||
|
||||
@@ -129,102 +131,17 @@ namespace fgl::engine
|
||||
|
||||
public:
|
||||
|
||||
Rotation& operator+=( const float scalar )
|
||||
{
|
||||
static_assert( !is_const, "Cannot perform operator-= on a const rotation" );
|
||||
Rotation& operator+=( const float scalar );
|
||||
|
||||
const glm::quat modifier { glm::angleAxis( scalar, getModifierAxis< ModifierType >() ) };
|
||||
Rotation& operator-=( const float scalar );
|
||||
|
||||
switch ( ModifierType )
|
||||
{
|
||||
case Pitch:
|
||||
[[fallthrough]];
|
||||
case Roll:
|
||||
rot = static_cast< glm::quat >( rot ) * modifier; // local
|
||||
break;
|
||||
case Yaw:
|
||||
rot = modifier * static_cast< glm::quat >( rot ); // global
|
||||
break;
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
|
||||
return rot;
|
||||
}
|
||||
|
||||
Rotation& operator-=( const float scalar )
|
||||
{
|
||||
static_assert( !is_const, "Cannot perform operator-= on a const rotation" );
|
||||
|
||||
const auto modifier { glm::angleAxis( -scalar, getModifierAxis< ModifierType >() ) };
|
||||
|
||||
switch ( ModifierType )
|
||||
{
|
||||
case Pitch:
|
||||
[[fallthrough]];
|
||||
case Roll:
|
||||
rot = static_cast< glm::quat >( rot ) * modifier; // local
|
||||
break;
|
||||
case Yaw:
|
||||
rot = modifier * static_cast< glm::quat >( rot ); // global
|
||||
break;
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
return rot;
|
||||
}
|
||||
|
||||
Rotation& operator=( const float scalar )
|
||||
{
|
||||
glm::vec3 euler { glm::eulerAngles( rot ) };
|
||||
|
||||
switch ( ModifierType )
|
||||
{
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
case Pitch:
|
||||
euler.x = scalar;
|
||||
break;
|
||||
case Roll:
|
||||
euler.y = scalar;
|
||||
break;
|
||||
case Yaw:
|
||||
euler.z = scalar;
|
||||
break;
|
||||
}
|
||||
|
||||
return rot;
|
||||
}
|
||||
Rotation& operator=( const float scalar );
|
||||
|
||||
operator float() const;
|
||||
|
||||
float value() const;
|
||||
};
|
||||
|
||||
template < RotationModifierType ModifierType, bool is_const >
|
||||
FGL_FORCE_INLINE_FLATTEN inline RotationModifier< ModifierType, is_const >::operator float() const
|
||||
{
|
||||
return value();
|
||||
}
|
||||
|
||||
template < RotationModifierType ModifierType, bool is_const >
|
||||
float RotationModifier< ModifierType, is_const >::value() const
|
||||
{
|
||||
switch ( ModifierType )
|
||||
{
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
case Pitch:
|
||||
return glm::pitch( rot );
|
||||
case Roll:
|
||||
return glm::roll( rot );
|
||||
case Yaw:
|
||||
return glm::yaw( rot );
|
||||
}
|
||||
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
|
||||
namespace constants
|
||||
{
|
||||
constexpr glm::vec3 DEFAULT_ROTATION { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
Reference in New Issue
Block a user