mirror of https://github.com/buggins/dlangui.git
minecraft like renderer
This commit is contained in:
parent
3671b1f2cb
commit
01da716a70
|
|
@ -337,7 +337,7 @@
|
||||||
<useIn>0</useIn>
|
<useIn>0</useIn>
|
||||||
<useOut>0</useOut>
|
<useOut>0</useOut>
|
||||||
<useArrayBounds>0</useArrayBounds>
|
<useArrayBounds>0</useArrayBounds>
|
||||||
<noboundscheck>0</noboundscheck>
|
<noboundscheck>1</noboundscheck>
|
||||||
<useSwitchError>0</useSwitchError>
|
<useSwitchError>0</useSwitchError>
|
||||||
<useUnitTests>0</useUnitTests>
|
<useUnitTests>0</useUnitTests>
|
||||||
<useInline>1</useInline>
|
<useInline>1</useInline>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
return Platform.instance.enterMessageLoop();
|
return Platform.instance.enterMessageLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
class UiWidget : VerticalLayout {
|
class UiWidget : VerticalLayout, CellVisitor {
|
||||||
this() {
|
this() {
|
||||||
super("OpenGLView");
|
super("OpenGLView");
|
||||||
layoutWidth = FILL_PARENT;
|
layoutWidth = FILL_PARENT;
|
||||||
|
|
@ -121,22 +121,38 @@ class UiWidget : VerticalLayout {
|
||||||
_mesh.addCubeMesh(vec3(-i * 2 - 1.0f, -i * 2 - 1.0f, -i * 2 - 1.0f), 0.2f, vec4(1 - i / 12, i / 12, i / 12, 1));
|
_mesh.addCubeMesh(vec3(-i * 2 - 1.0f, -i * 2 - 1.0f, -i * 2 - 1.0f), 0.2f, vec4(1 - i / 12, i / 12, i / 12, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
World w = new World();
|
_minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
|
||||||
|
World _world = new World();
|
||||||
for (int x = -1000; x < 1000; x++)
|
for (int x = -1000; x < 1000; x++)
|
||||||
for (int z = -1000; z < 1000; z++)
|
for (int z = -1000; z < 1000; z++)
|
||||||
w.setCell(x, 10, z, 1);
|
_world.setCell(x, 10, z, 1);
|
||||||
w.setCell(0, 11, 10, 2);
|
_world.setCell(0, 11, 10, 2);
|
||||||
w.setCell(5, 11, 15, 2);
|
_world.setCell(5, 11, 15, 2);
|
||||||
Position position = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
_world.camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
||||||
CellVisitor visitor = new TestVisitor();
|
CellVisitor visitor = new TestVisitor();
|
||||||
Log.d("Testing cell visitor");
|
Log.d("Testing cell visitor");
|
||||||
long ts = currentTimeMillis;
|
long ts = currentTimeMillis;
|
||||||
w.visitVisibleCells(position, visitor);
|
_world.visitVisibleCells(_world.camPosition, visitor);
|
||||||
long duration = currentTimeMillis - ts;
|
long duration = currentTimeMillis - ts;
|
||||||
Log.d("DiamondVisitor finished in ", duration, " ms");
|
Log.d("DiamondVisitor finished in ", duration, " ms");
|
||||||
destroy(w);
|
//destroy(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
World _world;
|
||||||
|
|
||||||
/// returns true is widget is being animated - need to call animate() and redraw
|
/// returns true is widget is being animated - need to call animate() and redraw
|
||||||
@property override bool animating() { return true; }
|
@property override bool animating() { return true; }
|
||||||
/// animates window; interval is time left from previous draw, in hnsecs (1/10000000 of second)
|
/// animates window; interval is time left from previous draw, in hnsecs (1/10000000 of second)
|
||||||
|
|
@ -153,6 +169,7 @@ class UiWidget : VerticalLayout {
|
||||||
Scene3d _scene;
|
Scene3d _scene;
|
||||||
Camera _cam;
|
Camera _cam;
|
||||||
Mesh _mesh;
|
Mesh _mesh;
|
||||||
|
Mesh _minerMesh;
|
||||||
GLTexture _tx;
|
GLTexture _tx;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -212,6 +229,7 @@ class UiWidget : VerticalLayout {
|
||||||
destroy(_program);
|
destroy(_program);
|
||||||
if (_tx)
|
if (_tx)
|
||||||
destroy(_tx);
|
destroy(_tx);
|
||||||
|
destroy(_world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
module dminer.core.blocks;
|
module dminer.core.blocks;
|
||||||
|
|
||||||
import dminer.core.minetypes;
|
import dminer.core.minetypes;
|
||||||
|
import dminer.core.world;
|
||||||
|
import dlangui.graphics.scene.mesh;
|
||||||
|
|
||||||
immutable string BLOCK_TEXTURE_FILENAME = "blocks";
|
immutable string BLOCK_TEXTURE_FILENAME = "blocks";
|
||||||
immutable int BLOCK_TEXTURE_DX = 1024;
|
immutable int BLOCK_TEXTURE_DX = 1024;
|
||||||
|
|
@ -9,6 +11,7 @@ immutable int BLOCK_SPRITE_SIZE = 16;
|
||||||
immutable int BLOCK_SPRITE_STEP = 20;
|
immutable int BLOCK_SPRITE_STEP = 20;
|
||||||
immutable int BLOCK_SPRITE_OFFSET = 21;
|
immutable int BLOCK_SPRITE_OFFSET = 21;
|
||||||
immutable int BLOCK_TEXTURE_SPRITES_PER_LINE = 50;
|
immutable int BLOCK_TEXTURE_SPRITES_PER_LINE = 50;
|
||||||
|
immutable int VERTEX_COMPONENTS = 12;
|
||||||
|
|
||||||
enum BlockVisibility {
|
enum BlockVisibility {
|
||||||
INVISIBLE,
|
INVISIBLE,
|
||||||
|
|
@ -57,13 +60,149 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// create cube face
|
/// create cube face
|
||||||
//void createFace(World * world, Position & camPosition, Vector3d pos, Dir face, FloatArray & vertices, IntArray & indexes) {
|
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 + 0.5f, pos.y + 0.5f, pos.z + 0.5f, 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
|
/// create faces
|
||||||
//void createFaces(World * world, Position & camPosition, Vector3d pos, int visibleFaces, FloatArray & vertices, IntArray & indexes) {
|
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 < 11; j++) {
|
||||||
|
float v = srcvertex[j];
|
||||||
|
switch (j) {
|
||||||
|
default:
|
||||||
|
case 0: // x
|
||||||
|
v += x0;
|
||||||
|
break;
|
||||||
|
case 1: // y
|
||||||
|
v += y0;
|
||||||
|
break;
|
||||||
|
case 2: // z
|
||||||
|
v += z0;
|
||||||
|
break;
|
||||||
|
case 9: // tx.u
|
||||||
|
v = ((tileX + v * BLOCK_SPRITE_SIZE)) / cast(float)BLOCK_TEXTURE_DX;
|
||||||
|
break;
|
||||||
|
case 10: // tx.v
|
||||||
|
v = (BLOCK_TEXTURE_DY - (tileY + v * BLOCK_SPRITE_SIZE)) / cast(float)BLOCK_TEXTURE_DY;
|
||||||
|
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) {
|
||||||
|
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
|
// block type definitions
|
||||||
__gshared BlockDef[256] BLOCK_DEFS;
|
__gshared BlockDef[256] BLOCK_DEFS;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ immutable int CHUNK_DX_SHIFT = 4;
|
||||||
immutable int CHUNK_DX = (1<<CHUNK_DX_SHIFT);
|
immutable int CHUNK_DX = (1<<CHUNK_DX_SHIFT);
|
||||||
immutable int CHUNK_DX_MASK = (CHUNK_DX - 1);
|
immutable int CHUNK_DX_MASK = (CHUNK_DX - 1);
|
||||||
|
|
||||||
immutable int CHUNK_DY_SHIFT = 7;
|
// Y range: 0..CHUNK_DY-1
|
||||||
|
immutable int CHUNK_DY_SHIFT = 6;
|
||||||
immutable int CHUNK_DY = (1<<CHUNK_DY_SHIFT);
|
immutable int CHUNK_DY = (1<<CHUNK_DY_SHIFT);
|
||||||
immutable int CHUNK_DY_MASK = (CHUNK_DY - 1);
|
immutable int CHUNK_DY_MASK = (CHUNK_DY - 1);
|
||||||
|
|
||||||
|
|
@ -109,7 +110,7 @@ public:
|
||||||
/// Voxel World
|
/// Voxel World
|
||||||
class World {
|
class World {
|
||||||
private:
|
private:
|
||||||
Position camPosition;
|
Position _camPosition;
|
||||||
int maxVisibleRange = MAX_VIEW_DISTANCE;
|
int maxVisibleRange = MAX_VIEW_DISTANCE;
|
||||||
int lastChunkX = 1000000;
|
int lastChunkX = 1000000;
|
||||||
int lastChunkZ = 1000000;
|
int lastChunkZ = 1000000;
|
||||||
|
|
@ -117,19 +118,21 @@ private:
|
||||||
ChunkMatrix chunks;
|
ChunkMatrix chunks;
|
||||||
DiamondVisitor visitorHelper;
|
DiamondVisitor visitorHelper;
|
||||||
public:
|
public:
|
||||||
this()
|
this() {
|
||||||
{
|
_camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
||||||
}
|
}
|
||||||
~this() {
|
~this() {
|
||||||
|
|
||||||
}
|
}
|
||||||
ref Position getCamPosition() { return camPosition; }
|
@property final ref Position camPosition() { return _camPosition; }
|
||||||
cell_t getCell(Vector3d v) {
|
final cell_t getCell(Vector3d v) {
|
||||||
return getCell(v.x, v.y, v.z);
|
return getCell(v.x, v.y, v.z);
|
||||||
}
|
}
|
||||||
cell_t getCell(int x, int y, int z) {
|
final cell_t getCell(int x, int y, int z) {
|
||||||
if (y < 0)
|
if (y < 0)
|
||||||
return 3;
|
return BOUND_BOTTOM;
|
||||||
|
if (y >= CHUNK_DY)
|
||||||
|
return BOUND_SKY;
|
||||||
int chunkx = x >> CHUNK_DX_SHIFT;
|
int chunkx = x >> CHUNK_DX_SHIFT;
|
||||||
int chunkz = z >> CHUNK_DX_SHIFT;
|
int chunkz = z >> CHUNK_DX_SHIFT;
|
||||||
Chunk * p;
|
Chunk * p;
|
||||||
|
|
@ -145,11 +148,11 @@ public:
|
||||||
return NO_CELL;
|
return NO_CELL;
|
||||||
return p.get(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK);
|
return p.get(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK);
|
||||||
}
|
}
|
||||||
bool isOpaque(Vector3d v) {
|
final bool isOpaque(Vector3d v) {
|
||||||
cell_t cell = getCell(v);
|
cell_t cell = getCell(v);
|
||||||
return BLOCK_TYPE_OPAQUE[cell] && cell != BOUND_SKY;
|
return BLOCK_TYPE_OPAQUE.ptr[cell] && cell != BOUND_SKY;
|
||||||
}
|
}
|
||||||
void setCell(int x, int y, int z, cell_t value) {
|
final void setCell(int x, int y, int z, cell_t value) {
|
||||||
int chunkx = x >> CHUNK_DX_SHIFT;
|
int chunkx = x >> CHUNK_DX_SHIFT;
|
||||||
int chunkz = z >> CHUNK_DX_SHIFT;
|
int chunkz = z >> CHUNK_DX_SHIFT;
|
||||||
Chunk * p;
|
Chunk * p;
|
||||||
|
|
@ -172,7 +175,7 @@ public:
|
||||||
}
|
}
|
||||||
//bool canPass(Vector3d pos, Vector3d size) {
|
//bool canPass(Vector3d pos, Vector3d size) {
|
||||||
//}
|
//}
|
||||||
void visitVisibleCells(ref Position position, CellVisitor visitor) {
|
final void visitVisibleCells(ref Position position, CellVisitor visitor) {
|
||||||
visitorHelper.init(this, &position,
|
visitorHelper.init(this, &position,
|
||||||
visitor);
|
visitor);
|
||||||
visitorHelper.visitAll(MAX_VIEW_DISTANCE);
|
visitorHelper.visitAll(MAX_VIEW_DISTANCE);
|
||||||
|
|
@ -228,24 +231,24 @@ struct DiamondVisitor {
|
||||||
cell_t cell = world.getCell(pos);
|
cell_t cell = world.getCell(pos);
|
||||||
|
|
||||||
// read cell from world
|
// read cell from world
|
||||||
if (BLOCK_TYPE_VISIBLE[cell]) {
|
if (BLOCK_TYPE_VISIBLE.ptr[cell]) {
|
||||||
int visibleFaces = 0;
|
int visibleFaces = 0;
|
||||||
if (v.y <= 0 && v * DIRECTION_VECTORS[DIR_UP] <= 0 &&
|
if (v.y <= 0 && v * DIRECTION_VECTORS.ptr[DIR_UP] <= 0 &&
|
||||||
!world.isOpaque(pos.move(DIR_UP)))
|
!world.isOpaque(pos.move(DIR_UP)))
|
||||||
visibleFaces |= MASK_UP;
|
visibleFaces |= MASK_UP;
|
||||||
if (v.y >= 0 && v * DIRECTION_VECTORS[DIR_DOWN] <= 0 &&
|
if (v.y >= 0 && v * DIRECTION_VECTORS.ptr[DIR_DOWN] <= 0 &&
|
||||||
!world.isOpaque(pos.move(DIR_DOWN)))
|
!world.isOpaque(pos.move(DIR_DOWN)))
|
||||||
visibleFaces |= MASK_DOWN;
|
visibleFaces |= MASK_DOWN;
|
||||||
if (v.x <= 0 && v * DIRECTION_VECTORS[DIR_EAST] <= 0 &&
|
if (v.x <= 0 && v * DIRECTION_VECTORS.ptr[DIR_EAST] <= 0 &&
|
||||||
!world.isOpaque(pos.move(DIR_EAST)))
|
!world.isOpaque(pos.move(DIR_EAST)))
|
||||||
visibleFaces |= MASK_EAST;
|
visibleFaces |= MASK_EAST;
|
||||||
if (v.x >= 0 && v * DIRECTION_VECTORS[DIR_WEST] <= 0 &&
|
if (v.x >= 0 && v * DIRECTION_VECTORS.ptr[DIR_WEST] <= 0 &&
|
||||||
!world.isOpaque(pos.move(DIR_WEST)))
|
!world.isOpaque(pos.move(DIR_WEST)))
|
||||||
visibleFaces |= MASK_WEST;
|
visibleFaces |= MASK_WEST;
|
||||||
if (v.z <= 0 && v * DIRECTION_VECTORS[DIR_SOUTH] <= 0 &&
|
if (v.z <= 0 && v * DIRECTION_VECTORS.ptr[DIR_SOUTH] <= 0 &&
|
||||||
!world.isOpaque(pos.move(DIR_SOUTH)))
|
!world.isOpaque(pos.move(DIR_SOUTH)))
|
||||||
visibleFaces |= MASK_SOUTH;
|
visibleFaces |= MASK_SOUTH;
|
||||||
if (v.z >= 0 && v * DIRECTION_VECTORS[DIR_NORTH] <= 0 &&
|
if (v.z >= 0 && v * DIRECTION_VECTORS.ptr[DIR_NORTH] <= 0 &&
|
||||||
!world.isOpaque(pos.move(DIR_NORTH)))
|
!world.isOpaque(pos.move(DIR_NORTH)))
|
||||||
visibleFaces |= MASK_NORTH;
|
visibleFaces |= MASK_NORTH;
|
||||||
visitor.visit(world, *position, pos, cell, visibleFaces);
|
visitor.visit(world, *position, pos, cell, visibleFaces);
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,17 @@ class Mesh {
|
||||||
_dirtyVertexBuffer = true;
|
_dirtyVertexBuffer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
_vertexCount = 0;
|
||||||
|
_vertexData.length = 0;
|
||||||
|
_dirtyVertexBuffer = true;
|
||||||
|
if (_parts.length) {
|
||||||
|
foreach(p; _parts)
|
||||||
|
destroy(p);
|
||||||
|
_parts.length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// returns vertex count
|
/// returns vertex count
|
||||||
@property int vertexCount() const { return _vertexCount; }
|
@property int vertexCount() const { return _vertexCount; }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue