|
// camera direction
v3f d(0.f, 0.f, 1.f);
d = -math::mulBasis(d, m_editorCamera->m_viewMatrix);
printf("%f %f %f\n", d.x, d.y, d.z);
void yyOrbitCamera_onUpdate(yyCamera* camera)
{
math::makePerspectiveRHMatrix(
camera->m_projectionMatrix,
camera->m_fov,
camera->m_aspect,
camera->m_near,
camera->m_far);
v3f newCameraPosition = v3f(0.f, camera->m_objectBase.m_localPosition.w, 0.f);
Mat4 MX(Quat(camera->m_objectBase.m_rotation.x, 0.f, 0.f));
Mat4 MY(Quat(0.f, camera->m_objectBase.m_rotation.y, 0.f));
newCameraPosition = math::mul(newCameraPosition, (MY * MX));
newCameraPosition += v3f(
camera->m_objectBase.m_localPosition.x,
camera->m_objectBase.m_localPosition.y,
camera->m_objectBase.m_localPosition.z);
Mat4 T;
T.m_data[3] = newCameraPosition;
Mat4 P(Quat(v4f(-camera->m_objectBase.m_rotation.x + math::degToRad(90.f), 0.f, 0.f, 1.f)));
Mat4 Y(Quat(v4f(0.f, -camera->m_objectBase.m_rotation.y, 0.f, 1.f)));
Mat4 R(Quat(v4f(0.f, 0.f, -camera->m_objectBase.m_rotation.z, 1.f)));
camera->m_viewMatrix = (R*(P * Y)) * T;
}
void PanMove(const v2f& mouseDelta, f32 deltaTime) {
v4f vec(
mouseDelta.x * deltaTime,
0.f,
-mouseDelta.y * deltaTime,
0.f);
Mat4 MX(Quat(m_objectBase.m_rotation.x, 0.f, 0.f));
Mat4 MY(Quat(0.f, m_objectBase.m_rotation.y, 0.f));
//Mat4 MZ(Quat(0.f, 0.f, m_objectBase.m_rotation.z)); // не знаю как это учесть
vec = math::mul(vec, MY * MX);
m_objectBase.m_localPosition += vec;
}
void Rotate(const v2f& mouseDelta, f32 deltaTime) {
m_objectBase.m_rotation.x += mouseDelta.y * deltaTime;
m_objectBase.m_rotation.y += -mouseDelta.x * deltaTime;
}
void Zoom(f32 value) {
m_objectBase.m_localPosition.w -= value;
if (m_objectBase.m_localPosition.w < 0.01f)
m_objectBase.m_localPosition.w = 0.01f;
}
void ChangeFOV(f32 mouseDeltaX, f32 deltaTime) {
m_fov += mouseDeltaX * deltaTime;
if (m_fov < 0.01f)
m_fov = 0.01f;
if (m_fov > math::PI)
m_fov = math::PI;
}
void RotateZ(f32 mouseDeltaX, f32 deltaTime) {
m_objectBase.m_rotation.z += mouseDeltaX * deltaTime;
}
void Reset() {
m_near = 0.01f;
m_far = 1000.f;
m_fov = math::degToRad(90.f);
m_aspect = 800.f / 600.f;
m_objectBase.m_localPosition = v4f(0.f, 0.f, 0.f, 5.f);
m_objectBase.m_rotation = v3f(math::degToRad(-45.f), 0.f, 0.f);
}
/// TEST
m_editorCamera->Update();
if (g_demo->m_inputContext->m_isMMBHold)
{
if (g_demo->m_inputContext->IsKeyHold(yyKey::K_LALT))
m_editorCamera->Rotate(g_demo->m_inputContext->m_mouseDelta, g_demo->m_dt);
else
m_editorCamera->PanMove(g_demo->m_inputContext->m_mouseDelta, g_demo->m_dt);
}
if (g_demo->m_inputContext->IsKeyHold(yyKey::K_LALT))
{
if (g_demo->m_inputContext->m_isLMBHold)
m_editorCamera->RotateZ(g_demo->m_inputContext->m_mouseDelta.x, g_demo->m_dt);
if (g_demo->m_inputContext->m_isRMBHold)
m_editorCamera->ChangeFOV(g_demo->m_inputContext->m_mouseDelta.x, g_demo->m_dt);
}
if(g_demo->m_inputContext->m_wheelDelta)
m_editorCamera->Zoom(g_demo->m_inputContext->m_wheelDelta);
void ChaseCamera::update(const Mat4& chasisMatrix, f32 dt)
{
m_camera->m_objectBase.UpdateBase();
math::makePerspectiveRHMatrix(
m_camera->m_projectionMatrix,
m_camera->m_fov,
m_camera->m_aspect,
m_camera->m_near,
m_camera->m_far);
Mat4 V = chasisMatrix; // car body matrix
auto bodyPosition = V[3];
V[3] = v4f(0.f, 0.f, 0.f, 1.f);
Quat Q = math::matToQuat(V);
Q.normalize();
m_orientation = Q.slerp(m_orientation, Q, 1.f * dt, 0.1f);
Mat4 rot;
math::makeRotationMatrix(rot, m_orientation);
// m_originalPosition - camera position
v4f newPosition = math::mul(m_originalPosition, rot) + bodyPosition;
math::makeLookAtRHMatrix(
m_camera->m_viewMatrix,
newPosition,
bodyPosition + v4f(0.f, m_originalTarget, 0.f, 0.f), // m_originalTarget - move target up\down
m_camera->m_up
);
m_camera->Update(); // build frustum etc.
}
void camera_OnUpdate(Game_Camera* camera)
{
Mat4 P;
math::makePerspectiveRHMatrix(
P,
camera->GetFOV(),
camera->GetAspect(),
camera->GetNear(),
camera->GetFar() );
camera->SetProjection(P);
Mat4 V = g_body->GetGlobalMatrix();
V.invert();
camera->SetView(V);
}
// For example, hold RMB and fly
// in main loop
if (g_inputContex->m_isRMBHold)
{
m_activeCamera->rotate(g_inputContex->m_mouseDelta, deltaTime);
if (g_inputContex->isKeyHold(yyKey::K_LSHIFT) || g_inputContex->isKeyHold(yyKey::K_RSHIFT))
m_activeCamera->m_moveSpeed = m_activeCamera->m_moveSpeedDefault * 5.f;
else
m_activeCamera->m_moveSpeed = m_activeCamera->m_moveSpeedDefault;
if (g_inputContex->isKeyHold(yyKey::K_W))
m_activeCamera->moveForward(deltaTime);
if (g_inputContex->isKeyHold(yyKey::K_S))
m_activeCamera->moveBackward(deltaTime);
if (g_inputContex->isKeyHold(yyKey::K_A))
m_activeCamera->moveLeft(deltaTime);
if (g_inputContex->isKeyHold(yyKey::K_D))
m_activeCamera->moveRight(deltaTime);
if (g_inputContex->isKeyHold(yyKey::K_E))
m_activeCamera->moveUp(deltaTime);
if (g_inputContex->isKeyHold(yyKey::K_Q))
m_activeCamera->moveDown(deltaTime);
auto cursorX = std::floor((f32)window.m_data->m_clientSize.x / 2.f);
auto cursorY = std::floor((f32)window.m_data->m_clientSize.y / 2.f);
g_inputContex->m_cursorCoordsOld.set(cursorX, cursorY);
// move cursor to center of the window
// this example not about it, so implement it by yourself
yySetCursorPosition(cursorX, cursorY, window.m_data);
}
/// CAMERA
void Camera::rotate(const v2f& mouseDelta, f32 dt)
{
f32 speed = 4.4f;
Mat4 RX;
Mat4 RY;
bool update = false;
if (mouseDelta.x != 0.f)
{
update = true;
RY.setRotation(Quat(v4f(0.f, math::degToRad(-mouseDelta.x) * dt * speed, 0.f, 0.f)));
}
if (mouseDelta.y != 0.f)
{
update = true;
RX.setRotation(Quat(v4f(math::degToRad(-mouseDelta.y) * dt * speed, 0.f, 0.f, 0.f)));
}
if (update)
m_camera->m_rotationMatrix = RX * m_camera->m_rotationMatrix * RY;
}
void Camera::moveLeft(f32 dt)
{
_moveCamera(v4f(-m_moveSpeed * dt, 0.f, 0.f, 1.f));
}
void Camera::moveRight(f32 dt)
{
_moveCamera(v4f(m_moveSpeed * dt, 0.f, 0.f, 1.f));
}
void Camera::moveUp(f32 dt)
{
_moveCamera(v4f(0.f, m_moveSpeed * dt, 0.f, 1.f));
}
void Camera::moveDown(f32 dt)
{
_moveCamera(v4f(0.f, -m_moveSpeed * dt, 0.f, 1.f));
}
void Camera::moveBackward(f32 dt)
{
_moveCamera(v4f(0.f, 0.f, m_moveSpeed * dt, 1.f));
}
void Camera::moveForward(f32 dt)
{
_moveCamera(v4f(0.f, 0.f, -m_moveSpeed * dt, 1.f));
}
void Camera::_moveCamera(v4f& vel)
{
auto RotInv = m_camera->m_rotationMatrix;
RotInv.invert();
vel = math::mul(vel, RotInv);
m_camera->m_objectBase.m_localPosition += vel; // m_localPosition is just vec4 for position
}
void camera_onUpdate(yyCamera* camera)
{
math::makePerspectiveRHMatrix(
camera->m_projectionMatrix,
camera->m_fov,
camera->m_aspect,
camera->m_near,
camera->m_far);
auto V = math::mul(-camera->m_objectBase.m_localPosition, camera->m_rotationMatrix);
camera->m_viewMatrix = camera->m_rotationMatrix;
camera->m_viewMatrix[3] = V;
camera->m_viewMatrix[3].w = 1.f;
}
|
|