raycast method with no aliasing raycastF

finalized the raycast method.  this method has no aliasing but
sacrifices some efficiency/performance in order to accomplish it.
master
matortheeternal 2014-05-20 15:42:18 -07:00
parent ac02aac537
commit 7570bcabeb
8 changed files with 36 additions and 32 deletions

4
VoxelEngine/bin/html.txt Normal file
View File

@ -0,0 +1,4 @@
<html>
<applet code="voxelengine.Menu.class" width="800" height="640">
</applet>
</html>

View File

@ -7,10 +7,11 @@ public class Camera {
public double rotX;
public double rotY;
public double rotZ;
public double fov;
public double fovH;
public double fovV;
// constructor
public Camera(double x, double y, double z, double rotY, double rotZ, double rotX, double fov) {
public Camera(double x, double y, double z, double rotY, double rotZ, double rotX, double fovH, double fovV) {
super();
this.x = x;
this.y = y;
@ -18,6 +19,7 @@ public class Camera {
this.rotX = rotX;
this.rotY = rotY;
this.rotZ = rotZ;
this.fov = fov;
this.fovH = fovH;
this.fovV = fovV;
}
}

View File

@ -135,9 +135,10 @@ public class Renderer {
private int raycastE(int px, int py, int width, int height, int castScale, double[][] ref) {
double w2 = width / 2;
double h2 = height / 2;
double fov = camera.fov / 2;
double yawr = ((px - w2) / w2) * fov;
double pitchr = ((py - h2) / h2) * fov * 0.5; // correction because view window isn't 1:1
double fovH = camera.fovH / 2;
double fovV = camera.fovV / 2;
double yawr = ((px - w2) / w2) * fovH;
double pitchr = ((py - h2) / h2) * fovV; // correction because view window isn't 1:1
double x1 = camera.x;
double y1 = camera.y;
@ -146,11 +147,7 @@ public class Renderer {
int cx1, cy1, cz1, cx2, cy2, cz2;
double[] ray = new double[] { cos(pitchr) * cos(yawr), cos(pitchr) * sin(yawr), -sin(pitchr) };
ray = new double[] {
ray[0] * ref[0][0] + ray[1] * ref[1][0] + ray[2] * ref[2][0],
ray[0] * ref[0][1] + ray[1] * ref[1][1] + ray[2] * ref[2][1],
ray[0] * ref[0][2] + ray[1] * ref[1][2] + ray[2] * ref[2][2],
};
ray = new double[] { ray[0] * ref[0][0] + ray[1] * ref[1][0] + ray[2] * ref[2][0], ray[0] * ref[0][1] + ray[1] * ref[1][1] + ray[2] * ref[2][1], ray[0] * ref[0][2] + ray[1] * ref[1][2] + ray[2] * ref[2][2], };
double xs = ray[0] / castScale;
double ys = ray[1] / castScale;
double zs = ray[2] / castScale;
@ -192,20 +189,19 @@ public class Renderer {
return SkyboxColor.getRGB();
}
public MemoryImageSource renderF(int width, int height, int pixelScale, int castScale) {
int[] mem = new int[width * height];
double yaw = camera.rotY;
double pitch = camera.rotX;
double[][] ref = new double[][] {
{ sin(pitch) * cos(yaw), sin(pitch) * sin(yaw), -cos(pitch) },
{ -sin(yaw), cos(yaw), 0 }, // equal to cos(yaw + PI/2), sin(yaw + PI/2), 0
double[][] ref = new double[][] { { sin(pitch) * cos(yaw), sin(pitch) * sin(yaw), -cos(pitch) }, { -sin(yaw), cos(yaw), 0 }, // equal to cos(yaw + PI/2), sin(yaw + PI/2), 0
{ cos(pitch) * cos(yaw), cos(pitch) * sin(yaw), 2 * sin(pitch) } // cross product of the two vectors above
};
// raycast for each pixel
for (int py = 0; py < height - pixelScale; py += pixelScale) {
for (int px = 0; px < width - pixelScale; px += pixelScale) {
// if (camera.rotX != PI/2) System.out.println("Raycasting "+px+","+py);
if (pixelScale == 1)
mem[px + py * width] = raycastF(px, py, width, height, ref);
else {
@ -222,14 +218,15 @@ public class Renderer {
// return image source
return new MemoryImageSource(width, height, mem, 0, width);
}
private int raycastF(int px, int py, int width, int height, double[][] ref) {
double sv = 0.00000000001;
double sv = 0.00000001;
double w2 = width / 2;
double h2 = height / 2;
double fov = camera.fov / 2;
double yawr = ((px - w2) / w2) * fov;
double pitchr = ((py - h2) / h2) * fov * 0.5; // correction because view window isn't 1:1
double fovH = camera.fovH / 2;
double fovV = camera.fovV / 2;
double yawr = ((px - w2) / w2) * fovH;
double pitchr = ((py - h2) / h2) * fovV; // correction because view window isn't 1:1
double x1 = camera.x;
double y1 = camera.y;
@ -239,19 +236,20 @@ public class Renderer {
double i1, i2, i3;
double[] ray = new double[] { cos(pitchr) * cos(yawr), cos(pitchr) * sin(yawr), -sin(pitchr) };
ray = new double[] {
ray[0] * ref[0][0] + ray[1] * ref[1][0] + ray[2] * ref[2][0],
ray[0] * ref[0][1] + ray[1] * ref[1][1] + ray[2] * ref[2][1],
ray[0] * ref[0][2] + ray[1] * ref[1][2] + ray[2] * ref[2][2],
};
ray = new double[] { ray[0] * ref[0][0] + ray[1] * ref[1][0] + ray[2] * ref[2][0], ray[0] * ref[0][1] + ray[1] * ref[1][1] + ray[2] * ref[2][1], ray[0] * ref[0][2] + ray[1] * ref[1][2] + ray[2] * ref[2][2], };
double xs = ray[0];
double ys = ray[1];
double zs = ray[2];
x1 += (x1 % 1.0 == 0) ? sv : 0;
y1 += (y1 % 1.0 == 0) ? sv : 0;
z1 += (z1 % 1.0 == 0) ? sv : 0;
while (inBoundsC(x1, y1, z1)) {
// add/subtract sv if we're on a border exactly
if (x1 % 1.0 == 0)
x1 += (xs > 0) ? sv : -sv;
if (y1 % 1.0 == 0)
y1 += (ys > 0) ? sv : -sv;
if (z1 % 1.0 == 0)
z1 += (zs > 0) ? sv : -sv;
// chunk processing
cx1 = (int) (x1 / 16.0);
cy1 = (int) (y1 / 16.0);
@ -307,7 +305,7 @@ public class Renderer {
z1 += zs * (i3 + sv);
}
}
return SkyboxColor.getRGB();
}
@ -326,4 +324,4 @@ public class Renderer {
// return calculated color
return new Color(red, green, blue);
}
}
}

View File

@ -17,7 +17,7 @@ public class SwingInterface extends JPanel {
private Image src = null;
private World world;
private Renderer renderer;
private Camera camera = new Camera(0, 0, 0, 0, 0, 0, Math.PI/2);
private Camera camera = new Camera(0, 0, 0, 0, 0, 0, Math.PI/2, Math.PI/5);
private static String[] arguments;
private static final int X_SIZE = 800;
@ -59,7 +59,7 @@ public class SwingInterface extends JPanel {
time = System.currentTimeMillis();
}
process_input();
Image img = createImage(renderer.renderE(X_SIZE, Y_SIZE, pixelScale, castScale));
Image img = createImage(renderer.renderF(X_SIZE, Y_SIZE, pixelScale, castScale));
BufferedImage buffer = new BufferedImage(X_SIZE, Y_SIZE, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = buffer.createGraphics();
g2.drawImage(img, 0, 0, null);