Merge pull request #2 from nopoe/master
Added multithreading and fixed step aliasing in renderG, now default render algorithmmaster
commit
280fd75c44
|
@ -1,2 +1,3 @@
|
||||||
*.class
|
*.class
|
||||||
*.jar
|
*.jar
|
||||||
|
*.policy.applet
|
|
@ -1,7 +0,0 @@
|
||||||
/* AUTOMATICALLY GENERATED ON Tue Apr 16 17:20:59 EDT 2002*/
|
|
||||||
/* DO NOT EDIT */
|
|
||||||
|
|
||||||
grant {
|
|
||||||
permission java.security.AllPermission;
|
|
||||||
};
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,57 @@
|
||||||
|
package voxelengine;
|
||||||
|
|
||||||
|
public class RayCastCollision {
|
||||||
|
private Block collisionBlock;
|
||||||
|
private int face;
|
||||||
|
|
||||||
|
private double x, y, z;
|
||||||
|
|
||||||
|
public RayCastCollision(Block collisionBlock, int face, double x, double y, double z) {
|
||||||
|
super();
|
||||||
|
this.collisionBlock = collisionBlock;
|
||||||
|
this.face = face;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getCollisionBlock() {
|
||||||
|
return collisionBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCollisionBlock(Block collisionBlock) {
|
||||||
|
this.collisionBlock = collisionBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFace() {
|
||||||
|
return face;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFace(int face) {
|
||||||
|
this.face = face;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(double x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(double y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZ(double z) {
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,8 +9,10 @@ import java.util.concurrent.*;
|
||||||
public class Renderer {
|
public class Renderer {
|
||||||
private World world;
|
private World world;
|
||||||
private Color SkyboxColor = Color.BLACK;
|
private Color SkyboxColor = Color.BLACK;
|
||||||
private double falloff = 8.0;
|
private double falloff = 4.0;
|
||||||
private double rate = 0.85;
|
private double rate = 0.6;
|
||||||
|
private double ambientIntensity = 0.2;
|
||||||
|
private double directionalIntensity = 0.3;
|
||||||
private int renderDistance = 8;
|
private int renderDistance = 8;
|
||||||
public Camera camera;
|
public Camera camera;
|
||||||
|
|
||||||
|
@ -311,8 +313,13 @@ public class Renderer {
|
||||||
return SkyboxColor.getRGB();
|
return SkyboxColor.getRGB();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryImageSource renderG(int width, int height, int pixelScale, int castScale) {
|
int[] mem = new int[0];
|
||||||
int[] mem = new int[width * height];
|
MemoryImageSource fb;
|
||||||
|
|
||||||
|
public MemoryImageSource renderG(int width, int height, int pixelScale, int castScale, boolean doShadows) {
|
||||||
|
if (mem.length != width * height) {
|
||||||
|
mem = new int[width * height]; // this is very marginally faster than recreating it every frame
|
||||||
|
}
|
||||||
double yaw = camera.rotY;
|
double yaw = camera.rotY;
|
||||||
double pitch = camera.rotX;
|
double pitch = camera.rotX;
|
||||||
double[][] ref = new double[][] { { sin(pitch) * cos(yaw), sin(pitch) * sin(yaw), -cos(pitch) },
|
double[][] ref = new double[][] { { sin(pitch) * cos(yaw), sin(pitch) * sin(yaw), -cos(pitch) },
|
||||||
|
@ -325,32 +332,38 @@ public class Renderer {
|
||||||
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||||
for (int py = 0; py < height - pixelScale; py += pixelScale) {
|
for (int py = 0; py < height - pixelScale; py += pixelScale) {
|
||||||
for (int px = 0; px < width - pixelScale; px += pixelScale) {
|
for (int px = 0; px < width - pixelScale; px += pixelScale) {
|
||||||
if (pixelScale == 1)
|
if (pixelScale == 1) {
|
||||||
service.execute(new PixelWorker(mem, new int[] { px + py * width }, px, py, width, height, ref));
|
service.execute(new PixelWorker(mem, new int[] { px + py * width }, px, py, width, height, ref,
|
||||||
else {
|
doShadows));
|
||||||
|
} else {
|
||||||
int[] fbIndices = new int[pixelScale * pixelScale];
|
int[] fbIndices = new int[pixelScale * pixelScale];
|
||||||
for (int pys = 0; pys < pixelScale; ++pys) {
|
for (int pys = 0; pys < pixelScale; ++pys) {
|
||||||
for (int pxs = 0; pxs < pixelScale; ++pxs) {
|
for (int pxs = 0; pxs < pixelScale; ++pxs) {
|
||||||
fbIndices[pys * pixelScale + pxs] = px + pxs + (py + pys) * width;
|
fbIndices[pys * pixelScale + pxs] = px + pxs + (py + pys) * width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
service.execute(new PixelWorker(mem, fbIndices, px, py, width, height, ref));
|
service.execute(new PixelWorker(mem, fbIndices, px, py, width, height, ref, doShadows));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
service.shutdown();
|
service.shutdown();
|
||||||
service.awaitTermination(1, TimeUnit.SECONDS);
|
service.awaitTermination(10, TimeUnit.SECONDS);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
if (fb == null) {
|
||||||
|
fb = new MemoryImageSource(width, height, mem, 0, width);
|
||||||
|
} else {
|
||||||
|
fb.newPixels(); // this is very marginally faster than recreating it
|
||||||
|
}
|
||||||
|
|
||||||
// return image source
|
// return image source
|
||||||
return new MemoryImageSource(width, height, mem, 0, width);
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int raycastG(int px, int py, int width, int height, double[][] ref) {
|
private RayCastCollision raycastGScreenCoords(int px, int py, int width, int height, double[][] ref) {
|
||||||
double w2 = width / 2.0;
|
double w2 = width / 2.0;
|
||||||
double h2 = height / 2.0;
|
double h2 = height / 2.0;
|
||||||
|
|
||||||
|
@ -368,64 +381,93 @@ public class Renderer {
|
||||||
ray[0] * ref[0][1] + ray[1] * ref[1][1] + ray[2] * ref[2][1],
|
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[0] * ref[0][2] + ray[1] * ref[1][2] + ray[2] * ref[2][2], };
|
||||||
|
|
||||||
|
return raycastG(x, y, z, ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RayCastCollision raycastG(double x, double y, double z, double[] ray) {
|
||||||
|
|
||||||
|
double startX = x;
|
||||||
|
double startY = y;
|
||||||
|
double startZ = z;
|
||||||
|
|
||||||
double dx = ray[0] * renderDistance * 16;
|
double dx = ray[0] * renderDistance * 16;
|
||||||
double dy = ray[1] * renderDistance * 16;
|
double dy = ray[1] * renderDistance * 16;
|
||||||
double dz = ray[2] * renderDistance * 16;
|
double dz = ray[2] * renderDistance * 16;
|
||||||
|
|
||||||
double exy, exz, ezy, ax, ay, az, bx, by, bz;
|
double rayMagnitude = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
|
||||||
|
double ax, ay, az;
|
||||||
|
|
||||||
int sx, sy, sz, n;
|
int sx, sy, sz, n;
|
||||||
|
|
||||||
|
double sv = Double.MIN_NORMAL;
|
||||||
|
|
||||||
sx = (int) Math.signum(dx);
|
sx = (int) Math.signum(dx);
|
||||||
sy = (int) Math.signum(dy);
|
sy = (int) Math.signum(dy);
|
||||||
sz = (int) Math.signum(dz);
|
sz = (int) Math.signum(dz);
|
||||||
|
|
||||||
ax = Math.abs(dx);
|
ax = Math.abs(dx) / rayMagnitude;
|
||||||
ay = Math.abs(dy);
|
ay = Math.abs(dy) / rayMagnitude;
|
||||||
az = Math.abs(dz);
|
az = Math.abs(dz) / rayMagnitude;
|
||||||
|
|
||||||
bx = 2 * ax;
|
ax = ((ax > sv) ? ax : sv);
|
||||||
by = 2 * ay;
|
ay = ((ay > sv) ? ay : sv);
|
||||||
bz = 2 * az;
|
az = ((az > sv) ? az : sv);
|
||||||
|
|
||||||
exy = ay - ax;
|
double tDeltaX = 1 / ax;
|
||||||
exz = az - ax;
|
double tDeltaY = 1 / ay;
|
||||||
ezy = ay - az;
|
double tDeltaZ = 1 / az;
|
||||||
|
|
||||||
n = (int) (ax + ay + az);
|
double tMaxX = Math.abs((sx == 1) ? (1 - (x % 1.0)) : (x % 1.0)) / ax;
|
||||||
|
double tMaxY = Math.abs((sy == 1) ? (1 - (y % 1.0)) : (y % 1.0)) / ay;
|
||||||
|
double tMaxZ = Math.abs((sz == 1) ? (1 - (z % 1.0)) : (z % 1.0)) / az;
|
||||||
|
|
||||||
|
n = (int) (Math.abs(dx) + Math.abs(dy) + Math.abs(dz));
|
||||||
|
|
||||||
|
int face = -1;
|
||||||
|
|
||||||
while (n-- != 0) {
|
while (n-- != 0) {
|
||||||
Block block = world.getBlock(x, y, z);
|
if (tMaxX < tMaxY) {
|
||||||
if (block != null) {
|
if (tMaxX < tMaxZ) {
|
||||||
Color c = block.getType().getColor();
|
face = 0;
|
||||||
c = CalculateColor(c, camera.x, x, camera.y, y, camera.z, z);
|
|
||||||
return c.getRGB();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exy < 0) {
|
|
||||||
if (exz < 0) {
|
|
||||||
x += sx;
|
x += sx;
|
||||||
exy += by;
|
tMaxX += tDeltaX;
|
||||||
exz += bz;
|
|
||||||
} else {
|
} else {
|
||||||
|
face = 2;
|
||||||
z += sz;
|
z += sz;
|
||||||
exz -= bx;
|
tMaxZ += tDeltaZ;
|
||||||
ezy += by;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ezy < 0) {
|
if (tMaxY < tMaxZ) {
|
||||||
z += sz;
|
face = 1;
|
||||||
exz -= bx;
|
|
||||||
ezy += by;
|
|
||||||
} else {
|
|
||||||
y += sy;
|
y += sy;
|
||||||
exy -= bx;
|
tMaxY += tDeltaY;
|
||||||
ezy -= bz;
|
} else {
|
||||||
|
face = 2;
|
||||||
|
z += sz;
|
||||||
|
tMaxZ += tDeltaZ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Block block = world.getBlock(x, y, z);
|
||||||
|
if (block != null) {
|
||||||
|
double t = 0;
|
||||||
|
switch (face) {
|
||||||
|
case 0:
|
||||||
|
t = tMaxX - tDeltaX - 0.01;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
t = tMaxY - tDeltaY - 0.01;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
t = tMaxZ - tDeltaZ - 0.01;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new RayCastCollision(block, face, t * dx / rayMagnitude + startX,
|
||||||
|
t * dy / rayMagnitude + startY, t * dz / rayMagnitude + startZ);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SkyboxColor.getRGB();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color CalculateColor(Color c, double x1, double x2, double y1, double y2, double z1, double z2) {
|
private Color CalculateColor(Color c, double x1, double x2, double y1, double y2, double z1, double z2) {
|
||||||
|
@ -444,6 +486,42 @@ public class Renderer {
|
||||||
return new Color(red, green, blue);
|
return new Color(red, green, blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Color CalculateColor(Color c, double x1, double x2, double y1, double y2, double z1, double z2, int face,
|
||||||
|
double directionalDot) {
|
||||||
|
double ray[] = { x1 - x2, y1 - y2, z1 - z2 };
|
||||||
|
double distance = Math.sqrt(ray[0] * ray[0] + ray[1] * ray[1] + ray[2] * ray[2]);
|
||||||
|
ray[0] /= distance;
|
||||||
|
ray[1] /= distance;
|
||||||
|
ray[2] /= distance;
|
||||||
|
double dot = 0;
|
||||||
|
switch (face) {
|
||||||
|
case 0:
|
||||||
|
dot = Math.abs(ray[0]);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dot = Math.abs(ray[1]);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dot = Math.abs(ray[2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
double diffuseIntensity = Math.max(falloff / Math.pow(distance, rate), 1.0) * dot;
|
||||||
|
double lightIntensity = ambientIntensity + (1 - ambientIntensity - directionalIntensity) * diffuseIntensity;
|
||||||
|
|
||||||
|
lightIntensity += directionalIntensity * directionalDot;
|
||||||
|
|
||||||
|
// calculate color components
|
||||||
|
int red = (int) (c.getRed() * lightIntensity);
|
||||||
|
red = (red > 255) ? 255 : red;
|
||||||
|
int green = (int) (c.getGreen() * lightIntensity);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
private class PixelWorker implements Runnable {
|
private class PixelWorker implements Runnable {
|
||||||
|
|
||||||
private int[] framebuffer;
|
private int[] framebuffer;
|
||||||
|
@ -453,8 +531,10 @@ public class Renderer {
|
||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
private double[][] ref;
|
private double[][] ref;
|
||||||
|
private boolean doShadows;
|
||||||
|
|
||||||
public PixelWorker(int[] framebuffer, int[] fbIndices, int px, int py, int width, int height, double[][] ref) {
|
public PixelWorker(int[] framebuffer, int[] fbIndices, int px, int py, int width, int height, double[][] ref,
|
||||||
|
boolean doShadows) {
|
||||||
this.framebuffer = framebuffer;
|
this.framebuffer = framebuffer;
|
||||||
this.fbIndices = fbIndices;
|
this.fbIndices = fbIndices;
|
||||||
this.px = px;
|
this.px = px;
|
||||||
|
@ -462,14 +542,48 @@ public class Renderer {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.ref = ref;
|
this.ref = ref;
|
||||||
|
this.doShadows = doShadows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double[] lightRay = { renderDistance * 8, renderDistance * 2, renderDistance * 4 };
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int result = Renderer.this.raycastG(px, py, width, height, ref);
|
RayCastCollision result = Renderer.this.raycastGScreenCoords(px, py, width, height, ref);
|
||||||
|
Color c;
|
||||||
|
double lightRayMagnitude = Math.sqrt(lightRay[0] * lightRay[0] + lightRay[1] * lightRay[1] + lightRay[2]
|
||||||
|
* lightRay[2]);
|
||||||
|
if (result != null) {
|
||||||
|
Block block = result.getCollisionBlock();
|
||||||
|
double x = result.getX();
|
||||||
|
double y = result.getY();
|
||||||
|
double z = result.getZ();
|
||||||
|
double lightDot = 0;
|
||||||
|
if (doShadows) {
|
||||||
|
RayCastCollision lightOcclusion = Renderer.this.raycastG(result.getX(), result.getY(),
|
||||||
|
result.getZ(), lightRay);
|
||||||
|
if (lightOcclusion == null) {
|
||||||
|
switch (result.getFace()) {
|
||||||
|
case 0:
|
||||||
|
lightDot = Math.abs(lightRay[0] / lightRayMagnitude);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
lightDot = Math.abs(lightRay[1] / lightRayMagnitude);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
lightDot = Math.abs(lightRay[2] / lightRayMagnitude);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = Renderer.this.CalculateColor(block.getType().getColor(), camera.x, x, camera.y, y, camera.z, z,
|
||||||
|
result.getFace(), lightDot);
|
||||||
|
} else {
|
||||||
|
c = SkyboxColor;
|
||||||
|
}
|
||||||
synchronized (framebuffer) {
|
synchronized (framebuffer) {
|
||||||
for (int index : fbIndices) {
|
for (int index : fbIndices) {
|
||||||
framebuffer[index] = result;
|
framebuffer[index] = c.getRGB();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@ public class SwingInterface extends JPanel {
|
||||||
private static final int Y_SIZE = 600;
|
private static final int Y_SIZE = 600;
|
||||||
private static int pixelScale = 4;
|
private static int pixelScale = 4;
|
||||||
private static int castScale = 4;
|
private static int castScale = 4;
|
||||||
|
|
||||||
|
private static boolean doShadows = false;
|
||||||
|
|
||||||
public SwingInterface() {
|
public SwingInterface() {
|
||||||
new Worker().execute();
|
new Worker().execute();
|
||||||
}
|
}
|
||||||
|
@ -48,7 +50,9 @@ public class SwingInterface extends JPanel {
|
||||||
set_up();
|
set_up();
|
||||||
int frames = 0;
|
int frames = 0;
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
|
|
||||||
|
long lastFrameNanos = System.nanoTime();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
frames++;
|
frames++;
|
||||||
if (frames == 30) {
|
if (frames == 30) {
|
||||||
|
@ -58,11 +62,12 @@ public class SwingInterface extends JPanel {
|
||||||
frames = 0;
|
frames = 0;
|
||||||
time = System.currentTimeMillis();
|
time = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
process_input();
|
process_input((System.nanoTime() - lastFrameNanos) / 1000000000.0);
|
||||||
Image img = createImage(renderer.renderF(X_SIZE, Y_SIZE, pixelScale, castScale));
|
lastFrameNanos = System.nanoTime();
|
||||||
|
Image img = createImage(renderer.renderG(X_SIZE, Y_SIZE, pixelScale, castScale, doShadows));
|
||||||
BufferedImage buffer = new BufferedImage(X_SIZE, Y_SIZE, BufferedImage.TYPE_INT_ARGB);
|
BufferedImage buffer = new BufferedImage(X_SIZE, Y_SIZE, BufferedImage.TYPE_INT_ARGB);
|
||||||
Graphics2D g2 = buffer.createGraphics();
|
Graphics2D g2 = buffer.createGraphics();
|
||||||
g2.drawImage(img, 0, 0, null);
|
g2.drawImage(img, 0, 0, null);
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
publish(buffer);
|
publish(buffer);
|
||||||
}
|
}
|
||||||
|
@ -103,41 +108,44 @@ public class SwingInterface extends JPanel {
|
||||||
renderer = new Renderer(world, camera);
|
renderer = new Renderer(world, camera);
|
||||||
System.out.println("World set up. Now rendering...");
|
System.out.println("World set up. Now rendering...");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process_input() {
|
private void process_input(double timestep) {
|
||||||
|
final int movement_scale = 15;
|
||||||
|
final int rotation_scale = 15;
|
||||||
|
|
||||||
if (keyboard.isKeyDown('A')) {
|
if (keyboard.isKeyDown('A')) {
|
||||||
camera.x += Math.cos(camera.rotY - Math.PI / 2);
|
camera.x += timestep * movement_scale * Math.cos(camera.rotY - Math.PI / 2);
|
||||||
camera.y += Math.sin(camera.rotY - Math.PI / 2);
|
camera.y += timestep * movement_scale * Math.sin(camera.rotY - Math.PI / 2);
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('D')) {
|
if (keyboard.isKeyDown('D')) {
|
||||||
camera.x += Math.cos(camera.rotY + Math.PI / 2);
|
camera.x += timestep * movement_scale * Math.cos(camera.rotY + Math.PI / 2);
|
||||||
camera.y += Math.sin(camera.rotY + Math.PI / 2);
|
camera.y += timestep * movement_scale * Math.sin(camera.rotY + Math.PI / 2);
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('W')) {
|
if (keyboard.isKeyDown('W')) {
|
||||||
camera.x += Math.cos(camera.rotY);
|
camera.x += timestep * movement_scale * Math.cos(camera.rotY);
|
||||||
camera.y += Math.sin(camera.rotY);
|
camera.y += timestep * movement_scale * Math.sin(camera.rotY);
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('S')) {
|
if (keyboard.isKeyDown('S')) {
|
||||||
camera.x += Math.cos(camera.rotY + Math.PI);
|
camera.x += timestep * movement_scale * Math.cos(camera.rotY + Math.PI);
|
||||||
camera.y += Math.sin(camera.rotY + Math.PI);
|
camera.y += timestep * movement_scale * Math.sin(camera.rotY + Math.PI);
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('Q')) {
|
if (keyboard.isKeyDown('Q')) {
|
||||||
camera.z -= 1;
|
camera.z -= timestep * movement_scale;
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('E')) {
|
if (keyboard.isKeyDown('E')) {
|
||||||
camera.z += 1;
|
camera.z += timestep * movement_scale;
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('J')) {
|
if (keyboard.isKeyDown('J')) {
|
||||||
camera.rotY -= Math.PI / 32;
|
camera.rotY -= timestep * rotation_scale * Math.PI / 32;
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('L')) {
|
if (keyboard.isKeyDown('L')) {
|
||||||
camera.rotY += Math.PI / 32;
|
camera.rotY += timestep * rotation_scale * Math.PI / 32;
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('I')) {
|
if (keyboard.isKeyDown('I')) {
|
||||||
camera.rotX += Math.PI / 32;
|
camera.rotX += timestep * rotation_scale * Math.PI / 32;
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('K')) {
|
if (keyboard.isKeyDown('K')) {
|
||||||
camera.rotX -= Math.PI / 32;
|
camera.rotX -= timestep * rotation_scale * Math.PI / 32;
|
||||||
}
|
}
|
||||||
if (keyboard.isKeyDown('T')) {
|
if (keyboard.isKeyDown('T')) {
|
||||||
pixelScale++;
|
pixelScale++;
|
||||||
|
@ -151,6 +159,13 @@ public class SwingInterface extends JPanel {
|
||||||
if (keyboard.isKeyDown('H')) {
|
if (keyboard.isKeyDown('H')) {
|
||||||
castScale--;
|
castScale--;
|
||||||
}
|
}
|
||||||
|
if (keyboard.isKeyDown('P')) { // P is for pretty
|
||||||
|
doShadows = true;
|
||||||
|
pixelScale = 1;
|
||||||
|
} else {
|
||||||
|
doShadows = false;
|
||||||
|
pixelScale = 4;
|
||||||
|
}
|
||||||
camera.rotY = camera.rotY % (Math.PI * 2);
|
camera.rotY = camera.rotY % (Math.PI * 2);
|
||||||
camera.rotX = Math.max(Math.min(camera.rotX, Math.PI), 0);
|
camera.rotX = Math.max(Math.min(camera.rotX, Math.PI), 0);
|
||||||
pixelScale = Math.max(Math.min(pixelScale, 10), 1);
|
pixelScale = Math.max(Math.min(pixelScale, 10), 1);
|
||||||
|
|
Loading…
Reference in New Issue