mirror of https://github.com/buggins/dlangui.git
update D3d example
This commit is contained in:
parent
f2d2df59a5
commit
5898fd478d
|
@ -31,10 +31,10 @@
|
|||
<useIn>0</useIn>
|
||||
<useOut>0</useOut>
|
||||
<useArrayBounds>0</useArrayBounds>
|
||||
<noboundscheck>0</noboundscheck>
|
||||
<noboundscheck>1</noboundscheck>
|
||||
<useSwitchError>0</useSwitchError>
|
||||
<useUnitTests>0</useUnitTests>
|
||||
<useInline>0</useInline>
|
||||
<useUnitTests>1</useUnitTests>
|
||||
<useInline>1</useInline>
|
||||
<release>0</release>
|
||||
<preservePaths>0</preservePaths>
|
||||
<warnings>0</warnings>
|
||||
|
@ -235,9 +235,9 @@
|
|||
<useIn>0</useIn>
|
||||
<useOut>0</useOut>
|
||||
<useArrayBounds>0</useArrayBounds>
|
||||
<noboundscheck>0</noboundscheck>
|
||||
<noboundscheck>1</noboundscheck>
|
||||
<useSwitchError>0</useSwitchError>
|
||||
<useUnitTests>0</useUnitTests>
|
||||
<useUnitTests>1</useUnitTests>
|
||||
<useInline>1</useInline>
|
||||
<release>0</release>
|
||||
<preservePaths>0</preservePaths>
|
||||
|
@ -248,7 +248,7 @@
|
|||
<pic>0</pic>
|
||||
<cov>0</cov>
|
||||
<nofloat>0</nofloat>
|
||||
<Dversion>2.043</Dversion>
|
||||
<Dversion>2</Dversion>
|
||||
<ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>
|
||||
<allinst>0</allinst>
|
||||
<stackStomp>0</stackStomp>
|
||||
|
@ -337,10 +337,10 @@
|
|||
<useIn>0</useIn>
|
||||
<useOut>0</useOut>
|
||||
<useArrayBounds>0</useArrayBounds>
|
||||
<noboundscheck>0</noboundscheck>
|
||||
<noboundscheck>1</noboundscheck>
|
||||
<useSwitchError>0</useSwitchError>
|
||||
<useUnitTests>0</useUnitTests>
|
||||
<useInline>0</useInline>
|
||||
<useUnitTests>1</useUnitTests>
|
||||
<useInline>1</useInline>
|
||||
<release>0</release>
|
||||
<preservePaths>0</preservePaths>
|
||||
<warnings>1</warnings>
|
||||
|
@ -541,9 +541,9 @@
|
|||
<useIn>0</useIn>
|
||||
<useOut>0</useOut>
|
||||
<useArrayBounds>0</useArrayBounds>
|
||||
<noboundscheck>0</noboundscheck>
|
||||
<noboundscheck>1</noboundscheck>
|
||||
<useSwitchError>0</useSwitchError>
|
||||
<useUnitTests>0</useUnitTests>
|
||||
<useUnitTests>1</useUnitTests>
|
||||
<useInline>1</useInline>
|
||||
<release>1</release>
|
||||
<preservePaths>0</preservePaths>
|
||||
|
|
|
@ -413,6 +413,7 @@
|
|||
<Folder name="core">
|
||||
<File path="src\dminer\core\blocks.d" />
|
||||
<File path="src\dminer\core\minetypes.d" />
|
||||
<File path="src\dminer\core\terrain.d" />
|
||||
<File path="src\dminer\core\world.d" />
|
||||
</Folder>
|
||||
</Folder>
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
module dminer.core.blocks;
|
||||
|
||||
public import dlangui.core.config;
|
||||
static if (ENABLE_OPENGL):
|
||||
|
||||
import dminer.core.minetypes;
|
||||
import dminer.core.world;
|
||||
import dlangui.graphics.scene.mesh;
|
||||
|
@ -184,7 +181,7 @@ static void createFaceMesh(float * data, Dir face, float x0, float y0, float z0,
|
|||
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) {
|
||||
switch (face) with(Dir) {
|
||||
default:
|
||||
case NORTH:
|
||||
fillFaceMesh(data, face_vertices_north.ptr, x0, y0, z0, tileX, tileY);
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
module dminer.core.minetypes;
|
||||
|
||||
public import dlangui.core.config;
|
||||
static if (ENABLE_OPENGL):
|
||||
|
||||
alias cell_t = ubyte;
|
||||
|
||||
immutable cell_t NO_CELL = 0;
|
||||
|
@ -13,126 +10,46 @@ immutable cell_t VISITED_OCCUPIED = 254;
|
|||
immutable cell_t BOUND_BOTTOM = 253;
|
||||
immutable cell_t BOUND_SKY = 252;
|
||||
|
||||
enum : ubyte {
|
||||
enum Dir : ubyte {
|
||||
NORTH = 0,
|
||||
SOUTH,
|
||||
WEST,
|
||||
EAST,
|
||||
WEST,
|
||||
UP,
|
||||
DOWN,
|
||||
}
|
||||
|
||||
alias Dir = ubyte;
|
||||
|
||||
/// Extended Dir simple Dir directions can be combined; first 6 items of DirEx match items of Dir - 26 directions (3*3*3-1)
|
||||
enum : ubyte {
|
||||
// main directions
|
||||
DIR_NORTH = 0,
|
||||
DIR_SOUTH,
|
||||
DIR_WEST,
|
||||
DIR_EAST,
|
||||
DIR_UP,
|
||||
DIR_DOWN,
|
||||
// combined directions
|
||||
DIR_WEST_UP,
|
||||
DIR_EAST_UP,
|
||||
DIR_WEST_DOWN,
|
||||
DIR_EAST_DOWN,
|
||||
DIR_NORTH_WEST,
|
||||
DIR_NORTH_EAST,
|
||||
DIR_NORTH_UP,
|
||||
DIR_NORTH_DOWN,
|
||||
DIR_NORTH_WEST_UP,
|
||||
DIR_NORTH_EAST_UP,
|
||||
DIR_NORTH_WEST_DOWN,
|
||||
DIR_NORTH_EAST_DOWN,
|
||||
DIR_SOUTH_WEST,
|
||||
DIR_SOUTH_EAST,
|
||||
DIR_SOUTH_UP,
|
||||
DIR_SOUTH_DOWN,
|
||||
DIR_SOUTH_WEST_UP,
|
||||
DIR_SOUTH_EAST_UP,
|
||||
DIR_SOUTH_WEST_DOWN,
|
||||
DIR_SOUTH_EAST_DOWN,
|
||||
DIR_MAX,
|
||||
DIR_MIN = DIR_NORTH,
|
||||
}
|
||||
alias DirEx = ubyte;
|
||||
|
||||
// 26 direction masks based on Dir
|
||||
enum : uint {
|
||||
MASK_NORTH = (1 << NORTH),
|
||||
MASK_SOUTH = (1 << SOUTH),
|
||||
MASK_WEST = (1 << WEST),
|
||||
MASK_EAST = (1 << EAST),
|
||||
MASK_UP = (1 << UP),
|
||||
MASK_DOWN = (1 << DOWN),
|
||||
MASK_WEST_UP = (1 << WEST) | MASK_UP,
|
||||
MASK_EAST_UP = (1 << EAST) | MASK_UP,
|
||||
MASK_WEST_DOWN = (1 << WEST) | MASK_DOWN,
|
||||
MASK_EAST_DOWN = (1 << 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,
|
||||
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,
|
||||
}
|
||||
|
||||
alias DirMask = uint;
|
||||
|
||||
/+
|
||||
struct SymmetricMatrix (T, T initValue) {
|
||||
private:
|
||||
int _size;
|
||||
int dx;
|
||||
int dx2;
|
||||
T * data;
|
||||
public:
|
||||
this(int sz = 1) {
|
||||
_size = sz;
|
||||
reset(sz);
|
||||
}
|
||||
~this() {
|
||||
if (data)
|
||||
delete[] data;
|
||||
}
|
||||
T get(int x, int y) {
|
||||
return data[(x + dx2) * dx + (y + dx2)];
|
||||
}
|
||||
void set(int x, int y, T value) {
|
||||
data[(x + dx2) * dx + (y + dx2)] = value;
|
||||
}
|
||||
int size() {
|
||||
return _size;
|
||||
}
|
||||
void reset(int sz) {
|
||||
if (_size != sz || !data) {
|
||||
_size = sz;
|
||||
dx = _size + _size - 1;
|
||||
dx2 = dx / 2;
|
||||
if (data)
|
||||
delete[] data;
|
||||
data = new T[dx * dx];
|
||||
}
|
||||
for (int i = dx * dx - 1; i >= 0; i--)
|
||||
data[i] = initValue;
|
||||
}
|
||||
}
|
||||
|
||||
alias BoolSymmetricMatrix = SymmetricMatrix!(bool, false);
|
||||
+/
|
||||
|
||||
struct Vector2d {
|
||||
int x;
|
||||
int y;
|
||||
|
@ -140,9 +57,9 @@ struct Vector2d {
|
|||
x = xx;
|
||||
y = yy;
|
||||
}
|
||||
bool opEqual(Vector2d v) const {
|
||||
return x == v.x && y == v.y;
|
||||
}
|
||||
//bool opEqual(Vector2d v) const {
|
||||
// return x == v.x && y == v.y;
|
||||
//}
|
||||
}
|
||||
|
||||
immutable Vector2d ZERO2 = Vector2d(0, 0);
|
||||
|
@ -156,9 +73,9 @@ struct Vector3d {
|
|||
y = yy;
|
||||
z = zz;
|
||||
}
|
||||
bool opEqual(const Vector3d v) const {
|
||||
return x == v.x && y == v.y && z == v.z;
|
||||
}
|
||||
//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 {
|
||||
|
@ -214,25 +131,25 @@ struct Vector3d {
|
|||
Vector3d turnDown() {
|
||||
return Vector3d(x, z, -y);
|
||||
}
|
||||
Vector3d move(DirEx dir) {
|
||||
Vector3d move(Dir dir) {
|
||||
Vector3d res = this;
|
||||
switch (dir) {
|
||||
case DIR_NORTH:
|
||||
switch (dir) with(Dir) {
|
||||
case NORTH:
|
||||
res.z--;
|
||||
break;
|
||||
case DIR_SOUTH:
|
||||
case SOUTH:
|
||||
res.z++;
|
||||
break;
|
||||
case DIR_WEST:
|
||||
case WEST:
|
||||
res.x--;
|
||||
break;
|
||||
case DIR_EAST:
|
||||
case EAST:
|
||||
res.x++;
|
||||
break;
|
||||
case DIR_UP:
|
||||
case UP:
|
||||
res.y++;
|
||||
break;
|
||||
case DIR_DOWN:
|
||||
case DOWN:
|
||||
res.y--;
|
||||
break;
|
||||
default:
|
||||
|
@ -406,12 +323,11 @@ public:
|
|||
|
||||
struct InfiniteMatrix(T) {
|
||||
private:
|
||||
int _minx = 0;
|
||||
int _maxx = 0;
|
||||
int _miny = 0;
|
||||
int _maxy = 0;
|
||||
int _size = 0;
|
||||
int _sizeShift = 0;
|
||||
int _sizeShiftMul2 = 0;
|
||||
int _sizeMask = 0;
|
||||
int _invSizeMask = 0;
|
||||
T[] _data;
|
||||
void resize(int newSizeShift) {
|
||||
int newSize = (1<<newSizeShift);
|
||||
|
@ -433,16 +349,24 @@ private:
|
|||
_data = newdata;
|
||||
_size = newSize;
|
||||
_sizeShift = newSizeShift;
|
||||
_sizeShiftMul2 = _sizeShift + 1;
|
||||
_sizeMask = (1 << _sizeShiftMul2) - 1;
|
||||
_invSizeMask = ~_sizeMask;
|
||||
}
|
||||
int calcIndex(int x, int y) {
|
||||
return ((y + _size) << (_sizeShift + 1)) + (x + _size);
|
||||
return (y << _sizeShiftMul2) + x;
|
||||
}
|
||||
public:
|
||||
@property int size() { return _size; }
|
||||
T get(int x, int y) {
|
||||
if (x < -_size || x >= _size || y < -_size || y >= _size)
|
||||
if (!_data)
|
||||
return null;
|
||||
return _data.ptr[calcIndex(x, y)];
|
||||
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) {
|
||||
|
@ -455,6 +379,8 @@ public:
|
|||
}
|
||||
resize(newSizeShift);
|
||||
}
|
||||
x += _size;
|
||||
y += _size;
|
||||
int index = calcIndex(x, y);
|
||||
if (_data.ptr[index])
|
||||
destroy(_data.ptr[index]);
|
||||
|
@ -480,7 +406,7 @@ struct Position {
|
|||
}
|
||||
Vector2d calcPlaneCoords(Vector3d v) {
|
||||
v = v - pos;
|
||||
switch (direction.dir) {
|
||||
switch (direction.dir) with(Dir) {
|
||||
default:
|
||||
case NORTH:
|
||||
return Vector2d(v.x, v.y);
|
||||
|
@ -502,6 +428,12 @@ struct Position {
|
|||
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();
|
||||
}
|
||||
|
@ -514,6 +446,18 @@ struct Position {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -523,7 +467,7 @@ Dir opposite(Dir d) {
|
|||
}
|
||||
|
||||
Dir turnLeft(Dir d) {
|
||||
switch (d) {
|
||||
switch (d) with (Dir) {
|
||||
case WEST:
|
||||
return SOUTH;
|
||||
case EAST:
|
||||
|
@ -541,7 +485,7 @@ Dir turnLeft(Dir d) {
|
|||
}
|
||||
|
||||
Dir turnRight(Dir d) {
|
||||
switch (d) {
|
||||
switch (d) with (Dir) {
|
||||
case WEST:
|
||||
return NORTH;
|
||||
case EAST:
|
||||
|
@ -559,7 +503,7 @@ Dir turnRight(Dir d) {
|
|||
}
|
||||
|
||||
Dir turnUp(Dir d) {
|
||||
switch (d) {
|
||||
switch (d) with (Dir) {
|
||||
case WEST:
|
||||
return UP;
|
||||
case EAST:
|
||||
|
@ -577,7 +521,7 @@ Dir turnUp(Dir d) {
|
|||
}
|
||||
|
||||
Dir turnDown(Dir d) {
|
||||
switch (d) {
|
||||
switch (d) with (Dir) {
|
||||
case WEST:
|
||||
return DOWN;
|
||||
case EAST:
|
||||
|
@ -605,9 +549,26 @@ struct Direction {
|
|||
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) {
|
||||
switch (d) with (Dir) {
|
||||
default:
|
||||
case NORTH:
|
||||
set(0, 0, -1);
|
||||
|
@ -635,15 +596,15 @@ struct Direction {
|
|||
void set(int x, int y, int z) {
|
||||
forward = Vector3d(x, y, z);
|
||||
if (x) {
|
||||
dir = (x > 0) ? EAST : WEST;
|
||||
dir = (x > 0) ? Dir.EAST : Dir.WEST;
|
||||
}
|
||||
else if (y) {
|
||||
dir = (y > 0) ? UP : DOWN;
|
||||
dir = (y > 0) ? Dir.UP : Dir.DOWN;
|
||||
}
|
||||
else {
|
||||
dir = (z > 0) ? SOUTH : NORTH;
|
||||
dir = (z > 0) ? Dir.SOUTH : Dir.NORTH;
|
||||
}
|
||||
switch (dir) {
|
||||
switch (dir) with (Dir) {
|
||||
case UP:
|
||||
up = Vector3d(1, 0, 0);
|
||||
left = Vector3d(0, 0, 1);
|
||||
|
@ -748,7 +709,16 @@ struct Random {
|
|||
int nextInt() {
|
||||
return next(31);
|
||||
}
|
||||
int nextInt(int n);
|
||||
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 = [
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,9 @@
|
|||
module dminer.core.world;
|
||||
|
||||
public import dlangui.core.config;
|
||||
static if (ENABLE_OPENGL):
|
||||
|
||||
import dminer.core.minetypes;
|
||||
import dminer.core.blocks;
|
||||
|
||||
const int MAX_VIEW_DISTANCE_BITS = 7;
|
||||
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
|
||||
|
@ -18,14 +15,15 @@ immutable int CHUNK_DX_MASK = (CHUNK_DX - 1);
|
|||
immutable int CHUNK_DY_SHIFT = 6;
|
||||
immutable int CHUNK_DY = (1<<CHUNK_DY_SHIFT);
|
||||
immutable int CHUNK_DY_MASK = (CHUNK_DY - 1);
|
||||
immutable int CHUNK_DY_INV_MASK = ~CHUNK_DY_MASK;
|
||||
|
||||
//extern bool HIGHLIGHT_GRID;
|
||||
|
||||
// Layer is 256x16x16 CHUNK_DY layers = CHUNK_DY * (CHUNK_DX_SHIFT x CHUNK_DX_SHIFT) cells
|
||||
struct ChunkLayer {
|
||||
private:
|
||||
|
||||
cell_t[CHUNK_DX * CHUNK_DX] cells;
|
||||
public:
|
||||
|
||||
cell_t* ptr(int x, int z) {
|
||||
return &cells.ptr[(z << CHUNK_DX_SHIFT) + x];
|
||||
}
|
||||
|
@ -64,6 +62,15 @@ public:
|
|||
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];
|
||||
|
@ -82,42 +89,13 @@ public:
|
|||
//void getCells(Vector3d srcpos, Vector3d dstpos, Vector3d size, VolumeData & buf);
|
||||
}
|
||||
|
||||
struct ChunkMatrix {
|
||||
private:
|
||||
int minx;
|
||||
int maxx;
|
||||
int minz;
|
||||
int maxz;
|
||||
InfiniteMatrix!(Chunk *) matrix;
|
||||
public:
|
||||
@property int minX() { return minx; }
|
||||
@property int maxX() { return maxx; }
|
||||
@property int minZ() { return minz; }
|
||||
@property int maxZ() { return maxz; }
|
||||
Chunk * get(int x, int z) {
|
||||
return matrix.get(x, z);
|
||||
}
|
||||
void set(int x, int z, Chunk * chunk) {
|
||||
matrix.set(x, z, chunk);
|
||||
if (minz > z)
|
||||
minz = z;
|
||||
if (maxz < z + 1)
|
||||
maxz = z + 1;
|
||||
if (minx > x)
|
||||
minx = x;
|
||||
if (maxx < x + 1)
|
||||
maxx = x + 1;
|
||||
}
|
||||
}
|
||||
alias ChunkMatrix = InfiniteMatrix!(Chunk *);
|
||||
|
||||
/// Voxel World
|
||||
class World {
|
||||
private:
|
||||
Position _camPosition;
|
||||
int maxVisibleRange = MAX_VIEW_DISTANCE;
|
||||
int lastChunkX = 1000000;
|
||||
int lastChunkZ = 1000000;
|
||||
Chunk * lastChunk;
|
||||
ChunkMatrix chunks;
|
||||
DiamondVisitor visitorHelper;
|
||||
public:
|
||||
|
@ -125,63 +103,64 @@ public:
|
|||
_camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
||||
}
|
||||
~this() {
|
||||
|
||||
}
|
||||
@property final ref Position camPosition() { return _camPosition; }
|
||||
final cell_t getCell(Vector3d v) {
|
||||
return getCell(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
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)
|
||||
//if (y >= CHUNK_DY)
|
||||
else
|
||||
return BOUND_SKY;
|
||||
int chunkx = x >> CHUNK_DX_SHIFT;
|
||||
int chunkz = z >> CHUNK_DX_SHIFT;
|
||||
Chunk * p;
|
||||
if (lastChunkX == chunkx && lastChunkZ == chunkz) {
|
||||
p = lastChunk;
|
||||
} else {
|
||||
p = chunks.get(chunkx, chunkz);
|
||||
lastChunkX = chunkx;
|
||||
lastChunkZ = chunkz;
|
||||
lastChunk = p;
|
||||
}
|
||||
if (!p)
|
||||
return NO_CELL;
|
||||
return p.get(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK);
|
||||
}
|
||||
final bool isOpaque(Vector3d v) {
|
||||
cell_t cell = getCell(v);
|
||||
|
||||
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;
|
||||
if (lastChunkX == chunkx && lastChunkZ == chunkz) {
|
||||
p = lastChunk;
|
||||
} else {
|
||||
p = chunks.get(chunkx, chunkz);
|
||||
lastChunkX = chunkx;
|
||||
lastChunkZ = chunkz;
|
||||
lastChunk = p;
|
||||
}
|
||||
Chunk * p = chunks.get(chunkx, chunkz);
|
||||
if (!p) {
|
||||
p = new Chunk();
|
||||
chunks.set(chunkx, chunkz, p);
|
||||
lastChunkX = chunkx;
|
||||
lastChunkZ = chunkz;
|
||||
lastChunk = p;
|
||||
}
|
||||
p.set(x & CHUNK_DX_MASK, y, z & CHUNK_DX_MASK, value);
|
||||
}
|
||||
//bool canPass(Vector3d pos, Vector3d size) {
|
||||
//}
|
||||
|
||||
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,
|
||||
visitorHelper.init(this,
|
||||
&position,
|
||||
visitor);
|
||||
visitorHelper.visitAll(MAX_VIEW_DISTANCE);
|
||||
visitorHelper.visitAll(maxVisibleRange);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,8 +182,8 @@ struct DiamondVisitor {
|
|||
cell_t * visited_ptr;
|
||||
Vector3dArray oldcells;
|
||||
Vector3dArray newcells;
|
||||
ubyte visitedOccupied;
|
||||
ubyte visitedEmpty;
|
||||
ubyte visitedId;
|
||||
//ubyte visitedEmpty;
|
||||
int m0;
|
||||
int m0mask;
|
||||
void init(World w, Position * pos, CellVisitor v) {
|
||||
|
@ -213,59 +192,72 @@ struct DiamondVisitor {
|
|||
visitor = v;
|
||||
pos0 = position.pos;
|
||||
}
|
||||
void visitCell(Vector3d v) {
|
||||
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 = (v.x + m0) + ((v.z + m0) << (maxDistBits + 1));
|
||||
if (v.y < 0) {
|
||||
int index = (vx + m0) + ((vz + m0) << (maxDistBits + 1));
|
||||
if (vy < 0) {
|
||||
// inverse index for lower half
|
||||
index ^= m0mask;
|
||||
//m0--;
|
||||
//x ^= m0;
|
||||
//y ^= m0;
|
||||
}
|
||||
//int index = diamondIndex(v, maxDistBits);
|
||||
if (visited_ptr[index] == visitedOccupied)// || cell == visitedEmpty)
|
||||
if (visited_ptr[index] == visitedId)// || cell == visitedEmpty)
|
||||
return;
|
||||
//if (v * position.direction.forward < dist / 3)
|
||||
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;
|
||||
cell_t cell = world.getCell(pos);
|
||||
//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 (v.y <= 0 && v * DIRECTION_VECTORS.ptr[DIR_UP] <= 0 &&
|
||||
!world.isOpaque(pos.move(DIR_UP)))
|
||||
visibleFaces |= MASK_UP;
|
||||
if (v.y >= 0 && v * DIRECTION_VECTORS.ptr[DIR_DOWN] <= 0 &&
|
||||
!world.isOpaque(pos.move(DIR_DOWN)))
|
||||
visibleFaces |= MASK_DOWN;
|
||||
if (v.x <= 0 && v * DIRECTION_VECTORS.ptr[DIR_EAST] <= 0 &&
|
||||
!world.isOpaque(pos.move(DIR_EAST)))
|
||||
visibleFaces |= MASK_EAST;
|
||||
if (v.x >= 0 && v * DIRECTION_VECTORS.ptr[DIR_WEST] <= 0 &&
|
||||
!world.isOpaque(pos.move(DIR_WEST)))
|
||||
visibleFaces |= MASK_WEST;
|
||||
if (v.z <= 0 && v * DIRECTION_VECTORS.ptr[DIR_SOUTH] <= 0 &&
|
||||
!world.isOpaque(pos.move(DIR_SOUTH)))
|
||||
visibleFaces |= MASK_SOUTH;
|
||||
if (v.z >= 0 && v * DIRECTION_VECTORS.ptr[DIR_NORTH] <= 0 &&
|
||||
!world.isOpaque(pos.move(DIR_NORTH)))
|
||||
visibleFaces |= MASK_NORTH;
|
||||
visitor.visit(world, *position, pos, cell, visibleFaces);
|
||||
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[cell])
|
||||
newcells.append(v);
|
||||
if (BLOCK_TYPE_CAN_PASS.ptr[cell])
|
||||
newcells.append(Vector3d(vx, vy, vz));
|
||||
//cell = BLOCK_TYPE_CAN_PASS[cell] ? visitedEmpty : visitedOccupied;
|
||||
visited_ptr[index] = visitedOccupied; // cell;
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -281,87 +273,144 @@ struct DiamondVisitor {
|
|||
visited.clear();
|
||||
visited.append(cast(ubyte)0, vsize);
|
||||
visited_ptr = visited.ptr();
|
||||
visitedOccupied = 2;
|
||||
visitedEmpty = 3;
|
||||
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
|
||||
if (oldcells.length() == 0) { // no cells to pass through
|
||||
import dlangui.core.logger;
|
||||
Log.d("No more cells at distance ", dist);
|
||||
break;
|
||||
}
|
||||
newcells.clear();
|
||||
visitedOccupied += 2;
|
||||
visitedEmpty += 2;
|
||||
//CRLog::trace("dist: %d cells: %d", dist, oldcells.length());
|
||||
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];
|
||||
int sx = mySign(pt.x);
|
||||
int sy = mySign(pt.y);
|
||||
int sz = mySign(pt.z);
|
||||
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
|
||||
visitCell(Vector3d(pt.x + sx, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y + sy, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z + sz));
|
||||
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(Vector3d(pt.x + 1, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x - 1, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y + 1, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y - 1, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z + 1));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z - 1));
|
||||
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(Vector3d(pt.x, pt.y, pt.z + sz));
|
||||
visitCell(Vector3d(pt.x + 1, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x - 1, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y + 1, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y - 1, 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);
|
||||
visitCell(pt.x, pt.y + 1, pt.z);
|
||||
visitCell(pt.x, pt.y - 1, pt.z);
|
||||
}
|
||||
} else {
|
||||
if (!sz) {
|
||||
// 0, 1, 0
|
||||
visitCell(Vector3d(pt.x, pt.y + sy, pt.z));
|
||||
visitCell(Vector3d(pt.x + 1, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x - 1, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z + 1));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z - 1));
|
||||
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(Vector3d(pt.x, pt.y + sy, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z + sz));
|
||||
visitCell(Vector3d(pt.x + 1, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x - 1, pt.y, pt.z));
|
||||
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(Vector3d(pt.x + sx, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y + 1, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y - 1, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z + 1));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z - 1));
|
||||
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(Vector3d(pt.x + sx, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z + sz));
|
||||
visitCell(Vector3d(pt.x, pt.y + 1, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y - 1, pt.z));
|
||||
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(Vector3d(pt.x + sx, pt.y, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y + sy, pt.z));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z + 1));
|
||||
visitCell(Vector3d(pt.x, pt.y, pt.z - 1));
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -370,3 +419,83 @@ struct DiamondVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ class Transform : RefCountedObject {
|
|||
_hasTranslation = _hasRotation = _hasScale = _dirtyTransform = false;
|
||||
_scale = vec3(1.0f, 1.0f, 1.0f);
|
||||
_translation = vec3(0.0f, 0.0f, 0.0f);
|
||||
_rotation = mat4.identity;
|
||||
_rotation.setIdentity();
|
||||
_matrix.setIdentity();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue