plenty of additions to rendering. transformation now work almost as expected ...

This commit is contained in:
Hartmut Seichter 2019-02-12 21:28:20 +01:00
parent 841b0eeb46
commit 40b84fb78f
18 changed files with 242 additions and 251 deletions

View file

@ -24,6 +24,7 @@
#define PW_CORE_MATH_HPP
#include <cmath>
#include <algorithm>
namespace pw {
@ -45,6 +46,20 @@ inline T deg_to_rad(const T& angle_in_degree) {
return angle_in_degree * __DEG2RAD;
}
template <typename T>
static inline
T repeat(const T& t, const T& length) {
return std::clamp(t - std::floor(t / length) * length, T(0), length);
}
template <typename T>
static inline
T ping_pong(const T& t,const T& length) {
auto tn = repeat(t, length * T(2));
return length - std::abs(tn - length);
}
}
#endif

View file

@ -39,23 +39,42 @@ struct transform_tools {
}
inline static
matrix_<4,4,T> projection_from_frustum(T left,T right,T bottom,T top,T z_near,T z_far)
matrix_<4,4,T> projection_from_frustum(const T &left,const T &right,
const T &bottom,const T &top,
const T &z_near,const T &z_far)
{
matrix_<4,4,T> frustum; frustum.zero();
frustum(0,0) = T(2) * z_near / (right - left);
frustum(1,1) = T(2) * z_near / (top - bottom);
frustum(0,0) = T(2) * z_near / (right - left);
frustum(1,1) = T(2) * z_near / (top - bottom);
frustum(2,0) = (right+left)/(right-left); //A
frustum(2,1) = (top+bottom)/(top-bottom); //B
frustum(2,2) = - (z_far+z_near)/(z_far-z_near); //C
frustum(2,3) = -(T(2) * z_far*z_near)/(z_far-z_near); //D
frustum(0,2) = (right+left)/(right-left); //A
frustum(1,2) = (top+bottom)/(top-bottom); //B
frustum(2,2) = -(z_far+z_near)/(z_far-z_near); //C
frustum(2,3) = -T(2) * z_far*z_near/(z_far-z_near); //D
frustum(3,2) = -T(1);
frustum(3,2) = -T(1);
return frustum;
}
inline static
matrix_<4,4,T> perspective_projection(const T &field_of_view,
const T &aspect_ratio,
const T &z_near,const T &z_far)
{
const T tan_half = tan(field_of_view / T(2));
const T right = aspect_ratio * tan_half * z_near;
const T left = -right;
const T top = aspect_ratio * tan_half;
const T bottom = -top;
return projection_from_frustum(left,right,
bottom,top,
z_near,z_far);
}
inline static
matrix_<4,4,T> orthogonal_projection(T left, T right,
T bottom,T top,
@ -78,63 +97,25 @@ struct transform_tools {
return ortho;
}
inline static
matrix_<4,4,T> perspective_projection(T fov_y, T aspect_ratio, T z_near, T z_far)
{
const T height = z_near * tan(fov_y/T(360) * pi<T>()); // half height of near plane
const T width = height * aspect_ratio; // half width of near plane
return projection_from_frustum(-width, width, -height, height, z_near, z_far );
}
inline static
matrix_<4,4,T> look_at(
const vector3_<T> &eye,
const vector3_<T> &target,
const vector3_<T> &up)
{
inline static
matrix_<4,4,T> look_at(const vector3_<T> &position,
const vector3_<T> &target,
const vector3_<T> &up)
{
matrix_<4,4,T> view_matrix; view_matrix.set_identity();
const vector3_<T> L = (target - eye).normalized(); // line of sight
const vector3_<T> S = L.cross(up).normalized();
const vector3_<T> Ud = S.cross(L).normalized();
const vector3_<T> los = (target - position).normalized(); // line of sight
const vector3_<T> sid = los.cross(up).normalized();
const vector3_<T> upd = sid.cross(los).normalized();
// set base vectors
view_matrix.set_slice(S, 0,0);
view_matrix.set_slice(Ud, 0,1);
view_matrix.set_slice(L*T(-1), 0,2);
view_matrix.set_slice(eye, 0,3);
return view_matrix;
// matrix<3,1,T> S = matrix31<T>::Cross(L,up);
// S.normalize();
// matrix<3,1,T> Ud = matrix31<T>::Cross(S,L);
// Ud.normalize();
// lookat(0,0) = S.at(0);
// lookat(0,1) = S.at(1);
// lookat(0,2) = S.at(2);
// lookat(0,3) = T(0);
// lookat(1,0) = Ud.at(0);
// lookat(1,1) = Ud.at(1);
// lookat(1,2) = Ud.at(2);
// lookat(1,3) = T(0);
// lookat(2,0) = -L.at(0);
// lookat(2,1) = -L.at(1);
// lookat(2,2) = -L.at(2);
// lookat(3,2) = T(0);
// lookat(3,0) = eye.at(0);
// lookat(3,1) = eye.at(1);
// lookat(3,2) = eye.at(2);
// lookat(3,3) = 1;
// return lookat;
view_matrix.set_slice(sid, 0, 0);
view_matrix.set_slice(upd, 0, 1);
view_matrix.set_slice(los * T(-1), 0, 2);
view_matrix.set_slice(position, 0, 3);
return view_matrix;
}
};