/* --------------------------------- VECTOR IMPLEMENTATION -------------------------------//
//----------------------------------------------------------------------------------------*/
const CVector& CVector::operator = (const CVector& V)
{
x = V.x;
y = V.y;
z = V.z;
return *this;
}
const CVector& CVector::operator = (const float * d)
{
x = d[0];
y = d[1];
z = d[2];
return *this;
}
void CVector::Transform(CMatrix *m)
{
double vector[4];
const float *matrix = m->m_matrix;
vector[0] = m_pos[0]*matrix[0]+m_pos[1]*matrix[4]+m_pos[2]*matrix[8]+matrix[12];
vector[1] = m_pos[0]*matrix[1]+m_pos[1]*matrix[5]+m_pos[2]*matrix[9]+matrix[13];
vector[2] = m_pos[0]*matrix[2]+m_pos[1]*matrix[6]+m_pos[2]*matrix[10]+matrix[14];
vector[3] = m_pos[0]*matrix[3]+m_pos[1]*matrix[7]+m_pos[2]*matrix[11]+matrix[15];
m_pos[0] = ( float )( vector[0] );
m_pos[1] = ( float )( vector[1] );
m_pos[2] = ( float )( vector[2] );
m_pos[3] = ( float )( vector[3] );
}
void CVector::Transform3(CMatrix *m)
{
double vector[3];
const float *matrix = m->m_matrix;
vector[0] = m_pos[0]*matrix[0]+m_pos[1]*matrix[4]+m_pos[2]*matrix[8];
vector[1] = m_pos[0]*matrix[1]+m_pos[1]*matrix[5]+m_pos[2]*matrix[9];
vector[2] = m_pos[0]*matrix[2]+m_pos[1]*matrix[6]+m_pos[2]*matrix[10];
m_pos[0] = ( float )( vector[0] );
m_pos[1] = ( float )( vector[1] );
m_pos[2] = ( float )( vector[2] );
m_pos[3] = 1;
}
// Add & Substract, Positive & Negative
const CVector CVector::operator + (const CVector& Vector) const
{ return CVector(x + Vector.x, y + Vector.y, z + Vector.z);
}
const CVector CVector::operator + () const
{ return CVector(*this);
}
const CVector& CVector::operator += (const CVector& Vector)
{ x += Vector.x;
y += Vector.y;
z += Vector.z;
return *this;
}
// minus vector
const CVector CVector::operator - (const CVector& Vector) const
{ return CVector(x - Vector.x, y - Vector.y, z - Vector.z);
}
const CVector CVector::operator - () const
{ return CVector(-x, -y, -z);
}
const CVector &CVector::operator -= (const CVector& Vector)
{ x -= Vector.x;
y -= Vector.y;
z -= Vector.z;
return *this;
}
// Multiply & Divide
const CVector CVector::operator * (const CVector& Vector) const
{ return CVector(x * Vector.x, y * Vector.y, z * Vector.z);
}
const CVector &CVector::operator *= (const CVector& Vector)
{ x *= Vector.x;
y *= Vector.y;
z *= Vector.z;
return *this;
}
const CVector CVector::operator * (const float d) const
{ return CVector(x * d, y * d, z * d);
}
const CVector &CVector::operator *= (const float d)
{ x *= d;
y *= d;
z *= d;
return *this;
}
const CVector CVector::operator / (const CVector& Vector) const
{ return CVector(x / Vector.x, y / Vector.y, z / Vector.z);
}
const CVector &CVector::operator /= (const CVector& Vector)
{ x /= Vector.x;
y /= Vector.y;
z /= Vector.z;
return *this;
}
const CVector CVector::operator / (const float d) const
{ const float _d = 1.0f / d;
return CVector(x * _d, y * _d, z * _d);
}
const CVector &CVector::operator /= (const float d)
{ const float _d = 1.0f / d;
x *= _d;
y *= _d;
z *= _d;
return *this;
}
// Dot Product
const float CVector::Dot(const CVector& Vector) const
{ return x*Vector.x + y*Vector.y + z*Vector.z;
}
// Cross Product
const CVector CVector::Cross(const CVector& Vector) const
{ return CVector(
y * Vector.z - Vector.y * z,
z * Vector.x - Vector.z * x,
x * Vector.y - Vector.x * y);
}
const bool CVector::operator > (const CVector& v)
{
return (x>v.x && y>v.y && z>v.z);
}
const bool CVector::operator < (const CVector& v)
{
return (x<v.x && y<v.y && z<v.z);
}
const float CVector::Magnitude() const
{ return sqrtf(x*x + y*y + z*z);
}
// Set length (Normalize if 1) or Magnitude of vector
void CVector::Normalize()
{
float magnitude=this->Magnitude();
*this/=magnitude;
}
const void CVector::SetNormal(CVector vTriangle0, CVector vTriangle1, CVector vTriangle2 )
{
*this = CVector((vTriangle2-vTriangle0)).Cross(vTriangle1-vTriangle0); // Cross Product
this->Normalize(); // Use our function we created to normalize the normal (Makes it a length of one)
}
// The angle between two vectors in radians
const float CVector::Angle(const CVector& Normal) const
{ return acosf((*this).Dot(Normal));
}
// Reflect in Normal Vector
const CVector CVector::Reflection(const CVector& PlaneNormal) const
{ return (*this - PlaneNormal * 2.0 * ((*this).Dot(PlaneNormal))) * (*this).Magnitude();
}
// Rotate dAngle Degrees (radians) Around Normal
const CVector CVector::Rotate(const float dAngle, const CVector& Normal) const
{ const float dCos = cosf(dAngle);
const float dSin = sinf(dAngle);
return CVector(
*this * dCos +
((Normal * *this) * (1.0f - dCos)) * Normal +
((*this).Dot(Normal)) * dSin);
}
/* -------------------------------END VECTOR IMPLEMENTATION ------------------------------//
//----------------------------------------------------------------------------------------*/
/* --------------------------------- MATRIX IMPLEMENTATION -------------------------------//
//----------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------
// MATRIX MULTIPLICATION OPERATORS
//---------------------------------------------------------------------------
void CMatrix::Multiply (CMatrix *matrix)
{
float newMatrix[16];
const float *m1 = m_matrix, *m2 = matrix->m_matrix;
newMatrix[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2];
newMatrix[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2];
newMatrix[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2];
newMatrix[3] = 0;
newMatrix[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6];
newMatrix[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6];
newMatrix[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6];
newMatrix[7] = 0;
newMatrix[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10];
newMatrix[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10];
newMatrix[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10];
newMatrix[11] = 0;
newMatrix[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12];
newMatrix[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13];
newMatrix[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14];
newMatrix[15] = 1;
for (int i=0; i<16; i++)
this->m_matrix[i] = newMatrix[i];
}
void CMatrix::SetTranslation(CVector pos)
{
m_matrix[12] = pos.x;
m_matrix[13] = pos.y;
m_matrix[14] = pos.z;
m_pos = pos;
}
void CMatrix::SetInvTranslation(CVector pos)
{
m_matrix[12] = -pos.x;
m_matrix[13] = -pos.y;
m_matrix[14] = -pos.z;
m_pos = pos;
}
void CMatrix::RotateDegrees(double dAngleX, double dAngleY, double dAngleZ)
{
// 1 radian = 180 degrees/PI;
float vec[3] = {0,0,0};
vec[0] = ( float )( dAngleX*PI/180 );
vec[1] = ( float )( dAngleY*PI/180 );
vec[2] = ( float )( dAngleZ*PI/180 );
RotateRadians( vec[0], vec[1], vec[2] );
}
void CMatrix::RotateInvDegrees(double dAngleX, double dAngleY, double dAngleZ)
{
float vec[3];
vec[0] = ( float )( dAngleX*PI/180 );
vec[1] = ( float )( dAngleY*PI/180 );
vec[2] = ( float )( dAngleZ*PI/180 );
RotateInvRadians( vec[0], vec[1], vec[2] );
}
void CMatrix::RotateRadians(double dAngleX, double dAngleY, double dAngleZ)
{
m_rot = CVector(dAngleX*180/PI, dAngleY*180/PI, dAngleZ*180/PI);
double cr = FastCos1( dAngleX );
double sr = FastSin1( dAngleX );
double cp = FastCos1( dAngleY );
double sp = FastSin1( dAngleY );
double cy = FastCos1( dAngleZ );
double sy = FastSin1( dAngleZ );
m_matrix[0] = ( float )( cp*cy );
m_matrix[1] = ( float )( cp*sy );
m_matrix[2] = ( float )( -sp );
double srsp = sr*sp;
double crsp = cr*sp;
m_matrix[4] = ( float )( srsp*cy-cr*sy );
m_matrix[5] = ( float )( srsp*sy+cr*cy );
m_matrix[6] = ( float )( sr*cp );
m_matrix[8] = ( float )( crsp*cy+sr*sy );
m_matrix[9] = ( float )( crsp*sy-sr*cy );
m_matrix[10] = ( float )( cr*cp );
}
void CMatrix::RotateInvRadians(double dAngleX, double dAngleY, double dAngleZ)
{
m_rot = CVector(dAngleX*180/PI, dAngleY*180/PI, dAngleZ*180/PI);
double cr = cos( dAngleX );
double sr = sin( dAngleX );
double cp = cos( dAngleY );
double sp = sin( dAngleY );
double cy = cos( dAngleZ );
double sy = sin( dAngleZ );
// matrix0 = cos(y)*cos(z)
//y = inv_cos(matrix0/cos(z))
m_matrix[0] = ( float )( cp*cy );
m_matrix[4] = ( float )( cp*sy );
m_matrix[8] = ( float )( -sp );
double srsp = sr*sp;
double crsp = cr*sp;
m_matrix[1] = ( float )( srsp*cy-cr*sy );
m_matrix[5] = ( float )( srsp*sy+cr*cy );
m_matrix[9] = ( float )( sr*cp );
m_matrix[2] = ( float )( crsp*cy+sr*sy );
m_matrix[6] = ( float )( crsp*sy-sr*cy );
m_matrix[10] = ( float )( cr*cp );
}
//---------------------------------------------------------------------------
/* -------------------------------END MATRIX IMPLEMENTATION ------------------------------//
//----------------------------------------------------------------------------------------*/
bool SaveMatrix(CMatrix *mat, char *filename, FILE *f)
{
if(mat == NULL)
return false;
FILE *file = NULL;
if(f == NULL)
{
if(filename == NULL)
return false;
else
file = fopen(filename,"w+t");
}
else
file = f;
if(file !=NULL)
{
fprintf(file, "%f %f %f %f %f %f %f %f %f\n",
mat->m_pos.x, mat->m_pos.y, mat->m_pos.z,
mat->m_rot.x, mat->m_rot.y, mat->m_rot.z,
mat->m_scale.x, mat->m_scale.y, mat->m_scale.z);
}
if(f == NULL)
fclose(file);
return true;
}
bool LoadMatrix(CMatrix *mat, char *filename, FILE *f)
{
if(mat == NULL)
return false;
FILE *file = NULL;
if(f == NULL)
{
if(filename == NULL)
return false;
else
file = fopen(filename,"r+t");
}
else
file = f;
if(file !=NULL)
{
fscanf(file, "%f %f %f %f %f %f %f %f %f\n",
&mat->m_pos.x, &mat->m_pos.y, &mat->m_pos.z,
&mat->m_rot.x, &mat->m_rot.y, &mat->m_rot.z,
&mat->m_scale.x, &mat->m_scale.y, &mat->m_scale.z);
mat->SetTranslation(mat->m_pos);
mat->RotateDegrees(mat->m_rot.x, mat->m_rot.y, mat->m_rot.z);
mat->Scale(mat->m_scale.x, mat->m_scale.y, mat->m_scale.z);
//fgetc(file); // SKIP NEWLINE
}
if(f == NULL)
fclose(file);
return true;
}