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 vcprojundefined
@@ -2,6 +2,7 @@ | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||
// 2012-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||
// 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) | |||
@@ -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 */ | |||
@@ -1804,10 +1804,9 @@ template <typename T> struct Mat4 | |||
/* Helpers for projection matrices */ | |||
static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far); | |||
static Mat4<T> ortho(T width, T height, T near, T far); | |||
static Mat4<T> ortho(T screen_size, T screen_ratio_xy, T draw_distance); | |||
static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far); | |||
static Mat4<T> perspective(T fov_y, T width, T height, T near, T far); | |||
static Mat4<T> shifted_perspective(T fov_y, T screen_size, T screen_ratio_xy, T draw_distance); | |||
static Mat4<T> shifted_perspective(T fov_y, T screen_size, T screen_ratio_yx, T near, T far); | |||
void printf() const; | |||
@@ -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 */ | |||
@@ -43,6 +43,45 @@ template <typename T1, typename T2, typename Tf> 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__ | |||
@@ -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; | |||
@@ -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 | |||