@CarstenT
it rotates the camera. but not as it needs to rotate. here is my camera class. Rotate and Pan not working perfectly.
edit: I am using modern OpenGL.
class x_Camera
{
public:
glm::vec3 m_Position{0,0,30};
glm::vec3 m_TargetAt = {0,0,0};
glm::vec3 m_Up = { 0.0f,1.0f,0.0f };
float m_Near = 0.0111f;
float m_Far = 1000.0f;
float m_ZoomScale = 1.1f;
glm::vec3 m_CamRotate = {0.0f,0.0f,0.0f};
glm::mat4 Get_MVP_Matrix();
glm::mat4 Get_View_Matrix();
glm::mat4 Get_Model_Matrix();
glm::mat4 Get_Projection_Matrix();
glm::vec3 m_Front;
float _fAspect = 1.0f;
float m_FOV = 45;
bool m_Orthographic = true;
void Rotate(int x, int y);
float GetDistance();
void Pan(POINT pt);
glm::vec3 lookAtToAngles(const glm::vec3 pos, const glm::vec3 lookat);
glm::vec3 GetDirection();
glm::vec3 GetRight();
private:
glm::mat4 m_Model = glm::mat4(1.0f), m_View = glm::mat4(1.0f), m_Projection = glm::mat4(1.0f);
};
glm::mat4 x_Camera::Get_MVP_Matrix()
{
glm::mat4 MVP;
if (m_Orthographic == false)
{
m_Projection = glm::perspective(glm::radians(m_FOV) * m_ZoomScale, _fAspect, this->m_Near, this->m_Far);
}
else
{
m_Projection = glm::ortho(-1.0f * m_ZoomScale, 1.0f * m_ZoomScale, -1.0f * m_ZoomScale, 1.0f * m_ZoomScale, this->m_Near, this->m_Far);
}
m_View = glm::lookAt(this->m_Position, this->m_TargetAt, this->m_Up);
MVP = m_Projection * m_View * m_Model;
return MVP;
}
glm::mat4 x_Camera::Get_View_Matrix()
{
//glm::mat4 MVP;
//glm::mat4 projection;
if (m_Orthographic == false)
{
m_Projection = glm::perspective(glm::radians(m_FOV) * m_ZoomScale, _fAspect, this->m_Near, this->m_Far);
}
else
{
//auto t = glm::radians(m_FOV) * 10;
m_Projection = glm::ortho(-1.0f * m_ZoomScale, 1.0f * m_ZoomScale, -1.0f * m_ZoomScale, 1.0f * m_ZoomScale, this->m_Near, this->m_Far);
}
return glm::lookAt(this->m_Position, this->m_TargetAt, this->m_Up);
}
glm::mat4 x_Camera::Get_Model_Matrix()
{
return m_Model;
}
glm::mat4 x_Camera::Get_Projection_Matrix()
{
if (m_Orthographic == false)
{
return glm::perspective(glm::radians(m_FOV) * m_ZoomScale, _fAspect, this->m_Near, this->m_Far);
}
else
{
//auto t = glm::radians(m_FOV) * 10;
return glm::ortho(-1.0f * m_ZoomScale, 1.0f * m_ZoomScale, -1.0f * m_ZoomScale, 1.0f * m_ZoomScale, this->m_Near, this->m_Far);
}
}
void x_Camera::Rotate(int x, int y)
{
auto speed = 0.01f;
auto rx = glm::radians(_ToFloat(x));
auto ry = glm::radians(_ToFloat(y));
m_CamRotate.x = cos(ry * cos(rx));
m_CamRotate.y = sin(rx);
m_CamRotate.z = sin(ry) * cos(rx);
m_Model = glm::mat4(1.0f);
//auto mDist = GetDistance();
//m_Model = glm::rotate(m_Model, m_CamRotate.y, glm::vec3(0,1,0));
//m_Model = glm::rotate(m_Model, m_CamRotate.x, glm::vec3(1, 0, 0));
//m_Model = glm::translate(m_Model, glm::vec3(0, 0, -mDist));
m_Front = glm::normalize(m_CamRotate);
m_Up = glm::rotate(m_Up, m_CamRotate.z, m_Front);
m_Position = glm::rotate(m_Model, m_CamRotate.x * speed, m_Up) * glm::vec4(m_Position, 1.0f);
m_Position = glm::rotate(m_Model, m_CamRotate.y * speed, m_Up) * glm::vec4(m_Position, 1.0f);
m_Position = glm::rotate(m_Model, m_CamRotate.z * speed, m_Up) * glm::vec4(m_Position, 1.0f);
//m_Position = glm::vec4(m_Position, 1.0f) * glm::rotate(m_Model, m_CamRotate.z * speed, glm::vec3(0, 0, 1));
//m_Position = glm::vec4(m_Position, 1.0f) * glm::rotate(m_Model, m_CamRotate.x * speed, glm::vec3(0,1,0));
//m_Position = glm::vec4(m_Position, 1.0f) * glm::rotate(m_Model, m_CamRotate.y * speed, glm::vec3(1, 0, 0));
}
float x_Camera::GetDistance()
{
return glm::distance(m_Position, m_TargetAt);
}
void x_Camera::Pan(POINT pt) // not working perfect
{
const float m_speed = 0.5f / m_ZoomScale;
glm::vec3 panX = GetRight() * (pt.x * 1.0f);
glm::vec3 panY = m_Up * (pt.y * 1.0f);
m_Position -= (panX + panY) * m_speed;
m_TargetAt -= (panX + panY) * m_speed;
//m_Position = m_Position - glm::vec3(pt.x* m_speed,pt.y* m_speed, 0.0f);
//m_TargetAt = m_TargetAt - glm::vec3(pt.x* m_speed, pt.y* m_speed, 0.0f);
}
glm::vec3 x_Camera::lookAtToAngles(const glm::vec3 pos, const glm::vec3 lookat)
{
const float DEG2RAD = acos(-1) / 180.0f; // PI/180
const float RAD2DEG = 180.0f / 3.141592f;
glm::vec3 vec;
float yaw, pitch; // roll is 0
// compute the vector from origin point to lookat point
vec = lookat - pos;
if (vec.x == 0.0f && vec.y == 0.0f) // vector is on the Y-axis, therefore,
{ // Yaw is 0, and Pitch will be +90 or -90.
yaw = 0.0f;
if (vec.y >= 0.0f)
pitch = 90.0f; // facing along +Y
else
pitch = -90.0f; // facing along -Y
}
else
{
// yaw: angle on X-Z plane (heading)
// yaw should be 0 if facing along +Z initially
yaw = RAD2DEG * atan2f(-vec.x, vec.z); // range -pi ~ +pi
// length of vector projected on X-Z plane
float dxz = sqrtf(vec.x * vec.x + vec.z * vec.z);
pitch = RAD2DEG * atan2f(vec.y, dxz); // range -pi ~ +pi
}
// store angles(degree) in the array
return glm::vec3(pitch, yaw, 0);
}
glm::vec3 x_Camera::GetDirection()
{
return glm::normalize(m_Position - m_TargetAt);
}
glm::vec3 x_Camera::GetRight()
{
return glm::normalize(glm::cross(m_Up, GetDirection()));
}