Fixing display bugs.
Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
This commit is contained in:
parent
344e91502d
commit
129d0e71b1
@ -14,7 +14,7 @@ public class Matrix {
|
|||||||
{0,0,0,1},
|
{0,0,0,1},
|
||||||
});
|
});
|
||||||
|
|
||||||
public static Vector MultiplyVector(Matrix m, Vector i) {
|
public static Vector MultiplyVector(Matrix m, Vector i) {
|
||||||
return new Vector(
|
return new Vector(
|
||||||
i.x*m.m[0][0]+i.y*m.m[1][0]+i.z*m.m[2][0]+i.w*m.m[3][0],
|
i.x*m.m[0][0]+i.y*m.m[1][0]+i.z*m.m[2][0]+i.w*m.m[3][0],
|
||||||
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][1]+i.y*m.m[1][1]+i.z*m.m[2][1]+i.w*m.m[3][1],
|
||||||
@ -78,4 +78,32 @@ public class Matrix {
|
|||||||
}
|
}
|
||||||
return mm;
|
return mm;
|
||||||
}
|
}
|
||||||
|
public static Matrix PointAt(Vector pos,Vector target,Vector up) {
|
||||||
|
Vector newForward = Vector.subtract(target,pos);
|
||||||
|
newForward = Vector.normalize(newForward);
|
||||||
|
|
||||||
|
Vector a = Vector.multiply(newForward,Vector.dotProduct(up,newForward));
|
||||||
|
Vector newUp = Vector.subtract(up,a);
|
||||||
|
newUp = Vector.normalize(newUp);
|
||||||
|
|
||||||
|
Vector newRight = Vector.crossProduct(newUp,newForward);
|
||||||
|
|
||||||
|
return new Matrix(new float[][]{
|
||||||
|
{newRight.x,newRight.y,newRight.z,0},
|
||||||
|
{newUp.x,newUp.y,newUp.z,0},
|
||||||
|
{newForward.x,newForward.y,newForward.z,0},
|
||||||
|
{pos.x,pos.y,pos.z,1},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public static Matrix QuickInverse(Matrix m) {
|
||||||
|
Matrix mm = new Matrix();
|
||||||
|
mm.m[0][0]=m.m[0][0];mm.m[0][1]=m.m[1][0];mm.m[0][2]=m.m[2][0];mm.m[0][3]=0;
|
||||||
|
mm.m[1][0]=m.m[0][1];mm.m[1][1]=m.m[1][1];mm.m[1][2]=m.m[2][1];mm.m[1][3]=0;
|
||||||
|
mm.m[2][0]=m.m[0][2];mm.m[2][1]=m.m[1][2];mm.m[2][2]=m.m[2][2];mm.m[2][3]=0;
|
||||||
|
mm.m[3][0]=-(m.m[3][0]*mm.m[0][0]+m.m[3][1]*mm.m[1][0]+m.m[3][2]*mm.m[2][0]);
|
||||||
|
mm.m[3][1]=-(m.m[3][0]*mm.m[0][1]+m.m[3][1]*mm.m[1][1]+m.m[3][2]*mm.m[2][1]);
|
||||||
|
mm.m[3][2]=-(m.m[3][0]*mm.m[0][2]+m.m[3][1]*mm.m[1][2]+m.m[3][2]*mm.m[2][2]);
|
||||||
|
mm.m[3][3]=1;
|
||||||
|
return mm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,15 +88,23 @@ public class Panel extends JPanel implements Runnable {
|
|||||||
|
|
||||||
accumulatedTris.clear();
|
accumulatedTris.clear();
|
||||||
|
|
||||||
Matrix matRotZ = Matrix.MakeRotationZ(fTheta),matRotX = Matrix.MakeRotationX(fTheta*0.5f);
|
Matrix matRotZ = Matrix.MakeRotationZ(fTheta*0.5f),matRotX = Matrix.MakeRotationX(fTheta);
|
||||||
Matrix matTranslation = Matrix.MakeTranslation(0,0,6);
|
Matrix matTranslation = Matrix.MakeTranslation(0,0,6);
|
||||||
Matrix matWorld = Matrix.IDENTITY;
|
Matrix matWorld = Matrix.IDENTITY;
|
||||||
matWorld = Matrix.MultiplyMatrix(matRotZ,matRotX);
|
matWorld = Matrix.MultiplyMatrix(matRotZ,matRotX);
|
||||||
matWorld = Matrix.MultiplyMatrix(matWorld,matTranslation);
|
matWorld = Matrix.MultiplyMatrix(matWorld,matTranslation);
|
||||||
fTheta+=0.01f;
|
|
||||||
|
Vector vUp = new Vector(0,1,0);
|
||||||
|
Vector vTarget = new Vector(0,0,1);
|
||||||
|
Matrix matCameraRot = Matrix.MakeRotationY(SigRenderer.yaw);
|
||||||
|
SigRenderer.vLookDir = Matrix.MultiplyVector(matCameraRot,vTarget);
|
||||||
|
vTarget = Vector.add(SigRenderer.vCamera,SigRenderer.vLookDir);
|
||||||
|
|
||||||
|
Matrix matCamera = Matrix.PointAt(SigRenderer.vCamera, vTarget, vUp);
|
||||||
|
Matrix matView = Matrix.QuickInverse(matCamera);
|
||||||
|
|
||||||
for (Triangle t : SigRenderer.cube.triangles) {
|
for (Triangle t : SigRenderer.cube.triangles) {
|
||||||
Triangle triProjected = new Triangle(),triTransformed=new Triangle();
|
Triangle triProjected = new Triangle(),triTransformed=new Triangle(),triViewed=new Triangle();
|
||||||
|
|
||||||
triTransformed.A = Matrix.MultiplyVector(matWorld,t.A);
|
triTransformed.A = Matrix.MultiplyVector(matWorld,t.A);
|
||||||
triTransformed.B = Matrix.MultiplyVector(matWorld,t.B);
|
triTransformed.B = Matrix.MultiplyVector(matWorld,t.B);
|
||||||
@ -118,27 +126,44 @@ public class Panel extends JPanel implements Runnable {
|
|||||||
|
|
||||||
float dp = Math.max(0.1f,Vector.dotProduct(lightDir,normal));
|
float dp = Math.max(0.1f,Vector.dotProduct(lightDir,normal));
|
||||||
|
|
||||||
triProjected.A = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.A);
|
triViewed.A = Matrix.MultiplyVector(matView,triTransformed.A);
|
||||||
triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.B);
|
triViewed.B = Matrix.MultiplyVector(matView,triTransformed.B);
|
||||||
triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.C);
|
triViewed.C = Matrix.MultiplyVector(matView,triTransformed.C);
|
||||||
triProjected.setColor(new Color(dp,dp,dp));
|
|
||||||
|
|
||||||
triProjected.A = Vector.divide(triProjected.A, triProjected.A.w);
|
int clippedTriangles = 0;
|
||||||
triProjected.B = Vector.divide(triProjected.B, triProjected.B.w);
|
Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()};
|
||||||
triProjected.C = Vector.divide(triProjected.C, triProjected.C.w);
|
|
||||||
|
|
||||||
Vector viewOffset = new Vector(1,1,0);
|
clippedTriangles = Triangle.ClipAgainstPlane(new Vector(0,0,1),new Vector(0,0,1), triViewed, clipped);
|
||||||
triProjected.A = Vector.add(triProjected.A,viewOffset);
|
for (int i=0;i<clippedTriangles;i++) {
|
||||||
triProjected.B = Vector.add(triProjected.B,viewOffset);
|
triProjected.A = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].A);
|
||||||
triProjected.C = Vector.add(triProjected.C,viewOffset);
|
triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].B);
|
||||||
triProjected.A.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].C);
|
||||||
triProjected.A.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
triProjected.setColor(new Color(dp,dp,dp));
|
||||||
triProjected.B.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
|
||||||
triProjected.B.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
|
||||||
triProjected.C.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
|
||||||
triProjected.C.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
|
||||||
|
|
||||||
accumulatedTris.add(triProjected);
|
triProjected.A = Vector.divide(triProjected.A, triProjected.A.w);
|
||||||
|
triProjected.B = Vector.divide(triProjected.B, triProjected.B.w);
|
||||||
|
triProjected.C = Vector.divide(triProjected.C, triProjected.C.w);
|
||||||
|
|
||||||
|
triProjected.A.x*=-1f;
|
||||||
|
triProjected.A.y*=-1f;
|
||||||
|
triProjected.B.x*=-1f;
|
||||||
|
triProjected.B.y*=-1f;
|
||||||
|
triProjected.C.x*=-1f;
|
||||||
|
triProjected.C.y*=-1f;
|
||||||
|
|
||||||
|
Vector viewOffset = new Vector(1,1,0);
|
||||||
|
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.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
||||||
|
triProjected.B.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
||||||
|
triProjected.B.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
||||||
|
triProjected.C.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
||||||
|
triProjected.C.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
||||||
|
|
||||||
|
accumulatedTris.add(triProjected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import java.awt.BorderLayout;
|
|||||||
|
|
||||||
public class SigRenderer implements KeyListener,MouseListener,MouseMotionListener{
|
public class SigRenderer implements KeyListener,MouseListener,MouseMotionListener{
|
||||||
|
|
||||||
public static boolean WIREFRAME = false;
|
public static boolean WIREFRAME = true;
|
||||||
|
|
||||||
public static Mesh cube;
|
public static Mesh cube;
|
||||||
public static int SCREEN_WIDTH=1280;
|
public static int SCREEN_WIDTH=1280;
|
||||||
@ -36,9 +36,43 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
|
|||||||
public static Matrix matProj = Matrix.MakeProjection(fFov,fAspectRatio,fNear,fFar);
|
public static Matrix matProj = Matrix.MakeProjection(fFov,fAspectRatio,fNear,fFar);
|
||||||
|
|
||||||
public static Vector vCamera = new Vector();
|
public static Vector vCamera = new Vector();
|
||||||
|
public static Vector vLookDir = new Vector(0,0,1);
|
||||||
|
public static float yaw = 0;
|
||||||
|
|
||||||
|
final float MOVESPEED = 0.03f;
|
||||||
|
final float TURNSPEED = 0.03f;
|
||||||
|
|
||||||
|
boolean upHeld=false,downHeld=false,leftHeld=false,rightHeld=false,
|
||||||
|
aHeld=false,sHeld=false,dHeld=false,wHeld=false;
|
||||||
|
|
||||||
public void runGameLoop() {
|
public void runGameLoop() {
|
||||||
rot+=Math.PI/480d;
|
if (upHeld) {
|
||||||
|
vCamera.y-=MOVESPEED;
|
||||||
|
}
|
||||||
|
if (downHeld) {
|
||||||
|
vCamera.y+=MOVESPEED;
|
||||||
|
}
|
||||||
|
if (rightHeld) {
|
||||||
|
vCamera.x+=MOVESPEED;
|
||||||
|
}
|
||||||
|
if (leftHeld) {
|
||||||
|
vCamera.x-=MOVESPEED;
|
||||||
|
}
|
||||||
|
if (wHeld||sHeld) {
|
||||||
|
Vector forward = Vector.multiply(vLookDir,MOVESPEED);
|
||||||
|
if (wHeld) {
|
||||||
|
vCamera = Vector.add(vCamera,forward);
|
||||||
|
}
|
||||||
|
if (sHeld) {
|
||||||
|
vCamera = Vector.subtract(vCamera,forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aHeld) {
|
||||||
|
yaw-=TURNSPEED;
|
||||||
|
}
|
||||||
|
if (dHeld) {
|
||||||
|
yaw+=TURNSPEED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SigRenderer(JFrame f) {
|
SigRenderer(JFrame f) {
|
||||||
@ -125,19 +159,59 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
|
|||||||
public void keyPressed(KeyEvent e) {
|
public void keyPressed(KeyEvent e) {
|
||||||
switch (e.getKeyCode()) {
|
switch (e.getKeyCode()) {
|
||||||
case KeyEvent.VK_UP:{
|
case KeyEvent.VK_UP:{
|
||||||
|
upHeld=true;
|
||||||
}break;
|
}break;
|
||||||
case KeyEvent.VK_RIGHT:{
|
case KeyEvent.VK_RIGHT:{
|
||||||
|
rightHeld=true;
|
||||||
}break;
|
}break;
|
||||||
case KeyEvent.VK_LEFT:{
|
case KeyEvent.VK_LEFT:{
|
||||||
|
leftHeld=true;
|
||||||
}break;
|
}break;
|
||||||
case KeyEvent.VK_DOWN:{
|
case KeyEvent.VK_DOWN:{
|
||||||
|
downHeld=true;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_W:{
|
||||||
|
wHeld=true;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_D:{
|
||||||
|
dHeld=true;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_A:{
|
||||||
|
aHeld=true;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_S:{
|
||||||
|
sHeld=true;
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void keyReleased(KeyEvent e) {
|
public void keyReleased(KeyEvent e) {
|
||||||
// TODO Auto-generated method stub
|
switch (e.getKeyCode()) {
|
||||||
|
case KeyEvent.VK_UP:{
|
||||||
|
upHeld=false;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_RIGHT:{
|
||||||
|
rightHeld=false;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_LEFT:{
|
||||||
|
leftHeld=false;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_DOWN:{
|
||||||
|
downHeld=false;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_W:{
|
||||||
|
wHeld=false;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_D:{
|
||||||
|
dHeld=false;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_A:{
|
||||||
|
aHeld=false;
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_S:{
|
||||||
|
sHeld=false;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,9 @@ public class Triangle {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected Object clone(){
|
protected Object clone(){
|
||||||
return new Triangle((Vector)this.A.clone(),(Vector)this.B.clone(),(Vector)this.C.clone());
|
Triangle t = new Triangle((Vector)this.A.clone(),(Vector)this.B.clone(),(Vector)this.C.clone());
|
||||||
|
t.col = col;
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -26,4 +28,63 @@ public class Triangle {
|
|||||||
public void setColor(Color col) {
|
public void setColor(Color col) {
|
||||||
this.col=col;
|
this.col=col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float dist(Vector plane_p,Vector plane_n,Vector p) {
|
||||||
|
Vector n = Vector.normalize(p);
|
||||||
|
return plane_n.x*p.x+plane_n.y*p.y+plane_n.z*p.z-Vector.dotProduct(plane_n,plane_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ClipAgainstPlane(Vector plane_p,Vector plane_n,Triangle in,Triangle[] out_tri) {
|
||||||
|
plane_n = Vector.normalize(plane_n);
|
||||||
|
Vector[] inside_points = new Vector[3];
|
||||||
|
Vector[] outside_points = new Vector[3];
|
||||||
|
int insidePointCount=0,outsidePointCount=0;
|
||||||
|
|
||||||
|
float d0=dist(plane_p,plane_n,in.A);
|
||||||
|
float d1=dist(plane_p,plane_n,in.B);
|
||||||
|
float d2=dist(plane_p,plane_n,in.C);
|
||||||
|
|
||||||
|
if (d0>=0) {
|
||||||
|
inside_points[insidePointCount++]=in.A;
|
||||||
|
} else {
|
||||||
|
outside_points[outsidePointCount++]=in.A;
|
||||||
|
}
|
||||||
|
if (d1>=0) {
|
||||||
|
inside_points[insidePointCount++]=in.B;
|
||||||
|
} else {
|
||||||
|
outside_points[outsidePointCount++]=in.B;
|
||||||
|
}
|
||||||
|
if (d2>=0) {
|
||||||
|
inside_points[insidePointCount++]=in.C;
|
||||||
|
} else {
|
||||||
|
outside_points[outsidePointCount++]=in.C;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insidePointCount==0) {
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
if (insidePointCount==1&&outsidePointCount==2) {
|
||||||
|
out_tri[0].col = in.col;
|
||||||
|
out_tri[0].A = inside_points[0];
|
||||||
|
out_tri[0].B = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0]);
|
||||||
|
out_tri[0].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[1]);
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
if (insidePointCount==2&&outsidePointCount==1) {
|
||||||
|
out_tri[0].col=out_tri[1].col=in.col;
|
||||||
|
out_tri[0].A = inside_points[0];
|
||||||
|
out_tri[0].B = inside_points[1];
|
||||||
|
out_tri[0].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0]);
|
||||||
|
out_tri[1].A = inside_points[1];
|
||||||
|
out_tri[1].B = out_tri[0].C;
|
||||||
|
out_tri[1].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[1], outside_points[0]);
|
||||||
|
return 2;
|
||||||
|
} else
|
||||||
|
if (insidePointCount==3) {
|
||||||
|
out_tri[0] = in;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,4 +48,15 @@ public class Vector {
|
|||||||
v.z=v1.x*v2.y-v1.y*v2.x;
|
v.z=v1.x*v2.y-v1.y*v2.x;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vector IntersectPlane(Vector plane_p,Vector plane_n,Vector lineStart,Vector lineEnd) {
|
||||||
|
plane_n = Vector.normalize(plane_n);
|
||||||
|
float plane_d = -Vector.dotProduct(plane_n,plane_p);
|
||||||
|
float ad = Vector.dotProduct(lineStart,plane_n);
|
||||||
|
float bd = Vector.dotProduct(lineEnd,plane_n);
|
||||||
|
float t = (-plane_d-ad)/(bd-ad);
|
||||||
|
Vector lineStartToEnd = Vector.subtract(lineEnd,lineStart);
|
||||||
|
Vector lineToIntersect = Vector.multiply(lineStartToEnd,t);
|
||||||
|
return Vector.add(lineStart,lineToIntersect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user