//
import java.awt.*;
import java.applet.*;
import java.awt.image.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.awt.Image;
import java.awt.Font;
//---- Z3D_Scene -------------------------------------------------------------//
class Z3D_Scene
{
//- Screen data
int buf[];
int w, h;
int clip_x1, clip_y1, clip_x2, clip_y2;
int cx, cy;
float scale;
//- Render options
boolean wireframe = false;
boolean wireframe_changed = false;
boolean wireframe_new = false;
//- Traingle data
float tri_x1, tri_y1, tri_z1, tri_u1, tri_v1;
float tri_x2, tri_y2, tri_z2, tri_u2, tri_v2;
float tri_x3, tri_y3, tri_z3, tri_u3, tri_v3;
//- ZN Logo (210x18)
int[] zn_add;
int[] zn_mul;
//- Orientation
float rx=0, ry=0, drx=0, dry=0;
boolean rchanged = true;
//- 3D Object
int[][] face;
float[][] point;
int[] factex;
int[][] tex;
float[][] tpoint;
float[][] spoint;
int numPoints, numFaces;
//---- Scene
public Z3D_Scene(Applet applet, int[] buf, int w, int h)
{
this.w = w;
this.h = h;
this.buf = buf;
clip_x1 = 0;
clip_y1 = 0;
clip_x2 = w;
clip_y2 = h;
cx = w >> 1;
cy = h >> 1;
scale = w*0.6f;
//- Create object
// Basic object
point = new float[8][5];
face = new int[12][4];
numPoints = 8;
numFaces = 6;
point[0][0] = 1; point[0][1] = 1; point[0][2] = 1; point[0][3] = 0; point[0][4] = 1; // u & v not done yet!
point[1][0] = 1; point[1][1] = 1; point[1][2] = -1; point[1][3] = 0; point[1][4] = 0;
point[2][0] = -1; point[2][1] = 1; point[2][2] = -1; point[2][3] = 0; point[2][4] = 0;
point[3][0] = -1; point[3][1] = 1; point[3][2] = 1; point[3][3] = 0; point[3][4] = 0;
point[4][0] = 1; point[4][1] = -1; point[4][2] = 1; point[4][3] = 0; point[4][4] = 0;
point[5][0] = 1; point[5][1] = -1; point[5][2] = -1; point[5][3] = 0; point[5][4] = 0;
point[6][0] = -1; point[6][1] = -1; point[6][2] = -1; point[6][3] = 0; point[6][4] = 0;
point[7][0] = -1; point[7][1] = -1; point[7][2] = 1; point[7][3] = 0; point[7][4] = 0;
face[0][0] = 3; face[0][1] = 0; face[0][2] = 1; face[0][3] = 2; // 0
face[1][0] = 2; face[1][1] = 1; face[1][2] = 5; face[1][3] = 6; // 1
face[2][0] = 3; face[2][1] = 2; face[2][2] = 6; face[2][3] = 7; // 2
face[3][0] = 6; face[3][1] = 5; face[3][2] = 4; face[3][3] = 7; // 3
face[4][0] = 0; face[4][1] = 3; face[4][2] = 7; face[4][3] = 4; // 4
face[5][0] = 1; face[5][1] = 0; face[5][2] = 4; face[5][3] = 5; // 5
// Load textures
tex = new int[6][256*256];
int i, j, k;
for(k=0; k<6; k++)
for(j=0; j<256; j++)
for(i=0; i<256; i++)
tex[k][(j<<8)+i] = (i^j) << (k*2);
tex[0] = getPixels(applet, "top.jpg", 256, 256);
tex[1] = getPixels(applet, "front.jpg", 256, 256);
tex[2] = getPixels(applet, "right.jpg", 256, 256);
tex[3] = getPixels(applet, "bottom.jpg", 256, 256);
tex[4] = getPixels(applet, "back.jpg", 256, 256);
tex[5] = getPixels(applet, "left.jpg", 256, 256);
// Working data
tpoint = new float[8][5];
spoint = new float[8][5];
// ZN Logo
zn_add = getPixels(applet, "zn_add.jpg", 210, 18);
zn_mul = getPixels(applet, "zn_mul.jpg", 210, 18);
}
//---- getPixels
private int[] getPixels(Applet applet, String ImageFile, int width, int height)
{
Image TempImage = applet.getImage(applet.getDocumentBase(),ImageFile);
applet.showStatus("Grabbing Pixels...");
int TempPixel[]=new int [width*height];
PixelGrabber pg= new PixelGrabber(TempImage,0,0,width,height,TempPixel,0,width);
try
{
pg.grabPixels();
}
catch (InterruptedException e)
{
}
return TempPixel;
}
//---- setRotation
public void addRotation(float rx, float ry)
{
drx -= rx*0.01;
dry += ry*0.01;
rchanged = true;
}
//---- setWireframe
public void setWireframe(boolean wf)
{
wireframe_new = wf;
wireframe_changed = true;
}
//---- render
public void render()
{
if(rchanged)
{
rx += drx;
ry += dry;
drx = dry = 0;
rchanged = false;
}
else
{
return;
}
if(wireframe_changed)
{
wireframe_changed = false;
wireframe = wireframe_new;
}
//- Clear buffer
idx3d_Math.clearBuffer(buf, 0x336699);
//- Render object
int i, j;
// rx = 0.0f;
// ry += 0.01f;
// Transform
float x, y, z;
idx3d_Matrix m;
m = new idx3d_Matrix();
m.rotateSelf(rx, 0, 0);
m.rotateSelf(0, ry, 0);
// m.shift(0, 0, 2);
// Render triangles
scale = w*1/8;
float hp = 3.14159f * 0.5f;
// front
transformPoints(m);
clip_x1 = w*1/4; clip_y1 = h*1/3;
clip_x2 = w*2/4; clip_y2 = h*2/3;
cx = (clip_x1+clip_x2)>>1;
cy = (clip_y1+clip_y2)>>1;
for(i=0; i<numFaces; i++) drawSquare(i);
// top
m.rotate(-hp, 0, 0);
transformPoints(m);
clip_x1 = w*1/4; clip_y1 = h*0/3;
clip_x2 = w*2/4; clip_y2 = h*1/3;
cx = (clip_x1+clip_x2)>>1;
cy = (clip_y1+clip_y2)>>1;
for(i=0; i<numFaces; i++) drawSquare(i);
// bottom
m.rotate(hp, 0, 0);
m.rotate(hp, 0, 0);
transformPoints(m);
clip_x1 = w*1/4; clip_y1 = h*2/3;
clip_x2 = w*2/4; clip_y2 = h*3/3;
cx = (clip_x1+clip_x2)>>1;
cy = (clip_y1+clip_y2)>>1;
for(i=0; i<numFaces; i++) drawSquare(i);
// left
m.rotate(-hp, 0, 0);
m.rotate(0, hp, 0);
transformPoints(m);
clip_x1 = w*0/4; clip_y1 = h*1/3;
clip_x2 = w*1/4; clip_y2 = h*2/3;
cx = (clip_x1+clip_x2)>>1;
cy = (clip_y1+clip_y2)>>1;
for(i=0; i<numFaces; i++) drawSquare(i);
// back
m.rotate(0, hp, 0);
transformPoints(m);
clip_x1 = w*3/4; clip_y1 = h*1/3;
clip_x2 = w*4/4; clip_y2 = h*2/3;
cx = (clip_x1+clip_x2)>>1;
cy = (clip_y1+clip_y2)>>1;
for(i=0; i<numFaces; i++) drawSquare(i);
// right
m.rotate(0, hp, 0);
transformPoints(m);
clip_x1 = w*2/4; clip_y1 = h*1/3;
clip_x2 = w*3/4; clip_y2 = h*2/3;
cx = (clip_x1+clip_x2)>>1;
cy = (clip_y1+clip_y2)>>1;
for(i=0; i<numFaces; i++) drawSquare(i);
//- Put ZN logo
int o1 = 0;
int o2 = w*(h-18);
int r, g, b, zm, za;
for(j=0; j<18; j++)
{
for(i=0; i<210; i++)
{
r = (buf[o2] >> 16)&255;
g = (buf[o2] >> 8 )&255;
b = (buf[o2] )&255;
zm = zn_mul[o1] & 255;
za = zn_add[o1] & 255;
r = ((r * zm)>>8);
g = ((g * zm)>>8);
b = ((b * zm)>>8);
r = ((za>>8) + (r)*(255-za))>>8;
g = ((za>>8) + (g)*(255-za))>>8;
b = ((za>>8) + (b)*(255-za))>>8;
if(r > 255) r = 255;
if(g > 255) g = 255;
if(b > 255) b = 255;
if(r < 0) r = 0;
if(g < 0) g = 0;
if(b < 0) b = 0;
buf[o2] = (r<<16)+(g<<8)+(b) + zn_add[o1];
o1 ++;
o2 ++;
}
o2 += w-210;
}
}
void transformPoints(idx3d_Matrix m)
{
int i;
float x, y, z;
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;
}
}
void renderQuad(int texnum, float[] p1, float[] p2, float[] p3, float[] p4)
{
tri_x1 = p1[0];
tri_y1 = p1[1];
tri_z1 = p1[2];
tri_u1 = p1[3];
tri_v1 = p1[4];
tri_x2 = p2[0];
tri_y2 = p2[1];
tri_z2 = p2[2];
tri_u2 = p2[3];
tri_v2 = p2[4];
tri_x3 = p3[0];
tri_y3 = p3[1];
tri_z3 = p3[2];
tri_u3 = p3[3];
tri_v3 = p3[4];
tri_persp(texnum);
tri_x1 = p3[0];
tri_y1 = p3[1];
tri_z1 = p3[2];
tri_u1 = p3[3];
tri_v1 = p3[4];
tri_x2 = p4[0];
tri_y2 = p4[1];
tri_z2 = p4[2];
tri_u2 = p4[3];
tri_v2 = p4[4];
tri_x3 = p1[0];
tri_y3 = p1[1];
tri_z3 = p1[2];
tri_u3 = p1[3];
tri_v3 = p1[4];
tri_persp(texnum);
}
void interpolate(float[] p1, float[] p2, float a, float[] result)
{
for(int i=0; i<5; i++)
{
result[i] = p1[i] * (1.0f-a) + p2[i] * a;
}
}
void drawSquare(int index)
{
float[] p1 = tpoint[face[index][0]];
float[] p2 = tpoint[face[index][1]];
float[] p3 = tpoint[face[index][2]];
float[] p4 = tpoint[face[index][3]];
float[] ip1 = new float[5];
float[] ip2 = new float[5];
float[] ip3 = new float[5];
float[] ip4 = new float[5];
float[] tp1 = new float[5];
float[] tp2 = new float[5];
//- Texture co-ords
p1[3] = 0; p1[4] = 0;
p2[3] = 256; p2[4] = 0;
p3[3] = 256; p3[4] = 256;
p4[3] = 0; p4[4] = 256;
//- Subdivide into 4x4
int i, j;
for(j=0; j<4; j++)
{
for(i=0; i<4; i++)
{
// Calculate square
interpolate(p1, p2, (i)*0.25f, tp1);
interpolate(p4, p3, (i)*0.25f, tp2);
interpolate(tp1, tp2, (j)*0.25f, ip1);
interpolate(p1, p2, (i+1)*0.25f, tp1);
interpolate(p4, p3, (i+1)*0.25f, tp2);
interpolate(tp1, tp2, j*0.25f, ip2);
interpolate(p1, p2, (i+1)*0.25f, tp1);
interpolate(p4, p3, (i+1)*0.25f, tp2);
interpolate(tp1, tp2, (j+1)*0.25f, ip3);
interpolate(p1, p2, (i)*0.25f, tp1);
interpolate(p4, p3, (i)*0.25f, tp2);
interpolate(tp1, tp2, (j+1)*0.25f, ip4);
// Screen co-ords
ip1[0] = cx + scale * ip1[0] / ip1[2];
ip1[1] = cy - scale * ip1[1] / ip1[2];
ip2[0] = cx + scale * ip2[0] / ip2[2];
ip2[1] = cy - scale * ip2[1] / ip2[2];
ip3[0] = cx + scale * ip3[0] / ip3[2];
ip3[1] = cy - scale * ip3[1] / ip3[2];
ip4[0] = cx + scale * ip4[0] / ip4[2];
ip4[1] = cy - scale * ip4[1] / ip4[2];
// render square
renderQuad(index, ip1, ip2, ip3, ip4);
}
}
}
//---- tri_col
public void tri_col(int col)
{
float t;
int x, y, y1, y2, x1, x2, o, ti;
float c1, c2;
float dc;
// Don't draw if backfacing
if((tri_x2-tri_x1)*(tri_y3-tri_y1) > (tri_x3-tri_x1)*(tri_y2-tri_y1)) return;
// Sort points
if(tri_y1 > tri_y2) { t=tri_y2; tri_y2=tri_y1; tri_y1=t; t=tri_x2; tri_x2=tri_x1; tri_x1=t; }
if(tri_y2 > tri_y3) { t=tri_y3; tri_y3=tri_y2; tri_y2=t; t=tri_x3; tri_x3=tri_x2; tri_x2=t; }
if(tri_y1 > tri_y2) { t=tri_y2; tri_y2=tri_y1; tri_y1=t; t=tri_x2; tri_x2=tri_x1; tri_x1=t; }
// Clip top point to screen and pixel
y1 = (int)tri_y1; if(y1>=h) return; if(y1<0) y1 = 0;
y2 = (int)tri_y3; if(y2<0) return; if(y2>h) y2 = h;
c1=0; c2=0;
for(y=y1-1; y<y2+1; y++)
{
if(y >= tri_y1 && y < tri_y3)
{
if(y >= tri_y1 && y < tri_y2)
{
x1 = (int)(tri_x1 + (tri_x3-tri_x1) * (y-tri_y1) / (tri_y3-tri_y1));
x2 = (int)(tri_x1 + (tri_x2-tri_x1) * (y-tri_y1) / (tri_y2-tri_y1));
}
else
{
x1 = (int)(tri_x1 + (tri_x3-tri_x1) * (y-tri_y1) / (tri_y3-tri_y1));
x2 = (int)(tri_x2 + (tri_x3-tri_x2) * (y-tri_y2) / (tri_y3-tri_y2));
}
if(x1 > x2)
{
ti = x2; x2 = x1; x1 = ti;
t = c2; c2 = c1; c1 = t;
}
if(x1 < 0) x1 = 0;
if(x2 > w) x2 = w;
if(x2 > x1) {
dc = (c2-c1)/(x2-x1);
o = y*w + x1;
for(x = x1; x < x2; x ++) buf[o++] = col;
}
}
}
}
//---- tri_tex
public void tri_tex(int texnum)
{
int[] tex = this.tex[texnum];
float t;
int x, y;
int x1, x2, y1, y2;
int o, ti;
float u1, v1, u2, v2;
float du, dv;
// Don't draw if backfacing
if((tri_x2-tri_x1)*(tri_y3-tri_y1) > (tri_x3-tri_x1)*(tri_y2-tri_y1)) return;
// Sort points
if(tri_y1 > tri_y2)
{
t=tri_x2; tri_x2=tri_x1; tri_x1=t;
t=tri_y2; tri_y2=tri_y1; tri_y1=t;
t=tri_u2; tri_u2=tri_u1; tri_u1=t;
t=tri_v2; tri_v2=tri_v1; tri_v1=t;
}
if(tri_y2 > tri_y3)
{
t=tri_x3; tri_x3=tri_x2; tri_x2=t;
t=tri_y3; tri_y3=tri_y2; tri_y2=t;
t=tri_u3; tri_u3=tri_u2; tri_u2=t;
t=tri_v3; tri_v3=tri_v2; tri_v2=t;
}
if(tri_y1 > tri_y2)
{
t=tri_x2; tri_x2=tri_x1; tri_x1=t;
t=tri_y2; tri_y2=tri_y1; tri_y1=t;
t=tri_u2; tri_u2=tri_u1; tri_u1=t;
t=tri_v2; tri_v2=tri_v1; tri_v1=t;
}
// Clip top point to screen and pixel
y1 = (int)tri_y1; if(y1>=h) return; if(y1<0) y1 = 0;
y2 = (int)tri_y3; if(y2<0) return; if(y2>h) y2 = h;
u1 = 0; v1 = 0; u2 = 0; v2 = 0;
for(y=y1-1; y<y2+1; y++)
{
if(y >= tri_y1 && y < tri_y3)
{
if(y >= tri_y1 && y < tri_y2)
{
x1 = (int)(tri_x1 + (tri_x3-tri_x1) * (y-tri_y1) / (tri_y3-tri_y1));
x2 = (int)(tri_x1 + (tri_x2-tri_x1) * (y-tri_y1) / (tri_y2-tri_y1));
u1 = (tri_u1 + (tri_u3-tri_u1) * (y-tri_y1) / (tri_y3-tri_y1));
u2 = (tri_u1 + (tri_u2-tri_u1) * (y-tri_y1) / (tri_y2-tri_y1));
v1 = (tri_v1 + (tri_v3-tri_v1) * (y-tri_y1) / (tri_y3-tri_y1));
v2 = (tri_v1 + (tri_v2-tri_v1) * (y-tri_y1) / (tri_y2-tri_y1));
}
else
{
x1 = (int)(tri_x1 + (tri_x3-tri_x1) * (y-tri_y1) / (tri_y3-tri_y1));
x2 = (int)(tri_x2 + (tri_x3-tri_x2) * (y-tri_y2) / (tri_y3-tri_y2));
u1 = (tri_u1 + (tri_u3-tri_u1) * (y-tri_y1) / (tri_y3-tri_y1));
u2 = (tri_u2 + (tri_u3-tri_u2) * (y-tri_y2) / (tri_y3-tri_y2));
v1 = (tri_v1 + (tri_v3-tri_v1) * (y-tri_y1) / (tri_y3-tri_y1));
v2 = (tri_v2 + (tri_v3-tri_v2) * (y-tri_y2) / (tri_y3-tri_y2));
}
if(x1 > x2)
{
ti = x2; x2 = x1; x1 = ti;
t = u2; u2 = u1; u1 = t;
t = v2; v2 = v1; v1 = t;
}
if(x1 < 0) x1 = 0;
if(x2 > w) x2 = w;
if(x2 > x1) {
du = (u2-u1)/(x2-x1);
dv = (v2-v1)/(x2-x1);
o = y*w + x1;
for(x = x1; x < x2; x ++)
{
ti = (((int)v1)<<8) + ((int)u1);
ti = (int)u1;
ti = (ti<<16)+(ti<<8)+ti;
buf[o++] = ti;//tex[ti];
u1 += du;
v1 += dv;
}
}
}
}
}
public void tri_persp(int texnum)
{
if(tri_z1 < 0) return;
if(tri_z2 < 0) return;
if(tri_z3 < 0) return;
int[] tex = this.tex[texnum];
tri_u1 = 256-tri_u1;
tri_u2 = 256-tri_u2;
tri_u3 = 256-tri_u3;
int i, j;
// Don't draw if backfacing
// if((tri_x2-tri_x1)*(tri_y3-tri_y1) < (tri_x3-tri_x1)*(tri_y2-tri_y1)) return;
//- Sort points
float t;
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_z1; tri_z1 = tri_z2; tri_z2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
if(tri_y3 < tri_y2)
{
t = tri_x2; tri_x2 = tri_x3; tri_x3 = t;
t = tri_y2; tri_y2 = tri_y3; tri_y3 = t;
t = tri_z2; tri_z2 = tri_z3; tri_z3 = t;
t = tri_u2; tri_u2 = tri_u3; tri_u3 = t;
t = tri_v2; tri_v2 = tri_v3; tri_v3 = t;
}
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_z1; tri_z1 = tri_z2; tri_z2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
//- Divide by z to do perspective correction
tri_u1 /= tri_z1; tri_u2 /= tri_z2; tri_u3 /= tri_z3;
tri_v1 /= tri_z1; tri_v2 /= tri_z2; tri_v3 /= tri_z3;
tri_z1 = 1.0f/tri_z1; tri_z2 = 1.0f/tri_z2; tri_z3 = 1.0f/tri_z3;
//- Work out deltas along edges
float dx12 = (tri_x2-tri_x1)/(tri_y2-tri_y1), dx23 = (tri_x3-tri_x2)/(tri_y3-tri_y2), dx13 = (tri_x3-tri_x1)/(tri_y3-tri_y1);
float dz12 = (tri_z2-tri_z1)/(tri_y2-tri_y1), dz23 = (tri_z3-tri_z2)/(tri_y3-tri_y2), dz13 = (tri_z3-tri_z1)/(tri_y3-tri_y1);
float du12 = (tri_u2-tri_u1)/(tri_y2-tri_y1), du23 = (tri_u3-tri_u2)/(tri_y3-tri_y2), du13 = (tri_u3-tri_u1)/(tri_y3-tri_y1);
float dv12 = (tri_v2-tri_v1)/(tri_y2-tri_y1), dv23 = (tri_v3-tri_v2)/(tri_y3-tri_y2), dv13 = (tri_v3-tri_v1)/(tri_y3-tri_y1);
//- Round to pixel and clip to top & bottom of screen
int y1 = (int)tri_y1; if(y1 < tri_y1) y1++;
int y2 = (int)tri_y2; if(y2 < tri_y2) y2++;
int y3 = (int)tri_y3; if(y3 < tri_y3) y3++;
if(y1 < clip_y1) y1 = clip_y1;
if(y2 < clip_y1) y2 = clip_y1;
if(y3 < clip_y1) y3 = clip_y1;
if(y1 > clip_y2) y1 = clip_y2;
if(y2 > clip_y2) y2 = clip_y2;
if(y3 > clip_y2) y3 = clip_y2;
if(y3 <= y1) return;
//- Calculate horizontal and vertical deltas for parameters
float d = (tri_x3-tri_x1)*(tri_y2-tri_y1) - (tri_y3-tri_y1)*(tri_x2-tri_x1);
float dzx = ( (tri_y2-tri_y1)*(tri_z3-tri_z1) + (tri_y1-tri_y3)*(tri_z2-tri_z1) ) / d;
float dzy = ( (tri_x1-tri_x2)*(tri_z3-tri_z1) + (tri_x3-tri_x1)*(tri_z2-tri_z1) ) / d;
float dux = ( (tri_y2-tri_y1)*(tri_u3-tri_u1) + (tri_y1-tri_y3)*(tri_u2-tri_u1) ) / d;
float duy = ( (tri_x1-tri_x2)*(tri_u3-tri_u1) + (tri_x3-tri_x1)*(tri_u2-tri_u1) ) / d;
float dvx = ( (tri_y2-tri_y1)*(tri_v3-tri_v1) + (tri_y1-tri_y3)*(tri_v2-tri_v1) ) / d;
float dvy = ( (tri_x1-tri_x2)*(tri_v3-tri_v1) + (tri_x3-tri_x1)*(tri_v2-tri_v1) ) / d;
//- See if we need to flip triangle horizontally
boolean side13onleft = dx13 < dx12;
//- Draw top of triangle
float xa, xb, dxa, dxb;
if(side13onleft)
{
xa = tri_x1 + dx13 * (y1-tri_y1);
xb = tri_x1 + dx12 * (y1-tri_y1);
dxa = dx13;
dxb = dx12;
}
else
{
xa = tri_x1 + dx12 * (y1-tri_y1);
xb = tri_x1 + dx13 * (y1-tri_y1);
dxa = dx12;
dxb = dx13;
}
float zl = tri_z1 - tri_x1*dzx + (y1-tri_y1)*dzy;
float ul = tri_u1 - tri_x1*dux + (y1-tri_y1)*duy;
float vl = tri_v1 - tri_x1*dvx + (y1-tri_y1)*dvy;
for(j=y1; j<y2; j++)
{
int xai = (int)xa; if(xai < xa) xai++;
int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
float z = zl + xai*dzx;
float u = ul + xai*dux;
float v = vl + xai*dvx;
int o = j*w+xai;
for(i=xai; i<xbi; i++)
{
buf[o++] = tex[ ( (((int)(v/z))<<8) + ((int)(u/z)) ) & 0xFFFF ];//(((int)u)<<16)+(((int)v)<<8);
z += dzx;
u += dux;
v += dvx;
}
xa += dxa; xb += dxb;
zl += dzy;
ul += duy;
vl += dvy;
}
//- Draw bottom of triangle
if(side13onleft)
{
xb = tri_x2 + dx23 * (y2-tri_y2);
dxb = dx23;
}
else
{
xa = tri_x2 + dx23 * (y2-tri_y2);
dxa = dx23;
}
for(j=y2; j<y3; j++)
{
int xai = (int)xa; if(xai < xa) xai++;
int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
float z = zl + xai*dzx;
float u = ul + xai*dux;
float v = vl + xai*dvx;
int o = j*w+xai;
for(i=xai; i<xbi; i++)
{
buf[o++] = tex[ ( (((int)(v/z))<<8) + ((int)(u/z)) ) & 0xFFFF ];//(((int)u)<<16)+(((int)v)<<8);
z += dzx;
u += dux;
v += dvx;
}
xa += dxa; xb += dxb;
zl += dzy;
ul += duy;
vl += dvy;
}
}
}
//---- House -----------------------------------------------------------------//
public class House extends tinyptc
{
//- Data
int rx, ry;
Z3D_Scene scene;
//- Mouse data
int mouse_x = 0, mouse_y = 0;
int mouse_oldx = 0, mouse_oldy = 0;
boolean mouse_drag = true;
int mouse_changex = 0, mouse_changey = 0;
//- Main code
public void main(int width, int height)
{
int size = width * height;
int buf[] = new int[size];
int seed = 0x12345;
scene = new Z3D_Scene(this, buf, width, height);
while (true)
{
scene.addRotation(mouse_changey, mouse_changex);
mouse_changex = 0;
mouse_changey = 0;
scene.render();
update(buf);
// while(mouse_changex == 0 && mouse_changey == 0);
}
}
public boolean mouseDown(Event evt, int x, int y)
{
mouse_oldx = x;
mouse_oldy = y;
mouse_x = x;
mouse_y = y;
mouse_drag = true;
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;
}
public boolean mouseUp(Event evt, int x, int y)
{
mouse_drag = false;
return true;
}
}