aboutsummaryrefslogtreecommitdiffstats
path: root/src/ru/olamedia
diff options
context:
space:
mode:
authorolamedia <[email protected]>2012-09-28 18:46:42 +0600
committerolamedia <[email protected]>2012-09-28 18:46:42 +0600
commitb4192c7a88bad111bebbd42d391d6e729c8617d6 (patch)
treeb05a586dbc60c5427fcc7f3fe01cf2fdcb970272 /src/ru/olamedia
initial
Diffstat (limited to 'src/ru/olamedia')
-rw-r--r--src/ru/olamedia/Options.java5
-rw-r--r--src/ru/olamedia/asset/Asset.java29
-rw-r--r--src/ru/olamedia/asset/AssetManager.java28
-rw-r--r--src/ru/olamedia/asset/AssetNotFoundException.java22
-rw-r--r--src/ru/olamedia/asset/package-info.java8
-rw-r--r--src/ru/olamedia/camera/CameraProjectionMatrix.java77
-rw-r--r--src/ru/olamedia/camera/Cameraman.java21
-rw-r--r--src/ru/olamedia/camera/MatrixCamera.java545
-rw-r--r--src/ru/olamedia/camera/package-info.java8
-rw-r--r--src/ru/olamedia/controls/package-info.java8
-rw-r--r--src/ru/olamedia/debug/SystemInfo.java24
-rw-r--r--src/ru/olamedia/debug/package-info.java8
-rw-r--r--src/ru/olamedia/game/ClientGame.java13
-rw-r--r--src/ru/olamedia/game/DynamicJList.java16
-rw-r--r--src/ru/olamedia/game/Game.java25
-rw-r--r--src/ru/olamedia/game/GameFrame.java194
-rw-r--r--src/ru/olamedia/game/GameManager.java165
-rw-r--r--src/ru/olamedia/game/Launcher.java17
-rw-r--r--src/ru/olamedia/game/MainMenu.java168
-rw-r--r--src/ru/olamedia/game/QuitAdapter.java71
-rw-r--r--src/ru/olamedia/game/ServerGame.java10
-rw-r--r--src/ru/olamedia/game/icon128x128.pngbin0 -> 2158 bytes
-rw-r--r--src/ru/olamedia/game/icon16x16.pngbin0 -> 635 bytes
-rw-r--r--src/ru/olamedia/game/icon256x256.pngbin0 -> 2820 bytes
-rw-r--r--src/ru/olamedia/game/icon32x32.pngbin0 -> 1426 bytes
-rw-r--r--src/ru/olamedia/game/icon64x64.pngbin0 -> 1715 bytes
-rw-r--r--src/ru/olamedia/game/package-info.java8
-rw-r--r--src/ru/olamedia/geom/DisplayList.java39
-rw-r--r--src/ru/olamedia/geom/Frustum.java11
-rw-r--r--src/ru/olamedia/geom/Mesh.java346
-rw-r--r--src/ru/olamedia/geom/Quad.java12
-rw-r--r--src/ru/olamedia/geom/SimpleQuadMesh.java113
-rw-r--r--src/ru/olamedia/geom/package-info.java8
-rw-r--r--src/ru/olamedia/input/AWTRobotUtil.java97
-rw-r--r--src/ru/olamedia/input/KeyListener.java10
-rw-r--r--src/ru/olamedia/input/Keyboard.java64
-rw-r--r--src/ru/olamedia/input/MouseJail.java113
-rw-r--r--src/ru/olamedia/input/MouseListener.java6
-rw-r--r--src/ru/olamedia/input/package-info.java8
-rw-r--r--src/ru/olamedia/liveEntity/LiveEntity.java683
-rw-r--r--src/ru/olamedia/liveEntity/LiveEntityEvent.java31
-rw-r--r--src/ru/olamedia/liveEntity/LiveEntityEventDispatcher.java7
-rw-r--r--src/ru/olamedia/liveEntity/package-info.java8
-rw-r--r--src/ru/olamedia/math/Box.java74
-rw-r--r--src/ru/olamedia/math/Classifier.java8
-rw-r--r--src/ru/olamedia/math/Frustum.java127
-rw-r--r--src/ru/olamedia/math/FrustumUtil.java72
-rw-r--r--src/ru/olamedia/math/Halfspace.java7
-rw-r--r--src/ru/olamedia/math/Matrix4f.java191
-rw-r--r--src/ru/olamedia/math/Matrix4fUtil.java36
-rw-r--r--src/ru/olamedia/math/Plane.java71
-rw-r--r--src/ru/olamedia/math/Quaternion.java25
-rw-r--r--src/ru/olamedia/math/QuaternionUtil.java54
-rw-r--r--src/ru/olamedia/math/TransformMatrix.java15
-rw-r--r--src/ru/olamedia/math/Vector3f.java70
-rw-r--r--src/ru/olamedia/math/ViewMatrix.java111
-rw-r--r--src/ru/olamedia/math/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/OlaCraft.java6
-rw-r--r--src/ru/olamedia/olacraft/OlaCraftFrame.java10
-rw-r--r--src/ru/olamedia/olacraft/events/GameEvent.java32
-rw-r--r--src/ru/olamedia/olacraft/events/GameEventDispatcher.java22
-rw-r--r--src/ru/olamedia/olacraft/events/GameEventListener.java5
-rw-r--r--src/ru/olamedia/olacraft/events/GameEventRegistry.java17
-rw-r--r--src/ru/olamedia/olacraft/events/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/game/Game.java106
-rw-r--r--src/ru/olamedia/olacraft/game/GameInterface.java7
-rw-r--r--src/ru/olamedia/olacraft/game/IGameWrapper.java7
-rw-r--r--src/ru/olamedia/olacraft/game/LocalGameWrapper.java17
-rw-r--r--src/ru/olamedia/olacraft/game/SpawnLocation.java7
-rw-r--r--src/ru/olamedia/olacraft/game/Timer.java99
-rw-r--r--src/ru/olamedia/olacraft/game/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/inventory/Frame.java44
-rw-r--r--src/ru/olamedia/olacraft/inventory/Inventory.java76
-rw-r--r--src/ru/olamedia/olacraft/inventory/package-info.java9
-rw-r--r--src/ru/olamedia/olacraft/network/ConnectionState.java17
-rw-r--r--src/ru/olamedia/olacraft/network/ConnectionStateListener.java7
-rw-r--r--src/ru/olamedia/olacraft/network/GameClient.java209
-rw-r--r--src/ru/olamedia/olacraft/network/GameServer.java169
-rw-r--r--src/ru/olamedia/olacraft/network/Network.java71
-rw-r--r--src/ru/olamedia/olacraft/network/PlayerConnection.java9
-rw-r--r--src/ru/olamedia/olacraft/network/discovery/DiscoveryClient.java143
-rw-r--r--src/ru/olamedia/olacraft/network/discovery/DiscoveryListener.java9
-rw-r--r--src/ru/olamedia/olacraft/network/discovery/DiscoveryThread.java91
-rw-r--r--src/ru/olamedia/olacraft/network/discovery/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/network/package-info.java9
-rw-r--r--src/ru/olamedia/olacraft/network/packet/ChatMessagePacket.java5
-rw-r--r--src/ru/olamedia/olacraft/network/packet/ChunkDataPacket.java10
-rw-r--r--src/ru/olamedia/olacraft/network/packet/ConnectionPacket.java11
-rw-r--r--src/ru/olamedia/olacraft/network/packet/ConnectionRequestPacket.java5
-rw-r--r--src/ru/olamedia/olacraft/network/packet/GetChunkDataPacket.java7
-rw-r--r--src/ru/olamedia/olacraft/network/packet/GetRegionPacket.java15
-rw-r--r--src/ru/olamedia/olacraft/network/packet/IPacket.java5
-rw-r--r--src/ru/olamedia/olacraft/network/packet/IPacketListener.java7
-rw-r--r--src/ru/olamedia/olacraft/network/packet/LiveEntityLocationUpdatePacket.java15
-rw-r--r--src/ru/olamedia/olacraft/network/packet/RegionDataPacket.java7
-rw-r--r--src/ru/olamedia/olacraft/network/packet/SpawnPacket.java15
-rw-r--r--src/ru/olamedia/olacraft/network/packet/SpawnRequestPacket.java4
-rw-r--r--src/ru/olamedia/olacraft/network/packet/WorldInfoPacket.java15
-rw-r--r--src/ru/olamedia/olacraft/network/packet/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/physics/GamePhysicsWorld.java27
-rw-r--r--src/ru/olamedia/olacraft/physics/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/picker/joglBlockPicker.java27
-rw-r--r--src/ru/olamedia/olacraft/picker/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/BlockRenderer.java87
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/BlockStackRenderer.java9
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java146
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java75
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/IRenderer.java8
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java87
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/PlaneRenderer.java102
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/VectorRenderer.java20
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/joglViewport.java24
-rw-r--r--src/ru/olamedia/olacraft/render/jogl/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/scene/GameScene.java252
-rw-r--r--src/ru/olamedia/olacraft/scene/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/weapon/Bullet.java51
-rw-r--r--src/ru/olamedia/olacraft/weapon/BulletScene.java35
-rw-r--r--src/ru/olamedia/olacraft/weapon/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/World.java12
-rw-r--r--src/ru/olamedia/olacraft/world/WorldInfo.java11
-rw-r--r--src/ru/olamedia/olacraft/world/block/Block.java111
-rw-r--r--src/ru/olamedia/olacraft/world/block/BlockRegistry.java46
-rw-r--r--src/ru/olamedia/olacraft/world/block/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/blockStack/BlockStack.java63
-rw-r--r--src/ru/olamedia/olacraft/world/blockStack/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java86
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/BlockType.java21
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java23
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java28
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java23
-rw-r--r--src/ru/olamedia/olacraft/world/blockTypes/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/BlockSlice.java164
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/Chunk.java290
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java47
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java114
-rw-r--r--src/ru/olamedia/olacraft/world/chunk/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/data/ChunkData.java86
-rw-r--r--src/ru/olamedia/olacraft/world/data/ChunkLightData.java102
-rw-r--r--src/ru/olamedia/olacraft/world/data/HeightMap.java42
-rw-r--r--src/ru/olamedia/olacraft/world/data/RegionData.java57
-rw-r--r--src/ru/olamedia/olacraft/world/data/SectorData.java33
-rw-r--r--src/ru/olamedia/olacraft/world/data/UnavailableDataException.java23
-rw-r--r--src/ru/olamedia/olacraft/world/data/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java60
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java70
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java218
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/LocalRegionDataProvider.java57
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java75
-rw-r--r--src/ru/olamedia/olacraft/world/dataProvider/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/generator/HeightMapGenerator.java157
-rw-r--r--src/ru/olamedia/olacraft/world/generator/ImprovedNoise.java61
-rw-r--r--src/ru/olamedia/olacraft/world/generator/Lerp.java27
-rw-r--r--src/ru/olamedia/olacraft/world/generator/RegionGenerator.java71
-rw-r--r--src/ru/olamedia/olacraft/world/generator/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/location/BlockLocation.java37
-rw-r--r--src/ru/olamedia/olacraft/world/location/ChunkLocation.java40
-rw-r--r--src/ru/olamedia/olacraft/world/location/RegionLocation.java29
-rw-r--r--src/ru/olamedia/olacraft/world/location/SectorLocation.java29
-rw-r--r--src/ru/olamedia/olacraft/world/location/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/provider/IChunkProvider.java8
-rw-r--r--src/ru/olamedia/olacraft/world/provider/WorldProvider.java130
-rw-r--r--src/ru/olamedia/olacraft/world/provider/blockData/BlockData.java5
-rw-r--r--src/ru/olamedia/olacraft/world/provider/blockData/EmptyBlockData.java5
-rw-r--r--src/ru/olamedia/olacraft/world/provider/blockData/IBlockData.java5
-rw-r--r--src/ru/olamedia/olacraft/world/provider/blockData/package-info.java8
-rw-r--r--src/ru/olamedia/olacraft/world/provider/package-info.java8
-rw-r--r--src/ru/olamedia/player/Player.java31
-rw-r--r--src/ru/olamedia/tasks/Task.java24
-rw-r--r--src/ru/olamedia/tasks/TaskManager.java18
-rw-r--r--src/ru/olamedia/tasks/package-info.java8
-rw-r--r--src/ru/olamedia/texture/ResourceUtil.java126
-rw-r--r--src/ru/olamedia/texture/TextureManager.java42
-rw-r--r--src/ru/olamedia/texture/package-info.java8
-rw-r--r--src/ru/olamedia/util/BufferUtils.java16
-rw-r--r--src/ru/olamedia/vbo/VBO.java29
-rw-r--r--src/ru/olamedia/vbo/package-info.java8
178 files changed, 9108 insertions, 0 deletions
diff --git a/src/ru/olamedia/Options.java b/src/ru/olamedia/Options.java
new file mode 100644
index 0000000..e1c4d41
--- /dev/null
+++ b/src/ru/olamedia/Options.java
@@ -0,0 +1,5 @@
+package ru.olamedia;
+
+public class Options {
+ public static int renderDistance = 256;
+}
diff --git a/src/ru/olamedia/asset/Asset.java b/src/ru/olamedia/asset/Asset.java
new file mode 100644
index 0000000..a420c10
--- /dev/null
+++ b/src/ru/olamedia/asset/Asset.java
@@ -0,0 +1,29 @@
+package ru.olamedia.asset;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+public class Asset {
+ protected URL url;
+
+ public boolean inJar() {
+ return url.toString().startsWith("file:jar:");
+ }
+
+ public Asset(URL url) {
+ this.url = url;
+ }
+
+ public URL getURL() {
+ return url;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return url.openStream();
+ }
+
+ public String getFile() {
+ return url.getFile();
+ }
+}
diff --git a/src/ru/olamedia/asset/AssetManager.java b/src/ru/olamedia/asset/AssetManager.java
new file mode 100644
index 0000000..d1de11b
--- /dev/null
+++ b/src/ru/olamedia/asset/AssetManager.java
@@ -0,0 +1,28 @@
+package ru.olamedia.asset;
+
+import java.net.URL;
+
+public class AssetManager {
+
+ public static URL getBaseURL() {
+ return AssetManager.class.getResource(AssetManager.class.getSimpleName() + ".class");
+ }
+
+ public boolean inJar() {
+ // file:jar:c:/path/to/jar/somejar.jar!
+ return getBaseURL().toString().startsWith("file:jar:");
+ // return getBaseURL().toString().indexOf(".jar!") > 0;
+ }
+
+ public static URL getURL(String path) throws AssetNotFoundException {
+ URL url = AssetManager.class.getClassLoader().getResource(path);
+ if (null == url) {
+ throw new AssetNotFoundException(path);
+ }
+ return url;
+ }
+
+ public static Asset getAsset(String path) throws AssetNotFoundException {
+ return new Asset(getURL(path));
+ }
+}
diff --git a/src/ru/olamedia/asset/AssetNotFoundException.java b/src/ru/olamedia/asset/AssetNotFoundException.java
new file mode 100644
index 0000000..29afdf0
--- /dev/null
+++ b/src/ru/olamedia/asset/AssetNotFoundException.java
@@ -0,0 +1,22 @@
+package ru.olamedia.asset;
+
+public class AssetNotFoundException extends Exception {
+
+ public AssetNotFoundException() {
+ super();
+ }
+
+ public AssetNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public AssetNotFoundException(String message) {
+ super(message);
+ }
+
+ public AssetNotFoundException(Throwable cause) {
+ super(cause);
+ }
+
+ private static final long serialVersionUID = 2197816222986044998L;
+}
diff --git a/src/ru/olamedia/asset/package-info.java b/src/ru/olamedia/asset/package-info.java
new file mode 100644
index 0000000..d2ed4df
--- /dev/null
+++ b/src/ru/olamedia/asset/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.asset; \ No newline at end of file
diff --git a/src/ru/olamedia/camera/CameraProjectionMatrix.java b/src/ru/olamedia/camera/CameraProjectionMatrix.java
new file mode 100644
index 0000000..ec1c390
--- /dev/null
+++ b/src/ru/olamedia/camera/CameraProjectionMatrix.java
@@ -0,0 +1,77 @@
+package ru.olamedia.camera;
+
+import org.openmali.FastMath;
+import org.openmali.vecmath2.Matrix4f;
+
+public class CameraProjectionMatrix extends Matrix4f {
+
+ /**
+ * Creates a mesa-style perspective projection transform, that mimics a
+ * standard, camera-based, view-model.
+ *
+ * @param fovy
+ * specifies the field of view in the y direction, in radians
+ * @param aspect
+ * specifies the aspect ratio and thus the field of view in the x
+ * direction. The aspect ratio is the ratio of x to y, or width
+ * to height.
+ * @param zNear
+ * the distance to the frustum's near clipping plane. This value
+ * must be positive, (the value -zNear is the location of the
+ * near clip plane).
+ * @param zFar
+ * the distance to the frustum's far clipping plane.
+ */
+ public final void perspectiveMesa(float fovy, float aspect, float zNear,
+ float zFar) {
+ final float ymax = zNear * FastMath.tan(fovy);
+ final float ymin = -ymax;
+ final float xmin = ymin * aspect;
+ final float xmax = ymax * aspect;
+
+ // don't call glFrustum() because of error semantics (covglu)
+ frustumMesa(xmin, xmax, ymin, ymax, zNear, zFar);
+ }
+
+ /**
+ * Creates a masa-style perspective projection transform, that mimics a
+ * standard, camera-based, view-model. The frustum function-call establishes
+ * a view-model with the eye at the apex of a symmetric view frustum. The
+ * arguments define the frustum and its associated perspective projection:
+ * (left, bottom, -near) and (right, top, -near) specify the point on the
+ * near clipping plane that maps onto the lower-left and upper-right corners
+ * of the window respectively, assuming the eye is located at (0, 0, 0).
+ *
+ * @param left
+ * the vertical line on the left edge of the near clipping plane
+ * mapped to the left edge of the graphics window
+ * @param right
+ * the vertical line on the right edge of the near clipping plane
+ * mapped to the right edge of the graphics window
+ * @param bottom
+ * the horizontal line on the bottom edge of the near clipping
+ * plane mapped to the bottom edge of the graphics window
+ * @param top
+ * the horizontal line on the top edge of the near
+ * @param zNear
+ * the distance to the frustum's near clipping plane. This value
+ * must be positive, (the value -near is the location of the near
+ * clip plane).
+ * @param zFar
+ * the distance to the frustum's far clipping plane. This value
+ * must be positive, and must be greater than near.
+ */
+ public final void frustumMesa(float left, float right, float bottom,
+ float top, float zNear, float zFar) {
+ final float x = (2.0f * zNear) / (right - left);
+ final float y = (2.0f * zNear) / (top - bottom);
+ final float a = (right + left) / (right - left);
+ final float b = (top + bottom) / (top - bottom);
+ final float c = -(zFar + zNear) / (zFar - zNear);
+ final float d = -(2.0f * zFar * zNear) / (zFar - zNear);
+
+ this.set(x, 0f, 0f, 0f, 0f, y, 0f, 0f, a, b, c, -1f, 0f, 0f, d, 0f);
+
+ }
+
+}
diff --git a/src/ru/olamedia/camera/Cameraman.java b/src/ru/olamedia/camera/Cameraman.java
new file mode 100644
index 0000000..7dbbcc0
--- /dev/null
+++ b/src/ru/olamedia/camera/Cameraman.java
@@ -0,0 +1,21 @@
+package ru.olamedia.camera;
+
+/**
+ * Cameraman.
+ *
+ * @desc Primary purpose is providing eyes level: getCameraY()
+ *
+ * @author olamedia
+ *
+ */
+public interface Cameraman {
+ public float getCameraX();
+
+ public float getCameraY();
+
+ public float getCameraZ();
+
+ public void update(float delta);
+
+ public void captureControls();
+}
diff --git a/src/ru/olamedia/camera/MatrixCamera.java b/src/ru/olamedia/camera/MatrixCamera.java
new file mode 100644
index 0000000..de37fc8
--- /dev/null
+++ b/src/ru/olamedia/camera/MatrixCamera.java
@@ -0,0 +1,545 @@
+package ru.olamedia.camera;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.glu.GLU;
+import javax.vecmath.Vector3f;
+import javax.vecmath.Matrix4f;
+
+import org.openmali.FastMath;
+
+import static org.openmali.FastMath.*;
+
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.input.Keyboard;
+import ru.olamedia.math.Frustum;
+import ru.olamedia.olacraft.render.jogl.PlaneRenderer;
+import ru.olamedia.olacraft.render.jogl.VectorRenderer;
+
+import com.jogamp.newt.event.KeyEvent;
+
+public class MatrixCamera {
+ protected float fov = 90f;
+ protected float aspect = 1f;
+ protected float zNear = 0.1f;
+ protected float zFar = 1000f;
+ private boolean isPitchLocked = true;
+ private float minPitch = -80f;
+ private float maxPitch = 80f;
+ public Frustum frustum = new Frustum();
+
+ private Vector3f position = new Vector3f();
+ private float yaw = 0; // around y
+ private float pitch = 0;
+ private float roll = 0;
+ public Matrix4f projectionMatrix = new Matrix4f();
+ private Matrix4f translationMatrix = new Matrix4f();
+ private Matrix4f xRotationMatrix = new Matrix4f();
+ private Matrix4f yRotationMatrix = new Matrix4f();
+ private Matrix4f zRotationMatrix = new Matrix4f();
+ private Matrix4f rotationMatrix = new Matrix4f();
+ public Matrix4f viewMatrix = new Matrix4f();
+ public Matrix4f worldMatrix = new Matrix4f();
+
+ private Vector3f look = new Vector3f();
+ private Vector3f right = new Vector3f();
+ private Vector3f up = new Vector3f();
+ public boolean isFrustumVisible = false;
+
+ @SuppressWarnings("unused")
+ private org.openmali.vecmath2.Matrix4f matrixToOpenMali(Matrix4f m) {
+ return new org.openmali.vecmath2.Matrix4f(matrixToTransposeArray(m));
+ }
+
+ public void pack() {
+ if (isAttachedToCameraman) {
+ position.x = cameraman.getCameraX();
+ position.y = cameraman.getCameraY();
+ position.z = cameraman.getCameraZ();
+ }
+
+ worldMatrix.setIdentity();
+ packProjectionMatrix();
+ // projectionMatrix.transpose();
+ // worldMatrix.mul(projectionMatrix);
+ translationMatrix.setIdentity();
+ translationMatrix.m03 = position.x;
+ translationMatrix.m13 = position.y - 0.5f; // FIXME y is looking greater
+ // than it should
+ translationMatrix.m23 = position.z;
+ packRotation();
+ packView();
+ // after view matrix created, retrieve vectors:
+ viewMatrix.invert();
+ viewMatrix.transpose();
+ packLookVector();
+ packRightVector();
+ packUpVector();
+ packFrustum();
+ // worldMatrix.mul(projectionMatrix, viewMatrix);
+ // worldMatrix.transpose();
+ // // oglViewMatrix.set(viewMatrix);
+ // // oglViewMatrix.transpose();
+ // frustum = FrustumUtil.extractFrustum(worldMatrix);
+ // Matrix4f vm = new Matrix4f(viewMatrix);
+ // vm.invert();
+ // frustum.compute(matrixToOpenMali(projectionMatrix),
+ // matrixToOpenMali(vm));
+ // ......
+ // finally
+ // ......
+ }
+
+ private ru.olamedia.math.Vector3f nearc;
+
+ private void packFrustum() {
+ float nearD = zNear + (isFrustumVisible ? 0.2f : 0);// zNear;
+ float farD = zFar - (isFrustumVisible ? 1f : 0);// zFar;
+ ru.olamedia.math.Vector3f eye = new ru.olamedia.math.Vector3f(position.getX(), position.getY(), position.getZ());
+ ru.olamedia.math.Vector3f eyef = eye;// .translate(look, 1f);
+ nearc = eyef.translate(look, nearD);
+ ru.olamedia.math.Vector3f farc = eyef.translate(look, farD);
+ final float tang = FastMath.tan(FastMath.toRad(fov) / 2.0f);
+ float nh = nearD * tang * (isFrustumVisible ? 0.3f : 1);// zNear * tang;
+ float nw = nh * aspect * aspect;
+ float fh = farD * tang * (isFrustumVisible ? 0.5f : 1);// zNear * tang;
+ float fw = fh * aspect * aspect;
+ ru.olamedia.math.Vector3f nrb = nearc.translate(right, -nw / 2).translate(up, -nh / 2);
+ ru.olamedia.math.Vector3f nlb = nearc.translate(right, nw / 2).translate(up, -nh / 2);
+ @SuppressWarnings("unused")
+ ru.olamedia.math.Vector3f nrt = nearc.translate(right, -nw / 2).translate(up, nh / 2);
+ ru.olamedia.math.Vector3f nlt = nearc.translate(right, nw / 2).translate(up, nh / 2);
+ ru.olamedia.math.Vector3f frb = farc.translate(right, -fw / 2).translate(up, -fh / 2);
+ ru.olamedia.math.Vector3f flb = farc.translate(right, fw / 2).translate(up, -fh / 2);
+ ru.olamedia.math.Vector3f frt = farc.translate(right, -fw / 2).translate(up, fh / 2);
+ ru.olamedia.math.Vector3f flt = farc.translate(right, fw / 2).translate(up, fh / 2);
+
+ frustum.leftPlane.set3Points(nlb, flb, flt);
+ frustum.leftPlane.n.negate();
+ frustum.rightPlane.set3Points(nrb, frt, frb);
+ // frustum.rightPlane.n.negate();
+ frustum.topPlane.set3Points(nlb, frb, flb);// nlt, frt, flt);
+ // frustum.topPlane.n.negate();
+ frustum.bottomPlane.set3Points(frt, nlt, flt);
+ // frustum.bottomPlane.n.negate();
+ frustum.nearPlane.set3Points(nlb, nlt, nrb);
+ frustum.farPlane.set3Points(flt, flb, frb);
+ }
+
+ private float[] matrixToTransposeArray(Matrix4f m) {
+ return new float[] {
+ //
+ m.m00, m.m01, m.m02, m.m03,//
+ m.m10, m.m11, m.m12, m.m13,//
+ m.m20, m.m21, m.m22, m.m23,//
+ m.m30, m.m31, m.m32, m.m33,//
+ };
+ }
+
+ private float[] matrixToArray(Matrix4f m) {
+ return new float[] {
+ //
+ m.m00, m.m10, m.m20, m.m30,//
+ m.m01, m.m11, m.m21, m.m31,//
+ m.m02, m.m12, m.m22, m.m32,//
+ m.m03, m.m13, m.m23, m.m33,//
+ };
+ }
+
+ private GLU glu;
+
+ public void setUp(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ updateKeyboard();
+ updateMouse();
+ if (glu == null) {
+ glu = new GLU();
+ }
+ // gl.glMatrixMode(GL2.GL_PROJECTION);
+ // gl.glLoadIdentity();
+ // glu.gluPerspective(100f, aspect, 0.2, 1000);
+ loadProjectionMatrix(drawable);
+ loadViewMatrix(drawable);
+
+ gl.glColor3f(1, 0, 0);
+ PlaneRenderer.render(frustum.leftPlane, drawable);
+ gl.glColor3f(1, 1, 0);
+ PlaneRenderer.render(frustum.rightPlane, drawable);
+ gl.glColor3f(1, 0, 1);
+ PlaneRenderer.render(frustum.topPlane, drawable);
+ gl.glColor3f(1, 1, 1);
+ PlaneRenderer.render(frustum.bottomPlane, drawable);
+
+ VectorRenderer.render(nearc, frustum.leftPlane.n, drawable);
+ }
+
+ private void loadViewMatrix(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ gl.glMatrixMode(GL2.GL_MODELVIEW);
+ gl.glLoadTransposeMatrixf(matrixToArray(viewMatrix), 0);
+ }
+
+ private void loadProjectionMatrix(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ gl.glMatrixMode(GL2.GL_PROJECTION);
+ gl.glLoadTransposeMatrixf(matrixToArray(projectionMatrix), 0);
+ }
+
+ private void packProjectionMatrix() {
+ projectionMatrix.setZero();
+ final float tang = FastMath.tan(FastMath.toRad(fov) / 2.0f);
+ final float size = zNear * tang;
+ float left = -size, right = size, bottom = -size / aspect, top = size / aspect;
+ // First Column
+ projectionMatrix.m00 = 2 * zNear / (right - left);
+ // Second Column
+ projectionMatrix.m11 = 2 * zNear / (top - bottom);
+ // Third Column
+ projectionMatrix.m20 = (right + left) / (right - left);
+ projectionMatrix.m21 = (top + bottom) / (top - bottom);
+ projectionMatrix.m22 = -(zFar + zNear) / (zFar - zNear);
+ projectionMatrix.m23 = -1;
+ // Fourth Column
+ projectionMatrix.m32 = -(2 * zFar * zNear) / (zFar - zNear);
+ }
+
+ private void packRotation() {
+ xRotationMatrix.rotX(toRad(pitch));
+ yRotationMatrix.rotY(toRad(yaw));
+ zRotationMatrix.rotZ(toRad(roll));
+
+ rotationMatrix.setIdentity();
+ rotationMatrix.mul(zRotationMatrix);
+ rotationMatrix.mul(yRotationMatrix);
+ rotationMatrix.mul(xRotationMatrix);
+ }
+
+ private void translatePoint(Vector3f point, Vector3f direction, float delta) {
+ point.x += direction.x * delta;
+ point.y += direction.y * delta;
+ point.z += direction.z * delta;
+ }
+
+ private void translate(Vector3f direction, float delta) {
+ translatePoint(position, direction, delta);
+ }
+
+ private void translate(float dx, float dy, float dz) {
+ translate(right, dx);
+ translate(up, dy);
+ translate(look, -dz);
+ }
+
+ private void packView() {
+ viewMatrix.setIdentity();
+ viewMatrix.mul(translationMatrix);
+ viewMatrix.mul(rotationMatrix);
+
+ }
+
+ private void packUpVector() {
+ up.set(viewMatrix.m01, viewMatrix.m11, viewMatrix.m21);
+ }
+
+ private void packRightVector() {
+ right.set(viewMatrix.m00, viewMatrix.m10, viewMatrix.m20);
+ }
+
+ private void packLookVector() {
+ look.set(viewMatrix.m02, viewMatrix.m12, viewMatrix.m22);
+ }
+
+ public MatrixCamera() {
+ right = new Vector3f(1, 0, 0);
+ up = new Vector3f(0, 1, 0);
+ look = new Vector3f(0, 0, 1);
+ isPitchLocked = true;
+ pack();
+ }
+
+ public void captureControls() {
+ Keyboard.setName("flyForward", KeyEvent.VK_W);
+ Keyboard.setName("flyBack", KeyEvent.VK_S);
+ Keyboard.setName("strafeLeft", KeyEvent.VK_A);
+ Keyboard.setName("strafeRight", KeyEvent.VK_D);
+ Keyboard.setName("flyUp", KeyEvent.VK_SPACE);
+ Keyboard.setName("flyDown", KeyEvent.VK_SHIFT);
+ }
+
+ public void mouseMoved(float dx, float dy) {
+ yaw += -dx;
+ pitch += -dy;
+ yaw = yaw % 360;
+ pitch = pitch % 360;
+ }
+
+ public void updateMouse() {
+ if (isPitchLocked) {
+ if (pitch < minPitch) {
+ pitch = minPitch;
+ } else if (pitch > maxPitch) {
+ pitch = maxPitch;
+ }
+ }
+ pack();
+ }
+
+ public void lockPitch(float min, float max) {
+ this.minPitch = min;
+ this.maxPitch = max;
+ isPitchLocked = true;
+ }
+
+ public void unlockPitch() {
+ isPitchLocked = false;
+ }
+
+ public void updateKeyboard() {
+ if (isAttachedToCameraman) {
+ this.cameraman.update(Game.instance.getDelta());
+ return;
+ }
+ // --- Keyboard
+ int left = Keyboard.isKeyDown("strafeLeft") ? 1 : 0;
+ int right = Keyboard.isKeyDown("strafeRight") ? 1 : 0;
+ int up = Keyboard.isKeyDown("flyForward") ? 1 : 0;
+ int down = Keyboard.isKeyDown("flyBack") ? 1 : 0;
+ int flyUp = Keyboard.isKeyDown("flyUp") ? 1 : 0;
+ int flyDown = Keyboard.isKeyDown("flyDown") ? 1 : 0;
+ float distance = 4f * 4.5f * Game.instance.getDelta(); // runspeed, m/s
+ if (up + down + right + left + flyDown + flyUp > 0) {
+ translate(//
+ right * distance - left * distance,//
+ (isAttachedToCameraman ? 0 : flyUp * distance - flyDown * distance),//
+ up * distance - down * distance//
+ );
+ pack();
+ // System.out.println("Moving... " + position.getX() + " "
+ // + position.getY() + " " + position.getZ());
+ }
+ }
+
+ protected Cameraman cameraman = null;
+ protected boolean isAttachedToCameraman = false;
+ protected float distanceFromCameraman = 0; // third-person view / 0 for
+ protected boolean lookToCameraman = false; // back/front third-person view
+
+ /**
+ * @return the fov
+ */
+ public float getFov() {
+ return fov;
+ }
+
+ /**
+ * @param fov
+ * the fov to set
+ */
+ public void setFov(float fov) {
+ this.fov = fov;
+ }
+
+ /**
+ * @return the aspect
+ */
+ public float getAspect() {
+ return aspect;
+ }
+
+ /**
+ * @param aspect
+ * the aspect to set
+ */
+ public void setAspect(float aspect) {
+ this.aspect = aspect;
+ }
+
+ /**
+ * @return the zNear
+ */
+ public float getzNear() {
+ return zNear;
+ }
+
+ /**
+ * @param zNear
+ * the zNear to set
+ */
+ public void setzNear(float zNear) {
+ this.zNear = zNear;
+ }
+
+ /**
+ * @return the zFar
+ */
+ public float getzFar() {
+ return zFar;
+ }
+
+ /**
+ * @param zFar
+ * the zFar to set
+ */
+ public void setzFar(float zFar) {
+ this.zFar = zFar;
+ }
+
+ /**
+ * @return the yaw
+ */
+ public float getYaw() {
+ return yaw;
+ }
+
+ /**
+ * @param yaw
+ * the yaw to set
+ */
+ public void setYaw(float yaw) {
+ this.yaw = yaw;
+ }
+
+ /**
+ * @return the pitch
+ */
+ public float getPitch() {
+ return pitch;
+ }
+
+ /**
+ * @param pitch
+ * the pitch to set
+ */
+ public void setPitch(float pitch) {
+ this.pitch = pitch;
+ }
+
+ /**
+ * @return the cameraman
+ */
+ public Cameraman getCameraman() {
+ return cameraman;
+ }
+
+ /**
+ * @param cameraman
+ * the cameraman to set
+ */
+ public void setCameraman(Cameraman cameraman) {
+ this.cameraman = cameraman;
+ }
+
+ /**
+ * @return the isAttachedToCameraman
+ */
+ public boolean isAttachedToCameraman() {
+ return isAttachedToCameraman;
+ }
+
+ /**
+ * @param isAttachedToCameraman
+ * the isAttachedToCameraman to set
+ */
+ public void setAttachedToCameraman(boolean isAttachedToCameraman) {
+ this.isAttachedToCameraman = isAttachedToCameraman;
+ }
+
+ /**
+ * @return the distanceFromCameraman
+ */
+ public float getDistanceFromCameraman() {
+ return distanceFromCameraman;
+ }
+
+ /**
+ * @param distanceFromCameraman
+ * the distanceFromCameraman to set
+ */
+ public void setDistanceFromCameraman(float distanceFromCameraman) {
+ this.distanceFromCameraman = distanceFromCameraman;
+ }
+
+ /**
+ * @return the lookToCameraman
+ */
+ public boolean isLookToCameraman() {
+ return lookToCameraman;
+ }
+
+ /**
+ * @param lookToCameraman
+ * the lookToCameraman to set
+ */
+ public void setLookToCameraman(boolean lookToCameraman) {
+ this.lookToCameraman = lookToCameraman;
+ }
+
+ public void setX(float x) {
+ position.x = x;
+ }
+
+ public void setY(float y) {
+ position.y = y;
+ }
+
+ public void setZ(float z) {
+ position.z = z;
+ }
+
+ public float getX() {
+ return position.x;
+ }
+
+ public float getY() {
+ return position.y;
+ }
+
+ public float getZ() {
+ return position.z;
+ }
+
+ public float[] getViewMatrixArray() {
+ return matrixToArray(viewMatrix);
+ }
+
+ public float[] getProjectionMatrixArray() {
+ return matrixToArray(viewMatrix);
+ }
+
+ public float getRoll() {
+ return roll;
+ }
+
+ public void attachTo(Cameraman player) {
+ this.cameraman = player;
+ this.isAttachedToCameraman = true;
+ this.cameraman.captureControls();
+ }
+
+ public void detach() {
+ this.isAttachedToCameraman = false;
+ this.captureControls();
+ }
+
+ /**
+ * @return the look
+ */
+ public Vector3f getLook() {
+ return look;
+ }
+
+ /**
+ * @return the right
+ */
+ public Vector3f getRight() {
+ return right;
+ }
+
+ /**
+ * @return the up
+ */
+ public Vector3f getUp() {
+ return up;
+ }
+
+}
diff --git a/src/ru/olamedia/camera/package-info.java b/src/ru/olamedia/camera/package-info.java
new file mode 100644
index 0000000..7a19b7f
--- /dev/null
+++ b/src/ru/olamedia/camera/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.camera; \ No newline at end of file
diff --git a/src/ru/olamedia/controls/package-info.java b/src/ru/olamedia/controls/package-info.java
new file mode 100644
index 0000000..09ce499
--- /dev/null
+++ b/src/ru/olamedia/controls/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.controls; \ No newline at end of file
diff --git a/src/ru/olamedia/debug/SystemInfo.java b/src/ru/olamedia/debug/SystemInfo.java
new file mode 100644
index 0000000..30060a5
--- /dev/null
+++ b/src/ru/olamedia/debug/SystemInfo.java
@@ -0,0 +1,24 @@
+package ru.olamedia.debug;
+
+public class SystemInfo {
+ public static void dump() {
+ int cpu = Runtime.getRuntime().availableProcessors();
+ long maxMemory = Runtime.getRuntime().maxMemory();
+ long totalMemory = Runtime.getRuntime().totalMemory();
+ long freeMemory = Runtime.getRuntime().freeMemory();
+ // String country = System.getProperty("user.country");
+ String username = System.getProperty("user.name");
+ String os = System.getProperty("os.name");
+ String osver = System.getProperty("os.version");
+ String arch = System.getProperty("os.arch");
+ System.out.println("Hello, " + username + " :)");
+ System.out.println("" + os + " " + arch + " " + osver);
+ System.out
+ .println("Total CPU: " + cpu + " Memory free/total/max: "
+ + ((int) Math.floor(freeMemory / (1024 * 1024))) + "/"
+ + ((int) Math.floor(totalMemory / (1024 * 1024))) + "/"
+ + ((int) Math.floor(maxMemory / (1024 * 1024))));
+ System.out.println(System.getProperty("java.vendor") + " " + System.getProperty("java.version"));
+ System.out.println(System.getProperty("java.runtime.name") + " " + System.getProperty("java.runtime.version"));
+ }
+}
diff --git a/src/ru/olamedia/debug/package-info.java b/src/ru/olamedia/debug/package-info.java
new file mode 100644
index 0000000..fbf0e84
--- /dev/null
+++ b/src/ru/olamedia/debug/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.debug; \ No newline at end of file
diff --git a/src/ru/olamedia/game/ClientGame.java b/src/ru/olamedia/game/ClientGame.java
new file mode 100644
index 0000000..1f0eeae
--- /dev/null
+++ b/src/ru/olamedia/game/ClientGame.java
@@ -0,0 +1,13 @@
+package ru.olamedia.game;
+
+public class ClientGame extends Game {
+ GameManager manager;
+ public ClientGame(GameManager manager) {
+ this.manager = manager;
+ }
+ public void pause(){
+ // open in-game menu
+ super.pause();
+ manager.start();
+ }
+}
diff --git a/src/ru/olamedia/game/DynamicJList.java b/src/ru/olamedia/game/DynamicJList.java
new file mode 100644
index 0000000..f944ba3
--- /dev/null
+++ b/src/ru/olamedia/game/DynamicJList.java
@@ -0,0 +1,16 @@
+package ru.olamedia.game;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JList;
+
+public class DynamicJList extends JList {
+ private static final long serialVersionUID = 8188447632893130182L;
+
+ public DynamicJList() {
+ super(new DefaultListModel());
+ }
+
+ public DefaultListModel getContents() {
+ return (DefaultListModel) getModel();
+ }
+}
diff --git a/src/ru/olamedia/game/Game.java b/src/ru/olamedia/game/Game.java
new file mode 100644
index 0000000..8e04259
--- /dev/null
+++ b/src/ru/olamedia/game/Game.java
@@ -0,0 +1,25 @@
+package ru.olamedia.game;
+
+public class Game {
+ public boolean isRunning = false;
+ public boolean isPaused = false;
+ public void dispose(){
+
+ }
+ public void start(){
+ isRunning = true;
+ init();
+ }
+ public void pause(){
+ isPaused = true;
+ }
+ public void resume(){
+ isPaused = false;
+ }
+ public void finish(){
+ isRunning = false;
+ }
+ public void init(){
+
+ }
+}
diff --git a/src/ru/olamedia/game/GameFrame.java b/src/ru/olamedia/game/GameFrame.java
new file mode 100644
index 0000000..e768b63
--- /dev/null
+++ b/src/ru/olamedia/game/GameFrame.java
@@ -0,0 +1,194 @@
+package ru.olamedia.game;
+
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.swing.JFrame;
+
+import ru.olamedia.asset.AssetManager;
+import ru.olamedia.asset.AssetNotFoundException;
+import ru.olamedia.input.Keyboard;
+import ru.olamedia.input.MouseJail;
+import ru.olamedia.olacraft.OlaCraft;
+
+import jogamp.newt.awt.NewtFactoryAWT;
+
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+
+public class GameFrame {
+ // java.awt.SystemTray
+ // http://www.oracle.com/technetwork/articles/javase/systemtray-139788.html
+
+ public static GameFrame instance;
+
+ Display display;
+ Screen screen;
+ int screenId;
+ GLProfile glProfile;
+ GLCapabilities caps;
+ protected Frame awtFrame;
+ protected static GLWindow glWindow;
+ protected static JFrame jFrame;
+ int width = 854;
+ int height = 480;
+ public static Animator animator;
+ NewtCanvasAWT newtCanvasAWT;
+ private boolean glMode = false;
+
+ public void initGL() {
+ if (null == newtCanvasAWT) {
+ glProfile = GLProfile.get(GLProfile.GL2);// Default();
+ // ES2
+ caps = new GLCapabilities(glProfile);
+ caps.setHardwareAccelerated(true);
+ caps.setDoubleBuffered(true);
+ caps.setBackgroundOpaque(false);
+
+ display = NewtFactoryAWT.createDisplay(null);
+ screen = NewtFactoryAWT.createScreen(display, screenId);
+ glWindow = GLWindow.create(screen, caps);// GLWindow.create(screen,
+ // caps);
+ newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ glWindow.setUndecorated(false);
+ glWindow.setPointerVisible(true);
+ glWindow.confinePointer(false);
+ glWindow.addWindowListener(new QuitAdapter());
+ animator = new Animator(glWindow);
+ animator.setRunAsFastAsPossible(true); // By default there is a
+ // brief
+ // pause in the animation
+ // loop
+ animator.start();
+ glWindow.addMouseListener(MouseJail.instance);
+ glWindow.addKeyListener(Keyboard.instance);
+ glWindow.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyReleased(KeyEvent e) {
+ super.keyReleased(e);
+ if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ glWindow.confinePointer(false);
+ glWindow.setPointerVisible(true);
+ }
+ }
+ });
+ // animator.setUpdateFPSFrames(100, System.err);
+ jFrame.add(newtCanvasAWT);
+ glWindow.addGLEventListener(GameManager.instance);
+ }
+ }
+
+ public void setGLMode() {
+ if (!glMode) {
+ initGL();
+ glMode = true;
+ newtCanvasAWT.setVisible(true);
+ }
+ }
+
+ public void setUIMode() {
+ if (glMode) {
+ glMode = false;
+ newtCanvasAWT.setVisible(false);
+ }
+ }
+
+ public static int getX() {
+ return jFrame.getX();
+ }
+
+ public static int getY() {
+ return jFrame.getY();
+ }
+
+ public static int getWidth() {
+ if (null == glWindow) {
+ return jFrame.getWidth();
+ }
+ return glWindow.getWidth();
+ }
+
+ public static int getHeight() {
+ if (null == glWindow) {
+ return jFrame.getHeight();
+ }
+ return glWindow.getHeight();
+ }
+
+ public GameFrame() {
+ instance = this;
+ jFrame = new JFrame();
+ jFrame.setMinimumSize(new Dimension(200, 200));
+ jFrame.setSize(width, height);
+ jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ jFrame.setTitle("OlaCraft " + OlaCraft.version);
+ setIcons();
+ // glWindow.setLocation(100, 100);
+ jFrame.addWindowListener(new QuitAdapter());
+ jFrame.setVisible(true);
+ }
+
+ private void setIcons() {
+ List<Image> icons = new ArrayList<Image>();
+ try {
+ icons.add(getImage("icon16x16.png"));
+ icons.add(getImage("icon32x32.png"));
+ icons.add(getImage("icon64x64.png"));
+ icons.add(getImage("icon128x128.png"));
+ icons.add(getImage("icon256x256.png"));
+ } catch (AssetNotFoundException e1) {
+ e1.printStackTrace();
+ }
+ // if (!icons.isEmpty()) {
+ // awtFrame.setIconImage(getImage("icon32x32.png"));
+ jFrame.setIconImages(icons);
+ // }
+ }
+
+ private Image getImage(String filename) throws AssetNotFoundException {
+ String iconFile = AssetManager.getAsset("ru/olamedia/game/" + filename).getFile();
+ return Toolkit.getDefaultToolkit().createImage(iconFile);
+ }
+
+ public Animator getAnimator() {
+ return animator;
+ }
+
+ public static void confinePointer(boolean confine) {
+ if (glWindow != null) {
+ glWindow.confinePointer(confine);
+ }
+ }
+
+ public static void setPointerVisible(boolean visible) {
+ if (glWindow != null) {
+ glWindow.setPointerVisible(visible);
+ }
+ }
+
+ public static GLWindow getWindow() {
+ return glWindow;
+ }
+
+ public static JFrame getFrame() {
+ return jFrame;
+ }
+
+ public void dispose() {
+ // glWindow.destroy();
+ // newtCanvasAWT.destroy();
+ jFrame.dispose();
+ // System.err.close();
+ }
+}
diff --git a/src/ru/olamedia/game/GameManager.java b/src/ru/olamedia/game/GameManager.java
new file mode 100644
index 0000000..f8c05d9
--- /dev/null
+++ b/src/ru/olamedia/game/GameManager.java
@@ -0,0 +1,165 @@
+package ru.olamedia.game;
+
+import java.util.Set;
+
+import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
+import javax.media.opengl.DebugGL2ES2;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.network.discovery.DiscoveryThread;
+import ru.olamedia.olacraft.render.jogl.DefaultRenderer;
+import ru.olamedia.olacraft.render.jogl.IRenderer;
+import ru.olamedia.tasks.TaskManager;
+
+
+import com.jogamp.opengl.JoglVersion;
+
+public class GameManager implements GLEventListener {
+ public static GameManager instance;
+ private GameFrame frame;
+ private ClientGame clientGame;
+ private ServerGame serverGame;
+ private IRenderer renderer;
+ private MainMenu menu;
+
+ public GameManager() {
+ instance = this;
+ }
+
+ private void createServerGame() {
+ if (null == serverGame) {
+ serverGame = new ServerGame(this);
+ }
+ }
+
+ private void createClientGame() {
+ if (null == clientGame) {
+ clientGame = new ClientGame(this);
+ }
+ }
+
+ public void startServerGame() {
+ createServerGame();
+ serverGame.start();
+ }
+
+ public void startClientGame() {
+ createClientGame();
+ clientGame.start();
+ }
+
+ public void resumeClientGame() {
+ createClientGame();
+ clientGame.resume();
+ }
+
+ public void finishClientGame() {
+ createClientGame();
+ clientGame.finish();
+ }
+
+ public void resumeServerGame() {
+ createServerGame();
+ serverGame.resume();
+ }
+
+ public void finishServerGame() {
+ createServerGame();
+ clientGame.finish();
+ serverGame.dispose();
+ }
+
+ private void init() {
+ this.frame = new GameFrame();
+ menu = new MainMenu();
+ this.renderer = new DefaultRenderer();
+ GameFrame.getFrame().getContentPane().add(menu);
+ menu.setVisible(true);
+ GameFrame.getFrame().validate();
+ }
+
+ public void start() {
+ init();
+ while (!QuitAdapter.shouldQuit) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void dispose() {
+ TaskManager.stopAll();
+ if (null != Game.server) {
+ Game.server.dispose();
+ }
+ if (null != Game.client) {
+ Game.client.dispose();
+ }
+ if (null != GameFrame.animator) {
+ if (GameFrame.animator.isStarted()) {
+ GameFrame.animator.stop();
+ }
+ }
+ frame.dispose();
+ // Get all threads
+ Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
+ for (Thread t : threadSet) {
+ if (t instanceof DiscoveryThread) {
+ t.interrupt();
+ }
+ }
+ }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ // GLContext.getContext().getGL()
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ //drawable.setGL(new DebugGL2ES2(gl));
+ System.err.println(JoglVersion.getGLInfo(drawable.getGL(), null));
+ System.err.println(Thread.currentThread() + " Chosen GLCapabilities: "
+ + drawable.getChosenGLCapabilities());
+ System.err.println(Thread.currentThread() + " INIT GL IS: " + gl.getClass().getName());
+ System.err.println(Thread.currentThread() + " GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+ System.err.println(Thread.currentThread() + " GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+ System.err.println(Thread.currentThread() + " GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println(Thread.currentThread() + " GL Profile: " + gl.getGLProfile());
+ System.err.println(Thread.currentThread() + " GL:" + gl);
+ System.err.println(Thread.currentThread() + " GL_VERSION=" + gl.glGetString(GL.GL_VERSION));
+ renderer.init(drawable);
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ //gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
+ renderer.render(drawable);
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ GL gl = drawable.getGL().getGL2ES2();
+ gl.glViewport(0, 0, width, height);
+ }
+
+ public void showMainMenu() {
+ menu.setVisible(true);
+ }
+
+ public void hideMainMenu() {
+ menu.setVisible(false);
+ }
+
+}
diff --git a/src/ru/olamedia/game/Launcher.java b/src/ru/olamedia/game/Launcher.java
new file mode 100644
index 0000000..7849468
--- /dev/null
+++ b/src/ru/olamedia/game/Launcher.java
@@ -0,0 +1,17 @@
+package ru.olamedia.game;
+
+public class Launcher {
+
+ public Launcher() {
+ }
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ GameManager manager = new GameManager();
+ manager.start();
+ manager.dispose();
+ }
+
+}
diff --git a/src/ru/olamedia/game/MainMenu.java b/src/ru/olamedia/game/MainMenu.java
new file mode 100644
index 0000000..1b3db13
--- /dev/null
+++ b/src/ru/olamedia/game/MainMenu.java
@@ -0,0 +1,168 @@
+package ru.olamedia.game;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.net.InetAddress;
+
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.network.ConnectionState;
+import ru.olamedia.olacraft.network.ConnectionStateListener;
+import ru.olamedia.olacraft.network.discovery.DiscoveryClient;
+import ru.olamedia.olacraft.network.discovery.DiscoveryListener;
+
+public class MainMenu extends JPanel implements ActionListener {
+ private JButton startButton;
+ private JButton startServerButton;
+ private JButton discoveryButton;
+ private DynamicJList hosts;
+ private DiscoveryClient discoveryClient = DiscoveryClient.getInstance();
+ private Thread discoveryClientThread;
+ private static final long serialVersionUID = -271797500986576805L;
+
+ private void stylizeButton(JButton b) {
+ Border line = new LineBorder(Color.BLACK);
+ Border margin = new EmptyBorder(5, 15, 5, 15);
+ Border compound = new CompoundBorder(line, margin);
+ b.setBackground(new Color(1f, 1f, 1f, 0.8f));
+ b.setBorder(compound);
+ }
+
+ private static boolean DEBUG = true;
+
+ @SuppressWarnings("unused")
+ private void debug(String s) {
+ if (DEBUG) {
+ System.out.println("[MainMenu] " + s);
+ }
+ }
+
+ public MainMenu() {
+ setSize(GameFrame.getWidth(), GameFrame.getHeight());
+ setOpaque(false);
+ // setBackground(new Color(0f, 0f, 0f, 0.8f));
+ startButton = new JButton();
+ startButton.setSize(500, 40);
+ startButton.setLocation((GameFrame.getWidth() - 500) / 2, 200);
+ startButton.setText("JOIN GAME");
+ startButton.setEnabled(false);
+ startButton.setActionCommand("connect");
+ startButton.addActionListener(this);
+ stylizeButton(startButton);
+ startServerButton = new JButton();
+ startServerButton.setSize(500, 40);
+ startServerButton.setLocation((GameFrame.getWidth() - 500) / 2, 260);
+ startServerButton.setText("START SERVER");
+ startServerButton.setActionCommand("start server");
+ startServerButton.addActionListener(this);
+ stylizeButton(startServerButton);
+ discoveryButton = new JButton();
+ discoveryButton.setSize(500, 40);
+ discoveryButton.setLocation((GameFrame.getWidth() - 500) / 2, 320);
+ discoveryButton.setText("REFRESH");
+ discoveryButton.setActionCommand("discovery lan");
+ discoveryButton.addActionListener(this);
+ stylizeButton(discoveryButton);
+ hosts = new DynamicJList();
+ hosts.setSize(500, 150);
+ hosts.setLocation((GameFrame.getWidth() - 500) / 2, 10);
+ hosts.addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ if (hosts.getContents().isEmpty()) {
+ Game.client.setHostname("127.0.0.1");
+ System.out.println("Selected: none");
+ startButton.setEnabled(false);
+ } else {
+ String host = (String) hosts.getContents().get(e.getFirstIndex());
+ Game.client.setHostname(host);
+ System.out.println("Selected: " + host);
+ startButton.setEnabled(true);
+ }
+ }
+ });
+ add(hosts);
+ add(startButton);
+ add(startServerButton);
+ add(discoveryButton);
+ // LAN discover
+ // InetAddress address = Game.client.discoverHost(54777, 5000);
+ // System.out.println(address);
+ setLayout(new BorderLayout());
+ validate();
+ Game.client.addStateListener(new ConnectionStateListener() {
+ @Override
+ public void onChangeState(ConnectionState state) {
+ // debug("Client ConnectionState changed");
+ if (state.isConnected()) {
+ GameFrame.instance.setGLMode();
+ Game.instance.player.captureControls();
+ startButton.setText("LEAVE GAME");
+ } else {
+ GameFrame.instance.setUIMode();
+ startButton.setText("JOIN GAME");
+ }
+ }
+ });
+ discoveryClient.addHostListener(new DiscoveryListener() {
+ @Override
+ public void onHost(InetAddress address) {
+ if (null == address) {
+ discoveryButton.setEnabled(true);
+ } else {
+ hosts.getContents().addElement(address.getHostAddress());
+ }
+ }
+ });
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ if (cmd.equals("connect")) {
+ if (null != Game.instance) {
+ Game.instance = null;
+ }
+ Game.instance = new Game(Game.MODE_MULTIPLAYER);
+ if (Game.client.isConnected()) {
+ // LEAVE GAME
+ Game.client.close();
+ } else {
+ Game.client.connect();
+ }
+ Game.instance.start();
+ }
+ if (cmd.equals("start server")) {
+ startServerButton.setEnabled(false);
+ if (Game.server.isRunning()) {
+ Game.server.stop();
+ startServerButton.setText("START SERVER");
+ startServerButton.setEnabled(true);
+ } else {
+ Game.server.start();
+ if (Game.server.isRunning()) {
+ startServerButton.setText("STOP SERVER");
+ startServerButton.setEnabled(true);
+ } else {
+ startServerButton.setEnabled(true);
+ }
+ }
+ }
+ if (cmd.equals("discovery lan")) {
+ discoveryButton.setEnabled(false);
+ discoveryClientThread = new Thread(DiscoveryClient.getInstance(), "DISCOVERY CLIENT");
+ discoveryClientThread.start();
+ hosts.getContents().clear();
+ }
+ }
+}
diff --git a/src/ru/olamedia/game/QuitAdapter.java b/src/ru/olamedia/game/QuitAdapter.java
new file mode 100644
index 0000000..8de1e8a
--- /dev/null
+++ b/src/ru/olamedia/game/QuitAdapter.java
@@ -0,0 +1,71 @@
+package ru.olamedia.game;
+
+import com.jogamp.newt.event.*;
+
+public class QuitAdapter extends WindowAdapter implements WindowListener, KeyListener, java.awt.event.WindowListener {
+ public static boolean shouldQuit = false;
+
+ public boolean shouldQuit() {
+ return shouldQuit;
+ }
+
+ public void windowDestroyNotify(WindowEvent e) {
+ System.err.println("QUIT Window " + Thread.currentThread());
+ shouldQuit = true;
+ }
+
+ public void keyTyped(KeyEvent e) {
+ if (e.getKeyChar() == 'q') {
+ System.err.println("QUIT Key " + Thread.currentThread());
+ shouldQuit = true;
+ }
+ }
+
+ public void keyPressed(KeyEvent e) {
+ }
+
+ public void keyReleased(KeyEvent e) {
+ }
+
+ @Override
+ public void windowActivated(java.awt.event.WindowEvent arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowClosed(java.awt.event.WindowEvent arg0) {
+ // TODO Auto-generated method stub
+ shouldQuit = true;
+ }
+
+ @Override
+ public void windowClosing(java.awt.event.WindowEvent arg0) {
+ System.err.println("QUIT Window " + Thread.currentThread());
+ shouldQuit = true;
+ }
+
+ @Override
+ public void windowDeactivated(java.awt.event.WindowEvent arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowDeiconified(java.awt.event.WindowEvent arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowIconified(java.awt.event.WindowEvent arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowOpened(java.awt.event.WindowEvent arg0) {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/src/ru/olamedia/game/ServerGame.java b/src/ru/olamedia/game/ServerGame.java
new file mode 100644
index 0000000..900a93f
--- /dev/null
+++ b/src/ru/olamedia/game/ServerGame.java
@@ -0,0 +1,10 @@
+package ru.olamedia.game;
+
+public class ServerGame extends Game {
+ GameManager manager;
+
+ public ServerGame(GameManager manager) {
+ this.manager = manager;
+ }
+
+}
diff --git a/src/ru/olamedia/game/icon128x128.png b/src/ru/olamedia/game/icon128x128.png
new file mode 100644
index 0000000..3572950
--- /dev/null
+++ b/src/ru/olamedia/game/icon128x128.png
Binary files differ
diff --git a/src/ru/olamedia/game/icon16x16.png b/src/ru/olamedia/game/icon16x16.png
new file mode 100644
index 0000000..1e2d694
--- /dev/null
+++ b/src/ru/olamedia/game/icon16x16.png
Binary files differ
diff --git a/src/ru/olamedia/game/icon256x256.png b/src/ru/olamedia/game/icon256x256.png
new file mode 100644
index 0000000..441eae8
--- /dev/null
+++ b/src/ru/olamedia/game/icon256x256.png
Binary files differ
diff --git a/src/ru/olamedia/game/icon32x32.png b/src/ru/olamedia/game/icon32x32.png
new file mode 100644
index 0000000..78a1277
--- /dev/null
+++ b/src/ru/olamedia/game/icon32x32.png
Binary files differ
diff --git a/src/ru/olamedia/game/icon64x64.png b/src/ru/olamedia/game/icon64x64.png
new file mode 100644
index 0000000..34a184b
--- /dev/null
+++ b/src/ru/olamedia/game/icon64x64.png
Binary files differ
diff --git a/src/ru/olamedia/game/package-info.java b/src/ru/olamedia/game/package-info.java
new file mode 100644
index 0000000..86a2d0d
--- /dev/null
+++ b/src/ru/olamedia/game/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.game; \ No newline at end of file
diff --git a/src/ru/olamedia/geom/DisplayList.java b/src/ru/olamedia/geom/DisplayList.java
new file mode 100644
index 0000000..aeaffc7
--- /dev/null
+++ b/src/ru/olamedia/geom/DisplayList.java
@@ -0,0 +1,39 @@
+package ru.olamedia.geom;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+
+public class DisplayList {
+ private GL2 gl;
+ private int glDL;
+
+ public DisplayList(GL glx) {
+ gl = glx.getGL2();
+ glDL = gl.glGenLists(1);
+ }
+
+ public void start() {
+ gl.glNewList(glDL, GL2.GL_COMPILE);
+ }
+
+ public void stop() {
+ gl.glEndList();
+ }
+
+ public void render() {
+ gl.glCallList(glDL);
+ }
+
+ public void destroy() {
+ gl.glDeleteLists(glDL, 1);
+ }
+
+ public void begin() {
+ start();
+ }
+
+ public void end() {
+ stop();
+ }
+}
diff --git a/src/ru/olamedia/geom/Frustum.java b/src/ru/olamedia/geom/Frustum.java
new file mode 100644
index 0000000..5428302
--- /dev/null
+++ b/src/ru/olamedia/geom/Frustum.java
@@ -0,0 +1,11 @@
+package ru.olamedia.geom;
+
+//import org.openmali.spatial.bodies.Frustum;
+
+public class Frustum extends org.openmali.spatial.bodies.Frustum {
+
+ public Frustum() {
+ super();
+ }
+
+}
diff --git a/src/ru/olamedia/geom/Mesh.java b/src/ru/olamedia/geom/Mesh.java
new file mode 100644
index 0000000..140cc4d
--- /dev/null
+++ b/src/ru/olamedia/geom/Mesh.java
@@ -0,0 +1,346 @@
+package ru.olamedia.geom;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.texture.Texture;
+
+public class Mesh {
+ private FloatBuffer buffer;
+ private float[] data;
+ private int ptr;
+ private int vertexCount;
+ private int vertexPtr;
+ private float xOffset;
+ private float yOffset;
+ private float zOffset;
+
+ private boolean useColor;
+ private float red = 1f;
+ private float green = 1f;
+ private float blue = 1f;
+ private float alpha = 1f;
+
+ private boolean useTexture;
+ private float GLTexture;
+ private float u = 0f;
+ private float v = 0f;
+ @SuppressWarnings("unused")
+ private float uFactor = 1f;
+ @SuppressWarnings("unused")
+ private float vFactor = 1f;
+
+ private boolean wireframe = false;
+
+ private static int vertexSize = 10;
+
+ private GLArrayDataServer interleaved;
+ private HashMap<Integer, Integer> materials = new HashMap<Integer, Integer>();
+ private HashMap<Integer, GLArrayDataServer> arrays = new HashMap<Integer, GLArrayDataServer>();
+
+ public void setTexture(Texture tex) {
+ if (null != tex) {
+ setTextureSize(tex.getWidth(), tex.getHeight());
+ setGLTexture(tex.getTextureObject(null));
+ }
+ }
+
+ public void setGLTexture(int tex) {
+ this.GLTexture = tex;
+ }
+
+ @SuppressWarnings("unused")
+ private static boolean useVbo = true;
+
+ private static boolean useQuad = true;
+ private static boolean useDisplayList = false;
+ private DisplayList DL;
+
+ public Mesh(int size) {
+ vertexCount = 0;
+ data = new float[size * vertexSize];
+ // data = new float[size * vertexSize];
+ vertexPtr = 0;
+ useTexture = false;
+ useColor = false;
+ }
+
+ private static FloatBuffer generateFloatBuffer(int size) {
+ return ByteBuffer.allocateDirect(size * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
+ }
+
+ /**
+ * Reallocates an array with a new size, and copies the contents of the old
+ * array to the new array.
+ *
+ * @param oldArray
+ * the old array, to be reallocated.
+ * @param newSize
+ * the new array size.
+ * @return A new array with the same contents.
+ */
+ private static float[] resizeArray(float[] oldArray, int newSize) {
+ int oldSize = oldArray.length;
+ float[] newArray = new float[newSize];
+ int preserveLength = Math.min(oldSize, newSize);
+ if (preserveLength > 0)
+ System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
+ return newArray;
+ }
+
+ public void compact() {
+ // data = resizeArray(data, vertexCount * vertexSize);
+ int size = vertexCount * vertexSize;
+ buffer = generateFloatBuffer(size);
+ buffer.position(0);
+ buffer.put(data, 0, size);
+ data = null;
+ // calc vertex count for each material
+ for (int n = 0; n < vertexCount; n++) {
+ int tex = (int) buffer.get(vertexSize * n + 9);
+ if (!materials.containsKey(tex)) {
+ materials.put(tex, 1);
+ } else {
+ materials.put(tex, materials.get(tex) + 1);
+ }
+ }
+ for (Integer m : materials.keySet()) {
+ int matVertCount = materials.get(m);
+ final GLArrayDataServer interleaved = GLArrayDataServer.createFixedInterleaved(9, GL2.GL_FLOAT, false,
+ matVertCount, GL.GL_STATIC_DRAW);
+ interleaved.addFixedSubArray(GLPointerFunc.GL_VERTEX_ARRAY, 3, GL.GL_ARRAY_BUFFER);
+ interleaved.addFixedSubArray(GLPointerFunc.GL_COLOR_ARRAY, 4, GL.GL_ARRAY_BUFFER);
+ interleaved.addFixedSubArray(GLPointerFunc.GL_TEXTURE_COORD_ARRAY, 2, GL.GL_ARRAY_BUFFER);
+ arrays.put(m, interleaved);
+ }
+ for (int n = 0; n < vertexCount; n++) {
+ int m = (int) buffer.get(vertexSize * n + 9);
+ final GLArrayDataServer interleaved = arrays.get(m);
+ interleaved.putf(buffer.get(vertexSize * n + 0));
+ interleaved.putf(buffer.get(vertexSize * n + 1));
+ interleaved.putf(buffer.get(vertexSize * n + 2));
+ interleaved.putf(buffer.get(vertexSize * n + 3));
+ interleaved.putf(buffer.get(vertexSize * n + 4));
+ interleaved.putf(buffer.get(vertexSize * n + 5));
+ interleaved.putf(buffer.get(vertexSize * n + 6));
+ interleaved.putf(buffer.get(vertexSize * n + 7));
+ interleaved.putf(buffer.get(vertexSize * n + 8));
+ }
+ for (Integer m : materials.keySet()) {
+ final GLArrayDataServer interleaved = arrays.get(m);
+ interleaved.seal(true);
+ }
+ // interleaved.put(buffer);
+ if (vertexCount > 0) {
+ // System.out.println(interleaved);
+ }
+ /*
+ * buffer.position(0);
+ * buffer.limit(size * vertexSize);
+ * buffer.position(0);
+ * buffer.limit(vertexCount * vertexSize);
+ * buffer.compact();
+ * buffer.position(0);
+ */
+ }
+
+ public void endMesh() {
+ compact();
+ }
+
+ public void setTranslation(float x, float y, float z) {
+ xOffset = x;
+ yOffset = y;
+ zOffset = z;
+ }
+
+ public void setPoint3f(float x, float y, float z) {
+ ptr = vertexPtr * vertexSize;
+ data[ptr + 0] = x + xOffset;
+ // buffer.put(x + xOffset);
+ data[ptr + 1] = y + yOffset;
+ // buffer.put(y + yOffset);
+ data[ptr + 2] = z + zOffset;
+ // buffer.put(z + zOffset);
+ if (useColor) {
+ data[ptr + 3] = red;
+ // buffer.put(red);
+ data[ptr + 4] = green;
+ // buffer.put(green);
+ data[ptr + 5] = blue;
+ // buffer.put(blue);
+ data[ptr + 6] = alpha;
+ // buffer.put(alpha);
+ } else {
+ // buffer.put(1f);
+ // buffer.put(1f);
+ // buffer.put(1f);
+ // buffer.put(1f);
+ }
+ if (useTexture) {
+ // buffer.put(GLTexture);
+ data[ptr + 7] = u;// * uFactor;
+ // buffer.put(u);
+ data[ptr + 8] = v;// * vFactor;
+ data[ptr + 9] = GLTexture;
+ // buffer.put(v);
+ } else {
+ // buffer.put(0f);
+ // buffer.put(0f);
+ // buffer.put(0f);
+ }
+ vertexPtr++;
+ vertexCount++;
+ }
+
+ public void setColor4f(float red, float green, float blue, float alpha) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ this.alpha = alpha;
+ }
+
+ public void useColor() {
+ useColor = true;
+ }
+
+ public void useTexture() {
+ useTexture = true;
+ }
+
+ public void setUV(float u, float v) {
+ this.u = u;
+ this.v = v;
+ }
+
+ public void setTextureSize(float uSize, float vSize) {
+ this.uFactor = uSize;
+ this.vFactor = vSize;
+ }
+
+ public boolean joglIsVBOAvailable(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ return gl.isFunctionAvailable("glGenBuffers") && gl.isFunctionAvailable("glBindBuffer")
+ && gl.isFunctionAvailable("glBufferData") && gl.isFunctionAvailable("glDeleteBuffers");
+ }
+
+ public void joglCreateVBO(GLAutoDrawable drawable) {
+ @SuppressWarnings("unused")
+ GL2 gl = drawable.getGL().getGL2();
+ // gl.glInterleavedArrays(GL2.GL_T2F_C4F_N3F_V3F, stride, pointer)
+
+ }
+
+ public void joglRender(GL glx) {
+ if (vertexCount < 1) {
+ return;
+ }
+ GL2 gl;
+ GL2ES2 es2;
+ gl = glx.getGL2();
+ if (useDisplayList) {
+ gl.glEnable(GL2.GL_CULL_FACE);
+ gl.glEnable(GL2.GL_DEPTH_TEST);
+ }
+ if (wireframe) {
+ // Set wireframe mode
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_LINE);
+ } else {
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL);
+ }
+
+ if (useVbo) {
+ // es2 = glx.getGL2ES2();
+ // gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, data);
+
+ // gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
+ // gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
+ for (Integer m : materials.keySet()) {
+ //final GLArrayDataServer interleaved = arrays.get(m);
+ arrays.get(m).enableBuffer(gl, true);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ gl.glEnable(GL2.GL_CULL_FACE);
+ gl.glEnable(GL2.GL_DEPTH_TEST);
+ 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.glBindTexture(GL.GL_TEXTURE_2D, (int) m);
+ gl.glDrawArrays(GL2.GL_QUADS, 0, arrays.get(m).getElementCount());
+ arrays.get(m).enableBuffer(gl, false);
+ }
+ /*
+ * gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
+ * gl.glVertexPointer(3, GL2.GL_FLOAT, 10, buffer);
+ * gl.glDrawArrays(GL2.GL_QUADS, 0, vertexCount);
+ * gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
+ */
+
+ } else {
+ if (useDisplayList) {
+ if (DL == null) {
+ DL = new DisplayList(glx);
+ } else {
+ 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);
+ DL.render();
+ return;
+ }
+ DL.begin();
+ }
+ gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_POLYGON_BIT | GL2.GL_TEXTURE_BIT);
+ if (useTexture) {
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ 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);
+ }
+ for (int quadI = 0; quadI < vertexCount / 4; quadI++) {
+ ptr = (quadI * 4 + 0) * vertexSize;
+ if (useTexture) {
+ gl.glBindTexture(GL.GL_TEXTURE_2D, (int) buffer.get(ptr + 9));
+ 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.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
+ // gl.glDisable(GL.GL_BLEND);
+ // gl.glTexParameterf(GL.GL_TEXTURE_2D,
+ // GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
+ }
+ if (useQuad) {
+ gl.glBegin(GL2.GL_QUADS);
+ } else {
+ gl.glBegin(GL2.GL_TRIANGLE_STRIP);
+ }
+ {
+ for (int i = 0; i < 4; i++) {
+ int k = (useQuad) ? i : ((i == 2) ? 3 : (i == 3 ? 2 : i));
+ ptr = (quadI * 4 + k) * vertexSize;
+ if (useColor) {
+ gl.glColor4f(buffer.get(ptr + 3), buffer.get(ptr + 4), buffer.get(ptr + 5),
+ buffer.get(ptr + 6));
+ }
+ if (useTexture) {
+ float u = buffer.get(ptr + 7);
+ float v = buffer.get(ptr + 8);
+ gl.glTexCoord2f(u, v);
+ }
+ gl.glVertex3f(buffer.get(ptr), buffer.get(ptr + 1), buffer.get(ptr + 2));
+ }
+ }
+ gl.glEnd();
+ }
+ gl.glPopAttrib();
+ if (useDisplayList) {
+ DL.end();
+ DL.render();
+ }
+ }
+ }
+}
diff --git a/src/ru/olamedia/geom/Quad.java b/src/ru/olamedia/geom/Quad.java
new file mode 100644
index 0000000..e3d34dd
--- /dev/null
+++ b/src/ru/olamedia/geom/Quad.java
@@ -0,0 +1,12 @@
+package ru.olamedia.geom;
+
+public class Quad {
+ private float[] vertices;
+ private int vertexCount;
+
+ public void addVertex(float x, float y, float z) {
+ vertices[vertexCount] = x;
+ vertices[vertexCount + 1] = y;
+ vertices[vertexCount + 2] = z;
+ }
+}
diff --git a/src/ru/olamedia/geom/SimpleQuadMesh.java b/src/ru/olamedia/geom/SimpleQuadMesh.java
new file mode 100644
index 0000000..42cf439
--- /dev/null
+++ b/src/ru/olamedia/geom/SimpleQuadMesh.java
@@ -0,0 +1,113 @@
+package ru.olamedia.geom;
+
+public class SimpleQuadMesh extends Mesh {
+
+ public SimpleQuadMesh(int size) {
+ super(size * 4);
+ }
+
+ private void addBottomLeftBackVertex() {
+ setPoint3f(-0.5f, -0.5f, -0.5f);
+ }
+
+ private void addBottomLeftFrontVertex() {
+ setPoint3f(-0.5f, -0.5f, 0.5f);
+ }
+
+ private void addBottomRightBackVertex() {
+ setPoint3f(0.5f, -0.5f, -0.5f);
+ }
+
+ private void addBottomRightFrontVertex() {
+ setPoint3f(0.5f, -0.5f, 0.5f);
+ }
+
+ private void addTopLeftBackVertex() {
+ setPoint3f(-0.5f, 0.5f, -0.5f);
+ }
+
+ private void addTopLeftFrontVertex() {
+ setPoint3f(-0.5f, 0.5f, 0.5f);
+ }
+
+ private void addTopRightBackVertex() {
+ setPoint3f(0.5f, 0.5f, -0.5f);
+ }
+
+ private void addTopRightFrontVertex() {
+ setPoint3f(0.5f, 0.5f, 0.5f);
+ }
+
+ public void addFrontQuad() {
+ // triangle strip: И
+ setUV(0, 1);
+ addTopLeftFrontVertex(); // top left
+ setUV(0, 0);
+ addBottomLeftFrontVertex(); // bottom left
+ setUV(1, 0);
+ addBottomRightFrontVertex(); // bottom right
+ setUV(1, 1);
+ addTopRightFrontVertex(); // top right
+ }
+
+ public void addBackQuad() {
+ // triangle strip: И
+ setUV(0, 1);
+ addTopRightBackVertex();
+ setUV(0, 0);
+ addBottomRightBackVertex();
+ setUV(1, 0);
+ addBottomLeftBackVertex();
+ setUV(1, 1);
+ addTopLeftBackVertex();
+ }
+
+ public void addLeftQuad() {
+ // triangle strip: И
+ setUV(0, 1);
+ addTopLeftBackVertex();
+ setUV(0, 0);
+ addBottomLeftBackVertex();
+ setUV(1, 0);
+ addBottomLeftFrontVertex();
+ setUV(1, 1);
+ addTopLeftFrontVertex();
+ }
+
+ public void addRightQuad() {
+ // triangle strip: И
+ setUV(0, 1);
+ addTopRightFrontVertex();
+ setUV(0, 0);
+ addBottomRightFrontVertex();
+ setUV(1, 0);
+ addBottomRightBackVertex();
+ setUV(1, 1);
+ addTopRightBackVertex();
+ }
+
+ public void addTopQuad() {
+ // triangle strip: И
+ setUV(0, 0);
+ addTopLeftBackVertex();
+ setUV(0, 1);
+ addTopLeftFrontVertex();
+ setUV(1, 1);
+ addTopRightFrontVertex();
+ setUV(1, 0);
+ addTopRightBackVertex();
+ }
+
+ public void addBottomQuad() {
+ // triangle strip: И
+ setUV(0, 0);
+ addBottomLeftFrontVertex();
+ setUV(0, 1);
+ addBottomLeftBackVertex();
+ setUV(1, 1);
+ addBottomRightBackVertex();
+ setUV(1, 0);
+ addBottomRightFrontVertex();
+ }
+
+}
diff --git a/src/ru/olamedia/geom/package-info.java b/src/ru/olamedia/geom/package-info.java
new file mode 100644
index 0000000..97fe3c5
--- /dev/null
+++ b/src/ru/olamedia/geom/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.geom; \ No newline at end of file
diff --git a/src/ru/olamedia/input/AWTRobotUtil.java b/src/ru/olamedia/input/AWTRobotUtil.java
new file mode 100644
index 0000000..9c6778c
--- /dev/null
+++ b/src/ru/olamedia/input/AWTRobotUtil.java
@@ -0,0 +1,97 @@
+package ru.olamedia.input;
+
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+import java.lang.reflect.InvocationTargetException;
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.Robot;
+
+public class AWTRobotUtil {
+
+ private static final int ROBOT_DELAY = 100; // ms
+
+ public static Point getCenterLocation(Object obj, boolean onTitleBarIfWindow) throws InterruptedException,
+ InvocationTargetException {
+ Component comp = null;
+ com.jogamp.newt.Window win = null;
+
+ if (obj instanceof com.jogamp.newt.Window) {
+ win = (com.jogamp.newt.Window) obj;
+ } else if (obj instanceof Component) {
+ comp = (Component) obj;
+ } else {
+ throw new RuntimeException("Neither AWT nor NEWT: " + obj);
+ }
+
+ int x0, y0;
+ if (null != comp) {
+ java.awt.Point p0 = comp.getLocationOnScreen();
+ java.awt.Rectangle r0 = comp.getBounds();
+ if (onTitleBarIfWindow && comp instanceof java.awt.Window) {
+ java.awt.Window window = (java.awt.Window) comp;
+ java.awt.Insets insets = window.getInsets();
+ y0 = (int) (p0.getY() + insets.top / 2.0 + .5);
+ } else {
+ y0 = (int) (p0.getY() + r0.getHeight() / 2.0 + .5);
+ }
+ x0 = (int) (p0.getX() + r0.getWidth() / 2.0 + .5);
+ } else {
+ javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null);
+ if (onTitleBarIfWindow) {
+ javax.media.nativewindow.util.InsetsImmutable insets = win.getInsets();
+ p0.translate(win.getWidth() / 2, insets.getTopHeight() / 2);
+ } else {
+ javax.media.nativewindow.util.InsetsImmutable insets = win.getInsets();
+ p0.translate(win.getWidth() / 2, (win.getHeight() - insets.getTopHeight()) / 2);
+ }
+ x0 = p0.getX();
+ y0 = p0.getY();
+ }
+
+ return new Point(x0, y0);
+ }
+
+ /**
+ * centerMouse
+ */
+ public static Point centerMouse(Robot robot, Object obj, boolean onTitleBarIfWindow) throws AWTException,
+ InterruptedException, InvocationTargetException {
+
+ Point p0 = getCenterLocation(obj, onTitleBarIfWindow);
+ // System.err.println("centerMouse: robot pos: " + p0 +
+ // ", onTitleBarIfWindow: " + onTitleBarIfWindow);
+
+ robot.mouseMove((int) p0.getX(), (int) p0.getY());
+ // robot.delay(ROBOT_DELAY);
+ return p0;
+ }
+
+}
diff --git a/src/ru/olamedia/input/KeyListener.java b/src/ru/olamedia/input/KeyListener.java
new file mode 100644
index 0000000..8fb5d49
--- /dev/null
+++ b/src/ru/olamedia/input/KeyListener.java
@@ -0,0 +1,10 @@
+package ru.olamedia.input;
+
+import com.jogamp.newt.event.KeyEvent;
+
+public interface KeyListener {
+ public void onKeyPressed(String name, KeyEvent e);
+
+ public void onKeyReleased(String name, KeyEvent e);
+
+}
diff --git a/src/ru/olamedia/input/Keyboard.java b/src/ru/olamedia/input/Keyboard.java
new file mode 100644
index 0000000..6a9ecbd
--- /dev/null
+++ b/src/ru/olamedia/input/Keyboard.java
@@ -0,0 +1,64 @@
+package ru.olamedia.input;
+
+import java.awt.event.KeyEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.collections.BidiMap;
+import org.apache.commons.collections.bidimap.DualHashBidiMap;
+
+public class Keyboard implements com.jogamp.newt.event.KeyListener {
+ public static Keyboard instance = new Keyboard();
+ private static boolean[] downState = new boolean[256];
+ private static BidiMap names = new DualHashBidiMap();
+
+ public static void setName(String name, int keyCode) {
+ names.put(name, keyCode);
+ }
+
+ public static boolean isKeyDown(int keyCode) {
+ return downState[keyCode];
+ }
+
+ public static boolean isKeyDown(String name) {
+ if (names.containsKey(name)) {
+ return downState[((Integer) names.get(name)).intValue()];
+ }
+ return false;
+ }
+
+ private static List<ru.olamedia.input.KeyListener> listeners = new ArrayList<ru.olamedia.input.KeyListener>();
+
+ public static void attach(ru.olamedia.input.KeyListener l) {
+ listeners.add(l);
+ }
+
+ @Override
+ public void keyPressed(com.jogamp.newt.event.KeyEvent e) {
+ downState[e.getKeyCode()] = true;
+ if (names.containsValue(e.getKeyCode())) {
+ String name = (String) names.getKey(e.getKeyCode());
+ for (ru.olamedia.input.KeyListener l : listeners) {
+ l.onKeyPressed(name, e);
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(com.jogamp.newt.event.KeyEvent e) {
+ downState[e.getKeyCode()] = false;
+ if (names.containsValue(e.getKeyCode())) {
+ String name = (String) names.getKey(e.getKeyCode());
+ for (ru.olamedia.input.KeyListener l : listeners) {
+ l.onKeyReleased(name, e);
+ }
+ }
+ }
+
+ @Override
+ public void keyTyped(com.jogamp.newt.event.KeyEvent arg0) {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/src/ru/olamedia/input/MouseJail.java b/src/ru/olamedia/input/MouseJail.java
new file mode 100644
index 0000000..bd12b0a
--- /dev/null
+++ b/src/ru/olamedia/input/MouseJail.java
@@ -0,0 +1,113 @@
+package ru.olamedia.input;
+
+import java.awt.AWTException;
+import java.awt.Point;
+import java.awt.Robot;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jogamp.newt.event.MouseAdapter;
+import com.jogamp.newt.event.MouseEvent;
+
+import ru.olamedia.game.GameFrame;
+
+public class MouseJail extends MouseAdapter {
+ public static MouseJail instance = new MouseJail();
+
+ public MouseJail() {
+ }
+
+ private static boolean isActive = false;
+
+ /**
+ * @return the isActive
+ */
+ public static boolean isActive() {
+ return isActive;
+ }
+
+ /**
+ * @param isActive
+ * the isActive to set
+ */
+ public static void setActive(boolean isActive) {
+ System.out.println("Mouse jail " + (isActive ? "active" : "not active"));
+ MouseJail.isActive = isActive;
+ GameFrame.confinePointer(isActive);
+ GameFrame.setPointerVisible(!isActive);
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.isAltDown()) {
+ setActive(false);
+ } else {
+ setActive(true);
+ }
+ for (ru.olamedia.input.MouseListener l : listeners) {
+ l.onMouseClick();
+ }
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ System.out.println("Entered");
+
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ System.out.println("Exited");
+ isActive = false;
+ if (isActive) {
+ //moveToCenter();
+ }
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ onMove(e);
+ }
+
+ private float sensitivity = 2f;
+
+ private void onMove(MouseEvent e) {
+ if (isActive) {
+ int cx = GameFrame.getWidth() / 2;
+ int cy = GameFrame.getHeight() / 2;
+ float dx = e.getX() - cx;
+ float dy = e.getY() - cy;
+ dx *= sensitivity / 10;
+ dy *= sensitivity / 10;
+ // System.out.println("Mouse moved " + " dx:" + dx + " dy:" + dy
+ // + " x:" + e.getX() + " y:" + e.getY());
+ for (ru.olamedia.input.MouseListener l : listeners) {
+ l.onMouseMove(dx, dy);
+ }
+ GameFrame.getWindow().warpPointer(cx, cy);
+ }
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ onMove(e);
+ }
+
+ private static List<ru.olamedia.input.MouseListener> listeners = new ArrayList<ru.olamedia.input.MouseListener>();
+
+ public static void attach(ru.olamedia.input.MouseListener l) {
+ listeners.add(l);
+ }
+
+}
diff --git a/src/ru/olamedia/input/MouseListener.java b/src/ru/olamedia/input/MouseListener.java
new file mode 100644
index 0000000..3d93d1d
--- /dev/null
+++ b/src/ru/olamedia/input/MouseListener.java
@@ -0,0 +1,6 @@
+package ru.olamedia.input;
+
+public interface MouseListener {
+ public void onMouseMove(float dx, float dy);
+ public void onMouseClick();
+}
diff --git a/src/ru/olamedia/input/package-info.java b/src/ru/olamedia/input/package-info.java
new file mode 100644
index 0000000..ad3f418
--- /dev/null
+++ b/src/ru/olamedia/input/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.input; \ No newline at end of file
diff --git a/src/ru/olamedia/liveEntity/LiveEntity.java b/src/ru/olamedia/liveEntity/LiveEntity.java
new file mode 100644
index 0000000..ce31108
--- /dev/null
+++ b/src/ru/olamedia/liveEntity/LiveEntity.java
@@ -0,0 +1,683 @@
+package ru.olamedia.liveEntity;
+
+import javax.vecmath.Vector3f;
+
+import com.jogamp.newt.event.KeyEvent;
+
+import ru.olamedia.camera.Cameraman;
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.inventory.Inventory;
+import ru.olamedia.olacraft.world.block.Block;
+import ru.olamedia.olacraft.world.blockStack.BlockStack;
+import ru.olamedia.olacraft.world.blockTypes.GravelBlockType;
+import ru.olamedia.input.Keyboard;
+
+public class LiveEntity implements Cameraman {
+ private Inventory inventory; // every living entity can have inventory
+ private float x;
+ private float y;
+ private float z;
+ public Vector3f velocity = new Vector3f(0, 0, 0);
+ public Vector3f acceleration = new Vector3f(0, 0, 0);
+
+ private float fov = 90f;
+ private float mouseSpeed = 1.0f;
+ private float maxLookUp = 80.0f;
+ private float maxLookDown = -80.0f;
+ private float maxHeight = 1.9f;
+ private float cameraLevel = 1.8f;
+
+ private float pitch = 0f;
+ private float yaw = 0f;
+ private float roll = 0f;
+
+ private float walkSpeed = 1.3f;// 1.3-1.5 m/s
+ private float runSpeed = 4.5f;// m/s
+
+ private boolean isWalking = false;
+ private boolean isRunning = false;
+ private boolean isSneaking = false;
+ private boolean isCrouching = false;
+ private boolean isViewBobbing = true;
+ private float bob = 0f;
+ private float hSpeed = runSpeed; // horizontal speed
+ private float vVelocity = 0f;
+
+ @SuppressWarnings("unused")
+ private float maxHealthPoints;
+ private float healthPoints;
+ public float qD = 0;
+ public float qInvD = 0;
+ public boolean inJump = false;
+ public boolean inFall = false;
+ public boolean onGround = false;
+ private float savedX;
+ private float savedY;
+ private float savedZ;
+ private int id;
+ private int connectionId;
+ private boolean isPositionChanged = false;
+
+ protected void generateInventory() {
+ // can be overriden for mobs
+ for (int i = 0; i <= 9; i++) {
+ inventory.binded[i] = new BlockStack(new Block(), (int) Math.random() * 64);
+ inventory.binded[i].block.setType(new GravelBlockType());
+ }
+ }
+
+ public Inventory getInventory() {
+ if (null == inventory) {
+ inventory = new Inventory();
+ generateInventory();
+ }
+ return inventory;
+ }
+
+ public float getHSpeed() {
+ return (hSpeed) * (isCrouching ? 0.4f : 1) * (isSneaking ? 0.5f : 1);
+ }
+
+ public float getHeight() {
+ return maxHeight * (isCrouching ? 0.5f : 1) * (isSneaking ? 0.8f : 1);
+ }
+
+ public float getMaxJumpHeight() {
+ // ~1.5 for 1.8
+ return (float) ((float) (maxHeight * 0.83)) * (isCrouching ? 0.8f : 1f);
+ }
+
+ /**
+ * Returns the vertical velocity needed to jump the specified height (based
+ * on current gravity). Uses the Math.sqrt() function.
+ */
+ public float getJumpVelocity(float jumpHeight) {
+ // use velocity/acceleration formal: v*v = -2 * a(y-y0)
+ // (v is jump velocity, a is accel, y-y0 is max height)
+ return (float) Math.sqrt(2 * Game.client.getWorldInfo().gravity * jumpHeight);
+ }
+
+ public float getCameraLevel() {
+ return getHeight() * 0.9f;
+ }
+
+ public boolean isEmptyUnderFoot() {
+ return isEmptyBlock(0, -1, 0);
+ }
+
+ /**
+ * @param delta
+ * the elapsed time since the last frame update in seconds
+ */
+ public void updateKeyboard(float delta) {
+ acceleration.x = 0;
+ acceleration.y = 0;
+ acceleration.z = 0;
+ boolean keyLeft = Keyboard.isKeyDown("playerStrafeLeft");
+ boolean keyRight = Keyboard.isKeyDown("playerStrafeRight");
+ boolean keyForward = Keyboard.isKeyDown("playerForward");
+ boolean keyBack = Keyboard.isKeyDown("playerBack");
+ boolean keyJump = Keyboard.isKeyDown("playerJump");
+ boolean keySneak = Keyboard.isKeyDown("playerSneak");
+ boolean keyCrouch = Keyboard.isKeyDown("playerCrouch");
+
+ if (keySneak) {
+ if (!isSneaking) {
+ isSneaking = true;
+ if (!applyPosition()) {
+ isSneaking = false;
+ }
+ }
+ } else {
+ if (isSneaking) {
+ isSneaking = false;
+ if (!applyPosition()) {
+ isSneaking = true;
+ }
+ }
+ }
+ if (keyCrouch) {
+ if (!isCrouching) {
+ isCrouching = true;
+ if (!applyPosition()) {
+ isCrouching = false;
+ }
+ }
+ } else {
+ if (isCrouching) {
+ isCrouching = false;
+ if (!applyPosition()) { // Test if we don't have a block over
+ // head
+ isCrouching = true;
+ }
+ }
+ }
+ isWalking = false;
+ if ((keyForward && !keyBack) || (keyBack && !keyForward)) {
+ Vector3f look = Game.instance.camera.getLook();
+ acceleration.x += look.x * (keyBack ? 1 : -1) * 1f;
+ acceleration.y += 0;
+ acceleration.z += look.z * (keyBack ? 1 : -1) * 1f;
+ }
+ if ((keyLeft && !keyRight) || (keyRight && !keyLeft)) {
+ Vector3f right = Game.instance.camera.getRight();
+ acceleration.x += right.x * (keyRight ? 1 : -1) * 1f;
+ acceleration.y += 0;
+ acceleration.z += right.z * (keyRight ? 1 : -1) * 1f;
+ }
+ // acceleration.normalize();
+ float normalSpeed = 4.5f;
+ acceleration.x *= normalSpeed;// running
+ acceleration.y *= normalSpeed;
+ acceleration.z *= normalSpeed;
+
+ // if (inJump) {
+ // float FPS = (float) (delta / 1);
+ // float accelY = Game.world.gravity;
+ // float dt = (float) (delta / 1); // in seconds
+ // vVelocity -= accelY * dt;
+ // y += vVelocity * dt;
+ // if (vVelocity < 0) {
+ // inFall = true;
+ // }
+ // if (vVelocity > 0) {
+ // if (!keyJump) {
+ // vVelocity = 0;
+ // }
+ // }
+ // if (!applyPosition()) {
+ // if (vVelocity > 0) {
+ // // roof
+ // vVelocity = 0;
+ // } else {
+ // y = underFoot().getY() + 1;
+ // vVelocity = 0;
+ // inJump = false;
+ // inFall = false;
+ // }
+ // }
+ //
+ // } else {
+ // if (!inFall) {
+ // if (inAir()) {
+ //
+ // inJump = true;
+ // inFall = true;
+ // }
+ // }
+ // }
+ if (!onGround && !inAir()) {
+ // LANDING
+ onGround = true;
+ inJump = false;
+ velocity.y = 0;
+ acceleration.y = 0;
+ y = getJumperBlock().getY() + 1;
+ }
+ if (onGround && velocity.length() > 0 && acceleration.length() > 0) {
+ // BEFORE NEW JUMP
+ // Check direction changed
+ float vy = velocity.y;
+ float ay = acceleration.y;
+ velocity.y = 0;
+ acceleration.y = 0;
+ float dAngle = velocity.angle(acceleration);
+ float speedLimit = 10;
+ if (dAngle > 0) {
+ // changing angle
+ Vector3f newDirection = new Vector3f(velocity);
+ newDirection.add(acceleration);
+ if (newDirection.length() > 0) {
+ newDirection.normalize();
+ newDirection.scale(velocity.length());
+ }
+ velocity.set(newDirection);
+ // check velocity
+ if (velocity.length() * Math.cos(dAngle) > speedLimit) {
+ float deltaSpeed = (float) (velocity.length() * Math.cos(dAngle) - speedLimit);
+ velocity.scale((1 / velocity.length()) * (velocity.length() - deltaSpeed * 0.7f));
+ // velocity.scale((float) (10 / velocity.length() *
+ // Math.cos(dAngle)));
+ // velocity.scale((float) (velocity.length()
+ // - (velocity.length() - (10 / velocity.length() *
+ // Math.cos(dAngle))) * 0.5f * delta));
+ }
+ } else {
+ if (velocity.length() > speedLimit) {
+ float deltaSpeed = (float) (velocity.length() - speedLimit);
+ velocity.scale((1 / velocity.length()) * (velocity.length() - deltaSpeed * 0.7f));
+ }
+ }
+ velocity.y = vy;
+ acceleration.y = ay;
+ }
+ if (onGround && keyJump) {
+ // JUMPING
+ inJump = true;
+ onGround = false;
+ velocity.y = getJumpVelocity(getMaxJumpHeight());
+ acceleration.y = velocity.y;
+ // vVelocity = getJumpVelocity(getMaxJumpHeight());
+ System.out.println("Max jump height " + getMaxJumpHeight());
+ System.out.println("Starting velocity " + velocity.y);
+ }
+
+ if (onGround && !inJump) {
+ if (velocity.length() > normalSpeed) {
+ velocity.scale(normalSpeed / velocity.length());
+ }
+ // APPLY FRICTION
+ // Vector3f friction = new Vector3f(velocity);
+ // friction.negate();
+ // friction.scale(friction.length());
+ // friction.scale(delta);
+ // velocity.scale((float) Math.exp(-0.2 * delta));
+ // acceleration.scale(friction.length());
+ }
+
+ if (velocity.length() > 0 && acceleration.length() > 0) {
+ qD = Math.abs(velocity.dot(acceleration)) / (velocity.length() * acceleration.length());
+ }
+
+ // Vector3f a = new Vector3f(acceleration);
+ // if (a.length() > 0) {
+ // a.normalize();
+ // }
+ //
+ // if (qD > 0) {
+ // qInvD = (float) Math.acos(qD);
+ // acceleration.scale(qInvD * 10f);
+ // }
+ // if (qD > 10) {
+ // if (velocity.length() > 0) {
+ // velocity.normalize();
+ // }
+ // velocity.scale(qD);
+ // }
+ // if (qd > 10) {
+ // qd = 10;
+ // }
+ // velocity.set(acceleration);
+ // if (velocity.length() > 1){
+ // velocity.scale(1 / velocity.length());
+ // }
+ // velocity.scale(qd);
+
+ if (!onGround || inAir()) { // 0_o
+ acceleration.y = -Game.client.getWorldInfo().gravity;
+ }
+
+ // float qangle = (float) Math.abs(Math.acos(qd));
+ // if (qangle > 180){
+ // acceleration.scale(10f);
+ // }else if (qangle > 90){
+ // acceleration.scale(5f);
+ // }else if (qangle > 45){
+ // acceleration.scale(2f);
+ // }
+
+ // Quake-like tricks here...
+ // Vector3f qa = new Vector3f(acceleration);
+ // if (qa.length() != 0) {
+ // qa.scale(1 / qa.length());
+ // float qd = acceleration.dot(velocity);
+ // float qangle = (float) Math.abs(Math.acos(qd));
+ // if (qangle > 180) {
+ // // fast stop
+ // velocity.x *= 0.5f;
+ // velocity.z *= 0.5f;
+ // }else{
+ //
+ // }
+ // if (qd > 14) {
+ // velocity.x *= 1 / qd;
+ // velocity.z *= 1 / qd;
+ // }
+ // }
+ if (onGround && (acceleration.length() == 0)) {
+ velocity.set(0f, 0f, 0f);
+ } else {
+ // acceleration.normalize();
+ // Vector3f a = new Vector3f(acceleration);
+ // a.scale(delta);
+
+ if (velocity.length() == 0) {
+ velocity.x = acceleration.x;
+ // velocity.y = acceleration.y;
+ velocity.z = acceleration.z;
+ } else {
+ velocity.x += acceleration.x * delta;
+ velocity.z += acceleration.z * delta;
+ velocity.y += acceleration.y * delta;
+ }
+
+ Vector3f move = new Vector3f(velocity);
+ move.scale(delta);
+ float dx = 0;
+ while (move.x != 0) {
+ if (move.x > 1) {
+ dx = 1;
+ move.x -= 1;
+ } else if (move.x < -1) {
+ dx = -1;
+ move.x += 1;
+ } else {
+ dx = move.x;
+ move.x = 0;
+ }
+ x += dx;
+ if (applyPosition()) {
+ isWalking = true;
+ } else {
+ // full stop
+ velocity.x = 0;
+ }
+ }
+ float dz = 0;
+ while (move.z != 0) {
+ if (move.z > 1) {
+ dz = 1;
+ move.z -= 1;
+ } else if (move.z < -1) {
+ dz = -1;
+ move.z += 1;
+ } else {
+ dz = move.z;
+ move.z = 0;
+ }
+ z += dz;
+ if (applyPosition()) {
+ isWalking = true;
+ } else {
+ // full stop
+ velocity.z = 0;
+ }
+ }
+ float dy = 0;
+ if (move.y != 0) {
+ while (move.y != 0) {
+ if (move.y > 1) {
+ dy = 1;
+ move.y -= 1;
+ } else if (move.y < -1) {
+ dy = -1;
+ move.y += 1;
+ } else {
+ dy = move.y;
+ move.y = 0;
+ }
+ y += dy;
+ if (applyPosition()) {
+ isWalking = true;
+ } else {
+ // full stop
+ velocity.y = 0;
+ }
+ }
+
+ }
+ }
+ }
+
+ private Block underFoot() {
+ return getBlock(0, -1, 0);
+ }
+
+ public boolean isEmptyBlock(int dx, int dy, int dz) {
+ return Game.client.getWorldProvider().isEmptyBlock((int) x + dx, (int) Math.ceil(y) + dy, (int) z + dz);
+ }
+
+ public boolean haveBlockUnder(int dy) {
+ return !isEmptyBlock(0, -dy, 0);
+ }
+
+ public boolean inAir() {
+ return !haveBlockUnder(1);
+ }
+
+ public boolean underJumpHeight() {
+ return haveBlockUnder(1) || haveBlockUnder(2);
+ }
+
+ public Block getJumperBlock() {
+ if (haveBlockUnder(1)) {
+ return getBlock(0, -1, 0);
+ }
+ if (haveBlockUnder(2)) {
+ return getBlock(0, -2, 0);
+ }
+ return null;
+ }
+
+ private Block getBlock(int dx, int dy, int dz) {
+ return Game.client.getWorldProvider().getBlock((int) x + dx, (int) Math.ceil(y) + dy, (int) z + dz);
+ }
+
+ public void backupPosition() {
+ savedX = x;
+ savedY = y;
+ savedZ = z;
+ }
+
+ public void restorePosition() {
+ x = savedX;
+ y = savedY;
+ z = savedZ;
+ }
+
+ public boolean hasValidPosition() {
+ Block foot = getBlock(0, 0, 0);
+ Block underFoot = getBlock(0, -1, 0);
+ Block head = getBlock(0, (int) getHeight(), 0);
+ if (!inJump) {
+ if (underFoot.isEmpty()) {
+ // In AIR while normal walking
+ if (isSneaking) {
+ // TODO Jumping while Sneaking fixes x,z while jumping
+ return false;
+ }
+ }
+ }
+ // Check if we're too near to the wall
+ float screenPlane = 0.2f;
+ float screenPlaneVertical = 0.4f;
+ Block[] headNeighbors = head.getNeighbors();
+ for (Block b : headNeighbors) {
+ if (b.isEmpty()) {
+ continue;
+ }
+ if (b.getX() != head.getX()) {
+ // LEFT or RIGHT
+ float testX = b.getX();
+ if (testX < head.getX()) {
+ // LEFT, fixing
+ testX = head.getX();
+ }
+ float minDistance = Math.abs(testX - getX());
+ if (minDistance < screenPlane) {
+ return false;
+ }
+ }
+ if (b.getY() > head.getY()) { // Upper block
+ float minDistance = Math.abs(b.getY() - getY() + this.getHeight());// player
+ // height
+ if (minDistance < screenPlaneVertical) {
+ return false;
+ }
+ }
+
+ if (b.getZ() != head.getZ()) {
+ // FRONT OR BACK
+ float testZ = b.getZ();
+ if (testZ < head.getZ()) {
+ // BACK, fixing
+ testZ = head.getZ();
+ }
+ float minDistance = Math.abs(testZ - getZ());
+ if (minDistance < screenPlane) {
+ return false;
+ }
+ }
+ }
+ return foot.isEmpty() && head.isEmpty();
+ }
+
+ public boolean applyPosition() {
+ isPositionChanged = false;
+ if (hasValidPosition()) {
+ backupPosition();
+ isPositionChanged = true;
+ return true;
+ }
+ restorePosition();
+ return false;
+ }
+
+ public void notifyLocationUpdate() {
+ // overriden at player class
+ }
+
+ public void fixPosition() {
+ float dx = x - savedX;
+ float dy = y - savedY;
+ float dz = z - savedZ;
+ restorePosition();
+ if (Math.abs(dx) < 1) { // in a block range
+ x += dx;
+ applyPosition();
+ }
+ if (Math.abs(dy) < 1) { // in a block range
+ y += dy;
+ applyPosition();
+ }
+ if (Math.abs(dz) < 1) { // in a block range
+ y += dz;
+ applyPosition();
+ }
+ }
+
+ @Override
+ public void update(float delta) {
+ isPositionChanged = false;
+ backupPosition();
+ onGround = false;
+ Block below = getBlock(0, -1, 0);
+ if (y == below.getY() + 1) {
+ onGround = true;
+ }
+ updateKeyboard(delta);
+ // Check if position is valid
+ // fixPosition();
+
+ if (y < -20) {
+ // spawnAt((int) x, (int) z);
+ }
+ pitch = Game.instance.camera.getPitch();
+ yaw = Game.instance.camera.getYaw();
+ // Game.camera.setRoll(roll);
+ // saveTrace();
+ // if (isWalking && onGround) {
+ // if (!stepsound.isPlaying()) {
+ // stepsound.playAsSoundEffect(1f, 0.4f, true);
+ // }
+ // } else {
+ // if (stepsound.isPlaying()) {
+ // stepsound.stop();
+ // }
+ // }
+ if (isPositionChanged) {
+ notifyLocationUpdate();
+ }
+ }
+
+ public void setLocation(float x, float y, float z) {
+ this.setX(x);
+ this.setY(y);
+ this.setZ(z);
+ }
+
+ public void say(String message) {
+
+ }
+
+ public void die() {
+ healthPoints = 0;
+ LiveEntityEvent e = new LiveEntityEvent(this);
+ e.setType(LiveEntityEvent.ON_DIE);
+ e.dispatch();
+ }
+
+ public void acceptDamage(float amount) {
+ healthPoints -= amount;
+ if (healthPoints < 0) {
+ die();
+ }
+ }
+
+ public float getX() {
+ return x;
+ }
+
+ public void setX(float x) {
+ this.x = x;
+ }
+
+ public float getY() {
+ return y;
+ }
+
+ public void setY(float y) {
+ this.y = y;
+ }
+
+ public float getZ() {
+ return z;
+ }
+
+ public void setZ(float z) {
+ this.z = z;
+ }
+
+ @Override
+ public float getCameraX() {
+ return x;
+ }
+
+ @Override
+ public float getCameraY() {
+ return y + getCameraLevel();
+ }
+
+ @Override
+ public float getCameraZ() {
+ return z;
+ }
+
+ @Override
+ public void captureControls() {
+ System.out.println("Player took controls");
+ Keyboard.setName("playerForward", KeyEvent.VK_W);
+ Keyboard.setName("playerBack", KeyEvent.VK_S);
+ Keyboard.setName("playerStrafeLeft", KeyEvent.VK_A);
+ Keyboard.setName("playerStrafeRight", KeyEvent.VK_D);
+ Keyboard.setName("playerJump", KeyEvent.VK_SPACE);
+ Keyboard.setName("playerSneak", KeyEvent.VK_SHIFT);
+ Keyboard.setName("playerCrouch", KeyEvent.VK_CONTROL);
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public int getConnectionId() {
+ return connectionId;
+ }
+
+ public void setConnectionId(int connectionId) {
+ this.connectionId = connectionId;
+ }
+}
diff --git a/src/ru/olamedia/liveEntity/LiveEntityEvent.java b/src/ru/olamedia/liveEntity/LiveEntityEvent.java
new file mode 100644
index 0000000..5c0ded5
--- /dev/null
+++ b/src/ru/olamedia/liveEntity/LiveEntityEvent.java
@@ -0,0 +1,31 @@
+package ru.olamedia.liveEntity;
+
+public class LiveEntityEvent {
+ public static int ON_DIE;
+ private Object source;
+ private int type;
+
+ public LiveEntityEvent(Object source) {
+ this.setSource(source);
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public void setSource(Object source) {
+ this.source = source;
+ }
+
+ public void dispatch() {
+ LiveEntityEventDispatcher.dispatch(this);
+ }
+}
diff --git a/src/ru/olamedia/liveEntity/LiveEntityEventDispatcher.java b/src/ru/olamedia/liveEntity/LiveEntityEventDispatcher.java
new file mode 100644
index 0000000..5d29ae1
--- /dev/null
+++ b/src/ru/olamedia/liveEntity/LiveEntityEventDispatcher.java
@@ -0,0 +1,7 @@
+package ru.olamedia.liveEntity;
+
+public class LiveEntityEventDispatcher {
+ public static void dispatch(LiveEntityEvent e){
+
+ }
+}
diff --git a/src/ru/olamedia/liveEntity/package-info.java b/src/ru/olamedia/liveEntity/package-info.java
new file mode 100644
index 0000000..9c27733
--- /dev/null
+++ b/src/ru/olamedia/liveEntity/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.liveEntity; \ No newline at end of file
diff --git a/src/ru/olamedia/math/Box.java b/src/ru/olamedia/math/Box.java
new file mode 100644
index 0000000..7b9d968
--- /dev/null
+++ b/src/ru/olamedia/math/Box.java
@@ -0,0 +1,74 @@
+package ru.olamedia.math;
+
+public class Box {
+ private Vector3f low = new Vector3f();
+ private Vector3f high = new Vector3f();
+
+ /**
+ * @param x
+ * left
+ * @param y
+ * lower
+ * @param z
+ * back
+ * @param x2
+ * right
+ * @param y2
+ * higher
+ * @param z2
+ * front
+ */
+ public Box(float x, float y, float z, float x2, float y2, float z2) {
+ low.x = x;
+ low.y = y;
+ low.z = z;
+ high.x = x2;
+ high.y = y2;
+ high.z = z2;
+ }
+
+ public Vector3f getVertex(int i) {
+ Vector3f vertex = new Vector3f(low);
+ if (i > 3) {
+ // 4, 5, 6, 7
+ vertex.z = high.z;
+ }
+ if (i % 4 > 1) {
+ // 0 1 2 3 4 5 6 7
+ // 0 1 2 3 0 1 2 3
+ // - - + + - - + +
+ vertex.y = high.y;
+ }
+ if (i % 2 > 0) {
+ // 0 1 2 3 4 5 6 7
+ // 0 1 0 1 0 1 0 1
+ // - + - + - + - +
+ vertex.x = high.x;
+ }
+ return vertex;
+ }
+
+ public float getLowerX() {
+ return low.x;
+ }
+
+ public float getLowerY() {
+ return low.y;
+ }
+
+ public float getLowerZ() {
+ return low.z;
+ }
+
+ public float getUpperX() {
+ return high.x;
+ }
+
+ public float getUpperY() {
+ return high.y;
+ }
+
+ public float getUpperZ() {
+ return high.z;
+ }
+}
diff --git a/src/ru/olamedia/math/Classifier.java b/src/ru/olamedia/math/Classifier.java
new file mode 100644
index 0000000..551bcf6
--- /dev/null
+++ b/src/ru/olamedia/math/Classifier.java
@@ -0,0 +1,8 @@
+package ru.olamedia.math;
+
+public class Classifier {
+ // INSIDE > INTERSECT > OUTSIDE
+ public static int OUTSIDE = 0;
+ public static int INTERSECT = 1;
+ public static int INSIDE = 2;
+}
diff --git a/src/ru/olamedia/math/Frustum.java b/src/ru/olamedia/math/Frustum.java
new file mode 100644
index 0000000..e127cc0
--- /dev/null
+++ b/src/ru/olamedia/math/Frustum.java
@@ -0,0 +1,127 @@
+package ru.olamedia.math;
+
+public class Frustum {
+ public Plane topPlane = new Plane();
+ public Plane bottomPlane = new Plane();
+ public Plane leftPlane = new Plane();
+ public Plane rightPlane = new Plane();
+ public Plane nearPlane = new Plane();
+ public Plane farPlane = new Plane();
+ private Plane[] planes = getPlanes();
+
+ private Plane[] getPlanes() {
+ return new Plane[] { leftPlane, rightPlane, topPlane, bottomPlane };// ,
+ // topPlane,,
+ // topPlane
+ // bottomPlane,
+ // leftPlane,
+ // rightPlane, farPlane };
+ }
+
+ public Vector3f[] getVertices() {
+ Vector3f[] v = new Vector3f[8];
+ v[0] = topPlane.cross(leftPlane, nearPlane);
+ v[1] = topPlane.cross(leftPlane, farPlane);
+ v[2] = topPlane.cross(rightPlane, nearPlane);
+ v[3] = topPlane.cross(rightPlane, farPlane);
+ v[4] = bottomPlane.cross(leftPlane, nearPlane);
+ v[5] = bottomPlane.cross(leftPlane, farPlane);
+ v[6] = bottomPlane.cross(rightPlane, nearPlane);
+ v[7] = bottomPlane.cross(rightPlane, farPlane);
+ return v;
+ }
+
+ public int test(Box b) {
+ return quickClassify(b);
+ // int out, in = 0, result;
+ // result = Classifier.INSIDE;
+ // int pc = 5;
+ // for (int i = 0; i < 5; i++) {
+ // Plane plane = planes[i];
+ // out = 0;
+ // in = 0;
+ // for (int k = 0; k < 8 && (in == 0 || out == 0); k++) {
+ // if (plane.distance(b.getVertex(k)) > 0) {
+ // out++;
+ // } else {
+ // in++;
+ // }
+ // }
+ // if (out == 8) {
+ // System.out.println(i);
+ // return Classifier.OUTSIDE;
+ // }
+ // }
+ // if (in < pc) {
+ // result = Classifier.INTERSECT;
+ // }
+ // // for (int i = 0; i < 6; i++) {
+ // // for (int k = 0; k < 8 && (in == 0 || out == 0); k++) {
+ // // if (planes[i].distance(b.getVertex(k)) < 0) {
+ // // out++;
+ // // } else {
+ // // in++;
+ // // }
+ // // }
+ // // }
+ // // if (in < 1) {
+ // // return Classifier.OUTSIDE;
+ // // } else if (out > 0) {
+ // // result = Classifier.INTERSECT;
+ // // }
+ // return result;
+ }
+
+ private static final boolean isPointInside(Plane plane, Vector3f p) {
+ return (plane.distance(p) <= 0.0f);
+ }
+
+ @SuppressWarnings("unused")
+ private final boolean isPointInside(Vector3f p) {
+ return isPointInside(topPlane, p) && isPointInside(bottomPlane, p) && isPointInside(leftPlane, p)
+ && isPointInside(rightPlane, p) && isPointInside(nearPlane, p);
+ }
+
+ /**
+ * Quick check to see if an orthogonal bounding box is inside the frustum
+ */
+ public final int quickClassify(Box box) {
+ // If all vertices is outside of at least one of planes
+ for (Plane p : planes) {
+ int in = 0;
+ @SuppressWarnings("unused")
+ int out = 0;
+ for (int i = 0; i < 8; i++) {
+ Vector3f v = box.getVertex(i);
+ if (p.distance(v) > 0.0f) {
+ out++;
+ } else {
+ in++;
+ }
+ }
+ if (in < 1) {
+ return (Classifier.OUTSIDE);
+ }
+ }
+
+ return (Classifier.INTERSECT);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Frustum[\r\n" + //
+ "Top " + topPlane + "\r\n" + //
+ "Bottom " + bottomPlane + "\r\n" + //
+ "Left " + leftPlane + "\r\n" + //
+ "Right " + rightPlane + "\r\n" + //
+ "Near " + nearPlane + "\r\n" + //
+ "Far " + farPlane + "\r\n" + //
+ "]";
+ }
+
+}
diff --git a/src/ru/olamedia/math/FrustumUtil.java b/src/ru/olamedia/math/FrustumUtil.java
new file mode 100644
index 0000000..80b01fb
--- /dev/null
+++ b/src/ru/olamedia/math/FrustumUtil.java
@@ -0,0 +1,72 @@
+package ru.olamedia.math;
+
+public class FrustumUtil {
+ public static Plane[] extractPlanes(javax.vecmath.Matrix4f m, boolean normalize) {
+
+ Plane[] planes = new Plane[6];
+ for (int j = 0; j < 6; j++) {
+ planes[j] = new Plane();
+ }
+ // Left: [30+00, 31+01, 32+02, 33+03]
+
+ planes[0].n.x = m.m30 + m.m00;
+ planes[0].n.y = m.m31 + m.m01;
+ planes[0].n.z = m.m32 + m.m02;
+ planes[0].d = m.m33 + m.m03;
+
+ // Right: [30-00, 31-01, 32-02, 33-03]
+
+ planes[1].n.x = m.m30 - m.m00;
+ planes[1].n.y = m.m31 - m.m01;
+ planes[1].n.z = m.m32 - m.m02;
+ planes[1].d = m.m33 - m.m03;
+
+ // Bottom: [30+10, 31+11, 32+12, 33+13]
+
+ planes[2].n.x = m.m30 + m.m10;
+ planes[2].n.y = m.m31 + m.m11;
+ planes[2].n.z = m.m32 + m.m12;
+ planes[2].d = m.m33 + m.m13;
+
+ // Top: [30-10, 31-11, 32-12, 33-13]
+
+ planes[3].n.x = m.m30 - m.m10;
+ planes[3].n.y = m.m31 - m.m11;
+ planes[3].n.z = m.m32 - m.m12;
+ planes[3].d = m.m33 - m.m13;
+
+ // Near: [30+20, 31+21, 32+22, 33+23]
+
+ planes[4].n.x = m.m30 + m.m20;
+ planes[4].n.y = m.m31 + m.m21;
+ planes[4].n.z = m.m32 + m.m22;
+ planes[4].d = m.m33 + m.m23;
+
+ // Far: [30-20, 31-21, 32-22, 33-23]
+
+ planes[5].n.x = m.m30 - m.m20;
+ planes[5].n.y = m.m31 - m.m21;
+ planes[5].n.z = m.m32 - m.m22;
+ planes[5].d = m.m33 - m.m23;
+
+ // Normalize
+ if (normalize) {
+ for (int i = 0; i < 6; ++i) {
+ planes[i].normalize();
+ }
+ }
+ return planes;
+ }
+
+ public static Frustum extractFrustum(javax.vecmath.Matrix4f m) {
+ Frustum f = new Frustum();
+ Plane[] planes = extractPlanes(m, true);
+ f.leftPlane.set(planes[0]);
+ f.rightPlane.set(planes[1]);
+ f.bottomPlane.set(planes[2]);
+ f.topPlane.set(planes[3]);
+ f.nearPlane.set(planes[4]);
+ f.farPlane.set(planes[5]);
+ return f;
+ }
+}
diff --git a/src/ru/olamedia/math/Halfspace.java b/src/ru/olamedia/math/Halfspace.java
new file mode 100644
index 0000000..64834df
--- /dev/null
+++ b/src/ru/olamedia/math/Halfspace.java
@@ -0,0 +1,7 @@
+package ru.olamedia.math;
+
+public class Halfspace {
+ public static int NEGATIVE = -1;
+ public static int ON_PLANE = 0;
+ public static int POSITIVE = 1;
+}
diff --git a/src/ru/olamedia/math/Matrix4f.java b/src/ru/olamedia/math/Matrix4f.java
new file mode 100644
index 0000000..1ce2eb6
--- /dev/null
+++ b/src/ru/olamedia/math/Matrix4f.java
@@ -0,0 +1,191 @@
+package ru.olamedia.math;
+
+import static org.openmali.FastMath.*;
+
+// 4x4 float matrix, column-major notation
+public class Matrix4f {
+ protected float[] m;
+
+ public Matrix4f() {
+ m = new float[16];
+ }
+
+ public Matrix4f(float[] m) {
+ this.m = m;
+ }
+
+ public Matrix4f(javax.vecmath.Matrix4f m2) {
+ m = new float[16];
+ m[0] = m2.m00;
+ m[1] = m2.m10;
+ m[2] = m2.m20;
+ m[3] = m2.m30;
+ m[4] = m2.m01;
+ m[5] = m2.m11;
+ m[6] = m2.m21;
+ m[7] = m2.m31;
+ m[8] = m2.m02;
+ m[9] = m2.m12;
+ m[10] = m2.m22;
+ m[11] = m2.m32;
+ m[12] = m2.m03;
+ m[13] = m2.m13;
+ m[14] = m2.m23;
+ m[15] = m2.m33;
+ }
+
+ public float[] toFloatArray() {
+ return m;
+ }
+
+ public void set(int i, float v) {
+ m[i] = v;
+ }
+
+ public float get(int i) {
+ return m[i];
+ }
+
+ public void loadIdentity() {
+ setIdentity();
+ }
+
+ public void setIdentity() {
+ m[0] = m[5] = m[10] = m[15] = 1.0f;
+ m[1] = m[2] = m[3] = m[4] = 0.0f;
+ m[6] = m[7] = m[8] = m[9] = 0.0f;
+ m[11] = m[12] = m[13] = m[14] = 0.0f;
+ }
+
+ public static Matrix4f translateMatrix(float x, float y, float z) {
+ Matrix4f m = new Matrix4f();
+ m.setIdentity();
+ // Translate slots.
+ m.set(12, x);
+ m.set(13, y);
+ m.set(14, z);
+ return m;
+ }
+
+ public static Matrix4f scaleMatrix(float sx, float sy, float sz) {
+ Matrix4f m = new Matrix4f();
+ m.setIdentity();
+ // Scale slots.
+ m.set(0, sx);
+ m.set(5, sy);
+ m.set(10, sz);
+ return m;
+ }
+
+ public static Matrix4f rotateXMatrix(float degrees) {
+ float radians = toRad(degrees);
+ float c = cos(radians);
+ float s = sin(radians);
+ Matrix4f m = new Matrix4f();
+ m.setIdentity();
+ // Rotate X formula.
+ m.set(5, c);
+ m.set(6, -s);
+ m.set(9, s);
+ m.set(10, c);
+ return m;
+ }
+
+ public static Matrix4f rotateYMatrix(float degrees) {
+ float radians = toRad(degrees);
+ float c = cos(radians);
+ float s = sin(radians);
+ Matrix4f m = new Matrix4f();
+ m.setIdentity();
+ // Rotate Y formula.
+ m.set(0, c);
+ m.set(2, s);
+ m.set(8, -s);
+ m.set(10, c);
+ return m;
+ }
+
+ public static Matrix4f rotateZMatrix(float degrees) {
+ float radians = toRad(degrees);
+ float c = cos(radians);
+ float s = sin(radians);
+ Matrix4f m = new Matrix4f();
+ m.setIdentity();
+ // Rotate Z formula.
+ m.set(0, c);
+ m.set(1, s);
+ m.set(4, -s);
+ m.set(5, c);
+ return m;
+ }
+
+ public Vector3f getUpVector() {
+ return new Vector3f(m[1], m[5], m[9]);
+ }
+
+ public Vector3f getLookVector() { // POSITIVE_Z
+ return new Vector3f(m[2], m[6], m[10]);
+ }
+
+ public Vector3f getRightVector() {
+ return new Vector3f(m[0], m[4], m[8]);
+ }
+
+ public Matrix4f multiply(Matrix4f m) {
+ return Matrix4fUtil.multiply(this, m);
+ }
+
+ public void apply(Matrix4f m) {
+ this.m = multiply(m).toFloatArray();
+ }
+
+ public float[] getAngles() {
+ // TODO check majority
+ float ax, ay, az;
+ float cy;
+ ay = -asin(m[2]); /* Calculate Y-axis angle */
+ cy = cos(ay);
+ ay = toDeg(ay);
+ float trX, trY;
+
+ if (Math.abs(cy) > 0.005) /* Gimball lock? */
+ {
+ trX = m[10] / cy; /* No, so get X-axis angle */
+ trY = -m[6] / cy;
+
+ ax = toDeg(atan2(trY, trX));
+
+ trX = m[0] / cy; /* Get Z-axis angle */
+ trY = -m[1] / cy;
+
+ az = toDeg(atan2(trY, trX));
+ } else /* Gimball lock has occurred */
+ {
+ ax = 0; /* Set X-axis angle to zero */
+
+ trX = m[5]; /* And calculate Z-axis angle */
+ trY = m[4];
+
+ az = toDeg(atan2(trY, trX));
+ }
+
+ ax = clamp(ax, 0, 360); /* Clamp all angles to range */
+ ay = clamp(ay, 0, 360);
+ az = clamp(az, 0, 360);
+ return new float[] { ax, ay, ax };
+ }
+
+ private float clamp(float a, float min, float max) {
+ a = a % max;
+ return a;
+ }
+
+ public float c(int column, int row) {
+ // COLUMN-BASED
+ return m[column * 4 + row];
+ }
+
+ public void set(float[] m) {
+ this.m = m;
+ }
+}
diff --git a/src/ru/olamedia/math/Matrix4fUtil.java b/src/ru/olamedia/math/Matrix4fUtil.java
new file mode 100644
index 0000000..46d153e
--- /dev/null
+++ b/src/ru/olamedia/math/Matrix4fUtil.java
@@ -0,0 +1,36 @@
+package ru.olamedia.math;
+
+public class Matrix4fUtil {
+ public static Matrix4f multiply(Matrix4f m1, Matrix4f m2) {
+ return new Matrix4f(multiply(m1.toFloatArray(), m2.toFloatArray()));
+ }
+
+ // MATRIX MULTIPLICATION
+ public static float[] multiply(float[] m1, float[] m2) {
+ float[] result = new float[16];
+ // First Column
+ result[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
+ result[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
+ result[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
+ result[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
+
+ // Second Column
+ result[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
+ result[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
+ result[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
+ result[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
+
+ // Third Column
+ result[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
+ result[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
+ result[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
+ result[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
+
+ // Fourth Column
+ result[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
+ result[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
+ result[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
+ result[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
+ return result;
+ }
+}
diff --git a/src/ru/olamedia/math/Plane.java b/src/ru/olamedia/math/Plane.java
new file mode 100644
index 0000000..d5cd9d0
--- /dev/null
+++ b/src/ru/olamedia/math/Plane.java
@@ -0,0 +1,71 @@
+package ru.olamedia.math;
+
+import static java.lang.Math.sqrt;
+
+public class Plane {
+ // normal
+ public Vector3f n = new Vector3f();
+ // distance
+ public float d;
+
+ public void set(Plane p) {
+ n.x = p.n.x;
+ n.y = p.n.y;
+ n.z = p.n.z;
+ d = p.d;
+ }
+
+ public float magnitude() {
+ return (float) sqrt(n.x * n.x + n.y * n.y + n.z * n.z);
+ }
+
+ public void normalize() {
+ float mag = magnitude();
+ n.x /= mag;
+ n.y /= mag;
+ n.z /= mag;
+ d /= mag;
+ }
+
+ public float distance(float x, float y, float z) {
+ return n.x * x + n.y * y + n.z * z + d;
+ }
+
+ public float distance(Vector3f point) {
+ return n.x * point.x + n.y * point.y + n.z * point.z + d;
+ }
+
+ private float dec(float a) {
+ return (float) Math.floor(a * 100) / 100;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Plane[nx=" + dec(n.x) + ";ny=" + dec(n.y) + ";nz=" + dec(n.z) + ";d=" + dec(d) + "]";
+ }
+
+ public Vector3f cross(Plane a, Plane b) {
+ return n.cross(a.n.cross(b.n));
+ }
+
+ public void set3Points(Vector3f va, Vector3f vb, Vector3f vc) {
+ // A = y1 (z2 - z3) + y2 (z3 - z1) + y3 (z1 - z2)
+ // B = z1 (x2 - x3) + z2 (x3 - x1) + z3 (x1 - x2)
+ // C = x1 (y2 - y3) + x2 (y3 - y1) + x3 (y1 - y2)
+ // - D = x1 (y2 z3 - y3 z2) + x2 (y3 z1 - y1 z3) + x3 (y1 z2 - y2 z1)
+ Vector3f ab = vb.sub(va);
+ Vector3f ac = vc.sub(va);
+ Vector3f vn = ab.cross(ac);
+ n.set(vn);
+ n.x = va.y * (vb.z - vc.z) + vb.y * (vc.z - va.z) + vc.y * (va.z - vb.z);
+ n.y = va.z * (vb.x - vc.x) + vb.z * (vc.x - va.x) + vc.z * (va.x - vb.x);
+ n.z = va.x * (vb.y - vc.y) + vb.x * (vc.y - va.y) + vc.x * (va.y - vb.y);
+ d = -(vn.x * va.x + vn.y * va.y + vn.z * va.z);
+ normalize();
+ }
+}
diff --git a/src/ru/olamedia/math/Quaternion.java b/src/ru/olamedia/math/Quaternion.java
new file mode 100644
index 0000000..a263f39
--- /dev/null
+++ b/src/ru/olamedia/math/Quaternion.java
@@ -0,0 +1,25 @@
+package ru.olamedia.math;
+
+public class Quaternion {
+ // identity:
+ public float x = 0;
+ public float y = 0;
+ public float z = 0;
+ public float w = 1;
+
+ public static Quaternion identity() {
+ return new Quaternion();
+ }
+
+ public Quaternion inverse() {
+ return QuaternionUtil.inverse(this);
+ }
+
+ public Quaternion mul(Quaternion q) {
+ return QuaternionUtil.multiply(this, q);
+ }
+
+ public float[] toMatrixArray(){
+ return QuaternionUtil.toMatrixArray(this);
+ }
+}
diff --git a/src/ru/olamedia/math/QuaternionUtil.java b/src/ru/olamedia/math/QuaternionUtil.java
new file mode 100644
index 0000000..83ee005
--- /dev/null
+++ b/src/ru/olamedia/math/QuaternionUtil.java
@@ -0,0 +1,54 @@
+package ru.olamedia.math;
+
+public class QuaternionUtil {
+ // QUATERNION INVERSE
+ public static Quaternion inverse(Quaternion q) {
+ Quaternion newQ = new Quaternion();
+ newQ.w = q.w;
+ newQ.x = -q.x;
+ newQ.y = -q.y;
+ newQ.z = -q.z;
+ // normalize here
+ return newQ;
+ }
+
+ // QUATERNION MULTIPLICATION
+ public static Quaternion multiply(Quaternion q1, Quaternion q2) {
+ Quaternion newQ = new Quaternion();
+ newQ.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
+ newQ.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
+ newQ.y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x;
+ newQ.z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w;
+ return newQ;
+ }
+
+ // QUATERNION-TO-MATRIX, COLUMN-MAJOR NOTATION
+ public static float[] toMatrixArray(Quaternion q) {
+ float[] matrix = new float[16];
+ // First Column
+ matrix[0] = 1 - 2 * (q.y * q.y + q.z * q.z);
+ matrix[1] = 2 * (q.x * q.y + q.z * q.w);
+ matrix[2] = 2 * (q.x * q.z - q.y * q.w);
+ matrix[3] = 0;
+ // Second Column
+ matrix[4] = 2 * (q.x * q.y - q.z * q.w);
+ matrix[5] = 1 - 2 * (q.x * q.x + q.z * q.z);
+ matrix[6] = 2 * (q.z * q.y + q.x * q.w);
+ matrix[7] = 0;
+ // Third Column
+ matrix[8] = 2 * (q.x * q.z + q.y * q.w);
+ matrix[9] = 2 * (q.y * q.z - q.x * q.w);
+ matrix[10] = 1 - 2 * (q.x * q.x + q.y * q.y);
+ matrix[11] = 0;
+ // Fourth Column
+ matrix[12] = 0;
+ matrix[13] = 0;
+ matrix[14] = 0;
+ matrix[15] = 1;
+ return matrix;
+ }
+
+ public static float magnitude(Quaternion qa) {
+ return (float) (Math.sqrt((double) (qa.w * qa.w + qa.x * qa.x + qa.y * qa.y + qa.z * qa.z)));
+ }
+}
diff --git a/src/ru/olamedia/math/TransformMatrix.java b/src/ru/olamedia/math/TransformMatrix.java
new file mode 100644
index 0000000..6f2ea9d
--- /dev/null
+++ b/src/ru/olamedia/math/TransformMatrix.java
@@ -0,0 +1,15 @@
+package ru.olamedia.math;
+
+public class TransformMatrix extends Matrix4f {
+ public void applyTranslation(Matrix4f m) {
+ apply(m);
+ }
+
+ public void applyRotation(Matrix4f m) {
+ apply(m);
+ }
+
+ public void applyScale(Matrix4f m) {
+ apply(m);
+ }
+}
diff --git a/src/ru/olamedia/math/Vector3f.java b/src/ru/olamedia/math/Vector3f.java
new file mode 100644
index 0000000..b16a356
--- /dev/null
+++ b/src/ru/olamedia/math/Vector3f.java
@@ -0,0 +1,70 @@
+package ru.olamedia.math;
+
+public class Vector3f {
+ public float x;
+ public float y;
+ public float z;
+
+ public Vector3f() {
+ this(0, 0, 0);
+ }
+
+ public Vector3f(float x, float y, float z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public Vector3f(Vector3f vector) {
+ this(vector.x, vector.y, vector.z);
+ }
+
+ public float dot(Vector3f v) {
+ return (x * v.x + y * v.y + z * v.z);
+ }
+
+ public Vector3f cross(Vector3f n) {
+ Vector3f r = new Vector3f(y * n.z - z * n.y, z * n.x - x * n.z, x * n.y - y * n.x);
+ return r;
+ }
+
+ public Vector3f add(Vector3f n) {
+ Vector3f r = new Vector3f(x + n.x, y + n.y, z + n.z);
+ return r;
+ }
+
+ public Vector3f sub(Vector3f n) {
+ return add(n.negate());
+ }
+
+ public Vector3f negate() {
+ Vector3f n = new Vector3f(this);
+ n.x = -n.x;
+ n.y = -n.y;
+ n.z = -n.z;
+ return n;
+ }
+
+ public Vector3f translate(Vector3f look, float f) {
+ Vector3f v = new Vector3f(this);
+ v.x += look.x * f;
+ v.y += look.y * f;
+ v.z += look.z * f;
+ return v;
+ }
+
+ public Vector3f translate(javax.vecmath.Vector3f look, float f) {
+ Vector3f v = new Vector3f(this);
+ v.x += look.x * f;
+ v.y += look.y * f;
+ v.z += look.z * f;
+ return v;
+ }
+
+ public void set(Vector3f vn) {
+ x = vn.x;
+ y = vn.y;
+ z = vn.z;
+ }
+
+}
diff --git a/src/ru/olamedia/math/ViewMatrix.java b/src/ru/olamedia/math/ViewMatrix.java
new file mode 100644
index 0000000..dad4778
--- /dev/null
+++ b/src/ru/olamedia/math/ViewMatrix.java
@@ -0,0 +1,111 @@
+package ru.olamedia.math;
+
+public class ViewMatrix extends Matrix4f {
+ private Matrix4f translation = new Matrix4f();
+ private Matrix4f scale = new Matrix4f();
+ private Matrix4f rotation = new Matrix4f();
+ private TransformMatrix transform = new TransformMatrix();
+
+ public ViewMatrix() {
+ translation.setIdentity();
+ scale.setIdentity();
+ rotation.setIdentity();
+ transform.setIdentity();
+ pack();
+ }
+
+ public void pack() {
+ loadIdentity();
+ transform.loadIdentity();
+ transform.applyScale(scale);
+ transform.applyRotation(rotation);
+ transform.applyTranslation(translation);
+ apply(transform);
+ @SuppressWarnings("unused")
+ float[] t = transform.toFloatArray();
+
+ // this.m[12] = 0;
+ // this.m[13] = 0;
+ // this.m[14] = 0;
+ // Fill translation:
+ // this.m[3] = -(t[0] * t[12] + t[1] * t[13] + t[2] * t[14]);
+ // this.m[7] = -(t[4] * t[12] + t[5] * t[13] + t[6] * t[14]);
+ // this.m[11] = (t[8] * t[12] + t[9] * t[13] + t[10] * t[14]);
+ // m[12] = -(t[0] * t[12] + t[1] * t[13] + t[2] * t[14]);
+ // m[13] = -(t[4] * t[12] + t[5] * t[13] + t[6] * t[14]);
+ // m[14] = (t[8] * t[12] + t[9] * t[13] + t[10] * t[14]);
+ }
+
+ public float getX() {
+ return -translation.get(12);
+ }
+
+ public float getY() {
+ return -translation.get(13);
+ }
+
+ public float getZ() {
+ return -translation.get(14);
+ }
+
+ /**
+ * @return the translation
+ */
+ public Matrix4f getTranslation() {
+ return translation;
+ }
+
+ /**
+ * @param translation
+ * the translation to set
+ */
+ public void setTranslation(Matrix4f translation) {
+ this.translation = translation;
+ }
+
+ /**
+ * @return the scale
+ */
+ public Matrix4f getScale() {
+ return scale;
+ }
+
+ /**
+ * @param scale
+ * the scale to set
+ */
+ public void setScale(Matrix4f scale) {
+ this.scale = scale;
+ }
+
+ /**
+ * @return the rotation
+ */
+ public Matrix4f getRotation() {
+ return rotation;
+ }
+
+ /**
+ * @param rotation
+ * the rotation to set
+ */
+ public void setRotation(Matrix4f rotation) {
+ this.rotation = rotation;
+ }
+
+ public void rotateX(float degrees) {
+ setRotation(getRotation().multiply(Matrix4f.rotateXMatrix(degrees)));
+ }
+
+ public void rotateY(float degrees) {
+ setRotation(getRotation().multiply(Matrix4f.rotateYMatrix(degrees)));
+ }
+
+ public void rotateZ(float degrees) {
+ setRotation(getRotation().multiply(Matrix4f.rotateZMatrix(degrees)));
+ }
+
+ public Matrix4f getTransform() {
+ return transform;
+ }
+}
diff --git a/src/ru/olamedia/math/package-info.java b/src/ru/olamedia/math/package-info.java
new file mode 100644
index 0000000..82b4066
--- /dev/null
+++ b/src/ru/olamedia/math/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.math; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/OlaCraft.java b/src/ru/olamedia/olacraft/OlaCraft.java
new file mode 100644
index 0000000..b5b3234
--- /dev/null
+++ b/src/ru/olamedia/olacraft/OlaCraft.java
@@ -0,0 +1,6 @@
+package ru.olamedia.olacraft;
+
+public class OlaCraft {
+ public static String version = "0.1.6";
+
+}
diff --git a/src/ru/olamedia/olacraft/OlaCraftFrame.java b/src/ru/olamedia/olacraft/OlaCraftFrame.java
new file mode 100644
index 0000000..95f1835
--- /dev/null
+++ b/src/ru/olamedia/olacraft/OlaCraftFrame.java
@@ -0,0 +1,10 @@
+package ru.olamedia.olacraft;
+
+import ru.olamedia.game.GameFrame;
+
+public class OlaCraftFrame extends GameFrame {
+ public OlaCraftFrame() {
+ super();
+ jFrame.setTitle("OlaCraft " + OlaCraft.version);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/events/GameEvent.java b/src/ru/olamedia/olacraft/events/GameEvent.java
new file mode 100644
index 0000000..94b291c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/events/GameEvent.java
@@ -0,0 +1,32 @@
+package ru.olamedia.olacraft.events;
+
+public class GameEvent {
+ public static int GAME_START = GameEventRegistry.get("game.start");
+ public static int PLAYER_SPAWN = GameEventRegistry.get("player.spawn");
+ private Object source;
+ private int type;
+
+ public GameEvent(Object source) {
+ this.setSource(source);
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public void setSource(Object source) {
+ this.source = source;
+ }
+
+ public void dispatch() {
+ GameEventDispatcher.dispatch(this);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/events/GameEventDispatcher.java b/src/ru/olamedia/olacraft/events/GameEventDispatcher.java
new file mode 100644
index 0000000..7cae41a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/events/GameEventDispatcher.java
@@ -0,0 +1,22 @@
+package ru.olamedia.olacraft.events;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GameEventDispatcher {
+ private static List<GameEventListener> listeners = new ArrayList<GameEventListener>();
+
+ public static void attach(GameEventListener listener) {
+ listeners.add(listener);
+ }
+
+ public static void detach(GameEventListener listener) {
+ listeners.remove(listener);
+ }
+
+ public static void dispatch(GameEvent e) {
+ for (GameEventListener l : listeners) {
+ l.on(e);
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/events/GameEventListener.java b/src/ru/olamedia/olacraft/events/GameEventListener.java
new file mode 100644
index 0000000..1ff8185
--- /dev/null
+++ b/src/ru/olamedia/olacraft/events/GameEventListener.java
@@ -0,0 +1,5 @@
+package ru.olamedia.olacraft.events;
+
+public interface GameEventListener {
+ public void on(GameEvent e);
+}
diff --git a/src/ru/olamedia/olacraft/events/GameEventRegistry.java b/src/ru/olamedia/olacraft/events/GameEventRegistry.java
new file mode 100644
index 0000000..a9e1885
--- /dev/null
+++ b/src/ru/olamedia/olacraft/events/GameEventRegistry.java
@@ -0,0 +1,17 @@
+package ru.olamedia.olacraft.events;
+
+import java.util.HashMap;
+
+public class GameEventRegistry {
+ private static HashMap<String, Integer> map = new HashMap<String, Integer>();
+ private static int i = 0;
+
+ public static int get(String name) {
+ if (map.containsKey(name)) {
+ return map.get(name);
+ }
+ i++;
+ map.put(name, i);
+ return i;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/events/package-info.java b/src/ru/olamedia/olacraft/events/package-info.java
new file mode 100644
index 0000000..2a5a677
--- /dev/null
+++ b/src/ru/olamedia/olacraft/events/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.events; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/game/Game.java b/src/ru/olamedia/olacraft/game/Game.java
new file mode 100644
index 0000000..0980505
--- /dev/null
+++ b/src/ru/olamedia/olacraft/game/Game.java
@@ -0,0 +1,106 @@
+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 {
+ public static Game instance = null;
+ public static int port = 26002;
+ public static boolean isServerRunning = false;
+ public static GameServer server = new GameServer();
+ public static GameClient client = new GameClient();
+ public static Timer timer = new Timer();
+
+ public MatrixCamera camera;
+
+ public static int MODE_SINGLEPLAYER = 1;
+ public static int MODE_MULTIPLAYER = 2;
+ public static int MODE_SERVER = 4;
+ @SuppressWarnings("unused")
+ private int mode = 1;
+ private boolean isRunning = false;
+ @SuppressWarnings("unused")
+ // player
+ public Player player;
+
+ // block world
+ // private blockWorld;
+ // live entities (including player and npcs)
+ // private liveEntities;
+ public Game() {
+ this(MODE_SINGLEPLAYER);
+ }
+
+ public Game(int mode) {
+ this.mode = mode;
+ if ((MODE_MULTIPLAYER & mode) > 0) {
+ if ((MODE_SERVER & mode) > 0) {
+ // init server
+ } else {
+ // init client
+ }
+ }
+ player = new Player();
+ camera = new MatrixCamera();
+ camera.attachTo(player);
+ camera.setFov(90);
+ camera.pack();
+ // scene.registerLiveEntity(player);
+ }
+
+ public void start() {
+ isRunning = true;
+ GameEvent e = new GameEvent(null);
+ e.setType(GameEvent.GAME_START);
+ e.dispatch();
+ }
+
+ // Pause game in single mode
+ public void pause() {
+
+ }
+
+ public void stop() {
+
+ }
+
+ public boolean isRunning() {
+ return isRunning;
+ }
+
+ public void spawnMe(int x, int y, int z) {
+ player.setLocation(x, y, z);
+ }
+
+ public void tick() {
+ timer.update();
+
+ }
+
+ public static class Display {
+ public static int getWidth() {
+ return (int) GameFrame.getWidth();
+ }
+
+ public static int getHeight() {
+ return (int) GameFrame.getHeight();
+ }
+
+ public static float getAspect() {
+ return ((float) getWidth()) / ((float) getHeight());
+ }
+ }
+
+ public float getDelta() {
+ return (float) timer.getElapsedTime() / 1000;
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/game/GameInterface.java b/src/ru/olamedia/olacraft/game/GameInterface.java
new file mode 100644
index 0000000..1f02071
--- /dev/null
+++ b/src/ru/olamedia/olacraft/game/GameInterface.java
@@ -0,0 +1,7 @@
+package ru.olamedia.olacraft.game;
+
+public class GameInterface {
+ public void requestSpawn(){
+
+ }
+}
diff --git a/src/ru/olamedia/olacraft/game/IGameWrapper.java b/src/ru/olamedia/olacraft/game/IGameWrapper.java
new file mode 100644
index 0000000..a4a7ed1
--- /dev/null
+++ b/src/ru/olamedia/olacraft/game/IGameWrapper.java
@@ -0,0 +1,7 @@
+package ru.olamedia.olacraft.game;
+
+public interface IGameWrapper {
+ public void setMyId(int connectionId);
+
+ public void spawn(int connectionId, int x, int y, int z);
+}
diff --git a/src/ru/olamedia/olacraft/game/LocalGameWrapper.java b/src/ru/olamedia/olacraft/game/LocalGameWrapper.java
new file mode 100644
index 0000000..8c19ce6
--- /dev/null
+++ b/src/ru/olamedia/olacraft/game/LocalGameWrapper.java
@@ -0,0 +1,17 @@
+package ru.olamedia.olacraft.game;
+
+public class LocalGameWrapper implements IGameWrapper {
+
+ @Override
+ public void setMyId(int connectionId) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void spawn(int connectionId, int x, int y, int z) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/game/SpawnLocation.java b/src/ru/olamedia/olacraft/game/SpawnLocation.java
new file mode 100644
index 0000000..2ff0c39
--- /dev/null
+++ b/src/ru/olamedia/olacraft/game/SpawnLocation.java
@@ -0,0 +1,7 @@
+package ru.olamedia.olacraft.game;
+
+public class SpawnLocation {
+ public int x;
+ public int y;
+ public int z;
+}
diff --git a/src/ru/olamedia/olacraft/game/Timer.java b/src/ru/olamedia/olacraft/game/Timer.java
new file mode 100644
index 0000000..1c0aaee
--- /dev/null
+++ b/src/ru/olamedia/olacraft/game/Timer.java
@@ -0,0 +1,99 @@
+package ru.olamedia.olacraft.game;
+
+/**
+ * For frame-rate independent movement
+ *
+ * @author Oskar Veerhoek
+ */
+public class Timer {
+ private long lastTime; // nanoseconds
+ private double elapsedTime;
+ private float fps;
+ private int fpsCounter = 0;
+ private long lastFPS;
+ private float avgSeconds = 3;
+
+ /**
+ * @return the fps
+ */
+ public float getFps() {
+ return fps;
+ }
+
+ /**
+ * @return the avgFps
+ */
+ public float getAvgFps() {
+ return avgFps;
+ }
+
+ private float avgFps;
+
+ /**
+ * Creates a timer.
+ */
+ public Timer() {
+ fps = 0;
+ }
+
+ /**
+ * Initializes the timer. Call this just before entering the game loop.
+ */
+ public void initialize() {
+ lastTime = System.nanoTime();
+ }
+
+ /**
+ * @return the elapsed time since the the next to last update call
+ */
+ public double getElapsedTime() {
+ return elapsedTime;
+ }
+
+ /**
+ * Updates the timer. Call this once every iteration of the game loop.
+ *
+ * @return the elapsed time in milliseconds
+ */
+ public double update() {
+ if (lastTime == 0) {
+ lastTime = System.nanoTime();
+ return 0;
+ } else {
+ long elapsedTime = System.nanoTime() - lastTime;
+ updateFps(elapsedTime);
+ lastTime = System.nanoTime();
+ this.elapsedTime = elapsedTime / (double) 1000000;
+ return this.elapsedTime;
+ }
+ }
+
+ public void updateFps(long elapsedTime) {
+ if (elapsedTime > 0) {
+ float ms = (float) (elapsedTime / 1000000);
+ if (ms > 0) {
+ fps = (float) (1000 / ms);
+ }
+ }
+ fpsCounter++;
+ if (lastFPS == 0) {
+ lastFPS = System.nanoTime();
+ } else {
+ double elapsedFPS = (System.nanoTime() - lastFPS) / (double) 1000000;
+ if (elapsedFPS > 1000 * avgSeconds) {
+ avgFps = fpsCounter / avgSeconds;
+ fpsCounter = 0;
+ lastFPS = System.nanoTime();
+ }
+ }
+
+ // if (elapsedTime > 0) {
+ // fps = (float) (1000 / (elapsedTime / 1000000));
+ // if (avgFps == 0) {
+ // avgFps = fps;
+ // } else {
+ // avgFps = avgFps + (fps - avgFps) / 1000;
+ // }
+ // }
+ }
+} \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/game/package-info.java b/src/ru/olamedia/olacraft/game/package-info.java
new file mode 100644
index 0000000..85b0f16
--- /dev/null
+++ b/src/ru/olamedia/olacraft/game/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.game; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/inventory/Frame.java b/src/ru/olamedia/olacraft/inventory/Frame.java
new file mode 100644
index 0000000..a5cd979
--- /dev/null
+++ b/src/ru/olamedia/olacraft/inventory/Frame.java
@@ -0,0 +1,44 @@
+package ru.olamedia.olacraft.inventory;
+
+import org.olamedia.olacraft.draw.DrawInterface;
+import org.olamedia.olacraft.entity.AbstractEntity;
+
+import static org.olamedia.olacraft.blocks.Block.BLOCK_SIZE;
+import org.olamedia.olacraft.util.CommonApi;
+
+public class Frame extends AbstractEntity implements DrawInterface {
+ public Frame(double x, double y, double z, double width, double height,
+ double depth) {
+ super(x, y, z, width, height, depth);
+ }
+
+ public CommonApi api = CommonApi.instance;
+
+ @Override
+ public void update(double delta) {
+
+ }
+
+ @Override
+ public void draw() {
+ api.draw.texRecti("inventory_frame", x, y, BLOCK_SIZE, BLOCK_SIZE);
+ return;
+ // Texture t = api.texture.get("inventory_frame");
+ // t.bind();
+ // glColor3f(1, 1, 1);
+ // glLoadIdentity();
+ // glTranslated(x, y, 0);
+ // glBegin(GL_QUADS);
+ // glTexCoord2f(0, 0);
+ // glVertex2f(0, 0); // Upper-left
+ // glTexCoord2f(1, 0);
+ // glVertex2f(BLOCK_SIZE, 0); // Upper-right
+ // glTexCoord2f(1, 1);
+ // glVertex2f(BLOCK_SIZE, BLOCK_SIZE); // Bottom-right
+ // glTexCoord2f(0, 1);
+ // glVertex2f(0, BLOCK_SIZE); // Bottom-left
+ // glEnd();
+ // glLoadIdentity();
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/inventory/Inventory.java b/src/ru/olamedia/olacraft/inventory/Inventory.java
new file mode 100644
index 0000000..2ce843b
--- /dev/null
+++ b/src/ru/olamedia/olacraft/inventory/Inventory.java
@@ -0,0 +1,76 @@
+package ru.olamedia.olacraft.inventory;
+
+import ru.olamedia.olacraft.world.block.Block;
+import ru.olamedia.olacraft.world.blockStack.BlockStack;
+
+public class Inventory {
+ public static int BIND_NUM = 10;
+ public BlockStack[] binded = new BlockStack[BIND_NUM];
+ public BlockStack selected;
+ public int selectedId;
+ private boolean isInventoryGUIOpen = false;
+
+ public Inventory() {
+ }
+
+ 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);
+ }
+ 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);
+ }
+ if (key == Keyboard.KEY_2) {
+ select(1);
+ }
+ if (key == Keyboard.KEY_3) {
+ select(2);
+ }
+ if (key == Keyboard.KEY_4) {
+ select(3);
+ }
+ if (key == Keyboard.KEY_5) {
+ select(4);
+ }
+ if (key == Keyboard.KEY_6) {
+ select(5);
+ }
+ if (key == Keyboard.KEY_7) {
+ select(6);
+ }
+ if (key == Keyboard.KEY_8) {
+ select(7);
+ }
+ if (key == Keyboard.KEY_9) {
+ select(8);
+ }
+ if (key == Keyboard.KEY_0) {
+ select(9);
+ }
+ if (key == Keyboard.KEY_E) {
+ isInventoryGUIOpen = !isInventoryGUIOpen;
+ }
+
+ }
+
+ public void select(int i) {
+ selected = binded[i];
+ }
+}
diff --git a/src/ru/olamedia/olacraft/inventory/package-info.java b/src/ru/olamedia/olacraft/inventory/package-info.java
new file mode 100644
index 0000000..fe2b1fc
--- /dev/null
+++ b/src/ru/olamedia/olacraft/inventory/package-info.java
@@ -0,0 +1,9 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.inventory;
+
diff --git a/src/ru/olamedia/olacraft/network/ConnectionState.java b/src/ru/olamedia/olacraft/network/ConnectionState.java
new file mode 100644
index 0000000..2d6c5c5
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/ConnectionState.java
@@ -0,0 +1,17 @@
+package ru.olamedia.olacraft.network;
+
+public class ConnectionState {
+ private int state;
+
+ public ConnectionState(int state) {
+ this.state = state;
+ }
+
+ public static ConnectionState STATE_DISCONNECTED = new ConnectionState(0);
+ public static ConnectionState STATE_CONNECTED = new ConnectionState(1);
+ public static ConnectionState STATE_CONNECTING = new ConnectionState(2);
+
+ public boolean isConnected() {
+ return state == 1;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/ConnectionStateListener.java b/src/ru/olamedia/olacraft/network/ConnectionStateListener.java
new file mode 100644
index 0000000..6220029
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/ConnectionStateListener.java
@@ -0,0 +1,7 @@
+package ru.olamedia.olacraft.network;
+
+public class ConnectionStateListener {
+ public void onChangeState(ConnectionState state){
+ // override
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/GameClient.java b/src/ru/olamedia/olacraft/network/GameClient.java
new file mode 100644
index 0000000..669d954
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/GameClient.java
@@ -0,0 +1,209 @@
+package ru.olamedia.olacraft.network;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryonet.Client;
+import com.esotericsoftware.kryonet.Connection;
+import com.esotericsoftware.kryonet.Listener;
+
+import ru.olamedia.game.GameManager;
+import ru.olamedia.liveEntity.LiveEntity;
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.network.packet.ConnectionPacket;
+import ru.olamedia.olacraft.network.packet.ConnectionRequestPacket;
+import ru.olamedia.olacraft.network.packet.IPacket;
+import ru.olamedia.olacraft.network.packet.IPacketListener;
+import ru.olamedia.olacraft.network.packet.LiveEntityLocationUpdatePacket;
+import ru.olamedia.olacraft.network.packet.SpawnPacket;
+import ru.olamedia.olacraft.network.packet.SpawnRequestPacket;
+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.RemoteChunkDataProvider;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class GameClient extends ConnectionStateListener implements IPacketListener {
+ private WorldProvider worldProvider;
+ private GameScene scene;
+
+ private Client client = new Client(70 * 1024 * 1024, 70 * 1024 * 1024);
+ private String hostname = "127.0.0.1";
+
+ @Override
+ public void onChangeState(ConnectionState state) {
+ if (state.isConnected()) {
+ GameManager.instance.hideMainMenu();
+ client.sendTCP(new ConnectionRequestPacket());
+ //
+ // provider.load(0, 0, 0);
+ // provider.load(1, 2, 3);
+ }
+ }
+
+ /*
+ * public AbstractChunkDataProvider getChunkDataProvider() {
+ * return worldProvider.getChunkDataProvider();
+ * }
+ */
+
+ public WorldProvider getWorldProvider() {
+ return worldProvider;
+ }
+
+ private List<ConnectionStateListener> stateListeners = new ArrayList<ConnectionStateListener>();
+ private List<IPacketListener> packetListeners = new ArrayList<IPacketListener>();
+ private ExecutorService threadPool = Executors.newFixedThreadPool(1);
+
+ public GameClient() {
+ // INIT WORLD
+ worldProvider = new WorldProvider();
+ worldProvider.setChunkDataProvider(new CachedChunkDataProvider(new RemoteChunkDataProvider(this)));
+ // CREATE SCENE
+ scene = new GameScene(worldProvider);
+ Kryo kryo = client.getKryo();
+ Network.registerPackets(kryo);
+ addStateListener(this);
+ addPacketListener(this);
+ client.addListener(new Listener.ThreadedListener(new Listener() {
+
+ @Override
+ public void received(Connection connection, Object object) {
+ if (object instanceof IPacket) {
+ dispatchPacket(connection, (IPacket) object);
+ }
+ }
+
+ @Override
+ public void disconnected(Connection connection) {
+ super.disconnected(connection);
+ dispatchState(ConnectionState.STATE_DISCONNECTED);
+ }
+ }, threadPool));
+ client.start();
+ }
+
+ public void addStateListener(ConnectionStateListener listener) {
+ stateListeners.add(listener);
+ }
+
+ private void dispatchState(ConnectionState state) {
+ for (ConnectionStateListener l : stateListeners) {
+ l.onChangeState(state);
+ }
+ }
+
+ private void dispatchPacket(Connection connection, IPacket p) {
+ for (IPacketListener l : packetListeners) {
+ l.onPacket(connection, p);
+ }
+ }
+
+ public void connect() {
+ new Thread("Connect") {
+ public void run() {
+ try {
+ dispatchState(ConnectionState.STATE_CONNECTING);
+ client.connect(5000, hostname, Game.port);
+ dispatchState(ConnectionState.STATE_CONNECTED);
+ } catch (IOException ex) {
+ dispatchState(ConnectionState.STATE_DISCONNECTED);
+ }
+ }
+ }.start();
+ }
+
+ public void close() {
+ client.close();
+ }
+
+ public void send(IPacket p) {
+ client.sendTCP(p);
+ }
+
+ public void addPacketListener(IPacketListener listener) {
+ packetListeners.add(listener);
+ }
+
+ public boolean isConnected() {
+ return client.isConnected();
+ }
+
+ private static boolean DEBUG = true;
+
+ private void debug(String s) {
+ if (DEBUG) {
+ System.out.println("[GameClient] " + s);
+ }
+ }
+
+ @Override
+ public void onPacket(Connection connection, IPacket p) {
+ debug("received " + p.getClass().getName());
+ // 1. receive ConnectionPacket, send SpawnRequestPacket
+ if (p instanceof ConnectionPacket) {
+ Game.instance.player.setConnectionId(((ConnectionPacket) p).connectionId);
+ send(new SpawnRequestPacket());
+ }
+ if (p instanceof WorldInfoPacket) {
+ worldProvider.setInfo(((WorldInfoPacket) p).info);
+ }
+ // 2. Receive SpawnPacket
+ if (p instanceof SpawnPacket) {
+ LiveEntity entity;
+ if (((SpawnPacket) p).connectionId == client.getID()) {
+ // me
+ entity = Game.instance.player;
+ } else {
+ // another player
+ entity = new LiveEntity();
+ }
+ entity.setX(((SpawnPacket) p).x);
+ entity.setY(((SpawnPacket) p).y);
+ entity.setZ(((SpawnPacket) p).z);
+ entity.setConnectionId(((SpawnPacket) p).connectionId);
+ scene.registerLiveEntity(entity);
+ if (((SpawnPacket) p).connectionId == client.getID()) {
+ // me
+ scene.registerPlayer(entity);
+ }
+ }
+ if (p instanceof LiveEntityLocationUpdatePacket) {
+ LiveEntity entity = scene.getLiveEntity(((LiveEntityLocationUpdatePacket) p).connectionId);
+ if (null != entity) {
+ entity.setX(((LiveEntityLocationUpdatePacket) p).x);
+ entity.setY(((LiveEntityLocationUpdatePacket) p).y);
+ entity.setZ(((LiveEntityLocationUpdatePacket) p).z);
+ }
+ }
+ }
+
+ public String getHostname() {
+ return hostname;
+ }
+
+ public void setHostname(String hostname) {
+ this.hostname = hostname;
+ }
+
+ public void dispose() {
+ client.close();
+ client.stop();
+ // threadPool.awaitTermination(1000, TimeUnit.MILLISECONDS);
+ threadPool.shutdownNow();
+ }
+
+ public GameScene getScene() {
+ return scene;
+ }
+
+ public WorldInfo getWorldInfo() {
+ return worldProvider.getInfo();
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/network/GameServer.java b/src/ru/olamedia/olacraft/network/GameServer.java
new file mode 100644
index 0000000..67dffc5
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/GameServer.java
@@ -0,0 +1,169 @@
+package ru.olamedia.olacraft.network;
+
+import java.io.IOException;
+import java.net.BindException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import ru.olamedia.liveEntity.LiveEntity;
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.game.SpawnLocation;
+import ru.olamedia.olacraft.network.discovery.DiscoveryThread;
+import ru.olamedia.olacraft.network.packet.ConnectionPacket;
+import ru.olamedia.olacraft.network.packet.ConnectionRequestPacket;
+import ru.olamedia.olacraft.network.packet.GetRegionPacket;
+import ru.olamedia.olacraft.network.packet.IPacket;
+import ru.olamedia.olacraft.network.packet.LiveEntityLocationUpdatePacket;
+import ru.olamedia.olacraft.network.packet.RegionDataPacket;
+import ru.olamedia.olacraft.network.packet.SpawnPacket;
+import ru.olamedia.olacraft.network.packet.SpawnRequestPacket;
+import ru.olamedia.olacraft.network.packet.WorldInfoPacket;
+import ru.olamedia.olacraft.scene.GameScene;
+import ru.olamedia.olacraft.world.data.RegionData;
+import ru.olamedia.olacraft.world.dataProvider.CachedChunkDataProvider;
+import ru.olamedia.olacraft.world.dataProvider.LocalChunkDataProvider;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryonet.Connection;
+import com.esotericsoftware.kryonet.Listener;
+import com.esotericsoftware.kryonet.Server;
+
+public class GameServer {
+ private WorldProvider worldProvider;
+
+ private ExecutorService threadPool = Executors.newFixedThreadPool(1);
+ public static Server server = new Server(70 * 1024 * 1024, 1024 * 1024) {
+ @Override
+ protected PlayerConnection newConnection() {
+ // By providing our own connection implementation, we can store per
+ // connection state without a connection ID to state look up.
+ return new PlayerConnection();
+ }
+ };
+ private boolean isServerRunning = false;
+
+ private GameScene scene;
+
+ private static boolean DEBUG = true;
+
+ private void debug(String s) {
+ if (DEBUG) {
+ System.out.println("[GameServer] " + s);
+ }
+ }
+
+ public GameServer() {
+ // INIT WORLD
+ worldProvider = new WorldProvider();
+ worldProvider.setChunkDataProvider(new CachedChunkDataProvider(new LocalChunkDataProvider(worldProvider.getInfo().name)));
+ // CREATE SCENE
+ scene = new GameScene(worldProvider);
+ // worldProvider.getInfo().name = "world";
+ Kryo kryo = server.getKryo();
+ Network.registerPackets(kryo);
+ server.addListener(new Listener.ThreadedListener(new Listener() {
+ @Override
+ public void disconnected(Connection connection) {
+ }
+
+ @Override
+ public void received(Connection connection, Object object) {
+ debug("received " + object.getClass());
+ if (object instanceof ConnectionRequestPacket) {
+ ConnectionPacket p = new ConnectionPacket();
+ p.connectionId = connection.getID();
+ server.sendToTCP(connection.getID(), p);
+ }
+ if (object instanceof GetRegionPacket) {
+ GetRegionPacket p = (GetRegionPacket) object;
+ RegionData data = worldProvider.getRegion(p.location);
+ RegionDataPacket response = new RegionDataPacket();
+ response.data = data;
+ server.sendToTCP(connection.getID(), response);
+ }
+ if (object instanceof SpawnRequestPacket) {
+ SpawnLocation loc = worldProvider.getSpawnLocation(connection.getID());
+ if (null != loc) {
+ server.sendToTCP(connection.getID(), new WorldInfoPacket(worldProvider));
+ LiveEntity entity = new LiveEntity();
+ entity.setX(loc.x);
+ entity.setY(loc.y);
+ entity.setZ(loc.z);
+ entity.setConnectionId(connection.getID());
+ scene.registerLiveEntity(entity);
+ // send all entity locations
+ for (LiveEntity nextEntity : scene.getLiveEntities().values()) {
+ SpawnPacket p = new SpawnPacket();
+ p.x = nextEntity.getX();
+ p.y = nextEntity.getY();
+ p.z = nextEntity.getZ();
+ p.connectionId = nextEntity.getConnectionId();
+ if (p.connectionId == connection.getID()) {
+ server.sendToAllTCP(p);
+ } else {
+ server.sendToTCP(connection.getID(), p);
+ }
+ }
+ }
+ }
+ if (object instanceof LiveEntityLocationUpdatePacket) {
+ LiveEntityLocationUpdatePacket p = ((LiveEntityLocationUpdatePacket) object);
+ p.connectionId = connection.getID();
+ LiveEntity entity = scene.getLiveEntity(connection.getID());
+ if (null != entity) {
+ entity.setLocation(p.x, p.y, p.z);
+ server.sendToAllTCP(object);
+ }
+ }
+
+ // super.received(connection, object);
+ }
+ }, threadPool));
+ }
+
+ private DiscoveryThread discovery;
+
+ public void start() {
+ try {
+ server.start();
+ server.bind(Game.port);
+ discovery = new DiscoveryThread("SERVER DISCOVERY");
+ discovery.start();
+ isServerRunning = true;
+ // server.addListener(new Listener());
+ } catch (BindException ex) {
+ server.stop();
+ if (null != discovery && discovery.isAlive()) {
+ discovery.interrupt();
+ }
+ isServerRunning = false;
+ } catch (IOException e1) {
+ server.stop();
+ if (null != discovery && discovery.isAlive()) {
+ discovery.interrupt();
+ }
+ e1.printStackTrace();
+ isServerRunning = false;
+ }
+ }
+
+ public void stop() {
+ server.close();
+ server.stop();
+ isServerRunning = false;
+ }
+
+ public boolean isRunning() {
+ return isServerRunning;
+ }
+
+ public void send(IPacket p) {
+ }
+
+ public void dispose() {
+ stop();
+ // threadPool.awaitTermination(1000, TimeUnit.MILLISECONDS);
+ threadPool.shutdownNow();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/Network.java b/src/ru/olamedia/olacraft/network/Network.java
new file mode 100644
index 0000000..2ba8eab
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/Network.java
@@ -0,0 +1,71 @@
+package ru.olamedia.olacraft.network;
+
+import java.util.BitSet;
+
+import ru.olamedia.olacraft.network.packet.ChunkDataPacket;
+import ru.olamedia.olacraft.network.packet.ConnectionPacket;
+import ru.olamedia.olacraft.network.packet.ConnectionRequestPacket;
+import ru.olamedia.olacraft.network.packet.GetChunkDataPacket;
+import ru.olamedia.olacraft.network.packet.GetRegionPacket;
+import ru.olamedia.olacraft.network.packet.LiveEntityLocationUpdatePacket;
+import ru.olamedia.olacraft.network.packet.RegionDataPacket;
+import ru.olamedia.olacraft.network.packet.SpawnPacket;
+import ru.olamedia.olacraft.network.packet.SpawnRequestPacket;
+import ru.olamedia.olacraft.network.packet.WorldInfoPacket;
+import ru.olamedia.olacraft.world.WorldInfo;
+import ru.olamedia.olacraft.world.data.ChunkData;
+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.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.location.RegionLocation;
+import ru.olamedia.olacraft.world.location.SectorLocation;
+
+import com.esotericsoftware.kryo.Kryo;
+
+public class Network {
+ public static void registerPackets(Kryo kryo) {
+ // types
+ kryo.register(boolean.class);
+ kryo.register(boolean[].class);
+ kryo.register(byte.class);
+ kryo.register(byte[].class);
+ kryo.register(byte[][].class);
+ kryo.register(int.class);
+ kryo.register(int[].class);
+ kryo.register(float.class);
+ kryo.register(float[].class);
+ kryo.register(long.class);
+ kryo.register(long[].class);
+ kryo.register(BitSet.class);
+ kryo.register(HeightMap.class);
+ kryo.register(WorldInfo.class);
+ kryo.register(WorldInfoPacket.class);
+ kryo.register(BlockLocation.class);
+ kryo.register(ChunkLocation.class);
+ kryo.register(SectorLocation.class);
+ kryo.register(RegionLocation.class);
+ kryo.register(ChunkData.class);
+ kryo.register(ChunkData[].class);
+ kryo.register(SectorData.class);
+ kryo.register(SectorData[].class);
+ kryo.register(SectorData[][].class);
+ kryo.register(RegionData.class);
+ kryo.register(GetRegionPacket.class);
+ kryo.register(RegionDataPacket.class);
+
+
+ kryo.register(ChunkLightData.class);
+ kryo.register(ChunkData.class);
+ // packets
+ kryo.register(ConnectionRequestPacket.class);
+ kryo.register(ConnectionPacket.class);
+ kryo.register(SpawnRequestPacket.class);
+ kryo.register(SpawnPacket.class);
+ kryo.register(GetChunkDataPacket.class);
+ kryo.register(ChunkDataPacket.class);
+ kryo.register(LiveEntityLocationUpdatePacket.class);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/PlayerConnection.java b/src/ru/olamedia/olacraft/network/PlayerConnection.java
new file mode 100644
index 0000000..3120b4d
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/PlayerConnection.java
@@ -0,0 +1,9 @@
+package ru.olamedia.olacraft.network;
+
+import ru.olamedia.liveEntity.LiveEntity;
+
+import com.esotericsoftware.kryonet.Connection;
+
+public class PlayerConnection extends Connection{
+ public LiveEntity entity;
+}
diff --git a/src/ru/olamedia/olacraft/network/discovery/DiscoveryClient.java b/src/ru/olamedia/olacraft/network/discovery/DiscoveryClient.java
new file mode 100644
index 0000000..629e6e3
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/discovery/DiscoveryClient.java
@@ -0,0 +1,143 @@
+package ru.olamedia.olacraft.network.discovery;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import ru.olamedia.tasks.Task;
+
+public class DiscoveryClient extends Task {
+ private static DatagramSocket c;
+ public static List<InetAddress> list = new ArrayList<InetAddress>();
+ private static List<DiscoveryListener> listeners = new ArrayList<DiscoveryListener>();
+
+ public void addHostListener(DiscoveryListener listener) {
+ listeners.add(listener);
+ }
+
+ public static void discovery() {
+ list.clear();
+ try {
+ list.add(InetAddress.getByName("127.0.0.1"));
+ } catch (UnknownHostException e1) {
+ e1.printStackTrace();
+ }
+ // Find the server using UDP broadcast
+ try {
+ // Open a random port to send the package
+ c = new DatagramSocket();
+ c.setBroadcast(true);
+ c.setSoTimeout(3000);
+
+ byte[] sendData = "DISCOVER_OLACRAFTSERVER_REQUEST".getBytes();
+
+ // Try the 255.255.255.255 first
+ try {
+ DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
+ InetAddress.getByName("255.255.255.255"), DiscoveryThread.port);
+ c.send(sendPacket);
+ System.out.println(DiscoveryClient.class.getName()
+ + ">>> Request packet sent to: 255.255.255.255 (DEFAULT)");
+ } catch (Exception e) {
+ }
+
+ // Broadcast the message over all the network interfaces
+ @SuppressWarnings("rawtypes")
+ Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
+
+ if (networkInterface.isLoopback() || !networkInterface.isUp()) {
+ continue; // Don't want to broadcast to the loopback
+ // interface
+ }
+
+ for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
+ InetAddress broadcast = interfaceAddress.getBroadcast();
+ if (broadcast == null) {
+ continue;
+ }
+
+ // Send the broadcast package!
+ try {
+ DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, broadcast, 8888);
+ c.send(sendPacket);
+ } catch (Exception e) {
+ }
+
+ System.out.println(DiscoveryClient.class.getName() + ">>> Request packet sent to: "
+ + broadcast.getHostAddress() + "; Interface: " + networkInterface.getDisplayName());
+ }
+ }
+
+ System.out.println(DiscoveryClient.class.getName()
+ + ">>> Done looping over all network interfaces. Now waiting for a reply!");
+ while (true) {
+ // Wait for a response
+ byte[] recvBuf = new byte[15000];
+ DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
+ c.receive(receivePacket);
+
+ // We have a response
+ System.out.println(DiscoveryClient.class.getName() + ">>> Broadcast response from server: "
+ + receivePacket.getAddress().getHostAddress());
+
+ // Check if the message is correct
+ String message = new String(receivePacket.getData()).trim();
+ if (message.equals("DISCOVER_OLACRAFTSERVER_RESPONSE")) {
+ list.add(receivePacket.getAddress());
+ for (DiscoveryListener l : listeners) {
+ l.onHost(receivePacket.getAddress());
+ }
+ // DO SOMETHING WITH THE SERVER'S IP (for example, store it
+ // in
+ // your controller)
+ // Controller_Base.setServerIp(receivePacket.getAddress());
+ }
+ }
+ } catch (SocketTimeoutException ex) {
+ // no hosts were discovered
+ } catch (IOException ex) {
+ // no hosts were discovered
+ } finally {
+ // Close the port!
+ if (null != c) {
+ c.close();
+ }
+ for (DiscoveryListener l : listeners) {
+ l.onHost(null); // end of list marker
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+// while (!shouldStop()) {
+ discovery();
+ // try {
+ // wait(3000);
+ // } catch (InterruptedException e) {
+ // e.printStackTrace();
+ // }
+ // }
+ }
+
+ public void refresh() {
+ }
+
+ public static DiscoveryClient getInstance() {
+ return DiscoveryThreadHolder.INSTANCE;
+ }
+
+ private static class DiscoveryThreadHolder {
+ private static final DiscoveryClient INSTANCE = new DiscoveryClient();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/discovery/DiscoveryListener.java b/src/ru/olamedia/olacraft/network/discovery/DiscoveryListener.java
new file mode 100644
index 0000000..81c1019
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/discovery/DiscoveryListener.java
@@ -0,0 +1,9 @@
+package ru.olamedia.olacraft.network.discovery;
+
+import java.net.InetAddress;
+
+public class DiscoveryListener {
+ public void onHost(InetAddress address){
+
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/discovery/DiscoveryThread.java b/src/ru/olamedia/olacraft/network/discovery/DiscoveryThread.java
new file mode 100644
index 0000000..a6302fa
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/discovery/DiscoveryThread.java
@@ -0,0 +1,91 @@
+package ru.olamedia.olacraft.network.discovery;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+
+public class DiscoveryThread extends Thread {
+ public DiscoveryThread() {
+ super();
+ try {
+ socket = new DatagramSocket(port, InetAddress.getByName("0.0.0.0"));
+ socket.setBroadcast(true);
+ socket.setSoTimeout(1000);
+ } catch (SocketException e) {
+ e.printStackTrace();
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public DiscoveryThread(String name) {
+ this();
+ setName(name);
+ }
+
+ private DatagramSocket socket;
+ public static int port = 26003;
+
+ @Override
+ public void run() {
+ try {
+ System.out.println(getClass().getName() + ">>>Ready to receive broadcast packets!");
+ while (true) {
+
+ // Receive a packet
+ byte[] recvBuf = new byte[15000];
+ DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
+ try {
+ socket.receive(packet);
+
+ // Packet received
+ System.out.println(getClass().getName() + ">>>Discovery packet received from: "
+ + packet.getAddress().getHostAddress());
+ System.out.println(getClass().getName() + ">>>Packet received; data: "
+ + new String(packet.getData()));
+
+ // See if the packet holds the right command (message)
+ String message = new String(packet.getData()).trim();
+ if (message.equals("DISCOVER_OLACRAFTSERVER_REQUEST")) {
+ byte[] sendData = "DISCOVER_OLACRAFTSERVER_RESPONSE".getBytes();
+
+ // Send a response
+ DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, packet.getAddress(),
+ packet.getPort());
+ socket.send(sendPacket);
+
+ System.out.println(getClass().getName() + ">>>Sent packet to: "
+ + sendPacket.getAddress().getHostAddress());
+ }
+ } catch (SocketTimeoutException ex) {
+
+ }
+ try {
+ Thread.sleep(100);
+ } catch (IllegalMonitorStateException ex) {
+ ex.printStackTrace();
+ } catch (InterruptedException ex) {
+ socket.close();
+ Thread.currentThread().interrupt(); // very important
+ break;
+ }
+ }
+ } catch (IOException ex) {
+ socket.close();
+ }
+ }
+
+ public static DiscoveryThread getInstance() {
+ return DiscoveryThreadHolder.INSTANCE;
+ }
+
+ private static class DiscoveryThreadHolder {
+
+ private static final DiscoveryThread INSTANCE = new DiscoveryThread();
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/network/discovery/package-info.java b/src/ru/olamedia/olacraft/network/discovery/package-info.java
new file mode 100644
index 0000000..cb376c8
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/discovery/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.network.discovery; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/network/package-info.java b/src/ru/olamedia/olacraft/network/package-info.java
new file mode 100644
index 0000000..dfbaec9
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/package-info.java
@@ -0,0 +1,9 @@
+/**
+ *
+ */
+/**
+ * Used KryoNet library (Which is under BSD License)
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.network; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/network/packet/ChatMessagePacket.java b/src/ru/olamedia/olacraft/network/packet/ChatMessagePacket.java
new file mode 100644
index 0000000..332c9dd
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/ChatMessagePacket.java
@@ -0,0 +1,5 @@
+package ru.olamedia.olacraft.network.packet;
+
+public class ChatMessagePacket implements IPacket {
+ public String message;
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/ChunkDataPacket.java b/src/ru/olamedia/olacraft/network/packet/ChunkDataPacket.java
new file mode 100644
index 0000000..1bf92c4
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/ChunkDataPacket.java
@@ -0,0 +1,10 @@
+package ru.olamedia.olacraft.network.packet;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+
+public class ChunkDataPacket implements IPacket {
+ public int chunkX;
+ public int chunkY;
+ public int chunkZ;
+ public ChunkData data;
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/ConnectionPacket.java b/src/ru/olamedia/olacraft/network/packet/ConnectionPacket.java
new file mode 100644
index 0000000..ced43d5
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/ConnectionPacket.java
@@ -0,0 +1,11 @@
+package ru.olamedia.olacraft.network.packet;
+
+/**
+ * Server sends connection packet with assigned connection ID on client connect
+ *
+ * @author olamedia
+ *
+ */
+public class ConnectionPacket implements IPacket{
+ public int connectionId;
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/ConnectionRequestPacket.java b/src/ru/olamedia/olacraft/network/packet/ConnectionRequestPacket.java
new file mode 100644
index 0000000..419f339
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/ConnectionRequestPacket.java
@@ -0,0 +1,5 @@
+package ru.olamedia.olacraft.network.packet;
+
+public class ConnectionRequestPacket implements IPacket{
+
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/GetChunkDataPacket.java b/src/ru/olamedia/olacraft/network/packet/GetChunkDataPacket.java
new file mode 100644
index 0000000..492ce15
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/GetChunkDataPacket.java
@@ -0,0 +1,7 @@
+package ru.olamedia.olacraft.network.packet;
+
+public class GetChunkDataPacket implements IPacket{
+ public int chunkX;
+ public int chunkY;
+ public int chunkZ;
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/GetRegionPacket.java b/src/ru/olamedia/olacraft/network/packet/GetRegionPacket.java
new file mode 100644
index 0000000..2c57057
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/GetRegionPacket.java
@@ -0,0 +1,15 @@
+package ru.olamedia.olacraft.network.packet;
+
+import ru.olamedia.olacraft.world.location.RegionLocation;
+
+public class GetRegionPacket implements IPacket {
+ public RegionLocation location;
+
+ public GetRegionPacket() {
+
+ }
+
+ public GetRegionPacket(RegionLocation location) {
+ this.location = location;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/IPacket.java b/src/ru/olamedia/olacraft/network/packet/IPacket.java
new file mode 100644
index 0000000..adfa3c7
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/IPacket.java
@@ -0,0 +1,5 @@
+package ru.olamedia.olacraft.network.packet;
+
+public interface IPacket {
+
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/IPacketListener.java b/src/ru/olamedia/olacraft/network/packet/IPacketListener.java
new file mode 100644
index 0000000..2a17cd4
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/IPacketListener.java
@@ -0,0 +1,7 @@
+package ru.olamedia.olacraft.network.packet;
+
+import com.esotericsoftware.kryonet.Connection;
+
+public interface IPacketListener {
+ public void onPacket(Connection connection, IPacket p);
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/LiveEntityLocationUpdatePacket.java b/src/ru/olamedia/olacraft/network/packet/LiveEntityLocationUpdatePacket.java
new file mode 100644
index 0000000..15edfd9
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/LiveEntityLocationUpdatePacket.java
@@ -0,0 +1,15 @@
+package ru.olamedia.olacraft.network.packet;
+
+/**
+ * Client sends this packet every time location changed
+ * Server fills connectionId and sends back to every connection
+ *
+ * @author olamedia
+ *
+ */
+public class LiveEntityLocationUpdatePacket implements IPacket {
+ public float x;
+ public float y;
+ public float z;
+ public int connectionId; // filled by server only
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/RegionDataPacket.java b/src/ru/olamedia/olacraft/network/packet/RegionDataPacket.java
new file mode 100644
index 0000000..3a60230
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/RegionDataPacket.java
@@ -0,0 +1,7 @@
+package ru.olamedia.olacraft.network.packet;
+
+import ru.olamedia.olacraft.world.data.RegionData;
+
+public class RegionDataPacket implements IPacket {
+ public RegionData data;
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/SpawnPacket.java b/src/ru/olamedia/olacraft/network/packet/SpawnPacket.java
new file mode 100644
index 0000000..d25a692
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/SpawnPacket.java
@@ -0,0 +1,15 @@
+package ru.olamedia.olacraft.network.packet;
+
+/**
+ * Client sends SpawnRequestPacket on connect
+ * Server fills location, connectionId and sends SpawnPacket to every connection
+ *
+ * @author olamedia
+ *
+ */
+public class SpawnPacket implements IPacket {
+ public float x;
+ public float y;
+ public float z;
+ public int connectionId; // filled by server only
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/SpawnRequestPacket.java b/src/ru/olamedia/olacraft/network/packet/SpawnRequestPacket.java
new file mode 100644
index 0000000..0628272
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/SpawnRequestPacket.java
@@ -0,0 +1,4 @@
+package ru.olamedia.olacraft.network.packet;
+
+public class SpawnRequestPacket implements IPacket {
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/WorldInfoPacket.java b/src/ru/olamedia/olacraft/network/packet/WorldInfoPacket.java
new file mode 100644
index 0000000..9c8e1c7
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/WorldInfoPacket.java
@@ -0,0 +1,15 @@
+package ru.olamedia.olacraft.network.packet;
+
+import ru.olamedia.olacraft.world.WorldInfo;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class WorldInfoPacket implements IPacket {
+ public WorldInfoPacket(){
+
+ }
+ public WorldInfoPacket(WorldProvider worldProvider) {
+ info = worldProvider.getInfo();
+ }
+
+ public WorldInfo info;
+}
diff --git a/src/ru/olamedia/olacraft/network/packet/package-info.java b/src/ru/olamedia/olacraft/network/packet/package-info.java
new file mode 100644
index 0000000..a1da5fd
--- /dev/null
+++ b/src/ru/olamedia/olacraft/network/packet/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.network.packet; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/package-info.java b/src/ru/olamedia/olacraft/package-info.java
new file mode 100644
index 0000000..0049efb
--- /dev/null
+++ b/src/ru/olamedia/olacraft/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft;
diff --git a/src/ru/olamedia/olacraft/physics/GamePhysicsWorld.java b/src/ru/olamedia/olacraft/physics/GamePhysicsWorld.java
new file mode 100644
index 0000000..dd66ef0
--- /dev/null
+++ b/src/ru/olamedia/olacraft/physics/GamePhysicsWorld.java
@@ -0,0 +1,27 @@
+package ru.olamedia.olacraft.physics;
+
+import org.ode4j.ode.DBody;
+import org.ode4j.ode.DRay;
+import org.ode4j.ode.DWorld;
+import org.ode4j.ode.OdeHelper;
+
+public class GamePhysicsWorld {
+ private DWorld world;
+
+ public GamePhysicsWorld() {
+ world = OdeHelper.createWorld();
+ world.setGravity(0, -0.98, 0);
+ }
+
+ public DWorld getWorld() {
+ return world;
+ }
+
+ public DBody createBody(){
+ return OdeHelper.createBody(world);
+ }
+
+ public DRay createRay(int length){
+ return OdeHelper.createRay(length);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/physics/package-info.java b/src/ru/olamedia/olacraft/physics/package-info.java
new file mode 100644
index 0000000..6eaba10
--- /dev/null
+++ b/src/ru/olamedia/olacraft/physics/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.physics; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/picker/joglBlockPicker.java b/src/ru/olamedia/olacraft/picker/joglBlockPicker.java
new file mode 100644
index 0000000..6eb279c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/picker/joglBlockPicker.java
@@ -0,0 +1,27 @@
+package ru.olamedia.olacraft.picker;
+
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+
+import ru.olamedia.olacraft.world.block.Block;
+import ru.olamedia.olacraft.world.provider.ChunkProvider;
+
+public class joglBlockPicker {
+ ChunkProvider provider;
+
+ public void setChunkProvider(ChunkProvider provider) {
+ this.provider = provider;
+ }
+
+ public Block pickBlock(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ FloatBuffer projMatrix = FloatBuffer.allocate(16);
+ FloatBuffer modelMatrix = FloatBuffer.allocate(16);
+ gl.glGetFloatv(GL2.GL_PROJECTION, projMatrix);
+ gl.glGetFloatv(GL2.GL_MODELVIEW, modelMatrix);
+
+ return null;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/picker/package-info.java b/src/ru/olamedia/olacraft/picker/package-info.java
new file mode 100644
index 0000000..b254232
--- /dev/null
+++ b/src/ru/olamedia/olacraft/picker/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.picker; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/render/jogl/BlockRenderer.java b/src/ru/olamedia/olacraft/render/jogl/BlockRenderer.java
new file mode 100644
index 0000000..6d96403
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/BlockRenderer.java
@@ -0,0 +1,87 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+
+import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureCoords;
+
+import ru.olamedia.geom.SimpleQuadMesh;
+import ru.olamedia.olacraft.world.chunk.BlockSlice;
+import ru.olamedia.texture.TextureManager;
+
+public class BlockRenderer {
+ private BlockSlice slice;
+ private SimpleQuadMesh mesh;
+
+ public BlockRenderer(BlockSlice slice) {
+ this.slice = slice;
+ }
+
+ public SimpleQuadMesh getMesh(GL glx) {
+ GL2 gl = glx.getGL2();
+ // 14739
+ SimpleQuadMesh mesh = new SimpleQuadMesh(999999);
+ mesh.useColor();
+ mesh.useTexture();
+
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_NEAREST_MIPMAP_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
+ GL.GL_NEAREST_MIPMAP_NEAREST);
+ gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_FASTEST);
+ gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_NICEST);
+ Texture grass = TextureManager.get("texture/grass.png");
+ int tex = grass.getTextureObject(gl);
+
+ TextureCoords tc = grass.getImageTexCoords();
+ // mesh.setTextureSize(tc.right(), tc.top());
+ System.out.println(grass.getWidth() + " " + grass.getHeight() + " | "
+ + tc.left() + " " + tc.right() + " " + tc.top() + " "
+ + tc.bottom());
+ mesh.setTextureSize(grass.getWidth(), grass.getHeight());
+ for (int x = 0; x < slice.getWidth(); x++) {
+ for (int y = 0; y < slice.getHeight(); y++) {
+ for (int z = 0; z < slice.getDepth(); z++) {
+ mesh.setTranslation(x, y, z);
+ // mesh.setColor4f(0, 1, 0, 1);
+ mesh.setColor4f((float) Math.random(),
+ (float) Math.random(), (float) Math.random(), 1);
+ mesh.setGLTexture(tex);
+ if (y == 0) {
+ mesh.addBottomQuad();
+ }
+ if (y == 3) {
+ // Math.random();
+ mesh.addTopQuad();
+ }
+ if (y < 4) {
+ if (x == 0) {
+ mesh.addLeftQuad();
+ }
+ if (x == slice.getWidth() - 1) {
+ mesh.addRightQuad();
+ }
+ if (z == 0) {
+ mesh.addBackQuad();
+ }
+ if (z == slice.getDepth() - 1) {
+ mesh.addFrontQuad();
+ }
+ }
+ }
+ }
+ }
+ mesh.endMesh();
+ return mesh;
+ }
+
+ public void render(GL glx) {
+ if (null == mesh) {
+ mesh = getMesh(glx);
+ }
+ mesh.joglRender(glx);
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/BlockStackRenderer.java b/src/ru/olamedia/olacraft/render/jogl/BlockStackRenderer.java
new file mode 100644
index 0000000..28f07fd
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/BlockStackRenderer.java
@@ -0,0 +1,9 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import javax.media.opengl.GLAutoDrawable;
+
+public class BlockStackRenderer {
+ public void render(GLAutoDrawable drawable) {
+
+ }
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java b/src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java
new file mode 100644
index 0000000..e24e8e9
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/ChunkRenderer.java
@@ -0,0 +1,146 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLContext;
+
+import ru.olamedia.math.Box;
+import ru.olamedia.math.Classifier;
+import ru.olamedia.olacraft.game.Game;
+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;
+
+public class ChunkRenderer {
+ private BlockSlice slice;
+
+ public ChunkRenderer(BlockSlice slice) {
+ this.slice = slice;
+ }
+
+ 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 boolean renderChunk(Chunk chunk, boolean skipnew) {
+ GL gl = GLContext.getCurrentGL();
+ if (!chunk.isAvailable()) {
+ // System.out.println("not available");
+ chunk.request();
+ return skipnew;
+ }
+ /*
+ * if (!chunk.isNeighborsAvailable()) {
+ * System.out.println("no neighbors");
+ * chunk.requestNeighbors();
+ * return;
+ * }
+ */
+ // System.out.println("available");
+ Box box = new Box(chunk.getX(), chunk.getY(), chunk.getZ(), chunk.getX() + chunk.getWidth(), chunk.getY()
+ + chunk.getHeight(), chunk.getZ() + chunk.getDepth());
+ if (Game.instance.camera.frustum.quickClassify(box) == Classifier.OUTSIDE) {
+ frustumCulledChunks++;
+ return skipnew;
+ }
+
+ // // boolean inside = true;
+ // if (Game.camera.frustum != null) {
+ // if (Game.camera.frustum.quickClassify(box) ==
+ // Classifier.Classification.OUTSIDE) {
+ // frustumCulledChunks++;
+ // return;
+ // }
+ // }
+ // } else if (Game.camera.frustum.test(box) == Classifier.INTERSECT) {
+ // inside = false;
+ // frustumIntersectChunks++;
+ // } else {
+ // frustumCulledChunks++;
+ // return;
+ // }
+ if (!chunk.isMeshCostructed) {
+ if (skipnew) {
+ return skipnew;
+ }
+ }
+ if (!chunk.isMeshCostructed) {
+ ChunkMeshBulder.instance.add(chunk);
+ if (ChunkMeshBulder.instance.isFull()) {
+ skipnew = true;
+ }
+ return skipnew;
+ }
+ if (null == chunk.getMesh()) {
+ } else {
+ chunk.getMesh().joglRender(gl);
+ }
+ return skipnew;
+ }
+
+ public void render(GLAutoDrawable drawable) {
+
+ if (!ChunkMeshBulder.instance.isAlive()) {
+ ChunkMeshBulder.instance.start();
+ }
+
+ visibleTop = 0;
+ visibleBottom = 0;
+ visibleLeft = 0;
+ visibleRight = 0;
+ visibleFront = 0;
+ visibleBack = 0;
+ frustumCulledChunks = 0;
+ boolean skipnew = false;
+ ChunkSlice cs = slice.getChunkSlice();
+ // rendering from center
+ int x, y, z;
+ int dw = cs.getWidth() / 2;
+ int dd = cs.getDepth() / 2;
+ int dh = cs.getHeight() / 2;
+ for (int dx = 0; dx < dw; dx++) {
+ x = cs.getX() + dw + dx;
+ for (int dz = 0; dz < dd; dz++) {
+ z = cs.getZ() + dd + dz;
+ for (int dy = 0; dy < dh; dy++) {
+ y = cs.getY() + dh + dy;
+ skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
+ y = cs.getY() + dh - dy - 1;
+ skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
+ }
+ z = cs.getZ() + dd - dz - 1;
+ for (int dy = 0; dy < dh; dy++) {
+ y = cs.getY() + dh + dy;
+ skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
+ y = cs.getY() + dh - dy - 1;
+ skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
+ }
+ }
+ x = cs.getX() + dw - dx - 1;
+ for (int dz = 0; dz < dd; dz++) {
+ z = cs.getZ() + dd + dz;
+ for (int dy = 0; dy < dh; dy++) {
+ y = cs.getY() + dh + dy;
+ skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
+ y = cs.getY() + dh - dy - 1;
+ skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
+ }
+ z = cs.getZ() + dd - dz - 1;
+ for (int dy = 0; dy < dh; dy++) {
+ y = cs.getY() + dh + dy;
+ skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
+ y = cs.getY() + dh - dy - 1;
+ skipnew = renderChunk(cs.getChunk(x, y, z), skipnew);
+ }
+ }
+ }
+ // System.out.println("visible top " + visibleTop);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java b/src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java
new file mode 100644
index 0000000..12c12e0
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/DefaultRenderer.java
@@ -0,0 +1,75 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import com.jogamp.newt.event.KeyEvent;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.glu.GLU;
+
+import ru.olamedia.input.KeyListener;
+import ru.olamedia.input.Keyboard;
+import ru.olamedia.input.MouseJail;
+import ru.olamedia.input.MouseListener;
+import ru.olamedia.olacraft.game.Game;
+
+public class DefaultRenderer implements IRenderer, KeyListener, MouseListener {
+ private boolean isHUDEnabled = true;
+ GLU glu = new GLU();
+ // private static Color BLACK_TRANSPARENT = new Color(0, 0, 0, 0);
+ long lastHUD = System.nanoTime();
+
+ public DefaultRenderer() {
+ Keyboard.attach(this);
+ MouseJail.attach(this);
+ }
+
+ @Override
+ public void render(GLAutoDrawable drawable) {
+ Game.client.getScene().tick();
+ Game.client.getScene().render(drawable);
+ }
+
+ @Override
+ public void onKeyPressed(String name, KeyEvent e) {
+
+ }
+
+ @Override
+ public void onKeyReleased(String name, KeyEvent e) {
+ // System.out.println(name);
+ if (name == "toggleHUD") {
+ isHUDEnabled = !isHUDEnabled;
+ }
+ if (name == "captureMouse") {
+ MouseJail.setActive(true);
+ }
+ if (name == "releaseMouse") {
+ MouseJail.setActive(false);
+ }
+ 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
+ public void onMouseMove(float dx, float dy) {
+ Game.instance.camera.mouseMoved(dx, dy);
+ }
+
+ @Override
+ public void onMouseClick() {
+ Game.instance.player.onMouseClick();
+ }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+
+ }
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/IRenderer.java b/src/ru/olamedia/olacraft/render/jogl/IRenderer.java
new file mode 100644
index 0000000..1ba581a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/IRenderer.java
@@ -0,0 +1,8 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import javax.media.opengl.GLAutoDrawable;
+
+public interface IRenderer {
+ public void render(GLAutoDrawable drawable);
+ public void init(GLAutoDrawable drawable);
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java b/src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java
new file mode 100644
index 0000000..46daa4a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/InventoryRenderer.java
@@ -0,0 +1,87 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+
+import com.jogamp.opengl.util.texture.Texture;
+
+import ru.olamedia.olacraft.inventory.Inventory;
+import ru.olamedia.olacraft.world.blockStack.BlockStack;
+import ru.olamedia.olacraft.world.blockTypes.EmptyBlockType;
+import ru.olamedia.texture.TextureManager;
+
+public class InventoryRenderer {
+ private Inventory inventory;
+ private BlockStackRenderer stackRenderer;
+
+ int stackSize = 32;
+ int spacing = 2;
+ int padding = 2;
+ int x;
+ int y;
+
+ public InventoryRenderer(Inventory inventory) {
+ this.inventory = inventory;
+ stackRenderer = new BlockStackRenderer();
+ }
+
+ public void render(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ int vWidth = drawable.getWidth();
+ int vHeight = drawable.getHeight();
+ // Draw GUI
+
+ int width = stackSize * Inventory.BIND_NUM + spacing * (Inventory.BIND_NUM - 1) + padding * 2;
+ int height = stackSize + padding * 2;
+ x = (vWidth - width) / 2;
+ y = (vHeight - height) - 10;
+ gl.glRecti(x, y, x + width, y + height);
+ // Draw stacks
+ gl.glEnable(GL2.GL_TEXTURE_2D);
+ for (int i = 0; i < Inventory.BIND_NUM; i++) {
+ renderStack(i, drawable);
+ }
+ gl.glPopAttrib();
+ }
+
+ public void renderStack(int i, GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ 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 != tex) {
+ 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 x1 = sx;
+ int x2 = sx + stackSize;
+ int y1 = sy;
+ int y2 = sy + stackSize;
+ gl.glBegin(GL2.GL_QUADS);
+ {
+ gl.glTexCoord2f(0, 0);
+ gl.glVertex2f(x1, y1);
+ gl.glTexCoord2f(0, 1);
+ gl.glVertex2f(x1, y2);
+ gl.glTexCoord2f(1, 1);
+ gl.glVertex2f(x2, y2);
+ gl.glTexCoord2f(1, 0);
+ gl.glVertex2f(x2, y1);
+ }
+ gl.glEnd();
+ // gl.glRecti(sx, sy, sx + stackSize, sy + stackSize);
+ }
+ } else {
+ gl.glDisable(GL2.GL_TEXTURE_2D);
+ float gray = 0.5f;
+ gl.glColor3f(gray, gray, gray);
+ gl.glRecti(sx, sy, sx + stackSize, sy + stackSize);
+ gl.glEnable(GL2.GL_TEXTURE_2D);
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/PlaneRenderer.java b/src/ru/olamedia/olacraft/render/jogl/PlaneRenderer.java
new file mode 100644
index 0000000..754a093
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/PlaneRenderer.java
@@ -0,0 +1,102 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+
+import ru.olamedia.math.Plane;
+
+public class PlaneRenderer {
+ private static float getZ(Plane p, float x, float y) {
+ return -(p.n.x * x + p.n.y * y + p.d) / p.n.z;
+ }
+
+ private static float getY(Plane p, float x, float z) {
+ return -(p.n.x * x + p.n.z * z + p.d) / p.n.y;
+ }
+
+ private static float getX(Plane p, float y, float z) {
+ return -(p.n.y * y + p.n.z * z + p.d) / p.n.x;
+ }
+
+ public static void render(Plane p, GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ float size = 100;
+ float step = size / 5;
+ for (float x = -size; x <= size; x += step) {
+ for (float y = -size; y <= size; y += step) {
+ // nx * x + ny * y + nz * z + d = 0
+ // (z = nx * x + ny * y + d) / nz
+ float z = getZ(p, x, y);
+ float x2 = x + step;
+ float y2 = y;
+ float z2 = getZ(p, x2, y2);
+ float x3 = x + step;
+ float y3 = y + step;
+ float z3 = getZ(p, x3, y3);
+ float x4 = x;
+ float y4 = y + step;
+ float z4 = getZ(p, x4, y4);
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
+ gl.glBegin(GL2.GL_QUADS);
+ {
+ gl.glVertex3f(x, y, z);
+ gl.glVertex3f(x2, y2, z2);
+ gl.glVertex3f(x3, y3, z3);
+ gl.glVertex3f(x4, y4, z4);
+ }
+ gl.glEnd();
+ }
+ }
+ for (float x = -size; x <= size; x += step) {
+ for (float z = -size; z <= size; z += step) {
+ // nx * x + ny * y + nz * z + d = 0
+ // (z = nx * x + ny * y + d) / nz
+ float y = getY(p, x, z);
+ float x2 = x + step;
+ float z2 = z;
+ float y2 = getY(p, x2, z2);
+ float x3 = x + step;
+ float z3 = z + step;
+ float y3 = getY(p, x3, z3);
+ float x4 = x;
+ float z4 = z + step;
+ float y4 = getY(p, x4, z4);
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
+ gl.glBegin(GL2.GL_QUADS);
+ {
+ gl.glVertex3f(x, y, z);
+ gl.glVertex3f(x2, y2, z2);
+ gl.glVertex3f(x3, y3, z3);
+ gl.glVertex3f(x4, y4, z4);
+ }
+ gl.glEnd();
+ }
+ }
+
+ for (float y = -size; y <= size; y += step) {
+ for (float z = -size; z <= size; z += step) {
+ // nx * x + ny * y + nz * z + d = 0
+ // (z = nx * x + ny * y + d) / nz
+ float x = getX(p, y, z);
+ float y2 = y + step;
+ float z2 = z;
+ float x2 = getX(p, y2, z2);
+ float y3 = y + step;
+ float z3 = z + step;
+ float x3 = getX(p, y3, z3);
+ float y4 = y;
+ float z4 = z + step;
+ float x4 = getX(p, y4, z4);
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
+ gl.glBegin(GL2.GL_QUADS);
+ {
+ gl.glVertex3f(x, y, z);
+ gl.glVertex3f(x2, y2, z2);
+ gl.glVertex3f(x3, y3, z3);
+ gl.glVertex3f(x4, y4, z4);
+ }
+ gl.glEnd();
+ }
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/VectorRenderer.java b/src/ru/olamedia/olacraft/render/jogl/VectorRenderer.java
new file mode 100644
index 0000000..180ec2a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/VectorRenderer.java
@@ -0,0 +1,20 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+
+import ru.olamedia.math.Vector3f;
+
+public class VectorRenderer {
+ public static void render(Vector3f point, Vector3f v, GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ gl.glDisable(GL2.GL_TEXTURE_2D);
+ gl.glColor3f(1, 0, 0);
+ gl.glBegin(GL2.GL_LINES);
+ {
+ gl.glVertex3f(point.x, point.y, point.z);
+ gl.glVertex3f(point.x + v.x, point.y + v.y, point.z + v.z);
+ }
+ gl.glEnd();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/joglViewport.java b/src/ru/olamedia/olacraft/render/jogl/joglViewport.java
new file mode 100644
index 0000000..b3da2ce
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/joglViewport.java
@@ -0,0 +1,24 @@
+package ru.olamedia.olacraft.render.jogl;
+
+import java.awt.Font;
+
+import javax.media.opengl.GLAutoDrawable;
+
+import com.jogamp.opengl.util.awt.TextRenderer;
+
+public class joglViewport {
+ private GLAutoDrawable drawable;
+ private TextRenderer sans11;
+
+ public joglViewport(GLAutoDrawable drawable) {
+ this.drawable = drawable;
+ sans11 = new TextRenderer(new Font("SansSerif", Font.PLAIN, 11));
+ }
+
+ public void drawText(String text, int x, int y) {
+ sans11.setColor(1, 1, 1, 0.7f);
+ sans11.beginRendering(drawable.getWidth(), drawable.getHeight());
+ sans11.draw(text, x, y);
+ sans11.endRendering();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/render/jogl/package-info.java b/src/ru/olamedia/olacraft/render/jogl/package-info.java
new file mode 100644
index 0000000..73b0ace
--- /dev/null
+++ b/src/ru/olamedia/olacraft/render/jogl/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.render.jogl; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/scene/GameScene.java b/src/ru/olamedia/olacraft/scene/GameScene.java
new file mode 100644
index 0000000..618e270
--- /dev/null
+++ b/src/ru/olamedia/olacraft/scene/GameScene.java
@@ -0,0 +1,252 @@
+package ru.olamedia.olacraft.scene;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryUsage;
+import java.util.HashMap;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.GLUquadric;
+
+import org.ode4j.ode.DBody;
+
+import com.jogamp.opengl.util.PMVMatrix;
+
+import ru.olamedia.Options;
+import ru.olamedia.liveEntity.LiveEntity;
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.physics.GamePhysicsWorld;
+import ru.olamedia.olacraft.render.jogl.ChunkRenderer;
+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.blockTypes.AbstractBlockType;
+import ru.olamedia.olacraft.world.blockTypes.GrassBlockType;
+import ru.olamedia.olacraft.world.chunk.BlockSlice;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+import ru.olamedia.player.Player;
+import ru.olamedia.vbo.VBO;
+
+public class GameScene {
+
+ private PMVMatrix matrix;
+
+ private HashMap<Integer, LiveEntity> liveEntities = new HashMap<Integer, LiveEntity>();
+ WorldProvider provider;
+ private int renderDistance = Options.renderDistance;
+ private joglViewport viewport;
+ private BulletScene bullets = new BulletScene();
+ private GamePhysicsWorld physics = new GamePhysicsWorld();
+
+ private VBO testObject;
+
+ private boolean isInitialized = false;
+ BlockSlice viewSlice;
+
+ public GameScene(WorldProvider provider) {
+ this.provider = provider;
+ setRenderDistance(renderDistance);
+ }
+
+ public void addBullet(Bullet b) {
+ bullets.add(b);
+ DBody body = physics.createBody();
+ body.setPosition(b.location.x, b.location.y, b.location.z);
+ body.setLinearVel(b.velocity.x, b.velocity.y, b.velocity.z);
+ /*
+ * DMass mass = OdeHelper.createMass();
+ * mass.setMass(10);
+ * mass.setI(OdeHelper.c);
+ * body.setMass(mass);
+ */
+ b.body = body;
+ }
+
+ public int getBulletsCount() {
+ return bullets.getCount();
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ if (isInitialized) {
+ return;
+ }
+ isInitialized = true;
+ registerTextures();
+ viewport = new joglViewport(drawable);
+ testObject = new VBO(drawable);
+ }
+
+ private void registerTextures() {
+ AbstractBlockType t;
+ t = new GrassBlockType();
+ t.register();
+ }
+
+ /**
+ * @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 * 2, renderDistance);
+ blockRenderer = new ChunkRenderer(viewSlice);
+ }
+
+ ChunkRenderer blockRenderer = new ChunkRenderer(viewSlice);
+ GLU glu = new GLU();
+
+ public void registerLiveEntity(LiveEntity entity) {
+ // liveEntityIncrement++;
+ // entity.setId(liveEntityIncrement);
+ liveEntities.put(entity.getConnectionId(), entity);
+ }
+
+ private InventoryRenderer inventoryRenderer;
+
+ private Player player;
+
+ public void registerPlayer(LiveEntity player) {
+ inventoryRenderer = new InventoryRenderer(player.getInventory());
+ this.player = (Player) player;
+ }
+
+ public LiveEntity getLiveEntity(int connectionId) {
+ if (liveEntities.containsKey(connectionId)) {
+ return liveEntities.get(connectionId);
+ }
+ return null;
+ }
+
+ public HashMap<Integer, LiveEntity> getLiveEntities() {
+ return liveEntities;
+ }
+
+ public void 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());
+ }
+
+ public void render(GLAutoDrawable drawable) {
+ if (!Game.instance.isRunning()) {
+ // not running, just clear screen
+ GL2 gl = drawable.getGL().getGL2();
+ gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
+ gl.glClearColor(49f / 255f, 49f / 255f, 49f / 255f, 1);
+ return;
+ }
+ init(drawable);
+ GL2 gl = drawable.getGL().getGL2();
+ gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
+ gl.glClearColor(49f / 255f, 119f / 255f, 243f / 255f, 1);
+ // GOING 3D
+ gl.glPushMatrix();
+ Game.instance.camera.setUp(drawable);
+ viewSlice.setCenter((int) Game.instance.camera.getX(), (int) Game.instance.camera.getY(),
+ (int) Game.instance.camera.getZ());
+ // RENDER BLOCKS
+ gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ gl.glColor4f(0f, 1f, 0, 1);
+ gl.glEnable(GL2.GL_DEPTH_TEST);
+ 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_DENSITY, 0.002f);
+ // new float[] { 49f / 255f, 119f / 255f, 243f / 255f }
+ // gl.glFogfv(GL2.GL_FOG_COLOR, new float[] { 1, 1, 1, 0.2f }, 0);
+ blockRenderer.render(drawable);
+ 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());
+ glu.gluSphere(qobj0, 0.5f, 10, 10);
+ gl.glPopMatrix();
+ }
+ gl.glPopAttrib();
+ // bullets.render(drawable);
+ gl.glPopMatrix();
+
+ testObject.render();
+
+ // 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);
+ }
+
+ viewport.drawText("avg fps: " + (int) Game.timer.getAvgFps(), 10, height - 20);
+ viewport.drawText("fps: " + (int) Game.timer.getFps(), 10, height - 35);
+ MemoryUsage heap = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
+ viewport.drawText("mem: " + (heap.getUsed() / (1024 * 1024)) + "/" + (heap.getMax() / (1024 * 1024)), 10,
+ height - 50);
+
+ viewport.drawText("y: " + Game.instance.player.getY(), width - msz - 10, height - msz - 25);
+ 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 - 55);
+ viewport.drawText("players: " + liveEntities.size(), width - msz - 10, height - msz - 70);
+ viewport.drawText("bullets: " + getBulletsCount(), width - msz - 10, height - msz - 95);
+ viewport.drawText("inAir: " + Game.instance.player.inAir(), width - msz - 10, height - msz - 110);
+ viewport.drawText("rdistance: " + renderDistance, width - msz - 10, height - msz - 155);
+
+ viewport.drawText("cam x: " + Game.instance.camera.getX(), width - msz - 10, height - msz - 170);
+ gl.glPopAttrib();
+ gl.glPopMatrix();
+ gl.glFlush();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/scene/package-info.java b/src/ru/olamedia/olacraft/scene/package-info.java
new file mode 100644
index 0000000..660e324
--- /dev/null
+++ b/src/ru/olamedia/olacraft/scene/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.scene; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/weapon/Bullet.java b/src/ru/olamedia/olacraft/weapon/Bullet.java
new file mode 100644
index 0000000..6292bf2
--- /dev/null
+++ b/src/ru/olamedia/olacraft/weapon/Bullet.java
@@ -0,0 +1,51 @@
+package ru.olamedia.olacraft.weapon;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.GLUquadric;
+import javax.vecmath.Point3f;
+import javax.vecmath.Vector3f;
+
+import org.ode4j.ode.DBody;
+
+public class Bullet {
+ public Point3f location = new Point3f();
+ public Vector3f velocity = new Vector3f();
+ public Vector3f acceleration = new Vector3f(0, -0.98f, 0);
+ public DBody body;
+ public float width = 0.05f;
+ public float height = 0.05f;
+ public float depth = 0.25f;
+ public boolean toRemove = false;
+ private static GLU glu = new GLU();
+
+ public void update(float deltams) {
+ // acceleration.set(velocity);
+ // acceleration.negate();
+ // acceleration.scale(0.1f);
+ // acceleration.y += -0.98f;
+ // velocity.x += acceleration.x * deltams;
+ // velocity.y += acceleration.y * deltams;
+ // velocity.z += acceleration.z * deltams;
+ // float step = deltams;
+ // location.x += velocity.x * deltams;
+ // location.y += velocity.y * deltams;
+ // location.z += velocity.z * deltams;
+ if (body.getPosition().get1() < 0 || body.getPosition().get1() > 100) {
+ // FIXME
+ toRemove = true;
+ }
+ }
+
+ public void render(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+ gl.glPushMatrix();
+ gl.glTranslated(body.getPosition().get0(), body.getPosition().get1(), body.getPosition().get2());
+ GLUquadric bulletGeom = glu.gluNewQuadric();
+ glu.gluQuadricDrawStyle(bulletGeom, GLU.GLU_FILL);
+ glu.gluQuadricNormals(bulletGeom, GLU.GLU_SMOOTH);
+ glu.gluDisk(bulletGeom, 0.3, 0.4, 5, 5);
+ gl.glPopMatrix();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/weapon/BulletScene.java b/src/ru/olamedia/olacraft/weapon/BulletScene.java
new file mode 100644
index 0000000..1e5ea05
--- /dev/null
+++ b/src/ru/olamedia/olacraft/weapon/BulletScene.java
@@ -0,0 +1,35 @@
+package ru.olamedia.olacraft.weapon;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.opengl.GLAutoDrawable;
+
+public class BulletScene {
+ private List<Bullet> bullets = new ArrayList<Bullet>();
+
+ public void add(Bullet b) {
+ bullets.add(b);
+ }
+
+ public int getCount(){
+ return bullets.size();
+ }
+
+ public void update(float deltas) {
+ for (int i = 0; i < bullets.size(); i++) {
+ Bullet b = bullets.get(i);
+ b.update(deltas);
+ if (b.toRemove) {
+ bullets.remove(b);
+ i--;
+ }
+ }
+ }
+
+ public void render(GLAutoDrawable drawable) {
+ for (Bullet b : bullets) {
+ b.render(drawable);
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/weapon/package-info.java b/src/ru/olamedia/olacraft/weapon/package-info.java
new file mode 100644
index 0000000..89ca87c
--- /dev/null
+++ b/src/ru/olamedia/olacraft/weapon/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.weapon; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/World.java b/src/ru/olamedia/olacraft/world/World.java
new file mode 100644
index 0000000..e3d25f2
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/World.java
@@ -0,0 +1,12 @@
+package ru.olamedia.olacraft.world;
+
+import ru.olamedia.olacraft.world.block.BlockRegistry;
+import ru.olamedia.olacraft.world.blockTypes.GrassBlockType;
+
+public class World {
+ private BlockRegistry blockRegistry;
+ public void setup() {
+ blockRegistry = new BlockRegistry();
+ blockRegistry.registerBlockType(GrassBlockType.class);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/WorldInfo.java b/src/ru/olamedia/olacraft/world/WorldInfo.java
new file mode 100644
index 0000000..797339f
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/WorldInfo.java
@@ -0,0 +1,11 @@
+package ru.olamedia.olacraft.world;
+
+import java.io.Serializable;
+
+public class WorldInfo implements Serializable {
+ private static final long serialVersionUID = -3669317489158639456L;
+ public String name = "world";
+ public int minHeight = -128;
+ public int maxHeight = 127;
+ public float gravity = 9.81f;
+}
diff --git a/src/ru/olamedia/olacraft/world/block/Block.java b/src/ru/olamedia/olacraft/world/block/Block.java
new file mode 100644
index 0000000..a48c9df
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/block/Block.java
@@ -0,0 +1,111 @@
+package ru.olamedia.olacraft.world.block;
+
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+import ru.olamedia.olacraft.world.blockTypes.EmptyBlockType;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class Block {
+ private WorldProvider provider;
+ private int x;
+ private int y;
+ private int z;
+
+ /**
+ * Inventory block
+ */
+ public Block() {
+ this.provider = null;
+ this.x = 0;
+ this.y = 0;
+ this.z = 0;
+ }
+
+ public void putIntoWorld(WorldProvider worldProvider, int x, int y, int z) {
+ this.provider = worldProvider;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public Block(WorldProvider worldProvider, int x, int y, int z) {
+ putIntoWorld(worldProvider, x, y, z);
+ }
+
+ /**
+ * @return the x
+ */
+ public int getX() {
+ return x;
+ }
+
+ /**
+ * @param x
+ * the x to set
+ */
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ /**
+ * @return the y
+ */
+ public int getY() {
+ return y;
+ }
+
+ /**
+ * @param y
+ * the y to set
+ */
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ /**
+ * @return the z
+ */
+ public int getZ() {
+ return z;
+ }
+
+ /**
+ * @param z
+ * the z to set
+ */
+ public void setZ(int z) {
+ this.z = z;
+ }
+
+ public boolean isEmpty() {
+ return provider.isEmptyBlock(x, y, z);
+ }
+
+ public Block getNeighbor(int dx, int dy, int dz) {
+ return new Block(provider, x + dx, y + dy, z + dz);
+ }
+
+ public Block[] getNeighbors() {
+ return new Block[] {
+ //
+ getNeighbor(1, 0, 0),//
+ getNeighbor(0, 1, 0),//
+ getNeighbor(0, 0, 1),//
+ getNeighbor(-1, 0, 0),//
+ getNeighbor(0, -1, 0),//
+ getNeighbor(0, 0, -1),//
+ };
+ }
+
+ private BlockType type;
+
+ public void setType(BlockType type) {
+ this.type = type;
+ }
+
+ public BlockType getType() {
+ if (null == type) {
+ type = new EmptyBlockType();
+ }
+ return type;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/block/BlockRegistry.java b/src/ru/olamedia/olacraft/world/block/BlockRegistry.java
new file mode 100644
index 0000000..19ccc94
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/block/BlockRegistry.java
@@ -0,0 +1,46 @@
+package ru.olamedia.olacraft.world.block;
+
+import java.util.HashMap;
+
+import ru.olamedia.olacraft.world.blockTypes.BlockType;
+
+public class BlockRegistry {
+
+ private HashMap<Integer, String> names = new HashMap<Integer, String>();
+ private HashMap<Integer, BlockType> types = new HashMap<Integer, BlockType>();
+ private int autoincrement = 0;
+
+ private BlockRegistry worldRegistry;
+
+ public BlockRegistry() {
+ }
+
+ public BlockType getBlockType(int id) {
+ return types.get(id);
+ }
+
+ public String getBlockHumanId(int id) {
+ return names.get(id);
+ }
+
+ public int registerBlockType(@SuppressWarnings("rawtypes") Class type) {
+ if (type.isInstance(BlockType.class)) {
+ autoincrement++;
+ int id = autoincrement;
+ String classId = type.getName();
+ names.put(id, classId);
+ // types.put(id, type);
+ return autoincrement;
+ }
+ return 0;
+ }
+
+ public BlockRegistry getWorldRegistry() {
+ return worldRegistry;
+ }
+
+ public void setWorldRegistry(BlockRegistry worldRegistry) {
+ this.worldRegistry = worldRegistry;
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/block/package-info.java b/src/ru/olamedia/olacraft/world/block/package-info.java
new file mode 100644
index 0000000..0924926
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/block/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.block; \ 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
new file mode 100644
index 0000000..57258ef
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockStack/BlockStack.java
@@ -0,0 +1,63 @@
+package ru.olamedia.olacraft.world.blockStack;
+
+import ru.olamedia.olacraft.world.block.Block;
+
+public class BlockStack {
+ public Block block;
+ public int count;
+
+ public BlockStack(Block block, int count) {
+ this.block = block;
+ this.count = count;
+ }
+
+ public BlockStack get() {
+ return get(1);
+ }
+
+ public BlockStack get(int getcount) {
+ int c = 0;
+ if (count >= getcount) {
+ c = getcount;
+ count -= getcount;
+ } else {
+ c = count;
+ count = 0;
+ }
+ return new BlockStack(block, c);
+ }
+
+ public BlockStack getAll() {
+ int c = count;
+ count = 0;
+ return new BlockStack(block, 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;
+ }
+ } else {
+ // Replace
+ BlockStack remains = new BlockStack(block, count);
+ block = stack.block;
+ count = stack.count;
+ return remains;
+ }
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/blockStack/package-info.java b/src/ru/olamedia/olacraft/world/blockStack/package-info.java
new file mode 100644
index 0000000..933dc87
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockStack/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.blockStack; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java
new file mode 100644
index 0000000..6e2a86f
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/AbstractBlockType.java
@@ -0,0 +1,86 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+import com.jogamp.opengl.util.texture.Texture;
+
+import ru.olamedia.texture.TextureManager;
+
+public abstract class AbstractBlockType implements BlockType {
+
+ @Override
+ abstract public String getName();
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ abstract public String getStackTextureFile();
+
+ @Override
+ abstract public String getTopTextureFile();
+
+ @Override
+ public String getBottomTextureFile() {
+ return this.getTopTextureFile();
+ }
+
+ @Override
+ public String getLeftTextureFile() {
+ return this.getFrontTextureFile();
+ }
+
+ @Override
+ public String getRightTextureFile() {
+ return this.getFrontTextureFile();
+ }
+
+ @Override
+ public String getFrontTextureFile() {
+ return this.getTopTextureFile();
+ }
+
+ @Override
+ public String getBackTextureFile() {
+ return this.getFrontTextureFile();
+ }
+
+ @Override
+ public Texture getTopTexture() {
+ return TextureManager.get(this.getTopTextureFile());
+ }
+
+ @Override
+ public Texture getBottomTexture() {
+ return TextureManager.get(this.getBottomTextureFile());
+ }
+
+ @Override
+ public Texture getLeftTexture() {
+ return TextureManager.get(this.getLeftTextureFile());
+ }
+
+ @Override
+ public Texture getRightTexture() {
+ return TextureManager.get(this.getRightTextureFile());
+ }
+
+ @Override
+ public Texture getFrontTexture() {
+ return TextureManager.get(this.getFrontTextureFile());
+ }
+
+ @Override
+ public Texture getBackTexture() {
+ return TextureManager.get(this.getBackTextureFile());
+ }
+
+ public void register(){
+ getBackTexture();
+ getBottomTexture();
+ getFrontTexture();
+ getLeftTexture();
+ getRightTexture();
+ getTopTexture();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/BlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/BlockType.java
new file mode 100644
index 0000000..0bda2eb
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/BlockType.java
@@ -0,0 +1,21 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+import com.jogamp.opengl.util.texture.Texture;
+
+public interface BlockType {
+ public String getName();
+ public int getMaxStack();
+ public String getStackTextureFile();
+ public String getTopTextureFile();
+ public String getBottomTextureFile();
+ public String getLeftTextureFile();
+ public String getRightTextureFile();
+ public String getFrontTextureFile();
+ public String getBackTextureFile();
+ public Texture getTopTexture();
+ public Texture getBottomTexture();
+ public Texture getLeftTexture();
+ public Texture getRightTexture();
+ public Texture getFrontTexture();
+ public Texture getBackTexture();
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java
new file mode 100644
index 0000000..4073356
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/EmptyBlockType.java
@@ -0,0 +1,23 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+public class EmptyBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/empty.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/empty.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java
new file mode 100644
index 0000000..816b283
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/GrassBlockType.java
@@ -0,0 +1,28 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+public class GrassBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Grass";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/terrain-grassdarkgreen.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/terrain-grassdarkgreen.png";
+ }
+
+ @Override
+ public String getFrontTextureFile() {
+ return "texture/terrain-glong-darkgreen-dirt.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java b/src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java
new file mode 100644
index 0000000..354d383
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/GravelBlockType.java
@@ -0,0 +1,23 @@
+package ru.olamedia.olacraft.world.blockTypes;
+
+public class GravelBlockType extends AbstractBlockType {
+ @Override
+ public String getName() {
+ return "Gravel";
+ }
+
+ @Override
+ public int getMaxStack() {
+ return 64;
+ }
+
+ @Override
+ public String getStackTextureFile() {
+ return "texture/gravel.png";
+ }
+
+ @Override
+ public String getTopTextureFile() {
+ return "texture/gravel.png";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/blockTypes/package-info.java b/src/ru/olamedia/olacraft/world/blockTypes/package-info.java
new file mode 100644
index 0000000..a49dda8
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/blockTypes/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.blockTypes; \ 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
new file mode 100644
index 0000000..ca4c92a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/chunk/BlockSlice.java
@@ -0,0 +1,164 @@
+package ru.olamedia.olacraft.world.chunk;
+
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class BlockSlice {
+ protected WorldProvider provider;
+ protected int leftX;
+ protected int bottomY;
+ protected int backZ;
+ protected int width;
+ protected int height;
+ protected int depth;
+
+ protected ChunkSlice chunkSlice;
+
+ // Memory leak:
+ //protected int[][] highest = new int[256][256];
+
+ public void invalidateCache(){
+ //highest = new int[256][256];
+ }
+
+/* public int getHighest(int blockX, int blockZ) {
+ if (highest[blockX - leftX][blockZ - backZ] > 0){
+ return highest[blockX - leftX][blockZ - backZ];
+ }
+ for (int y = 0; y < 128; y++) {
+ if (provider.isEmptyBlock(blockX, y, blockZ)){
+ highest[blockX - leftX][blockZ - backZ] = y;
+ return y;
+ }
+ }
+ return 0;
+ }*/
+
+ /**
+ *
+ * @param provider
+ * @param width
+ * (blocks)
+ * @param height
+ * (blocks)
+ * @param depth
+ * (blocks)
+ */
+ public BlockSlice(WorldProvider provider, int width, int height, int depth) {
+ this.provider = provider;
+ this.width = width;
+ this.height = height;
+ this.depth = depth;
+ }
+
+ public ChunkSlice getChunkSlice() {
+ if (null == chunkSlice) {
+ chunkSlice = new ChunkSlice(provider, width / 16, height / 16, depth / 16);
+ }
+ int x = Chunk.v(leftX);
+ int y = Chunk.v(bottomY);
+ int z = Chunk.v(backZ);
+ chunkSlice.setLocation(x, y, z);
+ return chunkSlice;
+ }
+
+ public int getTotalBlocks() {
+ return getWidth() * getHeight() * getDepth();
+ }
+
+ /**
+ * @return the width (blocks)
+ */
+ public int getWidth() {
+ return width;
+ }
+
+ /**
+ * @param width
+ * (blocks)
+ */
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ /**
+ * @return the height (blocks)
+ */
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * @param height
+ * (blocks)
+ */
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ /**
+ * @return the depth (blocks)
+ */
+ public int getDepth() {
+ return depth;
+ }
+
+ /**
+ * @param depth
+ * (blocks)
+ */
+ public void setDepth(int depth) {
+ this.depth = depth;
+ }
+
+ /**
+ *
+ * @param x
+ * (blocks)
+ * @param y
+ * (blocks)
+ * @param z
+ * (blocks)
+ */
+ public void setLocation(int x, int y, int z) {
+ if (x != leftX || y != bottomY || z != backZ){
+ invalidateCache();
+ }
+ leftX = x;
+ bottomY = y;
+ backZ = z;
+ }
+
+ /**
+ *
+ * @param x
+ * (blocks)
+ * @param y
+ * (blocks)
+ * @param z
+ * (blocks)
+ */
+ public void setCenter(int x, int y, int z) {
+ setLocation(x - width / 2, y - height / 2, z - depth / 2);
+ }
+
+ /**
+ * @return the left x (blocks)
+ */
+ public int getX() {
+ return leftX;
+ }
+
+ /**
+ * @return the bottom y (blocks)
+ */
+ public int getY() {
+ return bottomY;
+ }
+
+ /**
+ * @return the back z (blocks)
+ */
+ public int getZ() {
+ return backZ;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/chunk/Chunk.java b/src/ru/olamedia/olacraft/world/chunk/Chunk.java
new file mode 100644
index 0000000..ca2d4bf
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/chunk/Chunk.java
@@ -0,0 +1,290 @@
+package ru.olamedia.olacraft.world.chunk;
+
+import ru.olamedia.geom.SimpleQuadMesh;
+import ru.olamedia.olacraft.world.blockTypes.GrassBlockType;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class Chunk extends BlockSlice {
+ public boolean isMeshCostructed = false;
+ public SimpleQuadMesh mesh;
+
+ 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 Chunk(WorldProvider provider) {
+ super(provider, 16, 16, 16);
+ }
+
+ /**
+ * Convert block coordinate into chunk coordinate
+ *
+ * @param v
+ * block coordinate along one axis
+ * @return
+ */
+ public static int v(int v) {
+ if (v >= 0) {
+ return v / 16;
+ } else {
+ return (v + 1) / 16 - 1;
+ }
+ }
+
+ /**
+ * Convert block coordinate into block position inside of chunk
+ *
+ * @param v
+ * block coordinate along one axis
+ * @return
+ */
+ public static int in(int v) {
+ int tmp = v - v(v) * 16;
+ return tmp >= 0 ? tmp : 16 + tmp; // block location minus chunk base
+ // location
+ // (lower-left-back corner)
+ // if (v >= 0) {
+ // return v % 16;
+ // } else {
+ // int in = v + 1; // shift up so -1 will be 0
+ // in %= 16; // get remaining -15..0
+ // in += 15; // revert 0..15
+ // return in;
+ // }
+ }
+
+ 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);
+ if (y < 0) {
+ mesh.setColor4f(0, 0, 1, 1);
+ } else if (y > 30) {
+ mesh.setColor4f(1, 1, 1, 1);
+ } else {
+ mesh.setColor4f(1, 1, 0, 1);
+ }
+ }
+
+ /**
+ * @return the mesh
+ */
+ public SimpleQuadMesh getMesh() {
+ if (isMeshCostructed) {
+ return mesh;
+ }
+ if (getY() > provider.getInfo().maxHeight) {
+ isMeshCostructed = true;
+ return null;
+ }
+ if (getY() < provider.getInfo().minHeight) {
+ isMeshCostructed = true;
+ return null;
+ }
+ if (null == mesh) {
+ mesh = new SimpleQuadMesh(14739); // unindexed
+ // 17x17x17
+ // vertices
+ mesh.useColor();
+ mesh.useTexture();
+ // gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_FASTEST);
+ // gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_NICEST);
+ GrassBlockType grass = new GrassBlockType();
+ for (int x = getX(); x < getX() + getWidth(); x++) {
+ for (int y = getY(); y < getY() + getHeight(); y++) {
+ for (int z = getZ(); z < getZ() + getDepth(); z++) {
+ //
+
+ if (!isEmptyBlock(x, y, z)) {
+ 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++;
+ }
+ }
+ }
+ }
+ }
+ mesh.endMesh();
+ isMeshCostructed = true;
+ return null;
+ }
+ return mesh;
+ }
+
+ /**
+ * @param mesh
+ * the mesh to set
+ */
+ public void setMesh(SimpleQuadMesh mesh) {
+ this.mesh = mesh;
+ }
+
+ public boolean isEmpty() {
+ // MUST BE LOADED
+ return provider.getChunk(getBlockLocation().getChunkLocation()).isEmpty();
+ }
+
+ private BlockLocation getBlockLocation() {
+ return new BlockLocation(getX(), getY(), getZ());
+ }
+
+ public boolean isAvailable() {
+ return provider.isChunkAvailable(getBlockLocation().getChunkLocation());
+ }
+
+ public boolean isNeighborsAvailable() {
+ int x = Chunk.v(getX());
+ int y = Chunk.v(getY());
+ int z = Chunk.v(getZ());
+ return provider.isChunkAvailable(new ChunkLocation(x - 1, y, z))
+ && provider.isChunkAvailable(new ChunkLocation(x + 1, y, z))
+ && provider.isChunkAvailable(new ChunkLocation(x, y - 1, z))
+ && provider.isChunkAvailable(new ChunkLocation(x, y + 1, z))
+ && provider.isChunkAvailable(new ChunkLocation(x, y, z - 1))
+ && provider.isChunkAvailable(new ChunkLocation(x, y, z + 1));
+ }
+
+ public void requestNeighbors() {
+ int x = Chunk.v(getX());
+ int y = Chunk.v(getY());
+ int z = Chunk.v(getZ());
+ if (!provider.isChunkAvailable(new ChunkLocation(x - 1, y, z))) {
+ provider.loadChunk(new ChunkLocation(x - 1, y, z));
+ }
+ if (!provider.isChunkAvailable(new ChunkLocation(x + 1, y, z))) {
+ provider.loadChunk(new ChunkLocation(x + 1, y, z));
+ }
+ if (!provider.isChunkAvailable(new ChunkLocation(x, y - 1, z))) {
+ provider.loadChunk(new ChunkLocation(x, y - 1, z));
+ }
+ if (!provider.isChunkAvailable(new ChunkLocation(x, y + 1, z))) {
+ provider.loadChunk(new ChunkLocation(x, y + 1, z));
+ }
+ if (!provider.isChunkAvailable(new ChunkLocation(x, y, z - 1))) {
+ provider.loadChunk(new ChunkLocation(x, y, z - 1));
+ }
+ if (!provider.isChunkAvailable(new ChunkLocation(x, y, z + 1))) {
+ provider.loadChunk(new ChunkLocation(x, y, z + 1));
+ }
+ }
+
+ public void request() {
+ BlockLocation blockLocation = new BlockLocation(getX(), getY(), getZ());
+ // System.out.println("provider.requestChunk(" +
+ // blockLocation.getRegionLocation() + blockLocation.getChunkLocation()
+ // + ")");
+ provider.loadChunk(blockLocation.getChunkLocation());
+ }
+
+ // public BlockType getBlockType(int x, int y, int z) {
+ // return provider.getBlockType(int x, int y, int z);
+ // }
+
+ public boolean isEmptyBlock(int x, int y, int z) {
+ return provider.isEmptyBlock(x, y, z);
+ }
+
+ public float getLightLevel256(int x, int y, int z) {
+ return ((float) getLightLevel(x, y, z)) / 15.0f;// * 255.0f
+ }
+
+ public int getLightLevel(int x, int y, int z) {
+ return 15;
+ }
+
+ public boolean renderBottom(int x, int y, int z) {
+ return provider.renderBottom(x, y, z);
+ }
+
+ public boolean renderTop(int x, int y, int z) {
+ return provider.renderTop(x, y, z);
+ }
+
+ public boolean renderLeft(int x, int y, int z) {
+ return provider.renderLeft(x, y, z);
+ }
+
+ public boolean renderRight(int x, int y, int z) {
+ return provider.renderRight(x, y, z);
+ }
+
+ public boolean renderFront(int x, int y, int z) {
+ return provider.renderFront(x, y, z);
+ }
+
+ public boolean renderBack(int x, int y, int z) {
+ return provider.renderBack(x, y, z);
+ }
+
+ public WorldProvider getProvider() {
+ return provider;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java b/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java
new file mode 100644
index 0000000..d362199
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/chunk/ChunkMeshBulder.java
@@ -0,0 +1,47 @@
+package ru.olamedia.olacraft.world.chunk;
+
+import java.util.concurrent.ArrayBlockingQueue;
+
+public class ChunkMeshBulder extends Thread {
+ public static ChunkMeshBulder instance = new ChunkMeshBulder("Mesh builder");
+ private ArrayBlockingQueue<Chunk> chunks = new ArrayBlockingQueue<Chunk>(16);
+
+ public ChunkMeshBulder(String name) {
+ super(name);
+ }
+
+ 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();
+ chunk.getMesh();
+ }
+ }
+
+ @Override
+ public void run() {
+ // glc.makeCurrent();
+ while (true) {
+ // main loop
+ try {
+ tick();
+ // 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/chunk/ChunkSlice.java b/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java
new file mode 100644
index 0000000..e440740
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/chunk/ChunkSlice.java
@@ -0,0 +1,114 @@
+package ru.olamedia.olacraft.world.chunk;
+
+import java.util.HashMap;
+
+import ru.olamedia.olacraft.world.provider.WorldProvider;
+
+public class ChunkSlice {
+ private WorldProvider provider;
+ private int leftX;
+ private int bottomY;
+ private int backZ;
+ private int width;
+ private int height;
+ private int depth;
+
+ public ChunkSlice(WorldProvider provider, int width, int height, int depth) {
+ this.provider = provider;
+ this.width = width;
+ this.height = height;
+ this.depth = depth;
+ }
+
+ protected HashMap<String, Chunk> chunks = new HashMap<String, Chunk>();
+
+ public Chunk getChunk(int x, int y, int z) {
+ String key = x + ";" + y + ";" + z;
+ if (chunks.containsKey(key)) {
+ return chunks.get(key);
+ } else {
+ Chunk chunk = new Chunk(provider);
+ chunk.setLocation(x * 16, y * 16, z * 16);
+ chunks.put(key, chunk);
+ return chunk;
+ }
+ }
+
+ /**
+ * @return the width
+ */
+ public int getWidth() {
+ return width;
+ }
+
+ /**
+ * @param width
+ * the width to set
+ */
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ /**
+ * @return the height
+ */
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * @param height
+ * the height to set
+ */
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ /**
+ * @return the depth
+ */
+ public int getDepth() {
+ return depth;
+ }
+
+ /**
+ * @param depth
+ * the depth to set
+ */
+ public void setDepth(int depth) {
+ this.depth = depth;
+ }
+
+ public void setLocation(int x, int y, int z) {
+ leftX = x;
+ bottomY = y;
+ backZ = z;
+ }
+
+ public void setCenter(int x, int y, int z) {
+ leftX = x - width / 2;
+ bottomY = y - height / 2;
+ backZ = z - depth / 2;
+ }
+
+ /**
+ * @return the leftX
+ */
+ public int getX() {
+ return leftX;
+ }
+
+ /**
+ * @return the bottomY
+ */
+ public int getY() {
+ return bottomY;
+ }
+
+ /**
+ * @return the backZ
+ */
+ public int getZ() {
+ return backZ;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/chunk/package-info.java b/src/ru/olamedia/olacraft/world/chunk/package-info.java
new file mode 100644
index 0000000..314ea35
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/chunk/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.chunk; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/data/ChunkData.java b/src/ru/olamedia/olacraft/world/data/ChunkData.java
new file mode 100644
index 0000000..a1abc9e
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/ChunkData.java
@@ -0,0 +1,86 @@
+package ru.olamedia.olacraft.world.data;
+
+import java.io.Serializable;
+import java.util.BitSet;
+
+import ru.olamedia.olacraft.world.chunk.Chunk;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+
+public class ChunkData implements Serializable {
+ private static final long serialVersionUID = -5704237444737895501L;
+ public ChunkLocation location;
+ public static transient int SIZE = 4096;
+ // private boolean[] notEmpty = new boolean[SIZE];
+ private BitSet emptyBlocks = new BitSet(4096);
+ public int notEmptyCount = 0;
+
+ // public transient int[] type = new int[SIZE];
+ // /public transient ChunkLightData light;
+
+ public ChunkData() {
+ // light = new ChunkLightData();
+ }
+
+ public void compact() {
+ if (notEmptyCount == 0) {
+ emptyBlocks = null;
+ }
+ }
+
+ public static int normalize(int v) {
+ int n = v;
+ if (n > 15) {
+ n = n % 16;
+ }
+ if (n < 0) {
+ n = 16 + n % 16 - 1;
+ // v = 15 - v;
+ }
+ // System.out.println("normalize(" + v + ") = " + n);
+ return n;
+ }
+
+ public static int getId(int xInsideChunk, int yInsideChunk, int zInsideChunk) {
+ xInsideChunk = normalize(xInsideChunk);
+ yInsideChunk = normalize(yInsideChunk);
+ zInsideChunk = normalize(zInsideChunk);
+ int id = xInsideChunk * 16 * 16 + yInsideChunk * 16 + zInsideChunk;
+ if (id > SIZE) {
+ System.err.println("Exception while getID(" + xInsideChunk + "," + yInsideChunk + "," + zInsideChunk + ")");
+ throw new ArrayIndexOutOfBoundsException(id);
+ }
+ return id;
+ }
+
+ public boolean isEmpty(BlockLocation blockLocation) {
+ if (notEmptyCount == 0) {
+ return true;
+ }
+ int id = getId(Chunk.in(blockLocation.x), Chunk.in(blockLocation.y), Chunk.in(blockLocation.z));
+ return isEmpty(id);
+ // return !notEmpty[id];
+ }
+
+ public boolean isEmpty(int id) {
+ if (notEmptyCount == 0) {
+ return true;
+ }
+ return emptyBlocks.get(id);
+ }
+
+ public void setEmpty(int id, boolean isEmpty) {
+ if (isEmpty(id) != isEmpty) {
+ if (!isEmpty) {
+ notEmptyCount++;
+ } else {
+ notEmptyCount--;
+ }
+ }
+ emptyBlocks.set(id, isEmpty);
+ }
+
+ public boolean isEmpty() {
+ return notEmptyCount == 0;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/data/ChunkLightData.java b/src/ru/olamedia/olacraft/world/data/ChunkLightData.java
new file mode 100644
index 0000000..f574420
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/ChunkLightData.java
@@ -0,0 +1,102 @@
+package ru.olamedia.olacraft.world.data;
+
+import ru.olamedia.olacraft.world.dataProvider.AbstractChunkDataProvider;
+
+/**
+ * The daylight calculated as sum of sunlight + emitted light
+ * The nightlight calculated as sum of emitted light
+ *
+ * The light at some time of a day calculated as part of daylight + part of
+ * nightlight (ex 30% of night + 70% of daylight) - sum of two array's elements
+ */
+public class ChunkLightData {
+ public static int SIZE = 4096;
+ /**
+ * Constant sunlight level
+ */
+ public byte[] sunLevel = new byte[SIZE];
+ /**
+ * Constant sunlight level
+ */
+ public byte[] emittedLevel = new byte[SIZE];
+ /**
+ * Constant light level during middle of a day
+ */
+ public byte[] daytimeLevel = new byte[SIZE];
+ /**
+ * Constant light level during midnight
+ */
+ public byte[] nighttimeLevel = new byte[SIZE];
+ public boolean isCalculated = false;
+ public boolean isSunlevelCalculated = false;
+ public byte[] level = new byte[SIZE];
+
+ public static int normalize(int v) {
+ int n = v;
+ if (n > 15) {
+ n = n % 16;
+ }
+ if (n < 0) {
+ n = 16 + n % 16 - 1;
+ // v = 15 - v;
+ }
+ // System.out.println("normalize(" + v + ") = " + n);
+ return n;
+ }
+
+ public static int getId(int xInsideChunk, int yInsideChunk, int zInsideChunk) {
+ xInsideChunk = normalize(xInsideChunk);
+ yInsideChunk = normalize(yInsideChunk);
+ zInsideChunk = normalize(zInsideChunk);
+ int id = xInsideChunk * 16 * 16 + yInsideChunk * 16 + zInsideChunk;
+ if (id > SIZE) {
+ System.err.println("Exception while getID(" + xInsideChunk + "," + yInsideChunk + "," + zInsideChunk + ")");
+ throw new ArrayIndexOutOfBoundsException(id);
+ }
+ return id;
+ }
+
+ private static byte sunlight = 15;
+
+ public void fillSunlight() {
+ // simplify: straight from top to bottom, utility to fill top layer
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ sunLevel[getId(x, 15, z)] = sunlight;
+ }
+ }
+ }
+
+ public void copySunlightFromAbove(ChunkLightData above) {
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ sunLevel[getId(x, 15, z)] = above.sunLevel[getId(x, 0, z)];
+ }
+ }
+ System.out.print("Copy sunlight");
+ }
+
+ /**
+ * Sunlight falling down until meets nonempty block from data
+ *
+ * @param data
+ */
+ public void falldownSunlight(ChunkData data) {
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ for (int y = 14; y >= 0; y--) {
+ if (!data.isEmpty(getId(x, y, z))) {
+ break;
+ } else {
+ sunLevel[getId(x, y, z)] = sunLevel[getId(x, y + 1, z)];
+ }
+ }
+ }
+ }
+ }
+
+ public void receiveNeighborLight(AbstractChunkDataProvider abstractChunkDataProvider) {
+
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/data/HeightMap.java b/src/ru/olamedia/olacraft/world/data/HeightMap.java
new file mode 100644
index 0000000..b2c0a63
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/HeightMap.java
@@ -0,0 +1,42 @@
+package ru.olamedia.olacraft.world.data;
+
+import java.io.Serializable;
+
+/**
+ * Heightmap
+ * Useful when looking for spawn location, calculating light
+ *
+ * @author olamedia
+ *
+ */
+public class HeightMap implements Serializable {
+ private static final long serialVersionUID = -6777972159522169977L;
+ public byte[][] map; // -128..127
+ public HeightMap(){
+
+ }
+ public HeightMap(int width, int height) {
+ map = new byte[width][height];
+ }
+
+ public void setHeight(int x, int y, int height) {
+ map[x][y] = (byte) height;
+ }
+
+ public int getHeight(int x, int y) {
+ return map[x][y];
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ for (int x = 0; x < map.length; x++){
+ for (int z = 0; z < map[x].length; z++){
+ b.append(map[x][z]);
+ b.append(",");
+ }
+ b.append("\n");
+ }
+ return b.toString();
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/data/RegionData.java b/src/ru/olamedia/olacraft/world/data/RegionData.java
new file mode 100644
index 0000000..fa292d2
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/RegionData.java
@@ -0,0 +1,57 @@
+package ru.olamedia.olacraft.world.data;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+import ru.olamedia.olacraft.world.chunk.Chunk;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.location.RegionLocation;
+import ru.olamedia.olacraft.world.location.SectorLocation;
+
+/**
+ * Region is a 16x16 range of sectors. (256x256x256 blocks)
+ *
+ * @author olamedia
+ *
+ */
+public class RegionData implements Serializable {
+ private static final long serialVersionUID = 7449677895073874520L;
+ public RegionLocation location;
+ public HeightMap heightMap = new HeightMap(256, 256);
+ public SectorData[][] sectorData = new SectorData[16][16];
+
+ public void writeTo(OutputStream stream) throws IOException {
+ ObjectOutputStream out = new ObjectOutputStream(stream);
+ out.writeObject(this);
+ out.close();
+ }
+
+ public static RegionData loadFrom(InputStream stream) throws IOException, ClassNotFoundException {
+ ObjectInputStream in = new ObjectInputStream(stream);
+ RegionData data = (RegionData) in.readObject();
+ in.close();
+ return data;
+ }
+
+ public static RegionData createEmpty(RegionLocation location) {
+ RegionData data = new RegionData();
+ data.location = location;
+ return data;
+ }
+
+ public ChunkData getChunkData(ChunkLocation chunkLocation) {
+ SectorData sector = getSectorData(chunkLocation.getSectorLocation());
+ int y = Chunk.in(chunkLocation.y + 128); // minHeight = -128
+ return sector.chunkData[y];
+ }
+
+ public SectorData getSectorData(SectorLocation sectorLocation) {
+ int x = Chunk.in(sectorLocation.x);
+ int z = Chunk.in(sectorLocation.z);
+ return sectorData[x][z];
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/data/SectorData.java b/src/ru/olamedia/olacraft/world/data/SectorData.java
new file mode 100644
index 0000000..12a97cd
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/SectorData.java
@@ -0,0 +1,33 @@
+package ru.olamedia.olacraft.world.data;
+
+import java.io.Serializable;
+
+import ru.olamedia.olacraft.world.location.SectorLocation;
+
+/**
+ * Sector: set of all chunks by one x,z vertical
+ *
+ * @author olamedia
+ *
+ */
+public class SectorData implements Serializable{
+ private static final long serialVersionUID = 5304471397211814748L;
+ public HeightMap heightMap; // locations of highest nonempty blocks
+ public ChunkData[] chunkData; // 256/16 = 16
+ public SectorLocation location;
+
+ public static int yIndex(int y) {
+ return (y + 128) / 16;
+ // 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(){
+ SectorData data = new SectorData();
+ data.heightMap = new HeightMap(16, 16);
+ data.chunkData = new ChunkData[16];
+ return data;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/data/UnavailableDataException.java b/src/ru/olamedia/olacraft/world/data/UnavailableDataException.java
new file mode 100644
index 0000000..a75a42e
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/UnavailableDataException.java
@@ -0,0 +1,23 @@
+package ru.olamedia.olacraft.world.data;
+
+public class UnavailableDataException extends Exception {
+
+ public UnavailableDataException() {
+ super();
+ }
+
+ public UnavailableDataException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public UnavailableDataException(String message) {
+ super(message);
+ }
+
+ public UnavailableDataException(Throwable cause) {
+ super(cause);
+ }
+
+ private static final long serialVersionUID = -8955947061088863309L;
+
+}
diff --git a/src/ru/olamedia/olacraft/world/data/package-info.java b/src/ru/olamedia/olacraft/world/data/package-info.java
new file mode 100644
index 0000000..2a171a6
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/data/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.data; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java
new file mode 100644
index 0000000..1670ef3
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/dataProvider/AbstractChunkDataProvider.java
@@ -0,0 +1,60 @@
+package ru.olamedia.olacraft.world.dataProvider;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.data.RegionData;
+import ru.olamedia.olacraft.world.data.SectorData;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.location.RegionLocation;
+import ru.olamedia.olacraft.world.location.SectorLocation;
+
+abstract public class AbstractChunkDataProvider {
+ /**
+ * is data already available or we should wait
+ *
+ * @param RegionLocation
+ * @return
+ */
+ public boolean isChunkAvailable(ChunkLocation chunkLocation) {
+ return this.isRegionAvailable(chunkLocation.getRegionLocation());
+ }
+
+ public boolean isSectorAvailable(SectorLocation sectorLocation) {
+ return this.isRegionAvailable(sectorLocation.getRegionLocation());
+ }
+
+ abstract public boolean isRegionAvailable(RegionLocation regionLocation);
+
+ /**
+ * we need this chunk now, send request to server or preload
+ *
+ * @param RegionLocation
+ */
+ public void loadChunk(ChunkLocation chunkLocation) {
+ //System.out.println("loadChunk(" + chunkLocation + ")");
+ this.loadRegion(chunkLocation.getRegionLocation());
+ //System.out.println("loadChunk(" + chunkLocation + ")--");
+ }
+
+ public void loadSector(SectorLocation sectorLocation) {
+ this.loadRegion(sectorLocation.getRegionLocation());
+ }
+
+ abstract public void loadRegion(RegionLocation regionLocation);
+
+ /**
+ * Get data if already available
+ *
+ * @param RegionLocation
+ * @return
+ */
+ public ChunkData getChunk(ChunkLocation chunkLocation) {
+ return this.getRegion(chunkLocation.getRegionLocation()).getChunkData(chunkLocation);
+ }
+
+ public SectorData getSector(SectorLocation sectorLocation) {
+ return this.getRegion(sectorLocation.getRegionLocation()).getSectorData(sectorLocation);
+ }
+
+ abstract public RegionData getRegion(RegionLocation regionLocation);
+
+}
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java
new file mode 100644
index 0000000..23270a7
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/dataProvider/CachedChunkDataProvider.java
@@ -0,0 +1,70 @@
+package ru.olamedia.olacraft.world.dataProvider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import ru.olamedia.olacraft.world.data.RegionData;
+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 List<String> loading = new ArrayList<String>();
+
+ public CachedChunkDataProvider(AbstractChunkDataProvider provider) {
+ this.provider = provider;
+ }
+
+ private static boolean DEBUG = true;
+
+ private void debug(String s) {
+ if (DEBUG) {
+ System.out.println("[CachedChunkDataProvider] " + s);
+ }
+ }
+
+ @Override
+ public boolean isRegionAvailable(RegionLocation regionLocation) {
+ String key = regionLocation.toString();// regionLocation.x + "-" +
+ // regionLocation.z;
+ if (regionMap.containsKey(key)) {
+ return true;
+ }
+ if (loading.contains(key)) {
+ // return false;
+ }
+ return provider.isRegionAvailable(regionLocation);
+ }
+
+ @Override
+ public void loadRegion(RegionLocation regionLocation) {
+ String key = regionLocation.toString();
+ //debug("loadRegion(" + regionLocation + ")");
+ if (!regionMap.containsKey(key)) {
+ if (!loading.contains(key)) {
+ debug("load()");
+ loading.add(key);
+ provider.loadRegion(regionLocation);
+ }else{
+ //debug("loadRegion(" + regionLocation + ") already in loading");
+ }
+ }else{
+ debug("error: loadRegion(" + regionLocation + ") already in regionMap");
+ }
+ }
+
+ @Override
+ public RegionData getRegion(RegionLocation regionLocation) {
+ String key = regionLocation.toString();
+ if (regionMap.containsKey(key)) {
+ return regionMap.get(key);
+ } else {
+ RegionData data = provider.getRegion(regionLocation);
+ regionMap.put(key, data);
+ loading.remove(key);
+ return data;
+ }
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java
new file mode 100644
index 0000000..514081f
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/dataProvider/LocalChunkDataProvider.java
@@ -0,0 +1,218 @@
+package ru.olamedia.olacraft.world.dataProvider;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.data.RegionData;
+import ru.olamedia.olacraft.world.generator.HeightMapGenerator;
+import ru.olamedia.olacraft.world.generator.RegionGenerator;
+import ru.olamedia.olacraft.world.location.RegionLocation;
+
+public class LocalChunkDataProvider extends AbstractChunkDataProvider {
+ private String worldName;
+ private String path;
+
+ private static boolean DEBUG = true;
+
+ private void debug(String s) {
+ if (DEBUG) {
+ System.out.println("[LocalChunkDataProvider] " + s);
+ }
+ }
+
+ public LocalChunkDataProvider(String worldName) {
+ this.worldName = worldName;
+ path = "data" + File.separator + this.worldName;
+ File worldDir = new File(path);
+ if (!worldDir.isDirectory()) {
+ worldDir.mkdirs();
+ }
+ }
+
+ private int[] seed;
+
+ private int[] getSeed() throws IOException {
+ if (null == seed) {
+ String filename = path + File.separator + "world.seed";
+ File seedFile = new File(filename);
+ // md5 - 32x0-f = 16 bytes or 8 short int
+ seed = new int[8];
+ if (seedFile.exists()) {
+ InputStream in = null;
+ DataInputStream din = null;
+ in = new FileInputStream(seedFile);
+ din = new DataInputStream(in);
+ for (int i = 0; i < 8; i++) {
+ seed[i] = din.readShort();
+ }
+ din.close();
+ in.close();
+ } else {
+ OutputStream out = new FileOutputStream(seedFile);
+ DataOutputStream dout = new DataOutputStream(out);
+ for (int i = 0; i < 8; i++) {
+ seed[i] = (int) (Integer.MAX_VALUE * Math.random());
+ dout.writeShort(seed[i]);
+ }
+ dout.close();
+ out.close();
+ }
+ }
+ return seed;
+ }
+
+ @Override
+ public boolean isRegionAvailable(RegionLocation regionLocation) {
+ return true;
+ }
+
+ @Override
+ public void loadRegion(RegionLocation regionLocation) {
+ // do nothing...
+ debug("loadRegion(" + regionLocation + ")");
+ }
+
+ private ChunkData createChunk(int chunkX, int chunkY, int chunkZ) {
+ debug("createChunk " + chunkX + " " + chunkY + " " + chunkZ);
+ ChunkData data = new ChunkData();
+ try {
+ getSeed();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ HeightMapGenerator.minValue = 1;
+ HeightMapGenerator.maxValue = 64;
+ HeightMapGenerator.init();
+ HeightMapGenerator.seed = seed[0];
+ int[][] heightMap = HeightMapGenerator.getChunkHeightMap(chunkX, chunkZ);
+ for (int y = 0; y < 16; y++) {
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ data.setEmpty(ChunkData.getId(x, y, z), (heightMap[x][z] < chunkY * 16 + y));
+ }
+ }
+ }
+ return data;
+ }
+
+ @Override
+ public RegionData getRegion(RegionLocation regionLocation) {
+ String filename = path + File.separator + regionLocation.getFilename();
+ RegionData data = null;
+ // TODO READ/WRITE FILE
+ File chunkFile = new File(filename);
+ if (chunkFile.exists()) {
+ InputStream in;
+ try {
+ in = new FileInputStream(chunkFile);
+ data = RegionData.loadFrom(in);
+ in.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ } else {
+ data = generateRegion(regionLocation);
+ try {
+ chunkFile.createNewFile();
+ FileOutputStream out = new FileOutputStream(chunkFile);
+ data.writeTo(out);
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return data;
+ }
+
+ public RegionData generateRegion(RegionLocation regionLocation) {
+ RegionData data = new RegionData();
+ data.location = regionLocation;
+ // TODO FILL HERE
+ RegionGenerator generator = new RegionGenerator();
+ try {
+ generator.setSeed(getSeed());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ generator.generate(data);
+ return data;
+ }
+
+ public ChunkData get(int chunkX, int chunkY, int chunkZ) {
+ debug("get " + chunkX + " " + chunkY + " " + chunkZ);
+ ChunkData data = null;
+ String filename = path + File.separator + chunkX + "_" + chunkY + "_" + chunkZ + ".chunk";
+ /*
+ * File chunkFile = new File(filename);
+ * if (chunkFile.exists()) {
+ * try {
+ * InputStream in = new FileInputStream(chunkFile);
+ * DataInputStream din = new DataInputStream(in);
+ * data = new ChunkData();
+ * data.readFrom(din);
+ * din.close();
+ * in.close();
+ * } catch (FileNotFoundException e) {
+ * e.printStackTrace();
+ * } catch (IOException e) {
+ * e.printStackTrace();
+ * }
+ * } else {
+ */
+ data = createChunk(chunkX, chunkY, chunkZ);
+ /*
+ * OutputStream out = null;
+ * ByteArrayOutputStream bout = null;
+ * DataOutputStream dout = null;
+ * try {
+ * chunkFile.createNewFile();
+ * out = new FileOutputStream(chunkFile);
+ * // bout = new ByteArrayOutputStream(4096);
+ * dout = new DataOutputStream(out);
+ * data.writeTo(dout);
+ * // dout.flush();
+ * // out.write(bout.toByteArray());
+ * out.flush();
+ * } catch (IOException e) {
+ * e.printStackTrace();
+ * } finally {
+ * if (null != dout) {
+ * try {
+ * dout.close();
+ * } catch (IOException e) {
+ * e.printStackTrace();
+ * }
+ * }
+ * if (null != bout) {
+ * try {
+ * bout.close();
+ * } catch (IOException e) {
+ * e.printStackTrace();
+ * }
+ * }
+ * if (null != out) {
+ * try {
+ * out.close();
+ * } catch (IOException e) {
+ * e.printStackTrace();
+ * }
+ * }
+ * }
+ * }
+ */
+ return data;
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/LocalRegionDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/LocalRegionDataProvider.java
new file mode 100644
index 0000000..447bcc3
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/dataProvider/LocalRegionDataProvider.java
@@ -0,0 +1,57 @@
+package ru.olamedia.olacraft.world.dataProvider;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class LocalRegionDataProvider {
+ private String worldName;
+ private String path;
+
+ public LocalRegionDataProvider(String worldName) {
+ this.worldName = worldName;
+ path = "data" + File.separator + this.worldName;
+ File worldDir = new File(path);
+ if (!worldDir.isDirectory()) {
+ worldDir.mkdirs();
+ }
+ }
+
+ private int[] seed;
+
+ private int[] getSeed() throws IOException {
+ if (null == seed) {
+ String filename = path + File.separator + "world.seed";
+ File seedFile = new File(filename);
+ // md5 - 32x0-f = 16 bytes or 8 short int
+ seed = new int[8];
+ if (seedFile.exists()) {
+ InputStream in = null;
+ DataInputStream din = null;
+ in = new FileInputStream(seedFile);
+ din = new DataInputStream(in);
+ for (int i = 0; i < 8; i++) {
+ seed[i] = din.readShort();
+ }
+ din.close();
+ in.close();
+ } else {
+ OutputStream out = new FileOutputStream(seedFile);
+ DataOutputStream dout = new DataOutputStream(out);
+ for (int i = 0; i < 8; i++) {
+ seed[i] = (int) (Integer.MAX_VALUE * Math.random());
+ dout.writeShort(seed[i]);
+ }
+ dout.close();
+ out.close();
+ }
+ }
+ return seed;
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java b/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java
new file mode 100644
index 0000000..8284ff9
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/dataProvider/RemoteChunkDataProvider.java
@@ -0,0 +1,75 @@
+package ru.olamedia.olacraft.world.dataProvider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import com.esotericsoftware.kryonet.Connection;
+
+import ru.olamedia.olacraft.network.GameClient;
+import ru.olamedia.olacraft.network.packet.GetRegionPacket;
+import ru.olamedia.olacraft.network.packet.IPacket;
+import ru.olamedia.olacraft.network.packet.IPacketListener;
+import ru.olamedia.olacraft.network.packet.RegionDataPacket;
+import ru.olamedia.olacraft.world.data.RegionData;
+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 List<String> loading = new ArrayList<String>();
+
+ public RemoteChunkDataProvider(GameClient client) {
+ this.client = client;
+ this.client.addPacketListener(this);
+ }
+
+ private static boolean DEBUG = true;
+
+ private void debug(String s) {
+ if (DEBUG) {
+ System.out.println("[RemoteChunkDataProvider] " + s);
+ }
+ }
+
+ @Override
+ public void loadRegion(RegionLocation regionLocation) {
+ String key = regionLocation.toString();
+ debug("loadRegion(" + key + ")");
+ if (!loading.contains(key)) {
+ loading.add(key);
+ client.send(new GetRegionPacket(regionLocation));
+ debug("sent packet: GetRegionPacket");
+ }
+ }
+
+ @Override
+ public boolean isRegionAvailable(RegionLocation regionLocation) {
+ String key = regionLocation.toString();
+ if (loading.contains(key)) {
+ return false;
+ }
+ return map.containsKey(key);
+ }
+
+ @Override
+ public RegionData getRegion(RegionLocation regionLocation) {
+ String key = regionLocation.toString();
+ RegionData data = map.get(key);
+ map.remove(key);
+ return data;
+ }
+
+ @Override
+ public void onPacket(Connection connection, IPacket p) {
+ if (p instanceof RegionDataPacket) {
+ debug("received packet [conn " + connection.getID() + "]: ChunkDataPacket");
+ RegionData data = ((RegionDataPacket) p).data;
+ String key = data.location.toString();
+ map.put(key, data);
+ loading.remove(key);
+ }
+ }
+
+}
diff --git a/src/ru/olamedia/olacraft/world/dataProvider/package-info.java b/src/ru/olamedia/olacraft/world/dataProvider/package-info.java
new file mode 100644
index 0000000..6a411e6
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/dataProvider/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.dataProvider; \ 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
new file mode 100644
index 0000000..c3e32b5
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/HeightMapGenerator.java
@@ -0,0 +1,157 @@
+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;
+import libnoiseforjava.exception.ExceptionInvalidParam;
+import libnoiseforjava.module.Billow;
+import libnoiseforjava.module.Blend;
+import libnoiseforjava.module.Max;
+import libnoiseforjava.module.Perlin;
+import libnoiseforjava.module.RidgedMulti;
+import libnoiseforjava.module.ScaleBias;
+import libnoiseforjava.module.Select;
+import libnoiseforjava.module.Turbulence;
+import libnoiseforjava.util.NoiseMap;
+import libnoiseforjava.util.NoiseMapBuilderPlane;
+
+public class HeightMapGenerator {
+ public static int minValue;
+ public static int maxValue;
+
+ public static int seed = (int) (Integer.MAX_VALUE * Math.random());
+
+ private static Billow plainsNoise;
+ private static ScaleBias plains;
+ private static RidgedMulti hillsNoise;
+ private static ScaleBias hills;
+ private static RidgedMulti mountainsNoise;
+ private static ScaleBias mountains;
+ private static Perlin terrainType;
+ private static Blend blendedTerrain;
+ private static Select selectedTerrain;
+ private static Max maxTerrain;
+ private static Turbulence turbulence;
+ private static ScaleBias finalTerrain;
+
+ private static boolean isInitialized = false;
+
+ public static void init() {
+ if (isInitialized) {
+ return;
+ }
+ isInitialized = true;
+ try {
+ // PLAINS
+ plainsNoise = new Billow();
+ plainsNoise.setFrequency(0.01);
+ plains = new ScaleBias(plainsNoise);
+ plains.setScale(0.05);
+ plains.setBias(-0.75);
+ // HILLS
+ hillsNoise = new RidgedMulti();
+ hillsNoise.setFrequency(0.01);
+ hills = new ScaleBias(hillsNoise);
+ hills.setScale(0.5);
+ hills.setBias(-0.75);
+ // MOUNTAINS
+ mountainsNoise = new RidgedMulti();
+ mountainsNoise.setFrequency(0.04);
+ mountainsNoise.setOctaveCount(6);
+ turbulence = new Turbulence(mountainsNoise);
+ turbulence.setFrequency(0.2);
+ turbulence.setPower(1);
+ mountains = new ScaleBias(turbulence);
+ mountains.setScale(1.0);
+ mountains.setBias(-1.25);
+ terrainType = new Perlin();
+ terrainType.setOctaveCount(6);
+ terrainType.setFrequency(0.06);
+ terrainType.setPersistence(0.25);
+ terrainType.setNoiseQuality(NoiseQuality.QUALITY_BEST);
+ selectedTerrain = new Select(plains, mountains, terrainType);
+ selectedTerrain.setBounds(0, 1);
+ selectedTerrain.setEdgeFalloff(0.125);
+ blendedTerrain = new Blend(plains, mountains, terrainType);
+ maxTerrain = new Max(plains, turbulence);
+ finalTerrain = new ScaleBias(maxTerrain);
+ finalTerrain.setBias(2);
+ setSeed(seed);
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void setSeed(int newseed) {
+ seed = newseed;
+ plainsNoise.setSeed(seed);
+ hillsNoise.setSeed(seed);
+ mountainsNoise.setSeed(seed);
+ terrainType.setSeed(seed);
+ }
+
+ public static int[][] getChunkHeightMap(int chunkX, int chunkZ) {
+ init();
+ try {
+ NoiseMapBuilderPlane builder = new NoiseMapBuilderPlane(16, 16);
+ // builder.enableSeamless(true);
+ // Perlin plains = new Perlin();
+
+ // Select finalTerrain = new Select(plains, mountains, null);
+ // finalTerrain.setControlModule(terrainType);
+ // finalTerrain.setBounds(0.0, 1000);
+ // finalTerrain.setEdgeFalloff(1.25);
+
+ NoiseMap heightMap = new NoiseMap(16, 16);
+ builder.setSourceModule(maxTerrain);
+ builder.setDestNoiseMap(heightMap);
+ double bx = chunkX;
+ double bz = chunkZ;
+ builder.setDestSize(16, 16);
+ builder.setBounds(bx, bx + 1, bz, bz + 1);
+ builder.build();
+ double[][] heights = heightMap.getNoiseMap();
+ int[][] ints = new int[16][16];
+ // System.out.print("heightmap:");
+ 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) (minValue + (maxValue - minValue) * (heights[x][z] + 1) / 2);
+ }
+ }
+ // System.out.println("");
+ return ints;
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static HeightMap getHeightMap(RegionLocation location) {
+ init();
+ HeightMap map = new HeightMap(256, 256);
+ try {
+ NoiseMapBuilderPlane builder = new NoiseMapBuilderPlane(256, 256);
+ NoiseMap heightMap = new NoiseMap(256, 256);
+ builder.setSourceModule(finalTerrain);
+ builder.setDestNoiseMap(heightMap);
+ builder.setDestSize(256, 256);
+ float bx = location.x;
+ float bz = location.z;
+ builder.setBounds(bx, bx + 1, bz, bz + 1);
+ builder.build();
+ double[][] heights = heightMap.getNoiseMap();
+ for (int x = 0; x < 256; x++) {
+ for (int z = 0; z < 256; z++) {
+ map.setHeight(x, z, 0);
+ //(int) (minValue + (maxValue - minValue) * (heights[x][z] + 1) / 2)
+ }
+ }
+ return map;
+ } catch (ExceptionInvalidParam e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/generator/ImprovedNoise.java b/src/ru/olamedia/olacraft/world/generator/ImprovedNoise.java
new file mode 100644
index 0000000..365aa12
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/ImprovedNoise.java
@@ -0,0 +1,61 @@
+package ru.olamedia.olacraft.world.generator;
+
+//JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE - COPYRIGHT 2002 KEN PERLIN.
+
+public final class ImprovedNoise {
+ static public double noise(double x, double y, double z) {
+ int X = (int) Math.floor(x) & 255, // FIND UNIT CUBE THAT
+ Y = (int) Math.floor(y) & 255, // CONTAINS POINT.
+ Z = (int) Math.floor(z) & 255;
+ x -= Math.floor(x); // FIND RELATIVE X,Y,Z
+ y -= Math.floor(y); // OF POINT IN CUBE.
+ z -= Math.floor(z);
+ double u = fade(x), // COMPUTE FADE CURVES
+ v = fade(y), // FOR EACH OF X,Y,Z.
+ w = fade(z);
+ int A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z, // HASH COORDINATES
+ // OF
+ B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z; // THE 8 CUBE
+ // CORNERS,
+
+ return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), // AND ADD
+ grad(p[BA], x - 1, y, z)), // BLENDED
+ lerp(u, grad(p[AB], x, y - 1, z), // RESULTS
+ grad(p[BB], x - 1, y - 1, z))),// FROM 8
+ lerp(v, lerp(u, grad(p[AA + 1], x, y, z - 1), // CORNERS
+ grad(p[BA + 1], x - 1, y, z - 1)), // OF CUBE
+ lerp(u, grad(p[AB + 1], x, y - 1, z - 1), grad(p[BB + 1], x - 1, y - 1, z - 1))));
+ }
+
+ static double fade(double t) {
+ return t * t * t * (t * (t * 6 - 15) + 10);
+ }
+
+ static double lerp(double t, double a, double b) {
+ return a + t * (b - a);
+ }
+
+ static double grad(int hash, double x, double y, double z) {
+ int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
+ double u = h < 8 ? x : y, // INTO 12 GRADIENT DIRECTIONS.
+ v = h < 4 ? y : h == 12 || h == 14 ? x : z;
+ return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
+ }
+
+ static final int p[] = new int[512], permutation[] = { 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194,
+ 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26,
+ 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171,
+ 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230,
+ 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187,
+ 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226,
+ 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189,
+ 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129,
+ 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193,
+ 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199,
+ 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24,
+ 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 };
+ static {
+ for (int i = 0; i < 256; i++)
+ p[256 + i] = p[i] = permutation[i];
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/generator/Lerp.java b/src/ru/olamedia/olacraft/world/generator/Lerp.java
new file mode 100644
index 0000000..cc009fe
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/Lerp.java
@@ -0,0 +1,27 @@
+package ru.olamedia.olacraft.world.generator;
+
+public class Lerp {
+ 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/RegionGenerator.java b/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java
new file mode 100644
index 0000000..9657e32
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/RegionGenerator.java
@@ -0,0 +1,71 @@
+package ru.olamedia.olacraft.world.generator;
+
+import ru.olamedia.olacraft.world.data.ChunkData;
+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.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.location.SectorLocation;
+
+public class RegionGenerator {
+ private int[] seed;
+
+ public void setSeed(int[] seed) {
+ this.seed = seed;
+ }
+
+ public void debug(String s) {
+ System.out.println("[RegionGenerator] " + s);
+ }
+
+ public void generate(RegionData data) {
+ HeightMapGenerator.minValue = -5;
+ HeightMapGenerator.maxValue = 100;
+ HeightMapGenerator.init();
+ HeightMapGenerator.seed = seed[0];
+ BlockLocation offset = data.location.getBlockLocation();
+ // int[][] heightMap =
+ // HeightMapGenerator.getHeightMap(data.location.getBlockLocation().x,
+ // data.location.getBlockLocation().z, 256, 256);
+ debug(data.location.toString());
+ data.heightMap = HeightMapGenerator.getHeightMap(data.location);
+ //debug(data.heightMap.toString());
+ data.sectorData = new SectorData[16][16];
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ // CREATE SECTOR
+ SectorData sector = new SectorData();
+ sector.location = new SectorLocation(offset.x + x * 16, offset.z + z * 16);
+ 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);
+ int chunkOffsetY = y * 16 - 128;
+ 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);
+ for (int inChunkY = 0; inChunkY < 16; inChunkY++) {
+ //height = sector.heightMap.getHeight(inChunkX, inChunkZ);
+ int id = ChunkData.getId(inChunkX, inChunkY, inChunkZ);
+ if (chunkOffsetY + inChunkY > height) {
+ chunk.setEmpty(id, true);
+ } else {
+ //System.out.println("not empty, height: " + height);
+ chunk.setEmpty(id, false);
+ }
+ }
+ }
+ }
+ chunk.compact();
+ sector.chunkData[y] = chunk;
+ }
+ data.sectorData[x][z] = sector;
+ }
+ }
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/generator/package-info.java b/src/ru/olamedia/olacraft/world/generator/package-info.java
new file mode 100644
index 0000000..2f62117
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/generator/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.generator; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/location/BlockLocation.java b/src/ru/olamedia/olacraft/world/location/BlockLocation.java
new file mode 100644
index 0000000..b104bad
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/BlockLocation.java
@@ -0,0 +1,37 @@
+package ru.olamedia.olacraft.world.location;
+
+import java.io.Serializable;
+
+import ru.olamedia.olacraft.world.chunk.Chunk;
+
+public class BlockLocation implements Serializable {
+ private static final long serialVersionUID = -4987461467575474762L;
+ public int x;
+ public int y;
+ public int z;
+
+ public BlockLocation() {
+ }
+
+ public BlockLocation(int x, int y, int z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public ChunkLocation getChunkLocation() {
+ return new ChunkLocation(Chunk.v(x), Chunk.v(y + 128), Chunk.v(z));
+ }
+
+ public RegionLocation getRegionLocation() {
+ return new RegionLocation(Chunk.v(Chunk.v(x)), Chunk.v(Chunk.v(z)));
+ }
+
+ public SectorLocation getSectorLocation() {
+ return new SectorLocation(Chunk.v(x), Chunk.v(z));
+ }
+
+ public String toString() {
+ return "blockLocation[" + x + "," + y + "," + z + "]";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/location/ChunkLocation.java b/src/ru/olamedia/olacraft/world/location/ChunkLocation.java
new file mode 100644
index 0000000..57acc52
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/ChunkLocation.java
@@ -0,0 +1,40 @@
+package ru.olamedia.olacraft.world.location;
+
+import java.io.Serializable;
+
+import ru.olamedia.olacraft.world.chunk.Chunk;
+
+public class ChunkLocation 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;
+ }
+
+ public int x;
+ public int y;
+ public int z;
+
+ public SectorLocation getSectorLocation() {
+ return new SectorLocation(x, z);
+ }
+
+ public RegionLocation getRegionLocation() {
+ return new RegionLocation(Chunk.v(x), Chunk.v(z));
+ }
+
+ public String toString() {
+ return "chunkLocation[" + x + "," + y + "," + z + "]";
+ }
+ /*
+ * public BlockSlice getSlice(){
+ *
+ * }
+ */
+}
diff --git a/src/ru/olamedia/olacraft/world/location/RegionLocation.java b/src/ru/olamedia/olacraft/world/location/RegionLocation.java
new file mode 100644
index 0000000..59a57ec
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/RegionLocation.java
@@ -0,0 +1,29 @@
+package ru.olamedia.olacraft.world.location;
+
+import java.io.Serializable;
+
+public class RegionLocation implements Serializable {
+ private static final long serialVersionUID = -141619138379029773L;
+ public int x;
+ public int z;
+
+ public RegionLocation() {
+ }
+
+ public RegionLocation(int x, int z) {
+ this.x = x;
+ this.z = z;
+ }
+
+ public String toString() {
+ return "regionLocation[" + x + "," + z + "]";
+ }
+
+ public String getFilename() {
+ return "" + x + "_" + z + ".region";
+ }
+
+ public BlockLocation getBlockLocation() {
+ return new BlockLocation(x * 256, 0, z * 256);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/location/SectorLocation.java b/src/ru/olamedia/olacraft/world/location/SectorLocation.java
new file mode 100644
index 0000000..59390b8
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/SectorLocation.java
@@ -0,0 +1,29 @@
+package ru.olamedia.olacraft.world.location;
+
+import java.io.Serializable;
+
+import ru.olamedia.olacraft.world.chunk.Chunk;
+
+public class SectorLocation implements Serializable {
+ private static final long serialVersionUID = 4500216114186249375L;
+
+ public SectorLocation() {
+
+ }
+
+ public SectorLocation(int x, int z) {
+ this.x = x;
+ this.z = z;
+ }
+
+ public int x;
+ public int z;
+
+ public RegionLocation getRegionLocation() {
+ return new RegionLocation(Chunk.v(x), Chunk.v(z));
+ }
+
+ public String toString() {
+ return "sectorLocation[" + x + "," + z + "]";
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/location/package-info.java b/src/ru/olamedia/olacraft/world/location/package-info.java
new file mode 100644
index 0000000..37f205d
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/location/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.location; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/package-info.java b/src/ru/olamedia/olacraft/world/package-info.java
new file mode 100644
index 0000000..914d8d2
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/provider/IChunkProvider.java b/src/ru/olamedia/olacraft/world/provider/IChunkProvider.java
new file mode 100644
index 0000000..5076c75
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/IChunkProvider.java
@@ -0,0 +1,8 @@
+package ru.olamedia.olacraft.world.provider;
+
+import ru.olamedia.olacraft.world.block.Block;
+
+public interface IChunkProvider {
+ public boolean isEmptyBlock(int x, int y, int z);
+ public Block getBlock(int x, int y, int z);
+}
diff --git a/src/ru/olamedia/olacraft/world/provider/WorldProvider.java b/src/ru/olamedia/olacraft/world/provider/WorldProvider.java
new file mode 100644
index 0000000..8dacce9
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/WorldProvider.java
@@ -0,0 +1,130 @@
+package ru.olamedia.olacraft.world.provider;
+
+import ru.olamedia.olacraft.game.SpawnLocation;
+import ru.olamedia.olacraft.world.WorldInfo;
+import ru.olamedia.olacraft.world.block.Block;
+import ru.olamedia.olacraft.world.chunk.Chunk;
+import ru.olamedia.olacraft.world.data.ChunkData;
+import ru.olamedia.olacraft.world.data.RegionData;
+import ru.olamedia.olacraft.world.dataProvider.AbstractChunkDataProvider;
+import ru.olamedia.olacraft.world.location.BlockLocation;
+import ru.olamedia.olacraft.world.location.ChunkLocation;
+import ru.olamedia.olacraft.world.location.RegionLocation;
+
+public class WorldProvider {
+ private WorldInfo info = new WorldInfo();
+ private AbstractChunkDataProvider dataProvider;
+
+ public WorldInfo getInfo() {
+ return info;
+ }
+
+ public void setInfo(WorldInfo worldInfo) {
+ info = worldInfo;
+ }
+
+ /*
+ * public AbstractChunkDataProvider getChunkDataProvider() {
+ * return dataProvider;
+ * }
+ */
+
+ public void setChunkDataProvider(AbstractChunkDataProvider provider) {
+ dataProvider = provider;
+ }
+
+ public SpawnLocation getSpawnLocation(int connectionId) {
+ SpawnLocation l = new SpawnLocation();
+ int maxShift = 10;
+ l.x = (int) (maxShift - Math.random() * 2 * maxShift);
+ l.z = (int) (maxShift - Math.random() * 2 * maxShift);
+ System.out.print("Searching spawn Y");
+ BlockLocation spawnLocation = new BlockLocation(l.x, 0, l.z);
+ for (int y = info.maxHeight; y > info.minHeight; y--) {
+ // search for floor block
+ spawnLocation.y = y;
+ System.out.print(y + ". ");
+ ChunkData chunk = dataProvider.getChunk(spawnLocation.getChunkLocation());
+ boolean notEmpty = !chunk.isEmpty(ChunkData.getId(Chunk.in(spawnLocation.x), Chunk.in(spawnLocation.y),
+ Chunk.in(spawnLocation.z)));
+ if (notEmpty) {
+ // found
+ l.y = y + 1;
+ System.out.println("found: " + y);
+ return l;
+ }
+ }
+ System.out.println("not found ");
+ // not found
+ l.y = info.maxHeight;
+ return l;
+ }
+
+ public boolean renderBottom(int x, int y, int z) {
+ return (!isEmptyBlock(x, y, z)) && (isEmptyBlock(x, y - 1, z));
+ }
+
+ public boolean renderTop(int x, int y, int z) {
+ return (!isEmptyBlock(x, y, z)) && (isEmptyBlock(x, y + 1, z));
+ }
+
+ public boolean renderLeft(int x, int y, int z) {
+ return (!isEmptyBlock(x, y, z)) && (isEmptyBlock(x - 1, y, z));
+ }
+
+ public boolean renderRight(int x, int y, int z) {
+ return (!isEmptyBlock(x, y, z)) && (isEmptyBlock(x + 1, y, z));
+ }
+
+ public boolean renderBack(int x, int y, int z) {
+ return (!isEmptyBlock(x, y, z)) && (isEmptyBlock(x, y, z - 1));
+ }
+
+ public boolean renderFront(int x, int y, int z) {
+ return (!isEmptyBlock(x, y, z)) && (isEmptyBlock(x, y, z + 1));
+ }
+
+ public boolean isEmptyBlock(int x, int y, int z) {
+ BlockLocation blockLocation = new BlockLocation(x, y, z);
+
+ if (isChunkAvailable(blockLocation.getChunkLocation())) {
+ ChunkData data = dataProvider.getChunk(blockLocation.getChunkLocation());
+ if (null != data) {
+ return data.isEmpty(blockLocation);
+ }
+ }
+ return false;
+ }
+
+ public void requestChunk(int chunkX, int chunkY, int chunkZ) {
+ ChunkLocation chunkLocation = new ChunkLocation(chunkX, chunkY, chunkZ);
+ // getChunkDataProvider().loadRegion(chunkLocation.getRegionLocation());
+ loadChunk(chunkLocation);
+ }
+
+ public boolean isChunkAvailable(ChunkLocation chunkLocation) {
+ return dataProvider.isChunkAvailable(chunkLocation);
+ }
+
+ public boolean isAvailableBlock(int x, int y, int z) {
+ BlockLocation blockLocation = new BlockLocation(x, y, z);
+ return dataProvider.isChunkAvailable(blockLocation.getChunkLocation());
+ }
+
+ public void loadChunk(ChunkLocation chunkLocation) {
+ dataProvider.loadChunk(chunkLocation);
+ }
+
+ public RegionData getRegion(RegionLocation regionLocation) {
+ return dataProvider.getRegion(regionLocation);
+ }
+
+ public Block getBlock(int x, int y, int z) {
+ BlockLocation blockLocation = new BlockLocation(x, y, z);
+ return new Block(this, x, y, z);
+ }
+
+ public ChunkData getChunk(ChunkLocation chunkLocation) {
+ return dataProvider.getChunk(chunkLocation);
+ }
+}
diff --git a/src/ru/olamedia/olacraft/world/provider/blockData/BlockData.java b/src/ru/olamedia/olacraft/world/provider/blockData/BlockData.java
new file mode 100644
index 0000000..94be4d7
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/blockData/BlockData.java
@@ -0,0 +1,5 @@
+package ru.olamedia.olacraft.world.provider.blockData;
+
+public class BlockData {
+
+}
diff --git a/src/ru/olamedia/olacraft/world/provider/blockData/EmptyBlockData.java b/src/ru/olamedia/olacraft/world/provider/blockData/EmptyBlockData.java
new file mode 100644
index 0000000..ab17107
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/blockData/EmptyBlockData.java
@@ -0,0 +1,5 @@
+package ru.olamedia.olacraft.world.provider.blockData;
+
+public class EmptyBlockData implements IBlockData{
+ public boolean notEmpty = false;
+}
diff --git a/src/ru/olamedia/olacraft/world/provider/blockData/IBlockData.java b/src/ru/olamedia/olacraft/world/provider/blockData/IBlockData.java
new file mode 100644
index 0000000..95dfb35
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/blockData/IBlockData.java
@@ -0,0 +1,5 @@
+package ru.olamedia.olacraft.world.provider.blockData;
+
+public interface IBlockData {
+ public boolean notEmpty = false;
+}
diff --git a/src/ru/olamedia/olacraft/world/provider/blockData/package-info.java b/src/ru/olamedia/olacraft/world/provider/blockData/package-info.java
new file mode 100644
index 0000000..0fa952a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/blockData/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.provider.blockData; \ No newline at end of file
diff --git a/src/ru/olamedia/olacraft/world/provider/package-info.java b/src/ru/olamedia/olacraft/world/provider/package-info.java
new file mode 100644
index 0000000..c43643a
--- /dev/null
+++ b/src/ru/olamedia/olacraft/world/provider/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.olacraft.world.provider; \ No newline at end of file
diff --git a/src/ru/olamedia/player/Player.java b/src/ru/olamedia/player/Player.java
new file mode 100644
index 0000000..08811b5
--- /dev/null
+++ b/src/ru/olamedia/player/Player.java
@@ -0,0 +1,31 @@
+package ru.olamedia.player;
+
+import ru.olamedia.liveEntity.LiveEntity;
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.network.packet.LiveEntityLocationUpdatePacket;
+import ru.olamedia.olacraft.weapon.Bullet;
+
+public class Player extends LiveEntity {
+
+ @Override
+ public void notifyLocationUpdate() {
+ LiveEntityLocationUpdatePacket p = new LiveEntityLocationUpdatePacket();
+ p.x = getX();
+ p.y = getY();
+ p.z = getZ();
+ Game.client.send(p);
+ }
+
+ public Player() {
+
+ }
+
+ public void onMouseClick() {
+ Bullet b = new Bullet();
+ b.velocity.set(Game.instance.camera.getLook());
+ b.velocity.negate();
+ b.velocity.scale(100);
+ b.location.set(getX(), getCameraY(), getZ());
+ Game.client.getScene().addBullet(b);
+ }
+}
diff --git a/src/ru/olamedia/tasks/Task.java b/src/ru/olamedia/tasks/Task.java
new file mode 100644
index 0000000..1886265
--- /dev/null
+++ b/src/ru/olamedia/tasks/Task.java
@@ -0,0 +1,24 @@
+package ru.olamedia.tasks;
+
+public abstract class Task implements Runnable {
+
+ public Task(){
+ TaskManager.add(this);
+ }
+
+ protected volatile boolean stopped = false;
+
+ public void setStopped(boolean s){
+ this.stopped = s;
+ }
+
+ public void stop() {
+ this.stopped = true;
+ }
+
+ protected boolean shouldStop() {
+ return this.stopped;
+ }
+
+ public abstract void run();
+}
diff --git a/src/ru/olamedia/tasks/TaskManager.java b/src/ru/olamedia/tasks/TaskManager.java
new file mode 100644
index 0000000..e1a637e
--- /dev/null
+++ b/src/ru/olamedia/tasks/TaskManager.java
@@ -0,0 +1,18 @@
+package ru.olamedia.tasks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TaskManager {
+ private static List<Task> tasks = new ArrayList<Task>();
+
+ public static void add(Task task) {
+ tasks.add(task);
+ }
+
+ public static void stopAll() {
+ for (Task task : tasks) {
+ task.stop();
+ }
+ }
+}
diff --git a/src/ru/olamedia/tasks/package-info.java b/src/ru/olamedia/tasks/package-info.java
new file mode 100644
index 0000000..88dffa7
--- /dev/null
+++ b/src/ru/olamedia/tasks/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.tasks; \ No newline at end of file
diff --git a/src/ru/olamedia/texture/ResourceUtil.java b/src/ru/olamedia/texture/ResourceUtil.java
new file mode 100644
index 0000000..656e3a8
--- /dev/null
+++ b/src/ru/olamedia/texture/ResourceUtil.java
@@ -0,0 +1,126 @@
+package ru.olamedia.texture;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+public class ResourceUtil {
+
+ private static URL baseURL;
+
+ private static ResourceUtil instance;
+
+ public static ResourceUtil getInstance() {
+ if (null == instance) {
+ instance = new ResourceUtil();
+ }
+ return instance;
+ }
+
+ public static URL getInternalBaseURL() {
+ if (null == baseURL) {
+ URL url = getInstance().getClass().getResource("ResourceUtil.class");
+ // URL back = null;
+ // try {
+ // back = new URL(url, "..");
+ // } catch (MalformedURLException e1) {
+ // e1.printStackTrace();
+ // }
+ // System.out.println("Back:" + back);
+ // System.out.println("Class:" + url);
+ int p = url.toString().indexOf("jar!");
+ if (p > 0) {
+ // in local jar:
+ // jar:file:/E:/com/mindprod/thepackage/thepackage.jar!/com/mindprod/thepackage/images/blueball.gif
+ // in remote jar:
+ // jar:http://mindprod.com/thepackage.jar!/com/mindprod/thepackage/images/blueball.gif
+ try {
+ baseURL = new URL(url.toString().substring(0, p + 4));
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ } else {
+ // in local file:
+ // file:/E:/com/mindprod/thepackage/images/blueball.gif
+ // in remote file:
+ // http://mindprod.com/com/mindprod/the...s/blueball.gif
+ int l = url.toString().length() - (ResourceUtil.class.toString()).length();
+ try {
+ baseURL = new URL(url.toString().substring(0, l));
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return baseURL;
+ }
+
+ public static String getInternalFilename(String fn) {
+ return getInternalBaseURL() + fn;
+ }
+
+ public static URL getInternalResource(String internalPath) throws MalformedURLException {
+ URL url = ResourceUtil.class.getClassLoader().getResource(internalPath);
+ if (url == null) {
+ System.out.println(internalPath + " not found");
+ } else {
+ System.out.println(url.toString());
+ }
+ return url;
+ // return new URL(getInternalBaseURL(), internalPath);
+ }
+
+ public static URL getURL(String internalPath) {
+ try {
+ return new URL(getInternalBaseURL(), internalPath);
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String getFilename(String internalPath) {
+ try {
+ URL url = new URL(getInternalBaseURL(), internalPath);
+ return url.getFile();
+ } catch (MalformedURLException e) {
+ System.err.println("Problems with " + internalPath);
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static InputStream getInternalInputStream(String internalPath) {
+ try {
+ return getInternalResource(internalPath).openStream();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static File getFile(String fn) {
+ URL url = null;
+ try {
+ url = new URL(getInternalFilename(fn));
+ } catch (MalformedURLException e1) {
+ e1.printStackTrace();
+ }
+ System.out.println("Fn:" + fn);
+ System.out.println("Base:" + getInternalBaseURL());
+ System.out.println("Internal:" + getInternalFilename(fn));
+ System.out.println("Url:" + url);
+ File f;
+ try {
+ f = new File(url.toURI());
+ } catch (URISyntaxException e) {
+ f = new File(url.getPath());
+ }
+ return f;
+ }
+}
diff --git a/src/ru/olamedia/texture/TextureManager.java b/src/ru/olamedia/texture/TextureManager.java
new file mode 100644
index 0000000..c790cee
--- /dev/null
+++ b/src/ru/olamedia/texture/TextureManager.java
@@ -0,0 +1,42 @@
+package ru.olamedia.texture;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+import ru.olamedia.asset.AssetManager;
+import ru.olamedia.asset.AssetNotFoundException;
+
+import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+public class TextureManager {
+ private static HashMap<String, Texture> list = new HashMap<String, Texture>();
+
+ public static Texture get(String filename) {
+ if (!list.containsKey(filename)) {
+ try {
+ return get(filename, AssetManager.getAsset(filename).getInputStream());
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ } catch (AssetNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ return list.get(filename);
+ }
+
+ public static Texture get(String key, InputStream stream) {
+ if (!list.containsKey(key)) {
+ try {
+ list.put(key, TextureIO.newTexture(stream, true, "PNG"));
+ } catch (IOException e) {
+ list.put(key, null);
+ e.printStackTrace();
+ }
+ }
+ return list.get(key);
+ }
+}
diff --git a/src/ru/olamedia/texture/package-info.java b/src/ru/olamedia/texture/package-info.java
new file mode 100644
index 0000000..fb1a5d4
--- /dev/null
+++ b/src/ru/olamedia/texture/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.texture; \ No newline at end of file
diff --git a/src/ru/olamedia/util/BufferUtils.java b/src/ru/olamedia/util/BufferUtils.java
new file mode 100644
index 0000000..10d9f36
--- /dev/null
+++ b/src/ru/olamedia/util/BufferUtils.java
@@ -0,0 +1,16 @@
+package ru.olamedia.util;
+
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+public class BufferUtils {
+
+ public static ShortBuffer createShortBuffer(int capacity) {
+ return ShortBuffer.allocate(capacity);
+ }
+
+ public static FloatBuffer createFloatBuffer(int capacity) {
+ return FloatBuffer.allocate(capacity);
+ }
+
+}
diff --git a/src/ru/olamedia/vbo/VBO.java b/src/ru/olamedia/vbo/VBO.java
new file mode 100644
index 0000000..6f6c508
--- /dev/null
+++ b/src/ru/olamedia/vbo/VBO.java
@@ -0,0 +1,29 @@
+package ru.olamedia.vbo;
+
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLUniformData;
+
+import com.jogamp.opengl.util.PMVMatrix;
+
+public class VBO {
+ private GLAutoDrawable drawable;
+ private PMVMatrix pmvMatrix;
+ private GLUniformData pmvMatrixUniform;
+ private GLUniformData colorUniform;
+ private int[] vboIda = new int[10];
+
+ public VBO(GLAutoDrawable drawable) {
+ this.drawable = drawable;
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ // gl.glGenBuffersARB(1, vboIda, 0);
+ }
+
+ public void setDrawable(GLAutoDrawable drawable) {
+ this.drawable = drawable;
+ }
+
+ public void render() {
+
+ }
+}
diff --git a/src/ru/olamedia/vbo/package-info.java b/src/ru/olamedia/vbo/package-info.java
new file mode 100644
index 0000000..325d96f
--- /dev/null
+++ b/src/ru/olamedia/vbo/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author olamedia
+ *
+ */
+package ru.olamedia.vbo; \ No newline at end of file