aboutsummaryrefslogtreecommitdiffstats
path: root/src/ru
diff options
context:
space:
mode:
authorolamedia <[email protected]>2012-10-17 09:52:48 +0600
committerolamedia <[email protected]>2012-10-17 09:52:48 +0600
commit5320fd1dad5b77fa227e83fbbe0a958f2c5fc283 (patch)
tree1b49b91cf820ad5536241fa093c34fd2ae9731db /src/ru
parente2b667011c8fc93388c3ebee6e2a64090456e2a1 (diff)
fps
Diffstat (limited to 'src/ru')
-rw-r--r--src/ru/olamedia/camera/MatrixCamera.java13
-rw-r--r--src/ru/olamedia/game/GameFrame.java4
-rw-r--r--src/ru/olamedia/game/GameTime.java4
-rw-r--r--src/ru/olamedia/geom/Frustum.java2
-rw-r--r--src/ru/olamedia/geom/Mesh.java31
-rw-r--r--src/ru/olamedia/geom/SimpleQuadMesh.java12
-rw-r--r--src/ru/olamedia/liveEntity/LiveEntity.java18
-rw-r--r--src/ru/olamedia/olacraft/network/GameClient.java6
-rw-r--r--src/ru/olamedia/olacraft/network/GameServer.java2
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java294
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/joglViewport.java6
-rw-r--r--src/ru/olamedia/olacraft/scene/GameScene.java177
-rw-r--r--src/ru/olamedia/olacraft/world/block/Block.java235
-rw-r--r--src/ru/olamedia/olacraft/world/block/BlockRegistry.java17
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java5
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java23
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/StoneBlockType.java29
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/BlockSlice.java3
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/Chunk.java72
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java5
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java42
-rw-r--r--src/ru/olamedia/olacraft/world/data/ChunkData.java147
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java23
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java3
-rw-r--r--src/ru/olamedia/olacraft/world/generator/RegionGenerator.java4
-rw-r--r--src/ru/olamedia/olacraft/world/location/BlockLocation.java37
-rw-r--r--src/ru/olamedia/olacraft/world/location/ChunkLocation.java34
-rw-r--r--src/ru/olamedia/olacraft/world/provider/WorldProvider.java14
-rw-r--r--src/ru/olamedia/player/Player.java23
29 files changed, 922 insertions, 363 deletions
diff --git a/src/ru/olamedia/camera/MatrixCamera.java b/src/ru/olamedia/camera/MatrixCamera.java
index e93e25c..b9290b7 100644
--- a/src/ru/olamedia/camera/MatrixCamera.java
+++ b/src/ru/olamedia/camera/MatrixCamera.java
@@ -10,8 +10,6 @@ import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
import javax.vecmath.Vector3f;
-import org.openmali.FastMath;
-
import ru.olamedia.olacraft.game.Game;
import ru.olamedia.input.Keyboard;
import ru.olamedia.math.Frustum;
@@ -25,6 +23,8 @@ public class MatrixCamera {
private boolean isDirty = true;
public GLUniformData pmvMatrixUniform;
+ public boolean isOrientationChanged = true;
+
protected float fov = 90f;
protected float aspect = 1f;
protected float zNear = 0.1f;
@@ -85,7 +85,7 @@ public class MatrixCamera {
ru.olamedia.math.Vector3f eyef = eye;// .translate(look, 1f);
nearc = eyef.translate(look, nearD);
ru.olamedia.math.Vector3f farc = eyef.translate(look, farD);
- final float tang = FastMath.tan(FastMath.toRad(fov) / 2.0f);
+ final float tang = (float) Math.tan((Math.PI * fov / 180) / 2.0f);
float nh = nearD * tang * (isFrustumVisible ? 0.3f : 1);// zNear * tang;
float nw = nh * aspect * aspect;
float fh = farD * tang * (isFrustumVisible ? 0.5f : 1);// zNear * tang;
@@ -143,9 +143,11 @@ public class MatrixCamera {
edge1.sub(vertex2, vertex1);
edge2.sub(vertex3, vertex1);
+ Vector3f nlook = new Vector3f(look);
+ nlook.negate();
// Compute the determinant.
Vector3f directionCrossEdge2 = new Vector3f();
- directionCrossEdge2.cross(look, edge2);
+ directionCrossEdge2.cross(nlook, edge2);
float determinant = directionCrossEdge2.dot(edge1);
// If the ray and triangle are parallel, there is no collision.
@@ -171,7 +173,7 @@ public class MatrixCamera {
Vector3f distanceCrossEdge1 = new Vector3f();
distanceCrossEdge1.cross(distanceVector, edge1);
- float triangleV = look.dot(distanceCrossEdge1);
+ float triangleV = nlook.dot(distanceCrossEdge1);
triangleV *= inverseDeterminant;
// Make sure the V is inside the triangle.
@@ -231,6 +233,7 @@ public class MatrixCamera {
yaw = yaw % 360;
pitch = pitch % 360;
setDirty();
+ isOrientationChanged = true;
}
public void updateMouse() {
diff --git a/src/ru/olamedia/game/GameFrame.java b/src/ru/olamedia/game/GameFrame.java
index e768b63..973fcb8 100644
--- a/src/ru/olamedia/game/GameFrame.java
+++ b/src/ru/olamedia/game/GameFrame.java
@@ -26,6 +26,7 @@ import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.FPSAnimator;
public class GameFrame {
// java.awt.SystemTray
@@ -66,7 +67,8 @@ public class GameFrame {
glWindow.confinePointer(false);
glWindow.addWindowListener(new QuitAdapter());
animator = new Animator(glWindow);
- animator.setRunAsFastAsPossible(true); // By default there is a
+ //animator = new FPSAnimator(glWindow, 60);
+ //animator.setRunAsFastAsPossible(true); // By default there is a
// brief
// pause in the animation
// loop
diff --git a/src/ru/olamedia/game/GameTime.java b/src/ru/olamedia/game/GameTime.java
index 7e4880f..bd687d9 100644
--- a/src/ru/olamedia/game/GameTime.java
+++ b/src/ru/olamedia/game/GameTime.java
@@ -131,7 +131,9 @@ public class GameTime {
spaceLightIsInvalid = true;
receivedLightIsInvalid = true;
}
- float[] sunSkyColors = new float[] { 0.5f, 0.7f, 1f };
+ //float[] sunSkyColors = new float[] { (float) 179 / 255, (float) 195 / 255, (float) 184 / 255 };
+ //float[] sunSkyColors = new float[] { (float) 209 / 255, (float) 227 / 255, (float) 251 / 255 };
+ float[] sunSkyColors = new float[] { (float) 203 / 255, (float) 233 / 255, (float) 244 / 255 };
for (int i = 0; i < 3; i++) {
clearColors[i] = addComponent(sunSkyColors[i] * (float) sunlightFactor, spaceColors[i]);
}
diff --git a/src/ru/olamedia/geom/Frustum.java b/src/ru/olamedia/geom/Frustum.java
index 5428302..2065157 100644
--- a/src/ru/olamedia/geom/Frustum.java
+++ b/src/ru/olamedia/geom/Frustum.java
@@ -3,9 +3,7 @@ package ru.olamedia.geom;
//import org.openmali.spatial.bodies.Frustum;
public class Frustum extends org.openmali.spatial.bodies.Frustum {
-
public Frustum() {
super();
}
-
}
diff --git a/src/ru/olamedia/geom/Mesh.java b/src/ru/olamedia/geom/Mesh.java
index 92f5666..bda53b9 100644
--- a/src/ru/olamedia/geom/Mesh.java
+++ b/src/ru/olamedia/geom/Mesh.java
@@ -16,6 +16,17 @@ import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.texture.Texture;
public class Mesh {
+ public void invalidate() {
+ buffer = null;
+ data = null;
+ vertexCount = 0;
+ data = new float[size * vertexSize];
+ // data = new float[size * vertexSize];
+ vertexPtr = 0;
+ useTexture = false;
+ useColor = false;
+ }
+
private FloatBuffer buffer;
private float[] data;
private int ptr;
@@ -63,14 +74,11 @@ public class Mesh {
private static boolean useQuad = true;
private static boolean useDisplayList = false;
private DisplayList DL;
+ private int size = 0;
public Mesh(int size) {
- vertexCount = 0;
- data = new float[size * vertexSize];
- // data = new float[size * vertexSize];
- vertexPtr = 0;
- useTexture = false;
- useColor = false;
+ this.size = size;
+ invalidate();
}
private static FloatBuffer generateFloatBuffer(int size) {
@@ -217,10 +225,15 @@ public class Mesh {
return;
}
GL glx = GLContext.getCurrentGL();
+ if (true){
+ GL2 gl = glx.getGL2();
+ gl.glShadeModel(GL2.GL_FLAT);
+ }
if (useVbo) {
GL2ES2 gl = glx.getGL2ES2();
- //GL2 gl = glx.getGL2();
+ // GL2 gl = glx.getGL2();
for (Integer m : materials.keySet()) {
+
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glBindTexture(GL.GL_TEXTURE_2D, (int) m);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
@@ -228,10 +241,10 @@ public class Mesh {
arrays.get(m).enableBuffer(gl, true);
gl.glEnable(GL.GL_CULL_FACE);
gl.glEnable(GL.GL_DEPTH_TEST);
- //gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL);
+ // gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL);
gl.glDrawArrays(GL2.GL_QUADS, 0, arrays.get(m).getElementCount());
arrays.get(m).enableBuffer(gl, false);
- //System.exit(0);
+ // System.exit(0);
}
} else {
GL2 gl = glx.getGL2();
diff --git a/src/ru/olamedia/geom/SimpleQuadMesh.java b/src/ru/olamedia/geom/SimpleQuadMesh.java
index e832789..ad3c27c 100644
--- a/src/ru/olamedia/geom/SimpleQuadMesh.java
+++ b/src/ru/olamedia/geom/SimpleQuadMesh.java
@@ -2,6 +2,16 @@ package ru.olamedia.geom;
public class SimpleQuadMesh extends Mesh {
+ public boolean restart = true;
+
+ public void restart() {
+ restart = true;
+ }
+
+ public void start() {
+ restart = false;
+ }
+
public SimpleQuadMesh(int size) {
super(size * 4);
}
@@ -110,6 +120,4 @@ public class SimpleQuadMesh extends Mesh {
addBottomRightFrontVertex();
}
-
-
}
diff --git a/src/ru/olamedia/liveEntity/LiveEntity.java b/src/ru/olamedia/liveEntity/LiveEntity.java
index dd60310..1befec6 100644
--- a/src/ru/olamedia/liveEntity/LiveEntity.java
+++ b/src/ru/olamedia/liveEntity/LiveEntity.java
@@ -4,6 +4,7 @@ import javax.vecmath.Vector3f;
import com.jogamp.newt.event.KeyEvent;
+import ru.olamedia.Options;
import ru.olamedia.camera.Cameraman;
import ru.olamedia.olacraft.game.Game;
import ru.olamedia.olacraft.inventory.Inventory;
@@ -23,6 +24,7 @@ public class LiveEntity implements Cameraman {
private float z;
public Vector3f velocity = new Vector3f(0, 0, 0);
public Vector3f acceleration = new Vector3f(0, 0, 0);
+ public boolean isOrientationChanged = true;
private float fov = 90f;
private float mouseSpeed = 1.0f;
@@ -125,7 +127,13 @@ public class LiveEntity implements Cameraman {
boolean keyJump = Keyboard.isKeyDown("playerJump");
boolean keySneak = Keyboard.isKeyDown("playerSneak");
boolean keyCrouch = Keyboard.isKeyDown("playerCrouch");
-
+ boolean keyRenderDistance = Keyboard.isKeyDown("playerRenderDistance");
+ if (keyRenderDistance) {
+ Options.renderDistance *= 2;
+ if (Options.renderDistance > 256) {
+ Options.renderDistance = 32;
+ }
+ }
if (keySneak) {
if (!isSneaking) {
isSneaking = true;
@@ -391,7 +399,7 @@ public class LiveEntity implements Cameraman {
Game.client.getWorldProvider().loadChunk(loc.getChunkLocation());
return false;
}
-
+
try {
return Game.client.getWorldProvider().isEmptyBlock((int) x + dx, (int) Math.ceil(y) + dy, (int) z + dz);
} catch (ChunkUnavailableException e) {
@@ -563,6 +571,7 @@ public class LiveEntity implements Cameraman {
// }
// }
if (isPositionChanged) {
+ isOrientationChanged = true;
notifyLocationUpdate();
}
}
@@ -625,6 +634,10 @@ public class LiveEntity implements Cameraman {
return y + getCameraLevel();
}
+ public BlockLocation getCameraBlockLocation() {
+ return new BlockLocation(x, y, z);
+ }
+
@Override
public float getCameraZ() {
return z;
@@ -640,6 +653,7 @@ public class LiveEntity implements Cameraman {
Keyboard.setName("playerJump", KeyEvent.VK_SPACE);
Keyboard.setName("playerSneak", KeyEvent.VK_SHIFT);
Keyboard.setName("playerCrouch", KeyEvent.VK_CONTROL);
+ Keyboard.setName("playerRenderDistance", KeyEvent.VK_F4);
}
public void setId(int id) {
diff --git a/src/ru/olamedia/olacraft/network/GameClient.java b/src/ru/olamedia/olacraft/network/GameClient.java
index 2312c3d..f74340a 100644
--- a/src/ru/olamedia/olacraft/network/GameClient.java
+++ b/src/ru/olamedia/olacraft/network/GameClient.java
@@ -25,7 +25,6 @@ import ru.olamedia.olacraft.network.packet.WorldInfoPacket;
import ru.olamedia.olacraft.scene.GameScene;
import ru.olamedia.olacraft.world.WorldInfo;
import ru.olamedia.olacraft.world.dataProvider.CachedChunkDataProvider;
-import ru.olamedia.olacraft.world.dataProvider.LocalChunkDataProvider;
import ru.olamedia.olacraft.world.dataProvider.RemoteChunkDataProvider;
import ru.olamedia.olacraft.world.provider.WorldProvider;
@@ -33,7 +32,7 @@ public class GameClient extends ConnectionStateListener implements IPacketListen
private WorldProvider worldProvider;
private GameScene scene;
- private Client client = new Client(10 * 1024 * 1024, 10 * 1024 * 1024);
+ private Client client = new Client(10 * 1024 * 1024, 30 * 1024 * 1024);
private String hostname = "127.0.0.1";
@Override
@@ -65,7 +64,8 @@ public class GameClient extends ConnectionStateListener implements IPacketListen
// INIT WORLD
worldProvider = new WorldProvider();
worldProvider.setChunkDataProvider(new CachedChunkDataProvider(new RemoteChunkDataProvider(this)));
- //worldProvider.setChunkDataProvider(new CachedChunkDataProvider(new LocalChunkDataProvider(worldProvider.getInfo().name)));
+ // worldProvider.setChunkDataProvider(new CachedChunkDataProvider(new
+ // LocalChunkDataProvider(worldProvider.getInfo().name)));
// CREATE SCENE
scene = new GameScene(worldProvider);
Kryo kryo = client.getKryo();
diff --git a/src/ru/olamedia/olacraft/network/GameServer.java b/src/ru/olamedia/olacraft/network/GameServer.java
index e1e7723..717b40b 100644
--- a/src/ru/olamedia/olacraft/network/GameServer.java
+++ b/src/ru/olamedia/olacraft/network/GameServer.java
@@ -33,7 +33,7 @@ public class GameServer {
private WorldProvider worldProvider;
private ExecutorService threadPool = Executors.newFixedThreadPool(1);
- public static Server server = new Server(10 * 1024 * 1024, 1024 * 1024) {
+ public static Server server = new Server(30 * 1024 * 1024, 1024 * 1024) {
@Override
protected PlayerConnection newConnection() {
// By providing our own connection implementation, we can store per
diff --git a/src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java b/src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java
index f53bba6..4aaf38c 100644
--- a/src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java
+++ b/src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java
@@ -1,7 +1,5 @@
package ru.olamedia.olacraft.render.jogl;
-import javax.media.opengl.GLAutoDrawable;
-
import ru.olamedia.Options;
import ru.olamedia.geom.SimpleQuadMesh;
import ru.olamedia.math.Box;
@@ -21,6 +19,8 @@ public class ChunkRenderer {
this.slice = slice;
}
+ public int testedChunks = 0;
+
public int visibleTop = 0;
public int visibleBottom = 0;
public int visibleLeft = 0;
@@ -32,20 +32,16 @@ public class ChunkRenderer {
public int frustumIntersectChunks = 0;
public boolean renderChunk(Chunk chunk, boolean skipnew) {
-
- if (!chunk.isAvailable()) {
- System.out.println("not available " + chunk);
- chunk.request();
+ float d = (float) Math.sqrt(Math.pow(chunk.getOffset().x + 8 - cameraBlock.x, 2)
+ + Math.pow(chunk.getOffset().y + 8 - cameraBlock.y, 2)
+ + Math.pow(chunk.getOffset().z + 8 - cameraBlock.z, 2));
+ if (d > Options.renderDistance) {
return skipnew;
}
-
- if (!chunk.isNeighborsAvailable()) {
- System.out.println("not available " + chunk);
- chunk.requestNeighbors();
+ testedChunks++;
+ if (!chunk.inWorldRange()) {
return skipnew;
}
-
- // System.out.println("available");
Box box = new Box(chunk.getOffset().x, chunk.getOffset().y, chunk.getOffset().z, chunk.getOffset().x
+ chunk.getWidth(), chunk.getOffset().y + chunk.getHeight(), chunk.getOffset().z + chunk.getDepth());
if (Game.instance.camera.frustum.quickClassify(box) == Classifier.OUTSIDE) {
@@ -53,53 +49,74 @@ public class ChunkRenderer {
return skipnew;
}
- // // boolean inside = true;
- // if (Game.camera.frustum != null) {
- // if (Game.camera.frustum.quickClassify(box) ==
- // Classifier.Classification.OUTSIDE) {
- // frustumCulledChunks++;
- // return;
- // }
- // }
- // } else if (Game.camera.frustum.test(box) == Classifier.INTERSECT) {
- // inside = false;
- // frustumIntersectChunks++;
- // } else {
- // frustumCulledChunks++;
- // return;
- // }
+ chunk.render();
if (!chunk.isMeshCostructed) {
- if (skipnew) {
+ if (!chunk.isAvailable()) {
+ // System.out.println("not available " + chunk);
+ chunk.request();
return skipnew;
}
- }
- if (!chunk.isMeshCostructed) {
- ChunkMeshBulder.instance.add(chunk);
- if (ChunkMeshBulder.instance.isFull()) {
- // System.out.println("queue is full, skipping");
- skipnew = true;
+
+ if (!chunk.isNeighborsAvailable()) {
+ // System.out.println("not available " + chunk);
+ chunk.requestNeighbors();
+ return skipnew;
}
- // System.out.println("not constructed");
+ // compute visibility
+
+ // System.out.println("available");
+
+ // // boolean inside = true;
+ // if (Game.camera.frustum != null) {
+ // if (Game.camera.frustum.quickClassify(box) ==
+ // Classifier.Classification.OUTSIDE) {
+ // frustumCulledChunks++;
+ // return;
+ // }
+ // }
+ // } else if (Game.camera.frustum.test(box) == Classifier.INTERSECT)
+ // {
+ // inside = false;
+ // frustumIntersectChunks++;
+ // } else {
+ // frustumCulledChunks++;
+ // return;
+ // }
+ if (!chunk.isMeshCostructed) {
+ if (skipnew) {
+ return skipnew;
+ }
+ }
+ if (!chunk.isMeshCostructed) {
+ ChunkMeshBulder.instance.add(chunk);
+ if (ChunkMeshBulder.instance.isFull()) {
+ // System.out.println("queue is full, skipping");
+ skipnew = true;
+ }
+ // System.out.println("not constructed");
+ return skipnew;
+ }
+
return skipnew;
- }
- if (null == chunk.getMesh()) {
- // System.out.println("mesh is null");
- // skipnew = true;
} else {
- SimpleQuadMesh mesh = chunk.getMesh();
- // System.out.println("render " + chunk + " " +
- // mesh.getVertexCount());
- mesh.joglRender();
+ return skipnew;
}
- return skipnew;
}
- public void render(GLAutoDrawable drawable) {
+ BlockLocation cameraBlock;
+ ChunkLocation cameraChunk;
+ int distance;
+ public ChunkSlice chunkSlice;
+
+ public void render() {
if (!ChunkMeshBulder.instance.isAlive() && !ChunkMeshBulder.instance.isInterrupted()) {
ChunkMeshBulder.instance.start();
}
-
+ if (null == chunkSlice) {
+ chunkSlice = slice.getChunkSlice();
+ }
+ testedChunks = 0;
visibleTop = 0;
visibleBottom = 0;
visibleLeft = 0;
@@ -107,164 +124,45 @@ public class ChunkRenderer {
visibleFront = 0;
visibleBack = 0;
frustumCulledChunks = 0;
+
+ cameraBlock = Game.client.getScene().getPlayer().getCameraBlockLocation();
+ cameraChunk = cameraBlock.getChunkLocation();
+ ChunkLocation renderLoc;
+
boolean skipnew = false;
- ChunkSlice cs = slice.getChunkSlice();
- for (int x = cs.getX(); x < cs.getX() + cs.getWidth(); x++) {
- for (int z = cs.getZ(); z < cs.getZ() + cs.getDepth(); z++) {
- for (int y = cs.getY(); y < cs.getY() + cs.getHeight(); y++) {
- skipnew = renderChunk(cs.getChunk(new ChunkLocation(x, y, z)), skipnew);
- }
- }
- }
- if (true) {
- return;
- }
- // rendering from center
- int x, y, z;
- int half = (Options.renderDistance / 16) / 2 + 1;
- BlockLocation camera = new BlockLocation();
- camera.x = (int) Game.client.getScene().getPlayer().getCameraX();
- camera.y = (int) Game.client.getScene().getPlayer().getCameraY();
- camera.z = (int) Game.client.getScene().getPlayer().getCameraZ();
- ChunkLocation cameraChunk = camera.getChunkLocation();
- int cx = cameraChunk.x;
- int cy = cameraChunk.y;
- int cz = cameraChunk.z;
- ChunkLocation cLoc = new ChunkLocation(cx, cy, cz);
- for (int r = 0; r <= half; r++) {
- // +x
- x = cx + r;
- for (z = cz - r - 1; z <= cz + r; z++) {
- for (y = cy - r - 1; y <= cy + r; y++) {
- cLoc = new ChunkLocation(x, y, z);
- skipnew = renderChunk(cs.getChunk(cLoc), skipnew);
- }
- }
- // -x
- x = cx - r - 1;
- for (z = cz - r - 1; z <= cz + r; z++) {
- for (y = cy - r - 1; y <= cy + r; y++) {
- cLoc = new ChunkLocation(x, y, z);
- skipnew = renderChunk(cs.getChunk(cLoc), skipnew);
- }
- }
- // +z
- z = cz + r;
- for (x = cx - r - 1; x <= cz + r; x++) {
- for (y = cy - r - 1; y <= cy + r; y++) {
- cLoc = new ChunkLocation(x, y, z);
- skipnew = renderChunk(cs.getChunk(cLoc), skipnew);
+ for (distance = 0; distance <= Options.renderDistance / 16; distance++) {
+ if (distance > 0) {
+ int shortDistance = distance - 1;
+ renderLoc = new ChunkLocation(cameraChunk);
+ for (renderLoc.x = cameraChunk.x - distance; renderLoc.x <= cameraChunk.x + distance; renderLoc.x += distance * 2) {
+ // render ZY sides
+ for (renderLoc.y = cameraChunk.y - distance; renderLoc.y <= cameraChunk.y + distance; renderLoc.y++) {
+ for (renderLoc.z = cameraChunk.z - distance; renderLoc.z <= cameraChunk.z + distance; renderLoc.z++) {
+ skipnew = renderChunk(chunkSlice.getChunk(renderLoc), skipnew);
+ }
+ }
}
- }
- // -z
- z = cz - r - 1;
- for (x = cx - r - 1; x <= cz + r; x++) {
- for (y = cy - r - 1; y <= cy + r; y++) {
- cLoc = new ChunkLocation(x, y, z);
- skipnew = renderChunk(cs.getChunk(cLoc), skipnew);
+ for (renderLoc.z = cameraChunk.z - distance; renderLoc.z <= cameraChunk.z + distance; renderLoc.z += distance * 2) {
+ // render XY sides
+ for (renderLoc.x = cameraChunk.x - shortDistance; renderLoc.x <= cameraChunk.x + shortDistance; renderLoc.x++) {
+ for (renderLoc.y = cameraChunk.y - distance; renderLoc.y <= cameraChunk.y + distance; renderLoc.y++) {
+ skipnew = renderChunk(chunkSlice.getChunk(renderLoc), skipnew);
+ }
+ }
}
- }
- // +y
- y = cy + r;
- for (x = cx - r - 1; x <= cz + r; x++) {
- for (z = cz - r - 1; z <= cz + r; z++) {
- cLoc = new ChunkLocation(x, y, z);
- skipnew = renderChunk(cs.getChunk(cLoc), skipnew);
+ for (renderLoc.y = cameraChunk.y - distance; renderLoc.y <= cameraChunk.y + distance; renderLoc.y += distance * 2) {
+ // render XZ sides
+ for (renderLoc.x = cameraChunk.x - shortDistance; renderLoc.x <= cameraChunk.x + shortDistance; renderLoc.x++) {
+ for (renderLoc.z = cameraChunk.z - shortDistance; renderLoc.z <= cameraChunk.z + shortDistance; renderLoc.z++) {
+ skipnew = renderChunk(chunkSlice.getChunk(renderLoc), skipnew);
+ }
+ }
}
+ } else {
+ renderLoc = new ChunkLocation(cameraChunk);
+ skipnew = renderChunk(chunkSlice.getChunk(renderLoc), skipnew);
}
- // -y
- y = cy - r - 1;
- for (x = cx - r - 1; x <= cz + r; x++) {
- for (z = cz - r - 1; z <= cz + r; z++) {
- cLoc = new ChunkLocation(x, y, z);
- skipnew = renderChunk(cs.getChunk(cLoc), skipnew);
- }
- }
- if (skipnew) {
- // break;
- }
- // break;
}
-
- // int dw = cs.getWidth() / 2;
- // int dd = cs.getDepth() / 2;
- // int dh = cs.getHeight() / 2;
- // for (int dx = 0; dx < dw; dx++) {
- // x = cs.getX() + dw + dx;
- // for (int dz = 0; dz < dd; dz++) {
- // z = cs.getZ() + dd + dz;
- // for (int dy = 0; dy < dh; dy++) {
- // y = cs.getY() + dh + dy;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // y = cs.getY() + dh - dy - 1;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // }
- // z = cs.getZ() + dd - dz - 1;
- // for (int dy = 0; dy < dh; dy++) {
- // y = cs.getY() + dh + dy;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // y = cs.getY() + dh - dy - 1;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // }
- // }
- // x = cs.getX() + dw - dx - 1;
- // for (int dz = 0; dz < dd; dz++) {
- // z = cs.getZ() + dd + dz;
- // for (int dy = 0; dy < dh; dy++) {
- // y = cs.getY() + dh + dy;
- // int dd = cs.getDepth() / 2;
- // int dh = cs.getHeight() / 2;
- // for (int dx = 0; dx < dw; dx++) {
- // x = cs.getX() + dw + dx;
- // for (int dz = 0; dz < dd; dz++) {
- // z = cs.getZ() + dd + dz;
- // for (int dy = 0; dy < dh; dy++) {
- // y = cs.getY() + dh + dy;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // y = cs.getY() + dh - dy - 1;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // }
- // z = cs.getZ() + dd - dz - 1;
- // for (int dy = 0; dy < dh; dy++) {
- // y = cs.getY() + dh + dy;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // y = cs.getY() + dh - dy - 1;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // }
- // }
- // x = cs.getX() + dw - dx - 1;
- // for (int dz = 0; dz < dd; dz++) {
- // z = cs.getZ() + dd + dz;
- // for (int dy = 0; dy < dh; dy++) {
- // y = cs.getY() + dh + dy;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // y = cs.getY() + dh - dy - 1;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // }
- // z = cs.getZ() + dd - dz - 1;
- // for (int dy = 0; dy < dh; dy++) {
- // y = cs.getY() + dh + dy;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // y = cs.getY() + dh - dy - 1;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // }
- // }
- // }
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // y = cs.getY() + dh - dy - 1;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // }
- // z = cs.getZ() + dd - dz - 1;
- // for (int dy = 0; dy < dh; dy++) {
- // y = cs.getY() + dh + dy;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // y = cs.getY() + dh - dy - 1;
- // skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
- // }
- // }
- // }
-
- // System.out.println("visible top " + visibleTop);
}
}
diff --git a/src/ru/olamedia/olacraft/render/jogl/joglViewport.java b/src/ru/olamedia/olacraft/render/jogl/joglViewport.java
index b3da2ce..ef59352 100644
--- a/src/ru/olamedia/olacraft/render/jogl/joglViewport.java
+++ b/src/ru/olamedia/olacraft/render/jogl/joglViewport.java
@@ -16,9 +16,11 @@ public class joglViewport {
}
public void drawText(String text, int x, int y) {
- sans11.setColor(1, 1, 1, 0.7f);
+ sans11.setColor(0, 0, 0, 0.7f);
sans11.beginRendering(drawable.getWidth(), drawable.getHeight());
- sans11.draw(text, x, y);
+ sans11.draw(text, x - 1, y - 1);
+ // sans11.setColor(1, 1, 1, 0.7f);
+ // sans11.draw(text, x, y);
sans11.endRendering();
}
}
diff --git a/src/ru/olamedia/olacraft/scene/GameScene.java b/src/ru/olamedia/olacraft/scene/GameScene.java
index 86b9574..e5655c9 100644
--- a/src/ru/olamedia/olacraft/scene/GameScene.java
+++ b/src/ru/olamedia/olacraft/scene/GameScene.java
@@ -11,8 +11,6 @@ import javax.media.opengl.glu.GLUquadric;
import org.ode4j.ode.DBody;
-import com.jogamp.opengl.util.PMVMatrix;
-
import ru.olamedia.Options;
import ru.olamedia.game.GameTime;
import ru.olamedia.liveEntity.LiveEntity;
@@ -25,18 +23,19 @@ import ru.olamedia.olacraft.weapon.Bullet;
import ru.olamedia.olacraft.weapon.BulletScene;
import ru.olamedia.olacraft.world.block.Block;
import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+import ru.olamedia.olacraft.world.blockTypes.DirtBlockType;
import ru.olamedia.olacraft.world.blockTypes.GrassBlockType;
+import ru.olamedia.olacraft.world.blockTypes.GravelBlockType;
+import ru.olamedia.olacraft.world.blockTypes.StoneBlockType;
import ru.olamedia.olacraft.world.chunk.BlockSlice;
+import ru.olamedia.olacraft.world.chunk.Chunk;
import ru.olamedia.olacraft.world.chunk.ChunkSlice;
-import ru.olamedia.olacraft.world.chunk.ChunkUnavailableException;
+import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.provider.WorldProvider;
import ru.olamedia.player.Player;
-import ru.olamedia.vbo.VBO;
public class GameScene {
- private PMVMatrix matrix;
-
private HashMap<Integer, LiveEntity> liveEntities = new HashMap<Integer, LiveEntity>();
WorldProvider provider;
private int renderDistance = Options.renderDistance;
@@ -44,8 +43,6 @@ public class GameScene {
private BulletScene bullets = new BulletScene();
private GamePhysicsWorld physics = new GamePhysicsWorld();
- private VBO testObject;
-
private boolean isInitialized = false;
BlockSlice viewSlice;
public GameTime time = new GameTime();
@@ -81,13 +78,18 @@ public class GameScene {
time.init();
registerTextures();
viewport = new joglViewport(drawable);
- testObject = new VBO(drawable);
}
private void registerTextures() {
AbstractBlockType t;
t = new GrassBlockType();
- t.register();
+ t.register(provider);
+ t = new StoneBlockType();
+ t.register(provider);
+ t = new DirtBlockType();
+ t.register(provider);
+ t = new GravelBlockType();
+ t.register(provider);
}
/**
@@ -107,7 +109,7 @@ public class GameScene {
blockRenderer = new ChunkRenderer(viewSlice);
}
- ChunkRenderer blockRenderer = new ChunkRenderer(viewSlice);
+ public ChunkRenderer blockRenderer = new ChunkRenderer(viewSlice);
GLU glu = new GLU();
public void registerLiveEntity(LiveEntity entity) {
@@ -136,7 +138,7 @@ public class GameScene {
return liveEntities;
}
- Block nearestBlock = null;
+ public Block nearestBlock = null;
public void tick() {
time.tick();
@@ -146,12 +148,18 @@ public class GameScene {
// bullets.update(Game.instance.getDelta());
physics.getWorld().step(Game.instance.getDelta());
BlockSlice pickSlice = new BlockSlice(provider, 10, 10, 10);
- pickSlice.setCenter(player.getCameraX(), player.getCameraY(), player.getCameraZ());
- nearestBlock = pickSlice.getNearest(Game.instance.camera);
+ if (null != player) {
+ if (player.isOrientationChanged || Game.instance.camera.isOrientationChanged) {
+ player.isOrientationChanged = false;
+ Game.instance.camera.isOrientationChanged = false;
+ pickSlice.setCenter(player.getCameraX(), player.getCameraY(), player.getCameraZ());
+ nearestBlock = pickSlice.getNearest(Game.instance.camera);
+ }
+ }
}
public void render(GLAutoDrawable drawable) {
- if (!Game.instance.isRunning()) {
+ if (null == player || !Game.instance.isRunning()) {
// not running, just clear screen
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
@@ -169,30 +177,33 @@ public class GameScene {
gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
Game.instance.camera.setUp(drawable);
// RENDER SUN
- gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
- gl.glEnable(GL2.GL_BLEND); // Enable Blending
- gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE); // Set Blending Mode To
- // Mix Based On SRC
- // Alpha
- GLUquadric sun = glu.gluNewQuadric();
- glu.gluQuadricDrawStyle(sun, GLU.GLU_FILL);
- glu.gluQuadricNormals(sun, GLU.GLU_SMOOTH);
- gl.glPushMatrix();
- gl.glTranslatef(time.sun.getX() + player.getCameraX(), time.sun.getY(), time.sun.getZ() + player.getCameraZ());
- gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
- gl.glColor4f(1, 1, 1, 0.02f);
- glu.gluSphere(sun, 100f, 10, 10);
- glu.gluSphere(sun, 90f, 10, 10);
- glu.gluSphere(sun, 80f, 10, 10);
- glu.gluSphere(sun, 70f, 10, 10);
- glu.gluSphere(sun, 60f, 10, 10);
- glu.gluSphere(sun, 50f, 10, 10);
- glu.gluSphere(sun, 40f, 10, 10);
- glu.gluSphere(sun, 35f, 10, 10);
- gl.glColor4f(1, 1, 1, 1f);
- glu.gluSphere(sun, 30f, 10, 10);
- gl.glPopMatrix();
- gl.glPopAttrib();
+ // gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ // gl.glEnable(GL2.GL_BLEND); // Enable Blending
+ // gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE); // Set Blending Mode To
+ // // Mix Based On SRC
+ // // Alpha
+ // GLUquadric sun = glu.gluNewQuadric();
+ // glu.gluQuadricDrawStyle(sun, GLU.GLU_FILL);
+ // glu.gluQuadricNormals(sun, GLU.GLU_SMOOTH);
+ // gl.glPushMatrix();
+ // gl.glTranslatef(time.sun.getX() + player.getCameraX(),
+ // time.sun.getY(), time.sun.getZ() + player.getCameraZ());
+ // gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
+ // gl.glColor4f(1, 1, 1, 0.02f);
+ // gl.glColor4f((float) 251 / 255, (float) 255 / 255, (float) 228 / 255,
+ // 0.02f);
+ // glu.gluSphere(sun, 100f, 10, 10);
+ // glu.gluSphere(sun, 90f, 10, 10);
+ // glu.gluSphere(sun, 80f, 10, 10);
+ // glu.gluSphere(sun, 70f, 10, 10);
+ // glu.gluSphere(sun, 60f, 10, 10);
+ // glu.gluSphere(sun, 50f, 10, 10);
+ // glu.gluSphere(sun, 40f, 10, 10);
+ // glu.gluSphere(sun, 35f, 10, 10);
+ // gl.glColor4f(1, 1, 1, 1f);
+ // glu.gluSphere(sun, 30f, 10, 10);
+ // gl.glPopMatrix();
+ // gl.glPopAttrib();
viewSlice.setCenter((int) Game.instance.camera.getX(), (int) Game.instance.camera.getY(),
(int) Game.instance.camera.getZ());
@@ -212,7 +223,7 @@ public class GameScene {
// gl.glFogf(GL2.GL_FOG_DENSITY, 0.002f);
// new float[] { 49f / 255f, 119f / 255f, 243f / 255f }
// gl.glFogfv(GL2.GL_FOG_COLOR, new float[] { 1, 1, 1, 0.2f }, 0);
- blockRenderer.render(drawable);
+ blockRenderer.render();
gl.glPopAttrib();
// RENDER ANYTHING ELSE
gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
@@ -227,6 +238,11 @@ public class GameScene {
gl.glPopMatrix();
}
gl.glPopAttrib();
+ if (nearestBlock != null) {
+ gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ nearestBlock.renderFrame();
+ gl.glPopAttrib();
+ }
// bullets.render(drawable);
gl.glPopMatrix();
@@ -273,35 +289,68 @@ public class GameScene {
// inventoryRenderer.render(drawable);
}
- viewport.drawText("avg fps: " + (int) Game.timer.getAvgFps(), 10, height - 20);
- viewport.drawText("fps: " + (int) Game.timer.getFps(), 10, height - 35);
+ viewport.drawText("rad: " + Options.renderDistance, 10, height - 20);
+ viewport.drawText("avg fps: " + (int) Game.timer.getAvgFps(), 10, height - 35);
+ viewport.drawText("fps: " + (int) Game.timer.getFps(), 10, height - 50);
MemoryUsage heap = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
viewport.drawText("mem: " + (heap.getUsed() / (1024 * 1024)) + "/" + (heap.getMax() / (1024 * 1024)), 10,
- height - 50);
-
- viewport.drawText("y: " + Game.instance.player.getY(), width - msz - 10, height - msz - 20);
- viewport.drawText("y: " + Game.instance.player.getCameraY() + " (cam)", width - msz - 10, height - msz - 30);
- viewport.drawText("x: " + Game.instance.player.getX(), width - msz - 10, height - msz - 40);
- viewport.drawText("z: " + Game.instance.player.getZ(), width - msz - 10, height - msz - 50);
- viewport.drawText("players: " + liveEntities.size(), width - msz - 10, height - msz - 70);
- viewport.drawText("bullets: " + getBulletsCount(), width - msz - 10, height - msz - 95);
- viewport.drawText("y velocity: " + player.velocity.y + " y accel: " + player.acceleration.y + " inJump: "
- + player.inJump + " onGround: " + player.onGround, width - msz - 350 - 10, height - msz - 110);
- viewport.drawText("rdistance: " + renderDistance, width - msz - 10, height - msz - 155);
-
- ChunkSlice cs = viewSlice.getChunkSlice();
- viewport.drawText("slice x: " + cs.getX() + ".." + (cs.getX() + cs.getWidth() - 1) + " y: " + cs.getY() + ".."
- + (cs.getY() + cs.getHeight() - 1) + " z: " + cs.getZ() + ".." + (cs.getZ() + cs.getDepth() - 1), width
- - msz * 2 - 10, height - msz - 170);
- viewport.drawText("time: " + time.getDateTimeString(), width - msz * 2 - 10, height - msz - 185);
- if (nearestBlock != null) {
- viewport.drawText("block: " + nearestBlock.getX() + ":" + nearestBlock.getY() + ":" + nearestBlock.getZ()
- + " d " + nearestBlock.getDistance(Game.instance.camera), width - msz * 2 - 10, height - msz - 200);
- }
+ height - 65);
+ //
+ // viewport.drawText("y: " + Game.instance.player.getY(), width - msz -
+ // 10, height - msz - 20);
+ // viewport.drawText("y: " + Game.instance.player.getCameraY() +
+ // " (cam)", width - msz - 10, height - msz - 30);
+ // viewport.drawText("x: " + Game.instance.player.getX(), width - msz -
+ // 10, height - msz - 40);
+ // viewport.drawText("z: " + Game.instance.player.getZ(), width - msz -
+ // 10, height - msz - 50);
+ // viewport.drawText("players: " + liveEntities.size(), width - msz -
+ // 10, height - msz - 70);
+ // viewport.drawText("bullets: " + getBulletsCount(), width - msz - 10,
+ // height - msz - 95);
+ // viewport.drawText("y velocity: " + player.velocity.y + " y accel: " +
+ // player.acceleration.y + " inJump: "
+ // + player.inJump + " onGround: " + player.onGround, width - msz - 350
+ // - 10, height - msz - 110);
+ // viewport.drawText("rdistance: " + Options.renderDistance, width - msz
+ // - 10, height - msz - 155);
+
+ // ChunkSlice cs = viewSlice.getChunkSlice();
+ // viewport.drawText("slice x: " + cs.getX() + ".." + (cs.getX() +
+ // cs.getWidth() - 1) + " y: " + cs.getY() + ".."
+ // + (cs.getY() + cs.getHeight() - 1) + " z: " + cs.getZ() + ".." +
+ // (cs.getZ() + cs.getDepth() - 1), width
+ // - msz * 2 - 10, height - msz - 170);
+ // viewport.drawText("time: " + time.getDateTimeString(), width - msz *
+ // 2 - 10, height - msz - 185);
+ // if (nearestBlock != null) {
+ // viewport.drawText("pick: " + nearestBlock.getX() + "," +
+ // nearestBlock.getY() + "," + nearestBlock.getZ()
+ // + " d " + nearestBlock.getDistance(Game.instance.camera), width - msz
+ // * 2 - 10, height - msz - 200);
+ // viewport.drawText(
+ // "edge: " + nearestBlock.location.isChunkEdge() + " left " +
+ // nearestBlock.location.isChunkLeftEdge(),
+ // width - msz * 2 - 10, height - msz - 210);
+ // }
+
+ // BlockLocation camloc = player.getCameraBlockLocation();
+ // viewport.drawText("cam chunk: " + camloc.getChunkLocation(), width -
+ // 200 - msz * 2 - 10, height - msz - 225);
+ // Chunk camc =
+ // viewSlice.getChunkSlice().getChunk(camloc.getChunkLocation());
+ // viewport.drawText("cam chunk: " + camc.isMeshCostructed + " mesh: " +
+ // camc.mesh, width - 200 - msz * 2 - 10,
+ // height - msz - 235);
+ // viewport.drawText(
+ // "chunk available: " + camc.isAvailable() + " chunk empty: "
+ // + (camc.isAvailable() ? camc.isEmpty() : "unknown"), width - 200 -
+ // msz * 2 - 10, height - msz
+ // - 245);
gl.glPopAttrib();
gl.glPopMatrix();
- gl.glFlush();
+ // gl.glFlush();
}
public Player getPlayer() {
diff --git a/src/ru/olamedia/olacraft/world/block/Block.java b/src/ru/olamedia/olacraft/world/block/Block.java
index 44e9b1d..50752f0 100644
--- a/src/ru/olamedia/olacraft/world/block/Block.java
+++ b/src/ru/olamedia/olacraft/world/block/Block.java
@@ -1,34 +1,73 @@
package ru.olamedia.olacraft.world.block;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLContext;
import javax.vecmath.Vector3f;
import ru.olamedia.camera.MatrixCamera;
+import ru.olamedia.olacraft.game.Game;
import ru.olamedia.olacraft.world.blockTypes.BlockType;
import ru.olamedia.olacraft.world.blockTypes.EmptyBlockType;
+import ru.olamedia.olacraft.world.chunk.Chunk;
import ru.olamedia.olacraft.world.chunk.ChunkUnavailableException;
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.provider.WorldProvider;
public class Block {
- private WorldProvider provider;
- private int x;
- private int y;
- private int z;
+ public WorldProvider provider;
+ public BlockLocation location = new BlockLocation();
+
+ public void removeFromWorld() {
+ ChunkData cdata = provider.getChunk(location.getChunkLocation());
+ cdata.setEmpty(location, true);
+ Chunk chunk = Game.client.getScene().blockRenderer.chunkSlice.getChunk(location.getChunkLocation());
+ chunk.invalidate();
+ if (location.isChunkEdge()) {
+ if (location.isChunkBackEdge()) {
+ Chunk neighbor = Game.client.getScene().blockRenderer.chunkSlice.getChunk(location.getChunkLocation()
+ .getBack());
+ neighbor.invalidate();
+ } else if (location.isChunkFrontEdge()) {
+ Chunk neighbor = Game.client.getScene().blockRenderer.chunkSlice.getChunk(location.getChunkLocation()
+ .getFront());
+ neighbor.invalidate();
+ } else if (location.isChunkLeftEdge()) {
+ Chunk neighbor = Game.client.getScene().blockRenderer.chunkSlice.getChunk(location.getChunkLocation()
+ .getLeft());
+ neighbor.invalidate();
+ } else if (location.isChunkRightEdge()) {
+ Chunk neighbor = Game.client.getScene().blockRenderer.chunkSlice.getChunk(location.getChunkLocation()
+ .getRight());
+ neighbor.invalidate();
+ } else if (location.isChunkTopEdge()) {
+ Chunk neighbor = Game.client.getScene().blockRenderer.chunkSlice.getChunk(location.getChunkLocation()
+ .getTop());
+ neighbor.invalidate();
+ } else if (location.isChunkBottomEdge()) {
+ Chunk neighbor = Game.client.getScene().blockRenderer.chunkSlice.getChunk(location.getChunkLocation()
+ .getBottom());
+ neighbor.invalidate();
+ }
+ }
+ }
/**
* Inventory block
*/
public Block() {
this.provider = null;
- this.x = 0;
- this.y = 0;
- this.z = 0;
+ location.x = 0;
+ location.y = 0;
+ location.z = 0;
}
public void putIntoWorld(WorldProvider worldProvider, int x, int y, int z) {
this.provider = worldProvider;
- this.x = x;
- this.y = y;
- this.z = z;
+ location.x = x;
+ location.y = y;
+ location.z = z;
}
public Block(WorldProvider worldProvider, int x, int y, int z) {
@@ -39,7 +78,7 @@ public class Block {
* @return the x
*/
public int getX() {
- return x;
+ return location.x;
}
/**
@@ -47,14 +86,14 @@ public class Block {
* the x to set
*/
public void setX(int x) {
- this.x = x;
+ location.x = x;
}
/**
* @return the y
*/
public int getY() {
- return y;
+ return location.y;
}
/**
@@ -62,14 +101,14 @@ public class Block {
* the y to set
*/
public void setY(int y) {
- this.y = y;
+ location.y = y;
}
/**
* @return the z
*/
public int getZ() {
- return z;
+ return location.z;
}
/**
@@ -77,15 +116,15 @@ public class Block {
* the z to set
*/
public void setZ(int z) {
- this.z = z;
+ location.z = z;
}
public boolean isEmpty() throws ChunkUnavailableException {
- return provider.isEmptyBlock(x, y, z);
+ return provider.isEmptyBlock(location.x, location.y, location.z);
}
public Block getNeighbor(int dx, int dy, int dz) {
- return new Block(provider, x + dx, y + dy, z + dz);
+ return new Block(provider, location.x + dx, location.y + dy, location.z + dz);
}
public Block[] getNeighbors() {
@@ -153,34 +192,178 @@ public class Block {
}
private Vector3f getBottomRightBack() {
- return new Vector3f(x + 0.5f, y - 0.5f, z - 0.5f);
+ return new Vector3f(location.x + 0.5f, location.y - 0.5f, location.z - 0.5f);
}
private Vector3f getBottomRightFront() {
- return new Vector3f(x + 0.5f, y - 0.5f, z + 0.5f);
+ return new Vector3f(location.x + 0.5f, location.y - 0.5f, location.z + 0.5f);
}
private Vector3f getBottomLeftFront() {
- return new Vector3f(x - 0.5f, y - 0.5f, z + 0.5f);
+ return new Vector3f(location.x - 0.5f, location.y - 0.5f, location.z + 0.5f);
}
private Vector3f getBottomLeftBack() {
- return new Vector3f(x - 0.5f, y - 0.5f, z - 0.5f);
+ return new Vector3f(location.x - 0.5f, location.y - 0.5f, location.z - 0.5f);
}
private Vector3f getTopRightBack() {
- return new Vector3f(x + 0.5f, y + 0.5f, z - 0.5f);
+ return new Vector3f(location.x + 0.5f, location.y + 0.5f, location.z - 0.5f);
}
private Vector3f getTopLeftFront() {
- return new Vector3f(x - 0.5f, y + 0.5f, z + 0.5f);
+ return new Vector3f(location.x - 0.5f, location.y + 0.5f, location.z + 0.5f);
}
private Vector3f getTopRightFront() {
- return new Vector3f(x + 0.5f, y + 0.5f, z + 0.5f);
+ return new Vector3f(location.x + 0.5f, location.y + 0.5f, location.z + 0.5f);
}
private Vector3f getTopLeftBack() {
- return new Vector3f(x - 0.5f, y + 0.5f, z - 0.5f);
+ return new Vector3f(location.x - 0.5f, location.y + 0.5f, location.z - 0.5f);
+ }
+
+ public void request() {
+ provider.loadChunk(location.getChunkLocation());
+ }
+
+ public void renderFrame() {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ gl.glDisable(GL2.GL_TEXTURE_2D);
+ gl.glEnable(GL2.GL_DEPTH_TEST);
+ gl.glEnable(GL2.GL_LINE_SMOOTH);
+ gl.glEnable(GL2.GL_POLYGON_SMOOTH);
+ gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_NICEST);
+ gl.glHint(GL2.GL_POLYGON_SMOOTH_HINT, GL2.GL_NICEST);
+ // gl.glEnable(GL2.GL_BLEND); // Enable Blending
+ // gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE);
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
+ float min = 0.505f;
+ float max = 0.495f;
+ gl.glBegin(GL2.GL_QUADS);
+ {
+ gl.glColor4f(0, 0, 0, 0.8f);
+ // top: right
+ gl.glVertex3f(location.x + min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x + min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x + max, location.y + min, location.z - min);
+ gl.glVertex3f(location.x + max, location.y + min, location.z + min);
+ // top: left
+ gl.glVertex3f(location.x - min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x - max, location.y + min, location.z - min);
+ gl.glVertex3f(location.x - max, location.y + min, location.z + min);
+ // top: back
+ gl.glVertex3f(location.x + min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y + min, location.z - max);
+ gl.glVertex3f(location.x + min, location.y + min, location.z - max);
+ // top: front
+ gl.glVertex3f(location.x + min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y + min, location.z + max);
+ gl.glVertex3f(location.x + min, location.y + min, location.z + max);
+ // bottom: right
+ gl.glVertex3f(location.x + min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x + min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x + max, location.y - min, location.z - min);
+ gl.glVertex3f(location.x + max, location.y - min, location.z + min);
+ // bottom: left
+ gl.glVertex3f(location.x - min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x - max, location.y - min, location.z - min);
+ gl.glVertex3f(location.x - max, location.y - min, location.z + min);
+ // bottom: back
+ gl.glVertex3f(location.x + min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z - max);
+ gl.glVertex3f(location.x + min, location.y - min, location.z - max);
+ // bottom: front
+ gl.glVertex3f(location.x + min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z + max);
+ gl.glVertex3f(location.x + min, location.y - min, location.z + max);
+ // front: right
+ gl.glVertex3f(location.x + min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x + min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x + max, location.y - min, location.z + min);
+ gl.glVertex3f(location.x + max, location.y + min, location.z + min);
+ // front: left
+ gl.glVertex3f(location.x - min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - max, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - max, location.y + min, location.z + min);
+ // front: bottom
+ gl.glVertex3f(location.x + min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - max, location.z + min);
+ gl.glVertex3f(location.x + min, location.y - max, location.z + min);
+ // front: top
+ gl.glVertex3f(location.x + min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y + max, location.z + min);
+ gl.glVertex3f(location.x + min, location.y + max, location.z + min);
+ // back: right
+ gl.glVertex3f(location.x + min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x + min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x + max, location.y - min, location.z - min);
+ gl.glVertex3f(location.x + max, location.y + min, location.z - min);
+ // back: left
+ gl.glVertex3f(location.x - min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x - max, location.y - min, location.z - min);
+ gl.glVertex3f(location.x - max, location.y + min, location.z - min);
+ // back: bottom
+ gl.glVertex3f(location.x + min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - max, location.z + min);
+ gl.glVertex3f(location.x + min, location.y - max, location.z + min);
+ // back: top
+ gl.glVertex3f(location.x + min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y + max, location.z + min);
+ gl.glVertex3f(location.x + min, location.y + max, location.z + min);
+ // left: back
+ gl.glVertex3f(location.x - min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z - max);
+ gl.glVertex3f(location.x - min, location.y + min, location.z - max);
+ // left: front
+ gl.glVertex3f(location.x - min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z + max);
+ gl.glVertex3f(location.x - min, location.y + min, location.z + max);
+ // left: top
+ gl.glVertex3f(location.x - min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y + max, location.z - min);
+ gl.glVertex3f(location.x - min, location.y + max, location.z + min);
+ // left: bottom
+ gl.glVertex3f(location.x - min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x - min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x - min, location.y - max, location.z - min);
+ gl.glVertex3f(location.x - min, location.y - max, location.z + min);
+ // right: back
+ gl.glVertex3f(location.x + min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x + min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x + min, location.y - min, location.z - max);
+ gl.glVertex3f(location.x + min, location.y + min, location.z - max);
+ // right: front
+ gl.glVertex3f(location.x + min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x + min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x + min, location.y - min, location.z + max);
+ gl.glVertex3f(location.x + min, location.y + min, location.z + max);
+ // right: top
+ gl.glVertex3f(location.x + min, location.y + min, location.z + min);
+ gl.glVertex3f(location.x + min, location.y + min, location.z - min);
+ gl.glVertex3f(location.x + min, location.y + max, location.z - min);
+ gl.glVertex3f(location.x + min, location.y + max, location.z + min);
+ // right: bottom
+ gl.glVertex3f(location.x + min, location.y - min, location.z + min);
+ gl.glVertex3f(location.x + min, location.y - min, location.z - min);
+ gl.glVertex3f(location.x + min, location.y - max, location.z - min);
+ gl.glVertex3f(location.x + min, location.y - max, location.z + min);
+ }
+ gl.glEnd();
}
}
diff --git a/src/ru/olamedia/olacraft/world/block/BlockRegistry.java b/src/ru/olamedia/olacraft/world/block/BlockRegistry.java
index 19ccc94..ec9f9c1 100644
--- a/src/ru/olamedia/olacraft/world/block/BlockRegistry.java
+++ b/src/ru/olamedia/olacraft/world/block/BlockRegistry.java
@@ -23,16 +23,13 @@ public class BlockRegistry {
return names.get(id);
}
- public int registerBlockType(@SuppressWarnings("rawtypes") Class type) {
- if (type.isInstance(BlockType.class)) {
- autoincrement++;
- int id = autoincrement;
- String classId = type.getName();
- names.put(id, classId);
- // types.put(id, type);
- return autoincrement;
- }
- return 0;
+ public int registerBlockType(BlockType type) {
+ autoincrement++;
+ int id = autoincrement;
+ String classId = type.getClass().getName();
+ names.put(id, classId);
+ types.put(id, type);
+ return autoincrement;
}
public BlockRegistry getWorldRegistry() {
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java
index 6e2a86f..717c01f 100644
--- a/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java
+++ b/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java
@@ -2,6 +2,8 @@ package ru.olamedia.olacraft.world.blockTypes;
import com.jogamp.opengl.util.texture.Texture;
+import ru.olamedia.olacraft.world.block.BlockRegistry;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
import ru.olamedia.texture.TextureManager;
public abstract class AbstractBlockType implements BlockType {
@@ -75,12 +77,13 @@ public abstract class AbstractBlockType implements BlockType {
return TextureManager.get(this.getBackTextureFile());
}
- public void register(){
+ public void register(WorldProvider provider){
getBackTexture();
getBottomTexture();
getFrontTexture();
getLeftTexture();
getRightTexture();
getTopTexture();
+ provider.getTypeRegistry().registerBlockType(this);
}
}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java
new file mode 100644
index 0000000..a4e5dd7
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java
@@ -0,0 +1,23 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+public class DirtBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Gravel";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/dirt.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/dirt.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/StoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/StoneBlockType.java
new file mode 100644
index 0000000..d2b3446
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/StoneBlockType.java
@@ -0,0 +1,29 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+public class StoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Stone";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/terrain-cobb.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/terrain-cobb.png";
+ }
+
+ @Override
+ public String getFrontTextureFile() {
+ return "texture/terrain-cobb.png";
+ }
+}
+
diff --git a/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java b/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java
index bad802f..d02999d 100644
--- a/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java
+++ b/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java
@@ -34,7 +34,8 @@ public class BlockSlice implements Iterator<Block> {
}
}
} catch (ChunkUnavailableException e) {
- e.printStackTrace();
+ //e.printStackTrace();
+ b.request();
}
}
return nearestBlock;
diff --git a/src/ru/olamedia/olacraft/world/chunk/Chunk.java b/src/ru/olamedia/olacraft/world/chunk/Chunk.java
index 9c0afb7..f390ebc 100644
--- a/src/ru/olamedia/olacraft/world/chunk/Chunk.java
+++ b/src/ru/olamedia/olacraft/world/chunk/Chunk.java
@@ -1,7 +1,8 @@
package ru.olamedia.olacraft.world.chunk;
import ru.olamedia.geom.SimpleQuadMesh;
-import ru.olamedia.olacraft.world.blockTypes.GrassBlockType;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.data.ChunkData;
import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.location.ChunkLocation;
import ru.olamedia.olacraft.world.provider.WorldProvider;
@@ -9,6 +10,8 @@ import ru.olamedia.olacraft.world.provider.WorldProvider;
public class Chunk extends BlockSlice {
public boolean isMeshCostructed = false;
public SimpleQuadMesh mesh;
+ public boolean usePrevMesh = false;
+ public SimpleQuadMesh prevMesh;
public int visibleTop = 0;
public int visibleBottom = 0;
@@ -17,6 +20,25 @@ public class Chunk extends BlockSlice {
public int visibleFront = 0;
public int visibleBack = 0;
+ public void render() {
+ if (isMeshCostructed) {
+ mesh.joglRender();
+ } else if (usePrevMesh) {
+ prevMesh.joglRender();
+ }
+ }
+
+ public void invalidate() {
+ if (null != mesh) {
+ prevMesh = mesh;
+ usePrevMesh = true;
+ if (null != mesh) {
+ mesh.restart();
+ }
+ }
+ isMeshCostructed = false;
+ }
+
public Chunk(WorldProvider provider) {
super(provider, 16, 16, 16);
}
@@ -93,32 +115,51 @@ public class Chunk extends BlockSlice {
* @return the mesh
*/
public SimpleQuadMesh getMesh() {
+ if (!isAvailable()) {
+ return null;
+ }
if (isMeshCostructed) {
return mesh;
}
- if (offset.y > provider.getInfo().maxHeight) {
- // isMeshCostructed = true;
- // return null;
+ if (offset.y >= provider.getInfo().maxHeight) {
+ isMeshCostructed = true;
+ return null;
}
if (offset.y < provider.getInfo().minHeight) {
- // isMeshCostructed = true;
- // return null;
+ isMeshCostructed = true;
+ return null;
}
- if (null == mesh) {
- mesh = new SimpleQuadMesh(14739); // unindexed
+
+ if (null == mesh || mesh.restart) {
+ ChunkData data = provider.getChunk(offset.getChunkLocation());
+ data.computeVisibility(provider);
+ // max 14739
+ System.out.println(data.visibleCount + " vis");
+ mesh = new SimpleQuadMesh(14739);
+ //mesh = new SimpleQuadMesh(Math.min(data.visibleCount * 6, 14739));
+ mesh.start();
// 17x17x17
// vertices
mesh.useColor();
mesh.useTexture();
// gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_FASTEST);
// gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_NICEST);
- GrassBlockType grass = new GrassBlockType();
- for (int x = offset.x; x < offset.x + getWidth(); x++) {
- for (int y = offset.y; y < offset.y + getHeight(); y++) {
- for (int z = offset.z; z < offset.z + getDepth(); z++) {
+ BlockType grass;
+ for (int dx = 0; dx < 16; dx++) {
+ for (int dy = 0; dy < 16; dy++) {
+ for (int dz = 0; dz < 16; dz++) {
+ int x = offset.x + dx;
+ int y = offset.y + dy;
+ int z = offset.z + dz;
+ if (mesh.restart) {
+ return null;
+ }
//
try {
- if (!isEmptyBlock(x, y, z)) {
+ int id = dx * 16 * 16 + dy * 16 + dz;
+ if (data.visible.get(id) && !data.emptyBlocks.get(id)) {
+ grass = provider.getTypeRegistry().getBlockType(
+ provider.getChunk((new BlockLocation(x, y, z)).getChunkLocation()).types[id]);
mesh.setTranslation(x, y, z);
// mesh.setColor4f(0, 1, 0, 1);
float cbase = (float) (y / 200.0) * (float) (7.0 / 10.0);
@@ -197,6 +238,7 @@ public class Chunk extends BlockSlice {
}
}
mesh.endMesh();
+ data.visible = null;
isMeshCostructed = true;
return null;
}
@@ -311,4 +353,8 @@ public class Chunk extends BlockSlice {
public void setLocation(ChunkLocation location) {
setLocation(location.getBlockLocation().x, location.getBlockLocation().y, location.getBlockLocation().z);
}
+
+ public boolean inWorldRange() {
+ return (offset.y + 16 < provider.getInfo().maxHeight) && (offset.y > provider.getInfo().minHeight);
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java b/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java
index d362199..e823b2f 100644
--- a/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java
+++ b/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java
@@ -4,7 +4,7 @@ import java.util.concurrent.ArrayBlockingQueue;
public class ChunkMeshBulder extends Thread {
public static ChunkMeshBulder instance = new ChunkMeshBulder("Mesh builder");
- private ArrayBlockingQueue<Chunk> chunks = new ArrayBlockingQueue<Chunk>(16);
+ private ArrayBlockingQueue<Chunk> chunks = new ArrayBlockingQueue<Chunk>(256);
public ChunkMeshBulder(String name) {
super(name);
@@ -36,6 +36,9 @@ public class ChunkMeshBulder extends Thread {
// main loop
try {
tick();
+ if (chunks.isEmpty()){
+ Thread.sleep(50);
+ }
// Thread.sleep(10); // or wait/join etc
} catch (InterruptedException ex) {
// cleanup here
diff --git a/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java b/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java
index d0307bb..14e2c1f 100644
--- a/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java
+++ b/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java
@@ -21,20 +21,41 @@ public class ChunkSlice {
}
protected HashMap<String, Chunk> chunks = new HashMap<String, Chunk>();
+ protected HashMap<Integer, HashMap<Integer, HashMap<Integer, Chunk>>> iChunks = new HashMap<Integer, HashMap<Integer, HashMap<Integer, Chunk>>>();
public Chunk getChunk(ChunkLocation location) {
- int x = location.x;
- int y = location.y;
- int z = location.z;
- String key = x + ";" + y + ";" + z;
- if (chunks.containsKey(key)) {
- return chunks.get(key);
+ // int x = location.x;
+ // int y = location.y;
+ // int z = location.z;
+ // String key = x + ";" + y + ";" + z;
+ if (iChunks.containsKey(location.x)) {
+ if (iChunks.get(location.x).containsKey(location.y)) {
+ if (iChunks.get(location.x).get(location.y).containsKey(location.z)) {
+ return iChunks.get(location.x).get(location.y).get(location.z);
+ } else {
+
+ }
+ } else {
+ iChunks.get(location.x).put(location.y, new HashMap<Integer, Chunk>());
+ }
} else {
- Chunk chunk = new Chunk(provider);
- chunk.setLocation(location);
- chunks.put(key, chunk);
- return chunk;
+ iChunks.put(location.x, new HashMap<Integer, HashMap<Integer, Chunk>>());
+ iChunks.get(location.x).put(location.y, new HashMap<Integer, Chunk>());
}
+
+ Chunk chunk = new Chunk(provider);
+ chunk.setLocation(location);
+ // chunks.put(key, chunk);
+ iChunks.get(location.x).get(location.y).put(location.z, chunk);
+ return chunk;
+ // if (chunks.containsKey(key)) {
+ // return chunks.get(key);
+ // } else {
+ // Chunk chunk = new Chunk(provider);
+ // chunk.setLocation(location);
+ // chunks.put(key, chunk);
+ // return chunk;
+ // }
}
/**
@@ -108,6 +129,7 @@ public class ChunkSlice {
public int getZ() {
return offset.z;
}
+
public void setLocation(ChunkLocation chunkOffset) {
offset = chunkOffset;
}
diff --git a/src/ru/olamedia/olacraft/world/data/ChunkData.java b/src/ru/olamedia/olacraft/world/data/ChunkData.java
index a6b9f34..42f7811 100644
--- a/src/ru/olamedia/olacraft/world/data/ChunkData.java
+++ b/src/ru/olamedia/olacraft/world/data/ChunkData.java
@@ -3,9 +3,11 @@ package ru.olamedia.olacraft.world.data;
import java.io.Serializable;
import ru.olamedia.math.OpenBitSet;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
import ru.olamedia.olacraft.world.chunk.Chunk;
import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
public class ChunkData implements Serializable {
private static final long serialVersionUID = -5704237444737895501L;
@@ -13,17 +15,160 @@ public class ChunkData implements Serializable {
public static transient int SIZE = 4096;
// private boolean[] notEmpty = new boolean[SIZE];
public OpenBitSet emptyBlocks = new OpenBitSet(4096);
+ public int visibleCount = 0;
+ public OpenBitSet visible = null; // fast precomputed
+ // visibility (true if
+ // any side is open)
+ //public OpenBitSet sunlight = new OpenBitSet(65536);
+ public byte[] types = new byte[4096];
public int notEmptyCount = 0;
+ public boolean visibilityPrecomputed = false;
// public transient int[] type = new int[SIZE];
public ChunkData() {
}
+ private void setVisible(int x, int y, int z) {
+ if (x < 0 || x > 15 || y < 0 || y > 15 || z < 0 || z > 15) {
+ return;
+ }
+ int id = x * 16 * 16 + y * 16 + z;
+ if (!visible.get(id)){
+ visibleCount++;
+ }
+ visible.set(id);
+ }
+
+ private void setInvisible(int x, int y, int z) {
+ if (x < 0 || x > 15 || y < 0 || y > 15 || z < 0 || z > 15) {
+ return;
+ }
+ int id = x * 16 * 16 + y * 16 + z;
+ if (visible.get(id)){
+ visibleCount--;
+ }
+ visible.clear(id);
+ }
+
+ public void computeVisibility(WorldProvider provider) {
+ visible = new OpenBitSet(4096);
+ visibleCount = 0;
+ precomputeVisibility();
+ computeVisibility(provider.getChunk(location.getLeft()), provider.getChunk(location.getRight()),
+ provider.getChunk(location.getTop()), provider.getChunk(location.getBottom()),
+ provider.getChunk(location.getFront()), provider.getChunk(location.getBack()));
+ }
+
+ public void computeVisibility(ChunkData left, ChunkData right, ChunkData top, ChunkData bottom, ChunkData front,
+ ChunkData back) {
+ // compute left/right
+ int x, y, z, id;
+ for (y = 0; y <= 15; y++) {
+ for (z = 0; z <= 15; z++) {
+ x = 15;
+ id = x * 16 * 16 + y * 16 + z;
+ if (left.emptyBlocks.get(id)) {
+ x = 0;
+ setVisible(x, y, z);
+ }
+ x = 0;
+ id = x * 16 * 16 + y * 16 + z;
+ if (right.emptyBlocks.get(id)) {
+ x = 15;
+ setVisible(x, y, z);
+ }
+ }
+ }
+ // top/bottom
+ for (x = 0; x <= 15; x++) {
+ for (z = 0; z <= 15; z++) {
+ y = 15;
+ id = x * 16 * 16 + y * 16 + z;
+ if (bottom.emptyBlocks.get(id)) {
+ y = 0;
+ setVisible(x, y, z);
+ }
+ y = 0;
+ id = x * 16 * 16 + y * 16 + z;
+ if (top.emptyBlocks.get(id)) {
+ y = 15;
+ setVisible(x, y, z);
+ }
+ }
+ }
+ // front/back
+ for (x = 0; x <= 15; x++) {
+ for (y = 0; y <= 15; y++) {
+ z = 15;
+ id = x * 16 * 16 + y * 16 + z;
+ if (back.emptyBlocks.get(id)) {
+ z = 0;
+ setVisible(x, y, z);
+ }
+ z = 0;
+ id = x * 16 * 16 + y * 16 + z;
+ if (front.emptyBlocks.get(id)) {
+ z = 15;
+ setVisible(x, y, z);
+ }
+ }
+ }
+ }
+
+ /**
+ * Compute visibility ("visible" if any side have non-opaque neighbor)
+ * Leaving side blocks invisible. Use computeVisibility(WorldProvider) to compute visibility of side blocks
+ */
+ public void precomputeVisibility() {
+ // first pass, make all blocks invisible, except side blocks
+ for (int x = 0; x <= 15; x++) {
+ for (int y = 0; y <= 15; y++) {
+ for (int z = 0; z <= 15; z++) {
+ // if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z
+ // == 15) {
+ // setVisible(x, y, z);
+ // } else {
+ // setInvisible(x, y, z);
+ // }
+ setInvisible(x, y, z);
+ }
+ }
+ }
+ // second pass, make some blocks visible
+ for (int x = 0; x <= 15; x++) {
+ for (int y = 0; y <= 15; y++) {
+ for (int z = 0; z <= 15; z++) {
+ int id = x * 16 * 16 + y * 16 + z;
+ if (emptyBlocks.get(id)) {
+ setVisible(x - 1, y, z);
+ setVisible(x + 1, y, z);
+ setVisible(x, y - 1, z);
+ setVisible(x, y + 1, z);
+ setVisible(x, y, z - 1);
+ setVisible(x, y, z + 1);
+ }
+ }
+ }
+ }
+ visibilityPrecomputed = true;
+ }
+
public void compact() {
if (emptyBlocks.cardinality() == 0) {
- emptyBlocks = null;
+ // emptyBlocks = null;
+ }
+ }
+
+ public BlockType getType(BlockLocation blockLocation, WorldProvider provider) {
+ if (emptyBlocks == null) {
+ return null;
+ }
+ int id = Chunk.in(blockLocation.x) * 16 * 16 + Chunk.in(blockLocation.y) * 16 + Chunk.in(blockLocation.z);
+ if (isEmpty(id)) {
+ return null;
}
+ return provider.getBlockTypeById(types[id]);
}
public boolean isEmpty(BlockLocation blockLocation) {
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java
index 9ba9496..1e6c0c1 100644
--- a/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java
+++ b/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java
@@ -1,6 +1,9 @@
package ru.olamedia.olacraft.world.dataProvider;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import ru.olamedia.olacraft.world.data.RegionData;
import ru.olamedia.olacraft.world.location.RegionLocation;
@@ -8,6 +11,7 @@ import ru.olamedia.olacraft.world.location.RegionLocation;
public class CachedChunkDataProvider extends AbstractChunkDataProvider {
private AbstractChunkDataProvider provider;
private HashMap<String, RegionData> regionMap = new HashMap<String, RegionData>();
+ private ConcurrentHashMap<String, Integer> ticks = new ConcurrentHashMap<String, Integer>();
public CachedChunkDataProvider(AbstractChunkDataProvider provider) {
this.provider = provider;
@@ -21,6 +25,24 @@ public class CachedChunkDataProvider extends AbstractChunkDataProvider {
}
}
+ @SuppressWarnings("unused")
+ private void tick(String key) {
+ ticks.put(key, 0);
+ gc();
+ }
+
+ private void gc() {
+ Iterator<String> keys = ticks.keySet().iterator();
+ while (keys.hasNext()) {
+ String key = keys.next();
+ ticks.put(key, ticks.get(key) + 1);
+ if (ticks.get(key) > 30) {
+ ticks.remove(key);
+ regionMap.remove(key);
+ }
+ }
+ }
+
@Override
public boolean isRegionAvailable(RegionLocation regionLocation) {
String key = regionLocation.toString();// regionLocation.x + "-" +
@@ -44,6 +66,7 @@ public class CachedChunkDataProvider extends AbstractChunkDataProvider {
@Override
public RegionData getRegion(RegionLocation regionLocation) {
String key = regionLocation.toString();
+ // tick(key);
if (regionMap.containsKey(key)) {
return regionMap.get(key);
} else {
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java
index cd48071..0c52ced 100644
--- a/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java
+++ b/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java
@@ -19,6 +19,7 @@ public class RemoteChunkDataProvider extends AbstractChunkDataProvider implement
private GameClient client;
private HashMap<String, RegionData> map = new HashMap<String, RegionData>();
private List<String> loading = new ArrayList<String>();
+ private List<RegionLocation> queue = new ArrayList<RegionLocation>();
public RemoteChunkDataProvider(GameClient client) {
this.client = client;
@@ -36,7 +37,7 @@ public class RemoteChunkDataProvider extends AbstractChunkDataProvider implement
@Override
public void loadRegion(RegionLocation regionLocation) {
String key = regionLocation.toString();
- if (!loading.contains(key)) {
+ if (loading.isEmpty() && !loading.contains(key)) {
debug("loadRegion(" + key + ")");
loading.add(key);
client.send(new GetRegionPacket(regionLocation));
diff --git a/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java b/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java
index 05fc067..79ac898 100644
--- a/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java
+++ b/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java
@@ -1,5 +1,6 @@
package ru.olamedia.olacraft.world.generator;
+import ru.olamedia.olacraft.world.chunk.Chunk;
import ru.olamedia.olacraft.world.data.ChunkData;
import ru.olamedia.olacraft.world.data.HeightMap;
import ru.olamedia.olacraft.world.data.RegionData;
@@ -68,7 +69,10 @@ public class RegionGenerator {
// System.out.println("not empty, height: "
// + height);
}
+ int id = Chunk.in(blockOffset.x) * 16 * 16 + Chunk.in(blockOffset.y) * 16
+ + Chunk.in(blockOffset.z);
chunk.setEmpty(blockOffset, false);
+ chunk.types[id] = (byte) (1 + Math.random() * 4);
}
}
}
diff --git a/src/ru/olamedia/olacraft/world/location/BlockLocation.java b/src/ru/olamedia/olacraft/world/location/BlockLocation.java
index b104bad..9639ac1 100644
--- a/src/ru/olamedia/olacraft/world/location/BlockLocation.java
+++ b/src/ru/olamedia/olacraft/world/location/BlockLocation.java
@@ -13,12 +13,49 @@ public class BlockLocation implements Serializable {
public BlockLocation() {
}
+ public boolean isChunkEdge() {
+ int cx = Chunk.in(x);
+ int cy = Chunk.in(y);
+ int cz = Chunk.in(z);
+ return (cx == 0 || cy == 0 || cz == 0 || cx == 15 || cy == 15 || cz == 15);
+ }
+
+ public boolean isChunkLeftEdge() {
+ return Chunk.in(x) == 0;
+ }
+
+ public boolean isChunkRightEdge() {
+ return Chunk.in(x) == 15;
+ }
+
+ public boolean isChunkTopEdge() {
+ return Chunk.in(y) == 15;
+ }
+
+ public boolean isChunkBottomEdge() {
+ return Chunk.in(y) == 0;
+ }
+
+ public boolean isChunkFrontEdge() {
+ return Chunk.in(z) == 15;
+ }
+
+ public boolean isChunkBackEdge() {
+ return Chunk.in(z) == 0;
+ }
+
public BlockLocation(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
+ public BlockLocation(float x, float y, float z) {
+ this.x = (int) x;
+ this.y = (int) y;
+ this.z = (int) z;
+ }
+
public ChunkLocation getChunkLocation() {
return new ChunkLocation(Chunk.v(x), Chunk.v(y + 128), Chunk.v(z));
}
diff --git a/src/ru/olamedia/olacraft/world/location/ChunkLocation.java b/src/ru/olamedia/olacraft/world/location/ChunkLocation.java
index a772c6d..439b9be 100644
--- a/src/ru/olamedia/olacraft/world/location/ChunkLocation.java
+++ b/src/ru/olamedia/olacraft/world/location/ChunkLocation.java
@@ -17,6 +17,12 @@ public class ChunkLocation implements Serializable {
this.z = z;
}
+ public ChunkLocation(ChunkLocation loc) {
+ this.x = loc.x;
+ this.y = loc.y;
+ this.z = loc.z;
+ }
+
public int x;
public int y;
public int z;
@@ -42,4 +48,32 @@ public class ChunkLocation implements Serializable {
public BlockLocation getBlockLocation() {
return new BlockLocation(Chunk.rev(x), Chunk.rev(y) - 128, Chunk.rev(z));
}
+
+ public ChunkLocation getNeighbor(int dx, int dy, int dz) {
+ return new ChunkLocation(x + dx, y + dy, z + dz);
+ }
+
+ public ChunkLocation getLeft() {
+ return getNeighbor(-1, 0, 0);
+ }
+
+ public ChunkLocation getRight() {
+ return getNeighbor(1, 0, 0);
+ }
+
+ public ChunkLocation getTop() {
+ return getNeighbor(0, 1, 0);
+ }
+
+ public ChunkLocation getBottom() {
+ return getNeighbor(0, -1, 0);
+ }
+
+ public ChunkLocation getBack() {
+ return getNeighbor(0, 0, -1);
+ }
+
+ public ChunkLocation getFront() {
+ return getNeighbor(0, 0, 1);
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/provider/WorldProvider.java b/src/ru/olamedia/olacraft/world/provider/WorldProvider.java
index 9e76d1a..7471b52 100644
--- a/src/ru/olamedia/olacraft/world/provider/WorldProvider.java
+++ b/src/ru/olamedia/olacraft/world/provider/WorldProvider.java
@@ -3,7 +3,9 @@ package ru.olamedia.olacraft.world.provider;
import ru.olamedia.olacraft.game.SpawnLocation;
import ru.olamedia.olacraft.world.WorldInfo;
import ru.olamedia.olacraft.world.block.Block;
-import ru.olamedia.olacraft.world.chunk.Chunk;
+import ru.olamedia.olacraft.world.block.BlockRegistry;
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
import ru.olamedia.olacraft.world.chunk.ChunkUnavailableException;
import ru.olamedia.olacraft.world.data.ChunkData;
import ru.olamedia.olacraft.world.data.RegionData;
@@ -14,11 +16,16 @@ import ru.olamedia.olacraft.world.location.RegionLocation;
public class WorldProvider {
private WorldInfo info = new WorldInfo();
+ private BlockRegistry typeRegistry = new BlockRegistry();
private AbstractChunkDataProvider dataProvider;
public WorldInfo getInfo() {
return info;
}
+
+ public BlockRegistry getTypeRegistry(){
+ return typeRegistry;
+ }
public void setInfo(WorldInfo worldInfo) {
info = worldInfo;
@@ -126,11 +133,14 @@ public class WorldProvider {
}
public Block getBlock(int x, int y, int z) {
- BlockLocation blockLocation = new BlockLocation(x, y, z);
return new Block(this, x, y, z);
}
public ChunkData getChunk(ChunkLocation chunkLocation) {
return dataProvider.getChunk(chunkLocation);
}
+
+ public BlockType getBlockTypeById(int id) {
+ return typeRegistry.getBlockType(id);
+ }
}
diff --git a/src/ru/olamedia/player/Player.java b/src/ru/olamedia/player/Player.java
index 08811b5..bb62201 100644
--- a/src/ru/olamedia/player/Player.java
+++ b/src/ru/olamedia/player/Player.java
@@ -4,6 +4,9 @@ import ru.olamedia.liveEntity.LiveEntity;
import ru.olamedia.olacraft.game.Game;
import ru.olamedia.olacraft.network.packet.LiveEntityLocationUpdatePacket;
import ru.olamedia.olacraft.weapon.Bullet;
+import ru.olamedia.olacraft.world.block.Block;
+import ru.olamedia.olacraft.world.chunk.Chunk;
+import ru.olamedia.olacraft.world.data.ChunkData;
public class Player extends LiveEntity {
@@ -17,15 +20,21 @@ public class Player extends LiveEntity {
}
public Player() {
-
+ }
+
+ public void pickBlock(Block b){
+ b.removeFromWorld();
}
public void onMouseClick() {
- Bullet b = new Bullet();
- b.velocity.set(Game.instance.camera.getLook());
- b.velocity.negate();
- b.velocity.scale(100);
- b.location.set(getX(), getCameraY(), getZ());
- Game.client.getScene().addBullet(b);
+ if (null != Game.client.getScene().nearestBlock){
+ pickBlock(Game.client.getScene().nearestBlock);
+ }
+ // Bullet b = new Bullet();
+ // b.velocity.set(Game.instance.camera.getLook());
+ // b.velocity.negate();
+ // b.velocity.scale(100);
+ // b.location.set(getX(), getCameraY(), getZ());
+ // Game.client.getScene().addBullet(b);
}
}