From 04556dea8b127a5975669a00f16822c2db4b2942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20=E2=80=98Touky=E2=80=99=20Huet?= Date: Sat, 14 Sep 2013 23:42:49 +0000 Subject: [PATCH] mat4 : removed useless ortho(). Fixed shifted_perspective so it actually works. numeric : Added SmoothClamp & swap camera : fixed target&up issues and added screen-scale factor. touky_demo : correct camera integration & first pass on uro refactor. Also added Makefile to vcproj --- src/camera.cpp | 47 ++++++++++++++------------ src/camera.h | 9 +++-- src/lol/math/vector.h | 3 +- src/math/vector.cpp | 17 ++++------ src/numeric.h | 39 +++++++++++++++++++++ test/meshviewer.cpp | 2 +- test/physics/lolbtphysicsintegration.h | 2 +- 7 files changed, 79 insertions(+), 40 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index 425b93e5..ebf72b07 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -2,6 +2,7 @@ // Lol Engine // // Copyright: (c) 2010-2013 Sam Hocevar +// 2012-2013 Benjamin "Touky" Huet // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See @@ -38,12 +39,13 @@ Camera::Camera() m_screen_size = (float)screen_size.x; m_screen_ratio = (float)screen_size.x / (float)screen_size.y; m_is_shifted = false; + m_screen_scale = vec2(1.f); + + m_target_distance = .0f; /* Create a default perspective */ SetProjection(mat4::perspective(45.f, 800.f, 600.f, -1000.f, 1000.f)); - SetView(mat4::lookat(vec3(0.f, 50.f, 50.f), - vec3(0.f), - vec3(0.f, 1.f, 0.f))); + SetView(mat4::lookat(vec3(0.f, 50.f, 50.f), vec3(0.f), vec3(0.f, 1.f, 0.f))); } Camera::~Camera() @@ -53,6 +55,8 @@ Camera::~Camera() //----------------------------------------------------------------------------- //View functions //-- + +//WARNING : Don't forget the position void Camera::SetView(mat4 const &view) { m_view_matrix = view; @@ -68,14 +72,12 @@ void Camera::SetView(vec3 eye, vec3 target, vec3 up) void Camera::SetView(vec3 pos, vec3 rot) { - SetView(pos, quat::fromeuler_xyz(rot)); + SetView(pos, quat::fromeuler_zyx(rot.zyx)); } void Camera::SetView(vec3 pos, quat rot) { - m_view_matrix = mat4::lookat(pos, - pos + rot.transform(vec3(0.f, 0.f, -max(m_target_distance, 1.f))), - rot.transform(vec3(0.f, 1.f, 0.f))); + m_view_matrix = inverse(mat4(rot)) * mat4::translate(-pos); m_position = pos; } @@ -104,16 +106,16 @@ void Camera::SetProjection(float fov, float near, float far, float screen_size, m_far = far; m_screen_size = screen_size; m_screen_ratio = screen_ratio; - + mat4 screen_scale = mat4::scale(vec3(m_screen_scale.xy, 1.f)); if (m_fov > .0f) { if (m_is_shifted) - SetProjection(mat4::shifted_perspective(m_fov, screen_size, screen_ratio, m_far - m_near)); + SetProjection(screen_scale * mat4::shifted_perspective(m_fov, screen_size, screen_ratio, m_near, m_far)); else - SetProjection(mat4::perspective(m_fov, screen_size, screen_size * screen_ratio, m_near, m_far)); + SetProjection(screen_scale * mat4::perspective(m_fov, screen_size, screen_size * screen_ratio, m_near, m_far)); } else - SetProjection(mat4::ortho(screen_size, screen_size * screen_ratio, m_near, m_far)); + SetProjection(screen_scale * mat4::ortho(screen_size, screen_size * screen_ratio, m_near, m_far)); } mat4 Camera::GetProjection() @@ -149,6 +151,12 @@ void Camera::SetDrawInfos(float near, float far) SetProjection(m_fov, near, far, m_screen_size, m_screen_ratio); } +void Camera::SetScreenScale(vec2 screen_scale) +{ + m_screen_scale = screen_scale; + SetProjection(m_fov, m_near, m_far, m_screen_size, m_screen_ratio); +} + void Camera::UseShift(bool should_shift) { m_is_shifted = should_shift; @@ -163,28 +171,23 @@ void Camera::UseTarget(bool use_target) //----------------------------------------------------------------------------- //camera manipulation Functions //-- -void Camera::SetPosition(vec3 pos) +void Camera::SetPosition(vec3 pos, bool keep_target) { - if (m_target_distance > .0f) - SetView(m_position, m_position + GetTarget(), GetUp()); + if (keep_target) + SetView(pos, GetTarget(), GetUp()); else SetView(GetView() * mat4::translate(pos - m_position)); m_position = pos; } -void Camera::SetTarget(vec3 target) +void Camera::SetTarget(vec3 target, vec3 up) { - SetView(m_position, target, GetUp()); -} - -void Camera::SetUp(vec3 up) -{ - SetView(m_position, GetTarget(), up); + SetView(m_position, target, up); } void Camera::SetRotation(vec3 rot) { - SetRotation(quat::fromeuler_xyz(rot)); + SetView(m_position, rot); } void Camera::SetRotation(quat rot) diff --git a/src/camera.h b/src/camera.h index 493ebd34..d275a9e0 100644 --- a/src/camera.h +++ b/src/camera.h @@ -52,6 +52,7 @@ public: void SetScreenInfos(float screen_size, float screen_ratio); void SetDrawInfos(float far); void SetDrawInfos(float near, float far); + void SetScreenScale(vec2 scale); void UseShift(bool should_shift); void UseTarget(bool use_target); @@ -60,13 +61,13 @@ public: float GetScreenRatio() { return m_screen_ratio; } float GetNear() { return m_near; } float GetFar() { return m_far; } + vec2 GetScreenScale() { return m_screen_scale; } bool IsShifted() { return m_is_shifted; } bool IsTargeting() { return (m_target_distance != .0f); } //camera manipulation Functions - void SetPosition(vec3 pos); - void SetTarget(vec3 target); - void SetUp(vec3 up); + void SetPosition(vec3 pos, bool keep_target=false); + void SetTarget(vec3 target, vec3 up); void SetRotation(vec3 rot); void SetRotation(quat rot); @@ -96,7 +97,9 @@ private: float m_screen_ratio; float m_near; float m_far; + vec2 m_screen_scale; bool m_is_shifted; + bool m_fix_up; }; } /* namespace lol */ diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index 7026fece..9f0685b6 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -1804,10 +1804,9 @@ template struct Mat4 /* Helpers for projection matrices */ static Mat4 ortho(T left, T right, T bottom, T top, T near, T far); static Mat4 ortho(T width, T height, T near, T far); - static Mat4 ortho(T screen_size, T screen_ratio_xy, T draw_distance); static Mat4 frustum(T left, T right, T bottom, T top, T near, T far); static Mat4 perspective(T fov_y, T width, T height, T near, T far); - static Mat4 shifted_perspective(T fov_y, T screen_size, T screen_ratio_xy, T draw_distance); + static Mat4 shifted_perspective(T fov_y, T screen_size, T screen_ratio_yx, T near, T far); void printf() const; diff --git a/src/math/vector.cpp b/src/math/vector.cpp index d4b942d5..e2625f9c 100644 --- a/src/math/vector.cpp +++ b/src/math/vector.cpp @@ -745,11 +745,6 @@ template<> mat4 mat4::ortho(float width, float height, -0.5f * height, 0.5f * height, near, far); } -template<> mat4 mat4::ortho(float screen_size, float screen_ratio_xy, float draw_distance) -{ - return mat4::ortho(screen_size * screen_ratio_xy, screen_size, .00001f, draw_distance); -} - template<> mat4 mat4::frustum(float left, float right, float bottom, float top, float near, float far) { @@ -782,15 +777,15 @@ template<> mat4 mat4::perspective(float fov_y, float width, //Returns a perspective matrix with the camera location shifted to be on the near plane template<> mat4 mat4::shifted_perspective(float fov_y, float screen_size, - float screen_ratio_xy, float draw_distance) + float screen_ratio_yx, float near, float far) { float new_fov_y = fov_y * (F_PI / 180.0f); + float dist_scr = (screen_size * screen_ratio_yx * .5f) / tanf(new_fov_y * .5f); - float near = (screen_size * .5f) / lol::tan(new_fov_y * .5f); - float far = near + draw_distance; - - return mat4::perspective(fov_y, screen_size * screen_ratio_xy, screen_size, near - .000001f, far) * - mat4::translate(.0f, .0f, -near); + return mat4::perspective(fov_y, screen_size, screen_size * screen_ratio_yx, + max(.001f, dist_scr + near), + max(.001f, dist_scr + far)) * + mat4::translate(.0f, .0f, -dist_scr); } } /* namespace lol */ diff --git a/src/numeric.h b/src/numeric.h index 04c9259c..7d7dfece 100644 --- a/src/numeric.h +++ b/src/numeric.h @@ -43,6 +43,45 @@ template static inline T1 damp(const T1 return lol::lerp(a, b, dt / (dt + x)); } +template< class T > inline void Swap( T& A, T& B ) +{ + const T Temp = A; + A = B; + B = Temp; +} + +//SmoothClamp clamps x in [a - sd, b + sd] and returns a value in [a, b] that is smoothed at the borders. +static inline float SmoothClamp(float &x, float a, float b, float sd) +{ + if (b < a) + Swap(a, b); + + float tx = x; + float ta = a - sd; + float tb = b + sd; + if (sd > 0.f) + { + if ((b - a) < 2.f * sd) + sd = .5f * (b - a); + + if (tx < a + sd && tx > a - sd) + { + float t = (tx - a) / sd; + t = 0.25f * (t + 1.0f) * (t + 1.0f); + tx = a + t * sd; + } + else if (tx < b + sd && tx > b - sd) + { + float t = -(tx - b) / sd; + t = 0.25f * (t + 1.0f) * (t + 1.0f); + tx = b - t * sd; + } + } + + x = lol::clamp(x, ta, tb); + return lol::clamp(tx, a, b); +} + } /* namespace lol */ #endif // __LOL_NUMERIC_H__ diff --git a/test/meshviewer.cpp b/test/meshviewer.cpp index c5c96f81..09de8b32 100644 --- a/test/meshviewer.cpp +++ b/test/meshviewer.cpp @@ -295,7 +295,7 @@ public: if (m_fov_damp < MIN_FOV) cur_cam->SetProjection(mat4::ortho(screen_size * fov_ratio * 1.1f, 1600.f / 600.f, 1000.f)); else if (fov_ratio > .0f) - cur_cam->SetProjection(mat4::shifted_perspective(m_fov_damp, screen_size * fov_ratio * 1.1f, 1600.f / 600.f, 1000.f)); + cur_cam->SetProjection(mat4::shifted_perspective(m_fov_damp, screen_size * fov_ratio * 1.1f, 1600.f / 600.f, .00001f, 1000.f)); vec3 cam_center = cam_min_max[0] + min_max_diff * .5f; diff --git a/test/physics/lolbtphysicsintegration.h b/test/physics/lolbtphysicsintegration.h index 323d999c..21324783 100644 --- a/test/physics/lolbtphysicsintegration.h +++ b/test/physics/lolbtphysicsintegration.h @@ -19,7 +19,7 @@ namespace lol { - //Override Gamegroups names for Physic-useage + //Override Gamegroups names for Physic-usage //"_ENT_" means that this is a group for Entities that use EasyPhysic primitives. //"_EZP_" means that this is a group for EasyPhysic primitives. #define GAMEGROUP_ENT_INPUT GAMEGROUP_BEFORE