190 lines
4.7 KiB
C
190 lines
4.7 KiB
C
/*
|
|
* PVVMUD a 3D MUD
|
|
* Copyright (C) 1998-1999 Programvareverkstedet (pvv@pvv.org)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
#include "pvvmud.H"
|
|
#include <math.h>
|
|
#include "matrix.H"
|
|
#include "vector.H"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Matrix vector format
|
|
//
|
|
// m = | m0 m4 m8 m12 |
|
|
// | m1 m5 m9 m13 |
|
|
// | m2 m6 m10 m14 |
|
|
// | m3 m7 m11 m15 |
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CMatrix::CMatrix(){
|
|
loadIdentity();
|
|
}
|
|
|
|
CMatrix::CMatrix(const CMatrix & matrix){
|
|
int ii;
|
|
for (ii = 0; ii < 16; ii++) m_matrix[ii] = matrix.m_matrix[ii];
|
|
}
|
|
|
|
CMatrix::CMatrix(double m0, double m4, double m8, double m12,
|
|
double m1, double m5, double m9, double m13,
|
|
double m2, double m6, double m10, double m14,
|
|
double m3, double m7, double m11, double m15)
|
|
{
|
|
m_matrix[0] = m0;
|
|
m_matrix[1] = m1;
|
|
m_matrix[2] = m2;
|
|
m_matrix[3] = m3;
|
|
m_matrix[4] = m4;
|
|
m_matrix[5] = m5;
|
|
m_matrix[6] = m6;
|
|
m_matrix[7] = m7;
|
|
m_matrix[8] = m8;
|
|
m_matrix[9] = m9;
|
|
m_matrix[10] = m10;
|
|
m_matrix[11] = m11;
|
|
m_matrix[12] = m12;
|
|
m_matrix[13] = m13;
|
|
m_matrix[14] = m14;
|
|
m_matrix[15] = m15;
|
|
}
|
|
|
|
CMatrix::CMatrix(CVector & v0, CVector & v1, CVector & v2, CVector & v3){
|
|
m_matrix[0] = v0.getX();
|
|
m_matrix[1] = v0.getY();
|
|
m_matrix[2] = v0.getZ();
|
|
m_matrix[3] = 0.0;
|
|
m_matrix[4] = v1.getX();
|
|
m_matrix[5] = v1.getY();
|
|
m_matrix[6] = v1.getZ();
|
|
m_matrix[7] = 0.0;
|
|
m_matrix[8] = v2.getX();
|
|
m_matrix[9] = v2.getY();
|
|
m_matrix[10] = v2.getZ();
|
|
m_matrix[11] = 0.0;
|
|
m_matrix[12] = v3.getX();
|
|
m_matrix[13] = v3.getY();
|
|
m_matrix[14] = v3.getZ();
|
|
m_matrix[15] = 1.0;
|
|
}
|
|
|
|
double * CMatrix::getVector(){
|
|
return m_matrix;
|
|
}
|
|
|
|
void CMatrix::multiply(const CMatrix & matrix){
|
|
CMatrix Temp(*this);
|
|
int ii,jj,kk;
|
|
for (ii = 0; ii < 4; ii++){
|
|
for (jj = 0; jj < 4; jj ++){
|
|
double sum = 0;
|
|
for (kk = 0; kk < 4; kk++){
|
|
sum += Temp.m_matrix[ii+kk*4]*matrix.m_matrix[jj*4+kk];
|
|
}
|
|
m_matrix[ii+jj*4] = sum;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMatrix::loadIdentity(){
|
|
int i;
|
|
for (i = 0; i < 16; i++){
|
|
if ((i % 5) == 0) m_matrix[i] = 1.0;
|
|
else m_matrix[i] = 0.0;
|
|
}
|
|
//m_matrix[0] = m_matrix[5] = m_matrix[10] = m_matrix[15] = 0;
|
|
}
|
|
|
|
void CMatrix::rotate(const CDirection & direction){
|
|
rotate(direction.getHeading(),0.0,0.0,1.0);
|
|
rotate(direction.getRoll(),0.0,1.0,0.0);
|
|
rotate(direction.getPitch(),1.0,0.0,0.0);
|
|
}
|
|
|
|
void CMatrix::rotate(double angle,double xx,double yy,double zz){
|
|
CMatrix r;
|
|
|
|
double rad_ang = angle*PI/180;
|
|
|
|
double sina = sin(rad_ang);
|
|
double cosa = cos(rad_ang);
|
|
|
|
r.m_matrix[0] = xx*xx + cosa*(1-xx*xx);
|
|
r.m_matrix[1] = xx*yy*(1-cosa) + zz*sina;
|
|
r.m_matrix[2] = zz*xx*(1-cosa) - yy*sina;
|
|
r.m_matrix[3] = 0.0f;
|
|
|
|
r.m_matrix[4] = xx*yy*(1-cosa) - zz*sina;
|
|
r.m_matrix[5] = yy*yy + cosa*(1-yy*yy);
|
|
r.m_matrix[6] = yy*zz*(1-cosa) + xx*sina;
|
|
r.m_matrix[7] = 0.0f;
|
|
|
|
r.m_matrix[8] = zz*xx*(1-cosa) + yy*sina;
|
|
r.m_matrix[9] = yy*zz*(1-cosa) - xx*sina;
|
|
r.m_matrix[10]= zz*zz + cosa*(1-zz*zz);
|
|
r.m_matrix[11]= 0.0f;
|
|
|
|
r.m_matrix[12]= 0.0f;
|
|
r.m_matrix[13]= 0.0f;
|
|
r.m_matrix[14]= 0.0f;
|
|
r.m_matrix[15]= 1.0f;
|
|
|
|
multiply(r);
|
|
}
|
|
|
|
void CMatrix::translate(const CPosition & position){
|
|
CMatrix trans;
|
|
trans.m_matrix[12] = position.getX();
|
|
trans.m_matrix[13] = position.getY();
|
|
trans.m_matrix[14] = position.getZ();
|
|
multiply(trans);
|
|
|
|
}
|
|
void CMatrix::transpose(){
|
|
int ii,jj;
|
|
for (ii = 1; ii < 4; ii++){
|
|
for (jj = 0; jj < ii; jj ++){
|
|
double tmp = m_matrix[ii+jj*4];
|
|
m_matrix[ii+jj*4] = m_matrix[ii*4+jj];
|
|
m_matrix[ii*4+jj] = tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
CMatrix operator*(const CMatrix & m1, const CMatrix & m2){
|
|
CMatrix result(m1);
|
|
result.multiply(m2);
|
|
return result;
|
|
}
|
|
|
|
ostream& operator<<(ostream&s,const CMatrix& matrix) {
|
|
int ii;
|
|
double * m = ((CMatrix)matrix).getVector();
|
|
|
|
s << "[" << m[0];
|
|
|
|
for (ii = 1; ii < 16; ii++){
|
|
s << "," << m[ii];
|
|
}
|
|
|
|
return s << "]";
|
|
}
|
|
|