diff --git a/src/sig/Block.java b/src/sig/Block.java index 16d0760..da5130d 100644 --- a/src/sig/Block.java +++ b/src/sig/Block.java @@ -1,10 +1,47 @@ package sig; +import java.util.ArrayList; +import java.util.List; + public class Block { Vector pos; Mesh block; + FaceList neighbors; Block(Vector pos,Mesh block) { + this.neighbors=new FaceList(); this.pos=pos; - this.block=block; + List newTris = new ArrayList<>(); + for (Triangle t : block.triangles) { + Triangle newT = (Triangle)t.clone(); + newT.b=this; + newTris.add(newT); + } + this.block=new Mesh(newTris); + } + public void updateFaces() { + if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y+1)+"_"+pos.z)) { + neighbors.UP=true; + SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).neighbors.DOWN=true; + } + if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y-1)+"_"+pos.z)) { + neighbors.DOWN=true; + SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).neighbors.UP=true; + } + if (SigRenderer.blockGrid.containsKey((pos.x-1)+"_"+(pos.y)+"_"+pos.z)) { + neighbors.LEFT=true; + SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).neighbors.RIGHT=true; + } + if (SigRenderer.blockGrid.containsKey((pos.x+1)+"_"+(pos.y)+"_"+pos.z)) { + neighbors.RIGHT=true; + SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).neighbors.LEFT=true; + } + if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y)+"_"+(pos.z+1))) { + neighbors.FORWARD=true; + SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).neighbors.BACKWARD=true; + } + if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y)+"_"+(pos.z-1))) { + neighbors.BACKWARD=true; + SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).neighbors.FORWARD=true; + } } } diff --git a/src/sig/FaceList.java b/src/sig/FaceList.java new file mode 100644 index 0000000..ea1ce75 --- /dev/null +++ b/src/sig/FaceList.java @@ -0,0 +1,10 @@ +package sig; + +public class FaceList { + boolean UP=false; //+Y + boolean DOWN=false; + boolean FORWARD=false; //+Z + boolean RIGHT=false; //+X + boolean LEFT=false; + boolean BACKWARD=false; +} diff --git a/src/sig/Panel.java b/src/sig/Panel.java index 5b42505..0b8445a 100644 --- a/src/sig/Panel.java +++ b/src/sig/Panel.java @@ -103,108 +103,105 @@ public class Panel extends JPanel implements Runnable { Matrix matCamera = Matrix.PointAt(SigRenderer.vCamera, vTarget, vUp); Matrix matView = Matrix.QuickInverse(matCamera); - for (Block b : SigRenderer.blocks) { - for (Triangle t : b.block.triangles) { - Triangle triProjected = new Triangle(),triTransformed=new Triangle(),triViewed=new Triangle(); - - matWorld = Matrix.MakeTranslation(b.pos.x,b.pos.y,b.pos.z); - - triTransformed.A = Matrix.MultiplyVector(matWorld,t.A); - triTransformed.B = Matrix.MultiplyVector(matWorld,t.B); - triTransformed.C = Matrix.MultiplyVector(matWorld,t.C); - triTransformed.T = t.T; - triTransformed.U = t.U; - triTransformed.V = t.V; - triTransformed.tex = t.tex; - - Vector normal=new Vector(),line1=new Vector(),line2=new Vector(); - line1 = Vector.subtract(triTransformed.B,triTransformed.A); - line2 = Vector.subtract(triTransformed.C,triTransformed.A); - - normal = Vector.crossProduct(line1,line2); - normal = Vector.normalize(normal); - - Vector cameraRay = Vector.subtract(triTransformed.A,SigRenderer.vCamera); - - if (Vector.dotProduct(normal,cameraRay)<0) { - /*Vector lightDir = Vector.multiply(SigRenderer.vLookDir, -1); - lightDir = Vector.normalize(lightDir);*/ - - //System.out.println(-Vector.dotProduct(normal,Vector.normalize(cameraRay))); - //float dp = Math.max(0.1f,Math.min(1,-1/Vector.dotProduct(normal,cameraRay))); - /*Vector center = Vector.divide(Vector.add(triTransformed.A,Vector.add(triTransformed.B,triTransformed.C)),3); - Vector cameraRay2 = Vector.subtract(center,SigRenderer.vCamera); - float dp = Math.max(0.1f,Math.min(1,(1f/((cameraRay2.x-center.x)*(cameraRay2.x-center.x)+ - (cameraRay2.y-center.y)*(cameraRay2.y-center.y)+ - (cameraRay2.z-center.z)*(cameraRay2.z-center.z))*4)));*/ - float dp = Math.max(0.1f,Math.min(1,(1f/((b.pos.x-SigRenderer.vCamera.x)+ - (b.pos.y-SigRenderer.vCamera.y)*(b.pos.y-SigRenderer.vCamera.y)+ - (b.pos.z-SigRenderer.vCamera.z)*(b.pos.z-SigRenderer.vCamera.z))*4))); - - triViewed.A = Matrix.MultiplyVector(matView,triTransformed.A); - triViewed.B = Matrix.MultiplyVector(matView,triTransformed.B); - triViewed.C = Matrix.MultiplyVector(matView,triTransformed.C); - triViewed.setColor(new Color(dp,dp,dp)); - triViewed.T = triTransformed.T; - triViewed.U = triTransformed.U; - triViewed.V = triTransformed.V; - triViewed.tex = triTransformed.tex; - - int clippedTriangles = 0; - Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()}; - - clippedTriangles = Triangle.ClipAgainstPlane(new Vector(0,0,0.1f),new Vector(0,0,1), triViewed, clipped); - for (int i=0;i0) { - triProjected = new Triangle(); - } - 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.col = clipped[i].col; - triProjected.tex = clipped[i].tex; - triProjected.T = (Vector2)clipped[i].T.clone(); - triProjected.U = (Vector2)clipped[i].U.clone(); - triProjected.V = (Vector2)clipped[i].V.clone(); - - triProjected.T.u = triProjected.T.u/triProjected.A.w; - triProjected.U.u = triProjected.U.u/triProjected.B.w; - triProjected.V.u = triProjected.V.u/triProjected.C.w; - triProjected.T.v = triProjected.T.v/triProjected.A.w; - triProjected.U.v = triProjected.U.v/triProjected.B.w; - triProjected.V.v = triProjected.V.v/triProjected.C.w; - - triProjected.T.w = 1.0f/triProjected.A.w; - triProjected.U.w = 1.0f/triProjected.B.w; - triProjected.V.w = 1.0f/triProjected.C.w; - - 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); + for (Triangle t : SigRenderer.triRender) { + Triangle triProjected = new Triangle(),triTransformed=new Triangle(),triViewed=new Triangle(); + + matWorld = Matrix.MakeTranslation(t.b.pos.x,t.b.pos.y,t.b.pos.z); + + triTransformed.A = Matrix.MultiplyVector(matWorld,t.A); + triTransformed.B = Matrix.MultiplyVector(matWorld,t.B); + triTransformed.C = Matrix.MultiplyVector(matWorld,t.C); + triTransformed.T = t.T; + triTransformed.U = t.U; + triTransformed.V = t.V; + triTransformed.tex = t.tex; + triTransformed.b=t.b; + + Vector normal=new Vector(),line1=new Vector(),line2=new Vector(); + line1 = Vector.subtract(triTransformed.B,triTransformed.A); + line2 = Vector.subtract(triTransformed.C,triTransformed.A); + + normal = Vector.crossProduct(line1,line2); + normal = Vector.normalize(normal); + + Vector cameraRay = Vector.subtract(triTransformed.A,SigRenderer.vCamera); + + if (Vector.dotProduct(normal,cameraRay)<0) { + /*Vector lightDir = Vector.multiply(SigRenderer.vLookDir, -1); + lightDir = Vector.normalize(lightDir);*/ + + //System.out.println(-Vector.dotProduct(normal,Vector.normalize(cameraRay))); + //float dp = Math.max(0.1f,Math.min(1,-1/Vector.dotProduct(normal,cameraRay))); + /*Vector center = Vector.divide(Vector.add(triTransformed.A,Vector.add(triTransformed.B,triTransformed.C)),3); + Vector cameraRay2 = Vector.subtract(center,SigRenderer.vCamera); + float dp = Math.max(0.1f,Math.min(1,(1f/((cameraRay2.x-center.x)*(cameraRay2.x-center.x)+ + (cameraRay2.y-center.y)*(cameraRay2.y-center.y)+ + (cameraRay2.z-center.z)*(cameraRay2.z-center.z))*4)));*/ + float dp = Math.max(0.1f,Math.min(1,(1f/((triTransformed.b.pos.x-SigRenderer.vCamera.x)*(triTransformed.b.pos.x-SigRenderer.vCamera.x)+ + (triTransformed.b.pos.y-SigRenderer.vCamera.y)*(triTransformed.b.pos.y-SigRenderer.vCamera.y)+ + (triTransformed.b.pos.z-SigRenderer.vCamera.z)*(triTransformed.b.pos.z-SigRenderer.vCamera.z))*4))); + + triViewed.A = Matrix.MultiplyVector(matView,triTransformed.A); + triViewed.B = Matrix.MultiplyVector(matView,triTransformed.B); + triViewed.C = Matrix.MultiplyVector(matView,triTransformed.C); + triTransformed.copyExtraDataTo(triViewed); + triViewed.setColor(new Color(dp,dp,dp)); + + int clippedTriangles = 0; + Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()}; + + clippedTriangles = Triangle.ClipAgainstPlane(new Vector(0,0,0.1f),new Vector(0,0,1), triViewed, clipped); + for (int i=0;i0) { + triProjected = new Triangle(); } + 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.col = clipped[i].col; + triProjected.tex = clipped[i].tex; + triProjected.T = (Vector2)clipped[i].T.clone(); + triProjected.U = (Vector2)clipped[i].U.clone(); + triProjected.V = (Vector2)clipped[i].V.clone(); + triProjected.b=clipped[i].b; + + triProjected.T.u = triProjected.T.u/triProjected.A.w; + triProjected.U.u = triProjected.U.u/triProjected.B.w; + triProjected.V.u = triProjected.V.u/triProjected.C.w; + triProjected.T.v = triProjected.T.v/triProjected.A.w; + triProjected.U.v = triProjected.U.v/triProjected.B.w; + triProjected.V.v = triProjected.V.v/triProjected.C.w; + + triProjected.T.w = 1.0f/triProjected.A.w; + triProjected.U.w = 1.0f/triProjected.B.w; + triProjected.V.w = 1.0f/triProjected.C.w; + + 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); } - } - } + } + } /*Collections.sort(accumulatedTris, new Comparator() { @Override @@ -214,8 +211,8 @@ public class Panel extends JPanel implements Runnable { return (z1 triList = new ArrayList<>(); triList.add(t); @@ -238,7 +235,7 @@ public class Panel extends JPanel implements Runnable { } newTriangles=triList.size(); } - + for (Triangle tt : triList) { if (tt.tex!=null) { DrawUtils.TexturedTriangle(p, @@ -258,11 +255,11 @@ public class Panel extends JPanel implements Runnable { public void repaint() { super.repaint(); - startTime = System.nanoTime(); } @Override public void paintComponent(Graphics g) { + startTime = System.nanoTime(); super.paintComponent(g); // perform draws on pixels render(); diff --git a/src/sig/SigRenderer.java b/src/sig/SigRenderer.java index 8e37c0b..cf6490b 100644 --- a/src/sig/SigRenderer.java +++ b/src/sig/SigRenderer.java @@ -12,7 +12,9 @@ import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.awt.Toolkit; import java.awt.BorderLayout; @@ -20,7 +22,7 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene public static boolean WIREFRAME = false; - public static List blocks = new ArrayList(); + public static List triRender = new ArrayList<>(); public static int SCREEN_WIDTH=1280; public static int SCREEN_HEIGHT=720; public final static long TIMEPERTICK = 16666667l; @@ -28,6 +30,7 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene public static float DRAWLOOPTIME=0; public static final float RESOLUTION=1; public static float rot = (float)Math.PI/4; //In radians. + public static Map blockGrid = new HashMap<>(); public static List pixels; @@ -37,7 +40,7 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene public static float fAspectRatio = (float)SCREEN_HEIGHT/SCREEN_WIDTH; public static Matrix matProj = Matrix.MakeProjection(fFov,fAspectRatio,fNear,fFar); - public static Vector vCamera = new Vector(); + public static Vector vCamera = new Vector(0.5f,2f,0.5f); public static Vector vLookDir = new Vector(0,0,1); public static float yaw = 0; public static float pitch = 0; @@ -50,6 +53,8 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene public static float[] depthBuffer; + public static Mesh DIRT_CUBE=new Mesh("cube.obj","dirt.png"); + boolean upHeld=false,downHeld=false,leftHeld=false,rightHeld=false, aHeld=false,sHeld=false,dHeld=false,wHeld=false; @@ -83,15 +88,31 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene } } + public static void addBlock(Vector pos,Mesh type) { + Block b = new Block(pos,type); + blockGrid.put(pos.x+"_"+pos.y+"_"+pos.z,b); + b.updateFaces(); + updateRenderGrid(); + } + + public static void updateRenderGrid() { + triRender.clear(); + for (String key : blockGrid.keySet()) { + Block b = blockGrid.get(key); + if (!b.neighbors.UP) {triRender.add(b.block.triangles.get(8));triRender.add(b.block.triangles.get(9));} + if (!b.neighbors.DOWN) {triRender.add(b.block.triangles.get(10));triRender.add(b.block.triangles.get(11));} + if (!b.neighbors.LEFT) {triRender.add(b.block.triangles.get(6));triRender.add(b.block.triangles.get(7));} + if (!b.neighbors.RIGHT) {triRender.add(b.block.triangles.get(2));triRender.add(b.block.triangles.get(3));} + if (!b.neighbors.FORWARD) {triRender.add(b.block.triangles.get(4));triRender.add(b.block.triangles.get(5));} + if (!b.neighbors.BACKWARD) {triRender.add(b.block.triangles.get(0));triRender.add(b.block.triangles.get(1));} + } + } + SigRenderer(JFrame f) { //cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj",false)); - Mesh dirtCube = new Mesh("cube.obj","dirt.png"); - for (int x=0;x<32;x++) { - for (int y=0;y<32;y++) { - blocks.add(new Block( - new Vector(x,0,y), - dirtCube - )); + for (int x=0;x<16;x++) { + for (int z=0;z<16;z++) { + addBlock(new Vector(x,0,z),DIRT_CUBE); } } diff --git a/src/sig/Triangle.java b/src/sig/Triangle.java index a63c48b..f9cede5 100644 --- a/src/sig/Triangle.java +++ b/src/sig/Triangle.java @@ -5,6 +5,7 @@ public class Triangle { Vector A,B,C; Vector2 T,U,V; Color col = Color.WHITE; + Block b = null; public Texture tex = null; public Triangle() { this(new Vector(),new Vector(),new Vector()); @@ -20,10 +21,20 @@ public class Triangle { this.U=U; this.V=V; } + public void copyExtraDataTo(Triangle targetTriangle) { + targetTriangle.T=this.T; + targetTriangle.U=this.U; + targetTriangle.V=this.V; + targetTriangle.col=this.col; + targetTriangle.tex=this.tex; + targetTriangle.b=this.b; + } @Override protected Object clone(){ - Triangle t = 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(),(Vector2)this.T.clone(),(Vector2)this.U.clone(),(Vector2)this.V.clone()); t.col = col; + t.tex=tex; + t.b=b; return t; } @Override @@ -88,6 +99,7 @@ public class Triangle { ExtraData t = new ExtraData(0); out_tri[0].col = in.col; out_tri[0].tex = in.tex; + out_tri[0].b=in.b; out_tri[0].A = inside_points[0]; out_tri[0].T = inside_tex[0]; out_tri[0].B = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0],t); @@ -104,6 +116,7 @@ public class Triangle { ExtraData t = new ExtraData(0); out_tri[0].col=out_tri[1].col=in.col; out_tri[0].tex=out_tri[1].tex=in.tex; + out_tri[0].b=out_tri[1].b=in.b; out_tri[0].A = inside_points[0]; out_tri[0].B = inside_points[1]; out_tri[0].T = inside_tex[0];