I made C++ rendering application that use one camera. The camera has 3 important members: A position(m_position), an horizontal angle(m_hAngle) and a vertical angle(m_vAngle)
The application currently support “Fly rotation” whick look like this:
https://youtu.be/HdyoTcLq7tg
When rotation should be applied the camera horizontal and vertical angles are updated, but the position remains the same.
I want to support “Orbit rotation” where the camera position is rotated: https://youtu.be/Wq0FxFp5cu8
The C++ class look like this:
class Camera
{
public:
void onMouseMove(const Math::Uvec2& windowSize, const Math::Vec2& mousePos);
Math::Vec3 getCurrentTarget() const;
Math::Vec3 getCurrentDirection() const;
void moveForward(nbFloat32 intensity);
// Fly mode rotation.
void horizontalRotationFly(Math::Radian angle);
void verticalRotationFly(Math::Radian angle);
// Orbit mode rotation to IMPLEMENT.
void horizontalRotationOrbit(Math::Radian angle);
void verticalRotationOrbit(Math::Radian angle);
Math::Mat4 getViewMatrix() const;
// Non required code to understand question
//....
//
private:
Math::Vec3 m_up = Math::Vec3(0.0f, 1.0f, 0.0f);
Math::Vec3 m_position;
Math::Radian m_hAngle;
Math::Radian m_vAngle;
bool m_mousePressed;
};
inline Math::Vec3 Camera::getCurrentTarget() const
{
return m_position + getCurrentDirection();
}
inline Math::Vec3 Camera::getCurrentDirection() const
{
// Dont remember where that code is from but it works.
return glm::normalize(
Math::Vec3(
std::cosf(-m_hAngle.getValue()),
std::tanf(m_vAngle.getValue()),
std::sin(-m_hAngle.getValue())
)
);
}
inline void Camera::moveForward(nbFloat32 intensity)
{
const Math::Vec3 direction = getCurrentDirection();
m_position += (direction * intensity);
}
inline Math::Mat4 Camera::getViewMatrix() const
{
return glm::lookAt(m_position, getCurrentTarget(), m_up);
}
When mouse is dragged I perform the rotation
void Camera::onMouseMove(const Math::Uvec2& windowSize, const Math::Vec2& mousePos)
{
if (!m_mousePressed)
return;
Math::Vec2 deltaRatio = mousePos - m_currentMousePosition;
deltaRatio.x /= (nbFloat32)windowSize.x;
deltaRatio.y /= (nbFloat32)windowSize.y;
m_currentMousePosition = mousePos;
static const float rotationSensibility = 2.40f;
static const bool flyRotation = true;
if (flyRotation)
{
horizontalRotationFly(Math::Radian(-deltaRatio.x * rotationSensibility));
verticalRotationFly(Math::Radian(-deltaRatio.y * rotationSensibility));
}
else
{
// HERE to implement
horizontalRotationOrbit(Math::Radian(-deltaRatio.x * rotationSensibility));
verticalRotationOrbit(Math::Radian(-deltaRatio.y * rotationSensibility));
}
}
The FLY rotation functions are implemented this this:
inline void Camera::horizontalRotationFly(Math::Radian angle)
{
m_hAngle += angle;
}
inline void Camera::verticalRotationFly(Math::Radian angle)
{
m_vAngle += angle;
}
Now I need to implement the ORBIT ones:
inline void Camera::horizontalRotationOrbit(Math::Radian angle)
{
//TODO.
}
inline void Camera::verticalRotationOrbit(Math::Radian angle)
{
//TODO.
}
Thanks for helping!