float x= 0, y = 0; float tdx = 0.04, tdy = 0.02; float dx = tdx, dy = tdy; BImage image; void setup( ){ framerate(20); size(200,200); fill(128); noStroke(); //smooth(); } Matrix3D m = new Matrix3D(); void mouseDragged() { mouseMoved(); } void mouseMoved() { tdx=0.01*(mouseX-pmouseX); tdy=0.01*(mouseY-pmouseY); } void loop( ){ image = copy(); background(255); x += dx; y += dy; dx += (tdx-dx)/20; dy += (tdy-dy)/20; translate(width/2, height/2, 0); m.transform(m.makeRotation(dy,dx,0)); m.apply(); box3d(image,width*0.5); } void box3d(BImage image, float x) { push(); scale(x); translate(-0.5,-0.5,-0.5); beginShape(QUADS); texture(image); vertex(0, 0, 0, 0, 0); vertex(1, 0, 0, image.width, 0); vertex(1, 1, 0, image.width, image.height); vertex(0, 1, 0, 0, image.height); vertex(0, 0, 1, 0, 0); vertex(1, 0, 1, image.width, 0); vertex(1, 1, 1, image.width, image.height); vertex(0, 1, 1, 0, image.height); vertex(0, 0, 0, 0, 0); vertex(0, 1, 0, image.width, 0); vertex(0, 1, 1, image.width, image.height); vertex(0, 0, 1, 0, image.height); vertex(1, 0, 0, 0, 0); vertex(1, 1, 0, image.width, 0); vertex(1, 1, 1, image.width, image.height); vertex(1, 0, 1, 0, image.height); vertex(0, 0, 0, 0, 0); vertex(1, 0, 0, image.width, 0); vertex(1, 0, 1, image.width, image.height); vertex(0, 0, 1, 0, image.height); vertex(0, 1, 0, 0, 0); vertex(1, 1, 0, image.width, 0); vertex(1, 1, 1, image.width, image.height); vertex(0, 1, 1, 0, image.height); endShape(); pop(); } public class Matrix3D { public void apply() { g.transform(m_0_0, m_0_1, m_0_2, m_0_3, m_1_0, m_1_1, m_1_2, m_1_3, m_2_0, m_2_1, m_2_2, m_2_3, m_3_0, m_3_1, m_3_2, m_3_3); } public Matrix3D() { setIdentity(); } public Matrix3D(float m_0_0, float m_0_1, float m_0_2, float m_0_3, float m_1_0, float m_1_1, float m_1_2, float m_1_3, float m_2_0, float m_2_1, float m_2_2, float m_2_3, float m_3_0, float m_3_1, float m_3_2, float m_3_3) { this.m_0_0 = m_0_0; this.m_0_1 = m_0_1; this.m_0_2 = m_0_2; this.m_0_3 = m_0_3; this.m_1_0 = m_1_0; this.m_1_1 = m_1_1; this.m_1_2 = m_1_2; this.m_1_3 = m_1_3; this.m_2_0 = m_2_0; this.m_2_1 = m_2_1; this.m_2_2 = m_2_2; this.m_2_3 = m_2_3; this.m_3_0 = m_3_0; this.m_3_1 = m_3_1; this.m_3_2 = m_3_2; this.m_3_3 = m_3_3; } public Matrix3D cloneMatrix() { return new Matrix3D(m_0_0, m_0_1, m_0_2, m_0_3, m_1_0, m_1_1, m_1_2, m_1_3, m_2_0, m_2_1, m_2_2, m_2_3, m_3_0, m_3_1, m_3_2, m_3_3); } public float m_0_0, m_0_1, m_0_2, m_0_3, m_1_0, m_1_1, m_1_2, m_1_3, m_2_0, m_2_1, m_2_2, m_2_3, m_3_0, m_3_1, m_3_2, m_3_3; public void setIdentity() { m_0_0 = 1; m_0_1 = 0; m_0_2 = 0; m_0_3 = 0; m_1_0 = 0; m_1_1 = 1; m_1_2 = 0; m_1_3 = 0; m_2_0 = 0; m_2_1 = 0; m_2_2 = 1; m_2_3 = 0; m_3_0 = 0; m_3_1 = 0; m_3_2 = 0; m_3_3 = 1; } public Matrix3D clearScale() { m_0_0 = 1; m_0_1 = 0; m_0_2 = 0; m_1_0 = 0; m_1_1 = 1; m_1_2 = 0; m_2_0 = 0; m_2_1 = 0; m_2_2 = 1; return this; } public Matrix3D clearTranslation() { m_0_3 = 0; m_1_3 = 0; m_2_3 = 0; return this; } public Matrix3D makeTranslation(float x, float y, float z) { return new Matrix3D( 1,0,0,x, 0,1,0,y, 0,0,1,z, 0,0,0,1 ); } public Matrix3D makeScale(float x, float y, float z) { return new Matrix3D( x,0,0,0, 0,y,0,0, 0,0,z,0, 0,0,0,1 ); } public Matrix3D makeScale(float u) { return makeScale(u,u,u); } public Matrix3D makeRotationX(float t) { if (t==0) return new Matrix3D(); float sin = (float)Math.sin(t); float cos = (float)Math.cos(t); return new Matrix3D( 1, 0, 0, 0, 0, cos, sin, 0, 0, -sin,cos, 0, 0, 0, 0, 1 ); } public Matrix3D makeRotationY(float t) { if (t==0) return new Matrix3D(); float sin = (float)Math.sin(t); float cos = (float)Math.cos(t); return new Matrix3D( cos, 0, sin, 0, 0, 1, 0, 0, -sin,0, cos, 0, 0, 0, 0, 1 ); } public Matrix3D makeRotationZ(float t) { if (t==0) return new Matrix3D(); float sin = (float)Math.sin(t); float cos = (float)Math.cos(t); return new Matrix3D( cos, sin, 0, 0, -sin,cos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); } public Matrix3D makeRotation(float x, float y, float z) { Matrix3D base = new Matrix3D(); if (x!=0) base.transform(makeRotationX(x)); if (y!=0) base.transform(makeRotationY(y)); if (z!=0) base.transform(makeRotationZ(z)); return base; } // The following four functions were borrowed from idx3d's idx3d_Matrix class public void transform(Matrix3D n) { Matrix3D m=cloneMatrix(); m_0_0 = n.m_0_0*m.m_0_0 + n.m_0_1*m.m_1_0 + n.m_0_2*m.m_2_0; m_0_1 = n.m_0_0*m.m_0_1 + n.m_0_1*m.m_1_1 + n.m_0_2*m.m_2_1; m_0_2 = n.m_0_0*m.m_0_2 + n.m_0_1*m.m_1_2 + n.m_0_2*m.m_2_2; m_0_3 = n.m_0_0*m.m_0_3 + n.m_0_1*m.m_1_3 + n.m_0_2*m.m_2_3 + n.m_0_3; m_1_0 = n.m_1_0*m.m_0_0 + n.m_1_1*m.m_1_0 + n.m_1_2*m.m_2_0; m_1_1 = n.m_1_0*m.m_0_1 + n.m_1_1*m.m_1_1 + n.m_1_2*m.m_2_1; m_1_2 = n.m_1_0*m.m_0_2 + n.m_1_1*m.m_1_2 + n.m_1_2*m.m_2_2; m_1_3 = n.m_1_0*m.m_0_3 + n.m_1_1*m.m_1_3 + n.m_1_2*m.m_2_3 + n.m_1_3; m_2_0 = n.m_2_0*m.m_0_0 + n.m_2_1*m.m_1_0 + n.m_2_2*m.m_2_0; m_2_1 = n.m_2_0*m.m_0_1 + n.m_2_1*m.m_1_1 + n.m_2_2*m.m_2_1; m_2_2 = n.m_2_0*m.m_0_2 + n.m_2_1*m.m_1_2 + n.m_2_2*m.m_2_2; m_2_3 = n.m_2_0*m.m_0_3 + n.m_2_1*m.m_1_3 + n.m_2_2*m.m_2_3 + n.m_2_3; } public void preTransform(Matrix3D n) // transforms this matrix by matrix n from right (this=this x n) { Matrix3D m=cloneMatrix(); m_0_0 = m.m_0_0*n.m_0_0 + m.m_0_1*n.m_1_0 + m.m_0_2*n.m_2_0; m_0_1 = m.m_0_0*n.m_0_1 + m.m_0_1*n.m_1_1 + m.m_0_2*n.m_2_1; m_0_2 = m.m_0_0*n.m_0_2 + m.m_0_1*n.m_1_2 + m.m_0_2*n.m_2_2; m_0_3 = m.m_0_0*n.m_0_3 + m.m_0_1*n.m_1_3 + m.m_0_2*n.m_2_3 + m.m_0_3; m_1_0 = m.m_1_0*n.m_0_0 + m.m_1_1*n.m_1_0 + m.m_1_2*n.m_2_0; m_1_1 = m.m_1_0*n.m_0_1 + m.m_1_1*n.m_1_1 + m.m_1_2*n.m_2_1; m_1_2 = m.m_1_0*n.m_0_2 + m.m_1_1*n.m_1_2 + m.m_1_2*n.m_2_2; m_1_3 = m.m_1_0*n.m_0_3 + m.m_1_1*n.m_1_3 + m.m_1_2*n.m_2_3 + m.m_1_3; m_2_0 = m.m_2_0*n.m_0_0 + m.m_2_1*n.m_1_0 + m.m_2_2*n.m_2_0; m_2_1 = m.m_2_0*n.m_0_1 + m.m_2_1*n.m_1_1 + m.m_2_2*n.m_2_1; m_2_2 = m.m_2_0*n.m_0_2 + m.m_2_1*n.m_1_2 + m.m_2_2*n.m_2_2; m_2_3 = m.m_2_0*n.m_0_3 + m.m_2_1*n.m_1_3 + m.m_2_2*n.m_2_3 + m.m_2_3; } public Matrix3D multiply(Matrix3D m1, Matrix3D m2) { Matrix3D m=new Matrix3D(); m.m_0_0 = m1.m_0_0*m2.m_0_0 + m1.m_0_1*m2.m_1_0 + m1.m_0_2*m2.m_2_0; m.m_0_1 = m1.m_0_0*m2.m_0_1 + m1.m_0_1*m2.m_1_1 + m1.m_0_2*m2.m_2_1; m.m_0_2 = m1.m_0_0*m2.m_0_2 + m1.m_0_1*m2.m_1_2 + m1.m_0_2*m2.m_2_2; m.m_0_3 = m1.m_0_0*m2.m_0_3 + m1.m_0_1*m2.m_1_3 + m1.m_0_2*m2.m_2_3 + m1.m_0_3; m.m_1_0 = m1.m_1_0*m2.m_0_0 + m1.m_1_1*m2.m_1_0 + m1.m_1_2*m2.m_2_0; m.m_1_1 = m1.m_1_0*m2.m_0_1 + m1.m_1_1*m2.m_1_1 + m1.m_1_2*m2.m_2_1; m.m_1_2 = m1.m_1_0*m2.m_0_2 + m1.m_1_1*m2.m_1_2 + m1.m_1_2*m2.m_2_2; m.m_1_3 = m1.m_1_0*m2.m_0_3 + m1.m_1_1*m2.m_1_3 + m1.m_1_2*m2.m_2_3 + m1.m_1_3; m.m_2_0 = m1.m_2_0*m2.m_0_0 + m1.m_2_1*m2.m_1_0 + m1.m_2_2*m2.m_2_0; m.m_2_1 = m1.m_2_0*m2.m_0_1 + m1.m_2_1*m2.m_1_1 + m1.m_2_2*m2.m_2_1; m.m_2_2 = m1.m_2_0*m2.m_0_2 + m1.m_2_1*m2.m_1_2 + m1.m_2_2*m2.m_2_2; m.m_2_3 = m1.m_2_0*m2.m_0_3 + m1.m_2_1*m2.m_1_3 + m1.m_2_2*m2.m_2_3 + m1.m_2_3; return m; } public Matrix3D inverse() { Matrix3D m=new Matrix3D(); float q1 = m_1_2; float q6 = m_1_0*m_0_1; float q7 = m_1_0*m_2_1; float q8 = m_0_2; float q13 = m_2_0*m_0_1; float q14 = m_2_0*m_1_1; float q21 = m_0_2*m_2_1; float q22 = m_0_3*m_2_1; float q25 = m_0_1*m_1_2; float q26 = m_0_1*m_1_3; float q27 = m_0_2*m_1_1; float q28 = m_0_3*m_1_1; float q29 = m_1_0*m_2_2; float q30 = m_1_0*m_2_3; float q31 = m_2_0*m_1_2; float q32 = m_2_0*m_1_3; float q35 = m_0_0*m_2_2; float q36 = m_0_0*m_2_3; float q37 = m_2_0*m_0_2; float q38 = m_2_0*m_0_3; float q41 = m_0_0*m_1_2; float q42 = m_0_0*m_1_3; float q43 = m_1_0*m_0_2; float q44 = m_1_0*m_0_3; float q45 = m_0_0*m_1_1; float q48 = m_0_0*m_2_1; float q49 = q45*m_2_2-q48*q1-q6*m_2_2+q7*q8; float q50 = q13*q1-q14*q8; float q51 = 1/(q49+q50); m.m_0_0 = (m_1_1*m_2_2*m_3_3-m_1_1*m_2_3*m_3_2-m_2_1*m_1_2*m_3_3+m_2_1*m_1_3*m_3_2+m_3_1*m_1_2*m_2_3-m_3_1*m_1_3*m_2_2)*q51; m.m_0_1 = -(m_0_1*m_2_2*m_3_3-m_0_1*m_2_3*m_3_2-q21*m_3_3+q22*m_3_2)*q51; m.m_0_2 = (q25*m_3_3-q26*m_3_2-q27*m_3_3+q28*m_3_2)*q51; m.m_0_3 = -(q25*m_2_3-q26*m_2_2-q27*m_2_3+q28*m_2_2+q21*m_1_3-q22*m_1_2)*q51; m.m_1_0 = -(q29*m_3_3-q30*m_3_2-q31*m_3_3+q32*m_3_2)*q51; m.m_1_1 = (q35*m_3_3-q36*m_3_2-q37*m_3_3+q38*m_3_2)*q51; m.m_1_2 = -(q41*m_3_3-q42*m_3_2-q43*m_3_3+q44*m_3_2)*q51; m.m_1_3 = (q41*m_2_3-q42*m_2_2-q43*m_2_3+q44*m_2_2+q37*m_1_3-q38*m_1_2)*q51; m.m_2_0 = (q7*m_3_3-q30*m_3_1-q14*m_3_3+q32*m_3_1)*q51; m.m_2_1 = -(q48*m_3_3-q36*m_3_1-q13*m_3_3+q38*m_3_1)*q51; m.m_2_2 = (q45*m_3_3-q42*m_3_1-q6*m_3_3+q44*m_3_1)*q51; m.m_2_3 = -(q45*m_2_3-q42*m_2_1-q6*m_2_3+q44*m_2_1+q13*m_1_3-q38*m_1_1)*q51; return m; } public String toString() { return "[Matrix3D:\n"+ "\t" + m_0_0 + "," + m_0_1 + "," + m_0_2 + "," + m_0_3 + "\n"+ "\t" + m_1_0 + "," + m_1_1 + "," + m_1_2 + "," + m_1_3 + "\n"+ "\t" + m_2_0 + "," + m_2_1 + "," + m_2_2 + "," + m_2_3 + "\n"+ "\t" + m_3_0 + "," + m_3_1 + "," + m_3_2 + "," + m_3_3 + "]"; } }