Browse Source

implemented application and scenegraph

master
cirdan 12 years ago
parent
commit
2373b382f1

+ 220
- 0
engine/Application.cpp View File

@@ -0,0 +1,220 @@
#include "Application.h"
#include "Utilities/CfgParser.h"
#include "Utilities/Log.h"
#include "ScriptSystem_Application.h"
#include "ScriptSystem_Camera.h"
#include "ScriptSystem_Font.h"
#include "ScriptSystem_Image.h"
#include "ScriptSystem_Math.h"
#include "ScriptSystem_RigidBody.h"
namespace BlueCore
{
void Application::KeySlot(int key, int action)
{
if (key == GLFW_KEY_ESC && action == GLFW_RELEASE)
quit();
}
void Application::MouseMoveSlot(int x, int y)
{
_CameraPhi += (x - _LastMouseX) / 200.0;
_LastMouseX = x;
_CameraTheta += (y - _LastMouseY) / 200.0;
_LastMouseY = y;
}
void Application::MouseWheelSlot(int z)
{
if ((z - _LastWheel) < 0)
_CameraRadius *= 2.0;
else
_CameraRadius *= 0.5;
if (_CameraRadius < 1.0)
_CameraRadius = 1.0;
_LastWheel = z;
}
bool Application::initialize()
{
CfgParser cfg;
cfg.parseFile("options.cfg");
int width = cfg.get("width", 640);
int height = cfg.get("height", 480);
bool fullscreen = cfg.get("fullscreen", false);
_Window = new RenderWindow();
if (_Window->create(width, height, 0, 0, 0, fullscreen) == false)
return false;
_Device = new RenderDevice(_Window);
_FontManager = new FontManager(_Device);
_MeshManager = new MeshManager(_Device);
_TextureManager = new TextureManager();
_ScriptSystem = new ScriptSystem();
_ShaderManager = new ShaderManager(_Window);
_Simulation = new RigidBodySimulation(_ScriptSystem);
_ModelManager = new ModelManager (_TextureManager, _ShaderManager, _MeshManager);
_RenderQueue = new RenderQueue();
setupScriptSystem_Application(_ScriptSystem, this);
setupScriptSystem_Camera(_ScriptSystem);
setupScriptSystem_Font(_ScriptSystem, _FontManager);
setupScriptSystem_Image(_ScriptSystem, _TextureManager, _Device);
setupScriptSystem_Math(_ScriptSystem);
setupScriptSystem_RigidBody(_ScriptSystem, _Simulation);
if (_ScriptSystem->loadScript("main") == false)
return false;
_ScriptSystem->callFunction("Initialize");
_Window->KeySignal.connect(this, &Application::KeySlot);
_Window->MouseMoveSignal.connect(this, &Application::MouseMoveSlot);
_Window->MouseWheelSignal.connect(this, &Application::MouseWheelSlot);
_Running = true;
return true;
}
void Application::shutdown()
{
_ScriptSystem->callFunction("Shutdown");
}
void Application::quit()
{
_Running = false;
}
void Application::run()
{
clog << "--- starting main loop..."<< endlog;
_SimulationTime = 0.0;
_StartTime = glfwGetTime();
_LastTime = _StartTime;
double delta = 0.0;
_Paused = false;
_Running = true;
while (_Window->isOpen() && _Running)
{
double now = glfwGetTime();
delta = now - _LastTime;
_LastTime = now;
_ScriptSystem->callFunction("OnFrame", delta, now - _StartTime);
_Device->clear();
//Quaternion q(-_CameraPhi, 0.0, -_CameraTheta);
//camera->setPosition(q.apply(Vector3(0.0, 0.0, _CameraRadius)));
//camera->setRotation(q);
//pos += 5 * _DeltaTime;
if (_SceneGraph.valid())
{
_SceneGraph->queue(_RenderQueue);
_RenderQueue->render(_Device);
}
/*
{
_Device->begin3D(_Camera);
_Device->setAmbientLight(1.0, 1.0, 1.0);
_RenderQueue->clear();
_RenderQueue->addOpaqueItem(model, Vector3(0.0, 0.0, 0.0),
Quaternion());
_RenderQueue->render(_Device);
_Device->end3D();
}
*/
/*
device->pushAbsoluteTransformation(Vector3(), camera->getRotation());
class RenderState
{
bool _Blending;
GLint _BlendFuncSrc;
GLint _BlendFuncDest;
bool _DepthTest;
bool _DepthMask;
bool _Lighting;
};
GLfloat mat_specular[] =
{ 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] =
{ 2.0 };
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_specular);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_specular);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
glColor4d( 1.0f, 1.0f, 1.0f, 1.0f);
device->setTexture(0, starTexture, true);
starMesh->render();
glDisable(GL_BLEND);
device->popTransformation();
*/
// device->useShader (program);
// device->setTexture (stage, name, texture)
// device->clearTextures (stage+1);
//glEnable (GL_TEXTURE_2D);
//glEnable (GL_LIGHTING);
//glBindTexture (GL_TEXTURE_2D, texture->getId() );
// device->
//device->
//model->render();
if (_Paused == false)
{
_Simulation->saveStates();
_Simulation->updateSteps(delta);
while (_Simulation->getSteps() > 0)
{
_ScriptSystem->callFunction("OnStep",
_Simulation->getStepSize(), _SimulationTime);
_SimulationTime += _Simulation->getStepSize();
_Simulation->step();
}
}
_Device->begin2D();
_ScriptSystem->callFunction("OnOverlay", delta, now - _StartTime);
_Device->end2D();
_Device->swap();
}
clog << "--- main loop finished..."<< endlog;
}
void Application::setSceneGraph(SceneGraph *graph)
{
_SceneGraph = graph;
}
void Application::togglePause()
{
_Paused = !_Paused;
}
}

+ 60
- 0
engine/Application.h View File

@@ -0,0 +1,60 @@
#ifndef BLUECORE_APPLICATION_H
#define BLUECORE_APPLICATION_H
#include "RenderWindow.h"
#include "RenderDevice.h"
#include "FontManager.h"
#include "MeshManager.h"
#include "TextureManager.h"
#include "ShaderManager.h"
#include "ModelManager.h"
#include "TextureImage.h"
#include "ScriptSystem.h"
#include "RigidBodySimulation.h"
#include "SceneGraph.h"
namespace BlueCore
{
class Application : public Referenced, public sigslot::has_slots<>
{
bool _Running;
bool _Paused;
double _SimulationTime;
double _StartTime;
double _LastTime;
double _CameraPhi, _CameraTheta, _CameraRadius;
int _LastMouseX, _LastMouseY, _LastWheel;
ref_ptr<RenderWindow> _Window;
ref_ptr<RenderDevice> _Device;
ref_ptr<FontManager> _FontManager;
ref_ptr<MeshManager> _MeshManager;
ref_ptr<TextureManager> _TextureManager;
ref_ptr<ScriptSystem> _ScriptSystem;
ref_ptr<ShaderManager> _ShaderManager;
ref_ptr<RigidBodySimulation> _Simulation;
ref_ptr<ModelManager> _ModelManager;
ref_ptr<RenderQueue> _RenderQueue;
ref_ptr<SceneGraph> _SceneGraph;
void KeySlot(int key, int action);
void MouseMoveSlot(int x, int y);
void MouseWheelSlot(int z);
public:
bool initialize();
void shutdown();
void quit();
void run();
void togglePause();
void setSceneGraph (SceneGraph *scenegraph);
};
}
#endif /*APPLICATION_H_*/

+ 20
- 78
engine/Camera.cpp View File

@@ -7,44 +7,36 @@
namespace BlueCore
{

Camera::Camera()
Camera::Camera() :
_LookAt (false), _FoV(45.0), _NearPlane(1.0), _FarPlane(15000.0)
{
}


Camera::~Camera()
{
}


void Camera::setFoV(Scalar fov)
{
_FoV = fov;
}


void Camera::setAspectRatio(Scalar aspect)
{
_AspectRatio = aspect;
}


void Camera::setNearPlane(Scalar near)
{
_NearPlane = near;
}


void Camera::setFarPlane(Scalar far)
{
_FarPlane = far;
}


void Camera::setPosition(const Vector3& position)
{
_Position = position;

if (_LookAt)
updateLookAtRotation();
}

const Vector3& Camera::getPosition()
@@ -52,7 +44,6 @@ const Vector3& Camera::getPosition()
return _Position;
}


void Camera::setRotation(const Quaternion& rotation)
{
_Rotation = rotation;
@@ -63,69 +54,6 @@ const Quaternion& Camera::getRotation()
return _Rotation;
}

#if 0

void Camera::setupProjectionMatrix()
{
Scalar fW, fH;

fH = tan ( (_FoV / 2) / 180* Pi ) * _NearPlane;
fW = fH * _AspectRatio;

// setup projectiom matrix
glMatrixMode (GL_PROJECTION );
glLoadIdentity();
glFrustum ( -fW, fW, -fH, fH, _NearPlane, _FarPlane );

// save variables for frustum culling
/*
_near = nearZ;
_far = farZ;
_hNear = tan ( ( fov / 2 ) / 180 * Pi ) * nearZ;
_wNear = _hNear * aspect;
_hFar = tan ( ( fov / 2 ) / 180 * Pi ) * farZ;
_wFar = _hFar * aspect;
*/
}


void Camera::setupViewMatrix()
{
// set the view matrix
glMatrixMode (GL_MODELVIEW );
glLoadIdentity();
Matrix4x4 m(_Rotation, _Rotation.applyInversed(_Position * -1.0) );
glMultMatrixd ( ( GLdouble * ) &m.m );
/*
// calculate frustum planes
Vector3 up = q.apply ( Vector3 ( 0.0, 1.0, 0.0 ) );
Vector3 right = q.apply ( Vector3 ( 1.0, 0.0, 0.0 ) );
Vector3 d = q.apply ( Vector3 ( 0.0, 0.0, -1.0 ) );

Vector3 fc = p + d * _far;

Vector3 ftl = fc + ( up * _hFar ) - ( right * _wFar );
Vector3 ftr = fc + ( up * _hFar ) + ( right * _wFar );
Vector3 fbl = fc - ( up * _hFar ) - ( right * _wFar );
Vector3 fbr = fc - ( up * _hFar ) + ( right * _wFar );

Vector3 nc = p + d * _near;

Vector3 ntl = nc + ( up * _hNear ) - ( right * _wNear );
Vector3 ntr = nc + ( up * _hNear ) + ( right * _wNear );
Vector3 nbl = nc - ( up * _hNear ) - ( right * _wNear );
Vector3 nbr = nc - ( up * _hNear ) + ( right * _wNear );

_frustumPlanes[RightPlane] = Plane ( nbr, fbr, ntr );
_frustumPlanes[LeftPlane] = Plane ( ntl, fbl, nbl );
_frustumPlanes[BottomPlane] = Plane ( nbl, fbr, nbr );
_frustumPlanes[TopPlane] = Plane ( ntr, ftl, ntl );
_frustumPlanes[FarPlane] = Plane ( ftl, ftr, fbl );
_frustumPlanes[NearPlane] = Plane ( ntl, nbl, ntr );
*/
}
#endif

Scalar Camera::getNearPlane() const
{
return _NearPlane;
@@ -141,5 +69,19 @@ Scalar Camera::getFov() const
return _FoV;
}

} // namespace BlueCore
void Camera::lookAt(const Vector3 &point)
{
_LookAt = true;
_LookAtPoint = point;
_LookAtUp = Vector3(0.0, 1.0, 0.0);

updateLookAtRotation();
}

void Camera::updateLookAtRotation()
{
Matrix3x3 m (_LookAtPoint - _Position, _LookAtUp);
_Rotation = m.toQuaternion().inversed();
}

} // namespace BlueCore

+ 4
- 3
engine/Camera.h View File

@@ -19,12 +19,14 @@ private:
Vector3 _LookAtPoint;
Vector3 _LookAtUp;
bool _LookAt;
Scalar _NearPlane, _FarPlane, _FoV, _AspectRatio;
Scalar _FoV, _NearPlane, _FarPlane;
//Frustum _Frustum;

Vector3 _Position;
Quaternion _Rotation;

void updateLookAtRotation();

public:

Camera();
@@ -35,7 +37,6 @@ public:
void lookStraight();

void setFoV(Scalar fov);
void setAspectRatio(Scalar aspect);
void setNearPlane(Scalar near);
void setFarPlane(Scalar far);

@@ -48,7 +49,7 @@ public:
Scalar getNearPlane() const;
Scalar getFarPlane() const;
Scalar getFov() const;
//const Frustum &getFrustum() const;
};


+ 601
- 774
engine/Math/Matrix.h View File

@@ -12,855 +12,682 @@
namespace BlueCore
{
template <class T>
class Matrix3x3Template
template<class T> class Matrix3x3Template
{
public:
T m[9];
inline Matrix3x3Template()
{
public:
T m[9];
identity();
}
/**
* default constructor
*/
inline Matrix3x3Template()
{
identity();
}
template<class S> inline Matrix3x3Template(const S a[9])
{
m[0] = static_cast<T>(a[0]);
m[1] = static_cast<T>(a[1]);
m[2] = static_cast<T>(a[2]);
m[3] = static_cast<T>(a[3]);
m[4] = static_cast<T>(a[4]);
m[5] = static_cast<T>(a[5]);
/**
* constructor from array
*/
template <class S>
inline Matrix3x3Template( const S a[9] )
{
m[0] = static_cast<T>(a[0]);
m[1] = static_cast<T>(a[1]);
m[2] = static_cast<T>(a[2]);
m[6] = static_cast<T>(a[6]);
m[7] = static_cast<T>(a[7]);
m[8] = static_cast<T>(a[8]);
}
m[3] = static_cast<T>(a[3]);
m[4] = static_cast<T>(a[4]);
m[5] = static_cast<T>(a[5]);
template<class S> inline Matrix3x3Template(const Matrix3x3Template<S> &a)
{
m[0] = static_cast<T>(a.m[0]);
m[1] = static_cast<T>(a.m[1]);
m[2] = static_cast<T>(a.m[2]);
m[6] = static_cast<T>(a[6]);
m[7] = static_cast<T>(a[7]);
m[8] = static_cast<T>(a[8]);
}
m[3] = static_cast<T>(a.m[3]);
m[4] = static_cast<T>(a.m[4]);
m[5] = static_cast<T>(a.m[5]);
/**
* copy constructor
*/
template <class S>
inline Matrix3x3Template( const Matrix3x3Template<S> &a )
{
m[0] = static_cast<T>(a.m[0]);
m[1] = static_cast<T>(a.m[1]);
m[2] = static_cast<T>(a.m[2]);
m[6] = static_cast<T>(a.m[6]);
m[7] = static_cast<T>(a.m[7]);
m[8] = static_cast<T>(a.m[8]);
}
m[3] = static_cast<T>(a.m[3]);
m[4] = static_cast<T>(a.m[4]);
m[5] = static_cast<T>(a.m[5]);
inline Matrix3x3Template(const Vector3Template<T> &h,
const Vector3Template<T> &u)
{
Vector3Template<T> a, b, c;
c = h.normalized();
a = h.cross( u ).normalized();
b = c.cross( a ).normalized();
m[6] = static_cast<T>(a.m[6]);
m[7] = static_cast<T>(a.m[7]);
m[8] = static_cast<T>(a.m[8]);
}
m[0] = a.x;
m[1] = b.x;
m[2] = c.x;
m[3] = a.y;
m[4] = b.y;
m[5] = c.y;
/**
* constructor from heading and up vectors
*/
inline Matrix3x3Template(
const Vector3Template<T> &h,
const Vector3Template<T> &u )
{
Vector3Template<T> a, b, c;
c = h.unit();
a = h.crossProduct( u ).unit();
b = c.crossProduct( a ).unit();
m[0] = a.x;
m[1] = b.x;
m[2] = c.x;
m[3] = a.y;
m[4] = b.y;
m[5] = c.y;
m[6] = a.z;
m[7] = b.z;
m[8] = c.z;
}
m[6] = a.z;
m[7] = b.z;
m[8] = c.z;
}
/**
* contructor from euler angles
*/
inline Matrix3x3Template( T a, T e, T t )
{
T ch = cos( a );
T sh = sin( a );
T ca = cos( e );
T sa = sin( e );
T cb = cos( t );
T sb = sin( t );
m[0] = ch * ca;
m[1] = sh*sb - ch*sa*cb;
m[2] = ch*sa*sb + sh*cb;
m[3] = sa;
m[4] = ca*cb;
m[5] = -ca*sb;
m[6] = -sh*ca;
m[7] = sh*sa*cb + ch*sb;
m[8] = -sh*sa*sb + ch*cb;
}
/**
* contructor from quaternion
*/
template <class S>
inline Matrix3x3Template( const QuaternionTemplate<S> &q )
{
T xx = static_cast<T>(q.x*q.x),
xy = static_cast<T>(q.x*q.y),
xz = static_cast<T>(q.x*q.z),
xw = static_cast<T>(q.x*q.w),
yy = static_cast<T>(q.y*q.y),
yz = static_cast<T>(q.y*q.z),
yw = static_cast<T>(q.y*q.w),
zz = static_cast<T>(q.z*q.z),
zw = static_cast<T>(q.z*q.w);
m[0] = 1 - yy - yy - zz - zz;
m[1] = xy + xy + zw + zw;
m[2] = xz + xz - yw - yw;
m[3] = xy + xy - zw - zw;
m[4] = 1 - xx - xx - zz - zz;
m[5] = yz + yz + xw + xw;
m[6] = xz + xz + yw + yw;
m[7] = yz + yz - xw - xw;
m[8] = 1 - xx - xx - yy - yy;
}
/**
* set matrix to identity matrix
*/
inline void identity()
{
m[0] = static_cast<T>(1);
m[1] = static_cast<T>(0);
m[2] = static_cast<T>(0);
m[3] = static_cast<T>(0);
m[4] = static_cast<T>(1);
m[5] = static_cast<T>(0);
m[6] = static_cast<T>(0);
m[7] = static_cast<T>(0);
m[8] = static_cast<T>(1);
}
inline Matrix3x3Template(T a, T e, T t)
{
T ch = cos(a);
T sh = sin(a);
T ca = cos(e);
T sa = sin(e);
T cb = cos(t);
T sb = sin(t);
m[0] = ch * ca;
m[1] = sh*sb - ch*sa*cb;
m[2] = ch*sa*sb + sh*cb;
m[3] = sa;
m[4] = ca*cb;
m[5] = -ca*sb;
m[6] = -sh*ca;
m[7] = sh*sa*cb + ch*sb;
m[8] = -sh*sa*sb + ch*cb;
}
template<class S> inline Matrix3x3Template(const QuaternionTemplate<S> &q)
{
T xx = static_cast<T>(q.x*q.x), xy = static_cast<T>(q.x*q.y), xz =
static_cast<T>(q.x*q.z), xw = static_cast<T>(q.x*q.w),
yy = static_cast<T>(q.y*q.y), yz = static_cast<T>(q.y*q.z), yw =
static_cast<T>(q.y*q.w),
/**
* get transposed matrix
*/
inline Matrix3x3Template<T> transposed() const
{
Matrix3x3Template<T> a;
a.m[0] = m[0]; a.m[3] = m[1]; a.m[6] = m[2];
a.m[1] = m[3]; a.m[4] = m[4]; a.m[7] = m[5];
a.m[2] = m[6]; a.m[5] = m[7]; a.m[8] = m[8];
return a;
}
zz = static_cast<T>(q.z*q.z), zw = static_cast<T>(q.z*q.w);
m[0] = 1 - yy - yy - zz - zz;
m[1] = xy + xy + zw + zw;
m[2] = xz + xz - yw - yw;
/**
* transpose
*/
inline void transpose()
{
swap( m[3], m[1] );
swap( m[6], m[2] );
swap( m[7], m[5] );
}
m[3] = xy + xy - zw - zw;
m[4] = 1 - xx - xx - zz - zz;
m[5] = yz + yz + xw + xw;
/**
* determinate
*/
inline T determinant() const
{
return ( m[0]*m[4]*m[8] + m[1]*m[5]*m[6] + m[2]*m[3]*m[7] )
- ( m[6]*m[4]*m[2] + m[7]*m[5]*m[0] + m[8]*m[3]*m[1] );
}
m[6] = xz + xz + yw + yw;
m[7] = yz + yz - xw - xw;
m[8] = 1 - xx - xx - yy - yy;
}
inline Matrix3x3Template<T> inverted()
{
T det = determinant();
T one_over_det = 1.0f / det;
Matrix3x3Template<T> result;
result.m[0] = +(m[4] * m[8] - m[5] * m[7]) * one_over_det;
result.m[1] = -(m[1] * m[8] - m[2] * m[7]) * one_over_det;
result.m[2] = +(m[1] * m[5] - m[2] * m[4]) * one_over_det;
result.m[3] = -(m[3] * m[8] - m[5] * m[6]) * one_over_det;
result.m[4] = +(m[0] * m[8] - m[2] * m[6]) * one_over_det;
result.m[5] = -(m[0] * m[5] - m[2] * m[3]) * one_over_det;
result.m[6] = +(m[3] * m[7] - m[4] * m[6]) * one_over_det;
result.m[7] = -(m[0] * m[7] - m[1] * m[6]) * one_over_det;
result.m[8] = +(m[0] * m[4] - m[1] * m[3]) * one_over_det;
return result;
}
/**
* add/assign operator
*/
template <class S>
inline Matrix3x3Template<T> &operator += (
const Matrix3x3Template<S> &a )
{
m[0] += static_cast<T>(a.m[0]);
m[1] += static_cast<T>(a.m[1]);
m[2] += static_cast<T>(a.m[2]);
m[3] += static_cast<T>(a.m[3]);
m[4] += static_cast<T>(a.m[4]);
m[5] += static_cast<T>(a.m[5]);
m[6] += static_cast<T>(a.m[6]);
m[7] += static_cast<T>(a.m[7]);
m[8] += static_cast<T>(a.m[8]);
return *this;
}
/**
* matrix multiplication
*/
template <class S>
inline Matrix3x3Template<T> operator * ( const Matrix3x3Template<S> &a )
{
Matrix3x3Template<T> result;
result.m[0] = m[0] * static_cast<T>(a.m[0])
+ m[3] * static_cast<T>(a.m[1])
+ m[6] * static_cast<T>(a.m[2]);
result.m[1] = m[1] * static_cast<T>(a.m[0])
+ m[4] * static_cast<T>(a.m[1])
+ m[7] * static_cast<T>(a.m[2]);
result.m[2] = m[2] * static_cast<T>(a.m[0])
+ m[5] * static_cast<T>(a.m[1])
+ m[8] * static_cast<T>(a.m[2]);
result.m[3] = m[0] * static_cast<T>(a.m[3])
+ m[3] * static_cast<T>(a.m[4])
+ m[6] * static_cast<T>(a.m[5]);
result.m[4] = m[1] * static_cast<T>(a.m[3])
+ m[4] * static_cast<T>(a.m[4])
+ m[7] * static_cast<T>(a.m[5]);
result.m[5] = m[2] * static_cast<T>(a.m[3])
+ m[5] * static_cast<T>(a.m[4])
+ m[8] * static_cast<T>(a.m[5]);
result.m[6] = m[0] * static_cast<T>(a.m[6])
+ m[3] * static_cast<T>(a.m[7])
+ m[6] * static_cast<T>(a.m[8]);
result.m[7] = m[1] * static_cast<T>(a.m[6])
+ m[4] * static_cast<T>(a.m[7])
+ m[7] * static_cast<T>(a.m[8]);
result.m[8] = m[2] * static_cast<T>(a.m[6])
+ m[5] * static_cast<T>(a.m[7])
+ m[8] * static_cast<T>(a.m[8]);
return result;
}
void set(size_t i, Vector3Template<T>& v)
{
m[i] = v.x;
m[i+3] = v.y;
m[i+6] = v.z;
}
/**
* matrix vector multiplication
*/
template <class S>
Vector3Template<T> operator * ( const Vector3Template<S>& a )
{
return Vector3Template<T>(
m[0] * static_cast<T>(a.x)
+ m[3] * static_cast<T>(a.y)
+ m[6] * static_cast<T>(a.z),
m[1] * static_cast<T>(a.x)
+ m[4] * static_cast<T>(a.y)
+ m[7] * static_cast<T>(a.z),
m[2] * static_cast<T>(a.x)
+ m[5] * static_cast<T>(a.y)
+ m[8] * static_cast<T>(a.z) );
}
inline void identity()
{
m[0] = static_cast<T>(1);
m[1] = static_cast<T>(0);
m[2] = static_cast<T>(0);
/**
* matrix scalar multiplication
*/
template <class S>
Matrix3x3Template<T> operator * ( const S a )
{
Matrix3x3Template<T> result;
result.m[0] = m[0] * static_cast<T>(a);
result.m[1] = m[1] * static_cast<T>(a);
result.m[2] = m[2] * static_cast<T>(a);
result.m[3] = m[3] * static_cast<T>(a);
result.m[4] = m[4] * static_cast<T>(a);
result.m[5] = m[5] * static_cast<T>(a);
result.m[6] = m[6] * static_cast<T>(a);
result.m[7] = m[7] * static_cast<T>(a);
result.m[8] = m[8] * static_cast<T>(a);
return result;
}
m[3] = static_cast<T>(0);
m[4] = static_cast<T>(1);
m[5] = static_cast<T>(0);
friend std::ostream &operator << ( std::ostream& os, Matrix3x3Template<T> m )
{
os << "( " << m.m[0] << ", " << m.m[1] << ", " << m.m[2] << " )" << std::endl;
os << "( " << m.m[3] << ", " << m.m[4] << ", " << m.m[5] << " )" << std::endl;
os << "( " << m.m[6] << ", " << m.m[7] << ", " << m.m[8] << " )" << std::endl;
return os;
}
m[6] = static_cast<T>(0);
m[7] = static_cast<T>(0);
m[8] = static_cast<T>(1);
}
};
typedef Matrix3x3Template<float> Matrix3x3Float;
typedef Matrix3x3Template<double> Matrix3x3Double;
typedef Matrix3x3Template<Scalar> Matrix3x3;
inline Matrix3x3Template<T> transposed() const
{
Matrix3x3Template<T> a;
a.m[0] = m[0];
a.m[3] = m[1];
a.m[6] = m[2];
a.m[1] = m[3];
a.m[4] = m[4];
a.m[7] = m[5];
a.m[2] = m[6];
a.m[5] = m[7];
a.m[8] = m[8];
return a;
}
inline void transpose()
{
swap(m[3], m[1]);
swap(m[6], m[2]);
swap(m[7], m[5]);
}
inline T determinant() const
{
return (m[0]*m[4]*m[8] + m[1]*m[5]*m[6] + m[2]*m[3]*m[7] ) - (m[6]*m[4]
*m[2] + m[7]*m[5]*m[0] + m[8]*m[3]*m[1] );
}
template <class T>
class Matrix4x4Template
inline Matrix3x3Template<T> inverted()
{
T det = determinant();
T one_over_det = 1.0f / det;
Matrix3x3Template<T> result;
result.m[0] = +(m[4] * m[8] - m[5] * m[7]) * one_over_det;
result.m[1] = -(m[1] * m[8] - m[2] * m[7]) * one_over_det;
result.m[2] = +(m[1] * m[5] - m[2] * m[4]) * one_over_det;
result.m[3] = -(m[3] * m[8] - m[5] * m[6]) * one_over_det;
result.m[4] = +(m[0] * m[8] - m[2] * m[6]) * one_over_det;
result.m[5] = -(m[0] * m[5] - m[2] * m[3]) * one_over_det;
result.m[6] = +(m[3] * m[7] - m[4] * m[6]) * one_over_det;
result.m[7] = -(m[0] * m[7] - m[1] * m[6]) * one_over_det;
result.m[8] = +(m[0] * m[4] - m[1] * m[3]) * one_over_det;
return result;
}
template<class S> inline Matrix3x3Template<T> &operator +=(
const Matrix3x3Template<S> &a)
{
m[0] += static_cast<T>(a.m[0]);
m[1] += static_cast<T>(a.m[1]);
m[2] += static_cast<T>(a.m[2]);
public:
m[3] += static_cast<T>(a.m[3]);
m[4] += static_cast<T>(a.m[4]);
m[5] += static_cast<T>(a.m[5]);
T m[16];
m[6] += static_cast<T>(a.m[6]);
m[7] += static_cast<T>(a.m[7]);
m[8] += static_cast<T>(a.m[8]);
/**
* default constructor
*/
inline Matrix4x4Template()
{
identity();
}
inline void identity()
{
m[0] = static_cast<T>(1);
m[1] = static_cast<T>(0);
m[2] = static_cast<T>(0);
m[3] = static_cast<T>(0);
m[4] = static_cast<T>(0);
m[5] = static_cast<T>(1);
m[6] = static_cast<T>(0);
m[7] = static_cast<T>(0);
m[8] = static_cast<T>(0);
m[9] = static_cast<T>(0);
m[10] = static_cast<T>(1);
m[11] = static_cast<T>(0);
m[12] = static_cast<T>(0);
m[13] = static_cast<T>(0);
m[14] = static_cast<T>(0);
m[15] = static_cast<T>(1);
}
/**
* constructor from array
*/
inline Matrix4x4Template( const T a[16] )
{
m[0] = a[0]; m[1] = a[1]; m[2] = a[2]; m[3] = a[3];
m[4] = a[4]; m[5] = a[5]; m[6] = a[6]; m[7] = a[7];
m[8] = a[8]; m[9] = a[9]; m[10] = a[10]; m[11] = a[11];
m[12] = a[12]; m[13] = a[13]; m[14] = a[14]; m[15] = a[15];
}
return *this;
}
/**
* constructor from 3x3 matrix, add. element are set to zero
*/
inline Matrix4x4Template( const Matrix3x3Template<T> &a )
{
m[0] = a[0];
m[1] = a[1];
m[2] = a[2];
m[3] = static_cast<T>(0);
m[4] = a[3];
m[5] = a[4];
m[6] = a[5];
m[7] = static_cast<T>(0);
m[8] = a[6];
m[9] = a[7];
m[10] = a[8];
m[11] = static_cast<T>(0);
m[12] = static_cast<T>(0);
m[13] = static_cast<T>(0);
m[14] = static_cast<T>(0);
m[15] = static_cast<T>(1);
}
/**
* constructor from 3x3 rotation matrix and translation vector
*/
inline Matrix4x4Template(
const Matrix3x3Template<T> &a,
const Vector3Template<T> &b )
{
m[0] = a[0];
m[1] = a[1];
m[2] = a[2];
m[3] = static_cast<T>(0);
m[4] = a[3];
m[5] = a[4];
m[6] = a[5];
m[7] = static_cast<T>(0);
m[8] = a[6];
m[9] = a[7];
m[10] = a[8];
m[11] = static_cast<T>(0);
m[12] = b.x;
m[13] = b.y;
m[14] = b.z;
m[15] = static_cast<T>(1);
}
template<class S> inline Matrix3x3Template<T> operator *(
const Matrix3x3Template<S> &a)
{
Matrix3x3Template<T> result;
/**
* copy constructor
*/
inline Matrix4x4Template( const Matrix4x4Template<T> &a )
{
m[0] = a.m[0];
m[1] = a.m[1];
m[2] = a.m[2];
m[3] = a.m[3];
m[4] = a.m[4];
m[5] = a.m[5];
m[6] = a.m[6];
m[7] = a.m[7];
m[8] = a.m[8];
m[9] = a.m[9];
m[10] = a.m[10];
m[11] = a.m[11];
m[12] = a.m[12];
m[13] = a.m[13];
m[14] = a.m[14];
m[15] = a.m[15];
}
result.m[0] = m[0] * static_cast<T>(a.m[0]) + m[3]
* static_cast<T>(a.m[1]) + m[6] * static_cast<T>(a.m[2]);
result.m[1] = m[1] * static_cast<T>(a.m[0]) + m[4]
* static_cast<T>(a.m[1]) + m[7] * static_cast<T>(a.m[2]);
/**
* constructor from quaternion
*/
inline Matrix4x4Template( const QuaternionTemplate<T> &q )
{
m[0] = 1 - 2*q.y*q.y - 2*q.z*q.z;
m[1] = 2*q.x*q.y - 2*q.z*q.w;
m[2] = 2*q.x*q.z + 2*q.y*q.w;
m[3] = static_cast<T>(0);
m[4] = 2*q.x*q.y + 2*q.z*q.w;
m[5] = 1 - 2*q.x*q.x - 2*q.z*q.z;
m[6] = 2*q.y*q.z - 2*q.x*q.w;
m[7] = static_cast<T>(0);
m[8] = 2*q.x*q.z - 2*q.y*q.w;
m[9] = 2*q.y*q.z + 2*q.x*q.w;
m[10] = 1 - 2*q.x*q.x - 2*q.y*q.y;
m[11] = static_cast<T>(0);
m[12] = static_cast<T>(0);
m[13] = static_cast<T>(0);
m[14] = static_cast<T>(0);
m[15] = static_cast<T>(1);
}
result.m[2] = m[2] * static_cast<T>(a.m[0]) + m[5]
* static_cast<T>(a.m[1]) + m[8] * static_cast<T>(a.m[2]);
result.m[3] = m[0] * static_cast<T>(a.m[3]) + m[3]
* static_cast<T>(a.m[4]) + m[6] * static_cast<T>(a.m[5]);
/**
* constructor from quaternion and translation vector
*/
inline Matrix4x4Template(
const QuaternionTemplate<T> &q,
const Vector3Template<T> &a )
{
m[0] = 1 - 2*q.y*q.y - 2*q.z*q.z;
m[1] = 2*q.x*q.y - 2*q.z*q.w;
m[2] = 2*q.x*q.z + 2*q.y*q.w;
m[3] = static_cast<T>(0);
m[4] = 2*q.x*q.y + 2*q.z*q.w;
m[5] = 1 - 2*q.x*q.x - 2*q.z*q.z;
m[6] = 2*q.y*q.z - 2*q.x*q.w;
m[7] = static_cast<T>(0);
m[8] = 2*q.x*q.z - 2*q.y*q.w;
m[9] = 2*q.y*q.z + 2*q.x*q.w;
m[10] = 1 - 2*q.x*q.x - 2*q.y*q.y;
m[11] = static_cast<T>(0);
m[12] = a.x;
m[13] = a.y;
m[14] = a.z;
m[15] = static_cast<T>(1);
}
result.m[4] = m[1] * static_cast<T>(a.m[3]) + m[4]
* static_cast<T>(a.m[4]) + m[7] * static_cast<T>(a.m[5]);
/**
* constructor from heading, up and translation vectors
*/
inline Matrix4x4Template(
const Vector3Template<T> &h,
const Vector3Template<T> &u,
const Vector3Template<T> &t )
{
Vector3Template<T> a, b, c;
c = h.unit();
a = h.crossProduct( u ).unit();
b = c.crossProduct( a ).unit();
m[0] = a.x;
m[1] = b.x;
m[2] = c.x;
m[3] = static_cast<T>(0);
m[4] = a.y;
m[5] = b.y;
m[6] = c.y;
m[7] = static_cast<T>(0);
m[8] = a.z;
m[9] = b.z;
m[10] = c.z;
m[11] = static_cast<T>(0);
m[12] = t.x;
m[13] = t.y;
m[14] = t.z;
m[15] = static_cast<T>(1);
}
result.m[5] = m[2] * static_cast<T>(a.m[3]) + m[5]
* static_cast<T>(a.m[4]) + m[8] * static_cast<T>(a.m[5]);
result.m[6] = m[0] * static_cast<T>(a.m[6]) + m[3]
* static_cast<T>(a.m[7]) + m[6] * static_cast<T>(a.m[8]);
/**
* contructor from euler angles
*/
inline Matrix4x4Template(
T a,
T e,
T t,
const Vector3Template<T> &tr )
{
T ch = cos( a );
T sh = sin( a );
T ca = cos( e );
T sa = sin( e );
T cb = cos( t );
T sb = sin( t );
m[0] = ch * ca;
m[1] = sh*sb - ch*sa*cb;
m[2] = ch*sa*sb + sh*cb;
m[3] = static_cast<T>(0);
m[4] = sa;
m[5] = ca*cb;
m[6] = -ca*sb;
m[7] = static_cast<T>(0);
m[8] = -sh*ca;
m[9] = sh*sa*cb + ch*sb;
m[10] = -sh*sa*sb + ch*cb;
m[11] = static_cast<T>(0);
m[12] = tr.x;
m[13] = tr.y;
m[14] = tr.z;
m[15] = static_cast<T>(1);
}
result.m[7] = m[1] * static_cast<T>(a.m[6]) + m[4]
* static_cast<T>(a.m[7]) + m[7] * static_cast<T>(a.m[8]);
result.m[8] = m[2] * static_cast<T>(a.m[6]) + m[5]
* static_cast<T>(a.m[7]) + m[8] * static_cast<T>(a.m[8]);
/**
* transpose this matrix
*/
inline void transpose()
{
std::swap( m[4], m[1] );
std::swap( m[8], m[2] );
std::swap( m[12], m[3] );
return result;
}
std::swap( m[9], m[6] );
std::swap( m[13], m[7] );
std::swap( m[14], m[11] );
template<class S> Vector3Template<T> operator *(const Vector3Template<S>& a)
{
return Vector3Template<T>(m[0] * static_cast<T>(a.x) + m[3]
* static_cast<T>(a.y) + m[6] * static_cast<T>(a.z), m[1]
* static_cast<T>(a.x) + m[4] * static_cast<T>(a.y) + m[7]
* static_cast<T>(a.z), m[2] * static_cast<T>(a.x) + m[5]
* static_cast<T>(a.y) + m[8] * static_cast<T>(a.z) );
}
template<class S> Matrix3x3Template<T> operator *(const S a)
{
Matrix3x3Template<T> result;
result.m[0] = m[0] * static_cast<T>(a);
result.m[1] = m[1] * static_cast<T>(a);
result.m[2] = m[2] * static_cast<T>(a);
result.m[3] = m[3] * static_cast<T>(a);
result.m[4] = m[4] * static_cast<T>(a);
result.m[5] = m[5] * static_cast<T>(a);
result.m[6] = m[6] * static_cast<T>(a);
result.m[7] = m[7] * static_cast<T>(a);
result.m[8] = m[8] * static_cast<T>(a);
return result;
}
friend std::ostream &operator <<(std::ostream& os, Matrix3x3Template<T> m)
{
os << "( " << m.m[0] << ", " << m.m[1] << ", " << m.m[2] << " )"
<< std::endl;
os << "( " << m.m[3] << ", " << m.m[4] << ", " << m.m[5] << " )"
<< std::endl;
os << "( " << m.m[6] << ", " << m.m[7] << ", " << m.m[8] << " )"
<< std::endl;
return os;
}
QuaternionTemplate<T> toQuaternion() const
{
// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
// article "Quaternion Calculus and Fast Animation".
T fTrace = m[0]+m[4]+m[8];
T fRoot;
QuaternionTemplate<T> q;
if (fTrace > 0.0)
{
// |w| > 1/2, may as well choose w > 1/2
fRoot = std::sqrt(fTrace + 1.0); // 2w
q.w = 0.5*fRoot;
fRoot = 0.5/fRoot; // 1/(4w)
q.x = (m[7]-m[5])*fRoot;
q.y = (m[2]-m[6])*fRoot;
q.z = (m[3]-m[1])*fRoot;
}
else
{
// |w| <= 1/2
static size_t s_iNext[3] =
{ 1, 2, 0 };
size_t i = 0;
if (m[4] > m[0])
i = 1;
if (m[8] > m[i*3+i])
i = 2;
size_t j = s_iNext[i];
size_t k = s_iNext[j];
fRoot = std::sqrt(m[i*3+i]-m[j*3+j]-m[k*k+1] + 1.0);
T* apkQuat[3] =
{ &q.x, &q.y, &q.z };
*apkQuat[i] = 0.5*fRoot;
fRoot = 0.5/fRoot;
q.w = (m[k*3+j]-m[j*3+k])*fRoot;
*apkQuat[j] = (m[j*3+i]+m[i*3+j])*fRoot;
*apkQuat[k] = (m[k*3+i]+m[i*3+k])*fRoot;
}
/**
* get transposed matrix
*/
inline Matrix4x4Template<T> transposed()
{
Matrix4x4Template<T> a;
a.m[0] = m[0]; a.m[4] = m[1]; a.m[8] = m[2]; a.m[12] = m[3];
a.m[1] = m[4]; a.m[5] = m[5]; a.m[9] = m[6]; a.m[13] = m[7];
a.m[2] = m[8]; a.m[6] = m[9]; a.m[10] = m[10]; a.m[14] = m[11];
a.m[3] = m[12]; a.m[7] = m[13]; a.m[11] = m[14]; a.m[15] = m[15];
return a;
}
/**
* matrix multiplication
*/
template <class S>
inline Matrix4x4Template<T> operator * ( const Matrix4x4Template<S> &a )
{
Matrix4x4Template<T> result;
result.m[0] = m[0] * static_cast<T>(a.m[0])
+ m[4] * static_cast<T>(a.m[1])
+ m[8] * static_cast<T>(a.m[2])
+ m[12] * static_cast<T>(a.m[3]);
result.m[1] = m[1] * static_cast<T>(a.m[0])
+ m[5] * static_cast<T>(a.m[1])
+ m[9] * static_cast<T>(a.m[2])
+ m[13] * static_cast<T>(a.m[3]);
result.m[2] = m[2] * static_cast<T>(a.m[0])
+ m[6] * static_cast<T>(a.m[1])
+ m[10] * static_cast<T>(a.m[2])
+ m[14] * static_cast<T>(a.m[3]);
return q;
}
};
result.m[3] = m[3] * static_cast<T>(a.m[0])
+ m[7] * static_cast<T>(a.m[1])
+ m[11] * static_cast<T>(a.m[2])
+ m[15] * static_cast<T>(a.m[3]);
typedef Matrix3x3Template<float> Matrix3x3Float;
typedef Matrix3x3Template<double> Matrix3x3Double;
typedef Matrix3x3Template<Scalar> Matrix3x3;
template<class T> class Matrix4x4Template
{
result.m[4] = m[0] * static_cast<T>(a.m[4])
+ m[4] * static_cast<T>(a.m[5])
+ m[8] * static_cast<T>(a.m[6])
+ m[12] * static_cast<T>(a.m[7]);
result.m[5] = m[1] * static_cast<T>(a.m[4])
+ m[5] * static_cast<T>(a.m[5])
+ m[9] * static_cast<T>(a.m[6])
+ m[13] * static_cast<T>(a.m[7]);
result.m[6] = m[2] * static_cast<T>(a.m[4])
+ m[6] * static_cast<T>(a.m[5])
+ m[10] * static_cast<T>(a.m[6])
+ m[14] * static_cast<T>(a.m[7]);
public:
result.m[7] = m[3] * static_cast<T>(a.m[4])
+ m[7] * static_cast<T>(a.m[5])
+ m[11] * static_cast<T>(a.m[6])
+ m[15] * static_cast<T>(a.m[7]);
T m[16];
inline Matrix4x4Template()
{
identity();
}
result.m[8] = m[0] * static_cast<T>(a.m[8])
+ m[4] * static_cast<T>(a.m[9])
+ m[8] * static_cast<T>(a.m[10])
+ m[12] * static_cast<T>(a.m[11]);
result.m[9] = m[1] * static_cast<T>(a.m[8])
+ m[5] * static_cast<T>(a.m[9])
+ m[9] * static_cast<T>(a.m[10])
+ m[13] * static_cast<T>(a.m[11]);
result.m[10] = m[2] * static_cast<T>(a.m[8])
+ m[6] * static_cast<T>(a.m[9])
+ m[10] * static_cast<T>(a.m[10])
+ m[14] * static_cast<T>(a.m[11]);
result.m[11] = m[3] * static_cast<T>(a.m[8])
+ m[7] * static_cast<T>(a.m[9])
+ m[11] * static_cast<T>(a.m[10])
+ m[15] * static_cast<T>(a.m[11]);
inline void identity()
{
m[0] = static_cast<T>(1);
m[1] = static_cast<T>(0);
m[2] = static_cast<T>(0);
m[3] = static_cast<T>(0);
m[4] = static_cast<T>(0);
m[5] = static_cast<T>(1);
m[6] = static_cast<T>(0);
m[7] = static_cast<T>(0);
m[8] = static_cast<T>(0);
m[9] = static_cast<T>(0);
m[10] = static_cast<T>(1);
m[11] = static_cast<T>(0);
m[12] = static_cast<T>(0);
m[13] = static_cast<T>(0);
m[14] = static_cast<T>(0);
m[15] = static_cast<T>(1);
}
inline Matrix4x4Template(const T a[16])
{
m[0] = a[0];
m[1] = a[1];
m[2] = a[2];
m[3] = a[3];
m[4] = a[4];
m[5] = a[5];
m[6] = a[6];
m[7] = a[7];
m[8] = a[8];
m[9] = a[9];
m[10] = a[10];
m[11] = a[11];
m[12] = a[12];
m[13] = a[13];
m[14] = a[14];
m[15] = a[15];
}
inline Matrix4x4Template(const Matrix3x3Template<T> &a)
{
m[0] = a[0];
m[1] = a[1];
m[2] = a[2];
m[3] = static_cast<T>(0);
m[4] = a[3];
m[5] = a[4];
m[6] = a[5];
m[7] = static_cast<T>(0);
m[8] = a[6];
m[9] = a[7];
m[10] = a[8];
m[11] = static_cast<T>(0);
m[12] = static_cast<T>(0);
m[13] = static_cast<T>(0);
m[14] = static_cast<T>(0);
m[15] = static_cast<T>(1);
}
inline Matrix4x4Template(const Matrix3x3Template<T> &a,
const Vector3Template<T> &b)
{
m[0] = a[0];
m[1] = a[1];
m[2] = a[2];
m[3] = static_cast<T>(0);
m[4] = a[3];
m[5] = a[4];
m[6] = a[5];
m[7] = static_cast<T>(0);
m[8] = a[6];
m[9] = a[7];
m[10] = a[8];
m[11] = static_cast<T>(0);
m[12] = b.x;
m[13] = b.y;
m[14] = b.z;
m[15] = static_cast<T>(1);
}
inline Matrix4x4Template(const Matrix4x4Template<T> &a)
{
m[0] = a.m[0];
m[1] = a.m[1];
m[2] = a.m[2];
m[3] = a.m[3];
m[4] = a.m[4];
m[5] = a.m[5];
m[6] = a.m[6];
m[7] = a.m[7];
m[8] = a.m[8];
m[9] = a.m[9];
m[10] = a.m[10];
m[11] = a.m[11];
m[12] = a.m[12];
m[13] = a.m[13];
m[14] = a.m[14];
m[15] = a.m[15];
}
inline Matrix4x4Template(const QuaternionTemplate<T> &q)
{
m[0] = 1 - 2*q.y*q.y - 2*q.z*q.z;
m[1] = 2*q.x*q.y - 2*q.z*q.w;
m[2] = 2*q.x*q.z + 2*q.y*q.w;
m[3] = static_cast<T>(0);
m[4] = 2*q.x*q.y + 2*q.z*q.w;
m[5] = 1 - 2*q.x*q.x - 2*q.z*q.z;
m[6] = 2*q.y*q.z - 2*q.x*q.w;
m[7] = static_cast<T>(0);
m[8] = 2*q.x*q.z - 2*q.y*q.w;
m[9] = 2*q.y*q.z + 2*q.x*q.w;
m[10] = 1 - 2*q.x*q.x - 2*q.y*q.y;
m[11] = static_cast<T>(0);
m[12] = static_cast<T>(0);
m[13] = static_cast<T>(0);
m[14] = static_cast<T>(0);
m[15] = static_cast<T>(1);
}
inline Matrix4x4Template(const QuaternionTemplate<T> &q,
const Vector3Template<T> &a)
{
m[0] = 1 - 2*q.y*q.y - 2*q.z*q.z;
m[1] = 2*q.x*q.y - 2*q.z*q.w;
m[2] = 2*q.x*q.z + 2*q.y*q.w;
m[3] = static_cast<T>(0);
m[4] = 2*q.x*q.y + 2*q.z*q.w;
m[5] = 1 - 2*q.x*q.x - 2*q.z*q.z;
m[6] = 2*q.y*q.z - 2*q.x*q.w;
m[7] = static_cast<T>(0);
m[8] = 2*q.x*q.z - 2*q.y*q.w;
m[9] = 2*q.y*q.z + 2*q.x*q.w;
m[10] = 1 - 2*q.x*q.x - 2*q.y*q.y;
m[11] = static_cast<T>(0);
m[12] = a.x;
m[13] = a.y;
m[14] = a.z;
m[15] = static_cast<T>(1);
}
inline Matrix4x4Template(const Vector3Template<T> &h,
const Vector3Template<T> &u, const Vector3Template<T> &t)
{
Vector3Template<T> a, b, c;
c = h.unit();
a = h.crossProduct( u ).unit();
b = c.crossProduct( a ).unit();
m[0] = a.x;
m[1] = b.x;
m[2] = c.x;
m[3] = static_cast<T>(0);
m[4] = a.y;
m[5] = b.y;
m[6] = c.y;
m[7] = static_cast<T>(0);
m[8] = a.z;
m[9] = b.z;
m[10] = c.z;
m[11] = static_cast<T>(0);
m[12] = t.x;
m[13] = t.y;
m[14] = t.z;
m[15] = static_cast<T>(1);
}
inline Matrix4x4Template(T a, T e, T t, const Vector3Template<T> &tr)
{
T ch = cos(a);
T sh = sin(a);
T ca = cos(e);
T sa = sin(e);
T cb = cos(t);
T sb = sin(t);
m[0] = ch * ca;
m[1] = sh*sb - ch*sa*cb;
m[2] = ch*sa*sb + sh*cb;
m[3] = static_cast<T>(0);
m[4] = sa;
m[5] = ca*cb;
m[6] = -ca*sb;
m[7] = static_cast<T>(0);
m[8] = -sh*ca;
m[9] = sh*sa*cb + ch*sb;
m[10] = -sh*sa*sb + ch*cb;
m[11] = static_cast<T>(0);
m[12] = tr.x;
m[13] = tr.y;
m[14] = tr.z;
m[15] = static_cast<T>(1);
}
inline void transpose()
{
std::swap(m[4], m[1]);
std::swap(m[8], m[2]);
std::swap(m[12], m[3]);
std::swap(m[9], m[6]);
std::swap(m[13], m[7]);
std::swap(m[14], m[11]);
}
result.m[12] = m[0] * static_cast<T>(a.m[12])
+ m[4] * static_cast<T>(a.m[13])
+ m[8] * static_cast<T>(a.m[14])
+ m[12] * static_cast<T>(a.m[15]);
result.m[13] = m[1] * static_cast<T>(a.m[12])
+ m[5] * static_cast<T>(a.m[13])
+ m[9] * static_cast<T>(a.m[14])
+ m[13] * static_cast<T>(a.m[15]);
result.m[14] = m[2] * static_cast<T>(a.m[12])
+ m[6] * static_cast<T>(a.m[13])
+ m[10] * static_cast<T>(a.m[14])
+ m[14] * static_cast<T>(a.m[15]);
inline Matrix4x4Template<T> transposed()
{
Matrix4x4Template<T> a;
a.m[0] = m[0];
a.m[4] = m[1];
a.m[8] = m[2];
a.m[12] = m[3];
a.m[1] = m[4];
a.m[5] = m[5];
a.m[9] = m[6];
a.m[13] = m[7];
a.m[2] = m[8];
a.m[6] = m[9];
a.m[10] = m[10];
a.m[14] = m[11];
a.m[3] = m[12];
a.m[7] = m[13];
a.m[11] = m[14];
a.m[15] = m[15];
return a;
}
template<class S> inline Matrix4x4Template<T> operator *(
const Matrix4x4Template<S> &a)
{
Matrix4x4Template<T> result;
result.m[15] = m[3] * static_cast<T>(a.m[12])
+ m[7] * static_cast<T>(a.m[13])
+ m[11] * static_cast<T>(a.m[14])
+ m[15] * static_cast<T>(a.m[15]);
return result;
}
/**
* matrix multiplication
*/
/*
template <class S>
inline Matrix4x4Template<T> operator *= ( const Matrix4x4Template<S> &a )
{
Matrix4x4Template<T> result;
result.m[0] = m[0] * static_cast<T>(a.m[0])
+ m[4] * static_cast<T>(a.m[1])
+ m[8] * static_cast<T>(a.m[2]);
result.m[0] = m[0] * static_cast<T>(a.m[0]) + m[4]
* static_cast<T>(a.m[1]) + m[8] * static_cast<T>(a.m[2])
+ m[12] * static_cast<T>(a.m[3]);
result.m[1] = m[1] * static_cast<T>(a.m[0])
+ m[5] * static_cast<T>(a.m[1])
+ m[9] * static_cast<T>(a.m[2]);
result.m[1] = m[1] * static_cast<T>(a.m[0]) + m[5]
* static_cast<T>(a.m[1]) + m[9] * static_cast<T>(a.m[2])
+ m[13] * static_cast<T>(a.m[3]);
result.m[2] = m[2] * static_cast<T>(a.m[0])
+ m[6] * static_cast<T>(a.m[1])
+ m[10] * static_cast<T>(a.m[2]);
result.m[2] = m[2] * static_cast<T>(a.m[0]) + m[6]
* static_cast<T>(a.m[1]) + m[10] * static_cast<T>(a.m[2])
+ m[14] * static_cast<T>(a.m[3]);
result.m[3] = m[3] * static_cast<T>(a.m[0])
+ m[7] * static_cast<T>(a.m[1])
+ m[11] * static_cast<T>(a.m[2]);
result.m[3] = m[3] * static_cast<T>(a.m[0]) + m[7]
* static_cast<T>(a.m[1]) + m[11] * static_cast<T>(a.m[2])
+ m[15] * static_cast<T>(a.m[3]);
result.m[4] = m[0] * static_cast<T>(a.m[4])
+ m[4] * static_cast<T>(a.m[5])
+ m[8] * static_cast<T>(a.m[6]);
result.m[4] = m[0] * static_cast<T>(a.m[4]) + m[4]
* static_cast<T>(a.m[5]) + m[8] * static_cast<T>(a.m[6])
+ m[12] * static_cast<T>(a.m[7]);
result.m[5] = m[1] * static_cast<T>(a.m[4])
+ m[5] * static_cast<T>(a.m[5])
+ m[9] * static_cast<T>(a.m[6]);
result.m[5] = m[1] * static_cast<T>(a.m[4]) + m[5]
* static_cast<T>(a.m[5]) + m[9] * static_cast<T>(a.m[6])
+ m[13] * static_cast<T>(a.m[7]);
result.m[6] = m[2] * static_cast<T>(a.m[4])
+ m[6] * static_cast<T>(a.m[5])
+ m[10] * static_cast<T>(a.m[6]);
result.m[6] = m[2] * static_cast<T>(a.m[4]) + m[6]
* static_cast<T>(a.m[5]) + m[10] * static_cast<T>(a.m[6])
+ m[14] * static_cast<T>(a.m[7]);
result.m[7] = m[3] * static_cast<T>(a.m[4])
+ m[7] * static_cast<T>(a.m[5])
+ m[11] * static_cast<T>(a.m[6]);
result.m[7] = m[3] * static_cast<T>(a.m[4]) + m[7]
* static_cast<T>(a.m[5]) + m[11] * static_cast<T>(a.m[6])
+ m[15] * static_cast<T>(a.m[7]);
result.m[8] = m[0] * static_cast<T>(a.m[8])
+ m[4] * static_cast<T>(a.m[9])
+ m[8] * static_cast<T>(a.m[10]);
result.m[8] = m[0] * static_cast<T>(a.m[8]) + m[4]
* static_cast<T>(a.m[9]) + m[8] * static_cast<T>(a.m[10])
+ m[12] * static_cast<T>(a.m[11]);
result.m[9] = m[1] * static_cast<T>(a.m[8])
+ m[5] * static_cast<T>(a.m[9])
+ m[9] * static_cast<T>(a.m[10]);
result.m[9] = m[1] * static_cast<T>(a.m[8]) + m[5]
* static_cast<T>(a.m[9]) + m[9] * static_cast<T>(a.m[10])
+ m[13] * static_cast<T>(a.m[11]);
result.m[10] = m[2] * static_cast<T>(a.m[8])
+ m[6] * static_cast<T>(a.m[9])
+ m[10] * static_cast<T>(a.m[10]);
result.m[10] = m[2] * static_cast<T>(a.m[8]) + m[6]
* static_cast<T>(a.m[9]) + m[10] * static_cast<T>(a.m[10])
+ m[14] * static_cast<T>(a.m[11]);
result.m[11] = m[3] * static_cast<T>(a.m[8])
+ m[7] * static_cast<T>(a.m[9])
+ m[11] * static_cast<T>(a.m[10]);
result.m[11] = m[3] * static_cast<T>(a.m[8]) + m[7]
* static_cast<T>(a.m[9]) + m[11] * static_cast<T>(a.m[10])
+ m[15] * static_cast<T>(a.m[11]);
result.m[12] = m[0] * static_cast<T>(a.m[12])
+ m[4] * static_cast<T>(a.m[13])
+ m[8] * static_cast<T>(a.m[14]);
result.m[12] = m[0] * static_cast<T>(a.m[12]) + m[4]
* static_cast<T>(a.m[13]) + m[8] * static_cast<T>(a.m[14])
+ m[12] * static_cast<T>(a.m[15]);
result.m[13] = m[1] * static_cast<T>(a.m[12])
+ m[5] * static_cast<T>(a.m[13])
+ m[9] * static_cast<T>(a.m[14]);
result.m[13] = m[1] * static_cast<T>(a.m[12]) + m[5]
* static_cast<T>(a.m[13]) + m[9] * static_cast<T>(a.m[14])
+ m[13] * static_cast<T>(a.m[15]);
result.m[14] = m[2] * static_cast<T>(a.m[12])
+ m[6] * static_cast<T>(a.m[13])
+ m[10] * static_cast<T>(a.m[14]);
result.m[14] = m[2] * static_cast<T>(a.m[12]) + m[6]
* static_cast<T>(a.m[13]) + m[10] * static_cast<T>(a.m[14])
+ m[14] * static_cast<T>(a.m[15]);
result.m[15] = m[3] * static_cast<T>(a.m[12])
+ m[7] * static_cast<T>(a.m[13])
+ m[11] * static_cast<T>(a.m[14]);
result.m[15] = m[3] * static_cast<T>(a.m[12]) + m[7]
* static_cast<T>(a.m[13]) + m[11] * static_cast<T>(a.m[14])
+ m[15] * static_cast<T>(a.m[15]);
m = result.m;
return *this;
}
*/
/**
* matrix vector multiplication
*/
Vector3Template<T> operator * ( const Vector3Template<T> &a )
{
Vector3Template<T> result;
result.x = m[0] * a.x + m[4] * a.y + m[8] * a.z + m[12];
result.y = m[1] * a.x + m[5] * a.y + m[9] * a.z + m[13];
result.z = m[2] * a.x + m[6] * a.y + m[11] * a.z + m[14];
return result;
}
T *data()
{
return &m[0];
}
};
typedef Matrix4x4Template<float> Matrix4x4Float;
typedef Matrix4x4Template<double> Matrix4x4Double;
typedef Matrix4x4Template<Scalar> Matrix4x4;
return result;
}
Vector3Template<T> operator *(const Vector3Template<T> &a)
{
Vector3Template<T> result;
result.x = m[0] * a.x + m[4] * a.y + m[8] * a.z + m[12];
result.y = m[1] * a.x + m[5] * a.y + m[9] * a.z + m[13];
result.z = m[2] * a.x + m[6] * a.y + m[11] * a.z + m[14];
return result;
}
T *data()
{
return &m[0];
}
};
typedef Matrix4x4Template<float> Matrix4x4Float;
typedef Matrix4x4Template<double> Matrix4x4Double;
typedef Matrix4x4Template<Scalar> Matrix4x4;
} // namespace bc
#endif // BLUECORE_MATRIX_H

+ 225
- 353
engine/Math/Quaternion.h View File

@@ -5,362 +5,234 @@
namespace BlueCore
{
template <class T>
class QuaternionTemplate
template<class T> class QuaternionTemplate
{
public:
T w, x, y, z;
inline QuaternionTemplate()
{
w = static_cast<T>(1.0);
x = static_cast<T>(0.0);
y = static_cast<T>(0.0);
z = static_cast<T>(0.0);
}
template<class S> inline QuaternionTemplate(S w, S x, S y, S z)
{
this->w = static_cast<T>(w);
this->x = static_cast<T>(x);
this->y = static_cast<T>(y);
this->z = static_cast<T>(z);
}
template<class S> inline QuaternionTemplate(Vector3Template<S> axis, S angle)
{
T half_angle = static_cast<T>(angle)/static_cast<T>(2.0);
T sin_half_angle = static_cast<T>(sin(half_angle) );
w = static_cast<T>(cos(half_angle) );
x = sin_half_angle * static_cast<T>(axis.x);
y = sin_half_angle * static_cast<T>(axis.y);
z = sin_half_angle * static_cast<T>(axis.z);
}
template<class S> inline QuaternionTemplate(S h, S a, S b)
{
T c1 = static_cast<T>(cos(h / 2.0) );
T c2 = static_cast<T>(cos(a / 2.0) );
T c3 = static_cast<T>(cos(b / 2.0) );
T s1 = static_cast<T>(sin(h / 2.0) );
T s2 = static_cast<T>(sin(a / 2.0) );
T s3 = static_cast<T>(sin(b / 2.0) );
w = c1 * c2 * c3 - s1 * s2 * s3;
x = s1 * s2 * c3 + c1 * c2 * s3;
y = s1 * c2 * c3 + c1 * s2 * s3;
z = c1 * s2 * c3 - s1 * c2 * s3;
}
inline void identity()
{
w = static_cast<T>(1.0);
x = static_cast<T>(0.0);
y = static_cast<T>(0.0);
z = static_cast<T>(0.0);
}
template<class S> inline QuaternionTemplate<T> operator +(
const QuaternionTemplate<S> &a) const
{
return QuaternionTemplate<T>(w + static_cast<T>(a.w), x
+ static_cast<T>(a.x), y + static_cast<T>(a.y), z
+ static_cast<T>(a.z) );
}
template<class S> inline QuaternionTemplate<T> &operator +=(
const QuaternionTemplate<S> &a)
{
w += static_cast<T>(a.w);
x += static_cast<T>(a.x);
y += static_cast<T>(a.y);
z += static_cast<T>(a.z);
return *this;
}
template<class S> inline QuaternionTemplate<T> operator -(
const QuaternionTemplate<S> &a) const
{
return QuaternionTemplate<T>(w - static_cast<T>(a.w), x
- static_cast<T>(a.x), y - static_cast<T>(a.y), z
- static_cast<T>(a.z) );
}
template<class S> inline QuaternionTemplate<T> operator *(
const QuaternionTemplate<S> &a) const
{
return QuaternionTemplate<T>(w * static_cast<T>(a.w) - x
* static_cast<T>(a.x) - y * static_cast<T>(a.y) - z
* static_cast<T>(a.z), w * static_cast<T>(a.x) + x
* static_cast<T>(a.w) + y * static_cast<T>(a.z) - z
* static_cast<T>(a.y), w * static_cast<T>(a.y) - x
* static_cast<T>(a.z) + y * static_cast<T>(a.w) + z
* static_cast<T>(a.x), w * static_cast<T>(a.z) + x
* static_cast<T>(a.y) - y * static_cast<T>(a.x) + z
* static_cast<T>(a.w) );
}
template<class S> inline QuaternionTemplate<T> &operator *=(
const QuaternionTemplate<S> &a)
{
w = w * static_cast<T>(a.w) - x * static_cast<T>(a.x) - y
* static_cast<T>(a.y) - z * static_cast<T>(a.z);
x = w * static_cast<T>(a.x) + x * static_cast<T>(a.w) + y
* static_cast<T>(a.z) - z * static_cast<T>(a.y);
y = w * static_cast<T>(a.y) - x * static_cast<T>(a.z) + y
* static_cast<T>(a.w) + z * static_cast<T>(a.x);
z = w * static_cast<T>(a.z) + x * static_cast<T>(a.y) - y
* static_cast<T>(a.x) + z * static_cast<T>(a.w);
return *this;
}
template<class S> inline QuaternionTemplate<T> &operator -=(
const QuaternionTemplate<S> &a)
{
w -= static_cast<T>(a.w);
x -= static_cast<T>(a.x);
y -= static_cast<T>(a.y);
z -= static_cast<T>(a.z);
return *this;
}
template<class S> inline QuaternionTemplate<T> &operator =(
const QuaternionTemplate<S> &a)
{
w = static_cast<T>(a.w);
x = static_cast<T>(a.x);
y = static_cast<T>(a.y);
z = static_cast<T>(a.z);
return *this;
}
inline QuaternionTemplate<T> unit() const
{
T d = 1/sqrt(w*w + x*x + y*y + z*z);
return QuaternionTemplate<T>(w * d, x * d, y * d, z * d);
}
inline QuaternionTemplate<T> inversed() const
{
return QuaternionTemplate<T>(w, -x, -y, -z);
}
inline void inverse()
{
x = -x;
y = -y;
z = -z;
}
inline QuaternionTemplate<T> &normalize()
{
public:
T w, x, y, z;
/**
* constructor
*/
inline QuaternionTemplate()
{
w = static_cast<T>(1.0);
x = static_cast<T>(0.0);
y = static_cast<T>(0.0);
z = static_cast<T>(0.0);
}
/**
* contructor
*/
template <class S>
inline QuaternionTemplate( S w, S x, S y, S z )
{
this->w = static_cast<T>(w);
this->x = static_cast<T>(x);
this->y = static_cast<T>(y);
this->z = static_cast<T>(z);
}
/**
* contructor
*/
template <class S>
inline QuaternionTemplate( Vector3Template<S> axis, S angle )
{
T half_angle = static_cast<T>(angle)/static_cast<T>(2.0);
T sin_half_angle = static_cast<T>( sin( half_angle ) );
w = static_cast<T>( cos( half_angle ) );
x = sin_half_angle * static_cast<T>(axis.x);
y = sin_half_angle * static_cast<T>(axis.y);
z = sin_half_angle * static_cast<T>(axis.z);
}
/**
* contructor
*/
template <class S>
inline QuaternionTemplate( S h, S a, S b )
{
T c1 = static_cast<T>( cos(h / 2.0) );
T c2 = static_cast<T>( cos(a / 2.0) );
T c3 = static_cast<T>( cos(b / 2.0) );
T s1 = static_cast<T>( sin(h / 2.0) );
T s2 = static_cast<T>( sin(a / 2.0) );
T s3 = static_cast<T>( sin(b / 2.0) );
w = c1 * c2 * c3 - s1 * s2 * s3;
x = s1 * s2 * c3 + c1 * c2 * s3;
y = s1 * c2 * c3 + c1 * s2 * s3;
z = c1 * s2 * c3 - s1 * c2 * s3;
}
/**
* identity
*/
inline void identity()
{
w = static_cast<T>(1.0);