I wrote a generic matrix class for all of my 3d objects, but the translations seem to be really off.
Here is my class:
class GenericMatrix
{
public:
GenericMatrix();
virtual void Identity();
virtual void Scale( float x, float y, float z );
virtual void Scale( const DirectX::XMFLOAT3& s );
virtual DirectX::XMFLOAT3 Scaling( void );
virtual void Translate( float x, float y, float z );
virtual void Translate( const DirectX::XMFLOAT3& t );
virtual DirectX::XMFLOAT3 Translations( void );
virtual void Rotate( float x, float y, float z );
virtual void Rotate( const DirectX::XMFLOAT3& r );
virtual DirectX::XMVECTOR Rotations( void );
virtual DirectX::XMFLOAT3 RotationsPYR( void );
virtual DirectX::XMMATRIX Matrix( bool process = true );
virtual operator DirectX::XMMATRIX()
{
return this->Matrix();
}
virtual void UpdateMatrix( void );
DirectX::XMMATRIX matrix;
DirectX::XMFLOAT3 scale;
DirectX::XMFLOAT3 translation;
DirectX::XMVECTOR rotation;
bool matrixNeedsUpdate;
protected:
float yaw, pitch, roll;
};
And the source:
#include "pch.h"
#include "GenericMatrix.h"
GenericMatrix::GenericMatrix()
: matrixNeedsUpdate( true )
{
this->Identity();
this->pitch = 90.0f;
this->yaw = 0.0f;
this->roll = 0.0f;
}
void GenericMatrix::Identity()
{
this->scale = DirectX::XMFLOAT3( 1.0f, 1.0f, 1.0f );
this->translation = DirectX::XMFLOAT3( 0.0f, 0.0f, 0.0f );
this->rotation = DirectX::XMQuaternionIdentity();
this->pitch = 90.0f;
this->yaw = 0.0f;
this->roll = 0.0f;
matrixNeedsUpdate = true;
}
void GenericMatrix::Scale( float x, float y, float z )
{
this->scale.x += x;
this->scale.y += y;
this->scale.z += z;
this->matrixNeedsUpdate = true;
}
void GenericMatrix::Scale( const DirectX::XMFLOAT3& s )
{ Scale( s.x, s.y, s.z ); }
DirectX::XMFLOAT3 GenericMatrix::Scaling( void )
{ return this->scale; }
void GenericMatrix::Translate( float x, float y, float z )
{
this->translation.x += x;
this->translation.y += y;
this->translation.z += z;
this->matrixNeedsUpdate = true;
}
void GenericMatrix::Translate( const DirectX::XMFLOAT3& t )
{ Translate( t.x, t.y, t.z ); }
DirectX::XMFLOAT3 GenericMatrix::Translations( void )
{ return this->translation; }
void GenericMatrix::Rotate( float x, float y, float z )
{
pitch = x;
yaw = y;
roll = z;
this->rotation = DirectX::XMQuaternionRotationRollPitchYaw( pitch, yaw, roll );
this->matrixNeedsUpdate = true;
}
void GenericMatrix::Rotate( const DirectX::XMFLOAT3& r )
{ Rotate( r.x, r.y, r.z ); }
DirectX::XMVECTOR GenericMatrix::Rotations( void )
{ return this->rotation; }
DirectX::XMFLOAT3 GenericMatrix::RotationsPYR( void )
{
return DirectX::XMFLOAT3( pitch, yaw, roll );
}
DirectX::XMMATRIX GenericMatrix::Matrix( bool process )
{
if ( process && this->matrixNeedsUpdate )
{
UpdateMatrix();
this->matrixNeedsUpdate = false;
}
return this->matrix;
}
void GenericMatrix::UpdateMatrix( void )
{
DirectX::XMVECTOR scaleVec, translateVec;
scaleVec = DirectX::XMLoadFloat3( &this->scale );
translateVec = DirectX::XMLoadFloat3( &this->translation );
this->matrix = DirectX::XMMatrixScalingFromVector( scaleVec ) * DirectX::XMMatrixRotationQuaternion( this->rotation ) * DirectX::XMMatrixTranslationFromVector( translateVec );
}
When I use this as a model matrix, after doing Identity(), then Translate( 0.0f, 0.0f, 5.0f ), my model becomes only visible when I position my camera at [0,0,5], and even then, it’s just a flicker. The last bit of 3d programming I have done was with OpenGL 1.x, so there is a good chance I’m doing something weird with the matrices, but haven’t found anything that would tell me how to do this otherwise. If there is more information anyone needs, just ask.
update: Some more details – if I set the matrix to Identity() and leave it, i can move the camera and see the model without any problem from any position, meanwhile if I move it anywhere, it messes up the visibility.
I discovered the problem after a few tests. It seems I was using a left-handed coordinate system for my camera, but right-handed for my perspective. In between z 0.9 to -0.9, both left and right handed systems were able to agree that the model should be visible, but when I moved them out of that space, neither matrix could agree on what was visible unless my camera was exactly at the same coordinates.
Moral of the story – remember to consistently use the same coordinate system throughout your code.