diff --git a/examples/d3d/d3d-msvc.visualdproj b/examples/d3d/d3d-msvc.visualdproj index 2cf675dd..8152b0a7 100644 --- a/examples/d3d/d3d-msvc.visualdproj +++ b/examples/d3d/d3d-msvc.visualdproj @@ -409,14 +409,6 @@ *.obj;*.cmd;*.build;*.json;*.dep - - - - - - - - diff --git a/examples/d3d/src/d3d.d b/examples/d3d/src/d3d.d index ad78d6ca..d7ee9aa3 100644 --- a/examples/d3d/src/d3d.d +++ b/examples/d3d/src/d3d.d @@ -16,10 +16,6 @@ import dlangui.graphics.gldrawbuf; import derelict.opengl3.gl3; import derelict.opengl3.gl; -import dminer.core.world; -import dminer.core.minetypes; -import dminer.core.blocks; - mixin APP_ENTRY_POINT; /// entry point for dlangui based application @@ -46,7 +42,7 @@ extern (C) int UIAppMain(string[] args) { static if (ENABLE_OPENGL): -class UiWidget : VerticalLayout, CellVisitor { +class UiWidget : VerticalLayout { this() { super("OpenGLView"); layoutWidth = FILL_PARENT; @@ -184,43 +180,6 @@ class UiWidget : VerticalLayout, CellVisitor { brickNode.drawable = new Model(brickMaterial, brickMesh); _scene.addChild(brickNode); - _minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0)); - _world = new World(); - _world.setCell(0, 11, 10, 2); - _world.setCell(5, 11, 15, 2); - for (int x = -100; x < 100; x++) - for (int z = -100; z < 100; z++) - _world.setCell(x, 0, z, 2); - Random rnd; - rnd.setSeed(12345); - for(int i = 0; i < 1000; i++) { - int bx = rnd.next(6)-32; - int by = rnd.next(4); - int bz = rnd.next(6)-32; - //Log.fd("Setting cell %d,%d,%d", bx, by, bz); - _world.setCell(bx, by, bz, 3); - } - - _world.camPosition = Position(Vector3d(0, 3, 0), Vector3d(0, 0, 1)); - updateMinerMesh(); - - Material minerMaterial = new Material(EffectId("textured.vert", "textured.frag", null), "blocks"); - //minerMaterial.textureLinear = false; - Model minerDrawable = new Model(minerMaterial, _minerMesh); - Node3d minerNode = new Node3d("miner", minerDrawable); - _scene.addChild(minerNode); - - - //minerNode.visible = false; - //cubeNode.visible = false; - - //CellVisitor visitor = new TestVisitor(); - //Log.d("Testing cell visitor"); - //long ts = currentTimeMillis; - //_world.visitVisibleCells(_world.camPosition, visitor); - //long duration = currentTimeMillis - ts; - //Log.d("DiamondVisitor finished in ", duration, " ms"); - //destroy(w); } Node3d dirLightNode; @@ -272,23 +231,6 @@ class UiWidget : VerticalLayout, CellVisitor { childById("lblRotationZ").text = to!dstring(rotationZ); } - void visit(World world, ref Position camPosition, Vector3d pos, cell_t cell, int visibleFaces) { - BlockDef def = BLOCK_DEFS[cell]; - def.createFaces(world, world.camPosition, pos, visibleFaces, _minerMesh); - } - - void updateMinerMesh() { - _minerMesh.reset(); - long ts = currentTimeMillis; - _world.visitVisibleCells(_world.camPosition, this); - long duration = currentTimeMillis - ts; - Log.d("DiamondVisitor finished in ", duration, " ms ", "Vertex count: ", _minerMesh.vertexCount); - for (int i = 0; i < 20; i++) - Log.d("vertex: ", _minerMesh.vertex(i)); - } - - World _world; - /// returns true is widget is being animated - need to call animate() and redraw @property override bool animating() { return true; } /// animates window; interval is time left from previous draw, in hnsecs (1/10000000 of second) @@ -307,17 +249,11 @@ class UiWidget : VerticalLayout, CellVisitor { Scene3dRef _scene; Camera _cam; - Mesh _minerMesh; - /// this is OpenGLDrawableDelegate implementation private void doDraw(Rect windowRect, Rect rc) { _cam.setPerspective(rc.width, rc.height, 45.0f, near, far); _cam.setIdentity(); - //_cam.translate(vec3( - // childById!ScrollBar("sbTranslationX").position / 10.0f, - // childById!ScrollBar("sbTranslationY").position / 10.0f, - // childById!ScrollBar("sbTranslationZ").position / 10.0f)); _cam.translateX(translationX); _cam.translateY(translationY); _cam.translateZ(translationZ); @@ -325,73 +261,6 @@ class UiWidget : VerticalLayout, CellVisitor { _cam.rotateY(rotationY); _cam.rotateZ(rotationZ); - //Log.d("camPosition: ", _scene.cameraPosition); - //Log.d("camDirection: ", _scene.forwardVectorWorld); - //Log.d("lightPosition: ", dirLightNode.light.position); - //Log.d("lightDirection: ", dirLightNode.light.direction); - //Log.d("lightColor: ", dirLightNode.light.color); - - //_cam.translate(vec3(-1, -1.5, -1)); // - angle/1000 - //_cam.translate(vec3(0, 0, -1.1)); // - angle/1000 - //_cam.translate(vec3(0, 3, - angle/1000)); // - //_cam.rotateZ(30.0f + angle * 0.3456778); - - mat4 projectionViewMatrix = _cam.projectionViewMatrix; - - // ======== Model Matrix ================== - mat4 modelMatrix; - //modelMatrix.scale(0.1f); - //modelMatrix.rotatez(30.0f + angle * 0.3456778); - //modelMatrix.rotatey(25); - //modelMatrix.rotatex(15); - //modelMatrix.rotatey(angle); - //modelMatrix.rotatex(angle * 1.98765f); - - mat4 projectionViewModelMatrix = projectionViewMatrix * modelMatrix; - //Log.d("projectionViewModelMatrix: ", projectionViewModelMatrix.dump); - - //{ - // mat4 projection; - // projection.setPerspective(45.0f, cast(float)rc.width / rc.height, near, far); - // mat4 view; - // view.translate(translationX, translationY, translationZ); - // Log.d(" .viewMatrix.trans ", view.dump); - // view.rotateX(rotationX); - // Log.d(" .viewMatrix.rx ", view.dump); - // view.rotateY(rotationY); - // Log.d(" .viewMatrix.ry ", view.dump); - // view.rotateZ(rotationZ); - // Log.d(" .viewMatrix.rz ", view.dump); - // mat4 projectionView = projection * view; - // Log.d(" .projectionMatrix: ", projection.dump); - // Log.d(" .viewMatrix: ", view.dump); - // Log.d(" .projectionViewMatrix: ", projectionView.dump); - // Log.d(" .projectionViewMMatrix: ", (projectionView * modelMatrix).dump); - //} - - //{ - // import gl3n.linalg; - // static string dump(mat4 m) { - // m.transpose; - // return to!string(m[0]) ~ to!string(m[1]) ~ to!string(m[2]) ~ to!string(m[3]); - // } - // static float toRad(float angle) { return angle * 2 * PI / 360; } - // mat4 projection = mat4.perspective(rc.width, rc.height, 45.0f, near, far); - // mat4 view = mat4.identity.translate(translationX, translationY, translationZ).rotatex(toRad(rotationX)).rotatey(toRad(rotationY)).rotatez(toRad(rotationZ)); - // Log.d("gl3n.viewMatrix: tr ", dump(mat4.identity.translate(translationX, translationY, translationZ))); - // Log.d("gl3n.viewMatrix: rx ", dump(mat4.identity.translate(translationX, translationY, translationZ).rotatex(toRad(rotationX)))); - // Log.d("gl3n.viewMatrix: ry ", dump(mat4.identity.translate(translationX, translationY, translationZ).rotatex(toRad(rotationX)).rotatey(toRad(rotationY)))); - // Log.d("gl3n.viewMatrix: rz ", dump(mat4.identity.translate(translationX, translationY, translationZ).rotatex(toRad(rotationX)).rotatey(toRad(rotationY)).rotatez(toRad(rotationZ)))); - // mat4 projectionView = projection * view; - // Log.d("gl3n.projectionMatrix: ", dump(projection)); - // Log.d("gl3n.viewMatrix: ", dump(view)); - // Log.d("gl3n.projectionViewMatrix: ", dump(projectionView)); - // Log.d("gl3n.projectionViewMMatrix: ", dump(projectionView * mat4.identity)); - //} - - //projectionViewModelMatrix.setIdentity(); - //Log.d("matrix uniform: ", projectionViewModelMatrix.m); - checkgl!glEnable(GL_CULL_FACE); //checkgl!glDisable(GL_CULL_FACE); checkgl!glEnable(GL_DEPTH_TEST); @@ -404,19 +273,5 @@ class UiWidget : VerticalLayout, CellVisitor { } ~this() { - destroy(_world); } } - -class TestVisitor : CellVisitor { - //void newDirection(ref Position camPosition) { - // Log.d("TestVisitor.newDirection"); - //} - //void visitFace(World world, ref Position camPosition, Vector3d pos, cell_t cell, Dir face) { - // Log.d("TestVisitor.visitFace ", pos, " cell=", cell, " face=", face); - //} - void visit(World world, ref Position camPosition, Vector3d pos, cell_t cell, int visibleFaces) { - //Log.d("TestVisitor.visit ", pos, " cell=", cell); - } -} - diff --git a/examples/d3d/src/dminer/core/blocks.d b/examples/d3d/src/dminer/core/blocks.d deleted file mode 100644 index 3ce10bf4..00000000 --- a/examples/d3d/src/dminer/core/blocks.d +++ /dev/null @@ -1,287 +0,0 @@ -module dminer.core.blocks; - -import dminer.core.minetypes; -import dminer.core.world; -import dlangui.graphics.scene.mesh; - -immutable string BLOCK_TEXTURE_FILENAME = "blocks"; -immutable int BLOCK_TEXTURE_DX = 1024; -immutable int BLOCK_TEXTURE_DY = 1024; -immutable int BLOCK_SPRITE_SIZE = 16; -immutable int BLOCK_SPRITE_STEP = 16; -immutable int BLOCK_SPRITE_OFFSET = 0; -immutable int BLOCK_TEXTURE_SPRITES_PER_LINE = 1024/16; -immutable int VERTEX_COMPONENTS = 12; - -enum BlockVisibility { - INVISIBLE, - OPAQUE, // completely opaque (cells covered by this block are invisible) - OPAQUE_SEPARATE_TX, - HALF_OPAQUE, // partially paque, cells covered by this block can be visible, render as normal block - HALF_OPAQUE_SEPARATE_TX, - HALF_TRANSPARENT, // should be rendered last (semi transparent texture) -} - -class BlockDef { -public: - cell_t id; - string name; - BlockVisibility visibility = BlockVisibility.INVISIBLE; - int txIndex; - this() { - } - this(cell_t blockId, string blockName, BlockVisibility v, int tx) { - id = blockId; - name = blockName; - visibility = v; - txIndex = tx; - } - ~this() { - } - // blocks behind this block can be visible - @property bool canPass() { - return visibility == BlockVisibility.INVISIBLE - || visibility == BlockVisibility.HALF_OPAQUE - || visibility == BlockVisibility.HALF_OPAQUE_SEPARATE_TX - || visibility == BlockVisibility.HALF_TRANSPARENT; - } - // block is fully opaque (all blocks behind are invisible) - @property bool isOpaque() { - return visibility == BlockVisibility.OPAQUE - || visibility == BlockVisibility.OPAQUE_SEPARATE_TX; - } - // block is visible - @property bool isVisible() { - return visibility != BlockVisibility.INVISIBLE; - } - - @property bool terrainSmoothing() { - return false; - } - - /// create cube face - void createFace(World world, ref Position camPosition, Vector3d pos, Dir face, Mesh mesh) { - // default implementation - ushort startVertexIndex = cast(ushort)mesh.vertexCount; - float[VERTEX_COMPONENTS * 4] vptr; - ushort[6] iptr; - createFaceMesh(vptr.ptr, face, pos.x, pos.y, pos.z, txIndex); - for (int i = 0; i < 6; i++) - iptr[i] = cast(ushort)(startVertexIndex + face_indexes[i]); - //if (HIGHLIGHT_GRID && ((pos.x & 7) == 0 || (pos.z & 7) == 0)) { - // for (int i = 0; i < 4; i++) { - // vptr[11 * i + 6 + 0] = 1.4f; - // vptr[11 * i + 6 + 1] = 1.4f; - // vptr[11 * i + 6 + 2] = 1.4f; - // } - //} - mesh.addVertexes(vptr); - mesh.addPart(PrimitiveType.triangles, iptr); - } - /// create faces - void createFaces(World world, ref Position camPosition, Vector3d pos, int visibleFaces, Mesh mesh) { - for (int i = 0; i < 6; i++) - if (visibleFaces & (1 << i)) - createFace(world, camPosition, pos, cast(Dir)i, mesh); - } -} - -// pos, normal, color, tx -static const float[VERTEX_COMPONENTS * 4] face_vertices_north = -[ - -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, - 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, - -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, - 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -]; - -static const float[VERTEX_COMPONENTS * 4] face_vertices_south = -[ - -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, - 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, - -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, - 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -]; - -static const float[VERTEX_COMPONENTS * 4] face_vertices_west = -[ - -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, - -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, - -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, - -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 -]; - -static const float[VERTEX_COMPONENTS * 4] face_vertices_east = -[ - 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, - 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, - 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, - 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -]; - -static const float[VERTEX_COMPONENTS * 4] face_vertices_up = -[ - -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, - 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, - -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, - 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -]; - -static const float[VERTEX_COMPONENTS * 4] face_vertices_down = -[ - -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, - 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, - -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, - 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -]; - -static const ushort[6] face_indexes = -[ - 0, 1, 2, 2, 1, 3 -]; - -static const ushort[6] face_indexes_back = -[ - 0, 2, 1, 2, 3, 1 -]; - -static void fillFaceMesh(float * data, const float * src, float x0, float y0, float z0, int tileX, int tileY) { - for (int i = 0; i < 4; i++) { - const float * srcvertex = src + i * VERTEX_COMPONENTS; - float * dstvertex = data + i * VERTEX_COMPONENTS; - for (int j = 0; j < VERTEX_COMPONENTS; j++) { - float v = srcvertex[j]; - switch (j) { - case 0: // x - v += x0; - break; - case 1: // y - v += y0; - break; - case 2: // z - v += z0; - break; - case 10: // tx.u - v = ((tileX + v * BLOCK_SPRITE_SIZE)) / cast(float)BLOCK_TEXTURE_DX; - break; - case 11: // tx.v - //v = (BLOCK_TEXTURE_DY - (tileY + v * BLOCK_SPRITE_SIZE)) / cast(float)BLOCK_TEXTURE_DY; - v = ((tileY + v * BLOCK_SPRITE_SIZE)) / cast(float)BLOCK_TEXTURE_DY; - break; - default: - break; - } - dstvertex[j] = v; - } - } -} - -static void createFaceMesh(float * data, Dir face, float x0, float y0, float z0, int tileIndex) { - - int tileX = (tileIndex % BLOCK_TEXTURE_SPRITES_PER_LINE) * BLOCK_SPRITE_STEP + BLOCK_SPRITE_OFFSET; - int tileY = (tileIndex / BLOCK_TEXTURE_SPRITES_PER_LINE) * BLOCK_SPRITE_STEP + BLOCK_SPRITE_OFFSET; - // data is 11 comp * 4 vert floats - switch (face) with(Dir) { - default: - case NORTH: - fillFaceMesh(data, face_vertices_north.ptr, x0, y0, z0, tileX, tileY); - break; - case SOUTH: - fillFaceMesh(data, face_vertices_south.ptr, x0, y0, z0, tileX, tileY); - break; - case WEST: - fillFaceMesh(data, face_vertices_west.ptr, x0, y0, z0, tileX, tileY); - break; - case EAST: - fillFaceMesh(data, face_vertices_east.ptr, x0, y0, z0, tileX, tileY); - break; - case UP: - fillFaceMesh(data, face_vertices_up.ptr, x0, y0, z0, tileX, tileY); - break; - case DOWN: - fillFaceMesh(data, face_vertices_down.ptr, x0, y0, z0, tileX, tileY); - break; - } -} - - - -// block type definitions -__gshared BlockDef[256] BLOCK_DEFS; -// faster check for block->canPass() -__gshared bool[256] BLOCK_TYPE_CAN_PASS; -// faster check for block->isOpaque() -__gshared bool[256] BLOCK_TYPE_OPAQUE; -// faster check for block->isVisible() -__gshared bool[256] BLOCK_TYPE_VISIBLE; -// faster check for block->isVisible() -__gshared bool[256] BLOCK_TERRAIN_SMOOTHING; - -/// registers new block type -void registerBlockType(BlockDef def) { - if (BLOCK_DEFS[def.id]) { - if (BLOCK_DEFS[def.id] is def) - return; - destroy(BLOCK_DEFS[def.id]); - } - BLOCK_DEFS[def.id] = def; - // init property shortcuts - BLOCK_TYPE_CAN_PASS[def.id] = def.canPass; - BLOCK_TYPE_OPAQUE[def.id] = def.isOpaque; - BLOCK_TYPE_VISIBLE[def.id] = def.isVisible; - BLOCK_TERRAIN_SMOOTHING[def.id] = def.terrainSmoothing; -} - -enum BlockImage : int { - stone, - grass_top, - grass_side, - grass_top_footsteps, - dirt, - bedrock, - sand, - gravel, - sandstone, - clay, - cobblestone, - cobblestone_mossy, - brick, - stonebrick, - red_sand, -} - -/// init block types array -__gshared static this() { - import std.string; - for (int i = 0; i < 256; i++) { - if (!BLOCK_DEFS[i]) { - registerBlockType(new BlockDef(cast(cell_t)i, "undef%d".format(i), BlockVisibility.INVISIBLE, 0)); - } - } - BLOCK_TYPE_CAN_PASS[BOUND_SKY] = false; - BLOCK_TYPE_VISIBLE[BOUND_SKY] = false; - BLOCK_TYPE_CAN_PASS[BOUND_BOTTOM] = false; - BLOCK_TYPE_VISIBLE[BOUND_BOTTOM] = true; - - // empty cell - registerBlockType(new BlockDef(0, "empty", BlockVisibility.INVISIBLE, 0)); - // standard block types - registerBlockType(new BlockDef(1, "gray_brick", BlockVisibility.OPAQUE, BlockImage.stonebrick)); - registerBlockType(new BlockDef(2, "brick", BlockVisibility.OPAQUE, BlockImage.brick)); - registerBlockType(new BlockDef(3, "bedrock", BlockVisibility.OPAQUE, BlockImage.bedrock)); - registerBlockType(new BlockDef(4, "clay", BlockVisibility.OPAQUE, BlockImage.clay)); - registerBlockType(new BlockDef(5, "cobblestone", BlockVisibility.OPAQUE, BlockImage.cobblestone)); - registerBlockType(new BlockDef(6, "gravel", BlockVisibility.OPAQUE, BlockImage.gravel)); - registerBlockType(new BlockDef(7, "red_sand", BlockVisibility.OPAQUE, BlockImage.red_sand)); - registerBlockType(new BlockDef(8, "sand", BlockVisibility.OPAQUE, BlockImage.sand)); - - registerBlockType(new BlockDef(50, "box", BlockVisibility.HALF_OPAQUE, 50)); - - //registerBlockType(new TerrainBlock(100, "terrain_bedrock", 2)); - //registerBlockType(new TerrainBlock(101, "terrain_clay", 3)); - //registerBlockType(new TerrainBlock(102, "terrain_cobblestone", 4)); - //registerBlockType(new TerrainBlock(103, "terrain_gravel", 5)); - //registerBlockType(new TerrainBlock(104, "terrain_red_sand", 6)); - //registerBlockType(new TerrainBlock(105, "terrain_sand", 7)); - -} diff --git a/examples/d3d/src/dminer/core/minetypes.d b/examples/d3d/src/dminer/core/minetypes.d deleted file mode 100644 index 6f326f40..00000000 --- a/examples/d3d/src/dminer/core/minetypes.d +++ /dev/null @@ -1,731 +0,0 @@ -module dminer.core.minetypes; - -alias cell_t = ubyte; - -immutable cell_t NO_CELL = 0; -immutable cell_t END_OF_WORLD = 253; -immutable cell_t VISITED_CELL = 255; -immutable cell_t VISITED_OCCUPIED = 254; - -immutable cell_t BOUND_BOTTOM = 253; -immutable cell_t BOUND_SKY = 252; - -enum Dir : ubyte { - NORTH = 0, - SOUTH, - EAST, - WEST, - UP, - DOWN, -} - -// 26 direction masks based on Dir -enum DirMask : ubyte { - MASK_NORTH = (1 << Dir.NORTH), - MASK_SOUTH = (1 << Dir.SOUTH), - MASK_EAST = (1 << Dir.EAST), - MASK_WEST = (1 << Dir.WEST), - MASK_UP = (1 << Dir.UP), - MASK_DOWN = (1 << Dir.DOWN), - MASK_ALL = 0x3F, - //MASK_WEST_UP = (1 << Dir.WEST) | MASK_UP, - //MASK_EAST_UP = (1 << Dir.EAST) | MASK_UP, - //MASK_WEST_DOWN = (1 << Dir.WEST) | MASK_DOWN, - //MASK_EAST_DOWN = (1 << Dir.EAST) | MASK_DOWN, - //MASK_NORTH_WEST = MASK_NORTH | MASK_WEST, - //MASK_NORTH_EAST = MASK_NORTH | MASK_EAST, - //MASK_NORTH_UP = MASK_NORTH | MASK_UP, - //MASK_NORTH_DOWN = MASK_NORTH | MASK_DOWN, - //MASK_NORTH_WEST_UP = MASK_NORTH | MASK_WEST | MASK_UP, - //MASK_NORTH_EAST_UP = MASK_NORTH | MASK_EAST | MASK_UP, - //MASK_NORTH_WEST_DOWN = MASK_NORTH | MASK_WEST | MASK_DOWN, - //MASK_NORTH_EAST_DOWN = MASK_NORTH | MASK_EAST | MASK_DOWN, - //MASK_SOUTH_WEST = MASK_SOUTH | MASK_WEST, - //MASK_SOUTH_EAST = MASK_SOUTH | MASK_EAST, - //MASK_SOUTH_UP = MASK_SOUTH | MASK_UP, - //MASK_SOUTH_DOWN = MASK_SOUTH | MASK_DOWN, - //MASK_SOUTH_WEST_UP = MASK_SOUTH | MASK_WEST | MASK_UP, - //MASK_SOUTH_EAST_UP = MASK_SOUTH | MASK_EAST | MASK_UP, - //MASK_SOUTH_WEST_DOWN = MASK_SOUTH | MASK_WEST | MASK_DOWN, - //MASK_SOUTH_EAST_DOWN = MASK_SOUTH | MASK_EAST | MASK_DOWN, -} - -struct Vector2d { - int x; - int y; - this(int xx, int yy) { - x = xx; - y = yy; - } - //bool opEqual(Vector2d v) const { - // return x == v.x && y == v.y; - //} -} - -immutable Vector2d ZERO2 = Vector2d(0, 0); - -struct Vector3d { - int x; - int y; - int z; - this(int xx, int yy, int zz) { - x = xx; - y = yy; - z = zz; - } - //bool opEqual(const Vector3d v) const { - // return x == v.x && y == v.y && z == v.z; - //} - - /// returns vector with all components which are negative of components for this vector - Vector3d opUnary(string op : "-")() const { - return Vector3d(-x, -y, -z); - } - /// subtract vectors - Vector3d opBinary(string op : "-")(const Vector3d v) const { - return Vector3d(x - v.x, y - v.y, z - v.z); - } - /// add vectors - Vector3d opBinary(string op : "+")(const Vector3d v) const { - return Vector3d(x + v.x, y + v.y, z + v.z); - } - /// - int opBinary(string op : "*")(const Vector3d v) const { - return x*v.x + y*v.y + z*v.z; - } - /// multiply vector elements by constant - Vector3d opBinary(string op : "*")(int n) const { - return Vector3d(x * n, y * n, z * n); - } - - /// - ref Vector3d opOpAssign(string op : "+")(const Vector3d v) { - x += v.x; - y += v.y; - z += v.z; - return this; - } - /// - ref Vector3d opOpAssign(string op : "-")(const Vector3d v) { - x -= v.x; - y -= v.y; - z -= v.z; - return this; - } - /// - ref Vector3d opOpAssign(string op : "*")(int n) { - x *= n; - y *= n; - z *= n; - return this; - } - Vector3d turnLeft() { - return Vector3d(z, y, -x); - } - Vector3d turnRight() { - return Vector3d(-z, y, x); - } - Vector3d turnUp() { - return Vector3d(x, -z, y); - } - Vector3d turnDown() { - return Vector3d(x, z, -y); - } - Vector3d move(Dir dir) { - Vector3d res = this; - switch (dir) with(Dir) { - case NORTH: - res.z--; - break; - case SOUTH: - res.z++; - break; - case WEST: - res.x--; - break; - case EAST: - res.x++; - break; - case UP: - res.y++; - break; - case DOWN: - res.y--; - break; - default: - break; - } - return res; - } -} - -const Vector3d ZERO3 = Vector3d(0, 0, 0); - -struct Array(T) { -private: - int _length; - T[] _data; -public: - T * ptr(int index = 0) { - return _data.ptr + index; - } - void swap(ref Array v) { - int tmp; - tmp = _length; _length = v._length; v._length = tmp; - T[] ptmp; - ptmp = _data; _data = v._data; v._data = ptmp; - } - /// ensure capacity is enough to fit sz items - void reserve(int sz) { - sz += _length; - if (_data.length < sz) { - int oldsize = cast(int)_data.length; - int newsize = 1024; - while (newsize < sz) - newsize <<= 1; - _data.length = newsize; - for (int i = oldsize; i < newsize; i++) - _data.ptr[i] = T.init; - _data.assumeSafeAppend(); - } - } - @property int length() { - return _length; - } - /// append single item by ref - void append(ref const T value) { - if (_length >= _data.length) - reserve(cast(int)(_data.length == 0 ? 64 : _data.length * 2 - _length)); - _data.ptr[_length++] = value; - } - /// append single item by value - void append(T value) { - if (_length >= _data.length) - reserve(cast(int)(_data.length == 0 ? 64 : _data.length * 2 - _length)); - _data.ptr[_length++] = value; - } - /// append single item w/o check - void appendNoCheck(ref const T value) { - _data.ptr[_length++] = value; - } - /// append single item w/o check - void appendNoCheck(T value) { - _data.ptr[_length++] = value; - } - /// appends same value several times, return pointer to appended items - T* append(ref const T value, int count) { - reserve(count); - int startLen = _length; - for (int i = 0; i < count; i++) - _data.ptr[_length++] = value; - return _data.ptr + startLen; - } - /// appends same value several times, return pointer to appended items - T* append(T value, int count) { - reserve(count); - int startLen = _length; - for (int i = 0; i < count; i++) - _data.ptr[_length++] = value; - return _data.ptr + startLen; - } - void clear() { - _length = 0; - } - T get(int index) { - return _data.ptr[index]; - } - void set(int index, T value) { - _data.ptr[index] = value; - } - ref T opIndex(int index) { - return _data.ptr[index]; - } -} - -alias FloatArray = Array!(float); -alias IntArray = Array!(int); -alias CellArray = Array!(cell_t); -alias Vector2dArray = Array!(Vector2d); -alias Vector3dArray = Array!(Vector3d); - -/// array with support of both positive and negative indexes -struct InfiniteArray(T) { -private: - T[] dataPlus; - T[] dataMinus; - int minIdx; - int maxIdx; -public: - @property int minIndex() { return minIdx; } - @property int maxIndex() { return maxIdx; } - void disposeFunction(T p) { - destroy(p); - } - ~this() { - foreach(p; dataPlus) - if (p !is T.init) - disposeFunction(p); - foreach(p; dataMinus) - if (p !is T.init) - disposeFunction(p); - } - T get(int index) { - if (index >= 0) { - if (index >= maxIdx) - return T.init; - return dataPlus[index]; - } else { - if (index <= minIdx) - return T.init; - return dataMinus[-index]; - } - } - void set(int index, T value) { - if (index >= 0) { - if (index >= maxIdx) { - // extend array - if (index <= dataPlus.length) { - int oldsize = dataPlus.length; - int newsize = 1024; - while (newsize <= index) - newsize <<= 1; - dataPlus.length = newsize; - dataPlus.assumeSafeAppend; - for(int i = oldsize; i < newsize; i++) - dataPlus[i] = T.init; - } - maxIdx = index + 1; - } - if (dataPlus[index] !is T.init && dataPlus[index] !is value) - disposeFunction(dataPlus[index]); - dataPlus[index] = value; - } else { - if (index <= minIdx) { - // extend array - if (-index <= dataMinus.length) { - int oldsize = dataMinus.length; - int newsize = 1024; - while (newsize <= -index) - newsize <<= 1; - dataMinus.length = newsize; - dataMinus.assumeSafeAppend; - for(int i = oldsize; i < newsize; i++) - dataMinus[i] = T.init; - } - maxIdx = index - 1; - } - if (dataMinus[-index] !is T.init && dataMinus[-index] !is value) - disposeFunction(dataMinus[-index]); - dataMinus[-index] = value; - } - } -} - -struct InfiniteMatrix(T) { -private: - int _size = 0; - int _sizeShift = 0; - int _sizeShiftMul2 = 0; - int _sizeMask = 0; - int _invSizeMask = 0; - T[] _data; - void resize(int newSizeShift) { - int newSize = (1<= newSize || y < -newSize || y >= newSize) { - // destory: // outside new size - destroy(v); - } else { - // move - newdata[((y + newSize) << (newSizeShift + 1)) | (x + newSize)] = v; - } - } - } - _data = newdata; - _size = newSize; - _sizeShift = newSizeShift; - _sizeShiftMul2 = _sizeShift + 1; - _sizeMask = (1 << _sizeShiftMul2) - 1; - _invSizeMask = ~_sizeMask; - } - int calcIndex(int x, int y) { - return (y << _sizeShiftMul2) + x; - } -public: - @property int size() { return _size; } - T get(int x, int y) { - if (!_data) - return null; - x += _size; - y += _size; - if (!((x | y) & ~_sizeMask)) { - return _data.ptr[(y << _sizeShiftMul2) + x]; //calcIndex(x, y) - } - return null; - } - void set(int x, int y, T v) { - if (x < -_size || x >= _size || y < -_size || y >= _size) { - int newSizeShift = _sizeShift < 6 ? 6 : _sizeShift + 1; - for (; ;newSizeShift++) { - int sz = 1 << newSizeShift; - if (x < -sz || x >= sz || y < -sz || y >= sz) - continue; - break; - } - resize(newSizeShift); - } - x += _size; - y += _size; - int index = calcIndex(x, y); - if (_data.ptr[index]) - destroy(_data.ptr[index]); - _data.ptr[index] = v; - } - ~this() { - foreach(ref v; _data) - if (v) - destroy(v); - } -} - -struct Position { - Vector3d pos; - Direction direction; - this(ref Position p) { - pos = p.pos; - direction = p.direction; - } - this(Vector3d position, Vector3d dir) { - pos = position; - direction = dir; - } - Vector2d calcPlaneCoords(Vector3d v) { - v = v - pos; - switch (direction.dir) with(Dir) { - default: - case NORTH: - return Vector2d(v.x, v.y); - case SOUTH: - return Vector2d(-v.x, v.y); - case EAST: - return Vector2d(v.z, v.y); - case WEST: - return Vector2d(-v.z, v.y); - case UP: - return Vector2d(-v.z, v.x); - case DOWN: - return Vector2d(v.z, v.x); - } - } - void turnLeft() { - direction.turnLeft(); - } - void turnRight() { - direction.turnRight(); - } - void shiftLeft(int step = 1) { - pos += direction.left * step; - } - void shiftRight(int step = 1) { - pos += direction.right * step; - } - void turnUp() { - direction.turnUp(); - } - void turnDown() { - direction.turnDown(); - } - void forward(int step = 1) { - pos += direction.forward * step; - } - void backward(int step = 1) { - pos -= direction.forward * step; - } - void moveUp(int step = 1) { - pos += direction.up * step; - } - void moveDown(int step = 1) { - pos += direction.down * step; - } - void moveLeft(int step = 1) { - pos += direction.left * step; - } - void moveRight(int step = 1) { - pos += direction.right * step; - } -} - - -/// returns opposite direction to specified direction -Dir opposite(Dir d) { - return cast(Dir)(d ^ 1); -} - -Dir turnLeft(Dir d) { - switch (d) with (Dir) { - case WEST: - return SOUTH; - case EAST: - return NORTH; - default: - case NORTH: - return WEST; - case SOUTH: - return EAST; - case UP: - return SOUTH; - case DOWN: - return NORTH; - } -} - -Dir turnRight(Dir d) { - switch (d) with (Dir) { - case WEST: - return NORTH; - case EAST: - return SOUTH; - default: - case NORTH: - return EAST; - case SOUTH: - return WEST; - case UP: - return NORTH; - case DOWN: - return SOUTH; - } -} - -Dir turnUp(Dir d) { - switch (d) with (Dir) { - case WEST: - return UP; - case EAST: - return UP; - default: - case NORTH: - return UP; - case SOUTH: - return UP; - case UP: - return SOUTH; - case DOWN: - return NORTH; - } -} - -Dir turnDown(Dir d) { - switch (d) with (Dir) { - case WEST: - return DOWN; - case EAST: - return DOWN; - default: - case NORTH: - return DOWN; - case SOUTH: - return DOWN; - case UP: - return NORTH; - case DOWN: - return SOUTH; - } -} - - -struct Direction { - this(int x, int y, int z) { - set(x, y, z); - } - this(Vector3d v) { - set(v); - } - this(Dir d) { - set(d); - } - /// returns Y axis rotation angle in degrees (0, 90, 180, 270) - @property float angle() { - switch (dir) with (Dir) { - default: - case NORTH: - return 0; - case SOUTH: - return 180; - case WEST: - return 90; - case EAST: - return 270; - case UP: - case DOWN: - return 0; - } - } - /// set by direction code - void set(Dir d) { - switch (d) with (Dir) { - default: - case NORTH: - set(0, 0, -1); - break; - case SOUTH: - set(0, 0, 1); - break; - case WEST: - set(-1, 0, 0); - break; - case EAST: - set(1, 0, 0); - break; - case UP: - set(0, 1, 0); - break; - case DOWN: - set(0, -1, 0); - break; - } - } - /// set by vector - void set(Vector3d v) { set(v.x, v.y, v.z); } - /// set by vector - void set(int x, int y, int z) { - forward = Vector3d(x, y, z); - if (x) { - dir = (x > 0) ? Dir.EAST : Dir.WEST; - } - else if (y) { - dir = (y > 0) ? Dir.UP : Dir.DOWN; - } - else { - dir = (z > 0) ? Dir.SOUTH : Dir.NORTH; - } - switch (dir) with (Dir) { - case UP: - up = Vector3d(1, 0, 0); - left = Vector3d(0, 0, 1); - break; - case DOWN: - up = Vector3d(1, 0, 0); - left = Vector3d(0, 0, -1); - break; - default: - case NORTH: - up = Vector3d(0, 1, 0); - left = Vector3d(-1, 0, 0); - break; - case SOUTH: - up = Vector3d(0, 1, 0); - left = Vector3d(1, 0, 0); - break; - case EAST: - up = Vector3d(0, 1, 0); - left = Vector3d(0, 0, -1); - break; - case WEST: - up = Vector3d(0, 1, 0); - left = Vector3d(0, 0, 1); - break; - } - down = -up; - right = -left; - forwardUp = forward + up; - forwardDown = forward + down; - forwardLeft = forward + left; - forwardLeftUp = forward + left + up; - forwardLeftDown = forward + left + down; - forwardRight = forward + right; - forwardRightUp = forward + right + up; - forwardRightDown = forward + right + down; - } - - void turnLeft() { - set(.turnLeft(dir)); - } - void turnRight() { - set(.turnRight(dir)); - } - void turnUp() { - set(.turnUp(dir)); - } - void turnDown() { - set(.turnDown(dir)); - } - - Dir dir; - Vector3d forward; - Vector3d up; - Vector3d right; - Vector3d left; - Vector3d down; - Vector3d forwardUp; - Vector3d forwardDown; - Vector3d forwardLeft; - Vector3d forwardLeftUp; - Vector3d forwardLeftDown; - Vector3d forwardRight; - Vector3d forwardRightUp; - Vector3d forwardRightDown; -} - -/// returns number of bits to store integer -int bitsFor(int n) { - int res; - for (res = 0; n > 0; res++) - n >>= 1; - return res; -} - -/// returns 0 for 0, 1 for negatives, 2 for positives -int mySign(int n) { - if (n > 0) - return 1; - else if (n < 0) - return -1; - else - return 0; -} - -immutable ulong RANDOM_MULTIPLIER = 0x5DEECE66D; -immutable ulong RANDOM_MASK = ((cast(ulong)1 << 48) - 1); -immutable ulong RANDOM_ADDEND = cast(ulong)0xB; - -struct Random { - ulong seed; - //Random(); - void setSeed(ulong value) { - seed = (value ^ RANDOM_MULTIPLIER) & RANDOM_MASK; - } - - int next(int bits) { - seed = (seed * RANDOM_MULTIPLIER + RANDOM_ADDEND) & RANDOM_MASK; - return cast(int)(seed >> (48 - bits)); - } - - int nextInt() { - return next(31); - } - int nextInt(int n) { - if ((n & -n) == n) // i.e., n is a power of 2 - return cast(int)((n * cast(long)next(31)) >> 31); - int bits, val; - do { - bits = next(31); - val = bits % n; - } while (bits - val + (n - 1) < 0); - return val; - } -} - -const Vector3d[6] DIRECTION_VECTORS = [ - Vector3d(0, 0, -1), - Vector3d(0, 0, 1), - Vector3d(-1, 0, 0), - Vector3d(1, 0, 0), - Vector3d(0, 1, 0), - Vector3d(0, -1, 0) -]; diff --git a/examples/d3d/src/dminer/core/terrain.d b/examples/d3d/src/dminer/core/terrain.d deleted file mode 100644 index 2310200d..00000000 --- a/examples/d3d/src/dminer/core/terrain.d +++ /dev/null @@ -1,153 +0,0 @@ -module dminer.core.terrain; - -import dminer.core.minetypes; - - -struct TerrainGen { - private int dx; - private int dy; - private int xpow; - private int ypow; - private short[] data; - private Random rnd; - private void diamond(int x, int y, int size, int offset) { - int avg = (get(x, y - size) + get(x + size, y) + get(x, y + size) + get(x - size, y)) >> 2; - set(x, y, avg + offset); - } - private void square(int x, int y, int size, int offset) { - int avg = (get(x - size, y - size) + get(x + size, y - size) + get(x - size, y + size) + get(x - size, y - size)) >> 2; - set(x, y, avg + offset); - } - - this(int xbits, int zbits) { - xpow = xbits; - ypow = zbits; - dx = (1 << xpow) + 1; - dy = (1 << ypow) + 1; - data = new short[dx * dy]; - } - ~this() { - } - void filter(int range) { - short[] tmp = new short[dx * dy]; - int div = (range * 2 + 1) * (range * 2 + 1); - for (int y = 0; y < dy; y++) { - for (int x = 0; x < dx; x++) { - int s = 0; - for (int yy = -range; yy <= range; yy++) { - for (int xx = -range; xx <= range; xx++) { - s += get(x + xx, y + yy); - } - } - s /= div; - tmp[(y << ypow) + y + x] = cast(short)s; - } - } - int sz = dx * dy; - data[0 .. sz] = tmp[0 .. sz]; - } - - void generate(int seed, short[] initData, int stepBits) { - rnd.setSeed(seed); - int step = 1 << stepBits; - int index = 0; - for (int y = 0; y <= dy; y += step) { - for (int x = 0; x <= dx; x += step) { - set(x, y, initData[index++]); - } - } - int half = step >> 1; - while (half > 0) { - int scale = step; - for (int y = half; y < dy; y += step) { - for (int x = half; x < dx; x++) { - square(x, y, half, rnd.nextInt(scale * 2) - scale); - } - } - for (int y = 0; y <= dy; y += half) { - for (int x = (y + half) % step; x <= dx; x += step) { - diamond(x, y, half, rnd.nextInt(scale * 2) - scale); - } - } - step >>= 1; - half >>= 1; - } - } - void generateWithScale(int seed, short[] initData, int stepBits, TerrainGen scaleMap) { - rnd.setSeed(seed); - int step = 1 << stepBits; - int index = 0; - for (int y = 0; y <= dy; y += step) { - for (int x = 0; x <= dx; x += step) { - set(x, y, initData[index++]); - } - } - int half = step >> 1; - while (half > 0) { - for (int y = half; y < dy; y += step) { - for (int x = half; x < dx; x++) { - int scale = (scaleMap.get(x, y) * step) >> 8; - scale = rnd.nextInt(scale * 2) - scale; - if (step < 4) - scale = 0; - square(x, y, half, scale); - } - } - for (int y = 0; y <= dy; y += half) { - for (int x = (y + half) % step; x <= dx; x += step) { - int scale = (scaleMap.get(x, y) * step) >> 8; - scale = rnd.nextInt(scale * 2) - scale; - if (step < 4) - scale = 0; - diamond(x, y, half, scale); - } - } - step >>= 1; - half >>= 1; - } - } - @property int width() { - return dx - 1; - } - @property int height() { - return dy - 1; - } - int get(int x, int y) { - if (x < 0 || y < 0 || x >= dx || y >= dy) - return 0; - return data[(y << ypow) + y + x]; - } - void set(int x, int y, int value) { - if (x < 0 || y < 0 || x >= dx || y >= dy) - return; - if (value < -32767) - value = -32767; - if (value > 32767) - value = 32767; - data[(y << ypow) + y + x] = cast(short)value; - } - /// ensure that data is in range [minvalue, maxvalue] - void limit(int minvalue, int maxvalue) { - // find actual min/max - int minv, maxv; - minv = maxv = get(0, 0); - for (int y = 0; y <= dy; y++) { - for (int x = 0; x <= dx; x++) { - int v = get(x, y); - if (minv > v) - minv = v; - if (maxv < v) - maxv = v; - } - } - int mul = (maxvalue - minvalue); - int div = (maxv - minv); - if (div > 0) { - for (int y = 0; y <= dy; y++) { - for (int x = 0; x <= dx; x++) { - set(x, y, minvalue + (get(x, y) - minv) * mul / div); - } - } - } - } -} diff --git a/examples/d3d/src/dminer/core/world.d b/examples/d3d/src/dminer/core/world.d deleted file mode 100644 index 024c46a6..00000000 --- a/examples/d3d/src/dminer/core/world.d +++ /dev/null @@ -1,501 +0,0 @@ -module dminer.core.world; - -import dminer.core.minetypes; -import dminer.core.blocks; - -const int MAX_VIEW_DISTANCE_BITS = 8; -const int MAX_VIEW_DISTANCE = (1 << MAX_VIEW_DISTANCE_BITS); - -// Layer is 16x16 (CHUNK_DX_SHIFT x CHUNK_DX_SHIFT) cells -immutable int CHUNK_DX_SHIFT = 4; -immutable int CHUNK_DX = (1< bottomLayer) - minLayer = bottomLayer; - if (maxLayer == -1 || maxLayer < topLayer) - maxLayer = topLayer; - } - cell_t get(int x, int y, int z) { - //if (!this) - // return NO_CELL; - ChunkLayer * layer = layers[y & CHUNK_DY_MASK]; - if (!layer) - return NO_CELL; - return layer.get(x & CHUNK_DX_MASK, z & CHUNK_DY_MASK); - } - - /// get, x, y, z are already checked for bounds - cell_t getNoCheck(int x, int y, int z) { - ChunkLayer * layer = layers.ptr[y]; - if (!layer) // likely - return NO_CELL; - return layer.cells.ptr[(z << CHUNK_DX_SHIFT) + x]; // inlined return layer.get(x, z); - } - - void set(int x, int y, int z, cell_t cell) { - int layerIndex = y & CHUNK_DY_MASK; - ChunkLayer * layer = layers.ptr[layerIndex]; - if (!layer) { - layer = new ChunkLayer(); - layers.ptr[layerIndex] = layer; - if (topLayer == -1 || topLayer < layerIndex) - topLayer = layerIndex; - if (bottomLayer == -1 || bottomLayer > layerIndex) - bottomLayer = layerIndex; - } - layer.set(x & CHUNK_DX_MASK, z & CHUNK_DY_MASK, cell); - } - - /// srcpos coords x, z are in chunk bounds - //void getCells(Vector3d srcpos, Vector3d dstpos, Vector3d size, VolumeData & buf); -} - -alias ChunkMatrix = InfiniteMatrix!(Chunk *); - -/// Voxel World -class World { -private: - Position _camPosition; - int maxVisibleRange = MAX_VIEW_DISTANCE; - ChunkMatrix chunks; - DiamondVisitor visitorHelper; -public: - this() { - _camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1)); - } - ~this() { - } - @property final ref Position camPosition() { return _camPosition; } - - final cell_t getCell(int x, int y, int z) { - if (!(y & CHUNK_DY_INV_MASK)) { - if (Chunk * p = chunks.get(x >> CHUNK_DX_SHIFT, z >> CHUNK_DX_SHIFT)) - return p.getNoCheck(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK); - return NO_CELL; - } - // y out of bounds - if (y < 0) - return BOUND_BOTTOM; - //if (y >= CHUNK_DY) - else - return BOUND_SKY; - } - - final bool isOpaque(int x, int y, int z) { - cell_t cell = getCell(x, y, z); - return BLOCK_TYPE_OPAQUE.ptr[cell] && cell != BOUND_SKY; - } - - final void setCell(int x, int y, int z, cell_t value) { - int chunkx = x >> CHUNK_DX_SHIFT; - int chunkz = z >> CHUNK_DX_SHIFT; - Chunk * p = chunks.get(chunkx, chunkz); - if (!p) { - p = new Chunk(); - chunks.set(chunkx, chunkz, p); - } - p.set(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK, value); - } - - void setCellRange(Vector3d pos, Vector3d sz, cell_t value) { - for (int x = 0; x < sz.x; x++) - for (int y = 0; y < sz.y; y++) - for (int z = 0; z < sz.z; z++) - setCell(pos.x + x, pos.y + y, pos.z + z, value); - } - - bool canPass(Vector3d pos) { - return canPass(Vector3d(pos.x - 2, pos.y - 3, pos.z - 2), Vector3d(4, 5, 4)); - } - - bool canPass(Vector3d pos, Vector3d size) { - for (int x = 0; x <= size.x; x++) - for (int z = 0; z <= size.z; z++) - for (int y = 0; y < size.y; y++) { - if (isOpaque(pos.x + x, pos.y + y, pos.z + z)) - return false; - } - return true; - } - final void visitVisibleCells(ref Position position, CellVisitor visitor) { - visitorHelper.init(this, - &position, - visitor); - visitorHelper.visitAll(maxVisibleRange); - } -} - -interface CellVisitor { - //void newDirection(ref Position camPosition); - //void visitFace(World world, ref Position camPosition, Vector3d pos, cell_t cell, Dir face); - void visit(World world, ref Position camPosition, Vector3d pos, cell_t cell, int visibleFaces); -} - -struct DiamondVisitor { - int maxDist; - int maxDistBits; - int dist; - World world; - Position * position; - Vector3d pos0; - CellVisitor visitor; - CellArray visited; - cell_t * visited_ptr; - Vector3dArray oldcells; - Vector3dArray newcells; - ubyte visitedId; - //ubyte visitedEmpty; - int m0; - int m0mask; - void init(World w, Position * pos, CellVisitor v) { - world = w; - position = pos; - visitor = v; - pos0 = position.pos; - } - void visitCell(int vx, int vy, int vz) { - //CRLog::trace("visitCell(%d %d %d) dist=%d", v.x, v.y, v.z, myAbs(v.x) + myAbs(v.y) + myAbs(v.z)); - - //int occupied = visitedOccupied; - int index = (vx + m0) + ((vz + m0) << (maxDistBits + 1)); - if (vy < 0) { - // inverse index for lower half - index ^= m0mask; - } - //int index = diamondIndex(v, maxDistBits); - if (visited_ptr[index] == visitedId)// || cell == visitedEmpty) - return; - visitCellNoCheck(vx, vy, vz); - visited_ptr[index] = visitedId; // cell; - } - - void visitCellNoCheck(int vx, int vy, int vz) { - //if (v * position.direction.forward < dist / 3) // limit by visible from cam - // return; - //Vector3d pos = pos0 + v; - int posx = pos0.x + vx; - int posy = pos0.y + vy; - int posz = pos0.z + vz; - cell_t cell = world.getCell(posx, posy, posz); - - // read cell from world - if (BLOCK_TYPE_VISIBLE.ptr[cell]) { - int visibleFaces = 0; - if (vy <= 0 && !world.isOpaque(posx, posy + 1, posz)) - visibleFaces |= DirMask.MASK_UP; - if (vy >= 0 && !world.isOpaque(posx, posy - 1, posz)) - visibleFaces |= DirMask.MASK_DOWN; - if (vx <= 0 && !world.isOpaque(posx + 1, posy, posz)) - visibleFaces |= DirMask.MASK_EAST; - if (vx >= 0 && !world.isOpaque(posx - 1, posy, posz)) - visibleFaces |= DirMask.MASK_WEST; - if (vz <= 0 && !world.isOpaque(posx, posy, posz + 1)) - visibleFaces |= DirMask.MASK_SOUTH; - if (vz >= 0 && !world.isOpaque(posx, posy, posz - 1)) - visibleFaces |= DirMask.MASK_NORTH; - visitor.visit(world, *position, Vector3d(posx, posy, posz), cell, visibleFaces); - } - // mark as visited - if (BLOCK_TYPE_CAN_PASS.ptr[cell]) - newcells.append(Vector3d(vx, vy, vz)); - //cell = BLOCK_TYPE_CAN_PASS[cell] ? visitedEmpty : visitedOccupied; - } - - bool needVisit(int index) { - if (visited_ptr[index] != visitedId) { - visited_ptr[index] = visitedId; - return true; - } - return false; - } - - static int myAbs(int n) { - return n < 0 ? -n : n; - } - - void visitAll(int maxDistance) { - maxDist = maxDistance; - maxDistance *= 2; - maxDistBits = bitsFor(maxDist); - int maxDistMask = ~((1 << maxDistBits) - 1); - maxDistBits++; - - m0 = 1 << maxDistBits; - m0mask = (m0 - 1) + ((m0 - 1) << (maxDistBits + 1)); - - oldcells.clear(); - newcells.clear(); - oldcells.reserve(maxDist * 4 * 4); - newcells.reserve(maxDist * 4 * 4); - - dist = 1; - - int vsize = ((1 << maxDistBits) * (1 << maxDistBits)) << 2; - visited.clear(); - visited.append(cast(ubyte)0, vsize); - visited_ptr = visited.ptr(); - visitedId = 2; - oldcells.clear(); - oldcells.append(Vector3d(0, 0, 0)); - Dir dir = position.direction.dir; - - int zstep = 1 << (maxDistBits + 1); - for (; dist < maxDistance; dist++) { - // for each distance - if (oldcells.length() == 0) { // no cells to pass through - import dlangui.core.logger; - Log.d("No more cells at distance ", dist); - break; - } - newcells.clear(); - visitedId++; - int maxUp = (((dist + 1) * 7) / 8) + 1; - int maxDown = - (dist < 3 ? 3 : (((dist + 1) * 7) / 8)) - 1; - //CRLog::trace("dist: %d cells: %d", dist, oldcells.length()); - for (int i = 0; i < oldcells.length(); i++) { - Vector3d pt = oldcells[i]; - assert(myAbs(pt.x) + myAbs(pt.y) + myAbs(pt.z) == dist - 1); - if (((pt.x + maxDist) | (pt.y + maxDist) | (pt.z + maxDist)) & maxDistMask) - continue; - if (dist > 2) { - // skip some directions - if (pt.y > maxUp || pt.y < maxDown) - continue; - if (dir == Dir.SOUTH) { - if (pt.z < -1) - continue; - } else if (dir == Dir.NORTH) { - if (pt.z > 1) - continue; - } else if (dir == Dir.EAST) { - if (pt.x < -1) - continue; - } else { // WEST - if (pt.x > 1) - continue; - } - } - int mx = pt.x; - int my = pt.y; - int mz = pt.z; - int sx = mx > 0 ? 1 : 0; - int sy = my > 0 ? 1 : 0; - int sz = mz > 0 ? 1 : 0; - if (mx < 0) { - mx = -mx; - sx = -1; - } - if (my < 0) { - my = -my; - sy = -1; - } - if (mz < 0) { - mz = -mz; - sz = -1; - } - int ymask = sy < 0 ? m0mask : 0; - int index = ((pt.x + m0) + ((pt.z + m0) << (maxDistBits + 1))) ^ ymask; - if (sx && sy && sz) { - //bool noStepZ = (mx > mz) || (my > mz); - // 1, 1, 1 - int xindex = index + (sy < 0 ? -sx : sx); - if (visited_ptr[xindex] != visitedId) { - visitCellNoCheck(pt.x + sx, pt.y, pt.z); - visited_ptr[xindex] = visitedId; - } - int zindex = index + (sz * sy > 0 ? zstep : -zstep); - if (visited_ptr[zindex] != visitedId) { - visitCellNoCheck(pt.x, pt.y, pt.z + sz); - visited_ptr[zindex] = visitedId; - } - if (!ymask && sy < 0) - index ^= m0mask; - if (visited_ptr[index] != visitedId) { - visitCellNoCheck(pt.x, pt.y + sy, pt.z); - visited_ptr[index] = visitedId; - } - } else { - // has 0 in one of coords - if (!sx) { - if (!sy) { - if (!sz) { - // 0, 0, 0 - visitCell(pt.x + 1, pt.y, pt.z); - visitCell(pt.x - 1, pt.y, pt.z); - visitCell(pt.x, pt.y + 1, pt.z); - visitCell(pt.x, pt.y - 1, pt.z); - visitCell(pt.x, pt.y, pt.z + 1); - visitCell(pt.x, pt.y, pt.z - 1); - } else { - // 0, 0, 1 - visitCell(pt.x, pt.y, pt.z + sz); - visitCell(pt.x + 1, pt.y, pt.z); - visitCell(pt.x - 1, pt.y, pt.z); - visitCell(pt.x, pt.y + 1, pt.z); - visitCell(pt.x, pt.y - 1, pt.z); - } - } else { - if (!sz) { - // 0, 1, 0 - visitCell(pt.x, pt.y + sy, pt.z); - visitCell(pt.x + 1, pt.y, pt.z); - visitCell(pt.x - 1, pt.y, pt.z); - visitCell(pt.x, pt.y, pt.z + 1); - visitCell(pt.x, pt.y, pt.z - 1); - } else { - // 0, 1, 1 - visitCell(pt.x, pt.y + sy, pt.z); - visitCell(pt.x, pt.y, pt.z + sz); - visitCell(pt.x + 1, pt.y, pt.z); - visitCell(pt.x - 1, pt.y, pt.z); - } - } - } else { - if (!sy) { - if (!sz) { - // 1, 0, 0 - visitCell(pt.x + sx, pt.y, pt.z); - visitCell(pt.x, pt.y + 1, pt.z); - visitCell(pt.x, pt.y - 1, pt.z); - visitCell(pt.x, pt.y, pt.z + 1); - visitCell(pt.x, pt.y, pt.z - 1); - } else { - // 1, 0, 1 - visitCell(pt.x + sx, pt.y, pt.z); - visitCell(pt.x, pt.y, pt.z + sz); - visitCell(pt.x, pt.y + 1, pt.z); - visitCell(pt.x, pt.y - 1, pt.z); - } - } else { - // 1, 1, 0 - visitCell(pt.x + sx, pt.y, pt.z); - visitCell(pt.x, pt.y + sy, pt.z); - visitCell(pt.x, pt.y, pt.z + 1); - visitCell(pt.x, pt.y, pt.z - 1); - } - } - } - } - newcells.swap(oldcells); - } - } -} - -static short[] TERRAIN_INIT_DATA = [ - // V - 10, 10, 10, 10, 30, 30, 30, 30, 30, 30, 30, 30, 10, 10, 10, 10, 10, - 10, 10, 20, 50, 50, 50, 50, 50, 50, 50, 50, 50, 20, 20, 20, 20, 10, - 10, 20, 20, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 20, 20, 10, - 10, 20, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 20, 10, - 10, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 20, 30, - 30, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 30, - 30, 50, 50, 50, 50, 50, 50, 50, 120, 50, 50, 50, 50, 50, 50, 50, 30, - 30, 50, 50, 50, 50, 50, 50, 110, 140, 130, 50, 50, 50, 50, 50, 50, 30, - 30, 50, 50, 50, 50, 50, 50, 140, 150, 140, 50, 50, 50, 50, 50, 50, 30, // <== - 30, 50, 50, 50, 50, 50, 50, 110, 140, 120, 50, 50, 50, 50, 50, 50, 30, - 30, 50, 50, 50, 50, 50, 50, 50, 110, 50, 50, 50, 50, 50, 50, 50, 30, - 30, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 10, - 30, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 10, - 30, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 40, 50, 10, - 30, 20, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 40, 20, 20, 10, - 30, 20, 20, 50, 50, 50, 50, 50, 50, 50, 40, 20, 20, 20, 20, 20, 10, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 10, 10, 10, 10, 10, - // ^ -]; - -static short[] TERRAIN_SCALE_DATA = [ - // V - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 30, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 45, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 80, 20, 20, 20, 40, 50, 40, 20, 20, - 20, 20, 20, 20, 20, 20, 90, 20, 80, 20, 30, 20, 20, 30, 20, 20, 20, - 20, 20, 20, 20, 20, 90, 20, 80, 30, 20, 40, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 90, 30, 40, 30, 50, 20, 20, 20, 20, 20, 20, // <== - 20, 20, 20, 20, 20, 20, 50, 20, 30, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 40, 70, 40, 90, 20, 40, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 80, 20, 50, 70, 50, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 60, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - // ^ -]; - -void initWorldTerrain(World world, int terrSizeBits = 10, int x0 = 0, int z0 = 0) { - import dminer.core.terrain; - int terrSize = 1 << terrSizeBits; - TerrainGen scaleterr = TerrainGen(terrSizeBits, terrSizeBits); // 512x512 - scaleterr.generate(4321, TERRAIN_SCALE_DATA, terrSizeBits - 4); // init grid is 16x16 (1 << (9-7)) - scaleterr.filter(1); - //scaleterr.filter(2); - scaleterr.limit(0, 90); - TerrainGen terr = TerrainGen(terrSizeBits, terrSizeBits); // 512x512 - terr.generateWithScale(123456, TERRAIN_INIT_DATA, terrSizeBits - 4, scaleterr); // init grid is 16x16 (1 << (9-7)) - terr.filter(1); - terr.limit(5, CHUNK_DY * 3 / 4); - terr.filter(1); - for (int x = 0; x < terrSize; x++) { - for (int z = 0; z < terrSize; z++) { - int h = terr.get(x, z); - cell_t cell = 1; - //if (h < CHUNK_DY / 10) - // cell = 100; - //else if (h < CHUNK_DY / 5) - // cell = 101; - //else if (h < CHUNK_DY / 4) - // cell = 102; - //else if (h < CHUNK_DY / 3) - // cell = 103; - //else if (h < CHUNK_DY / 2) - // cell = 104; - //else - // cell = 105; - for (int y = 0; y < h; y++) { - world.setCell(x0 + x - terrSize / 2, y, z0 + z - terrSize / 2, cell); - } - } - } -} diff --git a/examples/d3d/views/res/mdpi/blocks.png b/examples/d3d/views/res/mdpi/blocks.png deleted file mode 100644 index 0440ab4b..00000000 Binary files a/examples/d3d/views/res/mdpi/blocks.png and /dev/null differ diff --git a/examples/d3d/views/resources.list b/examples/d3d/views/resources.list index 49e2f24f..f40f5911 100644 --- a/examples/d3d/views/resources.list +++ b/examples/d3d/views/resources.list @@ -3,7 +3,6 @@ res/i18n/ru.ini res/mdpi/cr3_logo.png res/mdpi/tx_fabric.jpg res/mdpi/crate.png -res/mdpi/blocks.png res/mdpi/brick.png res/mdpi/brickn.png res/models/suzanne.obj