Refactor and create helper utility functions.
Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
This commit is contained in:
parent
dfe6210836
commit
7b0467cc5d
@ -2,20 +2,80 @@ package sig;
|
|||||||
|
|
||||||
public class Matrix {
|
public class Matrix {
|
||||||
float[][] m = new float[4][4];
|
float[][] m = new float[4][4];
|
||||||
|
Matrix(){}
|
||||||
Matrix(float[][]m) {
|
Matrix(float[][]m) {
|
||||||
this.m=m;
|
this.m=m;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MultiplyMatrixVector(Vector i,Vector o,Matrix m) {
|
public final static Matrix IDENTITY = new Matrix(new float[][]{
|
||||||
o.x=i.x*m.m[0][0]+i.y*m.m[1][0]+i.z*m.m[2][0]+m.m[3][0];
|
{1,0,0,0},
|
||||||
o.y=i.x*m.m[0][1]+i.y*m.m[1][1]+i.z*m.m[2][1]+m.m[3][1];
|
{0,1,0,0},
|
||||||
o.z=i.x*m.m[0][2]+i.y*m.m[1][2]+i.z*m.m[2][2]+m.m[3][2];
|
{0,0,1,0},
|
||||||
float w=i.x*m.m[0][3]+i.y*m.m[1][3]+i.z*m.m[2][3]+m.m[3][3];
|
{0,0,0,1},
|
||||||
|
});
|
||||||
|
|
||||||
if (w!=0f) {
|
public static Vector MultiplyVector(Matrix m, Vector i) {
|
||||||
o.x/=w;
|
return new Vector(
|
||||||
o.y/=w;
|
i.x*m.m[0][0]+i.y*m.m[1][0]+i.z*m.m[2][0]+i.w*m.m[3][0],
|
||||||
o.z/=w;
|
i.x*m.m[0][1]+i.y*m.m[1][1]+i.z*m.m[2][1]+i.w*m.m[3][1],
|
||||||
|
i.x*m.m[0][2]+i.y*m.m[1][2]+i.z*m.m[2][2]+i.w*m.m[3][2],
|
||||||
|
i.x*m.m[0][3]+i.y*m.m[1][3]+i.z*m.m[2][3]+i.w*m.m[3][3]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Matrix MakeRotationX(float angle) {
|
||||||
|
return new Matrix(new float[][]{
|
||||||
|
{1,0,0,0,},
|
||||||
|
{0,(float)Math.cos(angle),(float)Math.sin(angle),0,},
|
||||||
|
{0,(float)-Math.sin(angle),(float)Math.cos(angle),0,},
|
||||||
|
{0,0,0,1,},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public static Matrix MakeRotationY(float angle) {
|
||||||
|
return new Matrix(new float[][]{
|
||||||
|
{(float)Math.cos(angle),0,(float)Math.sin(angle),0,},
|
||||||
|
{0,1,0,0,},
|
||||||
|
{(float)-Math.sin(angle),0,(float)Math.cos(angle),0,},
|
||||||
|
{0,0,0,1,},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public static Matrix MakeRotationZ(float angle) {
|
||||||
|
return new Matrix(new float[][]{
|
||||||
|
{(float)Math.cos(angle),(float)Math.sin(angle),0,0,},
|
||||||
|
{(float)-Math.sin(angle),(float)Math.cos(angle),0,0,},
|
||||||
|
{0,0,1,0,},
|
||||||
|
{0,0,0,1,},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public static Matrix MakeTranslation(float x,float y,float z) {
|
||||||
|
return new Matrix(new float[][]{
|
||||||
|
{1,0,0,0},
|
||||||
|
{0,1,0,0},
|
||||||
|
{0,0,1,0},
|
||||||
|
{x,y,z,1},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public static Matrix MakeProjection(float fov,float aspectRatio,float near,float far) {
|
||||||
|
float fFovRad = 1f/(float)Math.tan(fov*0.5f/180f*Math.PI);
|
||||||
|
return new Matrix(
|
||||||
|
new float[][]{
|
||||||
|
{aspectRatio*fFovRad,0,0,0},
|
||||||
|
{0,fFovRad,0,0},
|
||||||
|
{0,0,far/(far-near),1f},
|
||||||
|
{0,0,(-far*near)/(far-near),0f},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public static Matrix MultiplyMatrix(Matrix m1,Matrix m2) {
|
||||||
|
Matrix mm = new Matrix();
|
||||||
|
for (int c=0;c<4;c++) {
|
||||||
|
for (int r=0;r<4;r++) {
|
||||||
|
mm.m[r][c]=
|
||||||
|
m1.m[r][0]*m2.m[0][c]+
|
||||||
|
m1.m[r][1]*m2.m[1][c]+
|
||||||
|
m1.m[r][2]*m2.m[2][c]+
|
||||||
|
m1.m[r][3]*m2.m[3][c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,72 +88,49 @@ public class Panel extends JPanel implements Runnable {
|
|||||||
|
|
||||||
accumulatedTris.clear();
|
accumulatedTris.clear();
|
||||||
|
|
||||||
Matrix matRotZ = new Matrix(new float[][]{
|
Matrix matRotZ = Matrix.MakeRotationZ(fTheta),matRotX = Matrix.MakeRotationX(fTheta*0.5f);
|
||||||
{(float)Math.cos(fTheta),(float)Math.sin(fTheta),0,0,},
|
Matrix matTranslation = Matrix.MakeTranslation(0,0,16);
|
||||||
{(float)-Math.sin(fTheta),(float)Math.cos(fTheta),0,0,},
|
Matrix matWorld = Matrix.IDENTITY;
|
||||||
{0,0,1,0,},
|
matWorld = Matrix.MultiplyMatrix(matRotZ,matRotX);
|
||||||
{0,0,0,1,},
|
matWorld = Matrix.MultiplyMatrix(matWorld,matTranslation);
|
||||||
}),matRotX = new Matrix(new float[][]{
|
|
||||||
{1,0,0,0,},
|
|
||||||
{0,(float)Math.cos(fTheta*0.5f),(float)Math.sin(fTheta*0.5f),0,},
|
|
||||||
{0,(float)-Math.sin(fTheta*0.5f),(float)Math.cos(fTheta*0.5f),0,},
|
|
||||||
{0,0,0,1,},
|
|
||||||
});
|
|
||||||
fTheta+=0.01f;
|
fTheta+=0.01f;
|
||||||
|
|
||||||
for (Triangle t : SigRenderer.cube.triangles) {
|
for (Triangle t : SigRenderer.cube.triangles) {
|
||||||
Triangle triProjected = new Triangle(new Vector(),new Vector(),new Vector()),triTranslated=new Triangle(new Vector(),new Vector(),new Vector()),triRotatedZ=new Triangle(new Vector(),new Vector(),new Vector()),triRotatedZX=new Triangle(new Vector(),new Vector(),new Vector());
|
Triangle triProjected = new Triangle(),triTransformed=new Triangle();
|
||||||
|
|
||||||
|
triTransformed.A = Matrix.MultiplyVector(matWorld,t.A);
|
||||||
Matrix.MultiplyMatrixVector(t.A, triRotatedZ.A, matRotZ);
|
triTransformed.B = Matrix.MultiplyVector(matWorld,t.B);
|
||||||
Matrix.MultiplyMatrixVector(t.B, triRotatedZ.B, matRotZ);
|
triTransformed.C = Matrix.MultiplyVector(matWorld,t.C);
|
||||||
Matrix.MultiplyMatrixVector(t.C, triRotatedZ.C, matRotZ);
|
|
||||||
Matrix.MultiplyMatrixVector(triRotatedZ.A, triRotatedZX.A, matRotX);
|
|
||||||
Matrix.MultiplyMatrixVector(triRotatedZ.B, triRotatedZX.B, matRotX);
|
|
||||||
Matrix.MultiplyMatrixVector(triRotatedZ.C, triRotatedZX.C, matRotX);
|
|
||||||
|
|
||||||
|
|
||||||
triTranslated = (Triangle)triRotatedZX.clone();
|
|
||||||
triTranslated.A.z=triRotatedZX.A.z+6f;
|
|
||||||
triTranslated.B.z=triRotatedZX.B.z+6f;
|
|
||||||
triTranslated.C.z=triRotatedZX.C.z+6f;
|
|
||||||
|
|
||||||
Vector normal=new Vector(),line1=new Vector(),line2=new Vector();
|
Vector normal=new Vector(),line1=new Vector(),line2=new Vector();
|
||||||
line1.x=triTranslated.B.x-triTranslated.A.x;
|
line1 = Vector.subtract(triTransformed.B,triTransformed.A);
|
||||||
line1.y=triTranslated.B.y-triTranslated.A.y;
|
line2 = Vector.subtract(triTransformed.C,triTransformed.A);
|
||||||
line1.z=triTranslated.B.z-triTranslated.A.z;
|
|
||||||
line2.x=triTranslated.C.x-triTranslated.A.x;
|
|
||||||
line2.y=triTranslated.C.y-triTranslated.A.y;
|
|
||||||
line2.z=triTranslated.C.z-triTranslated.A.z;
|
|
||||||
|
|
||||||
normal.x=line1.y*line2.z-line1.z*line2.y;
|
normal = Vector.crossProduct(line1,line2);
|
||||||
normal.y=line1.z*line2.x-line1.x*line2.z;
|
normal = Vector.normalize(normal);
|
||||||
normal.z=line1.x*line2.y-line1.y*line2.x;
|
|
||||||
|
|
||||||
float l = (float)Math.sqrt(normal.x*normal.x+normal.y*normal.y+normal.z*normal.z);
|
Vector cameraRay = Vector.subtract(triTransformed.A,SigRenderer.vCamera);
|
||||||
normal.x/=l; normal.y/=l; normal.z/=l;
|
|
||||||
|
|
||||||
if (normal.x*(triTranslated.A.x-SigRenderer.vCamera.x)+
|
if (Vector.dotProduct(normal,cameraRay)<0) {
|
||||||
normal.y*(triTranslated.A.y-SigRenderer.vCamera.y)+
|
|
||||||
normal.z*(triTranslated.A.z-SigRenderer.vCamera.z)<0) {
|
|
||||||
|
|
||||||
Vector lightDir = new Vector(0,0,-1);
|
Vector lightDir = new Vector(0,0,-1);
|
||||||
l = (float)Math.sqrt(lightDir.x*lightDir.x+lightDir.y*lightDir.y+lightDir.z*lightDir.z);
|
lightDir = Vector.normalize(lightDir);
|
||||||
lightDir.x/=l; lightDir.y/=l; lightDir.z/=l;
|
|
||||||
|
|
||||||
float dp = Math.abs(normal.x*lightDir.x+normal.y*lightDir.y+normal.z*lightDir.z);
|
float dp = Math.max(0.1f,Vector.dotProduct(lightDir,normal));
|
||||||
|
|
||||||
Matrix.MultiplyMatrixVector(triTranslated.A, triProjected.A, SigRenderer.matProj);
|
triProjected.A = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.A);
|
||||||
Matrix.MultiplyMatrixVector(triTranslated.B, triProjected.B, SigRenderer.matProj);
|
triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.B);
|
||||||
Matrix.MultiplyMatrixVector(triTranslated.C, triProjected.C, SigRenderer.matProj);
|
triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.C);
|
||||||
triProjected.setColor(new Color(dp,dp,dp));
|
triProjected.setColor(new Color(dp,dp,dp));
|
||||||
|
|
||||||
triProjected.A.x+=1f;
|
triProjected.A = Vector.divide(triProjected.A, triProjected.A.w);
|
||||||
triProjected.A.y+=1f;
|
triProjected.B = Vector.divide(triProjected.B, triProjected.B.w);
|
||||||
triProjected.B.x+=1f;
|
triProjected.C = Vector.divide(triProjected.C, triProjected.C.w);
|
||||||
triProjected.B.y+=1f;
|
|
||||||
triProjected.C.x+=1f;
|
Vector viewOffset = new Vector(1,1,0);
|
||||||
triProjected.C.y+=1f;
|
triProjected.A = Vector.add(triProjected.A,viewOffset);
|
||||||
|
triProjected.B = Vector.add(triProjected.B,viewOffset);
|
||||||
|
triProjected.C = Vector.add(triProjected.C,viewOffset);
|
||||||
triProjected.A.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
triProjected.A.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
||||||
triProjected.A.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
triProjected.A.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
||||||
triProjected.B.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
triProjected.B.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
||||||
|
@ -33,14 +33,7 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
|
|||||||
public static float fFar = 1000f;
|
public static float fFar = 1000f;
|
||||||
public static float fFov = 90f;
|
public static float fFov = 90f;
|
||||||
public static float fAspectRatio = (float)SCREEN_HEIGHT/SCREEN_WIDTH;
|
public static float fAspectRatio = (float)SCREEN_HEIGHT/SCREEN_WIDTH;
|
||||||
public static float fFovRad = 1f/(float)Math.tan(fFov*0.5f/180f*Math.PI);
|
public static Matrix matProj = Matrix.MakeProjection(fFov,fAspectRatio,fNear,fFar);
|
||||||
public static Matrix matProj = new Matrix(
|
|
||||||
new float[][]{
|
|
||||||
{fAspectRatio*fFovRad,0,0,0},
|
|
||||||
{0,fFovRad,0,0},
|
|
||||||
{0,0,fFar/(fFar-fNear),1f},
|
|
||||||
{0,0,(-fFar*fNear)/(fFar-fNear),0f},
|
|
||||||
});
|
|
||||||
|
|
||||||
public static Vector vCamera = new Vector();
|
public static Vector vCamera = new Vector();
|
||||||
|
|
||||||
|
@ -4,6 +4,9 @@ import java.awt.Color;
|
|||||||
public class Triangle {
|
public class Triangle {
|
||||||
Vector A,B,C;
|
Vector A,B,C;
|
||||||
Color col = Color.WHITE;
|
Color col = Color.WHITE;
|
||||||
|
public Triangle() {
|
||||||
|
this(new Vector(),new Vector(),new Vector());
|
||||||
|
}
|
||||||
public Triangle(Vector A,Vector B,Vector C) {
|
public Triangle(Vector A,Vector B,Vector C) {
|
||||||
this.A=A;
|
this.A=A;
|
||||||
this.B=B;
|
this.B=B;
|
||||||
|
@ -1,17 +1,51 @@
|
|||||||
package sig;
|
package sig;
|
||||||
|
|
||||||
public class Vector {
|
public class Vector {
|
||||||
public float x,y,z;
|
public float x,y,z,w;
|
||||||
Vector() {
|
Vector() {
|
||||||
this(0,0,0);
|
this(0,0,0,1);
|
||||||
}
|
}
|
||||||
public Vector(float x,float y,float z) {
|
public Vector(float x,float y,float z) {
|
||||||
|
this(x,y,z,1);
|
||||||
|
}
|
||||||
|
public Vector(float x,float y,float z,float w) {
|
||||||
this.x=x;
|
this.x=x;
|
||||||
this.y=y;
|
this.y=y;
|
||||||
this.z=z;
|
this.z=z;
|
||||||
|
this.w=w;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected Object clone(){
|
protected Object clone(){
|
||||||
return new Vector(x,y,z);
|
return new Vector(x,y,z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vector add(Vector v1,Vector v2) {
|
||||||
|
return new Vector(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z);
|
||||||
|
}
|
||||||
|
public static Vector subtract(Vector v1,Vector v2) {
|
||||||
|
return new Vector(v1.x-v2.x,v1.y-v2.y,v1.z-v2.z);
|
||||||
|
}
|
||||||
|
public static Vector multiply(Vector v1,float k) {
|
||||||
|
return new Vector(v1.x*k,v1.y*k,v1.z*k);
|
||||||
|
}
|
||||||
|
public static Vector divide(Vector v1,float k) {
|
||||||
|
return new Vector(v1.x/k,v1.y/k,v1.z/k);
|
||||||
|
}
|
||||||
|
public static float dotProduct(Vector v1,Vector v2) {
|
||||||
|
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z;
|
||||||
|
}
|
||||||
|
public static float length(Vector v) {
|
||||||
|
return (float)Math.sqrt(dotProduct(v,v));
|
||||||
|
}
|
||||||
|
public static Vector normalize(Vector v) {
|
||||||
|
float l = length(v);
|
||||||
|
return new Vector(v.x/l,v.y/l,v.z/l);
|
||||||
|
}
|
||||||
|
public static Vector crossProduct(Vector v1,Vector v2) {
|
||||||
|
Vector v = new Vector();
|
||||||
|
v.x=v1.y*v2.z-v1.z*v2.y;
|
||||||
|
v.y=v1.z*v2.x-v1.x*v2.z;
|
||||||
|
v.z=v1.x*v2.y-v1.y*v2.x;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user