Fixing display bugs.

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
origin
sigonasr2, Sig, Sigo 3 years ago
parent 344e91502d
commit 129d0e71b1
  1. 28
      src/sig/Matrix.java
  2. 37
      src/sig/Panel.java
  3. 82
      src/sig/SigRenderer.java
  4. 63
      src/sig/Triangle.java
  5. 11
      src/sig/Vector.java

@ -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,15 +126,31 @@ 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);
int clippedTriangles = 0;
Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()};
clippedTriangles = Triangle.ClipAgainstPlane(new Vector(0,0,1),new Vector(0,0,1), triViewed, clipped);
for (int i=0;i<clippedTriangles;i++) {
triProjected.A = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].A);
triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].B);
triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].C);
triProjected.setColor(new Color(dp,dp,dp)); triProjected.setColor(new Color(dp,dp,dp));
triProjected.A = Vector.divide(triProjected.A, triProjected.A.w); triProjected.A = Vector.divide(triProjected.A, triProjected.A.w);
triProjected.B = Vector.divide(triProjected.B, triProjected.B.w); triProjected.B = Vector.divide(triProjected.B, triProjected.B.w);
triProjected.C = Vector.divide(triProjected.C, triProjected.C.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); Vector viewOffset = new Vector(1,1,0);
triProjected.A = Vector.add(triProjected.A,viewOffset); triProjected.A = Vector.add(triProjected.A,viewOffset);
triProjected.B = Vector.add(triProjected.B,viewOffset); triProjected.B = Vector.add(triProjected.B,viewOffset);
@ -141,6 +165,7 @@ public class Panel extends JPanel implements Runnable {
accumulatedTris.add(triProjected); accumulatedTris.add(triProjected);
} }
} }
}
Collections.sort(accumulatedTris, new Comparator<Triangle>() { Collections.sort(accumulatedTris, new Comparator<Triangle>() {
@Override @Override

@ -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…
Cancel
Save