diff --git a/src/sig/Matrix.java b/src/sig/Matrix.java index 3e32cd9..8648251 100644 --- a/src/sig/Matrix.java +++ b/src/sig/Matrix.java @@ -14,7 +14,7 @@ public class Matrix { {0,0,0,1}, }); - public static Vector MultiplyVector(Matrix m, Vector i) { + public static Vector MultiplyVector(Matrix m, Vector i) { 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][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; } + 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; + } } diff --git a/src/sig/Panel.java b/src/sig/Panel.java index fd80640..b53a4e7 100644 --- a/src/sig/Panel.java +++ b/src/sig/Panel.java @@ -88,15 +88,23 @@ public class Panel extends JPanel implements Runnable { 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 matWorld = Matrix.IDENTITY; matWorld = Matrix.MultiplyMatrix(matRotZ,matRotX); 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) { - 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.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)); - triProjected.A = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.A); - triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.B); - triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,triTransformed.C); - triProjected.setColor(new Color(dp,dp,dp)); - - 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); - - 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); + triViewed.A = Matrix.MultiplyVector(matView,triTransformed.A); + triViewed.B = Matrix.MultiplyVector(matView,triTransformed.B); + 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=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; + } } diff --git a/src/sig/Vector.java b/src/sig/Vector.java index fb56652..b3b8151 100644 --- a/src/sig/Vector.java +++ b/src/sig/Vector.java @@ -48,4 +48,15 @@ public class Vector { v.z=v1.x*v2.y-v1.y*v2.x; 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); + } }