Commit ce2734d4 authored by hybrid's avatar hybrid

Add a new matrix method, e.g. used for stencil shadows.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3216 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 3c6b62c1
...@@ -258,6 +258,9 @@ namespace core ...@@ -258,6 +258,9 @@ namespace core
//! Builds a left-handed perspective projection matrix based on a field of view //! Builds a left-handed perspective projection matrix based on a field of view
CMatrix4<T>& buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar); CMatrix4<T>& buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
//! Builds a left-handed perspective projection matrix based on a field of view, with far plane at infinity
CMatrix4<T>& buildProjectionMatrixPerspectiveFovInfinityLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 epsilon=0);
//! Builds a right-handed perspective projection matrix. //! Builds a right-handed perspective projection matrix.
CMatrix4<T>& buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); CMatrix4<T>& buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
...@@ -1482,6 +1485,42 @@ namespace core ...@@ -1482,6 +1485,42 @@ namespace core
} }
// Builds a left-handed perspective projection matrix based on a field of view
template <class T>
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovInfinityLH(
f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 epsilon)
{
const f64 h = reciprocal(tan(fieldOfViewRadians*0.5));
_IRR_DEBUG_BREAK_IF(aspectRatio==0.f); //divide by zero
const T w = (T)(h / aspectRatio);
M[0] = w;
M[1] = 0;
M[2] = 0;
M[3] = 0;
M[4] = 0;
M[5] = (T)h;
M[6] = 0;
M[7] = 0;
M[8] = 0;
M[9] = 0;
M[10] = 1-epsilon;
M[11] = 1;
M[12] = 0;
M[13] = 0;
M[14] = (T)(zNear*(1-epsilon));
M[15] = 0;
#if defined ( USE_MATRIX_TEST )
definitelyIdentityMatrix=false;
#endif
return *this;
}
// Builds a left-handed orthogonal projection matrix. // Builds a left-handed orthogonal projection matrix.
template <class T> template <class T>
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoLH( inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoLH(
...@@ -1817,22 +1856,22 @@ namespace core ...@@ -1817,22 +1856,22 @@ namespace core
inline CMatrix4<T>& CMatrix4<T>::buildRotateFromTo(const core::vector3df& from, const core::vector3df& to) inline CMatrix4<T>& CMatrix4<T>::buildRotateFromTo(const core::vector3df& from, const core::vector3df& to)
{ {
// unit vectors // unit vectors
core::vector3df f ( from ); core::vector3df f(from);
core::vector3df t ( to ); core::vector3df t(to);
f.normalize (); f.normalize();
t.normalize (); t.normalize();
// axis multiplication by sin // axis multiplication by sin
core::vector3df vs ( t.crossProduct ( f ) ); core::vector3df vs(t.crossProduct(f));
// axis of rotation // axis of rotation
core::vector3df v ( vs ); core::vector3df v(vs);
v.normalize(); v.normalize();
// cosinus angle // cosinus angle
T ca = f.dotProduct ( t ); T ca = f.dotProduct(t);
core::vector3df vt ( v * ( (T) 1 - ca ) ); core::vector3df vt(v * (1 - ca));
M[0] = vt.X * v.X + ca; M[0] = vt.X * v.X + ca;
M[5] = vt.Y * v.Y + ca; M[5] = vt.Y * v.Y + ca;
...@@ -1844,84 +1883,78 @@ namespace core ...@@ -1844,84 +1883,78 @@ namespace core
M[1] = vt.X - vs.Z; M[1] = vt.X - vs.Z;
M[2] = vt.Z + vs.Y; M[2] = vt.Z + vs.Y;
M[3] = (T) 0; M[3] = 0;
M[4] = vt.X + vs.Z; M[4] = vt.X + vs.Z;
M[6] = vt.Y - vs.X; M[6] = vt.Y - vs.X;
M[7] = (T) 0; M[7] = 0;
M[8] = vt.Z - vs.Y; M[8] = vt.Z - vs.Y;
M[9] = vt.Y + vs.X; M[9] = vt.Y + vs.X;
M[11] = (T) 0; M[11] = 0;
M[12] = (T) 0; M[12] = 0;
M[13] = (T) 0; M[13] = 0;
M[14] = (T) 0; M[14] = 0;
M[15] = (T) 1; M[15] = 1;
return *this; return *this;
} }
//! Builds a matrix which rotates a source vector to a look vector over an arbitrary axis //! Builds a matrix which rotates a source vector to a look vector over an arbitrary axis
/** \param camPos: viewer position in world coo /** \param camPos: viewer position in world coord
\param center: object position in world-coo and rotation pivot \param center: object position in world-coord, rotation pivot
\param translation: object final translation from center \param translation: object final translation from center
\param axis: axis to rotate about \param axis: axis to rotate about
\param from: source vector to rotate from \param from: source vector to rotate from
*/ */
template <class T> template <class T>
inline void CMatrix4<T>::buildAxisAlignedBillboard( const core::vector3df& camPos, inline void CMatrix4<T>::buildAxisAlignedBillboard(
const core::vector3df& center, const core::vector3df& camPos,
const core::vector3df& translation, const core::vector3df& center,
const core::vector3df& axis, const core::vector3df& translation,
const core::vector3df& from const core::vector3df& axis,
) const core::vector3df& from)
{ {
// axis of rotation // axis of rotation
core::vector3df up = axis; core::vector3df up = axis;
up.normalize (); up.normalize();
const core::vector3df forward = (camPos - center).normalize();
core::vector3df forward = camPos - center; const core::vector3df right = up.crossProduct(forward).normalize();
forward.normalize();
core::vector3df right = up.crossProduct ( forward );
right.normalize ();
// correct look vector // correct look vector
core::vector3df look = right.crossProduct ( up ); const core::vector3df look = right.crossProduct(up);
// rotate from to // rotate from to
// axis multiplication by sin // axis multiplication by sin
core::vector3df vs = look.crossProduct ( from ); const core::vector3df vs = look.crossProduct(from);
// cosinus angle // cosinus angle
f32 ca = from.dotProduct ( look ); const f32 ca = from.dotProduct(look);
core::vector3df vt ( up * ( 1.f - ca ) ); core::vector3df vt(up * (1.f - ca));
M[0] = vt.X * up.X + ca; M[0] = static_cast<T>(vt.X * up.X + ca);
M[5] = vt.Y * up.Y + ca; M[5] = static_cast<T>(vt.Y * up.Y + ca);
M[10] = vt.Z * up.Z + ca; M[10] = static_cast<T>(vt.Z * up.Z + ca);
vt.X *= up.Y; vt.X *= up.Y;
vt.Z *= up.X; vt.Z *= up.X;
vt.Y *= up.Z; vt.Y *= up.Z;
M[1] = vt.X - vs.Z; M[1] = static_cast<T>(vt.X - vs.Z);
M[2] = vt.Z + vs.Y; M[2] = static_cast<T>(vt.Z + vs.Y);
M[3] = (T) 0; M[3] = 0;
M[4] = vt.X + vs.Z;
M[6] = vt.Y - vs.X;
M[7] = (T) 0;
M[8] = vt.Z - vs.Y; M[4] = static_cast<T>(vt.X + vs.Z);
M[9] = vt.Y + vs.X; M[6] = static_cast<T>(vt.Y - vs.X);
M[11] = (T) 0; M[7] = 0;
setRotationCenter ( center, translation ); M[8] = static_cast<T>(vt.Z - vs.Y);
M[9] = static_cast<T>(vt.Y + vs.X);
M[11] = 0;
setRotationCenter(center, translation);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment