aboutsummaryrefslogtreecommitdiffstats
path: root/src/ru/olamedia/olacraft
diff options
context:
space:
mode:
authorolamedia <[email protected]>2012-12-23 11:30:36 +0600
committerolamedia <[email protected]>2012-12-23 11:30:36 +0600
commitf58bdfcb66353bb77213cab580bc49ef890417ad (patch)
tree2983a05d564891e92c115a679f9bfbf55465c755 /src/ru/olamedia/olacraft
parent5320fd1dad5b77fa227e83fbbe0a958f2c5fc283 (diff)
0.1.7
Diffstat (limited to 'src/ru/olamedia/olacraft')
-rw-r--r--src/ru/olamedia/olacraft/OlaCraft.java2
-rw-r--r--src/ru/olamedia/olacraft/game/Game.java14
-rw-r--r--src/ru/olamedia/olacraft/inventory/Inventory.java416
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/Arm.java27
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/Bone.java215
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/BoneSet.java163
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/ISkeletonNode.java26
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/Leg.java27
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/ModelAnimator.java324
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/Randomizer.java92
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/Skeleton.java47
-rw-r--r--src/ru/olamedia/olacraft/modelAnimator/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/network/GameClient.java8
-rw-r--r--src/ru/olamedia/olacraft/network/GameServer.java14
-rw-r--r--src/ru/olamedia/olacraft/network/Network.java6
-rw-r--r--src/ru/olamedia/olacraft/network/packet/SectorDataPacket.java14
-rw-r--r--src/ru/olamedia/olacraft/network/provider/CacheProvider.java29
-rw-r--r--src/ru/olamedia/olacraft/network/provider/IProvider.java11
-rw-r--r--src/ru/olamedia/olacraft/network/provider/LocalProvider.java21
-rw-r--r--src/ru/olamedia/olacraft/network/provider/RemoteProvider.java19
-rw-r--r--src/ru/olamedia/olacraft/network/provider/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/ChunkRangeRenderer.java254
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java29
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/IRenderer.java1
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java4
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/joglViewport.java38
-rw-r--r--src/ru/olamedia/olacraft/scene/GameScene.java691
-rw-r--r--src/ru/olamedia/olacraft/world/biome/Biome.java10
-rw-r--r--src/ru/olamedia/olacraft/world/biome/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/block/Block.java372
-rw-r--r--src/ru/olamedia/olacraft/world/block/BlockRegistry.java31
-rw-r--r--src/ru/olamedia/olacraft/world/blockRenderer/AbstractBlockRenderer.java64
-rw-r--r--src/ru/olamedia/olacraft/world/blockRenderer/BoxRenderer.java282
-rw-r--r--src/ru/olamedia/olacraft/world/blockRenderer/ChunkMeshGarbageCollector.java82
-rw-r--r--src/ru/olamedia/olacraft/world/blockRenderer/ChunkRenderer.java356
-rw-r--r--src/ru/olamedia/olacraft/world/blockRenderer/CrossQuadsRenderer.java115
-rw-r--r--src/ru/olamedia/olacraft/world/blockRenderer/IBlockRenderer.java15
-rw-r--r--src/ru/olamedia/olacraft/world/blockRenderer/RenderLocation.java35
-rw-r--r--src/ru/olamedia/olacraft/world/blockRenderer/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/blockStack/BlockStack.java56
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java110
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/BlockType.java62
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java6
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java6
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java4
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java4
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/IceBlockType.java32
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/SnowBlockType.java27
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/TallGrassBlockType.java58
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/WaterBlockType.java42
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/WheatBlockType.java58
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/BrecciaStoneBlockType.java25
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/ChertStoneBlockType.java25
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/CoalStoneBlockType.java25
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/ConglomerateStoneBlockType.java25
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/LimestoneStoneBlockType.java25
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/SandstoneStoneBlockType.java25
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/ShaleStoneBlockType.java25
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/SiltstoneStoneBlockType.java25
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/stone/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/calc/LightCalculator.java118
-rw-r--r--src/ru/olamedia/olacraft/world/calc/LightData.java28
-rw-r--r--src/ru/olamedia/olacraft/world/calc/VisibilityCalculator.java99
-rw-r--r--src/ru/olamedia/olacraft/world/calc/VisibilityData.java30
-rw-r--r--src/ru/olamedia/olacraft/world/calc/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/BlockSlice.java22
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/Chunk.java244
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java11
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java19
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/ChunkUnavailableException.java2
-rw-r--r--src/ru/olamedia/olacraft/world/data/ChunkData.java213
-rw-r--r--src/ru/olamedia/olacraft/world/data/ChunkDataManager.java22
-rw-r--r--src/ru/olamedia/olacraft/world/data/ChunkDataNeighbors.java162
-rw-r--r--src/ru/olamedia/olacraft/world/data/ChunkDataPointer.java82
-rw-r--r--src/ru/olamedia/olacraft/world/data/ChunkDataWrapper.java40
-rw-r--r--src/ru/olamedia/olacraft/world/data/RegionData.java24
-rw-r--r--src/ru/olamedia/olacraft/world/data/SectorData.java46
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java12
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java93
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java76
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java17
-rw-r--r--src/ru/olamedia/olacraft/world/drop/DroppedEntity.java17
-rw-r--r--src/ru/olamedia/olacraft/world/drop/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/fluid/FluidLevel.java9
-rw-r--r--src/ru/olamedia/olacraft/world/fluid/FluidLine.java56
-rw-r--r--src/ru/olamedia/olacraft/world/fluid/FluidSource.java99
-rw-r--r--src/ru/olamedia/olacraft/world/fluid/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/generator/HeightMapGenerator.java9
-rw-r--r--src/ru/olamedia/olacraft/world/generator/HumiditySelectLayer.java31
-rw-r--r--src/ru/olamedia/olacraft/world/generator/IslandSelectLayer.java31
-rw-r--r--src/ru/olamedia/olacraft/world/generator/MountainSelectLayer.java38
-rw-r--r--src/ru/olamedia/olacraft/world/generator/OceanSelectLayer.java31
-rw-r--r--src/ru/olamedia/olacraft/world/generator/RegionGenerator.java318
-rw-r--r--src/ru/olamedia/olacraft/world/generator/RiverSelectLayer.java56
-rw-r--r--src/ru/olamedia/olacraft/world/generator/TemperatureSelectLayer.java31
-rw-r--r--src/ru/olamedia/olacraft/world/location/BlockLocation.java88
-rw-r--r--src/ru/olamedia/olacraft/world/location/ChunkLocation.java21
-rw-r--r--src/ru/olamedia/olacraft/world/location/IntLocation.java200
-rw-r--r--src/ru/olamedia/olacraft/world/location/Location3f.java46
-rw-r--r--src/ru/olamedia/olacraft/world/location/Location3i.java71
-rw-r--r--src/ru/olamedia/olacraft/world/location/MetaLocation3i.java7
-rw-r--r--src/ru/olamedia/olacraft/world/location/RegionLocation.java36
-rw-r--r--src/ru/olamedia/olacraft/world/provider/IWorldProvider.java11
-rw-r--r--src/ru/olamedia/olacraft/world/provider/LocalWorld.java24
-rw-r--r--src/ru/olamedia/olacraft/world/provider/RemoteWorld.java32
-rw-r--r--src/ru/olamedia/olacraft/world/provider/WorldProvider.java144
106 files changed, 6429 insertions, 920 deletions
diff --git a/src/ru/olamedia/olacraft/OlaCraft.java b/src/ru/olamedia/olacraft/OlaCraft.java
index b5b3234..2dd39f0 100644
--- a/src/ru/olamedia/olacraft/OlaCraft.java
+++ b/src/ru/olamedia/olacraft/OlaCraft.java
@@ -1,6 +1,6 @@
package ru.olamedia.olacraft;
public class OlaCraft {
- public static String version = "0.1.6";
+ public static String version = "0.1.7";
}
diff --git a/src/ru/olamedia/olacraft/game/Game.java b/src/ru/olamedia/olacraft/game/Game.java
index 0980505..a2bc05e 100644
--- a/src/ru/olamedia/olacraft/game/Game.java
+++ b/src/ru/olamedia/olacraft/game/Game.java
@@ -1,14 +1,10 @@
package ru.olamedia.olacraft.game;
-import com.jogamp.newt.opengl.GLWindow;
-
import ru.olamedia.camera.MatrixCamera;
import ru.olamedia.game.GameFrame;
import ru.olamedia.olacraft.events.GameEvent;
import ru.olamedia.olacraft.network.GameClient;
import ru.olamedia.olacraft.network.GameServer;
-import ru.olamedia.olacraft.scene.GameScene;
-import ru.olamedia.olacraft.world.dataProvider.AbstractChunkDataProvider;
import ru.olamedia.player.Player;
public class Game {
@@ -17,7 +13,7 @@ public class Game {
public static boolean isServerRunning = false;
public static GameServer server = new GameServer();
public static GameClient client = new GameClient();
- public static Timer timer = new Timer();
+ public static Timer fpsTimer = new Timer();
public MatrixCamera camera;
@@ -27,7 +23,6 @@ public class Game {
@SuppressWarnings("unused")
private int mode = 1;
private boolean isRunning = false;
- @SuppressWarnings("unused")
// player
public Player player;
@@ -50,7 +45,7 @@ public class Game {
}
player = new Player();
camera = new MatrixCamera();
- camera.attachTo(player);
+ camera.attachTo(player, true);
camera.setFov(90);
camera.pack();
// scene.registerLiveEntity(player);
@@ -81,7 +76,6 @@ public class Game {
}
public void tick() {
- timer.update();
}
@@ -99,8 +93,8 @@ public class Game {
}
}
- public float getDelta() {
- return (float) timer.getElapsedTime() / 1000;
+ public float getFrameDelta() {
+ return (float) fpsTimer.getElapsedTime() / 1000f;
}
}
diff --git a/src/ru/olamedia/olacraft/inventory/Inventory.java b/src/ru/olamedia/olacraft/inventory/Inventory.java
index 2ce843b..3076dfe 100644
--- a/src/ru/olamedia/olacraft/inventory/Inventory.java
+++ b/src/ru/olamedia/olacraft/inventory/Inventory.java
@@ -1,76 +1,402 @@
package ru.olamedia.olacraft.inventory;
-import ru.olamedia.olacraft.world.block.Block;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLContext;
+
+import com.jogamp.opengl.util.texture.Texture;
+
+import ru.olamedia.asset.SpriteRectangle;
+import ru.olamedia.game.GameFrame;
+import ru.olamedia.geom.ImmModeMesh;
+import ru.olamedia.input.MouseJail;
+import ru.olamedia.olacraft.game.Game;
import ru.olamedia.olacraft.world.blockStack.BlockStack;
+import ru.olamedia.olacraft.world.blockTypes.EmptyBlockType;
+import ru.olamedia.olacraft.world.blockTypes.GravelBlockType;
+import ru.olamedia.olacraft.world.blockTypes.WheatBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.BrecciaStoneBlockType;
+import ru.olamedia.texture.TextureManager;
public class Inventory {
public static int BIND_NUM = 10;
- public BlockStack[] binded = new BlockStack[BIND_NUM];
+ public static int BACKPACK_NUM = 10 * 5;
+ public static int TOTAL_NUM = BIND_NUM + BACKPACK_NUM;
+ public BlockStack[] binded = new BlockStack[TOTAL_NUM];
public BlockStack selected;
- public int selectedId;
- private boolean isInventoryGUIOpen = false;
+ public int selectedId = 0;
+ private boolean isGUIOpened = false;
- public Inventory() {
+ private int[] bindedX = new int[TOTAL_NUM];
+ private int[] bindedY = new int[TOTAL_NUM];
+
+ public BlockStack picked = null;
+ public int pickedId = 0;
+
+ private ImmModeMesh bindedGUI;
+
+ public void pickHover(boolean half) {
+ System.out.println("pick hover " + MouseJail.instance.y);
+ int x = MouseJail.instance.x;
+ int y = MouseJail.instance.y;
+ for (int i = 0; i < TOTAL_NUM; i++) {
+ if (x >= bindedX[i] && x <= bindedX[i] + 32 && y >= bindedY[i] && y <= bindedY[i] + 32) {
+ if (binded[i].count > 0) {
+ int pickCount = binded[i].count;
+ if (pickCount > 1 && half) {
+ pickCount = pickCount / 2;
+ }
+ System.out.println("pick binded");
+ pickedId = i;
+ picked = binded[pickedId].get(pickCount);
+ }
+ }
+ }
}
- public void init() {
- for (int i = 0; i < BIND_NUM; i++) {
- Block block = new Block(x + bindedWrapperPadding + i * BLOCK_SIZE + bindedSpacing * i, y
- + bindedWrapperPadding + 0, 0, "gravel");
- binded[i] = new BlockStack(block, 64);
+ public void placePicked() {
+ if (null == picked) {
+ return;
+ }
+ int x = MouseJail.instance.x;
+ int y = MouseJail.instance.y;
+ for (int i = 0; i < TOTAL_NUM; i++) {
+ if (x >= bindedX[i] && x <= bindedX[i] + 32 && y >= bindedY[i] && y <= bindedY[i] + 32) {
+ if (picked.type.getClass().getName().equals(binded[i].type.getClass().getName())
+ || binded[i].count == 0) {
+ // same type or empty slot
+ binded[i].putStack(picked);
+ if (picked.count == 0) {
+ picked = null;
+ } else {
+ binded[pickedId] = picked; // place picked to hovered
+ picked = null;
+ }
+ } else {
+ // different types
+ // swap
+ binded[pickedId].putStack(picked);
+ picked = binded[pickedId];
+ binded[pickedId] = binded[i];
+ binded[i] = picked;
+ picked = null;
+ }
+ }
}
- binded[0].block.setName("dirt");
- binded[1].block.setName("grass");
- binded[2].block.setName("water");
- binded[3].block.setName("wood");
- binded[4].block.setName("asphalt");
- binded[5].block.setName("torch");
- binded[8].block.setName("grass");
- binded[9].block.setName("dirt");
- frame = new Frame(0, 0, 0, BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
- select(0);
}
- public void onKeyDown() {
- // System.out.println("keyName: " + api.keyboard.keyName);
- int key = Keyboard.getEventKey();
- if (key == Keyboard.KEY_1) {
- select(0);
+ public void putPickedBack() {
+ if (null != picked) {
+ binded[pickedId].putStack(picked); // put back
+ picked = null;
}
- if (key == Keyboard.KEY_2) {
- select(1);
+ }
+
+ public Inventory() {
+ for (int i = 0; i < TOTAL_NUM; i++) {
+ binded[i] = new BlockStack(new EmptyBlockType(), 0);
}
- if (key == Keyboard.KEY_3) {
- select(2);
+ binded[0].type = new WheatBlockType();
+ binded[0].count = 60;
+ binded[1].type = new BrecciaStoneBlockType();
+ binded[1].count = 60;
+ }
+
+ public void openGUI() {
+ isGUIOpened = true;
+ MouseJail.enable();
+ MouseJail.setActive(false);
+ MouseJail.disable();
+ }
+
+ public void buildMeshes() {
+ bindedGUI = ImmModeMesh.allocate(2 * 4 + BIND_NUM * 4);
+ bindedGUI.enableColor3();
+ bindedGUI.enableVertex2();
+ int x = 0 + GameFrame.getGLWidth() / 2 - width / 2;
+ int y = GameFrame.getGLHeight() - height - padding;
+ bindedGUI.glBegin(GL2.GL_QUADS);
+ {
+ bindedGUI.glColor3f(0.2f, 0.2f, 0.2f);
+ bindedGUI.glRectf(x, y, x + width, y + height);
+ for (int i = 0; i < BIND_NUM; i++) {
+ bindedX[i] = x + padding + spacing * i + 34 * i + 1;
+ bindedY[i] = y + padding + 1;
+ int fx = x + padding + spacing * i + 34 * i;
+ int fy = y + padding;
+ // left
+ bindedGUI.glColor3f(0.0f, 0.0f, 0.0f);
+ bindedGUI.glRectf(fx, fy, fx + spacing / 2, fy + 34);
+ // right
+ bindedGUI.glColor3f(0.5f, 0.5f, 0.5f);
+ bindedGUI.glRectf(fx + 33, fy, fx + 33 + spacing / 2, fy + 34);
+ // top
+ bindedGUI.glColor3f(0.2f, 0.2f, 0.2f);
+ bindedGUI.glRectf(fx, fy, fx + 34, fy + spacing / 2);
+ // bottom
+ bindedGUI.glColor3f(0.3f, 0.3f, 0.3f);
+ bindedGUI.glRectf(fx, fy + 33, fx + 34, fy + 33 + spacing / 2);
+ bindedGUI.glColor3f(0.6f, 0.6f, 0.6f);
+ bindedGUI.glRectf(fx + 1, fy + 1, fx + 1 + 32, fy + 1 + 32);
+ }
+ // frame
+ bindedGUI.glColor3f(0.2f, 0.2f, 0.2f);
+ int fx = x + padding + spacing * selectedId + 34 * selectedId;
+ int fy = y + padding;
+ bindedGUI.glColor3f(15f / 15f, 6f / 15f, 0f);
+ bindedGUI.glRectf(fx, fy, fx + 32 + 2, fy + 32 + 2);
+ bindedGUI.glColor3f(0.8f, 0.8f, 0.8f);
+ bindedGUI.glRectf(fx + 1, fy + 1, fx + 1 + 32, fy + 1 + 32);
}
- if (key == Keyboard.KEY_4) {
- select(3);
+ bindedGUI.glEnd();
+ }
+
+ public BlockStack getSelectedBlockStack() {
+ return binded[selectedId];
+ }
+
+ /**
+ *
+ */
+ public void putBlockStack(BlockStack external) {
+ System.out.println("put stack " + external.type.getClass().getName());
+ // looking for same type
+ int i = 0;
+ while (i < TOTAL_NUM && external.count > 0) {
+ if (binded[i].type.getClass().getName() == external.type.getClass().getName()) {
+ System.out.println("append stack");
+ binded[i].putStack(external);
+ }
+ i++;
}
- if (key == Keyboard.KEY_5) {
- select(4);
+ i = 0;
+ // looking for empty slot
+ while (i < TOTAL_NUM && external.count > 0) {
+ if (binded[i].count == 0) { // empty
+ System.out.println("replace stack");
+ binded[i].putStack(external);
+ }
+ i++;
}
- if (key == Keyboard.KEY_6) {
- select(5);
+ }
+
+ public void closeGUI() {
+ isGUIOpened = false;
+ MouseJail.enable();
+ MouseJail.setActive(true);
+ if (null != picked) {
+ putPickedBack();
}
- if (key == Keyboard.KEY_7) {
- select(6);
+ }
+
+ private int spacing = 2;
+ private int padding = spacing / 2 + 1;
+ private int width = 34 * BIND_NUM + padding * 2 + spacing * (BIND_NUM - 1);
+ private int height = 34 + padding * 2;
+
+ public void renderGUIClosed() {
+ // render bottom line
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+
+ int x = 0 + GameFrame.getGLWidth() / 2 - width / 2;
+ int y = GameFrame.getGLHeight() - height - padding;
+ /*
+ * gl.glColor3f(0.8f, 0.8f, 0.8f);
+ * gl.glRecti(x, y, x + width, y + height);
+ * for (int i = 0; i < BIND_NUM; i++) {
+ * bindedX[i] = x + padding + spacing * i + 32 * i + 1;
+ * bindedY[i] = y + padding + 1;
+ * int fx = x + padding + spacing * i + 32 * i;
+ * int fy = y + padding;
+ * // left
+ * gl.glColor3f(0.6f, 0.6f, 0.6f);
+ * gl.glRecti(fx, fy, fx + spacing / 2, fy + 32);
+ * // right
+ * gl.glColor3f(0.5f, 0.5f, 0.5f);
+ * gl.glRecti(fx, fy, fx + spacing / 2, fy + 32);
+ * // top
+ * gl.glColor3f(0.4f, 0.4f, 0.4f);
+ * gl.glRecti(fx, fy, fx + 32, fy + spacing / 2);
+ * // bottom
+ * gl.glColor3f(0.3f, 0.3f, 0.3f);
+ * gl.glRecti(fx, fy, fx + 32, fy + spacing / 2);
+ * }
+ */
+ if (null != bindedGUI) {
+ bindedGUI.draw();
}
- if (key == Keyboard.KEY_8) {
- select(7);
+
+ gl.glEnable(GL2.GL_TEXTURE_2D);
+ for (int i = 0; i < BIND_NUM; i++) {
+ BlockStack stack = binded[i];
+ if (null != stack && !(stack.type instanceof EmptyBlockType) && stack.count > 0 && !stack.hidden) {
+ Texture tex = TextureManager.getSprite(stack.type.getStackTextureFile());
+ SpriteRectangle uv = TextureManager.getSpriteOffset(stack.type.getStackTextureFile());
+ tex.bind(gl);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST);
+ gl.glColor3f(1, 1, 1);
+ int sx = x + padding + spacing * i + 34 * i + 1;
+ int sy = y + padding + 1;
+ gl.glTexCoord4f(uv.topLeft.x, uv.topLeft.y, uv.bottomRight.x, uv.bottomRight.y);
+ gl.glBegin(GL2.GL_QUADS);
+ {
+ gl.glTexCoord2f(uv.topLeft.x, uv.topLeft.y);
+ gl.glVertex2f(sx, sy);
+ gl.glTexCoord2f(uv.topLeft.x, uv.bottomRight.y);
+ gl.glVertex2f(sx, sy + 32);
+ gl.glTexCoord2f(uv.bottomRight.x, uv.bottomRight.y);
+ gl.glVertex2f(sx + 32, sy + 32);
+ gl.glTexCoord2f(uv.bottomRight.x, uv.topLeft.y);
+ gl.glVertex2f(sx + 32, sy);
+ }
+ gl.glEnd();
+ // if (stack.count > 0) {
+ gl.glColor4f(1, 1, 1, 1);
+ Game.client.getScene().viewport.drawText("" + stack.count, sx, GameFrame.getGLHeight() - sy - 10);
+ // }
+ }
}
- if (key == Keyboard.KEY_9) {
- select(8);
+ if (null != picked) {
+ // draw picked
+ BlockStack stack = picked;
+ if (null != stack && !(stack.type instanceof EmptyBlockType) && stack.count > 0) {
+ Texture tex = TextureManager.getSprite(stack.type.getStackTextureFile());
+ SpriteRectangle uv = TextureManager.getSpriteOffset(stack.type.getStackTextureFile());
+ tex.bind(gl);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST);
+ gl.glColor3f(1, 1, 1);
+ int sx = MouseJail.instance.x - 16;
+ int sy = MouseJail.instance.y - 16;
+ gl.glTexCoord4f(uv.topLeft.x, uv.topLeft.y, uv.bottomRight.x, uv.bottomRight.y);
+ gl.glBegin(GL2.GL_QUADS);
+ {
+ gl.glTexCoord2f(uv.topLeft.x, uv.topLeft.y);
+ gl.glVertex2f(sx, sy);
+ gl.glTexCoord2f(uv.topLeft.x, uv.bottomRight.y);
+ gl.glVertex2f(sx, sy + 32);
+ gl.glTexCoord2f(uv.bottomRight.x, uv.bottomRight.y);
+ gl.glVertex2f(sx + 32, sy + 32);
+ gl.glTexCoord2f(uv.bottomRight.x, uv.topLeft.y);
+ gl.glVertex2f(sx + 32, sy);
+ }
+ gl.glEnd();
+ // if (stack.count > 0) {
+ gl.glColor4f(1, 1, 1, 1);
+ Game.client.getScene().viewport.drawText("" + stack.count, sx, GameFrame.getGLHeight() - sy - 10);
+ // }
+ }
}
- if (key == Keyboard.KEY_0) {
- select(9);
+ gl.glDisable(GL2.GL_TEXTURE_2D);
+ }
+
+ public void renderGUIOpened() {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+
+ int oHeight = 300;
+ int x = 0 + GameFrame.getGLWidth() / 2 - width / 2;
+ int y = GameFrame.getGLHeight() - oHeight - height - padding - 32;
+ gl.glColor3f(0.8f, 0.8f, 0.8f);
+ gl.glRecti(x, y, x + width, y + oHeight);
+ for (int ni = BIND_NUM; ni < BIND_NUM + BACKPACK_NUM; ni++) {
+ int dy = ni / 10;
+ int dx = ni - dy * 10;
+ bindedX[ni] = x + padding + spacing * dx + 32 * dx + 1;
+ bindedY[ni] = y + padding + spacing * dy + 32 * dy + 1;
+ int fx = x + padding + spacing * dx + 32 * dx;
+ int fy = y + padding + spacing * dy + 32 * dy;
+ // left
+ gl.glColor3f(0.6f, 0.6f, 0.6f);
+ gl.glRecti(fx, fy, fx + spacing / 2, fy + 32);
+ // right
+ gl.glColor3f(0.5f, 0.5f, 0.5f);
+ gl.glRecti(fx, fy, fx + spacing / 2, fy + 32);
+ // top
+ gl.glColor3f(0.4f, 0.4f, 0.4f);
+ gl.glRecti(fx, fy, fx + 32, fy + spacing / 2);
+ // bottom
+ gl.glColor3f(0.3f, 0.3f, 0.3f);
+ gl.glRecti(fx, fy, fx + 32, fy + spacing / 2);
}
- if (key == Keyboard.KEY_E) {
- isInventoryGUIOpen = !isInventoryGUIOpen;
+ gl.glColor3f(0.2f, 0.2f, 0.2f);
+ int fx = x + padding + spacing * selectedId + 32 * selectedId;
+ int fy = y + padding;
+ gl.glRecti(fx, fy, fx + 32 + 2, fy + 32 + 2);
+ gl.glEnable(GL2.GL_TEXTURE_2D);
+ for (int ni = BIND_NUM; ni < BIND_NUM + BACKPACK_NUM; ni++) {
+ int dy = ni / 10;
+ int dx = ni - dy * 10;
+ bindedX[ni] = x + padding + spacing * dx + 32 * dx + 1;
+ bindedY[ni] = y + padding + spacing * dy + 32 * dy + 1;
+ int sx = x + padding + spacing * dx + 32 * dx + 1;
+ int sy = y + padding + spacing * dy + 32 * dy + 1;
+ BlockStack stack = binded[ni];
+ if (null != stack && !(stack.type instanceof EmptyBlockType) && stack.count > 0 && !stack.hidden) {
+ Texture tex = TextureManager.getSprite(stack.type.getStackTextureFile());
+ SpriteRectangle uv = TextureManager.getSpriteOffset(stack.type.getStackTextureFile());
+ tex.bind(gl);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST);
+ gl.glColor3f(1, 1, 1);
+ gl.glTexCoord4f(uv.topLeft.x, uv.topLeft.y, uv.bottomRight.x, uv.bottomRight.y);
+ gl.glBegin(GL2.GL_QUADS);
+ {
+ gl.glTexCoord2f(uv.topLeft.x, uv.topLeft.y);
+ gl.glVertex2f(sx, sy);
+ gl.glTexCoord2f(uv.topLeft.x, uv.bottomRight.y);
+ gl.glVertex2f(sx, sy + 32);
+ gl.glTexCoord2f(uv.bottomRight.x, uv.bottomRight.y);
+ gl.glVertex2f(sx + 32, sy + 32);
+ gl.glTexCoord2f(uv.bottomRight.x, uv.topLeft.y);
+ gl.glVertex2f(sx + 32, sy);
+ }
+ gl.glEnd();
+ // if (stack.count > 0) {
+ gl.glColor4f(1, 1, 1, 1);
+ Game.client.getScene().viewport.drawText("" + stack.count, sx, GameFrame.getGLHeight() - sy - 10);
+ // }
+ }
}
+ gl.glDisable(GL2.GL_TEXTURE_2D);
+ }
+ public void renderGUI() {
+ if (isGUIOpened) {
+ renderGUIOpened();
+ } else {
+ if (null != picked) {
+ putPickedBack();
+ }
+ }
+ renderGUIClosed();
}
public void select(int i) {
+ selectedId = i;
selected = binded[i];
+ buildMeshes();
+ }
+
+ public void toggleGUI() {
+ if (isGUIOpened) {
+ closeGUI();
+ } else {
+ openGUI();
+ }
+ buildMeshes();
+ }
+
+ public boolean isGUIOpened() {
+ return isGUIOpened;
+ }
+
+ public void click(boolean half) {
+ if (null == picked) {
+ pickHover(half);
+ } else {
+ placePicked();
+ }
+ buildMeshes();
}
}
diff --git a/src/ru/olamedia/olacraft/modelAnimator/Arm.java b/src/ru/olamedia/olacraft/modelAnimator/Arm.java
new file mode 100644
index 0000000..eeeea77
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/Arm.java
@@ -0,0 +1,27 @@
+package ru.olamedia.olacraft.modelAnimator;
+
+public class Arm extends BoneSet {
+ // 左腕 - левая рука
+ // 左ひじ - левый локоть
+ // 左手首 - левое запястье
+ // 左袖 - левый рукав
+ public Bone top;
+ public Bone elbow;
+ public Bone wrist;
+
+ public Arm() {
+ super(3);
+ top = new Bone();
+ elbow = new Bone();
+ wrist = new Bone();
+ setChild(0, top);
+ setChild(1, elbow);
+ setChild(2, wrist);
+ }
+
+ public void setNamePrefix(String prefix) {
+ top.setName(prefix + top.getName());
+ elbow.setName(prefix + elbow.getName());
+ wrist.setName(prefix + wrist.getName());
+ }
+}
diff --git a/src/ru/olamedia/olacraft/modelAnimator/Bone.java b/src/ru/olamedia/olacraft/modelAnimator/Bone.java
new file mode 100644
index 0000000..0bda33d
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/Bone.java
@@ -0,0 +1,215 @@
+package ru.olamedia.olacraft.modelAnimator;
+
+import java.util.Random;
+
+public class Bone implements ISkeletonNode {
+ private String name;
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ private float speed = 1f;
+ private float yaw;
+ private float pitch;
+ private float roll;
+ private float yawCorrection = 0;
+ private float pitchCorrection = 0;
+ private float rollCorrection = 0;
+ @SuppressWarnings("unused")
+ private boolean isAnglesModified = false;
+ private boolean isMatrixModified = false;
+
+ @Override
+ public int getChildrenCount() {
+ return 0;
+ }
+
+ @Override
+ public Bone getChild(int i) {
+ return null;
+ }
+
+ private void updateAngles() {
+ if (isMatrixModified) {
+
+ }
+ }
+
+ /*
+ * private void updateMatrix() {
+ * if (isAnglesModified) {
+ *
+ * }
+ * }
+ */
+
+ public float getSpeed() {
+ return speed;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ru.olamedia.olacraft.modelAnimator.ISkeletonNode#setSpeed(float)
+ */
+ @Override
+ public void setSpeed(float speed) {
+ this.speed = speed;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * ru.olamedia.olacraft.modelAnimator.ISkeletonNode#copyOrientation(ru.olamedia
+ * .olacraft.modelAnimator.Bone)
+ */
+ @Override
+ public void copyOrientation(ISkeletonNode node) {
+ final Bone b = (Bone) node;
+ setPitch(b.getPitch());
+ setPitchCorrection(b.getPitchCorrection());
+ setYaw(b.getYaw());
+ setYawCorrection(b.getYawCorrection());
+ setRoll(b.getRoll());
+ setRollCorrection(b.getRollCorrection());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * ru.olamedia.olacraft.modelAnimator.ISkeletonNode#setDelta(ru.olamedia
+ * .olacraft.modelAnimator.Bone, ru.olamedia.olacraft.modelAnimator.Bone,
+ * float)
+ */
+ @Override
+ public void setDelta(ISkeletonNode firstNode, ISkeletonNode secondNode, float delta) {
+ final Bone first = (Bone) firstNode;
+ final Bone second = (Bone) secondNode;
+ final float dPitch = second.getPitch() - first.getPitch();
+ setPitch(first.getPitch() + dPitch * getSpeed() * delta);
+ final float dYaw = second.getYaw() - first.getYaw();
+ setYaw(first.getYaw() + dYaw * getSpeed() * delta);
+ final float dRoll = second.getRoll() - first.getRoll();
+ setRoll(first.getRoll() + dRoll * getSpeed() * delta);
+ }
+
+ public float getYaw() {
+ updateAngles();
+ return yaw;
+ }
+
+ public float getCorrectedYaw() {
+ return getYawCorrection() + getYaw();
+ }
+
+ public void setYaw(float yaw) {
+ this.yaw = yaw;
+ isAnglesModified = true;
+ }
+
+ public float getPitch() {
+ updateAngles();
+ return pitch;
+ }
+
+ public float getCorrectedPitch() {
+ return getPitchCorrection() + getPitch();
+ }
+
+ public void setPitch(float pitch) {
+ this.pitch = pitch;
+ isAnglesModified = true;
+ }
+
+ public float getRoll() {
+ updateAngles();
+ return roll;
+ }
+
+ public float getCorrectedRoll() {
+ return getRollCorrection() + getRoll();
+ }
+
+ public void setRoll(float roll) {
+ this.roll = roll;
+ isAnglesModified = true;
+ }
+
+ private final float yawRand = 5f;
+ private final float pitchRand = 1f;
+ private final float rollRand = 5f;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ru.olamedia.olacraft.modelAnimator.ISkeletonNode#reset()
+ */
+ @Override
+ public void reset() {
+ yaw = 0;
+ pitch = 0;
+ roll = 0;
+ }
+
+ private float nextFloatDelta(Random rand, Random prev, float delta) {
+ final float first = prev.nextFloat();
+ final float second = rand.nextFloat();
+ return first + (second - first) * delta;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * ru.olamedia.olacraft.modelAnimator.ISkeletonNode#randomize(java.util.
+ * Random, java.util.Random, float)
+ */
+ @Override
+ public void randomize(Random rand, Random prev, float delta) {
+ // delta = 1;
+ setYaw(yaw + (nextFloatDelta(rand, prev, delta) - 0.5f) * yawRand);
+ setPitch(pitch + (nextFloatDelta(rand, prev, delta) - 0.5f) * pitchRand);
+ setRoll(roll + (nextFloatDelta(rand, prev, delta) - 0.5f) * rollRand);
+ }
+
+ public float getYawCorrection() {
+ return yawCorrection;
+ }
+
+ public void setYawCorrection(float yawCorrection) {
+ this.yawCorrection = yawCorrection;
+ }
+
+ public float getPitchCorrection() {
+ return pitchCorrection;
+ }
+
+ public void setPitchCorrection(float pitchCorrection) {
+ this.pitchCorrection = pitchCorrection;
+ }
+
+ public float getRollCorrection() {
+ return rollCorrection;
+ }
+
+ public void setRollCorrection(float rollCorrection) {
+ this.rollCorrection = rollCorrection;
+ }
+
+ @Override
+ public void setChild(int i, ISkeletonNode b) {
+
+ }
+}
diff --git a/src/ru/olamedia/olacraft/modelAnimator/BoneSet.java b/src/ru/olamedia/olacraft/modelAnimator/BoneSet.java
new file mode 100644
index 0000000..0e3ce2c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/BoneSet.java
@@ -0,0 +1,163 @@
+package ru.olamedia.olacraft.modelAnimator;
+
+import java.util.Iterator;
+import java.util.Random;
+
+public class BoneSet implements ISkeletonNode, Iterable<Bone> {
+
+ private class BonesIterator implements Iterator<Bone> {
+ private BoneSet set;
+ private Iterator<Bone> childIterator = null;
+ private int current = 0;
+
+ public BonesIterator(BoneSet boneSet) {
+ set = boneSet;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (null == childIterator) {
+ return current < set.getChildrenCount();
+ } else {
+ return childIterator.hasNext() || current < set.getChildrenCount();
+ }
+ }
+
+ private boolean nextIsChild;
+
+ @Override
+ public Bone next() {
+ if (null == childIterator) {
+ ISkeletonNode node = set.getChild(current);
+ if (node instanceof Bone) {
+ Bone b = (Bone) node;
+ current++;
+ return b;
+ } else if (node instanceof BoneSet) {
+ childIterator = ((BoneSet) node).iterator();
+ current++;
+ }
+ }
+ if (null != childIterator) {
+ nextIsChild = childIterator.hasNext();
+ if (nextIsChild) {
+ Bone b = childIterator.next();
+ return b;
+ }
+ if (!nextIsChild) {
+ childIterator = null;
+ }
+ }
+ if (current < set.getChildrenCount()) {
+ return next();
+ }
+ return null;
+ }
+
+ @Override
+ public void remove() {
+
+ }
+
+ }
+
+ public BoneSet(int bonesCount) {
+ nodes = new ISkeletonNode[bonesCount];
+ for (int i = 0; i < bonesCount; i++) {
+ // bones[i] = new Bone();
+ }
+ }
+
+ private ISkeletonNode[] nodes;
+ private String name;
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name
+ * the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public int getChildrenCount() {
+ return nodes.length;
+ }
+
+ public ISkeletonNode getChild(int i) {
+ return nodes[i];
+ }
+
+ @Override
+ public void setSpeed(float speed) {
+ for (ISkeletonNode b : nodes) {
+ b.setSpeed(speed);
+ }
+ }
+
+ @Override
+ public void copyOrientation(ISkeletonNode bs) {
+ for (int i = 0; i < nodes.length; i++) {
+ nodes[i].copyOrientation(bs.getChild(i));
+ }
+ }
+
+ @Override
+ public void setDelta(ISkeletonNode first, ISkeletonNode second, float delta) {
+ for (int i = 0; i < nodes.length; i++) {
+ nodes[i].setDelta(first.getChild(i), second.getChild(i), delta);
+ }
+ }
+
+ @Override
+ public void reset() {
+ for (int i = 0; i < nodes.length; i++) {
+ nodes[i].reset();
+ }
+ }
+
+ @Override
+ public void randomize(Random rand, Random prev, float delta) {
+ for (int i = 0; i < nodes.length; i++) {
+ nodes[i].randomize(rand, prev, delta);
+ }
+ }
+
+ @Override
+ public void setChild(int i, ISkeletonNode node) {
+ nodes[i] = node;
+ }
+
+ @Override
+ public Iterator<Bone> iterator() {
+ return new BonesIterator(this);
+ }
+
+ public int getBoneCount() {
+ int n = 0;
+ Iterator<Bone> it = iterator();
+ while (it.hasNext()) {
+ it.next();
+ n++;
+ }
+ return n;
+ }
+
+ public Bone getBone(int i) {
+ int j = 0;
+ Iterator<Bone> it = iterator();
+ Bone b = null;
+ while (it.hasNext() && j <= i) {
+ b = it.next();
+ j++;
+ }
+ return b;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/modelAnimator/ISkeletonNode.java b/src/ru/olamedia/olacraft/modelAnimator/ISkeletonNode.java
new file mode 100644
index 0000000..2b1b28a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/ISkeletonNode.java
@@ -0,0 +1,26 @@
+package ru.olamedia.olacraft.modelAnimator;
+
+import java.util.Random;
+
+public interface ISkeletonNode {
+ public void setName(String name);
+
+ public String getName();
+
+ public ISkeletonNode getChild(int i);
+
+ public void setChild(int i, ISkeletonNode b);
+
+ public int getChildrenCount();
+
+ public abstract void setSpeed(float speed);
+
+ public abstract void copyOrientation(ISkeletonNode b);
+
+ public abstract void setDelta(ISkeletonNode first, ISkeletonNode second, float delta);
+
+ public abstract void reset();
+
+ public abstract void randomize(Random rand, Random prev, float delta);
+
+} \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/modelAnimator/Leg.java b/src/ru/olamedia/olacraft/modelAnimator/Leg.java
new file mode 100644
index 0000000..0f9000d
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/Leg.java
@@ -0,0 +1,27 @@
+package ru.olamedia.olacraft.modelAnimator;
+
+public class Leg extends BoneSet {
+
+ public Bone top;
+ public Bone knee;
+ public Bone foot;
+
+ public Leg() {
+ super(3);
+ top = new Bone();
+ knee = new Bone();
+ foot = new Bone();
+ setChild(0, top);
+ setChild(1, knee);
+ setChild(2, foot);
+ top.setName("Top");
+ knee.setName("Knee");
+ foot.setName("Foot");
+ }
+
+ public void setNamePrefix(String prefix) {
+ top.setName(prefix + top.getName());
+ knee.setName(prefix + knee.getName());
+ foot.setName(prefix + foot.getName());
+ }
+}
diff --git a/src/ru/olamedia/olacraft/modelAnimator/ModelAnimator.java b/src/ru/olamedia/olacraft/modelAnimator/ModelAnimator.java
new file mode 100644
index 0000000..712cbd1
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/ModelAnimator.java
@@ -0,0 +1,324 @@
+package ru.olamedia.olacraft.modelAnimator;
+
+public class ModelAnimator {
+ private boolean isWalking = false;
+ private boolean isCrawling = false;
+ private boolean isCrouching = false;
+ private boolean isJumping = false;
+ private boolean isFalling = false;
+ private boolean isStrafingLeft = false;
+ private boolean isStrafingRight = false;
+ private boolean isMovingForward = false;
+ private boolean isMovingBackward = false;
+ private float delta;
+
+ private Skeleton currentOrientation = new Skeleton();
+ public Skeleton finalOrientation = new Skeleton();
+ public Skeleton deltaOrientation = new Skeleton();
+
+ public ModelAnimator() {
+ generateFrames();
+ }
+
+ public boolean isWalking() {
+ return isWalking;
+ }
+
+ public void setWalking(boolean isWalking) {
+ this.isWalking = isWalking;
+ }
+
+ public boolean isCrawling() {
+ return isCrawling;
+ }
+
+ public void setCrawling(boolean isCrawling) {
+ this.isCrawling = isCrawling;
+ }
+
+ public boolean isCrouching() {
+ return isCrouching;
+ }
+
+ public void setCrouching(boolean isCrouching) {
+ this.isCrouching = isCrouching;
+ }
+
+ public boolean isJumping() {
+ return isJumping;
+ }
+
+ public void setJumping(boolean isJumping) {
+ this.isJumping = isJumping;
+ }
+
+ public boolean isFalling() {
+ return isFalling;
+ }
+
+ public void setFalling(boolean isFalling) {
+ this.isFalling = isFalling;
+ }
+
+ public boolean isStrafingLeft() {
+ return isStrafingLeft;
+ }
+
+ public void setStrafingLeft(boolean isStrafingLeft) {
+ this.isStrafingLeft = isStrafingLeft;
+ }
+
+ public boolean isStrafingRight() {
+ return isStrafingRight;
+ }
+
+ public void setStrafingRight(boolean isStrafingRight) {
+ this.isStrafingRight = isStrafingRight;
+ }
+
+ public boolean isMovingForward() {
+ return isMovingForward;
+ }
+
+ public void setMovingForward(boolean isMovingForward) {
+ this.isMovingForward = isMovingForward;
+ }
+
+ public boolean isMovingBackward() {
+ return isMovingBackward;
+ }
+
+ public void setMovingBackward(boolean isMovingBackward) {
+ this.isMovingBackward = isMovingBackward;
+ }
+
+ public float getDelta() {
+ return delta;
+ }
+
+ public void setDelta(float delta) {
+ this.delta = delta;
+ }
+
+ // Frames
+ private Skeleton walkLeftLegForward = new Skeleton();
+ private Skeleton walkRightLegForward = new Skeleton();
+ private Skeleton standLeftLegApart = new Skeleton();
+ private Skeleton standRightLegApart = new Skeleton();
+
+ private void generateFrames() {
+ // walkLeftLegForward.leftLeg.top.setYaw(-5);
+ walkLeftLegForward.skirtFrontLeft.setPitch(30);
+ walkLeftLegForward.skirtFrontLeft.setYaw(30);
+ walkLeftLegForward.skirtFrontRight.setPitch(-5);
+ walkRightLegForward.skirtFrontRight.setPitch(30);
+ walkRightLegForward.skirtFrontRight.setYaw(-30);
+ walkRightLegForward.skirtFrontLeft.setPitch(-5);
+ // walkLeftLegForward.skirtFrontLeft.setYaw(40);
+ // walkLeftLegForward.skirtFrontLeft.setRoll(40);
+ // walkLeftLegForward.rightLeg.top.setYaw(5);
+ walkLeftLegForward.leftLeg.top.setPitch(35);
+ walkLeftLegForward.leftLeg.knee.setPitch(-30);
+ walkLeftLegForward.leftLeg.foot.setPitch(25);
+ walkLeftLegForward.leftLeg.top.setYaw(-10);
+ walkLeftLegForward.leftLeg.knee.setYaw(-10);
+ walkLeftLegForward.rightLeg.top.setYaw(-10);
+ walkLeftLegForward.rightLeg.knee.setYaw(-10);
+ walkLeftLegForward.rightLeg.top.setPitch(-10);
+ walkLeftLegForward.rightLeg.knee.setPitch(-15);
+ walkLeftLegForward.rightLeg.foot.setPitch(8);
+ /*walkLeftLegForward.leftLeg.top.setPitch(59);
+ walkLeftLegForward.leftLeg.top.setYaw(-9);
+ walkLeftLegForward.leftLeg.top.setRoll(10);
+ walkLeftLegForward.leftLeg.knee.setPitch(-100);
+ walkLeftLegForward.leftLeg.knee.setYaw(-9);*/
+ walkRightLegForward.leftLeg.copyOrientation(walkLeftLegForward.rightLeg);
+ walkRightLegForward.rightLeg.copyOrientation(walkLeftLegForward.leftLeg);
+ walkRightLegForward.rightLeg.top.setYaw(10);
+ walkRightLegForward.rightLeg.knee.setYaw(10);
+ walkRightLegForward.leftLeg.top.setYaw(10);
+ walkRightLegForward.leftLeg.knee.setYaw(10);
+
+ walkLeftLegForward.waist.setYaw(18);
+ walkRightLegForward.waist.setYaw(-18);
+ walkLeftLegForward.shoulders.setYaw(-10);
+ walkLeftLegForward.shoulders.setRoll(-4);
+ walkRightLegForward.shoulders.setYaw(10);
+ walkRightLegForward.shoulders.setRoll(4);
+ // ARMS
+ walkLeftLegForward.rightArm.top.setPitch(15);
+ walkLeftLegForward.rightArm.top.setRoll(-7);
+ walkLeftLegForward.rightArm.elbow.setYaw(-90);
+ walkLeftLegForward.rightArm.wrist.setYaw(0);
+ walkLeftLegForward.rightArm.wrist.setPitch(0);
+ walkLeftLegForward.rightArm.wrist.setRoll(50);
+ walkLeftLegForward.leftArm.wrist.setRoll(30);
+ walkLeftLegForward.leftArm.top.setPitch(-14);
+ walkLeftLegForward.leftArm.top.setYaw(-2);
+ walkLeftLegForward.leftArm.top.setRoll(17);
+ // walkRightLegForward.leftArm.elbow.setRoll(90);
+ walkRightLegForward.leftArm.top.setPitch(15);
+ walkRightLegForward.leftArm.top.setRoll(7);
+ walkRightLegForward.leftArm.elbow.setYaw(90);
+ walkRightLegForward.leftArm.wrist.setYaw(0);
+ walkRightLegForward.leftArm.wrist.setPitch(0);
+ walkRightLegForward.leftArm.wrist.setRoll(-50);
+ walkRightLegForward.rightArm.wrist.setRoll(-30);
+ walkRightLegForward.rightArm.top.setPitch(-14);
+ walkRightLegForward.rightArm.top.setYaw(2);
+ walkRightLegForward.rightArm.top.setRoll(-17);
+
+ standLeftLegApart.leftLeg.top.setRoll(-10);
+ standLeftLegApart.leftLeg.foot.setYaw(-10);
+ standRightLegApart.rightLeg.top.setRoll(10);
+ standRightLegApart.rightLeg.foot.setYaw(10);
+ }
+
+ private boolean areLegsApart = false;
+ private boolean areLegsTogether = true;
+ private boolean isLeftLegAhead = false;
+ private boolean isLegReturning = false;
+ private float walkStepTimer = 0;
+ private float walkStepTime = 0.25f;
+ private float standTimer = 0;
+ private float standTime = 3f;
+ private boolean isStandLeftLegApart = true;
+
+ private void standTick() {
+ standTimer += getDelta();
+ if (standTimer >= standTime) {
+ // Switch legs
+ standTimer -= standTime;
+ isStandLeftLegApart = !isStandLeftLegApart;
+ }
+ }
+
+ private void setLegsStanding() {
+ if (isStandLeftLegApart) {
+ finalOrientation.leftLeg.copyOrientation(standLeftLegApart.leftLeg);
+ finalOrientation.rightLeg.copyOrientation(standLeftLegApart.rightLeg);
+ } else {
+ finalOrientation.leftLeg.copyOrientation(standRightLegApart.leftLeg);
+ finalOrientation.rightLeg.copyOrientation(standRightLegApart.rightLeg);
+ }
+ }
+
+ private void walkTick() {
+ walkStepTimer += getDelta();
+ if (walkStepTimer >= walkStepTime) {
+ // Switch step, legs
+ walkStepTimer -= walkStepTime;
+ if (areLegsTogether) {
+ areLegsTogether = false;
+ areLegsApart = true;
+ isLeftLegAhead = !isLeftLegAhead;
+ isLegReturning = false;
+ } else {
+ areLegsTogether = true;
+ areLegsApart = false;
+ isLegReturning = true;
+ }
+ }
+ }
+
+ private void setLegsWalking() {
+ if (isLeftLegAhead) {
+ finalOrientation.leftLeg.copyOrientation(walkLeftLegForward.leftLeg);
+ finalOrientation.rightLeg.copyOrientation(walkLeftLegForward.rightLeg);
+ finalOrientation.waist.copyOrientation(walkLeftLegForward.waist);
+ finalOrientation.shoulders.copyOrientation(walkLeftLegForward.shoulders);
+ finalOrientation.leftArm.copyOrientation(walkLeftLegForward.leftArm);
+ finalOrientation.rightArm.copyOrientation(walkLeftLegForward.rightArm);
+ finalOrientation.skirtFrontLeft.copyOrientation(walkLeftLegForward.skirtFrontLeft);
+ finalOrientation.skirtFrontRight.copyOrientation(walkLeftLegForward.skirtFrontRight);
+ } else {
+ finalOrientation.leftLeg.copyOrientation(walkRightLegForward.leftLeg);
+ finalOrientation.rightLeg.copyOrientation(walkRightLegForward.rightLeg);
+ finalOrientation.waist.copyOrientation(walkRightLegForward.waist);
+ finalOrientation.shoulders.copyOrientation(walkRightLegForward.shoulders);
+ finalOrientation.leftArm.copyOrientation(walkRightLegForward.leftArm);
+ finalOrientation.rightArm.copyOrientation(walkRightLegForward.rightArm);
+ finalOrientation.skirtFrontLeft.copyOrientation(walkRightLegForward.skirtFrontLeft);
+ finalOrientation.skirtFrontRight.copyOrientation(walkRightLegForward.skirtFrontRight);
+ }
+ }
+
+ private Randomizer leftLegRandomizer = new Randomizer(0.5f, 7f);
+ private Randomizer rightLegRandomizer = new Randomizer(0.5f, 7f);
+
+ private void randomize() {
+ rightLegRandomizer.setPaused(!leftLegRandomizer.isPaused());
+ rightLegRandomizer.tick(delta);
+ leftLegRandomizer.tick(delta);
+ leftLegRandomizer.randomize(finalOrientation.leftLeg);
+ rightLegRandomizer.randomize(finalOrientation.rightLeg);
+ }
+
+ private void fixClothOrientation() {
+
+ }
+
+ public void tick() {
+ if (!demoMode) {
+ finalOrientation.reset();
+ }
+ if (!demoMode) {
+ // deltaOrientation.reset();
+ if (isJumping()) {
+ // air motion
+ while (!areLegsApart) {
+ walkTick();
+ setLegsWalking();
+ }
+ } else {
+ // on-ground motion
+ if (isWalking()) {
+ walkTick();
+ if (isCrawling()) {
+
+ } else if (isCrouching()) {
+
+ } else {
+ // standing
+ setLegsWalking();
+ }
+ } else {
+ // make legs together, switch forward leg
+ while (!areLegsTogether) {
+ walkTick();
+ standTick();
+ setLegsWalking();
+ setLegsStanding();
+ }
+ }
+ }
+ randomize();
+ // System.err.println("[leg] " +
+ // finalOrientation.leftLeg.top.getPitch());
+ fixClothOrientation();
+ deltaOrientation.leftArm.top.setRollCorrection(-50f);
+ deltaOrientation.rightArm.top.setRollCorrection(-deltaOrientation.leftArm.top.getRollCorrection());
+ deltaOrientation.setSpeed(4f);
+ deltaOrientation.skirtFrontLeft.setSpeed(1f);
+ deltaOrientation.skirtFrontRight.setSpeed(1f);
+ if (isLeftLegAhead && !isLegReturning) {
+ deltaOrientation.skirtFrontLeft.setSpeed(4f);
+ }
+ if (!isLeftLegAhead && !isLegReturning) {
+ deltaOrientation.skirtFrontRight.setSpeed(4f);
+ }
+ }else{
+ deltaOrientation.setSpeed(4f);
+ }
+ deltaOrientation.setDelta(currentOrientation, finalOrientation, getDelta());
+ // deltaOrientation.copyOrientation(finalOrientation);
+ currentOrientation.copyOrientation(deltaOrientation);
+ }
+
+ private boolean demoMode = false;
+
+ public void setPause(boolean boneMode) {
+ demoMode = boneMode;
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/modelAnimator/Randomizer.java b/src/ru/olamedia/olacraft/modelAnimator/Randomizer.java
new file mode 100644
index 0000000..1e66c87
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/Randomizer.java
@@ -0,0 +1,92 @@
+package ru.olamedia.olacraft.modelAnimator;
+
+import java.util.Random;
+
+public class Randomizer {
+
+ public Randomizer(float minTimeout, float maxTimeout) {
+ super();
+ this.minTimeout = minTimeout;
+ this.maxTimeout = maxTimeout;
+ }
+
+ private float minTimeout = 1f;
+ private float maxTimeout = 1f;
+ private long seed;
+ private long prevSeed = 0;
+ private float seedTimeout = 0;
+ private float seedTime = 0;
+ private float delta;
+ private boolean isPaused = false;
+ private boolean isForcePaused = false;
+
+ /**
+ * @return the isPaused
+ */
+ public boolean isPaused() {
+ return isPaused;
+ }
+
+ /**
+ * @param isPaused
+ * the isPaused to set
+ */
+ public void setPaused(boolean isPaused) {
+ this.isForcePaused = isPaused;
+ }
+
+ private Random rand = new Random();
+ private Random prev = new Random();
+
+ public void tick(float delta) {
+ if (!isForcePaused) {
+ seedTimeout -= delta;
+ }
+ if (seedTimeout <= 0) {
+ if (!isPaused) {
+ prevSeed = seed;
+ }
+ Random srand = new Random();
+ seed = srand.nextLong();
+ seedTime = seedTimeout = minTimeout + srand.nextFloat() * (maxTimeout - minTimeout);
+ }
+ prev.setSeed(prevSeed);
+ rand.setSeed(seed);
+ prev.nextBoolean();
+ isPaused = rand.nextBoolean();
+ if (isPaused) {
+ this.delta = 0;
+ } else {
+ this.delta = (seedTime - seedTimeout) / seedTime;
+ }
+ }
+
+ public float getMinTimeout() {
+ return minTimeout;
+ }
+
+ public void setMinTimeout(float minTimeout) {
+ this.minTimeout = minTimeout;
+ }
+
+ public float getMaxTimeout() {
+ return maxTimeout;
+ }
+
+ public void setMaxTimeout(float maxTimeout) {
+ this.maxTimeout = maxTimeout;
+ }
+
+ public void randomize(Skeleton skel) {
+ skel.randomize(rand, prev, delta);
+ }
+
+ public void randomize(Leg leg) {
+ leg.randomize(rand, prev, delta);
+ }
+
+ public void randomize(ISkeletonNode b) {
+ b.randomize(rand, prev, delta);
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/modelAnimator/Skeleton.java b/src/ru/olamedia/olacraft/modelAnimator/Skeleton.java
new file mode 100644
index 0000000..5cae422
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/Skeleton.java
@@ -0,0 +1,47 @@
+package ru.olamedia.olacraft.modelAnimator;
+
+public class Skeleton extends BoneSet {
+
+ public Bone neck; // 首 - шея
+ public Bone shoulders; // 上半身 - верхняя часть тела
+ public Bone waist; // 下半身 - нижняя часть корпуса
+ public Bone skirtFrontLeft;
+ public Bone skirtFrontRight;
+
+ public Arm leftArm;
+ public Arm rightArm;
+
+ public Leg leftLeg;
+ public Leg rightLeg;
+
+ public Skeleton() {
+ super(9);
+ neck = new Bone();
+ neck.setName("Neck");
+ waist = new Bone();
+ waist.setName("Waist");
+ shoulders = new Bone();
+ shoulders.setName("Shoulders");
+ skirtFrontLeft = new Bone();
+ skirtFrontLeft.setName("Skirt Front Left");
+ skirtFrontRight = new Bone();
+ skirtFrontRight.setName("Skirt Front Right");
+ leftArm = new Arm();
+ rightArm = new Arm();
+ leftLeg = new Leg();
+ rightLeg = new Leg();
+ leftArm.setNamePrefix("Left arm ");
+ rightArm.setNamePrefix("Right arm ");
+ leftLeg.setNamePrefix("Left leg ");
+ rightLeg.setNamePrefix("Right leg ");
+ setChild(0, neck);
+ setChild(1, waist);
+ setChild(2, shoulders);
+ setChild(3, skirtFrontLeft);
+ setChild(4, skirtFrontRight);
+ setChild(5, leftArm);
+ setChild(6, rightArm);
+ setChild(7, leftLeg);
+ setChild(8, rightLeg);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/modelAnimator/package-info.java b/src/ru/olamedia/olacraft/modelAnimator/package-info.java
new file mode 100644
index 0000000..7bc19b6
--- /dev/null
+++ b/src/ru/olamedia/olacraft/modelAnimator/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.modelAnimator; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/network/GameClient.java b/src/ru/olamedia/olacraft/network/GameClient.java
index f74340a..ee9ce32 100644
--- a/src/ru/olamedia/olacraft/network/GameClient.java
+++ b/src/ru/olamedia/olacraft/network/GameClient.java
@@ -25,6 +25,7 @@ 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;
@@ -63,9 +64,12 @@ public class GameClient extends ConnectionStateListener implements IPacketListen
public GameClient() {
// INIT WORLD
worldProvider = new WorldProvider();
- worldProvider.setChunkDataProvider(new CachedChunkDataProvider(new RemoteChunkDataProvider(this)));
// worldProvider.setChunkDataProvider(new CachedChunkDataProvider(new
- // LocalChunkDataProvider(worldProvider.getInfo().name)));
+ // RemoteChunkDataProvider(this)));
+ // worldProvider.setChunkDataProvider(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 717b40b..13b70c4 100644
--- a/src/ru/olamedia/olacraft/network/GameServer.java
+++ b/src/ru/olamedia/olacraft/network/GameServer.java
@@ -32,6 +32,20 @@ import com.esotericsoftware.kryonet.Server;
public class GameServer {
private WorldProvider worldProvider;
+ /**
+ * @return the worldProvider
+ */
+ public WorldProvider getWorldProvider() {
+ return worldProvider;
+ }
+
+ /**
+ * @param worldProvider the worldProvider to set
+ */
+ public void setWorldProvider(WorldProvider worldProvider) {
+ this.worldProvider = worldProvider;
+ }
+
private ExecutorService threadPool = Executors.newFixedThreadPool(1);
public static Server server = new Server(30 * 1024 * 1024, 1024 * 1024) {
@Override
diff --git a/src/ru/olamedia/olacraft/network/Network.java b/src/ru/olamedia/olacraft/network/Network.java
index 22434f1..2c44850 100644
--- a/src/ru/olamedia/olacraft/network/Network.java
+++ b/src/ru/olamedia/olacraft/network/Network.java
@@ -21,8 +21,11 @@ import ru.olamedia.olacraft.world.data.ChunkLightData;
import ru.olamedia.olacraft.world.data.HeightMap;
import ru.olamedia.olacraft.world.data.RegionData;
import ru.olamedia.olacraft.world.data.SectorData;
+import ru.olamedia.olacraft.world.drop.DroppedEntity;
import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.location.Location3f;
+import ru.olamedia.olacraft.world.location.Location3i;
import ru.olamedia.olacraft.world.location.RegionLocation;
import ru.olamedia.olacraft.world.location.SectorLocation;
@@ -53,10 +56,13 @@ public class Network {
kryo.register(HeightMap.class);
kryo.register(WorldInfo.class);
kryo.register(WorldInfoPacket.class);
+ kryo.register(Location3f.class);
+ kryo.register(Location3i.class);
kryo.register(BlockLocation.class);
kryo.register(ChunkLocation.class);
kryo.register(SectorLocation.class);
kryo.register(RegionLocation.class);
+ kryo.register(DroppedEntity.class);
kryo.register(ChunkData.class);
kryo.register(ChunkData[].class);
kryo.register(SectorData.class);
diff --git a/src/ru/olamedia/olacraft/network/packet/SectorDataPacket.java b/src/ru/olamedia/olacraft/network/packet/SectorDataPacket.java
new file mode 100644
index 0000000..d592a10
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/SectorDataPacket.java
@@ -0,0 +1,14 @@
+package ru.olamedia.olacraft.network.packet;
+
+import ru.olamedia.olacraft.world.data.SectorData;
+
+public class SectorDataPacket implements IPacket {
+ public SectorDataPacket() {
+ }
+
+ public SectorDataPacket(SectorData data) {
+ this.data = data;
+ }
+
+ public SectorData data;
+}
diff --git a/src/ru/olamedia/olacraft/network/provider/CacheProvider.java b/src/ru/olamedia/olacraft/network/provider/CacheProvider.java
new file mode 100644
index 0000000..267edb0
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/provider/CacheProvider.java
@@ -0,0 +1,29 @@
+package ru.olamedia.olacraft.network.provider;
+
+public class CacheProvider<T> implements IProvider<T> {
+ public CacheProvider(IProvider<T> parent) {
+ this.parent = parent;
+ }
+
+ private T obj;
+ private IProvider<T> parent;
+
+ public boolean has() {
+ return null != obj || parent.has();
+ }
+
+ public void request() {
+ parent.request();
+ }
+
+ public T get() {
+ if (null == obj) {
+ obj = parent.get();
+ }
+ return obj;
+ }
+
+ public void put(T obj) {
+ this.obj = obj;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/provider/IProvider.java b/src/ru/olamedia/olacraft/network/provider/IProvider.java
new file mode 100644
index 0000000..d73b55e
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/provider/IProvider.java
@@ -0,0 +1,11 @@
+package ru.olamedia.olacraft.network.provider;
+
+public interface IProvider<T> {
+ public boolean has();
+
+ public void request();
+
+ public T get();
+
+ public void put(T obj);
+}
diff --git a/src/ru/olamedia/olacraft/network/provider/LocalProvider.java b/src/ru/olamedia/olacraft/network/provider/LocalProvider.java
new file mode 100644
index 0000000..da9b82c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/provider/LocalProvider.java
@@ -0,0 +1,21 @@
+package ru.olamedia.olacraft.network.provider;
+
+public class LocalProvider<T> implements IProvider<T> {
+ private T obj;
+
+ public boolean has() {
+ return true;
+ }
+
+ public void request() {
+
+ }
+
+ public T get() {
+ return obj;
+ }
+
+ public void put(T obj) {
+ this.obj = obj;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/provider/RemoteProvider.java b/src/ru/olamedia/olacraft/network/provider/RemoteProvider.java
new file mode 100644
index 0000000..854293c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/provider/RemoteProvider.java
@@ -0,0 +1,19 @@
+package ru.olamedia.olacraft.network.provider;
+
+abstract public class RemoteProvider<T> implements IProvider<T> {
+ private T obj;
+
+ public boolean has() {
+ return null != obj;
+ }
+
+ abstract public void request();
+
+ public T get() {
+ return obj;
+ }
+
+ public void put(T obj) {
+ this.obj = obj;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/provider/package-info.java b/src/ru/olamedia/olacraft/network/provider/package-info.java
new file mode 100644
index 0000000..f444cac
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/provider/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.network.provider; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/render/jogl/ChunkRangeRenderer.java b/src/ru/olamedia/olacraft/render/jogl/ChunkRangeRenderer.java
new file mode 100644
index 0000000..cd84c99
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/ChunkRangeRenderer.java
@@ -0,0 +1,254 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLContext;
+
+import com.jogamp.opengl.math.geom.AABBox;
+
+import ru.olamedia.geom.ImmModeMesh;
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.world.blockRenderer.ChunkRenderer;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.blockTypes.GrassBlockType;
+import ru.olamedia.olacraft.world.chunk.BlockSlice;
+import ru.olamedia.olacraft.world.chunk.Chunk;
+import ru.olamedia.olacraft.world.chunk.ChunkMeshBulder;
+import ru.olamedia.olacraft.world.chunk.ChunkSlice;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.player.Player;
+
+public class ChunkRangeRenderer {
+
+ private class Point {
+ public int x;
+ public int y;
+ public int z;
+ }
+
+ private ArrayList<ArrayList<Point>> ranges = new ArrayList<ArrayList<Point>>();
+ private ArrayList<ArrayList<Point>> visibleRanges = new ArrayList<ArrayList<Point>>();
+
+ public ImmModeMesh big;
+ private boolean makeBig = false;
+ private boolean isBigInvalid = true;
+
+ private void precalcRange() {
+ for (int d = 0; d < 32; d++) {
+ ranges.add(new ArrayList<ChunkRangeRenderer.Point>());
+ }
+ for (int d = 0; d < 32; d++) {
+ visibleRanges.add(new ArrayList<ChunkRangeRenderer.Point>());
+ }
+ for (int dx = -15; dx <= 15; dx++) {
+ for (int dy = -15; dy <= 15; dy++) {
+ for (int dz = -15; dz <= 15; dz++) {
+ final Point p = new Point();
+ p.x = dx;
+ p.y = dy;
+ p.z = dz;
+ final int d = (int) Math.floor(Math.sqrt(dx * dx + dy * dy + dz * dz));
+ ranges.get(d).add(p);
+ }
+ }
+ }
+ }
+
+ private int vertexTmpCount;
+ private int components = 0;
+
+ public void updateFrustumCulling() {
+ if (null == chunkSlice) {
+ return;
+ }
+ final Player player = Game.client.getScene().getPlayer();
+ cameraBlock = player.getCameraBlockLocation();
+ cameraChunk = cameraBlock.getChunkLocation();
+ final float x = player.camera.getX();
+ final float y = player.camera.getY();
+ final float z = player.camera.getZ();
+ renderDistance = player.settings.renderDistance;
+ vertexTmpCount = 0;
+ for (int d = 0; d < renderDistance / 16; d++) {
+ visibleRanges.get(d).clear();
+ for (Point delta : ranges.get(d)) {
+ renderLoc.x = cameraChunk.x + delta.x;
+ renderLoc.y = cameraChunk.y + delta.y;
+ renderLoc.z = cameraChunk.z + delta.z;
+ final Chunk chunk = chunkSlice.getChunk(renderLoc);
+ center[0] = (float) (chunk.getOffset().x + 8);
+ center[1] = (float) (chunk.getOffset().y + 8);
+ center[2] = (float) (chunk.getOffset().z + 8);
+ if (!Game.instance.camera.frustum.isSphereOutside(center, radius)) {
+ if (chunk.mesh.isValid() && chunk.mesh.isEmpty()) {
+
+ } else {
+ visibleRanges.get(d).add(delta);
+ vertexTmpCount += chunk.mesh.getVertexCount();
+ if ((0 == components) && (null != chunk.mesh.getOpaqueMesh())) {
+ components = chunk.mesh.getOpaqueMesh().getComponents();
+ }
+ }
+ }
+ }
+ }
+ if (null != big) {
+ big.destroy();
+ big = null;
+ }
+ if (makeBig) {
+ big = ImmModeMesh.allocate(vertexTmpCount * components);
+ big.setGLSL(true);
+ big.enableVertex3();
+ big.enableColor4();
+ big.enableTexCoord2();
+ big.setServer(true);
+ big.beginQuads();
+ for (distance = 0; distance <= renderDistance / 16; distance++) {
+ for (Point offset : visibleRanges.get(distance)) {
+ renderLoc.x = cameraChunk.x + offset.x;
+ renderLoc.y = cameraChunk.y + offset.y;
+ renderLoc.z = cameraChunk.z + offset.z;
+ final Chunk chunk = chunkSlice.getChunk(renderLoc);
+ if (chunk.inWorldRange()) {
+ if (chunk.mesh.isValid() && chunk.mesh.isEmpty()) {
+
+ } else {
+ if (null != chunk.mesh.getOpaqueMesh()) {
+ big.put(chunk.mesh.getOpaqueMesh());
+ }
+ if (!chunk.mesh.isValid()) {
+ if (!ChunkMeshBulder.instance.isFull()) {
+ ChunkMeshBulder.instance.add(chunk);
+ }
+ }
+ }
+ }
+ }
+ }
+ big.end();
+ }
+ }
+
+ private boolean useShaders = true;
+
+ public ChunkRangeRenderer(BlockSlice slice) {
+ precalcRange();
+ }
+
+ private BlockType blockType = new GrassBlockType();
+
+ public int testedChunks = 0;
+ public int testedChunksVertices = 0;
+
+ public int visibleTop = 0;
+ public int visibleBottom = 0;
+ public int visibleLeft = 0;
+ public int visibleRight = 0;
+ public int visibleFront = 0;
+ public int visibleBack = 0;
+
+ public int frustumCulledChunks = 0;
+ public int frustumIntersectChunks = 0;
+
+ public int visibleBlocks = 0;
+ public int vertexCount = 0;
+
+ public static int lightTick = 0;
+
+ public static int OPAQUE_PASS = 0;
+ public static int ALPHA_PASS = 1;
+ private AABBox box = new AABBox();
+ private float d;
+ final float radius = (float) Math.sqrt(8 * 8 + 8 * 8 + 8 * 8);
+ final float radius2 = (float) Math.sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5);
+ private float[] center = new float[3];
+
+ public boolean renderChunk(Chunk chunk, boolean skipnew, int pass) {
+ testedChunks++;
+ if (!chunk.inWorldRange()) {
+ return skipnew;
+ }
+ // center[0] = (float) (chunk.getOffset().x + 8);
+ // center[1] = (float) (chunk.getOffset().y + 8);
+ // center[2] = (float) (chunk.getOffset().z + 8);
+ chunk.render(pass);
+
+ vertexCount += chunk.mesh.getVertexCount();
+ if (!chunk.mesh.isValid()) {
+ if (!skipnew) {
+ ChunkMeshBulder.instance.add(chunk);
+ if (ChunkMeshBulder.instance.isFull()) {
+ skipnew = true;
+ }
+ }
+ }
+ return skipnew;
+ }
+
+ Chunk lastInvalidChunk = null;
+ BlockLocation cameraBlock;
+ ChunkLocation cameraChunk;
+ int distance;
+ private int renderDistance;
+ public ChunkSlice chunkSlice;
+
+ private boolean allChunksRendered = false;
+ private boolean allChunksValid = false;
+ private ChunkLocation renderLoc = new ChunkLocation();
+
+ public void render(int pass) {
+ final GL2 gl = GLContext.getCurrentGL().getGL2();
+ visibleBlocks = 0;
+ vertexCount = 0;
+ allChunksRendered = true;
+ allChunksValid = true;
+ renderDistance = Game.client.getScene().getPlayer().settings.renderDistance;
+ if (!ChunkMeshBulder.instance.isAlive() && !ChunkMeshBulder.instance.isInterrupted()) {
+ ChunkMeshBulder.instance.start();
+ }
+ if (null == chunkSlice) {
+ ChunkSlice.rendererInstance = chunkSlice = new ChunkSlice(Game.client.getWorldProvider(), 1, 1, 1);// slice.getChunkSlice();
+ }
+ /*
+ * if (!ChunkMeshGarbageCollector.instance.isAlive() &&
+ * !ChunkMeshGarbageCollector.instance.isInterrupted()) {
+ * ChunkMeshGarbageCollector.instance.start();
+ * }
+ */
+ // chunkSlice = new ChunkSlice(Game.client.getWorldProvider(), 1, 1, 1);
+ testedChunks = 0;
+ visibleTop = 0;
+ visibleBottom = 0;
+ visibleLeft = 0;
+ visibleRight = 0;
+ visibleFront = 0;
+ visibleBack = 0;
+ frustumCulledChunks = 0;
+
+ cameraBlock = Game.client.getScene().getPlayer().getCameraBlockLocation();
+ cameraChunk = cameraBlock.getChunkLocation();
+
+ boolean skipnew = false;
+ if (null != big) {
+ big.draw();
+ } else {
+ for (distance = 0; distance <= renderDistance / 16; distance++) {
+ if (distance > 0) {
+ for (Point offset : visibleRanges.get(distance)) {
+ renderLoc.x = cameraChunk.x + offset.x;
+ renderLoc.y = cameraChunk.y + offset.y;
+ renderLoc.z = cameraChunk.z + offset.z;
+ skipnew = renderChunk(chunkSlice.getChunk(renderLoc), skipnew, pass);
+ }
+ } else {
+ renderLoc.set(cameraChunk);
+ skipnew = renderChunk(chunkSlice.getChunk(renderLoc), skipnew, pass);
+ }
+ }
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java b/src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java
index 12c12e0..60475cf 100644
--- a/src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java
+++ b/src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java
@@ -1,6 +1,9 @@
package ru.olamedia.olacraft.render.jogl;
+import java.util.Random;
+
import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.MouseEvent;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.GLU;
@@ -22,9 +25,14 @@ public class DefaultRenderer implements IRenderer, KeyListener, MouseListener {
MouseJail.attach(this);
}
+ private Random rand = new Random();
+
@Override
public void render(GLAutoDrawable drawable) {
+ Game.instance.fpsTimer.update();
+ // if (rand.nextFloat() > 0.8f) {
Game.client.getScene().tick();
+ // }
Game.client.getScene().render(drawable);
}
@@ -48,14 +56,6 @@ public class DefaultRenderer implements IRenderer, KeyListener, MouseListener {
if (name == "toggleFrustum") {
Game.instance.camera.isFrustumVisible = !Game.instance.camera.isFrustumVisible;
}
- if (name == "toggleRenderDistance") {
- int renderDistance = Game.client.getScene().getRenderDistance();
- renderDistance *= 2;
- if (renderDistance > 256) {
- renderDistance = 32;
- }
- Game.client.getScene().setRenderDistance(renderDistance);
- }
}
@Override
@@ -64,12 +64,19 @@ public class DefaultRenderer implements IRenderer, KeyListener, MouseListener {
}
@Override
- public void onMouseClick() {
- Game.instance.player.onMouseClick();
+ public void onMouseClick(MouseEvent e) {
+ if (null != Game.instance.player) {
+ Game.instance.player.onMouseClick(e);
+ }
}
@Override
public void init(GLAutoDrawable drawable) {
-
+
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable) {
+ Game.client.getScene().reshape(drawable);
}
}
diff --git a/src/ru/olamedia/olacraft/render/jogl/IRenderer.java b/src/ru/olamedia/olacraft/render/jogl/IRenderer.java
index 1ba581a..492e046 100644
--- a/src/ru/olamedia/olacraft/render/jogl/IRenderer.java
+++ b/src/ru/olamedia/olacraft/render/jogl/IRenderer.java
@@ -5,4 +5,5 @@ import javax.media.opengl.GLAutoDrawable;
public interface IRenderer {
public void render(GLAutoDrawable drawable);
public void init(GLAutoDrawable drawable);
+ public void reshape(GLAutoDrawable drawable);
}
diff --git a/src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java b/src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java
index 46daa4a..d2d103b 100644
--- a/src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java
+++ b/src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java
@@ -51,8 +51,8 @@ public class InventoryRenderer {
BlockStack stack = inventory.binded[i];
int sx = x + padding + stackSize * i + spacing * i;
int sy = y + padding;
- if (null != stack && !(stack.block.getType() instanceof EmptyBlockType)) {
- Texture tex = TextureManager.get(stack.block.getType().getStackTextureFile());
+ if (null != stack && !(stack.type instanceof EmptyBlockType)) {
+ Texture tex = TextureManager.get(stack.type.getStackTextureFile());
if (null != tex) {
tex.bind(gl);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
diff --git a/src/ru/olamedia/olacraft/render/jogl/joglViewport.java b/src/ru/olamedia/olacraft/render/jogl/joglViewport.java
index ef59352..3a62835 100644
--- a/src/ru/olamedia/olacraft/render/jogl/joglViewport.java
+++ b/src/ru/olamedia/olacraft/render/jogl/joglViewport.java
@@ -8,19 +8,41 @@ import com.jogamp.opengl.util.awt.TextRenderer;
public class joglViewport {
private GLAutoDrawable drawable;
- private TextRenderer sans11;
+ private TextRenderer sans11Black;
+ private TextRenderer sans11White;
+
+ // private TextRenderer sans12;
public joglViewport(GLAutoDrawable drawable) {
this.drawable = drawable;
- sans11 = new TextRenderer(new Font("SansSerif", Font.PLAIN, 11));
+ //sans11Black = new TextRenderer(new Font("SansSerif", Font.PLAIN, 11));
+ //sans11Black.setColor(0, 0, 0, 1f);
+ sans11White = new TextRenderer(new Font("SansSerif", Font.PLAIN, 11));
+ sans11White.setColor(0, 0, 0, 0.9f);
+ // sans12 = new TextRenderer(new Font("SansSerif", Font.PLAIN, 11));
+ }
+
+ public void beginRendering() {
+ sans11White.beginRendering(drawable.getWidth(), drawable.getHeight());
+ //sans11Black.beginRendering(drawable.getWidth(), drawable.getHeight());
+ }
+
+ public void endRendering() {
+ sans11White.flush();
+ sans11White.endRendering();
+ //sans11Black.endRendering();
}
public void drawText(String text, int x, int y) {
- sans11.setColor(0, 0, 0, 0.7f);
- sans11.beginRendering(drawable.getWidth(), drawable.getHeight());
- sans11.draw(text, x - 1, y - 1);
- // sans11.setColor(1, 1, 1, 0.7f);
- // sans11.draw(text, x, y);
- sans11.endRendering();
+ // sans12.beginRendering(drawable.getWidth(), drawable.getHeight());
+ // sans12.setColor(1, 1, 1, 0.9f);
+ // sans12.draw(text, x, y);
+ // sans12.endRendering();
+ //sans11White.draw(text, x - 1, y);
+ //sans11White.draw(text, x + 1, y);
+ //sans11White.draw(text, x, y - 1);
+ //sans11White.draw(text, x, y + 1);
+ sans11White.draw(text, x, y);
+
}
}
diff --git a/src/ru/olamedia/olacraft/scene/GameScene.java b/src/ru/olamedia/olacraft/scene/GameScene.java
index e5655c9..c0a3f86 100644
--- a/src/ru/olamedia/olacraft/scene/GameScene.java
+++ b/src/ru/olamedia/olacraft/scene/GameScene.java
@@ -3,53 +3,83 @@ package ru.olamedia.olacraft.scene;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.util.HashMap;
+import java.util.Random;
import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLContext;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import org.ode4j.ode.DBody;
-import ru.olamedia.Options;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.opengl.util.PMVMatrix;
+
+import ru.olamedia.game.GameFrame;
+import ru.olamedia.game.GameLogicThread;
import ru.olamedia.game.GameTime;
+import ru.olamedia.geom.ImmModeMesh;
+import ru.olamedia.input.KeyListener;
+import ru.olamedia.input.Keyboard;
import ru.olamedia.liveEntity.LiveEntity;
import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.modelAnimator.Bone;
import ru.olamedia.olacraft.physics.GamePhysicsWorld;
-import ru.olamedia.olacraft.render.jogl.ChunkRenderer;
+import ru.olamedia.olacraft.render.jogl.ChunkRangeRenderer;
import ru.olamedia.olacraft.render.jogl.InventoryRenderer;
import ru.olamedia.olacraft.render.jogl.joglViewport;
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.blockRenderer.ChunkRenderer;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
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.location.BlockLocation;
+import ru.olamedia.olacraft.world.chunk.ChunkUnavailableException;
import ru.olamedia.olacraft.world.provider.WorldProvider;
import ru.olamedia.player.Player;
+import ru.olamedia.texture.TextureManager;
-public class GameScene {
-
+public class GameScene implements KeyListener {
+ private boolean isHUDEnabled = false;
+ private boolean thirdPersonMode = true;
+ public boolean boneMode = false;
+ private boolean renderFrustum = false;
private HashMap<Integer, LiveEntity> liveEntities = new HashMap<Integer, LiveEntity>();
WorldProvider provider;
- private int renderDistance = Options.renderDistance;
- private joglViewport viewport;
+ public joglViewport viewport;
private BulletScene bullets = new BulletScene();
private GamePhysicsWorld physics = new GamePhysicsWorld();
- private boolean isInitialized = false;
+ public boolean isInitialized = false;
BlockSlice viewSlice;
- public GameTime time = new GameTime();
+ public GameTime dayTime = new GameTime();
+
+ private ImmModeMesh crosshair;
+
+ public Bone selectedBone = null;
+ public int bonesCount = 0;
+
+ private BlockType blockType = new GrassBlockType();
public GameScene(WorldProvider provider) {
this.provider = provider;
- setRenderDistance(renderDistance);
+ pickSlice = new BlockSlice(provider, 10, 10, 10);
+ Keyboard.attach(this);
+ Keyboard.setName("3_left", KeyEvent.VK_NUMPAD4);
+ Keyboard.setName("3_right", KeyEvent.VK_NUMPAD6);
+ Keyboard.setName("3_up", KeyEvent.VK_NUMPAD8);
+ Keyboard.setName("3_down", KeyEvent.VK_NUMPAD2);
+ Keyboard.setName("3_in", KeyEvent.VK_NUMPAD7);
+ Keyboard.setName("3_out", KeyEvent.VK_NUMPAD1);
+ Keyboard.setName("3_mode", KeyEvent.VK_F6);
+ Keyboard.setName("hud", KeyEvent.VK_F9);
+ Keyboard.setName("bone_mode", KeyEvent.VK_B);
+ Keyboard.setName("next", KeyEvent.VK_N);
+ Keyboard.setName("rotate_cw", KeyEvent.VK_RIGHT);
+ Keyboard.setName("rotate_ccw", KeyEvent.VK_LEFT);
}
public void addBullet(Bullet b) {
@@ -70,46 +100,51 @@ public class GameScene {
return bullets.getCount();
}
+ public void buildCrosshair() {
+ final int width = GameFrame.getGLWidth();
+ final int height = GameFrame.getGLHeight();
+ final int w = 1;
+ final int l = 5;
+ crosshair = ImmModeMesh.allocate(8);// 2 rectangles
+ // crosshair.setServer(true);
+ // crosshair.setGLSL(true);
+ crosshair.enableColor4();
+ crosshair.enableVertex2();
+ crosshair.setColor(0f, 1f, 1f, 0.7f);
+ crosshair.beginQuads();
+ {
+ crosshair.glRectf(width / 2 - w, height / 2 - l * 2, width / 2 + w, height / 2 + l * 2); // vertical
+ crosshair.glRectf(width / 2 - l * 2, height / 2 - w, width / 2 - 1, height / 2 + w); // horizontal
+ crosshair.glRectf(width / 2 + 1, height / 2 - w, width / 2 + l * 2, height / 2 + w); // horizontal
+ }
+ crosshair.end();
+ }
+
public void init(GLAutoDrawable drawable) {
if (isInitialized) {
return;
}
- isInitialized = true;
- time.init();
+ final GL2ES2 gl = GLContext.getCurrentGL().getGL2ES2();
+ gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
+ gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);// _MIPMAP_NEAREST
registerTextures();
+ gl.glActiveTexture(GL2.GL_TEXTURE1);
+ gl.glBindTexture(blockType.getTopTexture().getTarget(), blockType.getTopTexture().getTextureObject(gl));
+ gl.glActiveTexture(GL2.GL_TEXTURE0);
+ isInitialized = true;
+ dayTime.init();
viewport = new joglViewport(drawable);
+ buildCrosshair();
+ GameLogicThread.instance.start();
}
private void registerTextures() {
- AbstractBlockType t;
- t = new GrassBlockType();
- t.register(provider);
- t = new StoneBlockType();
- t.register(provider);
- t = new DirtBlockType();
- t.register(provider);
- t = new GravelBlockType();
- t.register(provider);
- }
-
- /**
- * @return the renderDistance
- */
- public int getRenderDistance() {
- return renderDistance;
- }
-
- /**
- * @param renderDistance
- * the renderDistance to set
- */
- public void setRenderDistance(int renderDistance) {
- this.renderDistance = renderDistance;
- viewSlice = new BlockSlice(provider, renderDistance, renderDistance, renderDistance);
- blockRenderer = new ChunkRenderer(viewSlice);
+ provider.registerTextures();
+ TextureManager.writeSprite("sprite.png");
+ TextureManager.finishSprite();
}
- public ChunkRenderer blockRenderer = new ChunkRenderer(viewSlice);
+ public ChunkRangeRenderer blockRenderer = new ChunkRangeRenderer(viewSlice);
GLU glu = new GLU();
public void registerLiveEntity(LiveEntity entity) {
@@ -120,11 +155,12 @@ public class GameScene {
private InventoryRenderer inventoryRenderer;
- private Player player;
+ public Player player;
public void registerPlayer(LiveEntity player) {
inventoryRenderer = new InventoryRenderer(player.getInventory());
this.player = (Player) player;
+ // this.player.getInventory().buildMeshes();
}
public LiveEntity getLiveEntity(int connectionId) {
@@ -139,221 +175,434 @@ public class GameScene {
}
public Block nearestBlock = null;
+ public Block nearestPutBlock = null;
+ public BlockSlice pickSlice;
+ private Random rand = new Random();
public void tick() {
- time.tick();
- Game.instance.tick();
- float aspect = Game.Display.getAspect();
- Game.instance.camera.setAspect(aspect);
- // bullets.update(Game.instance.getDelta());
- physics.getWorld().step(Game.instance.getDelta());
- BlockSlice pickSlice = new BlockSlice(provider, 10, 10, 10);
- 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);
- }
+ if (rand.nextFloat() > 0.95f) {
+ final GL2ES2 gl = GLContext.getCurrentGL().getGL2ES2();
+ // ChunkRenderer.getShader().enable();
+ dayTime.sunColor.put(0, 1);
+ dayTime.sunColor.put(1, 1);
+ dayTime.sunColor.put(2, 1);
+ // ChunkRenderer.getShader().getState().uniform(gl,
+ // ChunkRenderer.sunColor);
+ // ChunkRenderer.getShader().disable();
+ final float[] clearColor = dayTime.getClearColor();
+ // gl.glClearColor(clearColor[0], clearColor[1], clearColor[2], 1);
+ gl.glClearColor(0.8f, 0.8f, 0.8f, 1);
}
}
+ float dLook = 2;
+ float dUp = 0;
+ float dRight = 0;
+
public void render(GLAutoDrawable drawable) {
if (null == player || !Game.instance.isRunning()) {
// not running, just clear screen
- GL2 gl = drawable.getGL().getGL2();
+ final GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glClearColor(49f / 255f, 49f / 255f, 49f / 255f, 1);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
return;
}
init(drawable);
- float[] clearColor = time.getClearColor();
- GL2 gl = drawable.getGL().getGL2();
+ // final float[] clearColor = time.getClearColor();
+ final GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
- gl.glClearColor(clearColor[0], clearColor[1], clearColor[2], 1);
+ // gl.glClear(GL2.GL_DEPTH_BUFFER_BIT);
+ // gl.glClearColor(clearColor[0], clearColor[1], clearColor[2], 1);
// gl.glClearColor(49f / 255f, 119f / 255f, 243f / 255f, 1);
- // GOING 3D
- gl.glPushMatrix();
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);
+ // GOING 3D
+ if (player.camera.isDirty()) {
+ player.camera.offset.x = 0;
+ player.camera.offset.y = 0;
+ player.camera.offset.z = 0;
+ player.camera.pack();
+ if (thirdPersonMode) {
+ player.camera.offset.x = player.camera.getLook().x * dLook + player.camera.getUp().x * dUp
+ + player.camera.getRight().x * dRight;
+ player.camera.offset.y = player.camera.getLook().y * dLook + player.camera.getUp().y * dUp
+ + player.camera.getRight().y * dRight;
+ player.camera.offset.z = player.camera.getLook().z * dLook + player.camera.getUp().z * dUp
+ + player.camera.getRight().z * dRight;
+ player.camera.pack();
+ player.camera.updateFrustum();
+ blockRenderer.updateFrustumCulling();
+ }
+ ChunkRenderer.getShader().enable();
+ ChunkRenderer.getShader().getState().uniform(gl, ChunkRenderer.pmvMatrixUniform);
+ ChunkRenderer.getShader().disable();
+ }
+ player.camera.setUp();
// 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();
+ // gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+
+ // 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);
+ * 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());
// RENDER BLOCKS
- gl.glPopAttrib();
- gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
- gl.glColor4f(0f, 1f, 0, 1);
- gl.glEnable(GL2.GL_DEPTH_TEST);
+ // gl.glColor4f(0f, 1f, 0, 1);
gl.glShadeModel(GL2.GL_FLAT);
- gl.glCullFace(GL2.GL_BACK);
+ gl.glEnable(GL2.GL_DEPTH_TEST);
+ gl.glEnable(GL2.GL_CULL_FACE);
+ // gl.glColorMask(false, false, false, false);
+ // gl.glEnable(GL2.GL_TEXTURE_2D);
+ gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
+ gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);// _MIPMAP_NEAREST
+ ChunkRenderer.enableShader();
+ // ChunkRenderer.getShader().getState().uniform(gl,
+ // ChunkRenderer.sunColor);
+ gl.glActiveTexture(GL2.GL_TEXTURE1);
+ // gl.glBindTexture(blockType.getTopTexture().getTarget(),
+ // blockType.getTopTexture().getTextureObject(gl));
+ gl.glDisable(GL2.GL_BLEND);
+ blockRenderer.render(ChunkRangeRenderer.OPAQUE_PASS);
+ gl.glDisable(GL2.GL_BLEND);
+ // gl.glEnable(GL2.GL_BLEND);
+ // gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
+ // gl.glBlendEquationSeparate(GL2.GL_FUNC_ADD, GL2.GL_FUNC_ADD); // copy
+ // blockRenderer.render(ChunkRangeRenderer.ALPHA_PASS);
+ // gl.glDisable(GL2.GL_TEXTURE_2D);
+ gl.glDisable(GL2.GL_CULL_FACE);
+ gl.glDisable(GL2.GL_DEPTH_TEST);
+ gl.glDisable(GL2.GL_BLEND);
+ // gl.glDisable(GL2.GL_ALPHA_TEST);
+ ChunkRenderer.disableShader();
+ gl.glActiveTexture(GL2.GL_TEXTURE0);
+ // gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ // gl.glShadeModel(GL2.GL_FLAT);
+ // gl.glCullFace(GL2.GL_BACK);
// gl.glEnable(GL2.GL_FOG);
// gl.glFogf(GL2.GL_FOG_MODE, GL2.GL_LINEAR);
// gl.glFogf(GL2.GL_FOG_MODE, GL2.GL_EXP);
- // gl.glFogf(GL2.GL_FOG_START, renderDistance / 2 - renderDistance /
- // 10);
- // gl.glFogf(GL2.GL_FOG_END, renderDistance / 2);
+ // gl.glFogf(GL2.GL_FOG_START, player.settings.renderDistance / 2 -
+ // player.settings.renderDistance / 10);
+ // gl.glFogf(GL2.GL_FOG_END, player.settings.renderDistance / 2);
// 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();
- gl.glPopAttrib();
+ // gl.glPopAttrib();
// RENDER ANYTHING ELSE
- gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
- GLUquadric qobj0 = glu.gluNewQuadric();
- glu.gluQuadricDrawStyle(qobj0, GLU.GLU_FILL);
- glu.gluQuadricNormals(qobj0, GLU.GLU_SMOOTH);
- for (LiveEntity entity : liveEntities.values()) {
- gl.glPushMatrix();
- gl.glTranslatef(entity.getX(), entity.getCameraY(), entity.getZ());
- gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
- glu.gluSphere(qobj0, 0.1f, 10, 10);
- gl.glPopMatrix();
- }
- gl.glPopAttrib();
+ /*
+ * gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ * GLUquadric qobj0 = glu.gluNewQuadric();
+ * glu.gluQuadricDrawStyle(qobj0, GLU.GLU_FILL);
+ * glu.gluQuadricNormals(qobj0, GLU.GLU_SMOOTH);
+ * for (LiveEntity entity : liveEntities.values()) {
+ * gl.glPushMatrix();
+ * gl.glTranslatef(entity.getX(), entity.getCameraY(), entity.getZ());
+ * gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
+ * glu.gluSphere(qobj0, 0.03f, 10, 10);
+ * gl.glPopMatrix();
+ * }
+ * gl.glPopAttrib();
+ */
if (nearestBlock != null) {
gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
- nearestBlock.renderFrame();
+ if (nearestBlock != null) {
+ nearestBlock.renderFrame();
+ }
gl.glPopAttrib();
}
+ if (thirdPersonMode && renderFrustum) {
+ player.camera.renderFrustum();
+ }
// bullets.render(drawable);
- gl.glPopMatrix();
+ // gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ // player.render();
+ // gl.glPopAttrib();
+ // gl.glPopMatrix();
// testObject.render();
-
+ gl.glPopAttrib();
// GOIND 2D
- gl.glMatrixMode(GL2.GL_PROJECTION);
- gl.glLoadIdentity();
- int width = Game.Display.getWidth();
- int height = Game.Display.getHeight();
- glu.gluOrtho2D(0, width, height, 0);
- gl.glMatrixMode(GL2.GL_MODELVIEW);
- gl.glPushMatrix();
- // renderHUD();
- // MAP++
- gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
- gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
- int msz = 100;
- gl.glColor4f(0.3f, 0.3f, 0.3f, 0.7f);
- gl.glRectf(width - msz - 12, 8, width - 8, msz + 12);
- gl.glColor4f(0.9f, 0.9f, 0.9f, 1);
- gl.glRectf(width - msz - 10, 10, width - 10, msz + 10);
- gl.glColor4f(0.0f, 0.0f, 0.0f, 0.9f);
- /*
- * for (int mx = 0; mx < msz; mx++) {
- * for (int mz = 0; mz < msz; mz++) {
- * float h = (float) viewSlice
- * .getHighest((int) (mx - msz / 2 + player.getX()), (int) (mz - msz / 2
- * + player.getZ()));
- * gl.glColor4f(h / 128, h / 128, h / 128, 1f);
- * gl.glRectf(width - msz - 10 + mx, 10 + mz, width - msz - 10 + mx + 1,
- * 10 + mz + 1);
- * }
- * }
- */
- // MAP--
- // crosshair
- gl.glColor4f(1f, 1f, 1f, 0.7f);
- gl.glRectf(width / 2 - 1, height / 2 - 10, width / 2 + 1, height / 2 + 10); // vertical
- gl.glRectf(width / 2 - 10, height / 2 - 1, width / 2 + 10, height / 2 + 1); // horizontal
-
- // inventoryprivate PMVMatrix matrix;
- if (null != inventoryRenderer) {
- // inventoryRenderer.render(drawable);
- }
+ if (isHUDEnabled) {
+ gl.glMatrixMode(GL2.GL_PROJECTION);
+ gl.glLoadIdentity();
+ final int width = GameFrame.getGLWidth();
+ final int height = GameFrame.getGLHeight();
+ glu.gluOrtho2D(0, width, height, 0);
+ gl.glMatrixMode(GL2.GL_MODELVIEW);
+ gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ // gl.glPushMatrix();
+ // renderHUD();
+
+ // MAP++
+ // gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ // gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
+ // int msz = 100;
+ // gl.glColor4f(0.3f, 0.3f, 0.3f, 0.7f);
+ // gl.glRectf(width - msz - 12, 8, width - 8, msz + 12);
+ // gl.glColor4f(0.9f, 0.9f, 0.9f, 1);
+ // gl.glRectf(width - msz - 10, 10, width - 10, msz + 10);
+ // gl.glColor4f(0.0f, 0.0f, 0.0f, 0.9f);
+
+ // MAP--
+ // crosshair
+ if (null != crosshair) {
+ gl.glDisable(GL2.GL_TEXTURE_2D);
+ gl.glDisable(GL2.GL_CULL_FACE);
+ gl.glDisable(GL2.GL_DEPTH_TEST);
+ gl.glDisable(GL2.GL_BLEND);
+ gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);
+ gl.glEnable(GL2.GL_BLEND);
+ gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE);
+ gl.glBlendEquation(GL2.GL_FUNC_SUBTRACT);
+ // ChunkRenderer.enableShader();
+ crosshair.draw();
+ // ChunkRenderer.disableShader();
+ gl.glBlendEquation(GL2.GL_FUNC_ADD);
+ gl.glDisable(GL2.GL_BLEND);
+ } else {
+ System.err.println("no crosshair");
+ }
+ // gl.glColor4f(1f, 1f, 1f, 0.7f);
+ // gl.glRectf(width / 2 - 1, height / 2 - 10, width / 2 + 1, height
+ // / 2
+ // + 10); // vertical
+ // gl.glRectf(width / 2 - 10, height / 2 - 1, width / 2 + 10, height
+ // / 2
+ // + 1); // horizontal
+ // TODO ENABLE
+ // inventory
+ // player.getInventory().renderGUI();
+ // inventoryprivate PMVMatrix matrix;
+ // if (null != inventoryRenderer) {
+ // // inventoryRenderer.render(drawable);
+ // }
+ gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ viewport.beginRendering();
+ gl.glEnable(GL2.GL_BLEND);
+ // gl.glBlendColor(0, 0, 0, 1);
+ gl.glBlendFunc(GL2.GL_ZERO, GL2.GL_ONE_MINUS_SRC_ALPHA);
+ //gl.glBlendFuncSeparate(GL2.GL_DST_COLOR, GL2.GL_ONE_MINUS_SRC_ALPHA, GL2.GL_SRC_ALPHA,
+ // GL2.GL_ONE_MINUS_DST_COLOR);
+ gl.glBlendEquation(GL2.GL_FUNC_ADD);
+ viewport.drawText("⌀ " + player.settings.renderDistance, 10, height - 20);
+ viewport.drawText("avg fps: " + (int) Game.fpsTimer.getAvgFps(), 10, height - 35);
+ viewport.drawText("fps: " + (int) Game.fpsTimer.getFps(), 10, height - 50);
+ final MemoryUsage heap = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
+ final MemoryUsage nonheap = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
+ viewport.drawText("heap: " + (heap.getUsed() / (1024 * 1024)) + "/" + (heap.getMax() / (1024 * 1024)), 10,
+ height - 65);
+ viewport.drawText("non heap: " + (nonheap.getUsed() / (1024 * 1024)) + "/"
+ + (nonheap.getMax() / (1024 * 1024)), 10, height - 80);
+ // viewport.drawText("b: " + blockRenderer.visibleBlocks, 10, height
+ // -
+ // 80);
+ if (null != blockRenderer.big) {
+ viewport.drawText("v: " + blockRenderer.big.getVertexCount(), 10, height - 95);
+ }
+ viewport.drawText("c: " + blockRenderer.testedChunks, 10, height - 105);
+ //
+ viewport.drawText("y: " + Game.instance.player.getY(), width - 100 - 10, height - 100 - 20);
+ viewport.drawText("y: " + Game.instance.player.getCameraY() + " (cam)", width - 100 - 10, height - 100 - 30);
+ viewport.drawText("x: " + Game.instance.player.getX(), width - 100 - 10, height - 100 - 40);
+ viewport.drawText("z: " + Game.instance.player.getZ(), width - 100 - 10, height - 100 - 50);
+ if (boneMode) {
+ viewport.drawText("bones count: " + bonesCount, width - 100 - 10, height - 100 - 80);
+ }
+ if (boneMode && null != selectedBone) {
+ viewport.drawText("bone: " + selectedBone.getName(), width - 100 - 10, height - 100 - 90);
+ viewport.drawText("pitch: " + selectedBone.getPitch(), width - 100 - 10, height - 100 - 100);
+ viewport.drawText("__yaw: " + selectedBone.getYaw(), width - 100 - 10, height - 100 - 110);
+ viewport.drawText("_roll: " + selectedBone.getRoll(), width - 100 - 10, height - 100 - 120);
+ }
+ viewport.endRendering();
+ gl.glDisable(GL2.GL_BLEND);
+ gl.glBlendEquation(GL2.GL_FUNC_ADD);
+ gl.glBlendColor(0, 0, 0, 0);
+ gl.glPopAttrib();
- 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 - 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);
+ // 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();
+ disposeMeshes();
+ gl.glPopAttrib();
+ }
+ }
- gl.glPopAttrib();
- gl.glPopMatrix();
- // gl.glFlush();
+ public void disposeMeshes() {
+ // blockRenderer.chunkSlice.disposeMeshes();
}
public Player getPlayer() {
return player;
}
+
+ public PMVMatrix getPmvMatrix() {
+ return Game.instance.camera.pmvMatrix;
+ }
+
+ public void reshape(GLAutoDrawable drawable) {
+ buildCrosshair();
+ if (null != player) {
+ // player.getInventory().buildMeshes();
+ }
+ }
+
+ @Override
+ public void onKeyPressed(String name, KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_F6) {
+ thirdPersonMode = !thirdPersonMode;
+ }
+ if (e.getKeyCode() == KeyEvent.VK_B) {
+ boneMode = !boneMode;
+ }
+ final boolean thirdPersonControlsEnabled = thirdPersonMode && !boneMode;
+ if (thirdPersonControlsEnabled) {
+ final int shiftSpeed = 10;
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD4) {
+ dRight += -0.1 * shiftSpeed;
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD6) {
+ dRight += 0.1 * shiftSpeed;
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD8) {
+ dUp += 0.1 * shiftSpeed;
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD2) {
+ dUp += -0.1 * shiftSpeed;
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD1) {
+ dLook += 0.1 * shiftSpeed;
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD7) {
+ dLook += -0.1 * shiftSpeed;
+ }
+ }
+ if (boneMode && null != selectedBone) {
+ if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
+ player.rotateCW();
+ }
+ if (e.getKeyCode() == KeyEvent.VK_LEFT) {
+ player.rotateCCW();
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD4) {
+ selectedBone.setRoll(selectedBone.getRoll() + 1);
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD6) {
+ selectedBone.setRoll(selectedBone.getRoll() - 1);
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD8) {
+ selectedBone.setPitch(selectedBone.getPitch() + 1);
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD2) {
+ selectedBone.setPitch(selectedBone.getPitch() - 1);
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD1) {
+ selectedBone.setYaw(selectedBone.getYaw() + 1);
+ }
+ if (e.getKeyCode() == KeyEvent.VK_NUMPAD7) {
+ selectedBone.setYaw(selectedBone.getYaw() - 1);
+ }
+ if (e.getKeyCode() == KeyEvent.VK_N) {
+ player.selectNextBone();
+ }
+ }
+ if (e.getKeyCode() == KeyEvent.VK_F7) {
+ renderFrustum = !renderFrustum;
+ }
+ if (e.getKeyCode() == KeyEvent.VK_F9) {
+ isHUDEnabled = !isHUDEnabled;
+ }
+ if (null != player) {
+ player.camera.setDirty();
+ }
+ }
+
+ @Override
+ public void onKeyReleased(String name, KeyEvent e) {
+
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/biome/Biome.java b/src/ru/olamedia/olacraft/world/biome/Biome.java
new file mode 100644
index 0000000..178e799
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/biome/Biome.java
@@ -0,0 +1,10 @@
+package ru.olamedia.olacraft.world.biome;
+
+public class Biome {
+ public static int ocean = 1;
+ public static int land = 2;
+ public static int island = 3;
+ public static int beach = 4;
+ public static int desert = 5;
+ public static int snow = 5;
+}
diff --git a/src/ru/olamedia/olacraft/world/biome/package-info.java b/src/ru/olamedia/olacraft/world/biome/package-info.java
new file mode 100644
index 0000000..b39342c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/biome/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.biome; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/block/Block.java b/src/ru/olamedia/olacraft/world/block/Block.java
index 50752f0..1e7175f 100644
--- a/src/ru/olamedia/olacraft/world/block/Block.java
+++ b/src/ru/olamedia/olacraft/world/block/Block.java
@@ -1,7 +1,6 @@
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;
@@ -22,35 +21,16 @@ public class Block {
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();
- }
- }
+ cdata.voidLightPrecomputed = false;
+ invalidateChunks();
+ }
+
+ public void insertToWorld() {
+ ChunkData cdata = provider.getChunk(location.getChunkLocation());
+ cdata.setEmpty(location, false);
+ cdata.types[ChunkData.ClampID(location.x, location.y, location.z)] = (byte) type.getId(provider);
+ cdata.voidLightPrecomputed = false;
+ invalidateChunks();
}
/**
@@ -63,7 +43,7 @@ public class Block {
location.z = 0;
}
- public void putIntoWorld(WorldProvider worldProvider, int x, int y, int z) {
+ public void setLocation(WorldProvider worldProvider, int x, int y, int z) {
this.provider = worldProvider;
location.x = x;
location.y = y;
@@ -71,7 +51,11 @@ public class Block {
}
public Block(WorldProvider worldProvider, int x, int y, int z) {
- putIntoWorld(worldProvider, x, y, z);
+ setLocation(worldProvider, x, y, z);
+ }
+
+ public Block(WorldProvider worldProvider, BlockLocation location) {
+ setLocation(worldProvider, location.x, location.y, location.z);
}
/**
@@ -152,8 +136,14 @@ public class Block {
return type;
}
+ public int nearestX = 0;
+ public int nearestY = 0;
+ public int nearestZ = 0;
+
public float getDistance(MatrixCamera cam) {
- String nearest = "";
+ nearestX = 0;
+ nearestY = 0;
+ nearestZ = 0;
float topDistance = cam.intersectsRectangle(getTopLeftBack(), getTopLeftFront(), getTopRightFront(),
getTopRightBack());
float bottomDistance = cam.intersectsRectangle(getBottomLeftBack(), getBottomLeftFront(),
@@ -171,22 +161,17 @@ public class Block {
float frontBack = Math.min(frontDistance, backDistance);
float distance = Math.min(Math.min(topBottom, leftRight), frontBack);
if (distance == bottomDistance) {
- nearest = "BOTTOM";
- }
- if (distance == topDistance) {
- nearest = "TOP";
- }
- if (distance == leftDistance) {
- nearest = "LEFT";
- }
- if (distance == rightDistance) {
- nearest = "RIGHT";
- }
- if (distance == frontDistance) {
- nearest = "FRONT";
- }
- if (distance == backDistance) {
- nearest = "BACK";
+ nearestY = -1;
+ } else if (distance == topDistance) {
+ nearestY = 1;
+ } else if (distance == leftDistance) {
+ nearestX = -1;
+ } else if (distance == rightDistance) {
+ nearestX = 1;
+ } else if (distance == frontDistance) {
+ nearestZ = 1;
+ } else if (distance == backDistance) {
+ nearestZ = -1;
}
return distance;
}
@@ -243,127 +228,176 @@ public class Block {
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);
+ if (nearestY == 1) {
+ // 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);
+ }
+ if (nearestY == -1) {
+ // 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);
+ }
+ if (nearestZ == 1) {
+ // 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);
+ }
+ if (nearestZ == -1) {
+ // 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);
+ }
+ if (nearestX == -1) {
+ // 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);
+ }
+ if (nearestX == 1) {
+ // 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();
}
+
+ public void invalidateChunks() {
+ // TODO Auto-generated method stub
+ 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();
+ }
+ }
+ }
+
+ public boolean canMoveThrough() throws ChunkUnavailableException {
+ return provider.canMoveThrough(location.x, location.y, location.z);
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/block/BlockRegistry.java b/src/ru/olamedia/olacraft/world/block/BlockRegistry.java
index ec9f9c1..a6e8d38 100644
--- a/src/ru/olamedia/olacraft/world/block/BlockRegistry.java
+++ b/src/ru/olamedia/olacraft/world/block/BlockRegistry.java
@@ -2,20 +2,24 @@ package ru.olamedia.olacraft.world.block;
import java.util.HashMap;
-import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
public class BlockRegistry {
private HashMap<Integer, String> names = new HashMap<Integer, String>();
- private HashMap<Integer, BlockType> types = new HashMap<Integer, BlockType>();
+ private HashMap<Integer, Boolean> opaque = new HashMap<Integer, Boolean>();
+ private HashMap<Integer, Boolean> canMoveThrough = new HashMap<Integer, Boolean>();
+ private HashMap<Integer, AbstractBlockType> types = new HashMap<Integer, AbstractBlockType>();
+ private HashMap<String, Integer> ids = new HashMap<String, Integer>();
private int autoincrement = 0;
private BlockRegistry worldRegistry;
public BlockRegistry() {
+
}
- public BlockType getBlockType(int id) {
+ public AbstractBlockType getBlockType(int id) {
return types.get(id);
}
@@ -23,12 +27,19 @@ public class BlockRegistry {
return names.get(id);
}
- public int registerBlockType(BlockType type) {
+ public boolean isOpaque(int id) {
+ return opaque.get(id);
+ }
+
+ public int registerBlockType(AbstractBlockType type) {
autoincrement++;
int id = autoincrement;
- String classId = type.getClass().getName();
- names.put(id, classId);
+ String className = type.getClass().getName();
+ names.put(id, className);
types.put(id, type);
+ opaque.put(id, type.isOpaque());
+ canMoveThrough.put(id, type.canMoveThrough());
+ ids.put(className, id);
return autoincrement;
}
@@ -40,4 +51,12 @@ public class BlockRegistry {
this.worldRegistry = worldRegistry;
}
+ public int getBlockIdByClassName(String className) {
+ return ids.get(className);
+ }
+
+ public boolean canMoveThrough(int id) {
+ return canMoveThrough.get(id);
+ }
+
}
diff --git a/src/ru/olamedia/olacraft/world/blockRenderer/AbstractBlockRenderer.java b/src/ru/olamedia/olacraft/world/blockRenderer/AbstractBlockRenderer.java
new file mode 100644
index 0000000..dfb8e1c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockRenderer/AbstractBlockRenderer.java
@@ -0,0 +1,64 @@
+package ru.olamedia.olacraft.world.blockRenderer;
+
+import java.nio.FloatBuffer;
+
+import ru.olamedia.geom.ImmModeMesh;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.data.ChunkDataNeighbors;
+import ru.olamedia.olacraft.world.location.Location3f;
+import ru.olamedia.olacraft.world.location.Location3i;
+
+public abstract class AbstractBlockRenderer implements IBlockRenderer {
+
+ public boolean renderBottom = true;
+ public boolean renderTop = true;
+ public boolean renderLeft = true;
+ public boolean renderRight = true;
+ public boolean renderFront = true;
+ public boolean renderBack = true;
+ public float scale = 1f;
+ private ChunkDataNeighbors neighbors;
+
+ protected ImmModeMesh mesh = null;
+
+ public void renderAllSides() {
+ renderBottom = true;
+ renderTop = true;
+ renderLeft = true;
+ renderRight = true;
+ renderFront = true;
+ renderBack = true;
+ }
+
+ abstract public void putMesh(ImmModeMesh mesh, BlockType type, FloatBuffer renderLocation, boolean useShader);
+
+ public ImmModeMesh getMesh(BlockType type, FloatBuffer renderLocation, boolean useShader) {
+ return mesh;
+ }
+
+ public ImmModeMesh getMesh(BlockType type, Location3f location, boolean glsl) {
+ return mesh;
+ }
+
+ @Override
+ public void render(BlockType type, Location3f location, boolean glsl) {
+ getMesh(type, location, glsl).draw();
+ }
+
+ @Override
+ public void render(BlockType type, Location3i location, boolean glsl) {
+ getMesh(type, new Location3f(location), glsl).draw();
+ }
+
+ public void setScale(float f) {
+ scale = f;
+ }
+
+ abstract public int getMeshVertexCount(BlockType currentType, FloatBuffer renderLocation,
+ boolean useShader);
+
+ public void setNeighbors(ChunkDataNeighbors neighbors) {
+ this.neighbors = neighbors;
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/blockRenderer/BoxRenderer.java b/src/ru/olamedia/olacraft/world/blockRenderer/BoxRenderer.java
new file mode 100644
index 0000000..8482595
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockRenderer/BoxRenderer.java
@@ -0,0 +1,282 @@
+package ru.olamedia.olacraft.world.blockRenderer;
+
+import java.nio.FloatBuffer;
+
+import javax.vecmath.Point3f;
+
+import ru.olamedia.asset.SpriteRectangle;
+import ru.olamedia.geom.ImmModeMesh;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+
+public class BoxRenderer extends AbstractBlockRenderer {
+
+ public static boolean useTriangles = false;
+
+ public Point3f bottomLeftBack = new Point3f();
+ public Point3f bottomLeftFront = new Point3f();
+ public Point3f bottomRightBack = new Point3f();
+ public Point3f bottomRightFront = new Point3f();
+
+ public Point3f topLeftBack = new Point3f();
+ public Point3f topLeftFront = new Point3f();
+ public Point3f topRightBack = new Point3f();
+ public Point3f topRightFront = new Point3f();
+ public float textureTop = 1;
+ public float textureBottom = 0;
+ public float textureLeft = 0;
+ public float textureRight = 1;
+
+ public void setPoint3f(Point3f p) {
+ mesh.glVertex3f(p.x, p.y, p.z);
+ }
+
+ public void addBottomLeftBackVertex() {
+ setPoint3f(bottomLeftBack);
+ }
+
+ public void addBottomLeftFrontVertex() {
+ setPoint3f(bottomLeftFront);
+ }
+
+ public void addBottomRightBackVertex() {
+ setPoint3f(bottomRightBack);
+ }
+
+ public void addBottomRightFrontVertex() {
+ setPoint3f(bottomRightFront);
+ }
+
+ public void addTopLeftBackVertex() {
+ setPoint3f(topLeftBack);
+ }
+
+ public void addTopLeftFrontVertex() {
+ setPoint3f(topLeftFront);
+ }
+
+ public void addTopRightBackVertex() {
+ setPoint3f(topRightBack);
+ }
+
+ public void addTopRightFrontVertex() {
+ setPoint3f(topRightFront);
+ }
+
+ public void addFrontQuad() {
+ // triangle strip: И
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftFrontVertex(); // top left
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomLeftFrontVertex(); // bottom left
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightFrontVertex(); // bottom right
+
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftFrontVertex(); // top left
+ }
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightFrontVertex(); // bottom right
+ mesh.setUV(textureRight, textureTop);
+ addTopRightFrontVertex(); // top right
+ }
+
+ public void addBackQuad() {
+ // triangle strip: И
+ mesh.setUV(textureLeft, textureTop);
+ addTopRightBackVertex();
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomRightBackVertex();
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureBottom);
+ addBottomLeftBackVertex();
+
+ mesh.setUV(textureLeft, textureTop);
+ addTopRightBackVertex();
+ }
+ mesh.setUV(textureRight, textureBottom);
+ addBottomLeftBackVertex();
+ mesh.setUV(textureRight, textureTop);
+ addTopLeftBackVertex();
+ }
+
+ public void addLeftQuad() {
+ // triangle strip: И
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftBackVertex();
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomLeftBackVertex();
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureBottom);
+ addBottomLeftFrontVertex();
+
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftBackVertex();
+ }
+ mesh.setUV(textureRight, textureBottom);
+ addBottomLeftFrontVertex();
+ mesh.setUV(textureRight, textureTop);
+ addTopLeftFrontVertex();
+ }
+
+ public void addRightQuad() {
+ // triangle strip: И
+ mesh.setUV(textureLeft, textureTop);
+ addTopRightFrontVertex();
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomRightFrontVertex();
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightBackVertex();
+
+ mesh.setUV(textureLeft, textureTop);
+ addTopRightFrontVertex();
+ }
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightBackVertex();
+ mesh.setUV(textureRight, textureTop);
+ addTopRightBackVertex();
+ }
+
+ public void addTopQuad() {
+ // triangle strip: И
+ mesh.setUV(textureLeft, textureBottom);
+ addTopLeftBackVertex();
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftFrontVertex();
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureTop);
+ addTopRightFrontVertex();
+
+ mesh.setUV(textureLeft, textureBottom);
+ addTopLeftBackVertex();
+ }
+ mesh.setUV(textureRight, textureTop);
+ addTopRightFrontVertex();
+ mesh.setUV(textureRight, textureBottom);
+ addTopRightBackVertex();
+ }
+
+ public void addBottomQuad() {
+ // triangle strip: И
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomLeftFrontVertex();
+ mesh.setUV(textureLeft, textureTop);
+ addBottomLeftBackVertex();
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureTop);
+ addBottomRightBackVertex();
+
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomLeftFrontVertex();
+ }
+ mesh.setUV(textureRight, textureTop);
+ addBottomRightBackVertex();
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightFrontVertex();
+ }
+
+ public void setPointOffset(float offset) {
+ bottomLeftBack.x = -offset;
+ bottomLeftBack.y = -offset;
+ bottomLeftBack.z = -offset;
+ //
+ bottomLeftFront.x = -offset;
+ bottomLeftFront.y = -offset;
+ bottomLeftFront.z = offset;
+ //
+ bottomRightBack.x = offset;
+ bottomRightBack.y = -offset;
+ bottomRightBack.z = -offset;
+ //
+ bottomRightFront.x = offset;
+ bottomRightFront.y = -offset;
+ bottomRightFront.z = offset;
+ //
+ topLeftBack.x = -offset;
+ topLeftBack.y = offset;
+ topLeftBack.z = -offset;
+ //
+ topLeftFront.x = -offset;
+ topLeftFront.y = offset;
+ topLeftFront.z = offset;
+ //
+ topRightBack.x = offset;
+ topRightBack.y = offset;
+ topRightBack.z = -offset;
+ //
+ topRightFront.x = offset;
+ topRightFront.y = offset;
+ topRightFront.z = offset;
+
+ }
+
+ static float tcfix = 0.00001f;
+
+ public void setTextureOffset(SpriteRectangle texRect) {
+ tcfix = (texRect.bottomRight.x - texRect.topLeft.x) / 512;
+ textureLeft = texRect.topLeft.x + tcfix;
+ textureRight = texRect.bottomRight.x - tcfix;
+ textureTop = texRect.topLeft.y + tcfix;
+ textureBottom = texRect.bottomRight.y - tcfix;
+ }
+
+ @Override
+ public int getMeshVertexCount(BlockType currentType, FloatBuffer renderLocation, boolean useShader) {
+ return 4 * ((renderBack ? 1 : 0) + (renderFront ? 1 : 0) + (renderLeft ? 1 : 0) + (renderRight ? 1 : 0)
+ + (renderBottom ? 1 : 0) + (renderTop ? 1 : 0));
+ }
+
+ @Override
+ public void putMesh(ImmModeMesh mesh, BlockType type, FloatBuffer location, boolean useShader) {
+ this.mesh = mesh;
+ mesh.enableColor4();
+ mesh.enableVertex3();
+ mesh.enableTexCoord2();
+ // mesh.enableNormal3();
+ mesh.glTranslate(location.get(0), location.get(1), location.get(2));
+ mesh.glColor4f(1, 1, 1, 1);
+ setPointOffset(0.5f * scale);
+ {
+ if (renderBack) {
+ setTextureOffset(type.getBackTextureOffset());
+ mesh.glNormal3f(0, 0, 1);
+ addBackQuad();
+ }
+ if (renderFront) {
+ setTextureOffset(type.getFrontTextureOffset());
+ mesh.glNormal3f(0, 0, -1);
+ addFrontQuad();
+ }
+ if (renderLeft) {
+ setTextureOffset(type.getLeftTextureOffset());
+ mesh.glNormal3f(1, 0, 0);
+ addLeftQuad();
+ }
+ if (renderRight) {
+ setTextureOffset(type.getRightTextureOffset());
+ mesh.glNormal3f(-1, 0, 1);
+ addRightQuad();
+ }
+ if (renderBottom) {
+ setTextureOffset(type.getBottomTextureOffset());
+ mesh.glNormal3f(0, -1, 0);
+ addBottomQuad();
+ }
+ if (renderTop) {
+ setTextureOffset(type.getTopTextureOffset());
+ mesh.glNormal3f(0, 1, 0);
+ addTopQuad();
+ }
+ }
+ }
+
+ @Override
+ public ImmModeMesh getMesh(BlockType type, FloatBuffer location, boolean glsl) {
+ mesh = ImmModeMesh.allocate(4 * 6); // 6 rectangles
+ mesh.setGLSL(glsl);
+ putMesh(mesh, type, location, glsl);
+ mesh.end();
+ return mesh;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockRenderer/ChunkMeshGarbageCollector.java b/src/ru/olamedia/olacraft/world/blockRenderer/ChunkMeshGarbageCollector.java
new file mode 100644
index 0000000..ad8bb81
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockRenderer/ChunkMeshGarbageCollector.java
@@ -0,0 +1,82 @@
+package ru.olamedia.olacraft.world.blockRenderer;
+
+import java.util.concurrent.ArrayBlockingQueue;
+
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.world.chunk.Chunk;
+import ru.olamedia.olacraft.world.chunk.ChunkSlice;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+
+public class ChunkMeshGarbageCollector extends Thread {
+ public static ChunkMeshGarbageCollector instance = new ChunkMeshGarbageCollector("Mesh GC");
+ private ArrayBlockingQueue<Chunk> chunks = new ArrayBlockingQueue<Chunk>(32);
+
+ public ChunkMeshGarbageCollector(String name) {
+ super(name);
+ }
+
+ BlockLocation cameraBlock;
+ private int renderDistance;
+
+ public void lookup() {
+ renderDistance = Game.client.getScene().getPlayer().settings.renderDistance;
+ cameraBlock = Game.client.getScene().getPlayer().getCameraBlockLocation();
+ // FIXME: cuncurrent modification
+ for (Integer x : ChunkSlice.rendererInstance.iChunks.keySet()) {
+ for (Integer y : ChunkSlice.rendererInstance.iChunks.get(x).keySet()) {
+ for (Integer z : ChunkSlice.rendererInstance.iChunks.get(x).get(y).keySet()) {
+ if (isFull()) {
+ return;
+ }
+ Chunk chunk = ChunkSlice.rendererInstance.iChunks.get(x).get(y).get(z);
+ 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 > renderDistance + renderDistance / 4) {
+ add(chunk);
+ }
+ }
+ }
+ }
+ }
+
+ public boolean isFull() {
+ return chunks.remainingCapacity() == 0;
+ }
+
+ public void add(Chunk chunk) {
+ chunks.offer(chunk);
+ }
+
+ public void clear() {
+ chunks.clear();
+ }
+
+ public void tick() throws InterruptedException {
+ if (!chunks.isEmpty()) {
+ Chunk chunk = chunks.take();
+ ChunkSlice.rendererInstance.removeChunk(chunk.location);
+ } else {
+ lookup();
+ }
+ }
+
+ @Override
+ public void run() {
+ // glc.makeCurrent();
+ while (true) {
+ // main loop
+ try {
+ tick();
+ if (chunks.isEmpty()) {
+ Thread.sleep(50);
+ }
+ // Thread.sleep(10); // or wait/join etc
+ } catch (InterruptedException ex) {
+ // cleanup here
+ Thread.currentThread().interrupt(); // for nested loops
+ break;
+ }
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockRenderer/ChunkRenderer.java b/src/ru/olamedia/olacraft/world/blockRenderer/ChunkRenderer.java
new file mode 100644
index 0000000..f27eb76
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockRenderer/ChunkRenderer.java
@@ -0,0 +1,356 @@
+package ru.olamedia.olacraft.world.blockRenderer;
+
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLUniformData;
+
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+import ru.olamedia.asset.Shader;
+import ru.olamedia.geom.ChunkMesh;
+import ru.olamedia.geom.ImmModeMesh;
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.render.jogl.ChunkRangeRenderer;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.calc.LightCalculator;
+import ru.olamedia.olacraft.world.calc.LightData;
+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.data.ChunkDataNeighbors;
+import ru.olamedia.olacraft.world.drop.DroppedEntity;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.IntLocation;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class ChunkRenderer {
+ protected static WorldProvider provider;
+ protected static Chunk chunk;
+ protected static ChunkData data;
+ protected ChunkData top;
+ protected ChunkData bottom;
+ protected ChunkData left;
+ protected ChunkData right;
+ protected ChunkData front;
+ protected ChunkData back;
+
+ protected int[] visible;
+
+ public static int visibleCount = 0;
+ public static int visibleOpaqueCount = 0;
+ public static int vertexCount = 0;
+ public static int vertexOpaqueCount = 0;
+
+ public boolean isAvailable = false;
+ public boolean isCompiling = false;
+ public boolean isCompiled = false;
+ public boolean needRecompilation = true;
+
+ protected static ImmModeMesh mesh;
+ protected ImmModeMesh prevMesh;
+ protected ImmModeMesh[] meshes;
+
+ protected static ImmModeMesh opaqueMesh;
+ protected ImmModeMesh prevOpaqueMesh;
+ protected ImmModeMesh[] opaqueMeshes;
+
+ protected ImmModeMesh[] droppedMeshes;
+
+ protected ArrayBlockingQueue<ImmModeMesh> disposable = new ArrayBlockingQueue<ImmModeMesh>(4096);
+ int droppedEntityVertexCount = 0;
+
+ private static Shader shader = null;
+ public static GLUniformData pmvMatrixUniform;
+ public static GLUniformData sunColor;
+
+ private static boolean useShader = true;
+
+ public static Shader getShader() {
+ if (null == shader) {
+ shader = new Shader();
+ shader.compile();
+ final GL2ES2 gl = GLContext.getCurrentGL().getGL2ES2();
+ final ShaderState state = shader.getState();
+ final PMVMatrix pmvMatrix = Game.client.getScene().getPmvMatrix();
+ state.attachObject("pmvMatrix", pmvMatrix);
+ pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ state.ownUniform(pmvMatrixUniform);
+ state.uniform(gl, pmvMatrixUniform);
+
+ state.attachObject("sunColor", ChunkRenderer.sunColor);
+ sunColor = new GLUniformData("sunColor", 4, Game.client.getScene().dayTime.sunColor);
+ state.ownUniform(ChunkRenderer.sunColor);
+ state.uniform(gl, ChunkRenderer.sunColor);
+
+ // if (!state.uniform(gl, new GLUniformData("sunColor", 4,
+ // Game.client.getScene().time.sunColor))) {
+ // throw new GLException("Error setting sunColor in shader: " +
+ // state);
+ // }
+ if (!state.uniform(gl, new GLUniformData("mesh_ActiveTexture", 0))) {
+ throw new GLException("Error setting mesh_ActiveTexture in shader: " + state);
+ }
+ }
+ return shader;
+ }
+
+ public ChunkRenderer(Chunk chunk) {
+ this.chunk = chunk;
+ this.provider = chunk.getProvider();
+ }
+
+ public void invalidate() {
+ needRecompilation = true;
+ }
+
+ protected void disposeMesh(ImmModeMesh mesh) {
+ if (null != mesh) {
+ disposable.offer(mesh);
+ }
+ }
+
+ public void disposeMeshes() {
+ // while (!disposable.isEmpty()){
+ // final ImmModeMesh mesh = disposable.poll();
+ // mesh.dispose();
+ // }
+ }
+
+ private static IntBuffer blockLocation = IntBuffer.allocate(3);
+ private static FloatBuffer renderLocation = FloatBuffer.allocate(3);
+
+ private static short currentId;
+ private static BlockType currentType;
+ private static AbstractBlockRenderer currentRenderer;
+
+ private static void prepareRenderer(WorldProvider provider, Chunk chunk, ChunkData data) {
+ currentType = provider.getTypeRegistry().getBlockType(data.types[currentId]);
+ if (null == currentType) {
+ throw new RuntimeException("invalid type: " + currentType + " " + currentId);
+ }
+ final int x = currentId / 256;
+ final int y = (currentId - x * 256) / 16;
+ final int z = currentId - x * 256 - y * 16;
+ IntLocation.set(blockLocation, chunk.offset.x + x, chunk.offset.y + y, chunk.offset.z + z);
+ renderLocation.put(0, blockLocation.get(0));
+ renderLocation.put(1, blockLocation.get(1));
+ renderLocation.put(2, blockLocation.get(2));
+ // final RenderLocation location = new
+ // RenderLocation(blockLocation);
+ // System.out.println(chunk.location);
+ currentRenderer = currentType.getRenderer();
+ if (null == currentRenderer) {
+ throw new RuntimeException("invalid renderer: " + currentType.getClass().getName());
+ }
+ currentRenderer.setScale(1);
+ currentRenderer.setNeighbors(neighbors);
+ if (currentType.hideTouchedSides() || currentType.isOpaque()) {
+ // check each side
+ try {
+ currentRenderer.renderBottom = !provider.hideTouchedSides(blockLocation.get(0),
+ blockLocation.get(1) - 1, blockLocation.get(2), data.types[currentId]);
+ currentRenderer.renderTop = !provider.hideTouchedSides(blockLocation.get(0), blockLocation.get(1) + 1,
+ blockLocation.get(2), data.types[currentId]);
+ currentRenderer.renderLeft = !provider.hideTouchedSides(blockLocation.get(0) - 1, blockLocation.get(1),
+ blockLocation.get(2), data.types[currentId]);
+ currentRenderer.renderRight = !provider.hideTouchedSides(blockLocation.get(0) + 1,
+ blockLocation.get(1), blockLocation.get(2), data.types[currentId]);
+ currentRenderer.renderFront = !provider.hideTouchedSides(blockLocation.get(0), blockLocation.get(1),
+ blockLocation.get(2) + 1, data.types[currentId]);
+ currentRenderer.renderBack = !provider.hideTouchedSides(blockLocation.get(0), blockLocation.get(1),
+ blockLocation.get(2) - 1, data.types[currentId]);
+ } catch (ChunkUnavailableException e) {
+ e.printStackTrace();
+ }
+ } else {
+ currentRenderer.renderAllSides();
+ }
+ }
+
+ private static ChunkDataNeighbors neighbors = new ChunkDataNeighbors();
+
+ public static void compile(Chunk chunk) {
+ final ChunkMesh chunkMesh = chunk.mesh;
+ chunkMesh.setValid(true);
+ final WorldProvider provider = chunk.getProvider();
+ if (chunk.offset.y >= provider.getInfo().maxHeight) {
+ chunkMesh.setCompiled(true);
+ return;
+ }
+ if (chunk.offset.y < provider.getInfo().minHeight) {
+ chunkMesh.setCompiled(true);
+ return;
+ }
+
+ if (!chunk.isAvailable()) {
+ chunk.request();
+ return;
+ }
+ if (!chunk.isNeighborsAvailable()) {
+ chunk.requestNeighbors();
+ return;
+ }
+ final ChunkData data = chunk.getData();
+ neighbors.setProvider(provider);
+ neighbors.setData(data);
+ neighbors.loadNeighbors();
+ neighbors.calcLight();
+ neighbors.calcVisibility();
+ // data.computeVisibility(provider);
+ // updateVisibility();
+
+ // droppedEntityVertexCount = 0;
+ // if (!data.droppedEntities.isEmpty()) {
+ // droppedMeshes = new ImmModeMesh[data.droppedEntities.size()];
+ // int i = 0;
+ // for (DroppedEntity entity : data.droppedEntities) {
+ // droppedMeshes[i] = compileDroppedEntity(entity);
+ // droppedEntityVertexCount += droppedMeshes[i].getVertexCount();
+ // i++;
+ // }
+ // }
+ //
+ // vertexCount = droppedEntityVertexCount;
+ vertexCount = 0;
+ vertexOpaqueCount = 0;
+ for (currentId = 0; currentId < 4096; currentId++) {
+ if (neighbors.isVisible(currentId)) {
+ prepareRenderer(provider, chunk, data);
+ if (null != currentRenderer) {
+ if (currentType.isOpaque()) {
+ vertexOpaqueCount += currentRenderer.getMeshVertexCount(currentType, renderLocation, useShader);
+ } else {
+ vertexOpaqueCount += currentRenderer.getMeshVertexCount(currentType, renderLocation, useShader);
+ //vertexCount += currentRenderer.getMeshVertexCount(currentType, renderLocation, useShader);
+ }
+ }
+ }
+ }
+ if (vertexCount > 0) {
+ mesh = ImmModeMesh.allocate(vertexCount);
+ // mesh.setServer(true);
+ mesh.setGLSL(true);
+ mesh.enableColor4();
+ mesh.enableTexCoord2();
+ mesh.enableVertex3();
+ // mesh.enableNormal3();
+ mesh.beginQuads();
+ } else {
+ mesh = null;
+ }
+ if (vertexOpaqueCount > 0) {
+ opaqueMesh = ImmModeMesh.allocate(vertexOpaqueCount);
+ // opaqueMesh.setServer(true);
+ opaqueMesh.setGLSL(true);
+ opaqueMesh.enableColor4();
+ opaqueMesh.enableTexCoord2();
+ opaqueMesh.enableVertex3();
+ // opaqueMesh.enableNormal3();
+ opaqueMesh.beginQuads();
+ } else {
+ opaqueMesh = null;
+ }
+ for (currentId = 0; currentId < 4096; currentId++) {
+ if (neighbors.isVisible(currentId)) {
+ prepareRenderer(provider, chunk, data);
+ //if (currentType.isOpaque()) {
+ visibleOpaqueCount++;
+ if (vertexOpaqueCount > 0) {
+ currentRenderer.putMesh(opaqueMesh, currentType, renderLocation, useShader);
+ }
+ //} else {
+ // if (vertexCount > 0) {
+ // currentRenderer.putMesh(mesh, currentType, renderLocation, useShader);
+ // }
+ //}
+ }
+ }
+ if (vertexCount > 0) {
+ mesh.end();
+ mesh.compact();
+ }
+ if (vertexOpaqueCount > 0) {
+ opaqueMesh.end();
+ opaqueMesh.compact();
+ }
+ chunkMesh.setMesh(mesh);
+ chunkMesh.setOpaqueMesh(opaqueMesh);
+ }
+
+ public ImmModeMesh getOpaqueMesh() {
+ return opaqueMesh;
+ }
+
+ public ImmModeMesh getMesh() {
+ return mesh;
+ }
+
+ public ImmModeMesh compileDroppedEntity(DroppedEntity entity) {
+ final BlockType type = entity.stack.type;
+ final RenderLocation location = new RenderLocation(entity.location);
+ // int id = location.clampId();
+ // System.out.println(chunk.location);
+ final AbstractBlockRenderer renderer = type.getRenderer();
+ renderer.setScale(0.3f);
+ renderer.renderAllSides();
+ return renderer.getMesh(type, location, useShader);
+ }
+
+ public void render(int pass) {
+
+ if (!isCompiled || isCompiling || !isAvailable) {
+ // compile();
+ return;
+ }
+ if (pass == ChunkRangeRenderer.OPAQUE_PASS) {
+ if (null != opaqueMesh) {
+ opaqueMesh.draw();
+ } else if (null != prevOpaqueMesh) {
+ prevOpaqueMesh.draw();
+ }
+ } else {
+ if (null != mesh) {
+ mesh.draw();
+ } else if (null != prevMesh) {
+ prevMesh.draw();
+ }
+ }
+ /*
+ * if (!disposable.isEmpty()) {
+ * for (ImmModeMesh mesh : disposable) {
+ * mesh.dispose();
+ * }
+ * disposable.clear();
+ * }
+ */
+ }
+
+ public static void disableShader() {
+ getShader().disable();
+ }
+
+ public static void enableShader() {
+ // GL2ES2 gl = GLContext.getCurrentGL().getGL2ES2();
+ getShader().enable();
+ // Game.client.getScene().time.getClearColor();
+ // getShader().getState().uniform(gl, pmvMatrixUniform);
+ // getShader().getState().uniform(gl, sunColor);
+ }
+
+ public void destroy() {
+ isCompiling = true;
+ mesh = null;
+ prevMesh = null;
+ meshes = null;
+ needRecompilation = true;
+ isCompiled = false;
+ isCompiling = false;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockRenderer/CrossQuadsRenderer.java b/src/ru/olamedia/olacraft/world/blockRenderer/CrossQuadsRenderer.java
new file mode 100644
index 0000000..4dc14a6
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockRenderer/CrossQuadsRenderer.java
@@ -0,0 +1,115 @@
+package ru.olamedia.olacraft.world.blockRenderer;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+
+import ru.olamedia.geom.ImmModeMesh;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+
+public class CrossQuadsRenderer extends BoxRenderer {
+ public static boolean useTriangles = false;
+ private HashMap<Integer, ImmModeMesh> precompiled = new HashMap<Integer, ImmModeMesh>();
+
+ public void addLeftQuad() {
+ // triangle strip: И
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftBackVertex();
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomLeftBackVertex();
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightFrontVertex();
+
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftBackVertex();
+ }
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightFrontVertex();
+ mesh.setUV(textureRight, textureTop);
+ addTopRightFrontVertex();
+ // mirror
+ mesh.setUV(textureLeft, textureTop);
+ addTopRightFrontVertex();
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomRightFrontVertex();
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureBottom);
+ addBottomLeftBackVertex();
+
+ mesh.setUV(textureLeft, textureTop);
+ addTopRightFrontVertex();
+ }
+ mesh.setUV(textureRight, textureBottom);
+ addBottomLeftBackVertex();
+ mesh.setUV(textureRight, textureTop);
+ addTopLeftBackVertex();
+ }
+
+ public void addRightQuad() {
+ // triangle strip: И
+ mesh.setUV(textureLeft, textureTop);
+ addTopRightBackVertex();
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomRightBackVertex();
+ if (useTriangles) {
+ mesh.setUV(textureLeft, textureTop);
+ addTopRightBackVertex();
+
+ mesh.setUV(textureRight, textureBottom);
+ addBottomLeftFrontVertex();
+ }
+ mesh.setUV(textureRight, textureBottom);
+ addBottomLeftFrontVertex();
+ mesh.setUV(textureRight, textureTop);
+ addTopLeftFrontVertex();
+ // mirror
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftFrontVertex();
+ mesh.setUV(textureLeft, textureBottom);
+ addBottomLeftFrontVertex();
+ if (useTriangles) {
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightBackVertex();
+
+ mesh.setUV(textureLeft, textureTop);
+ addTopLeftFrontVertex();
+ }
+ mesh.setUV(textureRight, textureBottom);
+ addBottomRightBackVertex();
+ mesh.setUV(textureRight, textureTop);
+ addTopRightBackVertex();
+ }
+
+ @Override
+ public int getMeshVertexCount(BlockType currentType, FloatBuffer renderLocation, boolean useShader) {
+ return 4 * 4;
+ }
+
+ @Override
+ public void putMesh(ImmModeMesh mesh, BlockType type, FloatBuffer location, boolean useShader) {
+ this.mesh = mesh;
+ // mesh.enableNormal3();
+ mesh.glNormal3f(1, 0, 0);
+ mesh.glTranslate(location.get(0), location.get(1), location.get(2));
+ mesh.glColor4f(1, 1, 1, 1f);
+ setPointOffset(0.5f * scale);
+ {
+ setTextureOffset(type.getLeftTextureOffset());
+ addLeftQuad();
+ addRightQuad();
+ }
+ }
+
+ @Override
+ public ImmModeMesh getMesh(BlockType type, FloatBuffer location, boolean glsl) {
+ mesh = ImmModeMesh.allocate(4 * 4); // 6 rectangles
+ mesh.enableColor4();
+ mesh.enableVertex3();
+ mesh.enableTexCoord2();
+ mesh.setGLSL(glsl);
+ putMesh(mesh, type, location, glsl);
+ mesh.end();
+ return mesh;
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/blockRenderer/IBlockRenderer.java b/src/ru/olamedia/olacraft/world/blockRenderer/IBlockRenderer.java
new file mode 100644
index 0000000..4d2a239
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockRenderer/IBlockRenderer.java
@@ -0,0 +1,15 @@
+package ru.olamedia.olacraft.world.blockRenderer;
+
+import ru.olamedia.geom.ImmModeMesh;
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.location.Location3f;
+import ru.olamedia.olacraft.world.location.Location3i;
+
+public interface IBlockRenderer {
+
+ public void render(BlockType type, Location3i location, boolean glsl);
+
+ public void render(BlockType type, Location3f location, boolean glsl);
+
+ public ImmModeMesh getMesh(BlockType type, Location3f location, boolean glsl);
+}
diff --git a/src/ru/olamedia/olacraft/world/blockRenderer/RenderLocation.java b/src/ru/olamedia/olacraft/world/blockRenderer/RenderLocation.java
new file mode 100644
index 0000000..b396010
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockRenderer/RenderLocation.java
@@ -0,0 +1,35 @@
+package ru.olamedia.olacraft.world.blockRenderer;
+
+import java.nio.IntBuffer;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.location.Location3f;
+import ru.olamedia.olacraft.world.location.Location3i;
+
+public class RenderLocation extends Location3f {
+ public RenderLocation(float x, float y, float z) {
+ super(x, y, z);
+ }
+
+ public RenderLocation(Location3i location) {
+ super(location);
+ }
+
+ public RenderLocation(Location3f location) {
+ super(location);
+ }
+
+ public RenderLocation(IntBuffer location) {
+ super(location.get(0), location.get(1), location.get(2));
+ }
+
+ public void set(float x, float y, float z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public int clampId() {
+ return ChunkData.ClampID((int) x, (int) y, (int) z);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockRenderer/package-info.java b/src/ru/olamedia/olacraft/world/blockRenderer/package-info.java
new file mode 100644
index 0000000..65ce990
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockRenderer/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.blockRenderer; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/blockStack/BlockStack.java b/src/ru/olamedia/olacraft/world/blockStack/BlockStack.java
index 57258ef..0d6dd7f 100644
--- a/src/ru/olamedia/olacraft/world/blockStack/BlockStack.java
+++ b/src/ru/olamedia/olacraft/world/blockStack/BlockStack.java
@@ -1,13 +1,15 @@
package ru.olamedia.olacraft.world.blockStack;
-import ru.olamedia.olacraft.world.block.Block;
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+import ru.olamedia.olacraft.world.blockTypes.EmptyBlockType;
public class BlockStack {
- public Block block;
- public int count;
+ public AbstractBlockType type;
+ public int count = 0;
+ public boolean hidden = false; // do not render
- public BlockStack(Block block, int count) {
- this.block = block;
+ public BlockStack(AbstractBlockType type, int count) {
+ this.type = type;
this.count = count;
}
@@ -23,40 +25,40 @@ public class BlockStack {
} else {
c = count;
count = 0;
+ type = new EmptyBlockType();
}
- return new BlockStack(block, c);
+ return new BlockStack(type, c);
}
public BlockStack getAll() {
int c = count;
count = 0;
- return new BlockStack(block, c);
+ return new BlockStack(type, c);
}
/**
*
- * @return Remaining BlockStack
*/
- public BlockStack putStack(BlockStack stack) {
-
- if (block.getType() == stack.block.getType()) {
- int max = block.getType().getMaxStack();
- // Stack
- int total = count + stack.count;
- if (total < max) {
- count = total;
- return new BlockStack(block, 0);
- } else {
- BlockStack remains = new BlockStack(block, total - max);
- count = max;
- return remains;
- }
+ public void putStack(BlockStack stack) {
+ if (!type.getClass().getName().equals(stack.type.getClass().getName())) {
+ try {
+ type = stack.type.getClass().newInstance();
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } // replace
+ }
+ int max = type.getMaxStack();
+ // Stack
+ int total = count + stack.count;
+ if (total < max) {
+ count = total;
+ stack.count = 0;
+ stack.type = new EmptyBlockType();
} else {
- // Replace
- BlockStack remains = new BlockStack(block, count);
- block = stack.block;
- count = stack.count;
- return remains;
+ count = max;
+ stack.count = total - max;
}
}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java
index 717c01f..43e1332 100644
--- a/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java
+++ b/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java
@@ -2,12 +2,26 @@ package ru.olamedia.olacraft.world.blockTypes;
import com.jogamp.opengl.util.texture.Texture;
-import ru.olamedia.olacraft.world.block.BlockRegistry;
+import ru.olamedia.asset.SpriteRectangle;
+import ru.olamedia.olacraft.world.blockRenderer.AbstractBlockRenderer;
+import ru.olamedia.olacraft.world.blockRenderer.BoxRenderer;
+import ru.olamedia.olacraft.world.blockRenderer.RenderLocation;
+import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.provider.WorldProvider;
import ru.olamedia.texture.TextureManager;
public abstract class AbstractBlockType implements BlockType {
+ protected AbstractBlockRenderer renderer = new BoxRenderer();
+
+ public void dropBlock(WorldProvider provider, BlockLocation location){
+ provider.dropBlock(location, this);
+ }
+
+ public AbstractBlockRenderer getRenderer() {
+ return this.renderer;
+ }
+
@Override
abstract public String getName();
@@ -16,6 +30,23 @@ public abstract class AbstractBlockType implements BlockType {
return 64;
}
+ public boolean isOpaque() { // solid, non-transparent block
+ return true;
+ }
+
+ public boolean isLoose() {
+ return false;
+ }
+
+ @Override
+ public boolean hideTouchedSides() {
+ return isOpaque();
+ }
+
+ public boolean canMoveThrough() {
+ return false;
+ }
+
@Override
abstract public String getStackTextureFile();
@@ -49,41 +80,88 @@ public abstract class AbstractBlockType implements BlockType {
@Override
public Texture getTopTexture() {
- return TextureManager.get(this.getTopTextureFile());
+ return TextureManager.getSprite(this.getTopTextureFile());
+ }
+
+ @Override
+ public SpriteRectangle getTopTextureOffset() {
+ return TextureManager.getSpriteOffset(this.getTopTextureFile());
}
@Override
public Texture getBottomTexture() {
- return TextureManager.get(this.getBottomTextureFile());
+ return TextureManager.getSprite(this.getBottomTextureFile());
+ }
+
+ @Override
+ public SpriteRectangle getBottomTextureOffset() {
+ return TextureManager.getSpriteOffset(this.getBottomTextureFile());
}
@Override
public Texture getLeftTexture() {
- return TextureManager.get(this.getLeftTextureFile());
+ return TextureManager.getSprite(this.getLeftTextureFile());
+ }
+
+ @Override
+ public SpriteRectangle getLeftTextureOffset() {
+ return TextureManager.getSpriteOffset(this.getLeftTextureFile());
}
@Override
public Texture getRightTexture() {
- return TextureManager.get(this.getRightTextureFile());
+ return TextureManager.getSprite(this.getRightTextureFile());
+ }
+
+ @Override
+ public SpriteRectangle getRightTextureOffset() {
+ return TextureManager.getSpriteOffset(this.getRightTextureFile());
}
@Override
public Texture getFrontTexture() {
- return TextureManager.get(this.getFrontTextureFile());
+ return TextureManager.getSprite(this.getFrontTextureFile());
+ }
+
+ @Override
+ public SpriteRectangle getFrontTextureOffset() {
+ return TextureManager.getSpriteOffset(this.getFrontTextureFile());
}
@Override
public Texture getBackTexture() {
- return TextureManager.get(this.getBackTextureFile());
+ return TextureManager.getSprite(this.getBackTextureFile());
}
-
- public void register(WorldProvider provider){
- getBackTexture();
- getBottomTexture();
- getFrontTexture();
- getLeftTexture();
- getRightTexture();
- getTopTexture();
- provider.getTypeRegistry().registerBlockType(this);
+
+ @Override
+ public SpriteRectangle getBackTextureOffset() {
+ return TextureManager.getSpriteOffset(this.getBackTextureFile());
+ }
+
+ public void register(WorldProvider provider, boolean registerTextures) {
+ if (registerTextures) {
+ getBackTexture();
+ getBottomTexture();
+ getFrontTexture();
+ getLeftTexture();
+ getRightTexture();
+ getTopTexture();
+ } else {
+ provider.getTypeRegistry().registerBlockType(this);
+ }
+ }
+
+ public int getId(WorldProvider provider) {
+ return provider.getTypeRegistry().getBlockIdByClassName(this.getClass().getName());
+ }
+
+ @Override
+ public void render(RenderLocation location) {
+ this.renderer.render(this, location, true);
+ }
+
+ @Override
+ public boolean isTimeManaged() {
+ return false;
}
}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/BlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/BlockType.java
index 0bda2eb..d74dd6b 100644
--- a/src/ru/olamedia/olacraft/world/blockTypes/BlockType.java
+++ b/src/ru/olamedia/olacraft/world/blockTypes/BlockType.java
@@ -1,21 +1,83 @@
package ru.olamedia.olacraft.world.blockTypes;
+import ru.olamedia.asset.SpriteOffset;
+import ru.olamedia.asset.SpriteRectangle;
+import ru.olamedia.olacraft.world.blockRenderer.AbstractBlockRenderer;
+import ru.olamedia.olacraft.world.blockRenderer.IBlockRenderer;
+import ru.olamedia.olacraft.world.blockRenderer.RenderLocation;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
import com.jogamp.opengl.util.texture.Texture;
public interface BlockType {
public String getName();
+
public int getMaxStack();
+
+ public int getId(WorldProvider provider);
+
public String getStackTextureFile();
+
public String getTopTextureFile();
+
+ public SpriteRectangle getTopTextureOffset();
+
public String getBottomTextureFile();
+
+ public SpriteRectangle getBottomTextureOffset();
+
public String getLeftTextureFile();
+
+ public SpriteRectangle getLeftTextureOffset();
+
public String getRightTextureFile();
+
+ public SpriteRectangle getRightTextureOffset();
+
public String getFrontTextureFile();
+
+ public SpriteRectangle getFrontTextureOffset();
+
public String getBackTextureFile();
+
+ public SpriteRectangle getBackTextureOffset();
+
public Texture getTopTexture();
+
public Texture getBottomTexture();
+
public Texture getLeftTexture();
+
public Texture getRightTexture();
+
public Texture getFrontTexture();
+
public Texture getBackTexture();
+
+ /**
+ * Is block solid and completely non-transparent
+ */
+ public boolean isOpaque();
+
+ /**
+ * Is block solid and we can remove sides if touched by another solid block
+ */
+ public boolean hideTouchedSides();
+
+ /**
+ * Is block loose
+ */
+ public boolean isLoose();
+
+ /**
+ * Can live entities move through this block
+ */
+ public boolean canMoveThrough();
+
+ public AbstractBlockRenderer getRenderer();
+
+ public void render(RenderLocation location);
+
+ public boolean isTimeManaged();
}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java
index a4e5dd7..b359b08 100644
--- a/src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java
+++ b/src/ru/olamedia/olacraft/world/blockTypes/DirtBlockType.java
@@ -3,7 +3,11 @@ package ru.olamedia.olacraft.world.blockTypes;
public class DirtBlockType extends AbstractBlockType {
@Override
public String getName() {
- return "Gravel";
+ return "Dirt";
+ }
+
+ public boolean isLoose() {
+ return true;
}
@Override
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java
index 4073356..595c977 100644
--- a/src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java
+++ b/src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java
@@ -3,7 +3,7 @@ package ru.olamedia.olacraft.world.blockTypes;
public class EmptyBlockType extends AbstractBlockType {
@Override
public String getName() {
- return "";
+ return "Empty";
}
@Override
@@ -20,4 +20,8 @@ public class EmptyBlockType extends AbstractBlockType {
public String getTopTextureFile() {
return "texture/empty.png";
}
+ @Override
+ public boolean isOpaque() {
+ return false;
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java
index d863139..6104d13 100644
--- a/src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java
+++ b/src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java
@@ -6,6 +6,10 @@ public class GrassBlockType extends AbstractBlockType {
return "Grass";
}
+ public boolean isLoose() {
+ return true;
+ }
+
@Override
public int getMaxStack() {
return 64;
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java
index 354d383..e013148 100644
--- a/src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java
+++ b/src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java
@@ -6,6 +6,10 @@ public class GravelBlockType extends AbstractBlockType {
return "Gravel";
}
+ public boolean isLoose() {
+ return true;
+ }
+
@Override
public int getMaxStack() {
return 64;
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/IceBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/IceBlockType.java
new file mode 100644
index 0000000..a5c6767
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/IceBlockType.java
@@ -0,0 +1,32 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+public class IceBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Ice";
+ }
+
+ public boolean isLoose() {
+ return true;
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return true;
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 1;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/ice.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/ice.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/SnowBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/SnowBlockType.java
new file mode 100644
index 0000000..18697e4
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/SnowBlockType.java
@@ -0,0 +1,27 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+public class SnowBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Snow";
+ }
+
+ public boolean isLoose() {
+ return true;
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 1;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/snow.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/snow.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/TallGrassBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/TallGrassBlockType.java
new file mode 100644
index 0000000..c277d72
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/TallGrassBlockType.java
@@ -0,0 +1,58 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+import ru.olamedia.olacraft.world.blockRenderer.AbstractBlockRenderer;
+import ru.olamedia.olacraft.world.blockRenderer.CrossQuadsRenderer;
+
+public class TallGrassBlockType extends AbstractBlockType {
+
+ protected AbstractBlockRenderer renderer = new CrossQuadsRenderer();
+
+ @Override
+ public AbstractBlockRenderer getRenderer() {
+ return this.renderer;
+ }
+
+ @Override
+ public String getName() {
+ return "Tall Grass";
+ }
+
+ @Override
+ public boolean canMoveThrough() {
+ return true;
+ }
+
+ public boolean isLoose() {
+ return false;
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return false;
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/terrain-wheatgrass-lightgreen-med.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/terrain-wheatgrass-lightgreen-med.png";
+ }
+
+ @Override
+ public String getFrontTextureFile() {
+ return "texture/terrain-wheatgrass-lightgreen-med.png";
+ }
+
+ @Override
+ public boolean isTimeManaged() {
+ return true;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/WaterBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/WaterBlockType.java
new file mode 100644
index 0000000..0ff984f
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/WaterBlockType.java
@@ -0,0 +1,42 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+public class WaterBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Water";
+ }
+
+ public boolean isLoose() {
+ return true;
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 1;
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return false;
+ }
+
+ @Override
+ public boolean hideTouchedSides() {
+ return true;
+ }
+
+ @Override
+ public boolean canMoveThrough() {
+ return true;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/water.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/water.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/WheatBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/WheatBlockType.java
new file mode 100644
index 0000000..583e91a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/WheatBlockType.java
@@ -0,0 +1,58 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+import ru.olamedia.olacraft.world.blockRenderer.AbstractBlockRenderer;
+import ru.olamedia.olacraft.world.blockRenderer.CrossQuadsRenderer;
+
+public class WheatBlockType extends AbstractBlockType {
+
+ protected AbstractBlockRenderer renderer = new CrossQuadsRenderer();
+
+ @Override
+ public AbstractBlockRenderer getRenderer() {
+ return this.renderer;
+ }
+
+ @Override
+ public String getName() {
+ return "Wheat";
+ }
+
+ @Override
+ public boolean canMoveThrough() {
+ return true;
+ }
+
+ public boolean isLoose() {
+ return false;
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return false;
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/wheat.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/wheat.png";
+ }
+
+ @Override
+ public String getFrontTextureFile() {
+ return "texture/wheat.png";
+ }
+
+ @Override
+ public boolean isTimeManaged() {
+ return true;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/BrecciaStoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/BrecciaStoneBlockType.java
new file mode 100644
index 0000000..187938b
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/BrecciaStoneBlockType.java
@@ -0,0 +1,25 @@
+package ru.olamedia.olacraft.world.blockTypes.stone;
+
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+
+public class BrecciaStoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Breccia";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/stone/sedimentary/breccia.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/stone/sedimentary/breccia.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/ChertStoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/ChertStoneBlockType.java
new file mode 100644
index 0000000..706abfc
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/ChertStoneBlockType.java
@@ -0,0 +1,25 @@
+package ru.olamedia.olacraft.world.blockTypes.stone;
+
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+
+public class ChertStoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Chert";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/stone/sedimentary/chert.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/stone/sedimentary/chert.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/CoalStoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/CoalStoneBlockType.java
new file mode 100644
index 0000000..fe06c3d
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/CoalStoneBlockType.java
@@ -0,0 +1,25 @@
+package ru.olamedia.olacraft.world.blockTypes.stone;
+
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+
+public class CoalStoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Coal";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/stone/sedimentary/coal.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/stone/sedimentary/coal.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/ConglomerateStoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/ConglomerateStoneBlockType.java
new file mode 100644
index 0000000..e3829b2
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/ConglomerateStoneBlockType.java
@@ -0,0 +1,25 @@
+package ru.olamedia.olacraft.world.blockTypes.stone;
+
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+
+public class ConglomerateStoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Conglomerate";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/stone/sedimentary/conglomerate.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/stone/sedimentary/conglomerate.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/LimestoneStoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/LimestoneStoneBlockType.java
new file mode 100644
index 0000000..bb49e9c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/LimestoneStoneBlockType.java
@@ -0,0 +1,25 @@
+package ru.olamedia.olacraft.world.blockTypes.stone;
+
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+
+public class LimestoneStoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Limestone";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/stone/sedimentary/limestone.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/stone/sedimentary/limestone.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/SandstoneStoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/SandstoneStoneBlockType.java
new file mode 100644
index 0000000..c91bdce
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/SandstoneStoneBlockType.java
@@ -0,0 +1,25 @@
+package ru.olamedia.olacraft.world.blockTypes.stone;
+
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+
+public class SandstoneStoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Sandstone";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/stone/sedimentary/sandstone.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/stone/sedimentary/sandstone.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/ShaleStoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/ShaleStoneBlockType.java
new file mode 100644
index 0000000..e099227
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/ShaleStoneBlockType.java
@@ -0,0 +1,25 @@
+package ru.olamedia.olacraft.world.blockTypes.stone;
+
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+
+public class ShaleStoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Stone";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/stone/sedimentary/shale.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/stone/sedimentary/shale.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/SiltstoneStoneBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/SiltstoneStoneBlockType.java
new file mode 100644
index 0000000..db1a0f3
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/SiltstoneStoneBlockType.java
@@ -0,0 +1,25 @@
+package ru.olamedia.olacraft.world.blockTypes.stone;
+
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+
+public class SiltstoneStoneBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Stone";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/stone/sedimentary/siltstone.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/stone/sedimentary/siltstone.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/stone/package-info.java b/src/ru/olamedia/olacraft/world/blockTypes/stone/package-info.java
new file mode 100644
index 0000000..dd284af
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/stone/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.blockTypes.stone; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/calc/LightCalculator.java b/src/ru/olamedia/olacraft/world/calc/LightCalculator.java
new file mode 100644
index 0000000..7f55f71
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/calc/LightCalculator.java
@@ -0,0 +1,118 @@
+package ru.olamedia.olacraft.world.calc;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.data.ChunkDataNeighbors;
+import ru.olamedia.olacraft.world.data.ChunkDataWrapper;
+import ru.olamedia.olacraft.world.location.IntLocation;
+
+public class LightCalculator {
+
+ private static final byte fallingLight = 15;
+ private static boolean exposed = true;
+
+ public static void calculateVoidLightIgnoreNeighbors(ChunkDataWrapper dataWrapper) {
+ precalculateVoidLight(dataWrapper);
+ spreadVoidLightIgnoreNeighbors(dataWrapper);
+ }
+
+ public static void precalculateVoidLight(ChunkDataWrapper dataWrapper) {
+ final ChunkData data = dataWrapper.getData();
+ final LightData light = dataWrapper.getLight();
+ for (int x = 0; x <= 15; x++) {
+ for (int z = 0; z <= 15; z++) {
+ // FIXME (heightmap)
+ // falling from top
+ exposed = true;
+ for (byte y = 15; y >= 0; y--) {
+ final short id = IntLocation.id(x, y, z);
+ if (data.isEmpty(id)) {
+ if (exposed) {
+ light.setVoidLight(id, fallingLight);
+ } else {
+ light.setVoidLight(id, (byte) 0);
+ }
+ } else {
+ exposed = false;
+ light.setVoidLight(id, (byte) 0);
+ }
+ }
+ }
+ }
+ }
+
+ public static byte max(byte a, byte b, byte c, byte d) {
+ return max(max(a, b), max(c, d));
+ }
+
+ public static byte max(byte a, byte b) {
+ return a > b ? a : b;
+ }
+
+ public static void spreadVoidLightIgnoreNeighbors(ChunkDataWrapper dataWrapper) {
+ final ChunkData data = dataWrapper.getData();
+ final LightData light = dataWrapper.getLight();
+ for (byte i = 0; i < 15; i++) {
+ for (byte x = 0; x <= 15; x++) {
+ for (byte z = 0; z <= 15; z++) {
+ for (byte y = 0; y <= 15; y++) {
+ final short id = IntLocation.id(x, y, z);
+ if (data.isEmpty(id)) {
+ final byte current = light.getVoidLight(id);
+ if (current < 15) {
+ final byte top = (y == 15) ? 0 : (byte) (light
+ .getVoidLight(IntLocation.id(x, y + 1, z)) - 1);
+ final byte bottom = (y == 0) ? 0 : (byte) (light.getVoidLight(IntLocation.id(x, y - 1,
+ z)) - 1);
+ final byte left = (x == 0) ? 0 : (byte) (light
+ .getVoidLight(IntLocation.id(x - 1, y, z)) - 1);
+ final byte right = (x == 15) ? 0 : (byte) (light.getVoidLight(IntLocation.id(x + 1, y,
+ z)) - 1);
+ final byte front = (z == 15) ? 0 : (byte) (light.getVoidLight(IntLocation.id(x, y,
+ z + 1)) - 1);
+ final byte back = (z == 0) ? 0 : (byte) (light
+ .getVoidLight(IntLocation.id(x, y, z - 1)) - 1);
+ light.setVoidLight(id,
+ max(max(top, bottom, left, right), max(max(front, back), current)));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static void spreadVoidLight(ChunkDataNeighbors neighbors) {
+ final LightData light = neighbors.getCenter().getLight();
+ for (byte x = 0; x <= 15; x++) {
+ for (byte z = 0; z <= 15; z++) {
+ for (byte y = 0; y <= 15; y++) {
+ final LightData topData = y == 15 ? neighbors.getTop().getLight() : light;
+ final LightData bottomData = y == 0 ? neighbors.getBottom().getLight() : light;
+ final LightData leftData = x == 0 ? neighbors.getLeft().getLight() : light;
+ final LightData rightData = x == 15 ? neighbors.getRight().getLight() : light;
+ final LightData frontData = z == 15 ? neighbors.getFront().getLight() : light;
+ final LightData backData = z == 0 ? neighbors.getBack().getLight() : light;
+ final short id = IntLocation.id(x, y, z);
+ if (neighbors.getCenterData().isEmpty(id)) {
+ final byte current = light.getVoidLight(id);
+ if (current < 15) {
+ final byte top = (byte) (topData.getVoidLight(IntLocation.id(x, y + 1, z)) - 1);
+ final byte bottom = (byte) (bottomData.getVoidLight(IntLocation.id(x, y - 1, z)) - 1);
+ final byte left = (byte) (leftData.getVoidLight(IntLocation.id(x - 1, y, z)) - 1);
+ final byte right = (byte) (rightData.getVoidLight(IntLocation.id(x + 1, y, z)) - 1);
+ final byte front = (byte) (frontData.getVoidLight(IntLocation.id(x, y, z + 1)) - 1);
+ final byte back = (byte) (backData.getVoidLight(IntLocation.id(x, y, z - 1)) - 1);
+ final byte tb = (top > bottom ? top : bottom);
+ final byte lr = (left > right ? left : right);
+ final byte fb = (front > back ? front : back);
+ final byte tblr = (tb > lr ? tb : lr);
+ final byte fbc = (fb > current ? fb : current);
+ light.setVoidLight(id, (tblr > fbc ? tblr : fbc));
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/calc/LightData.java b/src/ru/olamedia/olacraft/world/calc/LightData.java
new file mode 100644
index 0000000..62a91fd
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/calc/LightData.java
@@ -0,0 +1,28 @@
+package ru.olamedia.olacraft.world.calc;
+
+public class LightData {
+ private byte[] light = new byte[4096];
+
+ public byte getVoidLight(short id) {
+ return (byte) (light[id] & 15);
+ }
+
+ public void setVoidLight(short id, byte value) {
+ if (value != getVoidLight(id)) {
+ // voidLightChanged = true;
+ }
+ light[id] = (byte) ((getEmitLight(id) << 4) | value);
+ }
+
+ public byte getEmitLight(short id) {
+ return (byte) ((light[id] >> 4) & 15);
+ }
+
+ public void setEmitLight(short id, byte value) {
+ light[id] = (byte) ((light[id] & 15) | (value << 4));
+ }
+
+ public void reset() {
+ light = null;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/calc/VisibilityCalculator.java b/src/ru/olamedia/olacraft/world/calc/VisibilityCalculator.java
new file mode 100644
index 0000000..3009697
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/calc/VisibilityCalculator.java
@@ -0,0 +1,99 @@
+package ru.olamedia.olacraft.world.calc;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.data.ChunkDataNeighbors;
+import ru.olamedia.olacraft.world.location.IntLocation;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class VisibilityCalculator {
+ /**
+ * Compute visibility ("visible" if any side have non-opaque neighbor)
+ * Leaving side blocks invisible. Use computeVisibility(WorldProvider) to
+ * compute visibility of side blocks
+ */
+ public static void precomputeVisibility(ChunkDataNeighbors neighbors) {
+ final VisibilityData v = neighbors.getCenter().getVisibility();
+ // first pass, make all blocks invisible, except side blocks
+ v.setAllInvisible();
+ // second pass, make some blocks visible
+ short id = 0;
+ for (byte x = 0; x <= 15; x++) {
+ for (byte y = 0; y <= 15; y++) {
+ for (byte z = 0; z <= 15; z++) {
+ if (!neighbors.isOpaque(id)) {
+ setVisible(v, (byte) (x - 1), y, z);
+ setVisible(v, (byte) (x + 1), y, z);
+ setVisible(v, x, (byte) (y - 1), z);
+ setVisible(v, x, (byte) (y + 1), z);
+ setVisible(v, x, y, (byte) (z - 1));
+ setVisible(v, x, y, (byte) (z + 1));
+ }
+ id++;
+ }
+ }
+ }
+ }
+
+ public static void computeVisibility(VisibilityData v, WorldProvider provider, ChunkData left, ChunkData right,
+ ChunkData top, ChunkData bottom, ChunkData front, ChunkData back) {
+ // compute left/right
+ byte x, y, z;
+ short id;
+ for (y = 0; y <= 15; y++) {
+ for (z = 0; z <= 15; z++) {
+ x = 15;
+ id = IntLocation.id(x, y, z);
+ if (!left.isOpaque(provider, id)) {
+ x = 0;
+ setVisible(v, x, y, z);
+ }
+ x = 0;
+ id = IntLocation.id(x, y, z);
+ if (!right.isOpaque(provider, id)) {
+ x = 15;
+ setVisible(v, x, y, z);
+ }
+ }
+ }
+ // top/bottom
+ for (x = 0; x <= 15; x++) {
+ for (z = 0; z <= 15; z++) {
+ y = 15;
+ id = IntLocation.id(x, y, z);
+ if (!bottom.isOpaque(provider, id)) {
+ y = 0;
+ setVisible(v, x, y, z);
+ }
+ y = 0;
+ id = IntLocation.id(x, y, z);
+ if (!top.isOpaque(provider, id)) {
+ y = 15;
+ setVisible(v, x, y, z);
+ }
+ }
+ }
+ // front/back
+ for (x = 0; x <= 15; x++) {
+ for (y = 0; y <= 15; y++) {
+ z = 15;
+ id = IntLocation.id(x, y, z);
+ if (!back.isOpaque(provider, id)) {
+ z = 0;
+ setVisible(v, x, y, z);
+ }
+ z = 0;
+ id = IntLocation.id(x, y, z);
+ if (!front.isOpaque(provider, id)) {
+ z = 15;
+ setVisible(v, x, y, z);
+ }
+ }
+ }
+ }
+
+ private static void setVisible(VisibilityData v, byte x, byte y, byte z) {
+ if (IntLocation.inRange(x, y, z)) {
+ v.setVisible(IntLocation.id(x, y, z));
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/calc/VisibilityData.java b/src/ru/olamedia/olacraft/world/calc/VisibilityData.java
new file mode 100644
index 0000000..3e61cb3
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/calc/VisibilityData.java
@@ -0,0 +1,30 @@
+package ru.olamedia.olacraft.world.calc;
+
+import ru.olamedia.math.OpenBitSet;
+
+public class VisibilityData {
+ private OpenBitSet visibility = new OpenBitSet(4096);
+
+ public void setVisible(short id) {
+ visibility.set(id);
+ }
+
+ public void setAllInvisible() {
+ for (short id = 0; id < 4096; id++) {
+ visibility.clear(id);
+ }
+ }
+
+ public void setInvisible(short id) {
+ visibility.clear(id);
+ }
+
+ public boolean isVisible(short id) {
+ return visibility.get(id);
+ }
+
+ public void reset() {
+ visibility = null;
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/calc/package-info.java b/src/ru/olamedia/olacraft/world/calc/package-info.java
new file mode 100644
index 0000000..ce047c7
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/calc/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.calc; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java b/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java
index d02999d..3da74f2 100644
--- a/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java
+++ b/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java
@@ -10,7 +10,7 @@ import ru.olamedia.olacraft.world.provider.WorldProvider;
public class BlockSlice implements Iterator<Block> {
protected WorldProvider provider;
- protected BlockLocation offset;
+ public BlockLocation offset;
protected int width;
protected int height;
protected int depth;
@@ -19,25 +19,31 @@ public class BlockSlice implements Iterator<Block> {
private int itY = 0;
private int itZ = 0;
+ private Block nearestPlaceholder = null;
+ Block nearestBlock = null;
+
public Block getNearest(MatrixCamera cam) {
+ nearestPlaceholder = null;
+ nearestBlock = null;
float notEmptyBlockDistance = Float.MAX_VALUE;
- Block nearestBlock = null;
while (hasNext()) {
Block b = next();
try {
if (!b.isEmpty()) {
- float d = b.getDistance(cam);
- //System.out.print("d: " + d + " ");
- if (d <= notEmptyBlockDistance) {
+ final float d = b.getDistance(cam);
+ if (d < notEmptyBlockDistance) {
notEmptyBlockDistance = d;
nearestBlock = b;
}
}
} catch (ChunkUnavailableException e) {
- //e.printStackTrace();
b.request();
}
}
+ if (null != nearestBlock) {
+ nearestPlaceholder = new Block(provider, nearestBlock.location.x + nearestBlock.nearestX,
+ nearestBlock.location.y + +nearestBlock.nearestY, nearestBlock.location.z + +nearestBlock.nearestZ);
+ }
return nearestBlock;
}
@@ -202,4 +208,8 @@ public class BlockSlice implements Iterator<Block> {
public void setCenter(float x, float y, float z) {
setCenter((int) x, (int) y, (int) z);
}
+
+ public Block getNearestPutBlock() {
+ return nearestPlaceholder;
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/chunk/Chunk.java b/src/ru/olamedia/olacraft/world/chunk/Chunk.java
index f390ebc..51b78c5 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.ChunkMesh;
import ru.olamedia.geom.SimpleQuadMesh;
-import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.blockRenderer.ChunkRenderer;
import ru.olamedia.olacraft.world.data.ChunkData;
import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.location.ChunkLocation;
@@ -9,9 +10,7 @@ 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;
@@ -19,28 +18,21 @@ public class Chunk extends BlockSlice {
public int visibleRight = 0;
public int visibleFront = 0;
public int visibleBack = 0;
+ public ChunkLocation location;
- public void render() {
- if (isMeshCostructed) {
- mesh.joglRender();
- } else if (usePrevMesh) {
- prevMesh.joglRender();
- }
+ public ChunkMesh mesh = new ChunkMesh();
+
+ public void render(int pass) {
+ mesh.render(pass);
}
public void invalidate() {
- if (null != mesh) {
- prevMesh = mesh;
- usePrevMesh = true;
- if (null != mesh) {
- mesh.restart();
- }
- }
- isMeshCostructed = false;
+ mesh.setValid(false);
}
- public Chunk(WorldProvider provider) {
+ public Chunk(WorldProvider provider, ChunkLocation location) {
super(provider, 16, 16, 16);
+ setLocation(location);
}
/**
@@ -98,159 +90,78 @@ public class Chunk extends BlockSlice {
// }
}
+ public void setMeshBrightness(ChunkData origin, ChunkData data, short id, boolean side) {
+ // data.calculateVoidLight(provider);
+ // float[] sunlight = Game.client.getScene().time.getClearColor();
+ // byte lv = data.getVoidLight(id);
+ // light = lightValues[lv];
+ // if (side && lv > 0) {
+ // light = lightValues[lv - 1];
+ // }
+ // lightR = light;// * sunlight[0];
+ // lightG = light;// * sunlight[1];
+ // lightB = light;// * sunlight[2];
+ }
+
+ public void setMeshBrightness(SimpleQuadMesh mesh, int x, int y, int z, ChunkData data, boolean side) {
+ if (x < 0) {
+ setMeshBrightness(data, provider.getChunk(data.location.getLeft()), ChunkData.ClampID(x, y, z), side);
+ } else if (x > 15) {
+ setMeshBrightness(data, provider.getChunk(data.location.getRight()), ChunkData.ClampID(x, y, z), side);
+ } else if (y < 0) {
+ setMeshBrightness(data, provider.getChunk(data.location.getBottom()), ChunkData.ClampID(x, y, z), side);
+ } else if (y > 15) {
+ setMeshBrightness(data, provider.getChunk(data.location.getTop()), ChunkData.ClampID(x, y, z), side);
+ } else if (z < 0) {
+ setMeshBrightness(data, provider.getChunk(data.location.getBack()), ChunkData.ClampID(x, y, z), side);
+ } else if (z > 15) {
+ setMeshBrightness(data, provider.getChunk(data.location.getFront()), ChunkData.ClampID(x, y, z), side);
+ } else {
+ setMeshBrightness(data, data, ChunkData.ID(x, y, z), side);
+ }
+ }
+
+ private float light = 0f;
+ private float lightR = 0f;
+ private float lightG = 0f;
+ private float lightB = 0f;
+ private static float[] lightValues = new float[] {//
+ 0.035f, // 0.035184372f, 0
+ 0.043980465f, // 1
+ 0.054975581f, // 2
+ 0.068719477f, // 3
+ 0.085899346f, // 4
+ 0.107374182f, // 5
+ 0.134217728f, // 6
+ 0.16777216f, // 7
+ 0.2097152f, // 8
+ 0.262144f, // 9
+ 0.32768f, // 10
+ 0.4096f, // 11
+ 0.512f, // 12
+ 0.64f, // 13
+ 0.8f, // 14
+ 1f // 15
+ };
+
public void setMeshColor(SimpleQuadMesh mesh, int x, int y, int z, boolean isSide) {
- float level = 1f;// ((float) getProvider().getBlockLightLevel(x, y, z) -
- // (isSide ? 2 : 0)) / 15.0f;
- mesh.setColor4f(level, level, level, 1);
+ mesh.setColor4f(lightR, lightG, lightB, 1);
if (y < 0) {
- mesh.setColor4f(0, 0, 1, 1);
+ // mesh.setColor4f(0, 0, 1, 1);
} else if (y > 30) {
- mesh.setColor4f(1, 1, 1, 1);
+ // mesh.setColor4f(1, 1, 1, 1);
} else {
- mesh.setColor4f(1, 1, 0, 1);
+ // mesh.setColor4f(1, 1, 0, 1);
}
}
/**
* @return the mesh
*/
- public SimpleQuadMesh getMesh() {
- if (!isAvailable()) {
- return null;
- }
- if (isMeshCostructed) {
- return mesh;
- }
- if (offset.y >= provider.getInfo().maxHeight) {
- isMeshCostructed = true;
- return null;
+ public void getMesh() {
+ if (!mesh.isCompiled()) {
+ ChunkRenderer.compile(this);
}
- if (offset.y < provider.getInfo().minHeight) {
- isMeshCostructed = true;
- return null;
- }
-
- 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);
- 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 {
- 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);
- if (cbase > 9 / 10) {
- cbase = (float) (9.0 / 10.0);
- }
- // cbase = (float) (9.0 / 10.0);
- float cred, cgreen, cblue;
- // cbase;
- cred = cgreen = cblue = getLightLevel256(x, y, z);
- if (x == 1) {
- mesh.setColor4f(1, 0, 0, 1);
- // red to the right
- }
- if (x == 0 || z == 0) {
- if (y == 6) {
- mesh.setColor4f(1, 0, 0, 1);
- } else if (y % 2 == 0) {
- mesh.setColor4f(1, 0, 1, 1);
- } else {
- mesh.setColor4f(1, 1, 0, 1);
- }
- }
- if (z == 1) {
- mesh.setColor4f(0, 0, 1, 1);
- // blue to the bottom
- }
- if (renderBottom(x, y, z)) {
- setMeshColor(mesh, x, y - 1, z, false);
- mesh.setTexture(grass.getBottomTexture());
- mesh.addBottomQuad();
- visibleBottom++;
- }
- if (renderTop(x, y, z)) {
- if (x == 15 || z == 15) {
- // debug: show through..
- } else {
- setMeshColor(mesh, x, y + 1, z, false);
- mesh.setTexture(grass.getTopTexture());
- mesh.addTopQuad();
- }
- visibleTop++;
- }
- if (renderLeft(x, y, z)) {
- setMeshColor(mesh, x - 1, y, z, true);
- mesh.setTexture(grass.getLeftTexture());
- mesh.addLeftQuad();
- visibleLeft++;
- }
- if (renderRight(x, y, z)) {
- setMeshColor(mesh, x + 1, y, z, true);
- mesh.setTexture(grass.getRightTexture());
- mesh.addRightQuad();
- visibleRight++;
- }
- if (renderBack(x, y, z)) {
- setMeshColor(mesh, x, y, z - 1, true);
- mesh.setTexture(grass.getBackTexture());
- mesh.addBackQuad();
- visibleBack++;
- }
- if (renderFront(x, y, z)) {
- setMeshColor(mesh, x, y, z + 1, true);
- mesh.setTexture(grass.getFrontTexture());
- mesh.addFrontQuad();
- visibleFront++;
- }
- // System.out.println("mesh not empty");
- } else {
- // System.out.println("mesh empty");
- }
- } catch (ChunkUnavailableException e) {
- e.printStackTrace();
- }
- }
- }
- }
- mesh.endMesh();
- data.visible = null;
- isMeshCostructed = true;
- return null;
- }
- return mesh;
- }
-
- /**
- * @param mesh
- * the mesh to set
- */
- public void setMesh(SimpleQuadMesh mesh) {
- this.mesh = mesh;
}
public boolean isEmpty() {
@@ -352,9 +263,22 @@ public class Chunk extends BlockSlice {
public void setLocation(ChunkLocation location) {
setLocation(location.getBlockLocation().x, location.getBlockLocation().y, location.getBlockLocation().z);
+ this.location = new ChunkLocation(location);
}
public boolean inWorldRange() {
return (offset.y + 16 < provider.getInfo().maxHeight) && (offset.y > provider.getInfo().minHeight);
}
+
+ public boolean meshInvalid = false;
+
+ public void markMeshInvalid() {
+ if (isMeshCostructed) {
+ meshInvalid = true;
+ }
+ }
+
+ public ChunkData getData() {
+ return provider.getChunk(location);
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java b/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java
index e823b2f..3ad2da2 100644
--- a/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java
+++ b/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java
@@ -2,9 +2,11 @@ package ru.olamedia.olacraft.world.chunk;
import java.util.concurrent.ArrayBlockingQueue;
+import ru.olamedia.olacraft.world.blockRenderer.ChunkRenderer;
+
public class ChunkMeshBulder extends Thread {
public static ChunkMeshBulder instance = new ChunkMeshBulder("Mesh builder");
- private ArrayBlockingQueue<Chunk> chunks = new ArrayBlockingQueue<Chunk>(256);
+ private ArrayBlockingQueue<Chunk> chunks = new ArrayBlockingQueue<Chunk>(16);
public ChunkMeshBulder(String name) {
super(name);
@@ -24,20 +26,19 @@ public class ChunkMeshBulder extends Thread {
public void tick() throws InterruptedException {
if (!chunks.isEmpty()) {
- Chunk chunk = chunks.take();
- chunk.getMesh();
+ ChunkRenderer.compile(chunks.take());
}
}
@Override
public void run() {
- // glc.makeCurrent();
while (true) {
// main loop
try {
tick();
- if (chunks.isEmpty()){
+ if (chunks.isEmpty()) {
Thread.sleep(50);
+ } else {
}
// Thread.sleep(10); // or wait/join etc
} catch (InterruptedException ex) {
diff --git a/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java b/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java
index 14e2c1f..909f0fe 100644
--- a/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java
+++ b/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java
@@ -12,6 +12,8 @@ public class ChunkSlice {
private int height;
private int depth;
+ public static ChunkSlice rendererInstance;
+
public ChunkSlice(WorldProvider provider, int width, int height, int depth) {
this.provider = provider;
this.width = width;
@@ -20,8 +22,7 @@ public class ChunkSlice {
offset = new ChunkLocation();
}
- 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 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;
@@ -43,8 +44,7 @@ public class ChunkSlice {
iChunks.get(location.x).put(location.y, new HashMap<Integer, Chunk>());
}
- Chunk chunk = new Chunk(provider);
- chunk.setLocation(location);
+ Chunk chunk = new Chunk(provider, location);
// chunks.put(key, chunk);
iChunks.get(location.x).get(location.y).put(location.z, chunk);
return chunk;
@@ -58,6 +58,16 @@ public class ChunkSlice {
// }
}
+ public void removeChunk(ChunkLocation location) {
+ if (iChunks.containsKey(location.x)) {
+ if (iChunks.get(location.x).containsKey(location.y)) {
+ if (iChunks.get(location.x).get(location.y).containsKey(location.z)) {
+ iChunks.get(location.x).get(location.y).remove(location.z);
+ }
+ }
+ }
+ }
+
/**
* @return the width
*/
@@ -133,4 +143,5 @@ public class ChunkSlice {
public void setLocation(ChunkLocation chunkOffset) {
offset = chunkOffset;
}
+
}
diff --git a/src/ru/olamedia/olacraft/world/chunk/ChunkUnavailableException.java b/src/ru/olamedia/olacraft/world/chunk/ChunkUnavailableException.java
index 9fef715..5fe81f6 100644
--- a/src/ru/olamedia/olacraft/world/chunk/ChunkUnavailableException.java
+++ b/src/ru/olamedia/olacraft/world/chunk/ChunkUnavailableException.java
@@ -1,6 +1,6 @@
package ru.olamedia.olacraft.world.chunk;
-public class ChunkUnavailableException extends Exception {
+public class ChunkUnavailableException extends RuntimeException {
private static final long serialVersionUID = -5382060550128159125L;
diff --git a/src/ru/olamedia/olacraft/world/data/ChunkData.java b/src/ru/olamedia/olacraft/world/data/ChunkData.java
index 42f7811..af703c0 100644
--- a/src/ru/olamedia/olacraft/world/data/ChunkData.java
+++ b/src/ru/olamedia/olacraft/world/data/ChunkData.java
@@ -1,28 +1,155 @@
package ru.olamedia.olacraft.world.data;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
import ru.olamedia.math.OpenBitSet;
-import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
import ru.olamedia.olacraft.world.chunk.Chunk;
+import ru.olamedia.olacraft.world.drop.DroppedEntity;
import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.location.IntLocation;
import ru.olamedia.olacraft.world.provider.WorldProvider;
+/**
+ * 1 bit for opaque
+ * if non-opaque, some left bits will be used for light, else can be used for
+ * meta
+ *
+ * Opaque blocks:
+ * stone/cobblestone/gravel/sand(dust) is a state, 2 bits
+ * dirt/peat
+ *
+ * Non-opaque:
+ * fluids: water, acid, lava
+ * glass
+ *
+ * trees etc is an entities, not the blocks
+ *
+ *
+ *
+ * @author olamedia
+ *
+ */
public class ChunkData implements Serializable {
private static final long serialVersionUID = -5704237444737895501L;
public ChunkLocation location;
- public static transient int SIZE = 4096;
+ private static transient int SIZE = 4096;
// private boolean[] notEmpty = new boolean[SIZE];
- public OpenBitSet emptyBlocks = new OpenBitSet(4096);
+ private 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);
+ // 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 boolean voidLightPrecomputed = false;
+ public boolean voidLightChanged = false;
+ private boolean compressionStarted = false;
+ private boolean isCompressed = false;
+ private byte[] compressed;
+ private ChunkDataPointer pointer = new ChunkDataPointer();
+ public HashMap<Integer, AbstractBlockType> timeManagedBlocks = new HashMap<Integer, AbstractBlockType>();
+ public ArrayList<DroppedEntity> droppedEntities = new ArrayList<DroppedEntity>();
+
+ public void invalidateComputations() {
+ visibilityPrecomputed = false;
+ voidLightPrecomputed = false;
+ }
+
+ public void detachBlock(short id) {
+ emptyBlocks.set(id);
+ types[id] = 0;
+ }
+
+ public void tick(WorldProvider provider) {
+
+ }
+
+ /**
+ * After populating with blocks, create entities
+ *
+ * @param provider
+ */
+ public void initBlockEntities(WorldProvider provider) {
+ pointer.reset();
+ while (pointer.hasNext()) {
+ if (!isEmpty(pointer.getId()) && types[pointer.getId()] != 0) {
+ AbstractBlockType type = provider.getTypeRegistry().getBlockType(types[pointer.getId()]);
+ // check if entity-managed block
+ // check if time-managed block
+ if (type.isTimeManaged()) {
+ timeManagedBlocks.put(pointer.getId(), type);
+ }
+ }
+ //
+ pointer.next();
+ }
+ }
+
+ public static short ID(int x, int y, int z) {
+ return (short) (x * 256 + y * 16 + z);
+ }
+
+ public static short ClampID(BlockLocation location) {
+ return location.getId();
+ }
+
+ public static short ClampID(int x, int y, int z) {
+ return ID(x & 15, y & 15, z & 15);
+ }
+
+ public void compress() {
+ if (!isCompressed && !compressionStarted) {
+ compressionStarted = true;
+ try {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ // GZIPOutputStream gzout = new GZIPOutputStream(bout);
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ out.writeObject(this);
+ compressed = bout.toByteArray();
+ types = null;
+ emptyBlocks = null;
+ out.close();
+ // gzout.close();
+ bout.close();
+ isCompressed = true;
+ } catch (IOException e) {
+ compressionStarted = false;
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public ChunkData decompress() {
+ if (isCompressed) {
+ try {
+ ByteArrayInputStream bin = new ByteArrayInputStream(compressed);
+ // GZIPInputStream gzin = new GZIPInputStream(new
+ // BufferedInputStream(bin));
+ ObjectInputStream in = new ObjectInputStream(bin);
+ ChunkData data = (ChunkData) in.readObject();
+ in.close();
+ // gzin.close();
+ bin.close();
+ return data;
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
// public transient int[] type = new int[SIZE];
@@ -30,22 +157,16 @@ public class ChunkData implements Serializable {
}
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)){
+ final short id = IntLocation.id(x, y, 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)){
+ final short id = IntLocation.id(x, y, z);
+ if (visible.get(id)) {
visibleCount--;
}
visible.clear(id);
@@ -54,27 +175,28 @@ public class ChunkData implements Serializable {
public void computeVisibility(WorldProvider provider) {
visible = new OpenBitSet(4096);
visibleCount = 0;
- precomputeVisibility();
- computeVisibility(provider.getChunk(location.getLeft()), provider.getChunk(location.getRight()),
+ precomputeVisibility(provider);
+ computeVisibility(provider, 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) {
+ public void computeVisibility(WorldProvider provider, ChunkData left, ChunkData right, ChunkData top,
+ ChunkData bottom, ChunkData front, ChunkData back) {
// compute left/right
- int x, y, z, id;
+ int x, y, z;
+ short 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)) {
+ id = IntLocation.id(x, y, z);
+ if (!left.isOpaque(provider, id)) {
x = 0;
setVisible(x, y, z);
}
x = 0;
- id = x * 16 * 16 + y * 16 + z;
- if (right.emptyBlocks.get(id)) {
+ id = IntLocation.id(x, y, z);
+ if (!right.isOpaque(provider, id)) {
x = 15;
setVisible(x, y, z);
}
@@ -84,14 +206,14 @@ public class ChunkData implements Serializable {
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)) {
+ id = IntLocation.id(x, y, z);
+ if (!bottom.isOpaque(provider, id)) {
y = 0;
setVisible(x, y, z);
}
y = 0;
- id = x * 16 * 16 + y * 16 + z;
- if (top.emptyBlocks.get(id)) {
+ id = IntLocation.id(x, y, z);
+ if (!top.isOpaque(provider, id)) {
y = 15;
setVisible(x, y, z);
}
@@ -101,14 +223,14 @@ public class ChunkData implements Serializable {
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)) {
+ id = IntLocation.id(x, y, z);
+ if (!back.isOpaque(provider, id)) {
z = 0;
setVisible(x, y, z);
}
z = 0;
- id = x * 16 * 16 + y * 16 + z;
- if (front.emptyBlocks.get(id)) {
+ id = IntLocation.id(x, y, z);
+ if (!front.isOpaque(provider, id)) {
z = 15;
setVisible(x, y, z);
}
@@ -118,9 +240,10 @@ public class ChunkData implements Serializable {
/**
* Compute visibility ("visible" if any side have non-opaque neighbor)
- * Leaving side blocks invisible. Use computeVisibility(WorldProvider) to compute visibility of side blocks
+ * Leaving side blocks invisible. Use computeVisibility(WorldProvider) to
+ * compute visibility of side blocks
*/
- public void precomputeVisibility() {
+ public void precomputeVisibility(WorldProvider provider) {
// first pass, make all blocks invisible, except side blocks
for (int x = 0; x <= 15; x++) {
for (int y = 0; y <= 15; y++) {
@@ -140,7 +263,7 @@ public class ChunkData implements Serializable {
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)) {
+ if (!isOpaque(provider, id)) {
setVisible(x - 1, y, z);
setVisible(x + 1, y, z);
setVisible(x, y - 1, z);
@@ -154,13 +277,17 @@ public class ChunkData implements Serializable {
visibilityPrecomputed = true;
}
+ public boolean isOpaque(WorldProvider provider, int id) {
+ return !isEmpty(id) && provider.getTypeRegistry().isOpaque(types[id]);
+ }
+
public void compact() {
- if (emptyBlocks.cardinality() == 0) {
+ if (notEmptyCount == 0) {
// emptyBlocks = null;
}
}
- public BlockType getType(BlockLocation blockLocation, WorldProvider provider) {
+ public AbstractBlockType getType(BlockLocation blockLocation, WorldProvider provider) {
if (emptyBlocks == null) {
return null;
}
@@ -215,4 +342,14 @@ public class ChunkData implements Serializable {
setEmpty(id, isEmpty);
}
+ public void freeRenderData() {
+ visible = null;
+ // light = null;
+ // voidLightPrecomputed = false;
+ }
+
+ public void addDroppedEntity(DroppedEntity droppedEntity) {
+ droppedEntities.add(droppedEntity);
+ }
+
}
diff --git a/src/ru/olamedia/olacraft/world/data/ChunkDataManager.java b/src/ru/olamedia/olacraft/world/data/ChunkDataManager.java
new file mode 100644
index 0000000..ba5b50a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/ChunkDataManager.java
@@ -0,0 +1,22 @@
+package ru.olamedia.olacraft.world.data;
+
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class ChunkDataManager {
+ private ChunkData data;
+ private ChunkDataPointer pointer = new ChunkDataPointer();
+ private WorldProvider provider;
+
+ public void setProvider(WorldProvider provider){
+ this.provider = provider;
+ }
+
+ public void setData(ChunkData data) {
+ this.data = data;
+ pointer.reset();
+ }
+
+ private void loadNeighbors(){
+
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/data/ChunkDataNeighbors.java b/src/ru/olamedia/olacraft/world/data/ChunkDataNeighbors.java
new file mode 100644
index 0000000..de82b5b
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/ChunkDataNeighbors.java
@@ -0,0 +1,162 @@
+package ru.olamedia.olacraft.world.data;
+
+import ru.olamedia.olacraft.world.calc.LightCalculator;
+import ru.olamedia.olacraft.world.calc.VisibilityCalculator;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class ChunkDataNeighbors {
+ private static byte CENTER = 0;
+ private static byte LEFT = 1;
+ private static byte RIGHT = 2;
+ private static byte TOP = 3;
+ private static byte BOTTOM = 4;
+ private static byte FRONT = 5;
+ private static byte BACK = 6;
+ private WorldProvider provider;
+ private ChunkLocation center;
+ private ChunkDataWrapper data;
+ private ChunkDataWrapper left;
+ private ChunkDataWrapper right;
+ private ChunkDataWrapper top;
+ private ChunkDataWrapper bottom;
+ private ChunkDataWrapper front;
+ private ChunkDataWrapper back;
+ private ChunkDataWrapper[] chunks;
+
+ public ChunkDataNeighbors() {
+ chunks = new ChunkDataWrapper[7];
+ for (byte i = 0; i < 7; i++) {
+ chunks[i] = new ChunkDataWrapper();
+ }
+ left = new ChunkDataWrapper();
+ right = new ChunkDataWrapper();
+ top = new ChunkDataWrapper();
+ bottom = new ChunkDataWrapper();
+ front = new ChunkDataWrapper();
+ back = new ChunkDataWrapper();
+ data = new ChunkDataWrapper();
+ center = new ChunkLocation();
+ }
+
+ public void setProvider(WorldProvider provider) {
+ this.provider = provider;
+ }
+
+ public void setData(ChunkData data) {
+ this.data.setData(data);
+ center.set(data.location);
+ chunks[CENTER].setData(data);
+ }
+
+ public void loadNeighbors() {
+ top.setData(provider.getChunk(center.getTop()));
+ bottom.setData(provider.getChunk(center.getBottom()));
+ left.setData(provider.getChunk(center.getLeft()));
+ right.setData(provider.getChunk(center.getRight()));
+ front.setData(provider.getChunk(center.getFront()));
+ back.setData(provider.getChunk(center.getBack()));
+ chunks[TOP].setData(top.getData());
+ chunks[BOTTOM].setData(bottom.getData());
+ chunks[LEFT].setData(left.getData());
+ chunks[RIGHT].setData(right.getData());
+ chunks[FRONT].setData(front.getData());
+ chunks[BACK].setData(back.getData());
+ }
+
+ public ChunkDataWrapper getCenter() {
+ return data;
+ }
+
+ public ChunkData getCenterData() {
+ return data.getData();
+ }
+
+ public ChunkDataWrapper getTop() {
+ return top;
+ }
+
+ public ChunkDataWrapper getBottom() {
+ return bottom;
+ }
+
+ public ChunkDataWrapper getLeft() {
+ return left;
+ }
+
+ public ChunkDataWrapper getRight() {
+ return right;
+ }
+
+ public ChunkDataWrapper getFront() {
+ return front;
+ }
+
+ public ChunkDataWrapper getBack() {
+ return back;
+ }
+
+ public ChunkData getTopData() {
+ return top.getData();
+ }
+
+ public ChunkData getBottomData() {
+ return bottom.getData();
+ }
+
+ public ChunkData getLeftData() {
+ return left.getData();
+ }
+
+ public ChunkData getRightData() {
+ return right.getData();
+ }
+
+ public ChunkData getFrontData() {
+ return front.getData();
+ }
+
+ public ChunkData getBackData() {
+ return back.getData();
+ }
+
+ public void calcLight() {
+ LightCalculator.calculateVoidLightIgnoreNeighbors(top);
+ LightCalculator.calculateVoidLightIgnoreNeighbors(bottom);
+ LightCalculator.calculateVoidLightIgnoreNeighbors(left);
+ LightCalculator.calculateVoidLightIgnoreNeighbors(right);
+ LightCalculator.calculateVoidLightIgnoreNeighbors(front);
+ LightCalculator.calculateVoidLightIgnoreNeighbors(back);
+ LightCalculator.precalculateVoidLight(data);
+ LightCalculator.spreadVoidLight(this);
+ }
+
+ public void reset() {
+ provider = null;
+ data.reset();
+ top.reset();
+ bottom.reset();
+ left.reset();
+ right.reset();
+ front.reset();
+ back.reset();
+ }
+
+ public ChunkLocation getLocation() {
+ return center;
+ }
+
+ public boolean isOpaque(short id) {
+ return !data.getData().isEmpty(id) && provider.getTypeRegistry().isOpaque(data.getData().types[id]);
+ }
+
+ public boolean isVisible(short id) {
+ return data.getVisibility().isVisible(id) && !data.getData().isEmpty(id) && (0 != data.getData().types[id]);
+ }
+
+ public void calcVisibility() {
+ VisibilityCalculator.precomputeVisibility(this);
+ VisibilityCalculator.computeVisibility(data.getVisibility(), provider, getLeftData(), getRightData(),
+ getTopData(), getBottomData(), getFrontData(), getBackData());
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/data/ChunkDataPointer.java b/src/ru/olamedia/olacraft/world/data/ChunkDataPointer.java
new file mode 100644
index 0000000..2c0f059
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/ChunkDataPointer.java
@@ -0,0 +1,82 @@
+package ru.olamedia.olacraft.world.data;
+
+import ru.olamedia.olacraft.world.chunk.Chunk;
+
+/**
+ * pointer.reset()
+ * while (pointer.hasNext()){
+ * int id = pointer.getId()
+ * ...
+ * pointer.next()
+ * }
+ * @author olamedia
+ *
+ */
+public class ChunkDataPointer {
+ private int x = 0;
+ private int y = 0;
+ private int z = 0;
+ private int id = 0;
+
+ public ChunkDataPointer() {
+ reset();
+ }
+
+ public ChunkDataPointer(int x, int y, int z) {
+ if (x >= 0 && x < 16) {
+ if (y >= 0 && y < 16) {
+ if (z >= 0 && z < 16) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ id = this.x * 16 * 16 + this.y * 16 + this.z;
+ return;
+ }
+ }
+ }
+ this.x = Chunk.in(x);
+ this.y = Chunk.in(y);
+ this.z = Chunk.in(z);
+ id = this.x * 16 * 16 + this.y * 16 + this.z;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public int getZ() {
+ return z;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void reset() {
+ x = 0;
+ y = 0;
+ z = 0;
+ id = 0;
+ }
+
+ public boolean hasNext() {
+ return id < 4096;
+ }
+
+ public void next() {
+ id++;
+ x++;
+ if (x > 15) {
+ x = 0;
+ y++;
+ if (y > 15) {
+ y = 0;
+ z++;
+ }
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/data/ChunkDataWrapper.java b/src/ru/olamedia/olacraft/world/data/ChunkDataWrapper.java
new file mode 100644
index 0000000..ae0f582
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/ChunkDataWrapper.java
@@ -0,0 +1,40 @@
+package ru.olamedia.olacraft.world.data;
+
+import ru.olamedia.math.OpenBitSet;
+import ru.olamedia.olacraft.world.calc.LightData;
+import ru.olamedia.olacraft.world.calc.VisibilityData;
+
+public class ChunkDataWrapper {
+ private ChunkData data;
+ private LightData light;
+ private VisibilityData visibility;
+
+ public ChunkDataWrapper() {
+ light = new LightData();
+ visibility = new VisibilityData();
+ }
+
+ public void setData(ChunkData data) {
+ this.data = data;
+ }
+
+ public ChunkData getData() {
+ return data;
+ }
+
+ public LightData getLight() {
+ return light;
+ }
+
+ public VisibilityData getVisibility() {
+ return visibility;
+ }
+
+ public void reset() {
+ data = null;
+ light.reset();
+ light = null;
+ visibility.reset();
+ visibility = null;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/data/RegionData.java b/src/ru/olamedia/olacraft/world/data/RegionData.java
index f58a424..cdc4497 100644
--- a/src/ru/olamedia/olacraft/world/data/RegionData.java
+++ b/src/ru/olamedia/olacraft/world/data/RegionData.java
@@ -24,10 +24,18 @@ public class RegionData implements Serializable {
public HeightMap heightMap = new HeightMap(256, 256);
public SectorData[][] sectorData = new SectorData[16][16];
- public RegionData(){
-
+ public RegionData() {
+
+ }
+
+ public void compress() {
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ sectorData[x][z].compress();
+ }
+ }
}
-
+
public void writeTo(OutputStream stream) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(stream);
out.writeObject(this);
@@ -50,7 +58,7 @@ public class RegionData implements Serializable {
public ChunkData getChunkData(ChunkLocation chunkLocation) {
SectorData sector = getSectorData(chunkLocation.getSectorLocation());
int y = Chunk.in(chunkLocation.y + 128); // minHeight = -128
- return sector.chunkData[y];
+ return sector.get(y);
}
public SectorData getSectorData(SectorLocation sectorLocation) {
@@ -58,4 +66,12 @@ public class RegionData implements Serializable {
int z = Chunk.in(sectorLocation.z);
return sectorData[x][z];
}
+
+ public void decompress() {
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ sectorData[x][z].decompress();
+ }
+ }
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/data/SectorData.java b/src/ru/olamedia/olacraft/world/data/SectorData.java
index 31526a7..76414d4 100644
--- a/src/ru/olamedia/olacraft/world/data/SectorData.java
+++ b/src/ru/olamedia/olacraft/world/data/SectorData.java
@@ -10,26 +10,56 @@ import ru.olamedia.olacraft.world.location.SectorLocation;
* @author olamedia
*
*/
-public class SectorData implements Serializable{
+public class SectorData implements Serializable {
private static final long serialVersionUID = 5304471397211814748L;
- public HeightMap heightMap = new HeightMap(16, 16); // locations of highest nonempty blocks
- public ChunkData[] chunkData = new ChunkData[16]; // 256/16 = 16
+ public HeightMap heightMap = new HeightMap(16, 16); // locations of highest
+ // nonempty blocks
+ protected ChunkData[] chunkData = new ChunkData[16]; // 256/16 = 16
public SectorLocation location;
- public SectorData(){
-
+ public SectorData() {
+
}
-
+
public static int yIndex(int y) {
return (y + 128) / 16;
- // 1: (-128 + 128) / 16 = 0
+ // 1: (-128 + 128) / 16 = 0
// ......
// 15: (-114 + 128) / 16 = 14/16 = 0
// 16: (-113 + 128) / 16 = 15/16 = 0
// 17: (-112 + 128) / 16 = 16/16 = 1
}
- public static SectorData generate(){
+
+ public static SectorData generate() {
SectorData data = new SectorData();
return data;
}
+
+ public void compress() {
+ /*
+ * for (int y = 0; y < 16; y++) {
+ * chunkData[y].compress();
+ * }
+ */
+ }
+
+ public void set(int y, ChunkData data) {
+ // data.compress();
+ chunkData[y] = data;
+ }
+
+ public ChunkData get(int y) {
+ /*
+ * if (chunkData[y].isCompressed){
+ * return chunkData[y].decompress();
+ * }
+ */
+ return chunkData[y];
+ }
+
+ public void decompress() {
+ for (int y = 0; y < 16; y++) {
+ // chunkData[y] = chunkData[y].decompress();
+ }
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java
index 1670ef3..495fae4 100644
--- a/src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java
+++ b/src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java
@@ -1,5 +1,6 @@
package ru.olamedia.olacraft.world.dataProvider;
+import ru.olamedia.olacraft.world.block.BlockRegistry;
import ru.olamedia.olacraft.world.data.ChunkData;
import ru.olamedia.olacraft.world.data.RegionData;
import ru.olamedia.olacraft.world.data.SectorData;
@@ -8,6 +9,13 @@ import ru.olamedia.olacraft.world.location.RegionLocation;
import ru.olamedia.olacraft.world.location.SectorLocation;
abstract public class AbstractChunkDataProvider {
+
+ protected BlockRegistry types;
+
+ public void setTypeRegistry(BlockRegistry types) {
+ this.types = types;
+ }
+
/**
* is data already available or we should wait
*
@@ -30,9 +38,9 @@ abstract public class AbstractChunkDataProvider {
* @param RegionLocation
*/
public void loadChunk(ChunkLocation chunkLocation) {
- //System.out.println("loadChunk(" + chunkLocation + ")");
+ // System.out.println("loadChunk(" + chunkLocation + ")");
this.loadRegion(chunkLocation.getRegionLocation());
- //System.out.println("loadChunk(" + chunkLocation + ")--");
+ // System.out.println("loadChunk(" + chunkLocation + ")--");
}
public void loadSector(SectorLocation sectorLocation) {
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java
index 1e6c0c1..d779a40 100644
--- a/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java
+++ b/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java
@@ -1,62 +1,69 @@
package ru.olamedia.olacraft.world.dataProvider;
+import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.world.block.BlockRegistry;
import ru.olamedia.olacraft.world.data.RegionData;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
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>();
+ private HashMap<RegionLocation, RegionData> regionMap = new HashMap<RegionLocation, RegionData>();
+
+ private RegionData current;
public CachedChunkDataProvider(AbstractChunkDataProvider provider) {
this.provider = provider;
+ this.provider.setTypeRegistry(types);
+ }
+
+ @Override
+ public void setTypeRegistry(BlockRegistry types) {
+ super.setTypeRegistry(types);
+ this.provider.setTypeRegistry(types);
}
private static boolean DEBUG = true;
private void debug(String s) {
if (DEBUG) {
- System.out.println("[CachedChunkDataProvider] " + s);
+ System.err.println("[CachedChunkDataProvider] " + s);
}
}
- @SuppressWarnings("unused")
- private void tick(String key) {
- ticks.put(key, 0);
- gc();
+ private boolean containsKey(RegionLocation l) {
+ return regionMap.containsKey(l);
}
- 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);
- }
- }
+ // private boolean containsKey(int x, int y, int z) {
+ // return regionMap.containsKey(x) && regionMap.get(x).containsKey(y) &&
+ // regionMap.get(x).get(y).containsKey(z);
+ // }
+
+ private void put(RegionLocation l, RegionData data) {
+ regionMap.put(l, data);
+ }
+
+ private RegionData get(RegionLocation l) {
+ return regionMap.get(l);
}
@Override
public boolean isRegionAvailable(RegionLocation regionLocation) {
- String key = regionLocation.toString();// regionLocation.x + "-" +
- if (regionMap.containsKey(key)) {
+ if (regionMap.containsKey(regionLocation)) {
return true;
}
+ debug("regions: " + regionMap.size() + "");
return provider.isRegionAvailable(regionLocation);
}
@Override
public void loadRegion(RegionLocation regionLocation) {
- String key = regionLocation.toString();
- // debug("loadRegion(" + regionLocation + ")");
- if (!regionMap.containsKey(key)) {
+ if (!containsKey(regionLocation)) {
provider.loadRegion(regionLocation);
} else {
debug("error: loadRegion(" + regionLocation + ") already in regionMap");
@@ -65,15 +72,37 @@ 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);
+ if (containsKey(regionLocation)) {
+ return get(regionLocation);
} else {
- RegionData data = provider.getRegion(regionLocation);
- regionMap.put(key, data);
- return data;
+ put(regionLocation, provider.getRegion(regionLocation));
+ gc();
+ return get(regionLocation);
}
}
+ public void unloadRegion(RegionLocation regionLocation) {
+ regionMap.remove(regionLocation);
+ }
+
+ private ArrayList<RegionLocation> gcKeys = new ArrayList<RegionLocation>();
+
+ public void gc() {
+ if (Game.instance.player != null && regionMap.size() > 4) {
+ final BlockLocation b = Game.instance.player.getCameraBlockLocation();
+ final RegionLocation r = b.getRegionLocation();
+ for (RegionLocation l : regionMap.keySet()) {
+ if ((l.x > r.x + 1) || (l.x < r.x - 1)) {
+ if ((l.z > r.z + 1) || (l.z < r.z - 1)) {
+ gcKeys.add(l);
+ }
+ }
+ }
+ for (RegionLocation l : gcKeys) {
+ unloadRegion(l);
+ }
+ gcKeys.clear();
+ regionMap.clear();
+ }
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java
index 887421f..4464b96 100644
--- a/src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java
+++ b/src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java
@@ -83,48 +83,50 @@ public class LocalChunkDataProvider extends AbstractChunkDataProvider {
@SuppressWarnings("unused")
@Override
public RegionData getRegion(RegionLocation regionLocation) {
- String filename = path + File.separator + regionLocation.getFilename();
- RegionData data = null;
- if (true) {
- return generateRegion(regionLocation);
- }
- File chunkFile = new File(filename);
- if (false && chunkFile.exists()) {
- InputStream in;
- try {
- FileInputStream fIn = new FileInputStream(chunkFile);
- in = new GZIPInputStream(fIn);
- data = RegionData.loadFrom(in);
- in.close();
- fIn.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- } else {
- data = generateRegion(regionLocation);
- OutputStream out;
- try {
- chunkFile.createNewFile();
- FileOutputStream fOut = new FileOutputStream(chunkFile);
- out = new GZIPOutputStream(fOut);
- data.writeTo(out);
- out.close();
- fOut.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return data;
+ // String filename = path + File.separator +
+ // regionLocation.getFilename();
+ // RegionData data = null;
+ return generateRegion(regionLocation);
+ // File chunkFile = new File(filename);
+ // if (false && chunkFile.exists()) {
+ // InputStream in;
+ // try {
+ // FileInputStream fIn = new FileInputStream(chunkFile);
+ // in = new GZIPInputStream(fIn);
+ // data = RegionData.loadFrom(in);
+ // in.close();
+ // fIn.close();
+ // } catch (FileNotFoundException e) {
+ // e.printStackTrace();
+ // } catch (IOException e) {
+ // e.printStackTrace();
+ // } catch (ClassNotFoundException e) {
+ // e.printStackTrace();
+ // }
+ // } else {
+ // data = generateRegion(regionLocation);
+ // OutputStream out;
+ // try {
+ // chunkFile.createNewFile();
+ // FileOutputStream fOut = new FileOutputStream(chunkFile);
+ // out = new GZIPOutputStream(fOut);
+ // data.writeTo(out);
+ // out.close();
+ // fOut.close();
+ // } catch (IOException e) {
+ // e.printStackTrace();
+ // }
+ // }
+ // return data;
}
+ RegionGenerator generator;
+
public RegionData generateRegion(RegionLocation regionLocation) {
- RegionData data = new RegionData();
+ final RegionData data = new RegionData();
data.location = regionLocation;
RegionGenerator generator = new RegionGenerator();
+ generator.setTypes(types);
try {
generator.setSeed(getSeed());
} catch (IOException e) {
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java
index 0c52ced..1f860d6 100644
--- a/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java
+++ b/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java
@@ -17,7 +17,7 @@ import ru.olamedia.olacraft.world.location.RegionLocation;
public class RemoteChunkDataProvider extends AbstractChunkDataProvider implements IPacketListener {
private GameClient client;
- private HashMap<String, RegionData> map = new HashMap<String, RegionData>();
+ private HashMap<RegionLocation, RegionData> map = new HashMap<RegionLocation, RegionData>();
private List<String> loading = new ArrayList<String>();
private List<RegionLocation> queue = new ArrayList<RegionLocation>();
@@ -51,14 +51,13 @@ public class RemoteChunkDataProvider extends AbstractChunkDataProvider implement
if (loading.contains(key)) {
return false;
}
- return map.containsKey(key);
+ return map.containsKey(regionLocation);
}
@Override
public RegionData getRegion(RegionLocation regionLocation) {
- String key = regionLocation.toString();
- RegionData data = map.get(key);
- map.remove(key);
+ RegionData data = map.get(regionLocation);
+ map.remove(regionLocation);
return data;
}
@@ -67,10 +66,10 @@ public class RemoteChunkDataProvider extends AbstractChunkDataProvider implement
if (p instanceof RegionDataPacket) {
debug("received packet [conn " + connection.getID() + "]: RegionDataPacket");
RegionData data = ((RegionDataPacket) p).data;
- System.out.println(data.sectorData[0][0].chunkData[15].isEmpty(0) + "");
- String key = data.location.toString();
- map.put(key, data);
- loading.remove(key);
+ data.decompress();
+ //System.out.println(data.sectorData[0][0].get(15).isEmpty(0) + "");
+ map.put(data.location, data);
+ loading.remove(data.location);
}
}
diff --git a/src/ru/olamedia/olacraft/world/drop/DroppedEntity.java b/src/ru/olamedia/olacraft/world/drop/DroppedEntity.java
new file mode 100644
index 0000000..0d2fede
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/drop/DroppedEntity.java
@@ -0,0 +1,17 @@
+package ru.olamedia.olacraft.world.drop;
+
+import ru.olamedia.olacraft.world.blockStack.BlockStack;
+import ru.olamedia.olacraft.world.blockTypes.AbstractBlockType;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.Location3f;
+
+public class DroppedEntity {
+ public DroppedEntity(BlockLocation location, AbstractBlockType type, int count) {
+ this.location = new Location3f(location);
+ this.location.addRandomOffset(0.4f);
+ stack = new BlockStack(type, count);
+ }
+
+ public Location3f location;
+ public BlockStack stack;
+}
diff --git a/src/ru/olamedia/olacraft/world/drop/package-info.java b/src/ru/olamedia/olacraft/world/drop/package-info.java
new file mode 100644
index 0000000..d349368
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/drop/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.drop; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/fluid/FluidLevel.java b/src/ru/olamedia/olacraft/world/fluid/FluidLevel.java
new file mode 100644
index 0000000..8e90e3c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/fluid/FluidLevel.java
@@ -0,0 +1,9 @@
+package ru.olamedia.olacraft.world.fluid;
+
+import java.util.HashMap;
+
+public class FluidLevel {
+ public HashMap<Integer, FluidLine> lines = new HashMap<Integer, FluidLine>();
+ public float fluidLevel = 1f;
+ public int size = 0;
+}
diff --git a/src/ru/olamedia/olacraft/world/fluid/FluidLine.java b/src/ru/olamedia/olacraft/world/fluid/FluidLine.java
new file mode 100644
index 0000000..9dc8d44
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/fluid/FluidLine.java
@@ -0,0 +1,56 @@
+package ru.olamedia.olacraft.world.fluid;
+
+import java.util.ArrayList;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class FluidLine {
+ public int y;
+ public int z;
+ public int start;
+ public int finish;
+ public int size;
+
+ public FluidLine(int x, int y, int z) {
+ this.start = this.finish = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public FluidLine(BlockLocation location) {
+ this.start = this.finish = location.x;
+ this.y = location.y;
+ this.z = location.z;
+ }
+
+ public ArrayList<FluidLine> getSideLines(WorldProvider provider) {
+ ArrayList<FluidLine> sideLines;
+ sideLines = getSideLines(provider, z + 1);
+ sideLines.addAll(getSideLines(provider, z - 1));
+ return sideLines;
+ }
+
+ public ArrayList<FluidLine> getSideLines(WorldProvider provider, int z) {
+ ArrayList<FluidLine> sideLines = new ArrayList<FluidLine>();
+ BlockLocation test = new BlockLocation(start, y, z);
+ boolean found = false;
+ FluidLine side = null;
+ while (test.x < finish) {
+ ChunkData data = provider.getChunk(test.getChunkLocation());
+ if (data.isEmpty(test)) {
+ found = true;
+ side = new FluidLine(test);
+ } else {
+ if (found) {
+ side.finish = test.x;
+ sideLines.add(side);
+ found = false;
+ }
+ }
+ test.x++;
+ }
+ return sideLines;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/fluid/FluidSource.java b/src/ru/olamedia/olacraft/world/fluid/FluidSource.java
new file mode 100644
index 0000000..17bffe8
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/fluid/FluidSource.java
@@ -0,0 +1,99 @@
+package ru.olamedia.olacraft.world.fluid;
+
+import java.util.HashMap;
+import java.util.List;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class FluidSource {
+ public HashMap<Integer, FluidLevel> levels = new HashMap<Integer, FluidLevel>();
+ int minY = 0;
+ int maxY = 0;
+
+ public FluidSource(int y) {
+ minY = y;
+ maxY = y;
+ }
+
+ public void flow(WorldProvider provider, BlockLocation location, float amount) {
+ ChunkData data = provider.getChunk(location.getChunkLocation());
+ if (!data.isEmpty(location)) {
+ return;
+ }
+ FluidLevel level = null;
+ int y = location.y;
+ while (null == level || amount > 0) {
+ level = getFluidLevel(provider, location);
+ if (null == level) {
+ return;
+ }
+ if (level.size < amount) {
+ level.fluidLevel = 1f;
+ amount--;
+ } else {
+ level.fluidLevel = ((float) level.size) / amount;
+ }
+ levels.put(y, level);
+ y++;
+ }
+ }
+
+ private FluidLevel getFluidLevel(WorldProvider provider, BlockLocation location) {
+ ChunkData data = provider.getChunk(location.getChunkLocation());
+ if (!data.isEmpty(location)) {
+ return null;
+ }
+ FluidLevel level = new FluidLevel();
+ FluidLine startLine = getFluidLine(provider, location);
+
+ if (location.z > 0) {
+ BlockLocation test = new BlockLocation(location);
+ for (test.z = location.z - 1; test.z >= 0; test.z--) {
+ test.x = startLine.start;
+ FluidLine nextLine = getFluidLine(provider, test);
+ if (null != nextLine) {
+ test.x = nextLine.finish + 2;
+ if (test.x <= 15) {
+ // continue
+ }else{
+ //
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private FluidLine getFluidLine(WorldProvider provider, BlockLocation location) {
+ ChunkData data = provider.getChunk(location.getChunkLocation());
+ if (!data.isEmpty(location)) {
+ return null;
+ }
+ FluidLine line = new FluidLine(location);
+ line.start = line.finish = location.x;
+ BlockLocation test = new BlockLocation(location);
+ if (location.x > 0) {
+ for (test.x = location.x - 1; test.x >= 0; test.x--) {
+ if (!data.isEmpty(test)) {
+ break;
+ }
+ line.start = test.x;
+ }
+ } else {
+ line.start = 0;
+ }
+ if (location.x < 15) {
+ for (test.x = location.x + 1; test.x <= 15; test.x++) {
+ if (!data.isEmpty(test)) {
+ break;
+ }
+ line.finish = test.x;
+ }
+ } else {
+ line.finish = 15;
+ }
+ return line;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/fluid/package-info.java b/src/ru/olamedia/olacraft/world/fluid/package-info.java
new file mode 100644
index 0000000..d2764d9
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/fluid/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.fluid; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/generator/HeightMapGenerator.java b/src/ru/olamedia/olacraft/world/generator/HeightMapGenerator.java
index 649961f..5d6d0d5 100644
--- a/src/ru/olamedia/olacraft/world/generator/HeightMapGenerator.java
+++ b/src/ru/olamedia/olacraft/world/generator/HeightMapGenerator.java
@@ -1,6 +1,5 @@
package ru.olamedia.olacraft.world.generator;
-import ru.olamedia.olacraft.world.chunk.Chunk;
import ru.olamedia.olacraft.world.data.HeightMap;
import ru.olamedia.olacraft.world.location.RegionLocation;
import libnoiseforjava.NoiseGen.NoiseQuality;
@@ -58,7 +57,7 @@ public class HeightMapGenerator {
// MOUNTAINS
mountainsNoise = new RidgedMulti();
mountainsNoise.setFrequency(0.04);
- mountainsNoise.setOctaveCount(6);
+ mountainsNoise.setOctaveCount(4);
turbulence = new Turbulence(mountainsNoise);
turbulence.setFrequency(0.2);
turbulence.setPower(1);
@@ -105,7 +104,7 @@ public class HeightMapGenerator {
// finalTerrain.setEdgeFalloff(1.25);
NoiseMap heightMap = new NoiseMap(16, 16);
- builder.setSourceModule(maxTerrain);
+ builder.setSourceModule(blendedTerrain);
builder.setDestNoiseMap(heightMap);
double bx = chunkX;
double bz = chunkZ;
@@ -118,7 +117,7 @@ public class HeightMapGenerator {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
// System.out.print(((float) heights[x][z]) + ";");
- ints[x][z] = (int) (50 + minValue + (maxValue - minValue) * (heights[x][z] + 1) / 2);
+ ints[x][z] = (int) (minValue + (maxValue - minValue) * (heights[x][z] + 1) / 2);
}
}
// System.out.println("");
@@ -138,8 +137,6 @@ public class HeightMapGenerator {
builder.setSourceModule(finalTerrain);
builder.setDestNoiseMap(heightMap);
builder.setDestSize(256, 256);
- float bx = location.getBlockLocation().x;
- float bz = location.getBlockLocation().z;
float cx = location.getChunkLocation().x;
float cz = location.getChunkLocation().z;
builder.setBounds(cx, cx + 16, cz, cz + 16);
diff --git a/src/ru/olamedia/olacraft/world/generator/HumiditySelectLayer.java b/src/ru/olamedia/olacraft/world/generator/HumiditySelectLayer.java
new file mode 100644
index 0000000..63d25c6
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/HumiditySelectLayer.java
@@ -0,0 +1,31 @@
+package ru.olamedia.olacraft.world.generator;
+
+import libnoiseforjava.NoiseGen.NoiseQuality;
+import libnoiseforjava.exception.ExceptionInvalidParam;
+import libnoiseforjava.module.Perlin;
+import libnoiseforjava.module.RidgedMulti;
+
+public class HumiditySelectLayer {
+ protected long seed;
+
+ protected Perlin noise = new Perlin();
+ //protected RidgedMulti noise = new RidgedMulti();
+
+ public HumiditySelectLayer() {
+ noise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ try {
+ noise.setOctaveCount(5);
+ noise.setFrequency(0.004);
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void setSeed(int seed) {
+ noise.setSeed(seed);
+ }
+
+ public double getHumidity(double x, double z) {
+ return noise.getValue(x, 0, z);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/generator/IslandSelectLayer.java b/src/ru/olamedia/olacraft/world/generator/IslandSelectLayer.java
new file mode 100644
index 0000000..facfc3b
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/IslandSelectLayer.java
@@ -0,0 +1,31 @@
+package ru.olamedia.olacraft.world.generator;
+
+import libnoiseforjava.NoiseGen.NoiseQuality;
+import libnoiseforjava.exception.ExceptionInvalidParam;
+import libnoiseforjava.module.Perlin;
+import libnoiseforjava.module.RidgedMulti;
+
+public class IslandSelectLayer {
+ protected long seed;
+
+ protected Perlin noise = new Perlin();
+ //protected RidgedMulti noise = new RidgedMulti();
+
+ public IslandSelectLayer() {
+ noise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ try {
+ noise.setOctaveCount(5);
+ noise.setFrequency(0.004);
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void setSeed(int seed) {
+ noise.setSeed(seed);
+ }
+
+ public double getHeight(double x, double z) {
+ return noise.getValue(x, 0, z);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/generator/MountainSelectLayer.java b/src/ru/olamedia/olacraft/world/generator/MountainSelectLayer.java
new file mode 100644
index 0000000..5c0390f
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/MountainSelectLayer.java
@@ -0,0 +1,38 @@
+package ru.olamedia.olacraft.world.generator;
+
+import libnoiseforjava.NoiseGen.NoiseQuality;
+import libnoiseforjava.exception.ExceptionInvalidParam;
+import libnoiseforjava.module.Perlin;
+import libnoiseforjava.module.RidgedMulti;
+
+public class MountainSelectLayer {
+ protected long seed;
+
+ protected Perlin mountainNoise = new Perlin();
+ protected Perlin hillNoise = new Perlin();
+
+ public MountainSelectLayer() {
+ hillNoise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ mountainNoise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ try {
+ hillNoise.setOctaveCount(5);
+ hillNoise.setFrequency(0.004);
+ mountainNoise.setOctaveCount(7);
+ mountainNoise.setFrequency(0.004);
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void setSeed(int seed) {
+ hillNoise.setSeed(seed);
+ mountainNoise.setSeed(seed);
+ }
+
+ private double val;
+
+ public double getHeight(double x, double z) {
+ val = mountainNoise.getValue(x, 0, z);
+ return (val > 0) ? 1 - val : 1 + val;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/generator/OceanSelectLayer.java b/src/ru/olamedia/olacraft/world/generator/OceanSelectLayer.java
new file mode 100644
index 0000000..f0ca567
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/OceanSelectLayer.java
@@ -0,0 +1,31 @@
+package ru.olamedia.olacraft.world.generator;
+
+import libnoiseforjava.NoiseGen.NoiseQuality;
+import libnoiseforjava.exception.ExceptionInvalidParam;
+import libnoiseforjava.module.Perlin;
+import libnoiseforjava.module.RidgedMulti;
+
+public class OceanSelectLayer {
+ protected long seed;
+
+ protected Perlin noise = new Perlin();
+ //protected RidgedMulti noise = new RidgedMulti();
+
+ public OceanSelectLayer() {
+ noise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ try {
+ noise.setOctaveCount(5);
+ noise.setFrequency(0.0004);
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void setSeed(int seed) {
+ noise.setSeed(seed);
+ }
+
+ public double getHeight(double x, double z) {
+ return noise.getValue(x, 0, z);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java b/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java
index 79ac898..8156b65 100644
--- a/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java
+++ b/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java
@@ -1,5 +1,18 @@
package ru.olamedia.olacraft.world.generator;
+import java.nio.IntBuffer;
+import java.util.Random;
+
+import libnoiseforjava.exception.ExceptionInvalidParam;
+import libnoiseforjava.module.Perlin;
+import ru.olamedia.olacraft.world.biome.Biome;
+import ru.olamedia.olacraft.world.block.BlockRegistry;
+import ru.olamedia.olacraft.world.blockTypes.GrassBlockType;
+import ru.olamedia.olacraft.world.blockTypes.IceBlockType;
+import ru.olamedia.olacraft.world.blockTypes.SnowBlockType;
+import ru.olamedia.olacraft.world.blockTypes.TallGrassBlockType;
+import ru.olamedia.olacraft.world.blockTypes.WaterBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.SandstoneStoneBlockType;
import ru.olamedia.olacraft.world.chunk.Chunk;
import ru.olamedia.olacraft.world.data.ChunkData;
import ru.olamedia.olacraft.world.data.HeightMap;
@@ -7,10 +20,23 @@ import ru.olamedia.olacraft.world.data.RegionData;
import ru.olamedia.olacraft.world.data.SectorData;
import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.location.IntLocation;
import ru.olamedia.olacraft.world.location.SectorLocation;
public class RegionGenerator {
private int[] seed;
+ private Random rand;
+
+ private OceanSelectLayer oceanSelect = new OceanSelectLayer();
+ private IslandSelectLayer islandSelect = new IslandSelectLayer();
+ private TemperatureSelectLayer tempSelect = new TemperatureSelectLayer();
+ private HumiditySelectLayer humSelect = new HumiditySelectLayer();
+ private RiverSelectLayer riverSelect = new RiverSelectLayer();
+ private MountainSelectLayer mountainSelect = new MountainSelectLayer();
+ private BlockRegistry types;
+
+ private byte waterId;
+ private byte iceId;
public void setSeed(int[] seed) {
this.seed = seed;
@@ -20,13 +46,229 @@ public class RegionGenerator {
System.out.println("[RegionGenerator] " + s);
}
+ private int[] heightCache;
+ private double[] temps;
+ private double[] hums;
+ private int[] biome;
+ private boolean[] initialized;
+ private boolean[] water;
+
+ protected Perlin erosionNoise = new Perlin();
+
+ public double avg(double a, double b) {
+ return (a + b) / 2;
+ }
+
+ public double blend(double... args) {
+ double x = 0;
+ for (int i = 0; i < args.length; i++) {
+ x += args[i];
+ }
+ return x / args.length;
+ }
+
+ public int getHeight(int vid, int x, int z) { // vid - vertical id
+ if (!initialized[vid]) {
+ double height = 0;
+ double oceanHeight = Math.min(0, oceanSelect.getHeight(x, z) * 100);
+ double isleHeight = islandSelect.getHeight(x, z) * 4;
+ double riverHeight = riverSelect.getHeight(x, z) * 15;
+ double temp = 10;// tempSelect.getTemperature(x, z) * 40; // -40..40
+ double humidity = humSelect.getHumidity(x, z) * 50 + 50; // 0..100
+ double mountain = mountainSelect.getHeight(x, z) * 20;
+ temps[vid] = temp;
+ hums[vid] = humidity;
+ height = mountain;// blend(oceanHeight, isleHeight);
+ if (oceanHeight < 0) {
+ water[vid] = true;
+ height = (int) Math.max(-120, oceanHeight);
+ } else {
+ water[vid] = false;
+ // height = (int) Math.max(0, avg(oceanHeight, avg(isleHeight,
+ // avg(oceanHeight, mountain))));
+ }
+
+ biome[vid] = Biome.land;
+ //
+ // if (oceanHeight > 0) {
+ // // materic
+ // biome[vid] = Biome.land;
+ // height = isleHeight;
+ // if (mountain > 1) {
+ // height = isleHeight;
+ // }
+ // if (riverHeight < 0) {
+ // // RIVERS
+ // water[vid] = true;
+ // height = riverHeight;
+ // } else {
+ // if (temp > 30) {
+ // biome[vid] = Biome.desert;
+ // }
+ // }
+ // } else {
+ // if (isleHeight > 0) {
+ // // island core
+ // height = 2;
+ // biome[vid] = Biome.island;
+ // } else if (oceanHeight > -3 && isleHeight > -10) {
+ // // half-island merged
+ // height = 1;
+ // biome[vid] = Biome.island;
+ // } else {
+ // water[vid] = true;
+ // height = -2;
+ // }
+ // }
+
+ // return (int) height;
+ heightCache[vid] = (int) height;
+ initialized[vid] = true;
+ }
+ return heightCache[vid];
+ }
+
+ public static int clampFloat(float x, float min, float max) { // x in -1..1
+ return (int) (min + (max - min) * ((1 + x) / 2));
+ }
+
+ // BlockLocation blockOffset = new BlockLocation();
+
+ private IntBuffer blockLocation = IntLocation.allocate();
+ private IntBuffer blockOffset = IntLocation.allocate();
+ private IntBuffer chunkLocation = IntLocation.allocate();
+ private IntBuffer chunkOffset = IntLocation.allocate();
+
+ public void generateSector(SectorData sector) {
+ heightCache = new int[256];
+ temps = new double[256];
+ hums = new double[256];
+ biome = new int[256];
+ initialized = new boolean[256];
+ water = new boolean[256];
+ for (int i = 0; i < 256; i++) {
+ initialized[i] = false;
+ water[i] = false;
+ }
+ sector.heightMap = new HeightMap(16, 16);
+ for (int y = 0; y < 16; y++) {
+ // CREATE CHUNK
+ final ChunkData chunk = new ChunkData();
+ chunk.location = new ChunkLocation(sector.location.x, y, sector.location.z);
+ IntLocation.set(chunkLocation, sector.location.x, y, sector.location.z);
+ IntLocation.chunk2block(chunkLocation, chunkOffset);
+ // final BlockLocation chunkOffset =
+ // chunk.location.getBlockLocation();
+ for (int inChunkX = 0; inChunkX < 16; inChunkX++) {
+ for (int inChunkZ = 0; inChunkZ < 16; inChunkZ++) {
+ final int vid = inChunkX * 16 + inChunkZ;
+ final int height = getHeight(vid, sector.location.x * 16 + inChunkX, sector.location.z * 16
+ + inChunkZ);
+ // int height = 60;
+ // System.out.println("height: " + height);
+ sector.heightMap.setHeight(inChunkX, inChunkZ, height);
+ IntLocation.setXZ(blockOffset, inChunkX, inChunkZ);
+ for (int inChunkY = 0; inChunkY < 16; inChunkY++) {
+ IntLocation.setY(blockOffset, inChunkY);
+ IntLocation.setSum(blockLocation, chunkOffset, blockOffset);
+ blockID = IntLocation.id(blockLocation);
+ // height = sector.heightMap.getHeight(inChunkX,
+ // inChunkZ);
+ makeBlock(chunk, vid);
+
+ }
+ }
+ }
+ // debug(sector.heightMap.toString());
+ chunk.compact();
+ sector.set(y, chunk);
+ }
+ }
+
+ private int blockHeight;
+ private int blockY;
+ private int blockID;
+
+ private void makeBlock(ChunkData chunk, int vid) {
+ if (null == types) {
+ throw new RuntimeException("types is null");
+ }
+ blockHeight = getHeight(vid, 0, 0); // coordinates makes no difference
+ // as
+ // cached already
+ blockY = IntLocation.getY(blockLocation);
+ blockID = IntLocation.id(blockLocation);
+ /*
+ * double erosion = erosionNoise.getValue(blockOffset.x, blockOffset.y,
+ * blockOffset.z);
+ * if (erosion > 0.99) {
+ * chunk.setEmpty(blockOffset, true);
+ * return;
+ * }
+ */
+ // WATER:
+ if (blockY <= 0) {
+ if (water[vid]) {
+ if (blockY > blockHeight) {
+ chunk.setEmpty(blockID, false);
+ chunk.types[blockID] = waterId;
+ if (temps[vid] < -10) {
+ chunk.types[blockID] = iceId;
+ }
+ return;
+ }
+ }
+ }
+ if (blockY > blockHeight) {
+ // AIR
+ chunk.setEmpty(blockID, true);
+ if (blockY - 1 == blockHeight) {
+ // floor level
+ if (temps[vid] > 15 && temps[vid] < 25 && hums[vid] > 30 && hums[vid] < 70) {
+ if (rand.nextInt(15) > 2) {
+ chunk.setEmpty(blockID, false);
+ chunk.types[blockID] = (byte) (types.getBlockIdByClassName(TallGrassBlockType.class.getName())); // FIXME,
+ }
+ }
+ }
+ } else {
+ // LAND
+ chunk.setEmpty(blockID, false);
+ if (temps[vid] > 30) {
+ chunk.types[blockID] = (byte) types.getBlockIdByClassName(SandstoneStoneBlockType.class.getName());
+ } else if (temps[vid] < -10 && hums[vid] > 30) {
+ chunk.types[blockID] = (byte) (types.getBlockIdByClassName(SnowBlockType.class.getName())); // FIXME,
+ // SNOW
+ } else {
+ chunk.types[blockID] = (byte) (types.getBlockIdByClassName(GrassBlockType.class.getName()));// (1
+ // +
+ // Math.random()
+ // *
+ // 11);
+ }
+ }
+ }
+
public void generate(RegionData data) {
+ final SectorLocation sectorOffset = data.location.getSectorLocation();
HeightMapGenerator.minValue = -5;
HeightMapGenerator.maxValue = 60;
HeightMapGenerator.init();
HeightMapGenerator.seed = seed[0];
+ oceanSelect.setSeed(seed[0]);
+ islandSelect.setSeed(seed[1]);
+ tempSelect.setSeed(seed[2]);
+ humSelect.setSeed(seed[3]);
+ riverSelect.setSeed(seed[4]);
+ rand = new Random(seed[6]);
+ erosionNoise.setFrequency(0.01);
+ try {
+ erosionNoise.setOctaveCount(5);
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ erosionNoise.setSeed(seed[5]);
// BlockLocation blockOffset = data.location.getBlockLocation();
- SectorLocation sectorOffset = data.location.getSectorLocation();
// int[][] heightMap =
// HeightMapGenerator.getHeightMap(data.location.getBlockLocation().x,
// data.location.getBlockLocation().z, 256, 256);
@@ -37,51 +279,41 @@ public class RegionGenerator {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
// CREATE SECTOR
- SectorData sector = new SectorData();
+ final SectorData sector = new SectorData();
sector.location = new SectorLocation(sectorOffset.x + x, sectorOffset.z + z);
- sector.heightMap = new HeightMap(16, 16);
- sector.chunkData = new ChunkData[16];
- for (int y = 0; y < 16; y++) {
- // CREATE CHUNK
- ChunkData chunk = new ChunkData();
- chunk.location = new ChunkLocation(sector.location.x, y, sector.location.z);
- BlockLocation chunkOffset = chunk.location.getBlockLocation();
- for (int inChunkX = 0; inChunkX < 16; inChunkX++) {
- for (int inChunkZ = 0; inChunkZ < 16; inChunkZ++) {
- int height = data.heightMap.getHeight(x * 16 + inChunkX, z * 16 + inChunkZ);
- // System.out.println("height: " + height);
- sector.heightMap.setHeight(inChunkX, inChunkZ, height);
- BlockLocation blockOffset = new BlockLocation();
- blockOffset.x = chunkOffset.x + inChunkX;
- blockOffset.z = chunkOffset.z + inChunkZ;
- for (int inChunkY = 0; inChunkY < 16; inChunkY++) {
- blockOffset.y = chunkOffset.y + inChunkY;
- // height = sector.heightMap.getHeight(inChunkX,
- // inChunkZ);
- if (blockOffset.y > height) {
- // System.out.println("--- height: " +
- // height + " block:" + blockOffset);
- chunk.setEmpty(blockOffset, true);
- } else {
- if (blockOffset.y > 0) {
- // System.out.println("+++ height: " +
- // height + " block:" + blockOffset);
- // 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);
- }
- }
- }
- }
- chunk.compact();
- sector.chunkData[y] = chunk;
- }
+ generateSector(sector);
data.sectorData[x][z] = sector;
}
}
}
+
+ public void setTypes(BlockRegistry types) {
+ this.types = types;
+ waterId = (byte) types.getBlockIdByClassName(WaterBlockType.class.getName());
+ iceId = (byte) types.getBlockIdByClassName(IceBlockType.class.getName());
+ }
+
+ public static float lerp(float x, float x1, float x2, float q00, float q01) {
+ return ((x2 - x) / (x2 - x1)) * q00 + ((x - x1) / (x2 - x1)) * q01;
+ }
+
+ public static float biLerp(float x, float y, float q11, float q12, float q21, float q22, float x1, float x2,
+ float y1, float y2) {
+ float r1 = lerp(x, x1, x2, q11, q21);
+ float r2 = lerp(x, x1, x2, q12, q22);
+
+ return lerp(y, y1, y2, r1, r2);
+ }
+
+ public static float triLerp(float x, float y, float z, float q000, float q001, float q010, float q011, float q100,
+ float q101, float q110, float q111, float x1, float x2, float y1, float y2, float z1, float z2) {
+ float x00 = lerp(x, x1, x2, q000, q100);
+ float x10 = lerp(x, x1, x2, q010, q110);
+ float x01 = lerp(x, x1, x2, q001, q101);
+ float x11 = lerp(x, x1, x2, q011, q111);
+ float r0 = lerp(y, y1, y2, x00, x01);
+ float r1 = lerp(y, y1, y2, x10, x11);
+
+ return lerp(z, z1, z2, r0, r1);
+ }
}
diff --git a/src/ru/olamedia/olacraft/world/generator/RiverSelectLayer.java b/src/ru/olamedia/olacraft/world/generator/RiverSelectLayer.java
new file mode 100644
index 0000000..a7b7c3e
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/RiverSelectLayer.java
@@ -0,0 +1,56 @@
+package ru.olamedia.olacraft.world.generator;
+
+import libnoiseforjava.NoiseGen.NoiseQuality;
+import libnoiseforjava.exception.ExceptionInvalidParam;
+import libnoiseforjava.module.Perlin;
+import libnoiseforjava.module.RidgedMulti;
+
+public class RiverSelectLayer {
+
+ protected Perlin noise = new Perlin();
+ protected Perlin widthNoise = new Perlin();
+ protected Perlin deepNoise = new Perlin();
+
+ // protected RidgedMulti noise = new RidgedMulti();
+
+ public RiverSelectLayer() {
+ noise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ widthNoise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ deepNoise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ try {
+ noise.setOctaveCount(5);
+ noise.setFrequency(0.000004);
+ widthNoise.setOctaveCount(6);
+ widthNoise.setFrequency(0.004);
+ deepNoise.setOctaveCount(3);
+ deepNoise.setFrequency(0.004);
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void setSeed(int seed) {
+ noise.setSeed(seed);
+ widthNoise.setSeed(seed);
+ deepNoise.setSeed(seed);
+ }
+
+ static double min = -0.0005;
+ static double max = 0;
+ private static double deepFactor = 0;
+
+ public static double scale(double value) {
+ final double factor = 1 / (max - min);
+ final double r01 = (value - min) * factor; // 0..1
+ final double r3 = r01 > 0.5 ? -r01 : -r01;
+ return -(1 - Math.abs(1 - r01 * 2)) * deepFactor;
+ }
+
+ public double getHeight(double x, double z) {
+ final double widthFactor = widthNoise.getValue(x, 0, z);
+ deepFactor = (deepNoise.getValue(x, 0, z) + 1.2) / 2.2;
+ min = -0.000005 * (1 + (1 + widthFactor) * 40);
+ final double value = noise.getValue(x, 0, z);
+ return value >= min && value <= max ? scale(value) : 0;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/generator/TemperatureSelectLayer.java b/src/ru/olamedia/olacraft/world/generator/TemperatureSelectLayer.java
new file mode 100644
index 0000000..ca3902f
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/TemperatureSelectLayer.java
@@ -0,0 +1,31 @@
+package ru.olamedia.olacraft.world.generator;
+
+import libnoiseforjava.NoiseGen.NoiseQuality;
+import libnoiseforjava.exception.ExceptionInvalidParam;
+import libnoiseforjava.module.Perlin;
+import libnoiseforjava.module.RidgedMulti;
+
+public class TemperatureSelectLayer {
+ protected long seed;
+
+ protected Perlin noise = new Perlin();
+ //protected RidgedMulti noise = new RidgedMulti();
+
+ public TemperatureSelectLayer() {
+ noise.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ try {
+ noise.setOctaveCount(5);
+ noise.setFrequency(0.004);
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void setSeed(int seed) {
+ noise.setSeed(seed);
+ }
+
+ public double getTemperature(double x, double z) {
+ return noise.getValue(x, 0, z);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/location/BlockLocation.java b/src/ru/olamedia/olacraft/world/location/BlockLocation.java
index 9639ac1..371c084 100644
--- a/src/ru/olamedia/olacraft/world/location/BlockLocation.java
+++ b/src/ru/olamedia/olacraft/world/location/BlockLocation.java
@@ -2,70 +2,110 @@ package ru.olamedia.olacraft.world.location;
import java.io.Serializable;
-import ru.olamedia.olacraft.world.chunk.Chunk;
-
-public class BlockLocation implements Serializable {
+public class BlockLocation extends Location3i implements Serializable {
private static final long serialVersionUID = -4987461467575474762L;
- public int x;
- public int y;
- public int z;
+ private static int yChunkShift = 128;
public BlockLocation() {
}
+ public byte getByteX() {
+ return (byte) (x & 15);
+ }
+
+ public int getChunkX() {
+ return (int) (x >> 4);
+ }
+
+ public int getRegionX() {
+ return (int) (x >> 8);
+ }
+
+ public byte getByteY() {
+ return (byte) (y & 15);
+ }
+
+ public int getChunkY() {
+ return (int) ((y + yChunkShift) >> 4);
+ }
+
+ public int getRegionY() {
+ return (int) ((y + yChunkShift) >> 8);
+ }
+
+ public byte getByteZ() {
+ return (byte) (z & 15);
+ }
+
+ public int getChunkZ() {
+ return (int) (z >> 4);
+ }
+
+ public int getRegionZ() {
+ return (int) (z >> 8);
+ }
+
+ public short getId() {
+ return IntLocation.id(x, y, z);
+ }
+
public boolean isChunkEdge() {
- int cx = Chunk.in(x);
- int cy = Chunk.in(y);
- int cz = Chunk.in(z);
+ int cx = getByteX();
+ int cy = getByteY();
+ int cz = getByteZ();
return (cx == 0 || cy == 0 || cz == 0 || cx == 15 || cy == 15 || cz == 15);
}
public boolean isChunkLeftEdge() {
- return Chunk.in(x) == 0;
+ return getByteX() == 0;
}
public boolean isChunkRightEdge() {
- return Chunk.in(x) == 15;
+ return getByteX() == 15;
}
public boolean isChunkTopEdge() {
- return Chunk.in(y) == 15;
+ return getByteY() == 15;
}
public boolean isChunkBottomEdge() {
- return Chunk.in(y) == 0;
+ return getByteY() == 0;
}
public boolean isChunkFrontEdge() {
- return Chunk.in(z) == 15;
+ return getByteZ() == 15;
}
public boolean isChunkBackEdge() {
- return Chunk.in(z) == 0;
+ return getByteZ() == 0;
}
public BlockLocation(int x, int y, int z) {
- this.x = x;
- this.y = y;
- this.z = z;
+ super(x, y, z);
}
public BlockLocation(float x, float y, float z) {
- this.x = (int) x;
- this.y = (int) y;
- this.z = (int) z;
+ super(x, y, z);
+ }
+
+ public BlockLocation(Location3i location) {
+ super(location);
+ }
+
+ public BlockLocation(Location3f location) {
+ super(location);
}
public ChunkLocation getChunkLocation() {
- return new ChunkLocation(Chunk.v(x), Chunk.v(y + 128), Chunk.v(z));
+ return new ChunkLocation(getChunkX(), getChunkY(), getChunkZ());
}
public RegionLocation getRegionLocation() {
- return new RegionLocation(Chunk.v(Chunk.v(x)), Chunk.v(Chunk.v(z)));
+ return new RegionLocation(getRegionX(), getRegionZ());
}
public SectorLocation getSectorLocation() {
- return new SectorLocation(Chunk.v(x), Chunk.v(z));
+ return new SectorLocation(getChunkX(), getChunkZ());
}
public String toString() {
diff --git a/src/ru/olamedia/olacraft/world/location/ChunkLocation.java b/src/ru/olamedia/olacraft/world/location/ChunkLocation.java
index 439b9be..73a9c16 100644
--- a/src/ru/olamedia/olacraft/world/location/ChunkLocation.java
+++ b/src/ru/olamedia/olacraft/world/location/ChunkLocation.java
@@ -4,28 +4,19 @@ import java.io.Serializable;
import ru.olamedia.olacraft.world.chunk.Chunk;
-public class ChunkLocation implements Serializable {
+public class ChunkLocation extends Location3i implements Serializable {
private static final long serialVersionUID = -3620722885522274470L;
- public ChunkLocation() {
-
- }
-
public ChunkLocation(int x, int y, int z) {
- this.x = x;
- this.y = y;
- this.z = z;
+ super(x, y, z);
}
- public ChunkLocation(ChunkLocation loc) {
- this.x = loc.x;
- this.y = loc.y;
- this.z = loc.z;
+ public ChunkLocation(Location3i cameraChunk) {
+ super(cameraChunk);
}
- public int x;
- public int y;
- public int z;
+ public ChunkLocation() {
+ }
public SectorLocation getSectorLocation() {
return new SectorLocation(x, z);
diff --git a/src/ru/olamedia/olacraft/world/location/IntLocation.java b/src/ru/olamedia/olacraft/world/location/IntLocation.java
new file mode 100644
index 0000000..3ee7110
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/IntLocation.java
@@ -0,0 +1,200 @@
+package ru.olamedia.olacraft.world.location;
+
+import java.nio.IntBuffer;
+
+public class IntLocation {
+ private static int yShift = 128;
+
+ public static IntBuffer allocate() {
+ return IntBuffer.allocate(3);
+ }
+
+ public static boolean inRange(int x, int y, int z) {
+ return inRange(x) && inRange(y) && inRange(z);
+ }
+
+ public static boolean inRange(int val) {
+ return (val >= 0) && (val <= 15);
+ }
+
+ public static byte in(int val) {
+ return (byte) (val & 15);
+ }
+
+ public static int chunk(int val) {
+ return val >> 4;
+ }
+
+ public static int region(int val) {
+ return val >> 8;
+ }
+
+ public static int rev(int val) {
+ return val * 16;
+ }
+
+ public static int rev2(int val) {
+ return val * 256;
+ }
+
+ public static short id(int x, int y, int z) {
+ return (short) ((x & 15) * 256 + (y & 15) * 16 + (z & 15));
+ }
+
+ public static short leftId(int x, int y, int z) {
+ return id(x - 1, y, z);
+ }
+
+ public static short rightId(int x, int y, int z) {
+ return id(x + 1, y, z);
+ }
+
+ public static short topId(int x, int y, int z) {
+ return id(x, y + 1, z);
+ }
+
+ public static short bottomId(int x, int y, int z) {
+ return id(x, y - 1, z);
+ }
+
+ public static short backId(int x, int y, int z) {
+ return id(x, y, z + 1);
+ }
+
+ public static short frontId(int x, int y, int z) {
+ return id(x, y, z - 1);
+ }
+
+ public static int[] block2chunk(int[] b) {
+ return new int[] { chunk(b[0]), chunk(b[1] + yShift), chunk(b[2]) };
+ }
+
+ public static void block2chunk(int[] b, int[] c) {
+ c[0] = chunk(b[0]);
+ c[1] = chunk(b[1] + yShift);
+ c[2] = chunk(b[2]);
+ }
+
+ public static void block2chunk(IntBuffer b, IntBuffer c) {
+ c.put(0, chunk(b.get(0)));
+ c.put(1, chunk(b.get(1) + yShift));
+ c.put(2, chunk(b.get(2)));
+ }
+
+ public static int[] chunk2block(int[] c) {
+ return new int[] { rev(c[0]), rev(c[1]) - yShift, rev(c[2]) };
+ }
+
+ public static void chunk2block(int[] c, int[] b) {
+ b[0] = rev(c[0]);
+ b[1] = rev(c[1]) - yShift;
+ b[2] = rev(c[2]);
+ }
+
+ public static void chunk2block(IntBuffer c, IntBuffer b) {
+ b.put(0, rev(c.get(0)));
+ b.put(1, rev(c.get(1)) - yShift);
+ b.put(2, rev(c.get(2)));
+ }
+
+ public static int[] region2chunk(int[] r) {
+ return new int[] { rev(r[0]), rev(r[1]), rev(r[2]) };
+ }
+
+ public static void region2chunk(int[] r, int[] c) {
+ c[0] = rev(r[0]);
+ c[1] = rev(r[1]);
+ c[2] = rev(r[2]);
+ }
+
+ public static void region2chunk(IntBuffer r, IntBuffer c) {
+ c.put(0, rev(r.get(0)));
+ c.put(1, rev(r.get(1)));
+ c.put(2, rev(r.get(2)));
+ }
+
+ public static int[] region2block(int[] r) {
+ return new int[] { rev2(r[0]), rev2(r[1]) - yShift, rev2(r[2]) };
+ }
+
+ public static void region2block(int[] r, int[] b) {
+ b[0] = rev2(r[0]);
+ b[1] = rev2(r[1]) - yShift;
+ b[2] = rev2(r[2]);
+ }
+
+ public static void region2block(IntBuffer r, IntBuffer b) {
+ b.put(0, rev2(r.get(0)));
+ b.put(1, rev2(r.get(1)) - yShift);
+ b.put(2, rev2(r.get(2)));
+ }
+
+ public static int[] block2region(int[] b) {
+ return new int[] { chunk(chunk(b[0])), chunk(chunk(b[1] + yShift)), chunk(chunk(b[2])) };
+ }
+
+ public static void block2region(int[] b, int[] r) {
+ r[0] = region(b[0]);
+ r[1] = region(b[1] + yShift);
+ r[2] = region(b[2]);
+ }
+
+ public static void block2region(IntBuffer b, IntBuffer r) {
+ r.put(0, region(b.get(0)));
+ r.put(1, region(b.get(1) + yShift));
+ r.put(2, region(b.get(2)));
+ }
+
+ public static int[] chunk2region(int[] c) {
+ return new int[] { chunk(c[0]), chunk(c[1]), chunk(c[2]) };
+ }
+
+ public static void chunk2region(int[] c, int[] r) {
+ r[0] = chunk(c[0]);
+ r[1] = chunk(c[1]);
+ r[2] = chunk(c[2]);
+ }
+
+ public static void chunk2region(IntBuffer c, IntBuffer r) {
+ r.put(0, chunk(c.get(0)));
+ r.put(1, chunk(c.get(1)));
+ r.put(2, chunk(c.get(2)));
+ }
+
+ public static void set(IntBuffer b, int x, int y, int z) {
+ b.put(0, x);
+ b.put(1, y);
+ b.put(2, z);
+ }
+
+ public static void setXZ(IntBuffer b, int x, int z) {
+ b.put(0, x);
+ b.put(2, z);
+ }
+
+ public static void setY(IntBuffer b, int y) {
+ b.put(1, y);
+ }
+
+ public static int getX(IntBuffer b) {
+ return b.get(0);
+ }
+
+ public static int getY(IntBuffer b) {
+ return b.get(1);
+ }
+
+ public static int getZ(IntBuffer b) {
+ return b.get(2);
+ }
+
+ public static int id(IntBuffer b) {
+ return id(b.get(0), b.get(1), b.get(2));
+ }
+
+ public static void setSum(IntBuffer target, IntBuffer b1, IntBuffer b2) {
+ target.put(0, b1.get(0) + b2.get(0));
+ target.put(1, b1.get(1) + b2.get(1));
+ target.put(2, b1.get(2) + b2.get(2));
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/location/Location3f.java b/src/ru/olamedia/olacraft/world/location/Location3f.java
new file mode 100644
index 0000000..a30c6d7
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/Location3f.java
@@ -0,0 +1,46 @@
+package ru.olamedia.olacraft.world.location;
+
+public class Location3f {
+ public float x;
+ public float y;
+ public float z;
+
+ public Location3f() {
+ x = 0;
+ y = 0;
+ z = 0;
+ }
+
+ public Location3f(float x, float y, float z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public Location3f(int x, int y, int z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public Location3f(Location3f location) {
+ x = location.x;
+ y = location.y;
+ z = location.z;
+ }
+
+ public Location3f(Location3i location) {
+ x = location.x;
+ y = location.y;
+ z = location.z;
+ }
+
+ public String toString() {
+ return "Location3f[" + x + "," + y + "," + z + "]";
+ }
+
+ public void addRandomOffset(float d) {
+ x += Math.random() * d * 2 - d;
+ z += Math.random() * d * 2 - d;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/location/Location3i.java b/src/ru/olamedia/olacraft/world/location/Location3i.java
new file mode 100644
index 0000000..347e4bc
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/Location3i.java
@@ -0,0 +1,71 @@
+package ru.olamedia.olacraft.world.location;
+
+public class Location3i {
+ public int x;
+ public int y;
+ public int z;
+
+ public byte getByteX() {
+ return (byte) (x & 15);
+ }
+
+ public byte getByteY() {
+ return (byte) (y & 15);
+ }
+
+ public byte getByteZ() {
+ return (byte) (z & 15);
+ }
+
+ public Location3i() {
+ x = 0;
+ y = 0;
+ z = 0;
+ }
+
+ public Location3i(float x, float y, float z) {
+ this.x = (int) x;
+ this.y = (int) y;
+ this.z = (int) z;
+ }
+
+ public Location3i(int x, int y, int z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public Location3i(Location3i location) {
+ x = location.x;
+ y = location.y;
+ z = location.z;
+ }
+
+ public Location3i(Location3f location) {
+ x = (int) location.x;
+ y = (int) location.y;
+ z = (int) location.z;
+ }
+
+ public void set(Location3i location) {
+ this.x = location.x;
+ this.y = location.y;
+ this.z = location.z;
+ }
+
+ public void set(int x, int y, int z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public void set(float x, float y, float z) {
+ this.x = (int) x;
+ this.y = (int) y;
+ this.z = (int) z;
+ }
+
+ public String toString() {
+ return "Location3i[" + x + "," + y + "," + z + "]";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/location/MetaLocation3i.java b/src/ru/olamedia/olacraft/world/location/MetaLocation3i.java
new file mode 100644
index 0000000..e440572
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/MetaLocation3i.java
@@ -0,0 +1,7 @@
+package ru.olamedia.olacraft.world.location;
+
+import java.nio.IntBuffer;
+
+public class MetaLocation3i {
+ private IntBuffer b = IntBuffer.allocate(3);
+}
diff --git a/src/ru/olamedia/olacraft/world/location/RegionLocation.java b/src/ru/olamedia/olacraft/world/location/RegionLocation.java
index a1100c0..c11d3c8 100644
--- a/src/ru/olamedia/olacraft/world/location/RegionLocation.java
+++ b/src/ru/olamedia/olacraft/world/location/RegionLocation.java
@@ -36,4 +36,40 @@ public class RegionLocation implements Serializable {
public BlockLocation getBlockLocation() {
return new BlockLocation(Chunk.rev(Chunk.rev(x)), 0, Chunk.rev(Chunk.rev(z)));
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + x;
+ result = prime * result + z;
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RegionLocation other = (RegionLocation) obj;
+ if (x != other.x)
+ return false;
+ if (z != other.z)
+ return false;
+ return true;
+ }
+
}
diff --git a/src/ru/olamedia/olacraft/world/provider/IWorldProvider.java b/src/ru/olamedia/olacraft/world/provider/IWorldProvider.java
new file mode 100644
index 0000000..5605728
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/IWorldProvider.java
@@ -0,0 +1,11 @@
+package ru.olamedia.olacraft.world.provider;
+
+import ru.olamedia.olacraft.world.WorldInfo;
+
+public interface IWorldProvider {
+ public boolean hasInfo();
+
+ public void requestInfo();
+
+ public WorldInfo getInfo();
+}
diff --git a/src/ru/olamedia/olacraft/world/provider/LocalWorld.java b/src/ru/olamedia/olacraft/world/provider/LocalWorld.java
new file mode 100644
index 0000000..1756118
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/LocalWorld.java
@@ -0,0 +1,24 @@
+package ru.olamedia.olacraft.world.provider;
+
+import ru.olamedia.olacraft.network.provider.LocalProvider;
+import ru.olamedia.olacraft.world.WorldInfo;
+
+public class LocalWorld implements IWorldProvider {
+ private LocalProvider<WorldInfo> info;
+
+ public LocalWorld() {
+ info.put(new WorldInfo());
+ }
+
+ public boolean hasInfo() {
+ return true;
+ }
+
+ public void requestInfo() {
+ // do nothing
+ }
+
+ public WorldInfo getInfo() {
+ return info.get();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/provider/RemoteWorld.java b/src/ru/olamedia/olacraft/world/provider/RemoteWorld.java
new file mode 100644
index 0000000..d086bf1
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/RemoteWorld.java
@@ -0,0 +1,32 @@
+package ru.olamedia.olacraft.world.provider;
+
+import ru.olamedia.olacraft.network.provider.CacheProvider;
+import ru.olamedia.olacraft.network.provider.RemoteProvider;
+import ru.olamedia.olacraft.world.WorldInfo;
+
+public class RemoteWorld implements IWorldProvider {
+ private CacheProvider<WorldInfo> info;
+
+ public RemoteWorld() {
+ info = new CacheProvider<WorldInfo>(new RemoteProvider<WorldInfo>() {
+ @Override
+ public void request() {
+
+ }
+ });
+ }
+
+ public boolean hasInfo() {
+ return info.has();
+ }
+
+ public void requestInfo() {
+ info.request();
+ }
+
+ @Override
+ public WorldInfo getInfo() {
+ return info.get();
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/provider/WorldProvider.java b/src/ru/olamedia/olacraft/world/provider/WorldProvider.java
index 7471b52..decf24d 100644
--- a/src/ru/olamedia/olacraft/world/provider/WorldProvider.java
+++ b/src/ru/olamedia/olacraft/world/provider/WorldProvider.java
@@ -6,25 +6,86 @@ import ru.olamedia.olacraft.world.block.Block;
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.blockTypes.DirtBlockType;
+import ru.olamedia.olacraft.world.blockTypes.GrassBlockType;
+import ru.olamedia.olacraft.world.blockTypes.GravelBlockType;
+import ru.olamedia.olacraft.world.blockTypes.IceBlockType;
+import ru.olamedia.olacraft.world.blockTypes.SnowBlockType;
+import ru.olamedia.olacraft.world.blockTypes.TallGrassBlockType;
+import ru.olamedia.olacraft.world.blockTypes.WaterBlockType;
+import ru.olamedia.olacraft.world.blockTypes.WheatBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.BrecciaStoneBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.ChertStoneBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.CoalStoneBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.ConglomerateStoneBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.LimestoneStoneBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.SandstoneStoneBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.ShaleStoneBlockType;
+import ru.olamedia.olacraft.world.blockTypes.stone.SiltstoneStoneBlockType;
import ru.olamedia.olacraft.world.chunk.ChunkUnavailableException;
import ru.olamedia.olacraft.world.data.ChunkData;
import ru.olamedia.olacraft.world.data.RegionData;
import ru.olamedia.olacraft.world.dataProvider.AbstractChunkDataProvider;
+import ru.olamedia.olacraft.world.drop.DroppedEntity;
import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.olacraft.world.location.ChunkLocation;
import ru.olamedia.olacraft.world.location.RegionLocation;
+/**
+ * Provides ALL information about world (world height, block types, chunks, mobs, spawn locations etc)
+ *
+ */
public class WorldProvider {
private WorldInfo info = new WorldInfo();
- private BlockRegistry typeRegistry = new BlockRegistry();
+ private BlockRegistry types = new BlockRegistry();
private AbstractChunkDataProvider dataProvider;
+
+ public WorldProvider() {
+ registerBlockTypes(false);
+ }
+
+ public void registerTextures(){
+ registerBlockTypes(true);
+ }
+
+ protected void registerBlockType(AbstractBlockType t, boolean registerTextures){
+ if (registerTextures) {
+ t.getBackTexture();
+ t.getBottomTexture();
+ t.getFrontTexture();
+ t.getLeftTexture();
+ t.getRightTexture();
+ t.getTopTexture();
+ } else {
+ types.registerBlockType(t);
+ }
+ }
+
+ protected void registerBlockTypes(boolean registerTextures) {
+ registerBlockType(new GrassBlockType(), registerTextures);
+ registerBlockType(new ConglomerateStoneBlockType(), registerTextures);
+ registerBlockType(new LimestoneStoneBlockType(), registerTextures);
+ registerBlockType(new ChertStoneBlockType(), registerTextures);
+ registerBlockType(new SiltstoneStoneBlockType(), registerTextures);
+ registerBlockType(new SandstoneStoneBlockType(), registerTextures);
+ registerBlockType(new ShaleStoneBlockType(), registerTextures);
+ registerBlockType(new CoalStoneBlockType(), registerTextures);
+ registerBlockType(new BrecciaStoneBlockType(), registerTextures);
+ registerBlockType(new DirtBlockType(), registerTextures);
+ registerBlockType(new GravelBlockType(), registerTextures);
+ registerBlockType(new WheatBlockType(), registerTextures);
+ registerBlockType(new WaterBlockType(), registerTextures);
+ registerBlockType(new IceBlockType(), registerTextures);
+ registerBlockType(new SnowBlockType(), registerTextures);
+ registerBlockType(new TallGrassBlockType(), registerTextures);
+ }
public WorldInfo getInfo() {
return info;
}
-
- public BlockRegistry getTypeRegistry(){
- return typeRegistry;
+
+ public BlockRegistry getTypeRegistry() {
+ return types;
}
public void setInfo(WorldInfo worldInfo) {
@@ -39,9 +100,11 @@ public class WorldProvider {
public void setChunkDataProvider(AbstractChunkDataProvider provider) {
dataProvider = provider;
+ dataProvider.setTypeRegistry(this.types);
}
public SpawnLocation getSpawnLocation(int connectionId) {
+ dataProvider.setTypeRegistry(this.types);
SpawnLocation l = new SpawnLocation();
int maxShift = 10;
l.x = (int) (maxShift - Math.random() * 2 * maxShift);
@@ -140,7 +203,76 @@ public class WorldProvider {
return dataProvider.getChunk(chunkLocation);
}
- public BlockType getBlockTypeById(int id) {
- return typeRegistry.getBlockType(id);
+ public AbstractBlockType getBlockTypeById(int id) {
+ return types.getBlockType(id);
}
+
+ public boolean isOpaque(int x, int y, int z) throws ChunkUnavailableException {
+ BlockLocation blockLocation = new BlockLocation(x, y, z);
+ if (isChunkAvailable(blockLocation.getChunkLocation())) {
+ ChunkData data = dataProvider.getChunk(blockLocation.getChunkLocation());
+ if (null != data) {
+ int id = ChunkData.ClampID(x, y, z);
+ if (data.isEmpty(id)) {
+ return false;
+ }
+ return types.isOpaque(data.types[id]);
+ } else {
+ System.out.println("chunk null " + x + " " + y + " " + z);
+ }
+ } else {
+ throw new ChunkUnavailableException();
+ }
+ return false;
+ }
+
+ public boolean hideTouchedSides(int x, int y, int z, int typeid) throws ChunkUnavailableException {
+ BlockLocation blockLocation = new BlockLocation(x, y, z);
+ if (isChunkAvailable(blockLocation.getChunkLocation())) {
+ ChunkData data = dataProvider.getChunk(blockLocation.getChunkLocation());
+ if (null != data) {
+ int id = ChunkData.ClampID(x, y, z);
+ if (data.isEmpty(id)) {
+ return false;
+ }
+ if (data.types[id] == typeid) {
+ return types.getBlockType(data.types[id]).hideTouchedSides();
+ }
+ return types.isOpaque(data.types[id]);
+ } else {
+ System.out.println("chunk null " + x + " " + y + " " + z);
+ }
+ } else {
+ throw new ChunkUnavailableException();
+ }
+ return false;
+ }
+
+ public boolean canMoveThrough(int x, int y, int z) throws ChunkUnavailableException {
+ BlockLocation blockLocation = new BlockLocation(x, y, z);
+ if (isChunkAvailable(blockLocation.getChunkLocation())) {
+ ChunkData data = dataProvider.getChunk(blockLocation.getChunkLocation());
+ if (null != data) {
+ int id = ChunkData.ClampID(x, y, z);
+ if (data.isEmpty(id)) {
+ return true;
+ }
+ return types.canMoveThrough(data.types[id]);
+ } else {
+ System.out.println("chunk null " + x + " " + y + " " + z);
+ }
+ } else {
+ throw new ChunkUnavailableException();
+ }
+ return false;
+ }
+
+ public void dropBlock(BlockLocation location, AbstractBlockType type) throws ChunkUnavailableException {
+ if (!isChunkAvailable(location.getChunkLocation())) {
+ throw new ChunkUnavailableException();
+ }
+ ChunkData data = dataProvider.getChunk(location.getChunkLocation());
+ data.addDroppedEntity(new DroppedEntity(location, type, 1));
+ }
+
}