import java.awt.*;
import java.applet.*;
//---- Dat -------------------------------------------------------------------//
class Dat
{
boolean changed = true;
public Dat()
{
System.out.println("Creating Dat");
}
public void update()
{
}
public String toString()
{
return "Dat()";
}
}
//---- Num -------------------------------------------------------------------//
class Num extends Dat
{
public float value = 0;
public Num()
{
System.out.println("Creating Num()");
}
public Num(float value)
{
System.out.println("Creating Num("+value+")");
this.value = value;
}
public String toString()
{
return "Num("+value+")";
}
}
//---- Vec -------------------------------------------------------------------//
class Vec extends Dat
{
public float x = 0;
public float y = 0;
public float z = 0;
public Vec(float x, float y, float z)
{
System.out.println("Creating Vec("+x+", "+y+", "+z+")");
set(x, y, z);
}
public void set(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public String toString()
{
return "Vec("+x+", "+y+", "+z+")";
}
}
//---- Mat -------------------------------------------------------------------//
class Mat extends Dat
{
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;
public Mat()
{
System.out.println("Creating Mat()");
}
/*
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 String toString()
{
return "Mat( ("+m00+","+m01+","+m02+","+m03+"), ("+m10+","+m11+","+m12+","+m13+"), ("+m20+","+m21+","+m22+","+m23+"), ("+m30+","+m31+","+m32+","+m33+") )";
}
}
//---- Im --------------------------------------------------------------------//
class Im extends Dat
{
int w, h;
RenderBuffer screen;
public Im()
{
}
public Im(int w, int h)
{
System.out.println("Creating Im("+w+", "+h+")");
screen = new RenderBuffer(w, h);
}
public String toString()
{
return "Im("+w+", "+h+")";
}
}
//---- ShiftMat --------------------------------------------------------------//
class ShiftMat extends Mat
{
public ShiftMat(float x, float y, float z)
{
System.out.println("Creating ShiftMat("+x+", "+y+", "+z+")");
set(x, y, z);
}
public void set(float x, float y, float z)
{
m03 = x;
m13 = y;
m23 = z;
}
public String toString()
{
return "ShiftMat()";
}
}
//---- ScaleMat --------------------------------------------------------------//
class ScaleMat extends Mat
{
public ScaleMat(float x, float y, float z)
{
System.out.println("Creating ScaleMat("+x+", "+y+", "+z+")");
set(x, y, z);
}
public void set(float x, float y, float z)
{
m00 = x;
m11 = y;
m22 = z;
}
public String toString()
{
return "ScaleMat()";
}
}
//---- RotateXMat ------------------------------------------------------------//
class RotateXMat extends Mat
{
public RotateXMat(float a)
{
System.out.println("Creating RotateXMat("+a+")");
set(a);
}
public void set(float a)
{
float s = (float)Math.sin(a*3.1415926*2);
float c = (float)Math.cos(a*3.1415926*2);
m11 = c;
m12 = s;
m21 = -s;
m22 = c;
}
public String toString()
{
return "RotateXMat()";
}
}
//---- RotateYMat ------------------------------------------------------------//
class RotateYMat extends Mat
{
public RotateYMat(float a)
{
System.out.println("Creating RotateYMat("+a+")");
set(a);
}
public void set(float a)
{
float s = (float)Math.sin(a*3.1415926*2);
float c = (float)Math.cos(a*3.1415926*2);
m00 = c;
m02 = s;
m20 = -s;
m22 = c;
}
public String toString()
{
return "RotateYMat()";
}
}
//---- RotateZMat ------------------------------------------------------------//
class RotateZMat extends Mat
{
public RotateZMat(float a)
{
System.out.println("Creating RotateZMat("+a+")");
set(a);
}
public void set(float a)
{
float s = (float)Math.sin(a*3.1415926*2);
float c = (float)Math.cos(a*3.1415926*2);
m00 = c;
m01 = s;
m10 = -s;
m11 = c;
}
public String toString()
{
return "RotateZMat()";
}
}
//---- CombineMat ------------------------------------------------------------//
class CombineMat extends Mat
{
Mat m1, m2;
public CombineMat()
{
System.out.println("Creating CombineMat()");
set(new Mat(), new Mat());
}
public CombineMat(Mat m1, Mat m2)
{
System.out.println("Creating CombineMat("+m1+", "+m2+")");
set(m1, m2);
}
public void set(Mat m1, Mat m2)
{
this.m1 = m1;
this.m2 = m2;
}
public void update()
{
m1.update();
m2.update();
m00 = m2.m00*m1.m00 + m2.m01*m1.m10 + m2.m02*m1.m20;
m01 = m2.m00*m1.m01 + m2.m01*m1.m11 + m2.m02*m1.m21;
m02 = m2.m00*m1.m02 + m2.m01*m1.m12 + m2.m02*m1.m22;
m03 = m2.m00*m1.m03 + m2.m01*m1.m13 + m2.m02*m1.m23 + m2.m03;
m10 = m2.m10*m1.m00 + m2.m11*m1.m10 + m2.m12*m1.m20;
m11 = m2.m10*m1.m01 + m2.m11*m1.m11 + m2.m12*m1.m21;
m12 = m2.m10*m1.m02 + m2.m11*m1.m12 + m2.m12*m1.m22;
m13 = m2.m10*m1.m03 + m2.m11*m1.m13 + m2.m12*m1.m23 + m2.m13;
m20 = m2.m20*m1.m00 + m2.m21*m1.m10 + m2.m22*m1.m20;
m21 = m2.m20*m1.m01 + m2.m21*m1.m11 + m2.m22*m1.m21;
m22 = m2.m20*m1.m02 + m2.m21*m1.m12 + m2.m22*m1.m22;
m23 = m2.m20*m1.m03 + m2.m21*m1.m13 + m2.m22*m1.m23 + m2.m23;
}
public String toString()
{
return "CombineMat("+m1+", "+m2+")";
}
}
//---- Obj -------------------------------------------------------------------//
class Obj extends Dat
{
int[][] face;
float[][] point;
float[][] tpoint;
float[][] spoint;
int numPoints, numFaces;
public Obj()
{
System.out.println("Creating Obj()");
}
public void render(RenderBuffer buf, Mat m)
{
m.update();
float x, y, z;
int i;
// Transform
for(i=0; i<numPoints; i++)
{
x = point[i][0];
y = point[i][1];
z = point[i][2];
tpoint[i][0] = x*m.m00 + y*m.m01 + z*m.m02+ m.m03;
tpoint[i][1] = x*m.m10 + y*m.m11 + z*m.m12+ m.m13;
tpoint[i][2] = x*m.m20 + y*m.m21 + z*m.m22+ m.m23;
}
// Calculate screen co-ords
for(i=0; i<numPoints; i++)
{
x = tpoint[i][0];
y = tpoint[i][1];
z = tpoint[i][2];
spoint[i][0] = buf.w*0.5f + buf.w*0.5f * x / z;
spoint[i][1] = buf.h*0.5f + buf.w*0.5f * y / z;
spoint[i][2] = 1.0f / z;
}
// Render dots
/*
for(i=0; i<numPoints; i++)
{
x = spoint[i][0];
y = spoint[i][1];
z = spoint[i][2];
buf.circle(x, y, 5 + 5.0 * z, 0xFFFFFFFF);
buf.circle(x, y, 2 + 5.0 * z, 0xFF000000);
buf.circle(x, y, 0 + 5.0 * z, 0xFF00FF00);
}
*/
// Render faces
for(i=0; i<numFaces; i++)
{
buf.tri_x1 = spoint[face[i][0]][0];
buf.tri_y1 = spoint[face[i][0]][1];
buf.tri_z1 = spoint[face[i][0]][2];
buf.tri_x2 = spoint[face[i][1]][0];
buf.tri_y2 = spoint[face[i][1]][1];
buf.tri_z2 = spoint[face[i][1]][2];
buf.tri_x3 = spoint[face[i][2]][0];
buf.tri_y3 = spoint[face[i][2]][1];
buf.tri_z3 = spoint[face[i][2]][2];
buf.zbufTri(0xFFFFCC00 | (i*0x87638723));
}
}
public String toString()
{
return "Obj()";
}
}
//---- TransformObj ----------------------------------------------------------//
class TransformObj extends Obj
{
Obj obj;
Mat mat;
CombineMat m2;
public TransformObj(Obj obj, Mat mat)
{
System.out.println("Creating TransformObj("+obj+", "+mat+")");
this.obj = obj;
this.mat = mat;
m2 = new CombineMat();
}
public void update()
{
obj.update();
mat.update();
}
public String toString()
{
return "TransformObj()";
}
public void render(RenderBuffer buf, Mat m)
{
m2.set(mat, m);
m2.update();
obj.render(buf, m2);
}
}
//---- CombineObj ------------------------------------------------------------//
class CombineObj extends Obj
{
Obj obj1, obj2;
public CombineObj()
{
System.out.println("Creating CombineObj()");
}
public CombineObj(Obj obj1, Obj obj2)
{
System.out.println("Creating CombineObj( "+obj1+", "+obj2+" )");
this.obj1 = obj1;
this.obj2 = obj2;
}
public void update()
{
obj1.update();
obj2.update();
}
public void render(RenderBuffer buf, Mat m)
{
obj1.render(buf, m);
obj2.render(buf, m);
}
}
//---- CubeObj ---------------------------------------------------------------//
class CubeObj extends Obj
{
public CubeObj()
{
super();
tpoint = new float[8][3];
spoint = new float[8][3];
point = new float[8][3];
face = new int[12][3];
numPoints = 8;
numFaces = 12;
point[0][0] = 1; point[0][1] = 1; point[0][2] = 1;
point[1][0] = 1; point[1][1] = 1; point[1][2] = -1;
point[2][0] = -1; point[2][1] = 1; point[2][2] = -1;
point[3][0] = -1; point[3][1] = 1; point[3][2] = 1;
point[4][0] = 1; point[4][1] = -1; point[4][2] = 1;
point[5][0] = 1; point[5][1] = -1; point[5][2] = -1;
point[6][0] = -1; point[6][1] = -1; point[6][2] = -1;
point[7][0] = -1; point[7][1] = -1; point[7][2] = 1;
face[ 0][0] = 0; face[ 0][1] = 1; face[ 0][2] = 2;
face[ 1][0] = 2; face[ 1][1] = 3; face[ 1][2] = 0;
face[ 2][0] = 5; face[ 2][1] = 6; face[ 2][2] = 2;
face[ 3][0] = 2; face[ 3][1] = 1; face[ 3][2] = 5;
face[ 4][0] = 6; face[ 4][1] = 7; face[ 4][2] = 3;
face[ 5][0] = 3; face[ 5][1] = 2; face[ 5][2] = 6;
face[ 6][0] = 7; face[ 6][1] = 6; face[ 6][2] = 5;
face[ 7][0] = 5; face[ 7][1] = 4; face[ 7][2] = 7;
face[ 8][0] = 0; face[ 8][1] = 3; face[ 8][2] = 7;
face[ 9][0] = 7; face[ 9][1] = 4; face[ 9][2] = 0;
face[10][0] = 0; face[10][1] = 4; face[10][2] = 5;
face[11][0] = 5; face[11][1] = 1; face[11][2] = 0;
System.out.println("Created "+this);
}
public String toString()
{
return "CubeObj()";
}
}
//---- CylinderObj -----------------------------------------------------------//
class CylinderObj extends Obj
{
public CylinderObj()
{
super();
int rdiv = 32;
numPoints = rdiv * 2 + 2;
numFaces = rdiv * 4;
tpoint = new float[numPoints][3];
spoint = new float[numPoints][3];
point = new float[numPoints][3];
face = new int[numFaces][3];
float x, z;
for(int i=0; i<rdiv; i++)
{
x = (float)Math.sin(i*3.14159*2/rdiv);
z = (float)Math.cos(i*3.14159*2/rdiv);
point[i*2+0][0] = x;
point[i*2+0][1] = 1;
point[i*2+0][2] = z;
point[i*2+1][0] = x;
point[i*2+1][1] = -1;
point[i*2+1][2] = z;
int p1 = ((i+0)%rdiv)*2 + 0;
int p2 = ((i+1)%rdiv)*2 + 0;
int p3 = ((i+1)%rdiv)*2 + 1;
int p4 = ((i+0)%rdiv)*2 + 1;
face[i*4+0][0] = rdiv*2;
face[i*4+0][1] = p2;
face[i*4+0][2] = p1;
face[i*4+1][0] = p1;
face[i*4+1][1] = p2;
face[i*4+1][2] = p3;
face[i*4+2][0] = p3;
face[i*4+2][1] = p4;
face[i*4+2][2] = p1;
face[i*4+3][0] = p4;
face[i*4+3][1] = p3;
face[i*4+3][2] = rdiv*2+1;
}
point[rdiv*2+0][0] = 0;
point[rdiv*2+0][1] = 1;
point[rdiv*2+0][2] = 0;
point[rdiv*2+1][0] = 0;
point[rdiv*2+1][1] = -1;
point[rdiv*2+1][2] = 0;
System.out.println("Creating CylinderObj()");
}
public String toString()
{
return "CylinderObj()";
}
}
//---- MadBoxBitObj ----------------------------------------------------------//
class MadBoxBitObj extends Obj
{
Obj pole1, pole2, pole3, pole4, ibox, icyl, cyl1, cyl2;
public MadBoxBitObj()
{
super();
pole1 = new TransformObj
(
new CubeObj(),
new CombineMat(new ScaleMat(0.15f, 1.0f, 0.15f), new ShiftMat(-0.85f, 0f, -0.85f))
);
pole2 = new TransformObj
(
new CubeObj(),
new CombineMat(new ScaleMat(0.15f, 1.0f, 0.15f), new ShiftMat( 0.85f, 0f, -0.85f))
);
pole3 = new TransformObj
(
new CubeObj(),
new CombineMat(new ScaleMat(0.15f, 1.0f, 0.15f), new ShiftMat(-0.85f, 0f, 0.85f))
);
pole4 = new TransformObj
(
new CubeObj(),
new CombineMat(new ScaleMat(0.15f, 1.0f, 0.15f), new ShiftMat( 0.85f, 0f, 0.85f))
);
tpoint = new float[8][3];
spoint = new float[8][3];
point = new float[8][3];
face = new int[8][3];
numPoints = 8;
numFaces = 12;
point[0][0] = 1; point[0][1] = 1; point[0][2] = 1;
point[1][0] = 1; point[1][1] = 1; point[1][2] = -1;
point[2][0] = -1; point[2][1] = 1; point[2][2] = -1;
point[3][0] = -1; point[3][1] = 1; point[3][2] = 1;
point[4][0] = 1; point[4][1] = -1; point[4][2] = 1;
point[5][0] = 1; point[5][1] = -1; point[5][2] = -1;
point[6][0] = -1; point[6][1] = -1; point[6][2] = -1;
point[7][0] = -1; point[7][1] = -1; point[7][2] = 1;
face[0][0] = 2; face[0][1] = 6; face[0][2] = 5;
face[1][0] = 5; face[1][1] = 1; face[1][2] = 2;
face[2][0] = 3; face[2][1] = 7; face[2][2] = 6;
face[3][0] = 6; face[3][1] = 2; face[3][2] = 3;
face[4][0] = 7; face[4][1] = 3; face[4][2] = 0;
face[5][0] = 0; face[5][1] = 4; face[5][2] = 7;
face[6][0] = 5; face[6][1] = 4; face[6][2] = 0;
face[7][0] = 0; face[7][1] = 1; face[7][2] = 5;
}
public void update()
{
pole1.update();
pole2.update();
pole3.update();
pole4.update();
}
public void render(RenderBuffer buf, Mat m)
{
pole1.render(buf, m);
pole2.render(buf, m);
pole3.render(buf, m);
pole4.render(buf, m);
}
}
//---- MadBoxObj -------------------------------------------------------------//
class MadBoxObj extends Obj
{
Obj bit1, bit2, bit3;
public MadBoxObj()
{
super();
bit1 = new MadBoxBitObj();
bit2 = new TransformObj
(
new MadBoxBitObj(),
new RotateXMat(0.25f)
);
bit3 = new TransformObj
(
new MadBoxBitObj(),
new RotateZMat(0.25f)
);
}
public void update()
{
bit1.update();
bit2.update();
bit3.update();
}
public void render(RenderBuffer buf, Mat m)
{
bit1.render(buf, m);
bit2.render(buf, m);
bit3.render(buf, m);
}
}
//---- RenderIm --------------------------------------------------------------//
class RenderIm extends Im
{
Obj obj;
Mat mat = new Mat();
public RenderIm()
{
}
public RenderIm(Obj obj, int w, int h)
{
super(w, h);
System.out.println("Creating RenderIm("+obj+", "+w+", "+h+")");
this.obj = obj;
}
public void update()
{
obj.update();
obj.render(screen, mat);
}
public String toString()
{
return "RenderIm("+obj+", "+w+", "+h+")";
}
}
//---- CubeScene -------------------------------------------------------------//
public class CubeScene extends tinyptc
{
//---- DATA
int mouse_x = 0, mouse_y = 0;
int mouse_oldx = 0, mouse_oldy = 0;
boolean mouse_drag = false;
int mouse_changex = 0, mouse_changey = 0;
float start_time, time;
RenderBuffer screen;
RenderBuffer bg, cubes;
Obj obj;
Mat matShift;
RotateXMat matRot1;
RotateYMat matRot2;
RotateZMat matRot3;
RotateXMat matRot4;
Mat matFinal;
ScaleMat[] scale;
ShiftMat[] shift;
//---- startup
public void startup(int w, int h)
{
System.out.println("");
System.out.println("");
System.out.println("-- Applet Starts here --");
System.out.println("");
System.out.println("");
screen = new RenderBuffer(w, h);
bg = new RenderBuffer(w, h);
cubes = new RenderBuffer(w, h);
bg.clear(0x336699);
bg.xSkewCircle(190, 120, 180, 0.85, -0.2, 0x6699CC);
bg.xSkewCircle(190, 120, 150, 0.85, -0.2, 0x336699);
bg.xSkewCircle(190, 120, 120, 0.85, -0.2, 0x6699CC);
bg.xSkewCircle(190, 120, 90, 0.85, -0.2, 0x336699);
bg.xSkewCircle(190, 120, 60, 0.85, -0.2, 0x6699CC);
bg.xSkewCircle(190, 120, 30, 0.85, -0.2, 0x336699);
// Prepare object
scale = new ScaleMat[4];
shift = new ShiftMat[4];
for(int i=0; i<4; i++)
{
shift[i] = new ShiftMat(0, 0, 0);
scale[i] = new ScaleMat(0, 0, 0);
}
obj = new CombineObj
(
new CombineObj
(
new TransformObj
(
new MadBoxObj(),
new CombineMat(
scale[0],
shift[0]
)
),
new TransformObj
(
new CylinderObj(),
new CombineMat(
scale[1],
shift[1]
)
)
),
new CombineObj
(
new TransformObj
(
new CubeObj(),
new CombineMat(
scale[2],
shift[2]
)
),
new TransformObj
(
new MadBoxObj(),
new CombineMat(
scale[3],
shift[3]
)
)
)
);
// Prepare transformation
matShift = new ShiftMat(0, 0, 2.5f);
matRot1 = new RotateXMat(0.0f);
matRot2 = new RotateYMat(0.0f);
matRot3 = new RotateZMat(0.0f);
matRot4 = new RotateXMat(0.0f);
matFinal = new CombineMat
(
new CombineMat
(
matRot1,
new CombineMat
(
matRot2,
new CombineMat(matRot4, matRot3)
)
),
matShift
);
}
//---- render
public void render()
{
// screen.copy(bg);
screen.clear(0x336699);
screen.xSkewCircle(190, 120, 180, 0.85, -0.2, 0x6699CC);
screen.xSkewCircle(190, 120, 150, 0.85, -0.2, 0x336699);
screen.xSkewCircle(190, 120, 120, 0.85, -0.2, 0x6699CC);
screen.xSkewCircle(190, 120, 90, 0.85, -0.2, 0x336699);
screen.xSkewCircle(190, 120, 60, 0.85, -0.2, 0x6699CC);
screen.xSkewCircle(190, 120, 30, 0.85, -0.2, 0x336699);
/*
float x = 160 + 100*(float)Math.sin(3.14159*time/4.92);
float y = 120 + 100*(float)Math.cos(3.14159*time/6.87);
screen.circle(x, y, 37, 0xFFFFFF);
screen.circle(x, y, 32, 0x000000);
screen.circle(x, y, 30, 0xFFCC00);
*/
// screen.box(22, 212, 42, 232, 0xFFFFFF);
// screen.box( 8, 198, 32, 222, 0x000000);
// screen.box(22, 212, 42, 214, 0xFFFFFF);
screen.box(10, 200, 30, 220, 0xFFFFFF);
screen.box(24, 214, 40, 230, 0x000000);
//- Position
for(int i=0; i<4; i++)
{
float s = (float)(0.45 + 0.15 * Math.sin(3.14159*time/(i*0.7+4.82) + i*5.91));
scale[i].set(s, s, s);
float xx = (float)(0.7 * Math.sin(3.14159*time / (3.21+0.7*i) + i*3.11));
float yy = (float)(0.7 * Math.sin(3.14159*time / (4.49+0.4*i) + i*8.22));
float zz = (float)(0.7 * Math.sin(3.14159*time / (5.88+0.3*i) + i*1.33));
shift[i].set(xx, yy, zz);
}
//- Render boxes
cubes.clear(0);
cubes.clearZBuf();
matRot1.set(time / 46.16f);
matRot2.set(time / 53.81f);
matRot3.set(time / 38.32f);
matRot4.set(time / 39.63f);
matRot1.set(0.0f);
matRot2.set(0.0f);
matRot3.set(-0.001f*mouse_changex);
matRot4.set(-0.001f*mouse_changey);
obj.update();
obj.render(cubes, matFinal);
//- Cartoon effect
cubes.hilightEdges(0xFF000000);
//- Overlay boxes onto screen
screen.layer(cubes);
}
//---- main
public void main(int width, int height)
{
startup(width, height);
start_time = (float)System.currentTimeMillis()*0.001f;
while(true)
{
if(mouse_drag)
{
start_time = (float)System.currentTimeMillis()*0.001f - time;
}
else
{
time = (float)System.currentTimeMillis()*0.001f - start_time;
}
render();
update(screen.buf);
try { _thread.sleep(10); } catch(InterruptedException e) { return; }
}
}
public boolean mouseDown(Event e, int x, int y)
{
mouse_drag = true;
return true;
}
public boolean mouseUp(Event e, int x, int y)
{
mouse_drag = false;
return true;
}
public boolean mouseDrag(Event e, int x, int y)
{
mouse_x = x;
mouse_y = y;
mouse_changex += mouse_x-mouse_oldx;
mouse_changey += mouse_y-mouse_oldy;
mouse_oldx = x;
mouse_oldy = y;
return true;
}
}