Ray tracing mess-arounds.
Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
This commit is contained in:
parent
9014eb92e6
commit
29c44d4207
@ -1,27 +1,43 @@
|
|||||||
package sig;
|
package sig;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.vecmath.Vector3d;
|
import javax.vecmath.Vector3f;
|
||||||
|
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
public class Panel extends JPanel{
|
public class Panel extends JPanel{
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
long endTime = System.nanoTime();
|
||||||
|
|
||||||
|
public void repaint() {
|
||||||
|
super.repaint();
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
}
|
||||||
public void paintComponent(Graphics g) {
|
public void paintComponent(Graphics g) {
|
||||||
Vector3d origin = new Vector3d(0,0,10);
|
g.clearRect(0,0,SigRenderer.SCREEN_WIDTH,SigRenderer.SCREEN_HEIGHT);
|
||||||
for (int x=0;x<SigRenderer.SCREEN_WIDTH;x++) {
|
//Vector3f origin = new Vector3f(Math.cos(SigRenderer.rot)*10,0,10+Math.sin(SigRenderer.rot)*10);
|
||||||
for (int y=0;y<SigRenderer.SCREEN_HEIGHT;y++) {
|
/*for (int x=0;x<SigRenderer.SCREEN_WIDTH/RESOLUTION;x++) {
|
||||||
Vector3d dir = new Vector3d((-SigRenderer.SCREEN_WIDTH/2d+x),(-SigRenderer.SCREEN_HEIGHT/2d+y),SigRenderer.SCREEN_WIDTH);
|
for (int y=0;y<SigRenderer.SCREEN_HEIGHT/RESOLUTION;y++) {
|
||||||
|
Vector3f dir = new Vector3f((-SigRenderer.SCREEN_WIDTH/2d+x*RESOLUTION),(-SigRenderer.SCREEN_HEIGHT/2d+y*RESOLUTION),SigRenderer.SCREEN_WIDTH);
|
||||||
if (SigRenderer.tri.rayTriangleIntersect(origin, dir)) {
|
if (SigRenderer.tri.rayTriangleIntersect(origin, dir)) {
|
||||||
g.setColor(Color.BLACK);
|
g.setColor(Color.BLACK);
|
||||||
g.fillRect(SigRenderer.SCREEN_WIDTH-x,SigRenderer.SCREEN_HEIGHT-y,1,1);
|
g.fillRect((int)(SigRenderer.SCREEN_WIDTH-x*RESOLUTION),(int)(SigRenderer.SCREEN_HEIGHT-y*RESOLUTION),(int)RESOLUTION,(int)RESOLUTION);
|
||||||
//System.out.println("Intersects at "+origin+"/"+dir);
|
//System.out.println("Intersects at "+origin+"/"+dir);
|
||||||
}
|
} else
|
||||||
if (SigRenderer.tri2.rayTriangleIntersect(origin, dir)) {
|
if (SigRenderer.tri2.rayTriangleIntersect(origin, dir)) {
|
||||||
g.setColor(Color.BLUE);
|
g.setColor(Color.BLUE);
|
||||||
g.fillRect(SigRenderer.SCREEN_WIDTH-x,SigRenderer.SCREEN_HEIGHT-y,1,1);
|
g.fillRect((int)(SigRenderer.SCREEN_WIDTH-x*RESOLUTION),(int)(SigRenderer.SCREEN_HEIGHT-y*RESOLUTION),(int)RESOLUTION,(int)RESOLUTION);
|
||||||
//System.out.println("Intersects at "+origin+"/"+dir);
|
//System.out.println("Intersects at "+origin+"/"+dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
for (Pixel p:SigRenderer.pixels) {
|
||||||
|
if (!g.getColor().equals(p.col)) {
|
||||||
|
g.setColor(p.col);
|
||||||
|
}
|
||||||
|
g.fillRect(p.x,p.y,(int)SigRenderer.RESOLUTION,(int)SigRenderer.RESOLUTION);
|
||||||
|
}
|
||||||
|
endTime=System.nanoTime();
|
||||||
|
SigRenderer.DRAWLOOPTIME = (endTime-startTime)/1000000f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
src/sig/Pixel.java
Normal file
13
src/sig/Pixel.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package sig;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
public class Pixel {
|
||||||
|
int x,y;
|
||||||
|
Color col;
|
||||||
|
Pixel(int x,int y,Color col) {
|
||||||
|
this.x=x;
|
||||||
|
this.y=y;
|
||||||
|
this.col=col;
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +1,62 @@
|
|||||||
package sig;
|
package sig;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.vecmath.Vector3d;
|
import javax.vecmath.Point2d;
|
||||||
|
import javax.vecmath.Tuple3d;
|
||||||
|
import javax.vecmath.Vector3f;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.awt.event.MouseMotionListener;
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
public class SigRenderer implements MouseListener,MouseMotionListener{
|
public class SigRenderer implements KeyListener,MouseListener,MouseMotionListener{
|
||||||
public static Triangle tri;
|
public static Triangle tri,tri2,tri3,tri4,tri5,tri6;
|
||||||
public static Triangle tri2;
|
|
||||||
public final static int SCREEN_WIDTH=1280;
|
public final static int SCREEN_WIDTH=1280;
|
||||||
public final static int SCREEN_HEIGHT=720;
|
public final static int SCREEN_HEIGHT=720;
|
||||||
public final static long TIMEPERTICK = 16666667l;
|
public final static long TIMEPERTICK = 16666667l;
|
||||||
public static double DRAWTIME=0;
|
public static float DRAWTIME=0;
|
||||||
|
public static float DRAWLOOPTIME=0;
|
||||||
|
public static final float RESOLUTION=4;
|
||||||
|
|
||||||
Vector3d origin = new Vector3d(0,0,-10);
|
Vector3f origin = new Vector3f(0,0,10);
|
||||||
Vector3d dir = new Vector3d(0,0,1);
|
public static float rot = (float)Math.PI/4; //In radians.
|
||||||
|
|
||||||
|
public static List<Pixel> pixels;
|
||||||
|
|
||||||
public void runGameLoop() {
|
public void runGameLoop() {
|
||||||
|
rot+=Math.PI/480d;
|
||||||
|
pixels = new ArrayList<>();
|
||||||
|
for (int x=0;x<SigRenderer.SCREEN_WIDTH/RESOLUTION;x++) {
|
||||||
|
for (int y=0;y<SigRenderer.SCREEN_HEIGHT/RESOLUTION;y++) {
|
||||||
|
Vector3f dir = new Vector3f((-SigRenderer.SCREEN_WIDTH/2f+x*RESOLUTION),(-SigRenderer.SCREEN_HEIGHT/2f+y*RESOLUTION),SigRenderer.SCREEN_WIDTH).dot;
|
||||||
|
if (SigRenderer.tri.rayTriangleIntersect(origin, dir)) {
|
||||||
|
pixels.add(new Pixel((int)(SigRenderer.SCREEN_WIDTH-x*RESOLUTION),(int)(SigRenderer.SCREEN_HEIGHT-y*RESOLUTION),Color.BLACK));
|
||||||
|
}
|
||||||
|
if (SigRenderer.tri2.rayTriangleIntersect(origin, dir)) {
|
||||||
|
pixels.add(new Pixel((int)(SigRenderer.SCREEN_WIDTH-x*RESOLUTION),(int)(SigRenderer.SCREEN_HEIGHT-y*RESOLUTION),Color.BLUE));
|
||||||
|
}
|
||||||
|
if (SigRenderer.tri3.rayTriangleIntersect(origin, dir)) {
|
||||||
|
pixels.add(new Pixel((int)(SigRenderer.SCREEN_WIDTH-x*RESOLUTION),(int)(SigRenderer.SCREEN_HEIGHT-y*RESOLUTION),Color.RED));
|
||||||
|
}
|
||||||
|
if (SigRenderer.tri4.rayTriangleIntersect(origin, dir)) {
|
||||||
|
pixels.add(new Pixel((int)(SigRenderer.SCREEN_WIDTH-x*RESOLUTION),(int)(SigRenderer.SCREEN_HEIGHT-y*RESOLUTION),Color.GREEN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SigRenderer(JFrame f) {
|
SigRenderer(JFrame f) {
|
||||||
tri = new Triangle(new Vector3d(-1,-1,0),new Vector3d(1,-1,0),new Vector3d(0,2,0));
|
|
||||||
tri2 = new Triangle(new Vector3d(-1,-1,120),new Vector3d(1,-1,120),new Vector3d(0,2,120));
|
tri = new Triangle(new Vector3f(-1,-1,0),new Vector3f(0,-1,0),new Vector3f(-1,0,0));
|
||||||
|
tri2 = new Triangle(new Vector3f(-1,0,0),new Vector3f(0,-1,0),new Vector3f(0,0,0));
|
||||||
|
tri3 = new Triangle(new Vector3f(0,0,0),new Vector3f(0,-1,0),new Vector3f(0,-1,-1));
|
||||||
|
tri4 = new Triangle(new Vector3f(0,-1,-1),new Vector3f(0,0,-1),new Vector3f(0,-1,0));
|
||||||
|
/*tri5 = new Triangle(new Vector3f(0,-1,0),new Vector3f(0,-1,-1),new Vector3f(0,0,0));
|
||||||
|
tri6 = new Triangle(new Vector3f(0,0,0),new Vector3f(0,-1,-1),new Vector3f(0,0,-1));*/
|
||||||
|
|
||||||
Panel p = new Panel();
|
Panel p = new Panel();
|
||||||
|
|
||||||
@ -32,29 +66,29 @@ public class SigRenderer implements MouseListener,MouseMotionListener{
|
|||||||
long startTime = System.nanoTime();
|
long startTime = System.nanoTime();
|
||||||
runGameLoop();
|
runGameLoop();
|
||||||
p.repaint();
|
p.repaint();
|
||||||
|
Toolkit.getDefaultToolkit().sync();
|
||||||
long endTime = System.nanoTime();
|
long endTime = System.nanoTime();
|
||||||
long diff = endTime-startTime;
|
long diff = endTime-startTime;
|
||||||
if (diff>TIMEPERTICK) { //Took longer than 1/60th of a second. No sleep.
|
|
||||||
System.err.println("Frame Drawing took longer than "+TIMEPERTICK+"ns to calculate ("+diff+"ns total)!");
|
|
||||||
} else {
|
|
||||||
try {
|
try {
|
||||||
long sleepTime = TIMEPERTICK - diff;
|
long sleepTime = TIMEPERTICK - diff;
|
||||||
long millis = (sleepTime)/1000000;
|
long millis = (sleepTime)/1000000;
|
||||||
int nanos = (int)(sleepTime-(((sleepTime)/1000000)*1000000));
|
int nanos = (int)(sleepTime-(((sleepTime)/1000000)*1000000));
|
||||||
//System.out.println("FRAME DRAWING: Sleeping for ("+millis+"ms,"+nanos+"ns) - "+(diff)+"ns");
|
//System.out.println("FRAME DRAWING: Sleeping for ("+millis+"ms,"+nanos+"ns) - "+(diff)+"ns");
|
||||||
DRAWTIME = (double)diff/1000000;
|
DRAWTIME = (float)diff/1000000;
|
||||||
f.setTitle("Game Loop: "+DRAWTIME+"ms");
|
f.setTitle("Game Loop: "+DRAWTIME+"ms, Draw Loop: "+DRAWLOOPTIME+"ms");
|
||||||
|
if (sleepTime>0) {
|
||||||
Thread.sleep(millis,nanos);
|
Thread.sleep(millis,nanos);
|
||||||
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}.start();
|
}.start();
|
||||||
|
|
||||||
f.getContentPane().addMouseListener(this);
|
f.getContentPane().addMouseListener(this);
|
||||||
f.getContentPane().addMouseMotionListener(this);
|
f.getContentPane().addMouseMotionListener(this);
|
||||||
|
f.addKeyListener(this);
|
||||||
f.add(p);
|
f.add(p);
|
||||||
f.setSize(SCREEN_WIDTH,SCREEN_HEIGHT);
|
f.setSize(SCREEN_WIDTH,SCREEN_HEIGHT);
|
||||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
@ -92,4 +126,34 @@ public class SigRenderer implements MouseListener,MouseMotionListener{
|
|||||||
@Override
|
@Override
|
||||||
public void mouseMoved(MouseEvent e) {
|
public void mouseMoved(MouseEvent e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
switch (e.getKeyCode()) {
|
||||||
|
case KeyEvent.VK_UP:{
|
||||||
|
origin.add(new Vector3f(0,0,-1));
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_RIGHT:{
|
||||||
|
origin.add(new Vector3f(1,0,0));
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_LEFT:{
|
||||||
|
origin.add(new Vector3f(-1,0,0));
|
||||||
|
}break;
|
||||||
|
case KeyEvent.VK_DOWN:{
|
||||||
|
origin.add(new Vector3f(0,0,1));
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package sig;
|
package sig;
|
||||||
import javax.vecmath.Vector3d;
|
import javax.vecmath.Vector3f;
|
||||||
|
|
||||||
public class Triangle {
|
public class Triangle {
|
||||||
Vector3d A,B,C;
|
Vector3f A,B,C;
|
||||||
Triangle(Vector3d A,Vector3d B,Vector3d C) {
|
Triangle(Vector3f A,Vector3f B,Vector3f C) {
|
||||||
this.A=A;
|
this.A=A;
|
||||||
this.B=B;
|
this.B=B;
|
||||||
this.C=C;
|
this.C=C;
|
||||||
@ -13,56 +13,56 @@ public class Triangle {
|
|||||||
return "Triangle [A=" + A + ", B=" + B + ", C=" + C + "]";
|
return "Triangle [A=" + A + ", B=" + B + ", C=" + C + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3d getNormal() {
|
public Vector3f getNormal() {
|
||||||
Vector3d AB = (Vector3d)A.clone();
|
Vector3f AB = (Vector3f)A.clone();
|
||||||
AB.sub(B);
|
AB.sub(B);
|
||||||
Vector3d BC = (Vector3d)B.clone();
|
Vector3f BC = (Vector3f)B.clone();
|
||||||
BC.sub(C);
|
BC.sub(C);
|
||||||
Vector3d crossP = new Vector3d();
|
Vector3f crossP = new Vector3f();
|
||||||
crossP.cross(AB,BC);
|
crossP.cross(AB,BC);
|
||||||
//crossP.normalize();
|
//crossP.normalize();
|
||||||
return crossP;
|
return crossP;
|
||||||
}
|
}
|
||||||
public double distanceFromOrigin() {
|
public float distanceFromOrigin() {
|
||||||
return getNormal().dot(A);
|
return getNormal().dot(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean rayTriangleIntersect(Vector3d origin,Vector3d dir) {
|
public boolean rayTriangleIntersect(Vector3f origin,Vector3f dir) {
|
||||||
Vector3d N = getNormal();
|
Vector3f N = getNormal();
|
||||||
|
|
||||||
double NrayDir = N.dot(dir);
|
float NrayDir = N.dot(dir);
|
||||||
if (NrayDir<=0.001) { //Very small, so it's parallel.
|
if (NrayDir<=0.001) { //Very small, so it's parallel.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
double d = distanceFromOrigin();
|
float d = distanceFromOrigin();
|
||||||
|
|
||||||
double T=(getNormal().dot(origin)+d)/(NrayDir);
|
float T=(getNormal().dot(origin)+d)/(NrayDir);
|
||||||
|
|
||||||
if (T<0) {return false;} //Triangle is behind the ray.
|
if (T<0) {return false;} //Triangle is behind the ray.
|
||||||
|
|
||||||
//System.out.println("Not behind.");
|
//System.out.println("Not behind.");
|
||||||
|
|
||||||
Vector3d scaleMult = (Vector3d)dir.clone();
|
Vector3f scaleMult = (Vector3f)dir.clone();
|
||||||
scaleMult.scale(T);
|
scaleMult.scale(T);
|
||||||
Vector3d P = (Vector3d)origin.clone();
|
Vector3f P = (Vector3f)origin.clone();
|
||||||
P.add(scaleMult);
|
P.add(scaleMult);
|
||||||
|
|
||||||
Vector3d C;
|
Vector3f C;
|
||||||
|
|
||||||
Vector3d edge0 = (Vector3d)B.clone(); edge0.sub(A);
|
Vector3f edge0 = (Vector3f)B.clone(); edge0.sub(A);
|
||||||
Vector3d vp0 = (Vector3d)P.clone(); vp0.sub(A);
|
Vector3f vp0 = (Vector3f)P.clone(); vp0.sub(A);
|
||||||
C = new Vector3d(); C.cross(edge0,vp0);
|
C = new Vector3f(); C.cross(edge0,vp0);
|
||||||
if (N.dot(C)<0) {return false;}
|
if (N.dot(C)<0) {return false;}
|
||||||
|
|
||||||
Vector3d edge1 = (Vector3d)this.C.clone(); edge1.sub(B);
|
Vector3f edge1 = (Vector3f)this.C.clone(); edge1.sub(B);
|
||||||
Vector3d vp1 = (Vector3d)P.clone(); vp1.sub(B);
|
Vector3f vp1 = (Vector3f)P.clone(); vp1.sub(B);
|
||||||
C = new Vector3d(); C.cross(edge1,vp1);
|
C = new Vector3f(); C.cross(edge1,vp1);
|
||||||
if (N.dot(C)<0) {return false;}
|
if (N.dot(C)<0) {return false;}
|
||||||
|
|
||||||
Vector3d edge2 = (Vector3d)A.clone(); edge2.sub(this.C);
|
Vector3f edge2 = (Vector3f)A.clone(); edge2.sub(this.C);
|
||||||
Vector3d vp2 = (Vector3d)P.clone(); vp2.sub(this.C);
|
Vector3f vp2 = (Vector3f)P.clone(); vp2.sub(this.C);
|
||||||
C = new Vector3d(); C.cross(edge2,vp2);
|
C = new Vector3f(); C.cross(edge2,vp2);
|
||||||
if (N.dot(C)<0) {return false;}
|
if (N.dot(C)<0) {return false;}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user