[eigen] Help with LHS matrices for directx |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: <eigen@xxxxxxxxxxxxxxxxxxx>
- Subject: [eigen] Help with LHS matrices for directx
- From: Shomari Sharpe <shomarijm@xxxxxxxxx>
- Date: Wed, 27 Jun 2018 17:13:54 +0000 (UTC)
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1530119635; bh=LHi1RRTYQnojBCJ4AHEyVRRIoPE3PRzG33sD5IjKTl4=; h=Date:From:Reply-To:To:Subject:References:From:Subject; b=hFIkhOQxeicL6ZZJnSIGULGCcUh/iSJxS90z33GkEb1tBXIj1PitOpnPwKfFLzNKgCeAY8nJ5Fssr4rnsCs0gLIx1mrZlV5CLf1sRDrU6ySDexBuYRCzR8GlErtulVMHoh2rhfR+hkWvGuyUrQvEmYMlix5/b0JQFPFFI0W5kZd34yVRr6DExCKlOFnO6QxducEADBzhA93lpTgnWH7mdv6p/RFV3LWCfnbT9xkk8FU1pmp8UhkX04qoHUnqgeoZXQ6XvGUowSi9c1ERf//lliQWiIVZytVVK4Mc9qQWw2jxq4Q+E4W4ZI1LL+UdtMHtm1JnqWniwI8R5FdSm6IRUg==
Hi,
i've written 2 classes that use Eigen for matrix calculations 1 for column major order (opengl) and 1 for row major order (directx)... OpenGL works as expected but directx seems to be off. How do i get the Orthographic and Perspective matrices working for left hand side, row major ordering. Also i would be nice if you guys included a matrixstack like mine that could work out of the box with directx or opengl.
Thanks for helping,
Shomari
#ifndef GGRAPHICSMATRIXSTACK_H
#define GGRAPHICSMATRIXSTACK_H
#include "GGraphicsDefines.h"
#define MAX_MATRIX_STACKS 16
/* ===============================================================
radians = ( degrees * pi ) / 180;
degrees = ( radians * 180 ) / pi;
column major -----------------------------
rightx upx forwardx positionx X
righty upy forwardy positiony Y
rightz upz forwardz positionz Z
0 0 0 1 W
------------------------------------------
row major (double check)------------------
X Y Z W
rightx righty rightz 0
upx upy upz 0
forwardx forwardy forwardz 0
positionx positiony positionz 1
------------------------------------------
=============================================================== */
class GGraphicsMatrixStack
{
public:
GGraphicsMatrixStack();
GGraphicsMatrixStack(GGraphicsMatrixOrder order);
GGraphicsMatrixOrder GetMatrixOrder() const;
virtual void SetMode(GGraphicsMatrixMode mode);
virtual void Push() = 0;
virtual void Pop() = 0;
virtual void PopAll(GGraphicsMatrixMode mode) = 0;
virtual void LockMode() = 0;
virtual void UnlockMode() = 0;
virtual void LoadIdentity() = 0;
virtual void LoadIdentity(GGraphicsMatrixMode mode) = 0;
virtual void SetTransform(float* trans) = 0;
virtual void SetTransform(GGraphicsMatrixMode mode, float* trans) = 0;
virtual float* GetTransform(GGraphicsMatrixMode mode) = 0;
virtual float* GetTransformModelView() = 0;
virtual float* GetTransformProjectionViewModel() = 0;
virtual void Scale(float x, float y, float z) = 0;
virtual void Translate(float x, float y, float z) = 0;
virtual void Rotate(float angle, float x, float y, float z) = 0;
virtual float* GetTranspose(GGraphicsMatrixMode mode) = 0;
virtual void Reset() = 0;
uint8_t GetMaxStacks() const;
virtual void LookAt(float eyex, float eyey, float eyez, float centerx, float centery, float centerz, float upx, float upy, float upz) = 0;
virtual void Perspective(float fovy, float aspect, float near, float far) = 0;
virtual void Ortho(double left, double right, double bottom, double top, double near, double far) = 0;
virtual ~GGraphicsMatrixStack();
protected:
GGraphicsMatrixOrder m_order;
GGraphicsMatrixMode m_mode;
};
#endif // GGRAPHICSMATRIXSTACK_H
#include "GGraphicsMatrixStack.h"
GGraphicsMatrixStack::GGraphicsMatrixStack() :
m_order(GGraphicsMatrixOrder::ROW_MAJOR),
m_mode(GGraphicsMatrixMode::VIEW)
{
//ctor
} //end function
GGraphicsMatrixStack::GGraphicsMatrixStack(GGraphicsMatrixOrder order) :
m_order(order),
m_mode(GGraphicsMatrixMode::VIEW)
{
//ctor
} //end function
GGraphicsMatrixOrder GGraphicsMatrixStack::GetMatrixOrder() const
{
return m_order;
} //end function
void GGraphicsMatrixStack::SetMode(GGraphicsMatrixMode mode)
{
m_mode = mode;
} //end function
GGraphicsMatrixStack::~GGraphicsMatrixStack()
{
//dtor
} //end function
#ifndef GGRAPHICSMATRIXSTACKEIGEN_H
#define GGRAPHICSMATRIXSTACKEIGEN_H
#include "GGraphicsDefines.h"
#include "GGraphicsMatrixStack.h"
#include <stack>
#include <Eigen/Geometry>
#include <pthread.h>
using namespace Eigen;
//https://eigen.tuxfamily.org/dox/group__TutorialGeometry.html
//https://eigen.tuxfamily.org/dox/group__TopicStlContainers.html
//https://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html
/* =================================== NOTES =========================================== *
* This is a FULL HEADER IMPLEMENTATION since templates and .cpp files don't play nicely *
* ===================================================================================== */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif // M_PI
template <int Order>
class GGraphicsMatrixStackEigen : public GGraphicsMatrixStack
{
public:
GGraphicsMatrixStackEigen();
void SetMode(GGraphicsMatrixMode mode);
void Push();
void Pop();
void PopAll(GGraphicsMatrixMode mode);
void LockMode();
void UnlockMode();
void LoadIdentity();
void LoadIdentity(GGraphicsMatrixMode mode);
void SetTransform(float* trans);
void SetTransform(GGraphicsMatrixMode mode, float* trans);
float* GetTransform(GGraphicsMatrixMode mode);
float* GetTransformModelView();
float* GetTransformProjectionViewModel();
void Scale(float x, float y, float z);
void Translate(float x, float y, float z);
void Rotate(float angle, float x, float y, float z);
float* GetTranspose(GGraphicsMatrixMode mode);
void Reset();
uint8_t GetMaxStacks() const;
void LookAt(float eyex, float eyey, float eyez, float centerx, float centery, float centerz, float upx, float upy, float upz);
void Perspective(float fovy, float aspect, float near, float far);
void Ortho(double left, double right, double bottom, double top, double near, double far);
virtual ~GGraphicsMatrixStackEigen();
EIGEN_MAKE_ALIGNED_OPERATOR_NEW //required to prevent crash when allocating from within renderer class
private:
std::stack<Eigen::Matrix<float, 4, 4, Order, 4, 4> > m_matrixstack[11];
Eigen::Matrix<float, 4, 4, Order, 4, 4> m_current[11];
pthread_mutex_t m_mutex;
};
template <int Order>
GGraphicsMatrixStackEigen<Order>::GGraphicsMatrixStackEigen() :
GGraphicsMatrixStack(static_cast<GGraphicsMatrixOrder>(Order))
{
pthread_mutex_init(&m_mutex, NULL);
Reset();
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::SetMode(GGraphicsMatrixMode mode)
{
if (pthread_mutex_trylock(&m_mutex) == 0)
{
m_mode = mode;
pthread_mutex_unlock(&m_mutex);
}
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::Push() ///OK
{
if (m_matrixstack[static_cast<uint8_t>(m_mode)].size() < MAX_MATRIX_STACKS-1)
m_matrixstack[static_cast<uint8_t>(m_mode)].push(m_current[static_cast<uint8_t>(m_mode)]);
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::Pop() ///OK
{
if (m_matrixstack[static_cast<uint8_t>(m_mode)].size() > 0)
{
m_current[static_cast<uint8_t>(m_mode)] = m_matrixstack[static_cast<uint8_t>(m_mode)].top();
m_matrixstack[static_cast<uint8_t>(m_mode)].pop();
}
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::PopAll(GGraphicsMatrixMode mode) ///OK
{
while (m_matrixstack[static_cast<uint8_t>(mode)].size() > 0)
{
m_current[static_cast<uint8_t>(mode)] = m_matrixstack[static_cast<uint8_t>(mode)].top();
m_matrixstack[static_cast<uint8_t>(mode)].pop();
}
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::LoadIdentity() ///OK
{
m_current[static_cast<uint8_t>(m_mode)].setIdentity();
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::LockMode()
{
pthread_mutex_lock(&m_mutex);
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::UnlockMode()
{
pthread_mutex_unlock(&m_mutex);
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::LoadIdentity(GGraphicsMatrixMode mode) ///OK
{
m_current[static_cast<uint8_t>(mode)].setIdentity();
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::SetTransform(float* trans) ///OK
{
Eigen::Map<Eigen::Matrix<float, 4, 4, Order, 4, 4> > mapped_buffer(trans);
m_current[static_cast<uint8_t>(m_mode)] = mapped_buffer.matrix();
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::SetTransform(GGraphicsMatrixMode mode, float* trans) ///OK
{
Eigen::Map<Eigen::Matrix<float, 4, 4, Order, 4, 4> > mapped_buffer(trans);
m_current[static_cast<uint8_t>(mode)] = mapped_buffer.matrix();
} //end function
template <int Order>
float* GGraphicsMatrixStackEigen<Order>::GetTransform(GGraphicsMatrixMode mode) ///OK
{
return m_current[static_cast<uint8_t>(mode)].data();
} //end function
template <int Order>
float* GGraphicsMatrixStackEigen<Order>::GetTransformModelView()
{
Eigen::Matrix<float, 4, 4, Order, 4, 4> prod =
(m_current[static_cast<uint8_t>(GGraphicsMatrixMode::VIEW)] *
m_current[static_cast<uint8_t>(GGraphicsMatrixMode::MODEL)]);
return prod.data();
} //end function
template <int Order>
float* GGraphicsMatrixStackEigen<Order>::GetTransformProjectionViewModel()
{
Eigen::Matrix<float, 4, 4, Order, 4, 4> prod =
(m_current[static_cast<uint8_t>(GGraphicsMatrixMode::PROJECTION)] *
m_current[static_cast<uint8_t>(GGraphicsMatrixMode::VIEW)] *
m_current[static_cast<uint8_t>(GGraphicsMatrixMode::MODEL)]);
return prod.data();
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::Scale(float x, float y, float z) ///OK
{
Eigen::Transform<float, 3, Eigen::Affine, Order> scale(Eigen::Scaling(x, y, z));
m_current[static_cast<uint8_t>(m_mode)] *= scale.matrix();
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::Translate(float x, float y, float z) ///OK
{
Eigen::Transform<float, 3, Eigen::Affine, Order> trans(Eigen::Translation3f(x, y, z));
m_current[static_cast<uint8_t>(m_mode)] *= trans.matrix();
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::Rotate(float angle, float x, float y, float z) ///OK
{
float radians = ( angle * M_PI ) /180.f;
Eigen::Transform<float, 3, Eigen::Affine, Order> trans(Eigen::AngleAxisf(radians, Eigen::Vector3f(x, y, z)));
m_current[static_cast<uint8_t>(m_mode)] *= trans.matrix();
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::Reset() ///OK
{
for (int i = 0; i < 11; i++)
while(m_matrixstack[i].size())
m_matrixstack[i].pop();
for (int i = 0; i < 11; i++)
m_current[i].setIdentity();
} //end function
template <int Order>
uint8_t GGraphicsMatrixStackEigen<Order>::GetMaxStacks() const ///OK
{
return MAX_MATRIX_STACKS;
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::Ortho(double left, double right, double bottom, double top, double nearval, double farval) ///OK
{
Eigen::Matrix<float, 4, 4, Order, 4, 4>& M = m_current[static_cast<uint8_t>(m_mode)];
//if (Order == 0)
//{
///Column Major Style OK OpenGL
/*column major -----------------------------
rightx upx forwardx positionx X
righty upy forwardy positiony Y
rightz upz forwardz positionz Z
0 0 0 1 W
------------------------------------------ */
M(0,0) = 2.0F / (right-left); //rightx
M(0,1) = 0.0F; //upx
M(0,2) = 0.0F; //forwardx
M(0,3) = -(right+left) / (right-left); //positionx
M(1,0) = 0.0F; //righty
M(1,1) = 2.0F / (top-bottom); //upy
M(1,2) = 0.0F; //forwardy
M(1,3) = -(top+bottom) / (top-bottom); //positiony
M(2,0) = 0.0F; //rightz
M(2,1) = 0.0F; //upz
M(2,2) = -2.0F / (farval-nearval); //forwardz
M(2,3) = -(farval+nearval) / (farval-nearval); //positionz
M(3,0) = 0.0F; //W
M(3,1) = 0.0F; //W
M(3,2) = 0.0F; //W
/*} else
{
///Row Major style
/*row major (double check)------------------
X Y Z W
rightx righty rightz 0
upx upy upz 0
forwardx forwardy forwardz 0
positionx positiony positionz 1
------------------------------------------ */
/*M(0,0) = 2.0f / (right-left); //rightx OK
M(0,1) = 0.0f; //righty OK
M(0,2) = 0.0f; //rightz OK
M(0,3) = 0.0f; //(0) W /// -(right+left) / (right-left);
M(1,0) = 0.0f; //upx
M(1,1) = 2.0f / (top-bottom); //upy
M(1,2) = 0.0f; //upz
M(1,3) = 0.f; //(0) W
M(2,0) = 0.0f; //forwardx
M(2,1) = 0.0F; //forwardy
M(2,2) = -2.0F / (farval-nearval); //forwardz
M(2,3) = 0; //(0) W
M(3,0) = 0.0F; //positionx
M(3,1) = -(top+bottom) / (top-bottom); //positiony OK
M(3,2) = -(farval+nearval) / (farval-nearval); //positionz OK
} */
} //end function
template <int Order>
float* GGraphicsMatrixStackEigen<Order>::GetTranspose(GGraphicsMatrixMode mode) ///OK
{
return m_current[static_cast<uint8_t>(mode)].transpose().data();
} //end function
///------------- ensure these 2 match matrix ordering -----------------------
template <int Order>
void GGraphicsMatrixStackEigen<Order>::LookAt(float eyex, float eyey, float eyez, float centerx, float centery, float centerz, float upx, float upy, float upz)
{
Eigen::Matrix<float, 4, 4, Order, 4, 4> M;
Eigen::Vector3f position(eyex, eyey, eyez);
Eigen::Vector3f target(centerx, centery, centerz);
Eigen::Vector3f up(upx, upy, upz);
Eigen::Matrix3f R;
R.col(2) = (position - target).normalized();
R.col(0) = up.cross(R.col(2)).normalized();
R.col(1) = R.col(2).cross(R.col(0));
M.setIdentity();
M.topLeftCorner(3,3) = R.transpose();
M.topRightCorner(3,1) = -R.transpose() * position;
M(3,3) = 1.0f;
m_current[static_cast<uint8_t>(m_mode)] *= M;
} //end function
template <int Order>
void GGraphicsMatrixStackEigen<Order>::Perspective(float fovy, float aspect, float nearval, float farval)
{
#ifdef MAD_DEBUG
assert(aspect > 0);
assert(farval > nearval);
#else
if (aspect <= 0)
return;
if (farval > nearval)
return;
#endif // MAD_DEBUG
Eigen::Matrix<float, 4, 4, Order, 4, 4>& M = m_current[static_cast<uint8_t>(m_mode)];
M = Matrix4f::Zero();
if (Order == 0)
{
double radians = (fovy * M_PI) / 180.f;
double tanHalfFovy = tan(radians / 2.0);
//column major
M(0,0) = 1.0 / (aspect * tanHalfFovy); //rightx
M(1,1) = 1.0 / (tanHalfFovy); //upy
M(2,2) = - (farval + nearval) / (farval - nearval); //forwardz
M(3,2) = - 1.0f;
M(2,3) = - (2.0f * farval * nearval) / (farval - nearval); //positionz
} else
{
float w = (float)1/tan(fovy*0.5); // 1/tan(x) == cot(x)
//float h = (float)1/tan(fov_vert*0.5); // 1/tan(x) == cot(x)
float Q = farval/(farval - nearval);
//row major
M(0, 0) = w;
M(1, 1) = w;
M(2, 2) = Q;
M(3, 2) = -Q*nearval;
M(2, 3) = 1;
}
} //end function
///------------- ensure these 2 match matrix ordering -----------------------
template <int Order>
GGraphicsMatrixStackEigen<Order>::~GGraphicsMatrixStackEigen()
{
//dtor
} //end function
#endif // GGRAPHICSMATRIXSTACKEIGEN_H