idx3d_Matrix.java
java · 324 lines · part of Test Java Cube Rendering · raw
// | -----------------------------------------------------------------
// | idx3d III is (c)1999/2000 by Peter Walser
// | -----------------------------------------------------------------
// | idx3d is a 3d engine written in 100% pure Java (1.1 compatible)
// | and provides a fast and flexible API for software 3d rendering
// | on the Java platform.
// |
// | Feel free to use the idx3d API / classes / source code for
// | non-commercial purposes (of course on your own risk).
// | If you intend to use idx3d for commercial purposes, please
// | contact me with an e-mail [proxima@active.ch].
// |
// | Thanx & greetinx go to:
// | * Wilfred L. Guerin, for testing, bug report, and tons
// | of brilliant suggestions
// | * Sandy McArthur, for reverse loops
// | * Dr. Douglas Lyons, for mentioning idx3d1 in his book
// | * Hugo Elias, for maintaining his great page
// | * the comp.graphics.algorithms people,
// | for scientific concerns
// | * Tobias Hill, for inspiration and awakening my
// | interest in java gfx coding
// | * Kai Krause, for inspiration and hope
// | * Incarom & Parisienne, for keeping me awake during the
// | long coding nights
// | * Doris Langhard, for being the sweetest girl on earth
// | * Etnica, Infinity Project, X-Dream and "Space Night"@BR3
// | for great sound while coding
// | and all coderz & scenerz out there (keep up the good work, ppl :)
// |
// | Peter Walser
// | proxima@active.ch
// | http://www2.active.ch/~proxima
// | "On the eigth day, God started debugging"
// | -----------------------------------------------------------------
public class idx3d_Matrix
// defines a 3d matrix
{
// M A T R I X D A T A
public float m00=1, m01=0, m02=0, m03=0;
public float m10=0, m11=1, m12=0, m13=0;
public float m20=0, m21=0, m22=1, m23=0;
public float m30=0, m31=0, m32=0, m33=1;
// C O N S T R U C T O R S
public idx3d_Matrix()
{
}
public idx3d_Matrix(idx3d_Vector right, idx3d_Vector up, idx3d_Vector forward)
{
m00=right.x;
m10=right.y;
m20=right.z;
m01=up.x;
m11=up.y;
m21=up.z;
m02=forward.x;
m12=forward.y;
m22=forward.z;
}
public void importFromArray(float[][] data)
{
if (data.length<4) return;
for (int i=0;i<4;i++) if (data[i].length<4) return;
m00=data[0][0]; m01=data[0][1]; m02=data[0][2]; m03=data[0][3];
m10=data[1][0]; m11=data[1][1]; m12=data[1][2]; m13=data[1][3];
m20=data[2][0]; m21=data[2][1]; m22=data[2][2]; m23=data[2][3];
m30=data[3][0]; m31=data[3][1]; m32=data[3][2]; m33=data[3][3];
}
public float[][] exportToArray()
{
float data[][]=new float[4][4];
data[0][0]=m00; data[0][1]=m01; data[0][2]=m02; data[0][3]=m03;
data[1][0]=m10; data[1][1]=m11; data[1][2]=m12; data[1][3]=m13;
data[2][0]=m20; data[2][1]=m21; data[2][2]=m22; data[2][3]=m23;
data[3][0]=m30; data[3][1]=m31; data[3][2]=m32; data[3][3]=m33;
return data;
}
// F A C T O R Y M E T H O D S
public static idx3d_Matrix shiftMatrix(float dx, float dy, float dz)
// matrix for shifting
{
idx3d_Matrix m=new idx3d_Matrix();
m.m03=dx;
m.m13=dy;
m.m23=dz;
return m;
}
public static idx3d_Matrix scaleMatrix(float dx, float dy, float dz)
// matrix for scaling
{
idx3d_Matrix m=new idx3d_Matrix();
m.m00=dx;
m.m11=dy;
m.m22=dz;
return m;
}
public static idx3d_Matrix scaleMatrix(float d)
// matrix for scaling
{
return idx3d_Matrix.scaleMatrix(d,d,d);
}
public static idx3d_Matrix rotateMatrix(float dx, float dy, float dz)
// matrix for rotation
{
idx3d_Matrix out=new idx3d_Matrix();
float SIN;
float COS;
if (dx!=0)
{
idx3d_Matrix m =new idx3d_Matrix();
SIN=idx3d_Math.sin(dx);
COS=idx3d_Math.cos(dx);
m.m11=COS;
m.m12=SIN;
m.m21=-SIN;
m.m22=COS;
out.transform(m);
}
if (dy!=0)
{
idx3d_Matrix m =new idx3d_Matrix();
SIN=idx3d_Math.sin(dy);
COS=idx3d_Math.cos(dy);
m.m00=COS;
m.m02=SIN;
m.m20=-SIN;
m.m22=COS;
out.transform(m);
}
if (dz!=0)
{
idx3d_Matrix m =new idx3d_Matrix();
SIN=idx3d_Math.sin(dz);
COS=idx3d_Math.cos(dz);
m.m00=COS;
m.m01=SIN;
m.m10=-SIN;
m.m11=COS;
out.transform(m);
}
return out;
}
// P U B L I C M E T H O D S
public void shift(float dx, float dy, float dz)
{
transform(shiftMatrix(dx,dy,dz));
}
public void scale(float dx, float dy, float dz)
{
transform(scaleMatrix(dx,dy,dz));
}
public void scale(float d)
{
transform(scaleMatrix(d));
}
public void rotate(float dx, float dy, float dz)
{
transform(rotateMatrix(dx,dy,dz));
}
public void scaleSelf(float dx, float dy, float dz)
{
preTransform(scaleMatrix(dx,dy,dz));
}
public void scaleSelf(float d)
{
preTransform(scaleMatrix(d));
}
public void rotateSelf(float dx, float dy, float dz)
{
preTransform(rotateMatrix(dx,dy,dz));
}
public void transform(idx3d_Matrix n)
// transforms this matrix by matrix n from left (this=n x this)
{
idx3d_Matrix m=this.getClone();
m00 = n.m00*m.m00 + n.m01*m.m10 + n.m02*m.m20;
m01 = n.m00*m.m01 + n.m01*m.m11 + n.m02*m.m21;
m02 = n.m00*m.m02 + n.m01*m.m12 + n.m02*m.m22;
m03 = n.m00*m.m03 + n.m01*m.m13 + n.m02*m.m23 + n.m03;
m10 = n.m10*m.m00 + n.m11*m.m10 + n.m12*m.m20;
m11 = n.m10*m.m01 + n.m11*m.m11 + n.m12*m.m21;
m12 = n.m10*m.m02 + n.m11*m.m12 + n.m12*m.m22;
m13 = n.m10*m.m03 + n.m11*m.m13 + n.m12*m.m23 + n.m13;
m20 = n.m20*m.m00 + n.m21*m.m10 + n.m22*m.m20;
m21 = n.m20*m.m01 + n.m21*m.m11 + n.m22*m.m21;
m22 = n.m20*m.m02 + n.m21*m.m12 + n.m22*m.m22;
m23 = n.m20*m.m03 + n.m21*m.m13 + n.m22*m.m23 + n.m23;
}
public void preTransform(idx3d_Matrix n)
// transforms this matrix by matrix n from right (this=this x n)
{
idx3d_Matrix m=this.getClone();
m00 = m.m00*n.m00 + m.m01*n.m10 + m.m02*n.m20;
m01 = m.m00*n.m01 + m.m01*n.m11 + m.m02*n.m21;
m02 = m.m00*n.m02 + m.m01*n.m12 + m.m02*n.m22;
m03 = m.m00*n.m03 + m.m01*n.m13 + m.m02*n.m23 + m.m03;
m10 = m.m10*n.m00 + m.m11*n.m10 + m.m12*n.m20;
m11 = m.m10*n.m01 + m.m11*n.m11 + m.m12*n.m21;
m12 = m.m10*n.m02 + m.m11*n.m12 + m.m12*n.m22;
m13 = m.m10*n.m03 + m.m11*n.m13 + m.m12*n.m23 + m.m13;
m20 = m.m20*n.m00 + m.m21*n.m10 + m.m22*n.m20;
m21 = m.m20*n.m01 + m.m21*n.m11 + m.m22*n.m21;
m22 = m.m20*n.m02 + m.m21*n.m12 + m.m22*n.m22;
m23 = m.m20*n.m03 + m.m21*n.m13 + m.m22*n.m23 + m.m23;
}
public static idx3d_Matrix multiply(idx3d_Matrix m1, idx3d_Matrix m2)
// returns m1 x m2
{
idx3d_Matrix m=new idx3d_Matrix();
m.m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20;
m.m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21;
m.m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22;
m.m03 = m1.m00*m2.m03 + m1.m01*m2.m13 + m1.m02*m2.m23 + m1.m03;
m.m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20;
m.m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21;
m.m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22;
m.m13 = m1.m10*m2.m03 + m1.m11*m2.m13 + m1.m12*m2.m23 + m1.m13;
m.m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20;
m.m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21;
m.m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22;
m.m23 = m1.m20*m2.m03 + m1.m21*m2.m13 + m1.m22*m2.m23 + m1.m23;
return m;
}
public String toString()
{
StringBuffer out=new StringBuffer("<Matrix: \r\n");
out.append(m00+","+m01+","+m02+","+m03+",\r\n");
out.append(m10+","+m11+","+m12+","+m13+",\r\n");
out.append(m20+","+m21+","+m22+","+m23+",\r\n");
out.append(m30+","+m31+","+m32+","+m33+">\r\n");
return out.toString();
}
public idx3d_Matrix getClone()
{
idx3d_Matrix m=new idx3d_Matrix();
m.m00=m00; m.m01=m01; m.m02=m02; m.m03=m03;
m.m10=m10; m.m11=m11; m.m12=m12; m.m13=m13;
m.m20=m20; m.m21=m21; m.m22=m22; m.m23=m23;
m.m30=m30; m.m31=m31; m.m32=m32; m.m33=m33;
return m;
}
public idx3d_Matrix inverse()
// Returns the inverse of this matrix
// Code generated with MapleV and handoptimized
{
idx3d_Matrix m=new idx3d_Matrix();
float q1 = m12; float q6 = m10*m01; float q7 = m10*m21; float q8 = m02;
float q13 = m20*m01; float q14 = m20*m11; float q21 = m02*m21; float q22 = m03*m21;
float q25 = m01*m12; float q26 = m01*m13; float q27 = m02*m11; float q28 = m03*m11;
float q29 = m10*m22; float q30 = m10*m23; float q31 = m20*m12; float q32 = m20*m13;
float q35 = m00*m22; float q36 = m00*m23; float q37 = m20*m02; float q38 = m20*m03;
float q41 = m00*m12; float q42 = m00*m13; float q43 = m10*m02; float q44 = m10*m03;
float q45 = m00*m11; float q48 = m00*m21;
float q49 = q45*m22-q48*q1-q6*m22+q7*q8;
float q50 = q13*q1-q14*q8;
float q51 = 1/(q49+q50);
m.m00 = (m11*m22*m33-m11*m23*m32-m21*m12*m33+m21*m13*m32+m31*m12*m23-m31*m13*m22)*q51;
m.m01 = -(m01*m22*m33-m01*m23*m32-q21*m33+q22*m32)*q51;
m.m02 = (q25*m33-q26*m32-q27*m33+q28*m32)*q51;
m.m03 = -(q25*m23-q26*m22-q27*m23+q28*m22+q21*m13-q22*m12)*q51;
m.m10 = -(q29*m33-q30*m32-q31*m33+q32*m32)*q51;
m.m11 = (q35*m33-q36*m32-q37*m33+q38*m32)*q51;
m.m12 = -(q41*m33-q42*m32-q43*m33+q44*m32)*q51;
m.m13 = (q41*m23-q42*m22-q43*m23+q44*m22+q37*m13-q38*m12)*q51;
m.m20 = (q7*m33-q30*m31-q14*m33+q32*m31)*q51;
m.m21 = -(q48*m33-q36*m31-q13*m33+q38*m31)*q51;
m.m22 = (q45*m33-q42*m31-q6*m33+q44*m31)*q51;
m.m23 = -(q45*m23-q42*m21-q6*m23+q44*m21+q13*m13-q38*m11)*q51;
return m;
}
public void reset()
// Resets the matrix
{
m00=1; m01=0; m02=0; m03=0;
m10=0; m11=1; m12=0; m13=0;
m20=0; m21=0; m22=1; m23=0;
m30=0; m31=0; m32=0; m33=1;
}
// P R I V A T E M E T H O D S
}