menu white flashes reduced, new raycast method

the new raycast method (raycastF) is a bit buggy right now (it freezes
at some arbitrary camera rotation/position values I have yet to
isolate), so the SwingInterface still uses raycastE.

the menu white flashes have been reduced by switching images in a
different thread and calling paint instead of repaint.
master
matortheeternal 2014-05-20 10:43:33 -07:00
parent 6cc6e4616e
commit ac02aac537
5 changed files with 184 additions and 59 deletions

View File

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

View File

@ -64,10 +64,6 @@ public class Menu extends Applet implements ActionListener, ItemListener, Runnab
}
public void paint(Graphics g) {
if (System.currentTimeMillis() - time >= ttime) {
time = System.currentTimeMillis();
ndx = (ndx + 1) % 9;
}
g.drawImage(slideshow[ndx], 0, 0, this);
}
@ -331,6 +327,7 @@ public class Menu extends Applet implements ActionListener, ItemListener, Runnab
color.addItem("dreamy");
powerL.setText("Scale: ");
size.setText("81");
power.setText("1.5");
power.setEnabled(true);
zoom.setEnabled(true);
minIt.setEnabled(true);
@ -400,11 +397,15 @@ public class Menu extends Applet implements ActionListener, ItemListener, Runnab
@Override
public void run() {
while (rpThread != null) {
repaint();
if (System.currentTimeMillis() - time >= ttime) {
time = System.currentTimeMillis();
ndx = (ndx + 1) % 9;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
paint(this.getGraphics());
}
}
}

View File

@ -11,17 +11,17 @@ public class Renderer {
private double rate = 0.85;
private int renderDistance = 8;
public Camera camera;
// constructor
public Renderer(World world, Camera camera) {
super();
this.world = world;
this.camera = camera;
}
public MemoryImageSource renderC(int width, int height, int pixelScale, int castScale) {
int[] mem = new int[width*height];
int[] mem = new int[width * height];
// raycast for each pixel
for (int py = 0; py < height - pixelScale; py += pixelScale) {
for (int px = 0; px < width - pixelScale; px += pixelScale) {
@ -37,44 +37,44 @@ public class Renderer {
}
}
}
// return image source
return new MemoryImageSource(width, height, mem, 0, width);
}
private int raycastC(int px, int py, int width, int height, int castScale) {
double w2 = width/2;
double h2 = height/2;
double w2 = width / 2;
double h2 = height / 2;
double yaw = camera.rotY + ((px - w2) / w2) * Math.PI / 4;
double pitch = camera.rotX + ((py - h2) / h2) * Math.PI / 4;
double x1 = camera.x;
double y1 = camera.y;
double z1 = camera.z;
int x2, y2, z2;
int cx1, cy1, cz1, cx2, cy2, cz2;
double xs = Math.sin(pitch) * Math.cos(yaw) / castScale;
double ys = Math.sin(pitch) * Math.sin(yaw) / castScale;
double zs = Math.cos(pitch) / castScale;
while (inBoundsC(x1, y1, z1)) {
// chunk processing
cx1 = (int) (x1/16.0);
cy1 = (int) (y1/16.0);
cz1 = (int) (z1/16.0);
cx1 = (int) (x1 / 16.0);
cy1 = (int) (y1 / 16.0);
cz1 = (int) (z1 / 16.0);
if (world.getIsEmpty(cx1, cy1, cz1)) {
do {
x1 += xs;
y1 += ys;
z1 += zs;
cx2 = (int) (x1/16.0);
cy2 = (int) (y1/16.0);
cz2 = (int) (z1/16.0);
cx2 = (int) (x1 / 16.0);
cy2 = (int) (y1 / 16.0);
cz2 = (int) (z1 / 16.0);
} while (cx1 == cx2 && cy1 == cy2 && cz1 == cz2);
continue;
}
// block processing
Block block = world.getBlock(x1, y1, z1);
if (block != null) {
@ -82,7 +82,7 @@ public class Renderer {
c = CalculateColor(c, camera.x, x1, camera.y, y1, camera.z, z1);
return c.getRGB();
}
x2 = (int) x1;
y2 = (int) y1;
z2 = (int) z1;
@ -92,7 +92,7 @@ public class Renderer {
z1 += zs;
} while ((int) x1 == x2 && (int) y1 == y2 && (int) z1 == z2);
}
return SkyboxColor.getRGB();
}
@ -103,17 +103,15 @@ public class Renderer {
int dz = ((int) Math.abs(camera.z - z)) / 16;
return x >= 0 && x < b && y >= 0 && y < b && z >= 0 && z < b && dx < renderDistance && dy < renderDistance && dz < renderDistance;
}
public MemoryImageSource renderE(int width, int height, int pixelScale, int castScale) {
int[] mem = new int[width*height];
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
{cos(pitch)*cos(yaw), cos(pitch)*sin(yaw), 2*sin(pitch)} // cross product of the two vectors above
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) {
@ -129,51 +127,51 @@ public class Renderer {
}
}
}
// return image source
return new MemoryImageSource(width, height, mem, 0, width);
}
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 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 x1 = camera.x;
double y1 = camera.y;
double z1 = camera.z;
int x2, y2, z2;
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],
};
double xs = ray[0]/castScale;
double ys = ray[1]/castScale;
double zs = ray[2]/castScale;
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],
};
double xs = ray[0] / castScale;
double ys = ray[1] / castScale;
double zs = ray[2] / castScale;
while (inBoundsC(x1, y1, z1)) {
// chunk processing
cx1 = (int) (x1/16.0);
cy1 = (int) (y1/16.0);
cz1 = (int) (z1/16.0);
cx1 = (int) (x1 / 16.0);
cy1 = (int) (y1 / 16.0);
cz1 = (int) (z1 / 16.0);
if (world.getIsEmpty(cx1, cy1, cz1)) {
do {
x1 += xs;
y1 += ys;
z1 += zs;
cx2 = (int) (x1/16.0);
cy2 = (int) (y1/16.0);
cz2 = (int) (z1/16.0);
cx2 = (int) (x1 / 16.0);
cy2 = (int) (y1 / 16.0);
cz2 = (int) (z1 / 16.0);
} while (cx1 == cx2 && cy1 == cy2 && cz1 == cz2);
continue;
}
// block processing
Block block = world.getBlock(x1, y1, z1);
if (block != null) {
@ -181,7 +179,7 @@ public class Renderer {
c = CalculateColor(c, camera.x, x1, camera.y, y1, camera.z, z1);
return c.getRGB();
}
x2 = (int) x1;
y2 = (int) y1;
z2 = (int) z1;
@ -191,14 +189,132 @@ public class Renderer {
z1 += zs;
} while ((int) x1 == x2 && (int) y1 == y2 && (int) z1 == z2);
}
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
{ 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 (pixelScale == 1)
mem[px + py * width] = raycastF(px, py, width, height, ref);
else {
int val = raycastF(px, py, width, height, ref);
for (int pys = 0; pys < pixelScale; ++pys) {
for (int pxs = 0; pxs < pixelScale; ++pxs) {
mem[px + pxs + (py + pys) * width] = val;
}
}
}
}
}
// 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 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 x1 = camera.x;
double y1 = camera.y;
double z1 = camera.z;
int x2, y2, z2;
int cx1, cy1, cz1, cx2, cy2, cz2;
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],
};
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)) {
// chunk processing
cx1 = (int) (x1 / 16.0);
cy1 = (int) (y1 / 16.0);
cz1 = (int) (z1 / 16.0);
if (world.getIsEmpty(cx1, cy1, cz1)) {
i1 = (xs == 0) ? 999999999 : (xs > 0) ? abs((16.0 - x1 % 16.0) / xs) : abs((x1 % 16.0) / xs);
i2 = (ys == 0) ? 999999999 : (ys > 0) ? abs((16.0 - y1 % 16.0) / ys) : abs((y1 % 16.0) / ys);
i3 = (zs == 0) ? 999999999 : (zs > 0) ? abs((16.0 - z1 % 16.0) / zs) : abs((z1 % 16.0) / zs);
if ((i1 <= i2) && (i1 <= i3)) {
// step by i1
x1 += xs * (i1 + sv);
y1 += ys * (i1 + sv);
z1 += zs * (i1 + sv);
} else if ((i2 <= i1) && (i2 <= i3)) {
// step by i2
x1 += xs * (i2 + sv);
y1 += ys * (i2 + sv);
z1 += zs * (i2 + sv);
} else {
// step by i3
x1 += xs * (i3 + sv);
y1 += ys * (i3 + sv);
z1 += zs * (i3 + sv);
}
continue;
}
// block processing
Block block = world.getBlock(x1, y1, z1);
if (block != null) {
Color c = block.getType().getColor();
c = CalculateColor(c, camera.x, x1, camera.y, y1, camera.z, z1);
return c.getRGB();
}
i1 = (xs == 0) ? 999999999 : (xs > 0) ? abs((1.0 - x1 % 1.0) / xs) : abs((x1 % 1.0) / xs);
i2 = (ys == 0) ? 999999999 : (ys > 0) ? abs((1.0 - y1 % 1.0) / ys) : abs((y1 % 1.0) / ys);
i3 = (zs == 0) ? 999999999 : (zs > 0) ? abs((1.0 - z1 % 1.0) / zs) : abs((z1 % 1.0) / zs);
if ((i1 <= i2) && (i1 <= i3)) {
// step by i1
x1 += xs * (i1 + sv);
y1 += ys * (i1 + sv);
z1 += zs * (i1 + sv);
} else if ((i2 <= i1) && (i2 <= i3)) {
// step by i2
x1 += xs * (i2 + sv);
y1 += ys * (i2 + sv);
z1 += zs * (i2 + sv);
} else {
// step by i3
x1 += xs * (i3 + sv);
y1 += ys * (i3 + sv);
z1 += zs * (i3 + sv);
}
}
return SkyboxColor.getRGB();
}
private Color CalculateColor(Color c, double x1, double x2, double y1, double y2, double z1, double z2) {
double distance = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2) + Math.pow(z1 - z2, 2));
double lightIntensity = falloff/Math.pow(distance, rate);
double lightIntensity = falloff / Math.pow(distance, rate);
// calculate color components
int red = (int) (c.getRed() * lightIntensity);
red = (red > 255) ? 255 : red;
@ -206,7 +322,7 @@ public class Renderer {
green = (green > 255) ? 255 : green;
int blue = (int) (c.getBlue() * lightIntensity);
blue = (blue > 255) ? 255 : blue;
// return calculated color
return new Color(red, green, blue);
}