aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/javax/media/opengl/util/PMVMatrix.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/javax/media/opengl/util/PMVMatrix.java')
-rwxr-xr-xsrc/classes/javax/media/opengl/util/PMVMatrix.java310
1 files changed, 310 insertions, 0 deletions
diff --git a/src/classes/javax/media/opengl/util/PMVMatrix.java b/src/classes/javax/media/opengl/util/PMVMatrix.java
new file mode 100755
index 000000000..4e8693be0
--- /dev/null
+++ b/src/classes/javax/media/opengl/util/PMVMatrix.java
@@ -0,0 +1,310 @@
+
+package javax.media.opengl.util;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.ProjectFloat;
+import java.nio.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PMVMatrix {
+
+ protected ProjectFloat pvmProjectf = null;
+ protected FloatBuffer matrixPMV, matrixP, matrixMV;
+ protected FloatBuffer matrixTemp, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixPersp, matrixFrustum;
+ protected float[] vec3f;
+ protected List/*FloatBuffer*/ matrixPStack, matrixMVStack;
+ protected int matrixMode = GL.GL_MODELVIEW;
+ protected boolean modifiedPMV = false;
+
+ public PMVMatrix() {
+ pvmProjectf = new ProjectFloat();
+
+ matrixPMV = BufferUtil.newFloatBuffer(2*16);
+ matrixP = slice(matrixPMV, 0*16, 16);
+ matrixMV = slice(matrixPMV, 1*16, 16);
+ matrixPMV.rewind();
+
+ FloatBuffer buf = BufferUtil.newFloatBuffer(7*16);
+
+ matrixTemp=slice(buf, 0*16, 16);
+
+ matrixTrans=slice(buf, 1*16, 16);
+ pvmProjectf.gluMakeIdentityf(matrixTrans);
+
+ matrixRot=slice(buf, 2*16, 16);
+ pvmProjectf.gluMakeIdentityf(matrixRot);
+
+ matrixScale=slice(buf, 3*16, 16);
+ pvmProjectf.gluMakeIdentityf(matrixScale);
+
+ matrixOrtho=slice(buf, 4*16, 16);
+ pvmProjectf.gluMakeIdentityf(matrixOrtho);
+
+ matrixFrustum=slice(buf, 5*16, 16);
+ pvmProjectf.gluMakeZero(matrixFrustum);
+
+ matrixPersp=slice(buf, 6*16, 16);
+ pvmProjectf.gluMakeIdentityf(matrixPersp);
+
+ vec3f=new float[3];
+
+ matrixPStack = new ArrayList();
+ matrixMVStack= new ArrayList();
+
+ // default values and mode
+ glMatrixMode(GL.GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL.GL_MODELVIEW);
+ glLoadIdentity();
+ modifiedPMV = true;
+ }
+
+ private static FloatBuffer slice(FloatBuffer buf, int pos, int len) {
+ buf.position(pos);
+ buf.limit(pos + len);
+ return buf.slice();
+ }
+
+ public boolean isDirty() {
+ return modifiedPMV;
+ }
+
+ public void clear() {
+ modifiedPMV=false;
+ }
+
+ public final int glGetMatrixMode() {
+ return matrixMode;
+ }
+
+ public void glMatrixMode(int matrixName) {
+ switch(matrixName) {
+ case GL.GL_MODELVIEW:
+ case GL.GL_PROJECTION:
+ break;
+ default:
+ throw new GLUnsupportedException("unsupported matrixName: "+matrixName);
+ }
+ matrixMode = matrixName;
+ }
+
+ public final FloatBuffer glGetPMVMatrixf() {
+ return matrixPMV;
+ }
+
+ public final FloatBuffer glGetMatrixf() {
+ return glGetMatrixf(matrixMode);
+ }
+
+ public final FloatBuffer glGetMatrixf(int matrixName) {
+ if(matrixName==GL.GL_MODELVIEW) {
+ return matrixMV;
+ } else if(matrixName==GL.GL_PROJECTION) {
+ return matrixP;
+ }
+ return null;
+ }
+
+ public void glLoadMatrixf(java.nio.FloatBuffer m) {
+ if(matrixMode==GL.GL_MODELVIEW) {
+ matrixMV.clear();
+ matrixMV.put(m);
+ matrixMV.rewind();
+ } else if(matrixMode==GL.GL_PROJECTION) {
+ matrixP.clear();
+ matrixP.put(m);
+ matrixP.rewind();
+ }
+ modifiedPMV = true;
+ }
+
+ public void glPopMatrix() {
+ if(matrixMode==GL.GL_MODELVIEW) {
+ matrixMV=(FloatBuffer)matrixMVStack.remove(0);
+ } else if(matrixMode==GL.GL_PROJECTION) {
+ matrixP=(FloatBuffer)matrixPStack.remove(0);
+ }
+ modifiedPMV = true;
+ }
+
+ public void glPushMatrix() {
+ if(matrixMode==GL.GL_MODELVIEW) {
+ matrixMVStack.add(0, matrixMV);
+ } else if(matrixMode==GL.GL_PROJECTION) {
+ matrixPStack.add(0, matrixP);
+ }
+ }
+
+ public void glLoadIdentity() {
+ if(matrixMode==GL.GL_MODELVIEW) {
+ matrixMV.clear();
+ pvmProjectf.gluMakeIdentityf(matrixMV);
+ matrixMV.rewind();
+ } else if(matrixMode==GL.GL_PROJECTION) {
+ matrixP.clear();
+ pvmProjectf.gluMakeIdentityf(matrixP);
+ matrixP.rewind();
+ }
+ modifiedPMV = true;
+ }
+
+ public void glMultMatrixf(FloatBuffer m) {
+ if(matrixMode==GL.GL_MODELVIEW) {
+ pvmProjectf.gluMultMatricesf(m, matrixMV, matrixTemp);
+ matrixMV.clear();
+ matrixMV.put(matrixTemp);
+ matrixMV.rewind();
+ } else if(matrixMode==GL.GL_PROJECTION) {
+ pvmProjectf.gluMultMatricesf(m, matrixP, matrixTemp);
+ matrixP.clear();
+ matrixP.put(matrixTemp);
+ matrixP.rewind();
+ }
+ matrixTemp.rewind();
+ modifiedPMV = true;
+ }
+
+ public void glTranslatef(float x, float y, float z) {
+ // Translation matrix:
+ // 1 0 0 0
+ // 0 1 0 0
+ // 0 0 1 0
+ // x y z 1
+ matrixTrans.put(3*4+0, x);
+ matrixTrans.put(3*4+1, y);
+ matrixTrans.put(3*4+2, z);
+
+ glMultMatrixf(matrixTrans);
+ }
+
+ public void glRotatef(float angdeg, float x, float y, float z) {
+ float angrad = angdeg * (float) Math.PI / 180;
+ float c = (float)Math.cos(angrad);
+ float ic= 1.0f - c;
+ float s = (float)Math.sin(angrad);
+
+ vec3f[0]=x; vec3f[1]=y; vec3f[2]=z;
+ pvmProjectf.normalize(vec3f);
+ x = vec3f[0]; y = vec3f[1]; z = vec3f[2];
+
+ // Rotation matrix:
+ // xx(1−c)+c xy(1−c)+zs xz(1−c)-ys 0
+ // xy(1−c)-zs yy(1−c)+c yz(1−c)+xs 0
+ // xz(1−c)+ys yz(1−c)-xs zz(1−c)+c 0
+ // 0 0 0 1
+ float xy = x*y;
+ float xz = x*z;
+ float xs = x*s;
+ float ys = y*s;
+ float yz = y*z;
+ float zs = z*s;
+ matrixRot.put(0*4+0, x*x*ic+c);
+ matrixRot.put(0*4+1, xy*ic+zs);
+ matrixRot.put(0*4+2, xz*ic-ys);
+
+ matrixRot.put(1*4+0, xy*ic-zs);
+ matrixRot.put(1*4+1, y*y*ic+c);
+ matrixRot.put(1*4+2, yz*ic+xs);
+
+ matrixRot.put(2*4+0, xz*ic+ys);
+ matrixRot.put(2*4+1, yz*ic-xs);
+ matrixRot.put(2*4+2, z*z*ic+c);
+
+ glMultMatrixf(matrixRot);
+ }
+
+ public void glScalef(float x, float y, float z) {
+ // Scale matrix:
+ // x 0 0 0
+ // 0 y 0 0
+ // 0 0 z 0
+ // 0 0 0 1
+ matrixScale.put(0*4+0, x);
+ matrixScale.put(1*4+1, y);
+ matrixScale.put(2*4+2, z);
+
+ glMultMatrixf(matrixScale);
+ }
+
+ public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) {
+ // Ortho matrix:
+ // 2/dx 0 0 0
+ // 0 2/dy 0 0
+ // 0 0 2/dz 0
+ // tx tx tx 1
+ float dx=right-left;
+ float dy=top-bottom;
+ float dz=zFar-zNear;
+ float tx=-1.0f*(right+left)/dx;
+ float ty=-1.0f*(top+bottom)/dy;
+ float tz=-1.0f*(zFar+zNear)/dz;
+
+ matrixOrtho.put(0*4+0, 2.0f/dx);
+ matrixOrtho.put(1*4+1, 2.0f/dy);
+ matrixOrtho.put(2*4+2, -2.0f/dz);
+ matrixOrtho.put(3*4+0, tx);
+ matrixOrtho.put(3*4+1, ty);
+ matrixOrtho.put(3*4+2, tz);
+
+ glMultMatrixf(matrixOrtho);
+ }
+
+ public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar) {
+ if(zNear<=0.0f||zFar<0.0f) {
+ throw new GLException("GL_INVALID_VALUE: zNear and zFar must be positive, and zNear>0");
+ }
+ if(left==right || top==bottom) {
+ throw new GLException("GL_INVALID_VALUE: top,bottom and left,right must not be equal");
+ }
+ // Frustum matrix:
+ // 2*zNear/dx 0 A 0
+ // 0 2*zNear/dy B 0
+ // 0 0 C D
+ // 0 0 −1 0
+ float zNear2 = 2.0f*zNear;
+ float dx=right-left;
+ float dy=top-bottom;
+ float dz=zFar-zNear;
+ float A=(right+left)/dx;
+ float B=(top+bottom)/dy;
+ float C=-1.0f*(zFar+zNear)/dz;
+ float D=-2.0f*(zFar*zNear)/dz;
+
+ matrixFrustum.put(0*4+0, zNear2/dx);
+ matrixFrustum.put(1*4+1, zNear2/dy);
+ matrixFrustum.put(2*4+2, C);
+ matrixFrustum.put(0*4+2, A);
+ matrixFrustum.put(1*4+2, B);
+ matrixFrustum.put(2*4+3, D);
+ matrixFrustum.put(3*4+2, -1.0f);
+
+ glMultMatrixf(matrixFrustum);
+ }
+
+ public void gluPerspective(float fovy, float aspect, float zNear, float zFar) {
+ float radians = fovy/2 * (float) Math.PI / 180;
+
+ float sine, cotangent, deltaZ;
+
+ deltaZ = zFar - zNear;
+ sine = (float) Math.sin(radians);
+
+ if ((deltaZ == 0.0f) || (sine == 0.0f) || (aspect == 0.0f)) {
+ return;
+ }
+
+ cotangent = (float) Math.cos(radians) / sine;
+
+ matrixPersp.put(0 * 4 + 0, cotangent / aspect);
+ matrixPersp.put(1 * 4 + 1, cotangent);
+ matrixPersp.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
+ matrixPersp.put(2 * 4 + 3, -1);
+ matrixPersp.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
+ matrixPersp.put(3 * 4 + 3, 0);
+
+ glMultMatrixf(matrixPersp);
+ }
+}
+
+