863 lines
24 KiB
C
863 lines
24 KiB
C
|
/****************************************************************************
|
||
|
Copyright (c) 2007, Radon Labs GmbH
|
||
|
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
||
|
|
||
|
http://www.genesis-3d.com.cn
|
||
|
|
||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
of this software and associated documentation files (the "Software"), to deal
|
||
|
in the Software without restriction, including without limitation the rights
|
||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
copies of the Software, and to permit persons to whom the Software is
|
||
|
furnished to do so, subject to the following conditions:
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included in
|
||
|
all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
|
THE SOFTWARE.
|
||
|
****************************************************************************/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include "core/types.h"
|
||
|
#include "math/scalar.h"
|
||
|
#include "math/float4.h"
|
||
|
#include "math/plane.h"
|
||
|
#include "math/quaternion.h"
|
||
|
#include "math/OgreMath/OgreMatrix4.h"
|
||
|
#include "../rendersystem/config/RenderDeviceConfig.h"
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
namespace Math
|
||
|
{
|
||
|
class quaternion;
|
||
|
class plane;
|
||
|
// could not get the compiler to really pass it in registers for xbox, so
|
||
|
// this is a reference so far
|
||
|
typedef const matrix44& __Matrix44Arg;
|
||
|
|
||
|
|
||
|
class matrix44
|
||
|
{
|
||
|
public:
|
||
|
/// default constructor, NOTE: does NOT setup components!
|
||
|
matrix44();
|
||
|
/// construct from components
|
||
|
matrix44(float4 const &row0, float4 const &row1, float4 const &row2, float4 const &row3);
|
||
|
/// copy constructor
|
||
|
//matrix44(const matrix44& rhs);
|
||
|
/// construct from Ogre::Matrix4
|
||
|
matrix44(const Ogre::Matrix4& rhs);
|
||
|
|
||
|
/// assignment operator
|
||
|
void operator=(const matrix44& rhs);
|
||
|
/// assign Ogre::Matrix4
|
||
|
void operator=(const Ogre::Matrix4& rhs);
|
||
|
/// equality operator
|
||
|
bool operator==(const matrix44& rhs) const;
|
||
|
/// inequality operator
|
||
|
bool operator!=(const matrix44& rhs) const;
|
||
|
/// get value operator
|
||
|
float* operator[](SizeT iRow);
|
||
|
/// get const value operator
|
||
|
const float* const operator[](SizeT iRow) const;
|
||
|
|
||
|
/// load content from unaligned memory
|
||
|
void loadu(const scalar* ptr);
|
||
|
/// write content to unaligned memory through the write cache
|
||
|
void storeu(scalar* ptr) const;
|
||
|
/// stream content to 16-byte-aligned memory circumventing the write-cache
|
||
|
void stream(scalar* ptr) const;
|
||
|
|
||
|
/// set content
|
||
|
void set(float4 const &row0, float4 const &row1, float4 const &row2, float4 const &row3);
|
||
|
/// write access to x component
|
||
|
void setrow0(float4 const &row0);
|
||
|
/// write access to y component
|
||
|
void setrow1(float4 const &row1);
|
||
|
/// write access to z component
|
||
|
void setrow2(float4 const &row2);
|
||
|
/// write access to w component
|
||
|
void setrow3(float4 const &row3);
|
||
|
/// wrtie access to specified component
|
||
|
void setrowcol(const float& val, const int& row,const int& col);
|
||
|
/// read-only access to x component
|
||
|
const float4 getrow0() const;
|
||
|
/// read-only access to y component
|
||
|
const float4 getrow1() const;
|
||
|
/// read-only access to z component
|
||
|
const float4 getrow2() const;
|
||
|
/// read-only access to w component
|
||
|
const float4 getrow3() const;
|
||
|
|
||
|
float* getarray();
|
||
|
|
||
|
/// write access to x component
|
||
|
void set_xaxis(float4 const &x);
|
||
|
/// write access to y component
|
||
|
void set_yaxis(float4 const &y);
|
||
|
/// write access to z component
|
||
|
void set_zaxis(float4 const &z);
|
||
|
/// write access to w component / pos component
|
||
|
void set_position(float4 const &pos);
|
||
|
/// read access to x component
|
||
|
const float4 get_xaxis() const;
|
||
|
/// read access to y component
|
||
|
const float4 get_yaxis() const;
|
||
|
/// read access to z component
|
||
|
const float4 get_zaxis() const;
|
||
|
/// read access to w component / pos component
|
||
|
const float4 get_position() const;
|
||
|
/// add a translation to pos_component
|
||
|
void translate(float4 const &t);
|
||
|
/// scale matrix
|
||
|
void scale(float4 const &v);
|
||
|
|
||
|
/// return true if matrix is identity
|
||
|
bool isidentity() const;
|
||
|
/// decompose into scale, rotation and translation
|
||
|
/// !!! Note:
|
||
|
void decompose(float4& outScale, quaternion& outRotation, float4& outTranslation) const;
|
||
|
|
||
|
float determinant() const;
|
||
|
|
||
|
void print() const;
|
||
|
|
||
|
/// build zero matrix
|
||
|
static matrix44 zero();
|
||
|
/// build identity matrix
|
||
|
static matrix44 identity();
|
||
|
/// compute the inverse of a matrix
|
||
|
static matrix44 inverse(const matrix44& m);
|
||
|
/// build right handed lookat matrix
|
||
|
static matrix44 lookatrh(float4 const &eye, float4 const &at, float4 const &up);
|
||
|
/// multiply 2 matrices
|
||
|
static matrix44 multiply(const matrix44& m0, const matrix44& m1);
|
||
|
/// build right handed orthogonal projection matrix
|
||
|
static matrix44 orthorh(scalar w, scalar h, scalar zn, scalar zf);
|
||
|
/// build right handed orthogonal projection matrix not at specific center
|
||
|
static matrix44 orthooffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf);
|
||
|
/// build right-handed perspective projection matrix based on field-of-view
|
||
|
static matrix44 perspfovrh(scalar fovy, scalar aspect, scalar zn, scalar zf);
|
||
|
/// build reflect matrix from a plane
|
||
|
static matrix44 reflect(const float4& p);
|
||
|
/// build rotation matrix around arbitrary axis
|
||
|
static matrix44 rotationaxis(float4 const &axis, scalar angle);
|
||
|
/// build x-axis-rotation matrix
|
||
|
static matrix44 rotationx(scalar angle);
|
||
|
/// build y-axis-rotation matrix
|
||
|
static matrix44 rotationy(scalar angle);
|
||
|
/// build z-axis-rotation matrix
|
||
|
static matrix44 rotationz(scalar angle);
|
||
|
/// build rotation matrix from yaw, pitch and roll
|
||
|
static matrix44 rotationyawpitchroll(scalar yaw, scalar pitch, scalar roll);
|
||
|
/// build rotation matrix from quaternion
|
||
|
static matrix44 rotationquaternion(const quaternion& q);
|
||
|
/// make quaternion from matrix44
|
||
|
static quaternion rotationmatrix(const matrix44& m);
|
||
|
/// build a scaling matrix from components
|
||
|
static matrix44 scaling(scalar sx, scalar sy, scalar sz);
|
||
|
/// build a scaling matrix from float4
|
||
|
static matrix44 scaling(float4 const &s);
|
||
|
/// build a transformation matrix
|
||
|
static matrix44 transformation(float4 const &scaling,const quaternion& rotation, float4 const &translation);
|
||
|
/// build a translation matrix
|
||
|
static matrix44 translation(scalar x, scalar y, scalar z);
|
||
|
/// build a translation matrix from point
|
||
|
static matrix44 translation(float4 const &t);
|
||
|
/// return the transpose of a matrix
|
||
|
static matrix44 transpose(const matrix44& m);
|
||
|
/// transform 4d vector by matrix44, faster inline version than float4::transform
|
||
|
static float4 transform(const matrix44 &m, const float4 &v);
|
||
|
/// transform a plane with a matrix
|
||
|
static plane transform(const matrix44& m, const plane& p);
|
||
|
/// check if point lies inside matrix frustum
|
||
|
static bool ispointinside(const matrix44& m, const float4& p);
|
||
|
/// convert to any type
|
||
|
template<typename T> T as() const;
|
||
|
|
||
|
|
||
|
Ogre::Matrix4 mx;
|
||
|
private:
|
||
|
friend class float4;
|
||
|
friend class plane;
|
||
|
friend class quaternion;
|
||
|
|
||
|
};
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline
|
||
|
matrix44::matrix44():
|
||
|
mx(Ogre::Matrix4::IDENTITY)
|
||
|
{
|
||
|
// empty
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline
|
||
|
matrix44::matrix44(float4 const &row0, float4 const &row1, float4 const &row2, float4 const &row3)
|
||
|
{
|
||
|
this->mx = Ogre::Matrix4( row0.vec.x,row0.vec.y,row0.vec.z,row0.vec.w,
|
||
|
row1.vec.x,row1.vec.y,row1.vec.z,row1.vec.w,
|
||
|
row2.vec.x,row2.vec.y,row2.vec.z,row2.vec.w,
|
||
|
row3.vec.x,row3.vec.y,row3.vec.z,row3.vec.w );
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline
|
||
|
matrix44::matrix44(const Ogre::Matrix4& rhs) :
|
||
|
mx(rhs)
|
||
|
{
|
||
|
// empty
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::operator=(const matrix44& rhs)
|
||
|
{
|
||
|
this->mx = rhs.mx;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::operator=(const Ogre::Matrix4& rhs)
|
||
|
{
|
||
|
this->mx = rhs;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline bool
|
||
|
matrix44::operator==(const matrix44& rhs) const
|
||
|
{
|
||
|
return this->mx == rhs.mx;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline bool
|
||
|
matrix44::operator!=(const matrix44& rhs) const
|
||
|
{
|
||
|
return this->mx != rhs.mx;
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline float*
|
||
|
matrix44::operator[]( SizeT iRow )
|
||
|
{
|
||
|
return this->mx[iRow];
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float* const
|
||
|
matrix44::operator[]( SizeT iRow ) const
|
||
|
{
|
||
|
return this->mx[iRow];
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline float
|
||
|
matrix44::determinant() const
|
||
|
{
|
||
|
return mx.determinant();
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::loadu(const scalar* ptr)
|
||
|
{
|
||
|
memcpy((void*)&this->mx,ptr,sizeof(matrix44));
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::storeu(scalar* ptr) const
|
||
|
{
|
||
|
memcpy(ptr,(void*)&this->mx,sizeof(matrix44));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::stream(scalar* ptr) const
|
||
|
{
|
||
|
memcpy(ptr,(void*)&this->mx,sizeof(matrix44));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::set(float4 const &row0, float4 const &row1, float4 const &row2, float4 const &row3)
|
||
|
{
|
||
|
this->mx = Ogre::Matrix4( row0.vec.x,row0.vec.y,row0.vec.z,row0.vec.w,
|
||
|
row1.vec.x,row1.vec.y,row1.vec.z,row1.vec.w,
|
||
|
row2.vec.x,row2.vec.y,row2.vec.z,row2.vec.w,
|
||
|
row3.vec.x,row3.vec.y,row3.vec.z,row3.vec.w );
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline
|
||
|
float* matrix44::getarray()
|
||
|
{
|
||
|
return this->mx.getArray();
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::setrow0(float4 const &r)
|
||
|
{
|
||
|
this->mx.setRow(0,r.vec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float4
|
||
|
matrix44::getrow0() const
|
||
|
{
|
||
|
|
||
|
return this->mx.getRow(0);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::setrow1(float4 const &r)
|
||
|
{
|
||
|
this->mx.setRow(1,r.vec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float4
|
||
|
matrix44::getrow1() const
|
||
|
{
|
||
|
return float4(mx.getRow(1));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::setrow2(float4 const &r)
|
||
|
{
|
||
|
this->mx.setRow(2,r.vec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float4
|
||
|
matrix44::getrow2() const
|
||
|
{
|
||
|
return float4(mx.getRow(2));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::setrow3(float4 const &r)
|
||
|
{
|
||
|
this->mx.setRow(3,r.vec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float4
|
||
|
matrix44::getrow3() const
|
||
|
{
|
||
|
return float4(mx.getRow(3));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::setrowcol(const float& val, const int& row,const int& col)
|
||
|
{
|
||
|
mx[row][col] = val;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::set_xaxis(float4 const &x)
|
||
|
{
|
||
|
Ogre::Vector4 colVec = this->mx.getCol(0);
|
||
|
colVec.x = x.vec.x;
|
||
|
colVec.y = x.vec.y;
|
||
|
colVec.z = x.vec.z;
|
||
|
this->mx.setCol(0,colVec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::set_yaxis(float4 const &y)
|
||
|
{
|
||
|
Ogre::Vector4 colVec = this->mx.getCol(1);
|
||
|
colVec.x = y.vec.x;
|
||
|
colVec.y = y.vec.y;
|
||
|
colVec.z = y.vec.z;
|
||
|
this->mx.setCol(1,colVec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::set_zaxis(float4 const &z)
|
||
|
{
|
||
|
Ogre::Vector4 colVec = this->mx.getCol(2);
|
||
|
colVec.x = z.vec.x;
|
||
|
colVec.y = z.vec.y;
|
||
|
colVec.z = z.vec.z;
|
||
|
this->mx.setCol(2,colVec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::set_position(float4 const &pos)
|
||
|
{
|
||
|
Ogre::Vector4 colVec = this->mx.getCol(3);
|
||
|
colVec.x = pos.vec.x;
|
||
|
colVec.y = pos.vec.y;
|
||
|
colVec.z = pos.vec.z;
|
||
|
this->mx.setCol(3,colVec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float4
|
||
|
matrix44::get_xaxis() const
|
||
|
{
|
||
|
return float4(this->mx.getCol(0));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float4
|
||
|
matrix44::get_yaxis() const
|
||
|
{
|
||
|
return float4(this->mx.getCol(1));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float4
|
||
|
matrix44::get_zaxis() const
|
||
|
{
|
||
|
return float4(this->mx.getCol(2));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline const float4
|
||
|
matrix44::get_position() const
|
||
|
{
|
||
|
return float4(this->mx.getCol(3));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline
|
||
|
void
|
||
|
matrix44::translate(float4 const &t)
|
||
|
{
|
||
|
#if _DEBUG
|
||
|
n_assert2(t.w() == 0, "w component not 0, use vector for translation not a point!");
|
||
|
#endif
|
||
|
|
||
|
this->mx.setCol(3,this->mx.getCol(3) + t.vec);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline void
|
||
|
matrix44::scale(float4 const &s)
|
||
|
{
|
||
|
// need to make sure that last column isn't erased
|
||
|
float4 scl = s;
|
||
|
scl.set_w(1.0f);
|
||
|
|
||
|
this->mx.setRow(0,this->mx.getRow(0) * scl.vec);
|
||
|
this->mx.setRow(1,this->mx.getRow(1) * scl.vec);
|
||
|
this->mx.setRow(2,this->mx.getRow(2) * scl.vec);
|
||
|
this->mx.setRow(3,this->mx.getRow(3) * scl.vec);
|
||
|
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline bool
|
||
|
matrix44::isidentity() const
|
||
|
{
|
||
|
return this->mx == Ogre::Matrix4::IDENTITY;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::identity()
|
||
|
{
|
||
|
return matrix44(Ogre::Matrix4::IDENTITY);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::zero()
|
||
|
{
|
||
|
return matrix44(Ogre::Matrix4::ZERO);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::inverse(const matrix44& m)
|
||
|
{
|
||
|
Ogre::Matrix4 mat(m.mx);
|
||
|
return matrix44(mat.inverse());
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::lookatrh(float4 const &eye, float4 const &at, float4 const &up)
|
||
|
{
|
||
|
#if NEBULA3_DEBUG
|
||
|
n_assert(up.length() > 0);
|
||
|
#endif
|
||
|
|
||
|
const float4 zaxis = float4::normalize(eye - at);
|
||
|
float4 normUp = float4::normalize(up);
|
||
|
const float4 xaxis = float4::cross3(normUp, zaxis);
|
||
|
const float4 yaxis = float4::cross3(zaxis, xaxis);
|
||
|
|
||
|
float4 row0 = xaxis;
|
||
|
row0.set_w(-float4::dot3(xaxis,eye));
|
||
|
float4 row1 = yaxis;
|
||
|
row1.set_w(-float4::dot3(yaxis,eye));
|
||
|
float4 row2 = zaxis;
|
||
|
row2.set_w(-float4::dot3(zaxis,eye));
|
||
|
float4 row3(0.f,0.f,0.f,1.f);
|
||
|
matrix44 mat(row0,row1,row2,row3);
|
||
|
return mat;
|
||
|
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::multiply(const matrix44& m0, const matrix44& m1)
|
||
|
{
|
||
|
return m0.mx * m1.mx;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::orthorh(scalar w, scalar h, scalar zn, scalar zf)
|
||
|
{
|
||
|
float4 row0(2/w, 0.f, 0.f, 0.f);
|
||
|
float4 row1(0.f, 2/h, 0.f, 0.f);
|
||
|
|
||
|
#if RENDERDEVICE_D3D9
|
||
|
float4 row2(0.f, 0.f, 1 / (zn - zf ), zn / (zn - zf) );
|
||
|
#endif
|
||
|
|
||
|
#if RENDERDEVICE_NULL
|
||
|
float4 row2(0.f, 0.f, 1 / (zn - zf ), zn / (zn - zf) );
|
||
|
#endif
|
||
|
|
||
|
#if RENDERDEVICE_OPENGL || RENDERDEVICE_OPENGLES
|
||
|
float4 row2(0.f, 0.f, 2 / (zn - zf ), (zn + zf) / (zn - zf) );
|
||
|
#endif
|
||
|
|
||
|
float4 row3(0.f, 0.f, 0.f, 1.f);
|
||
|
return matrix44(row0,row1,row2,row3);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::orthooffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf)
|
||
|
{
|
||
|
float4 row0(2/(r-l), 0.f, 0.f, (l+r)/(l-r));
|
||
|
float4 row1(0.f, 2/(t-b), 0.f, (t+b)/(b-t));
|
||
|
|
||
|
#if RENDERDEVICE_D3D9
|
||
|
float4 row2(0.f, 0.f, 1 / (zn - zf ), zn / (zn - zf) );
|
||
|
#endif
|
||
|
|
||
|
#if RENDERDEVICE_NULL
|
||
|
float4 row2(0.f, 0.f, 1 / (zn - zf ), zn / (zn - zf) );
|
||
|
#endif
|
||
|
|
||
|
#if RENDERDEVICE_OPENGL || RENDERDEVICE_OPENGLES
|
||
|
float4 row2(0.f, 0.f, 2 / (zn - zf ), (zn + zf) / (zn - zf) );
|
||
|
#endif
|
||
|
|
||
|
float4 row3(0.f, 0.f, 0.f, 1.f);
|
||
|
return matrix44(row0,row1,row2,row3);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::perspfovrh(scalar fovy, scalar aspect, scalar zn, scalar zf)
|
||
|
{
|
||
|
scalar yScale = n_cot(scalar(fovy * 0.5));
|
||
|
scalar xScale = yScale / aspect;
|
||
|
float4 row0(xScale, 0.f, 0.f, 0.f);
|
||
|
float4 row1(0.f, yScale, 0.f, 0.f);
|
||
|
|
||
|
#if RENDERDEVICE_D3D9
|
||
|
float4 row2(0.f, 0.f, zf / (zn - zf ), zn * zf / (zn - zf) );
|
||
|
#endif
|
||
|
|
||
|
#if RENDERDEVICE_NULL
|
||
|
float4 row2(0.f, 0.f, zf / (zn - zf ), zn * zf / (zn - zf) );
|
||
|
#endif
|
||
|
|
||
|
#if RENDERDEVICE_OPENGL || RENDERDEVICE_OPENGLES
|
||
|
float4 row2(0.f, 0.f, -(zf + zn) / (zf - zn), -2.0f * (zn * zf) / (zf - zn));
|
||
|
#endif
|
||
|
|
||
|
float4 row3(0.f, 0.f, -1.f, 0.f);
|
||
|
|
||
|
return matrix44(row0,row1,row2,row3);
|
||
|
}
|
||
|
|
||
|
__forceinline matrix44
|
||
|
matrix44::reflect(const float4& p)
|
||
|
{
|
||
|
float4 row0(-2 * p.x() * p.x() + 1, -2 * p.x() * p.y() , -2 * p.x() * p.z() , -2 * p.x() * p.w());
|
||
|
float4 row1(-2 * p.y() * p.x(), -2 * p.y() * p.y() + 1, -2 * p.y() * p.z() , -2 * p.y() * p.w() );
|
||
|
float4 row2(-2 * p.z() * p.x(), -2 * p.z() * p.y(), -2 * p.z() * p.z() + 1, -2 * p.z() * p.w() );
|
||
|
float4 row3(0.f, 0.f, 0.f, 1.f);
|
||
|
return matrix44(row0,row1,row2,row3);
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::rotationaxis(float4 const &axis, scalar angle)
|
||
|
{
|
||
|
Ogre::Quaternion q;
|
||
|
q.FromAngleAxis(Ogre::Radian(angle),Ogre::Vector3(axis.x(),axis.y(),axis.z()));
|
||
|
Ogre::Matrix3 rotM;
|
||
|
q.ToRotationMatrix(rotM);
|
||
|
matrix44 result;
|
||
|
result.set_xaxis(float4(rotM.GetColumn(0).x,rotM.GetColumn(0).y,rotM.GetColumn(0).z,0.f));
|
||
|
result.set_yaxis(float4(rotM.GetColumn(1).x,rotM.GetColumn(1).y,rotM.GetColumn(1).z,0.f));
|
||
|
result.set_zaxis(float4(rotM.GetColumn(2).x,rotM.GetColumn(2).y,rotM.GetColumn(2).z,0.f));
|
||
|
result.set_position(float4(0.f,0.f,0.f,1.f));
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::rotationx(scalar angle)
|
||
|
{
|
||
|
Ogre::Quaternion q;
|
||
|
q.FromAngleAxis(Ogre::Radian(angle),Ogre::Vector3::UNIT_X);
|
||
|
Ogre::Matrix3 rotM;
|
||
|
q.ToRotationMatrix(rotM);
|
||
|
matrix44 result;
|
||
|
result.set_xaxis(float4(rotM.GetColumn(0).x,rotM.GetColumn(0).y,rotM.GetColumn(0).z,0.f));
|
||
|
result.set_yaxis(float4(rotM.GetColumn(1).x,rotM.GetColumn(1).y,rotM.GetColumn(1).z,0.f));
|
||
|
result.set_zaxis(float4(rotM.GetColumn(2).x,rotM.GetColumn(2).y,rotM.GetColumn(2).z,0.f));
|
||
|
result.set_position(float4(0.f,0.f,0.f,1.f));
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::rotationy(scalar angle)
|
||
|
{
|
||
|
Ogre::Quaternion q;
|
||
|
q.FromAngleAxis(Ogre::Radian(angle),Ogre::Vector3::UNIT_Y);
|
||
|
Ogre::Matrix3 rotM;
|
||
|
q.ToRotationMatrix(rotM);
|
||
|
matrix44 result;
|
||
|
result.set_xaxis(float4(rotM.GetColumn(0).x,rotM.GetColumn(0).y,rotM.GetColumn(0).z,0.f));
|
||
|
result.set_yaxis(float4(rotM.GetColumn(1).x,rotM.GetColumn(1).y,rotM.GetColumn(1).z,0.f));
|
||
|
result.set_zaxis(float4(rotM.GetColumn(2).x,rotM.GetColumn(2).y,rotM.GetColumn(2).z,0.f));
|
||
|
result.set_position(float4(0.f,0.f,0.f,1.f));
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::rotationz(scalar angle)
|
||
|
{
|
||
|
Ogre::Quaternion q;
|
||
|
q.FromAngleAxis(Ogre::Radian(angle),Ogre::Vector3::UNIT_Z);
|
||
|
Ogre::Matrix3 rotM;
|
||
|
q.ToRotationMatrix(rotM);
|
||
|
matrix44 result;
|
||
|
result.set_xaxis(float4(rotM.GetColumn(0).x,rotM.GetColumn(0).y,rotM.GetColumn(0).z,0.f));
|
||
|
result.set_yaxis(float4(rotM.GetColumn(1).x,rotM.GetColumn(1).y,rotM.GetColumn(1).z,0.f));
|
||
|
result.set_zaxis(float4(rotM.GetColumn(2).x,rotM.GetColumn(2).y,rotM.GetColumn(2).z,0.f));
|
||
|
result.set_position(float4(0.f,0.f,0.f,1.f));
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::rotationyawpitchroll(scalar yaw, scalar pitch, scalar roll)
|
||
|
{
|
||
|
Ogre::Quaternion q;
|
||
|
q = q.CalRollPitchYaw(roll,pitch,yaw);
|
||
|
Ogre::Matrix3 rotM;
|
||
|
q.ToRotationMatrix(rotM);
|
||
|
matrix44 result;
|
||
|
result.set_xaxis(float4(rotM.GetColumn(0).x,rotM.GetColumn(0).y,rotM.GetColumn(0).z,0.f));
|
||
|
result.set_yaxis(float4(rotM.GetColumn(1).x,rotM.GetColumn(1).y,rotM.GetColumn(1).z,0.f));
|
||
|
result.set_zaxis(float4(rotM.GetColumn(2).x,rotM.GetColumn(2).y,rotM.GetColumn(2).z,0.f));
|
||
|
result.set_position(float4(0.f,0.f,0.f,1.f));
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::scaling(scalar sx, scalar sy, scalar sz)
|
||
|
{
|
||
|
matrix44 mat(Ogre::Matrix4::IDENTITY);
|
||
|
mat.mx.setScale(Ogre::Vector3(sx,sy,sz));
|
||
|
return mat;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::scaling(float4 const &s)
|
||
|
{
|
||
|
matrix44 mat(Ogre::Matrix4::IDENTITY);
|
||
|
mat.mx.setScale(Ogre::Vector3(s.x(),s.y(),s.z()));
|
||
|
return mat;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::translation(scalar x, scalar y, scalar z)
|
||
|
{
|
||
|
matrix44 mat(Ogre::Matrix4::IDENTITY);
|
||
|
mat.set_position(float4(x,y,z,1.f));
|
||
|
return mat;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::translation(float4 const &t)
|
||
|
{
|
||
|
matrix44 mat(Ogre::Matrix4::IDENTITY);
|
||
|
mat.set_position(t);
|
||
|
return mat;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline matrix44
|
||
|
matrix44::transpose(const matrix44& m)
|
||
|
{
|
||
|
|
||
|
return matrix44(m.mx.transpose());
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline
|
||
|
float4
|
||
|
matrix44::transform(const matrix44 &m, const float4 &v)
|
||
|
{
|
||
|
return m.mx * v.vec;
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
/**
|
||
|
*/
|
||
|
__forceinline
|
||
|
void
|
||
|
matrix44::print() const
|
||
|
{
|
||
|
n_printf("%f, %f, %f, %f \n%f, %f, %f, %f\n %f, %f, %f, %f\n%f, %f, %f, %f\n",
|
||
|
mx[0][0],mx[0][1],mx[0][2],mx[0][3],
|
||
|
mx[1][0],mx[1][1],mx[1][2],mx[1][3],
|
||
|
mx[2][0],mx[2][1],mx[2][2],mx[2][3],
|
||
|
mx[3][0],mx[3][1],mx[3][2],mx[3][3]);
|
||
|
}
|
||
|
} // namespace Math
|
||
|
//------------------------------------------------------------------------------
|
||
|
|