mirror of
https://github.com/Relintai/voxelman.git
synced 2024-11-14 10:17:20 +01:00
Relintai
d35efab890
-Merged the needed things from the subvoxel helper classes into VoxelCubePoints. -Mesh generation kind of works.
840 lines
26 KiB
C++
840 lines
26 KiB
C++
#include "voxel_cube_points.h"
|
|
|
|
const unsigned int VoxelCubePoints::index_table[6][4] = {
|
|
{ P000, P010, P110, P100 }, //VOXEL_FACE_FRONT 0
|
|
{ P100, P110, P111, P101 }, //VOXEL_FACE_RIGHT 1
|
|
{ P101, P111, P011, P001 }, //VOXEL_FACE_BACK 2
|
|
{ P001, P011, P010, P000 }, //VOXEL_FACE_LEFT 3
|
|
{ P111, P110, P010, P011 }, //VOXEL_FACE_TOP 4
|
|
{ P001, P000, P100, P101 }, //VOXEL_FACE_BOTTOM 5
|
|
};
|
|
|
|
const unsigned int VoxelCubePoints::visibility_table[6] = {
|
|
VOXEL_NEIGHBOUR_FRONT, //VOXEL_FACE_FRONT 0
|
|
VOXEL_NEIGHBOUR_RIGHT, //VOXEL_FACE_RIGHT 1
|
|
VOXEL_NEIGHBOUR_BACK, //VOXEL_FACE_BACK 2
|
|
VOXEL_NEIGHBOUR_LEFT, //VOXEL_FACE_LEFT 3
|
|
VOXEL_NEIGHBOUR_TOP, //VOXEL_FACE_TOP 4
|
|
VOXEL_NEIGHBOUR_BOTTOM //VOXEL_FACE_BOTTOM 5
|
|
};
|
|
|
|
int VoxelCubePoints::get_x() {
|
|
return _x;
|
|
}
|
|
void VoxelCubePoints::set_x(int value) {
|
|
_x = value;
|
|
}
|
|
|
|
int VoxelCubePoints::get_y() {
|
|
return _y;
|
|
}
|
|
void VoxelCubePoints::set_y(int value) {
|
|
_y = value;
|
|
}
|
|
|
|
int VoxelCubePoints::get_z() {
|
|
return _z;
|
|
}
|
|
void VoxelCubePoints::set_z(int value) {
|
|
_z = value;
|
|
}
|
|
|
|
int VoxelCubePoints::get_size() {
|
|
return _size;
|
|
}
|
|
void VoxelCubePoints::set_size(int value) {
|
|
_size = value;
|
|
}
|
|
|
|
void VoxelCubePoints::refresh_points() {
|
|
//Front
|
|
//Bottom Left
|
|
refresh_point(P000, 0, 0, 0,
|
|
VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_BOTTOM_LEFT, VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_FRONT,
|
|
VOXEL_NEIGHBOUR_BOTTOM, VOXEL_NEIGHBOUR_BOTTOM_LEFT, VOXEL_NEIGHBOUR_BOTTOM_FRONT, VOXEL_NEIGHBOUR_BOTTOM_LEFT_FRONT,
|
|
VOXEL_NEIGHBOUR_FRONT, VOXEL_NEIGHBOUR_BOTTOM_FRONT, VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_FRONT);
|
|
|
|
//Bottom Right
|
|
refresh_point(P100, 255, 0, 0,
|
|
VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_BOTTOM_RIGHT, VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_FRONT,
|
|
VOXEL_NEIGHBOUR_BOTTOM, VOXEL_NEIGHBOUR_BOTTOM_RIGHT, VOXEL_NEIGHBOUR_BOTTOM_FRONT, VOXEL_NEIGHBOUR_BOTTOM_RIGHT_FRONT,
|
|
VOXEL_NEIGHBOUR_FRONT, VOXEL_NEIGHBOUR_BOTTOM_FRONT, VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_FRONT);
|
|
|
|
//Top Left
|
|
refresh_point(P010, 0, 255, 0,
|
|
VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_TOP_LEFT, VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_FRONT,
|
|
VOXEL_NEIGHBOUR_TOP, VOXEL_NEIGHBOUR_TOP_LEFT, VOXEL_NEIGHBOUR_TOP_FRONT, VOXEL_NEIGHBOUR_TOP_LEFT_FRONT,
|
|
VOXEL_NEIGHBOUR_FRONT, VOXEL_NEIGHBOUR_TOP_FRONT, VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_FRONT);
|
|
|
|
//Top Right
|
|
refresh_point(P110, 255, 255, 0,
|
|
VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_TOP_RIGHT, VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_FRONT,
|
|
VOXEL_NEIGHBOUR_TOP, VOXEL_NEIGHBOUR_TOP_RIGHT, VOXEL_NEIGHBOUR_TOP_FRONT, VOXEL_NEIGHBOUR_TOP_RIGHT_FRONT,
|
|
VOXEL_NEIGHBOUR_FRONT, VOXEL_NEIGHBOUR_TOP_FRONT, VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_FRONT);
|
|
|
|
//Back
|
|
//Bottom Left
|
|
refresh_point(P001, 0, 0, 255,
|
|
VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_BOTTOM_LEFT, VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_BACK,
|
|
VOXEL_NEIGHBOUR_BOTTOM, VOXEL_NEIGHBOUR_BOTTOM_LEFT, VOXEL_NEIGHBOUR_BOTTOM_BACK, VOXEL_NEIGHBOUR_BOTTOM_LEFT_BACK,
|
|
VOXEL_NEIGHBOUR_BACK, VOXEL_NEIGHBOUR_BOTTOM_BACK, VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_BACK);
|
|
|
|
//Bottom Right
|
|
refresh_point(P101, 255, 0, 255,
|
|
VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_BOTTOM_RIGHT, VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_BACK,
|
|
VOXEL_NEIGHBOUR_BOTTOM, VOXEL_NEIGHBOUR_BOTTOM_RIGHT, VOXEL_NEIGHBOUR_BOTTOM_BACK, VOXEL_NEIGHBOUR_BOTTOM_RIGHT_BACK,
|
|
VOXEL_NEIGHBOUR_BACK, VOXEL_NEIGHBOUR_BOTTOM_BACK, VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_BACK);
|
|
|
|
//Top Left
|
|
refresh_point(P011, 0, 255, 255,
|
|
VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_TOP_LEFT, VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_BACK,
|
|
VOXEL_NEIGHBOUR_TOP, VOXEL_NEIGHBOUR_TOP_LEFT, VOXEL_NEIGHBOUR_TOP_BACK, VOXEL_NEIGHBOUR_TOP_LEFT_BACK,
|
|
VOXEL_NEIGHBOUR_BACK, VOXEL_NEIGHBOUR_TOP_BACK, VOXEL_NEIGHBOUR_LEFT, VOXEL_NEIGHBOUR_BACK);
|
|
|
|
//Top Right
|
|
refresh_point(P111, 255, 255, 255,
|
|
VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_TOP_RIGHT, VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_BACK,
|
|
VOXEL_NEIGHBOUR_TOP, VOXEL_NEIGHBOUR_TOP_RIGHT, VOXEL_NEIGHBOUR_TOP_BACK, VOXEL_NEIGHBOUR_TOP_RIGHT_BACK,
|
|
VOXEL_NEIGHBOUR_BACK, VOXEL_NEIGHBOUR_TOP_BACK, VOXEL_NEIGHBOUR_RIGHT, VOXEL_NEIGHBOUR_BACK);
|
|
}
|
|
|
|
void VoxelCubePoints::refresh_point(int index, int vectx, int vecty, int vectz, int axisx, int axis2x, int axis3x, int axis4notx, int axisy, int axis2y, int axis3y, int axis4y, int axisz, int axis2z, int axis3z, int axis4notz) {
|
|
|
|
char fill = _point_fills[index];
|
|
unsigned int neighbours = _point_neighbours[index];
|
|
|
|
Vector3i vector3i = Vector3i(vectx, vecty, vectz);
|
|
if ((neighbours & axisx) != axisx) {
|
|
if (vectx == 0) {
|
|
vector3i.x = (int)(128 - fill);
|
|
} else {
|
|
vector3i.x = (int)(fill + 128);
|
|
}
|
|
}
|
|
|
|
if ((neighbours & axisy) != axisy) {
|
|
if (vecty == 0) {
|
|
vector3i.y = (int)(128 - fill);
|
|
} else {
|
|
vector3i.y = (int)(fill + 128);
|
|
}
|
|
}
|
|
|
|
if ((neighbours & axisz) != axisz) {
|
|
if (vectz == 0) {
|
|
vector3i.z = (int)(128 - fill);
|
|
} else {
|
|
vector3i.z = (int)(fill + 128);
|
|
}
|
|
}
|
|
|
|
_points[index] = vector3i;
|
|
}
|
|
|
|
void VoxelCubePoints::refresh_point_full(int index, int vectx, int vecty, int vectz, int axisx, int axis2x, int axis3x, int axisy, int axis2y, int axis3y, int axis4y, int axisz, int axis2z, int axis3z) {
|
|
Vector3i vector3i = Vector3i(vectx, vecty, vectz);
|
|
_points[index] = vector3i;
|
|
}
|
|
|
|
void VoxelCubePoints::refresh_neighbours(const Ref<VoxelBuffer> buffer) {
|
|
int neighbours = 0;
|
|
|
|
int x = _x;
|
|
int y = _y;
|
|
int z = _z;
|
|
|
|
//000
|
|
if (buffer->get_voxel(x - 1, y, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM;
|
|
|
|
if (buffer->get_voxel(x, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT_FRONT;
|
|
|
|
_point_neighbours[P000] = neighbours;
|
|
|
|
neighbours = 0;
|
|
x = _x + 1;
|
|
y = _y;
|
|
z = _z;
|
|
|
|
//100
|
|
if (buffer->get_voxel(x - 1, y, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM;
|
|
|
|
if (buffer->get_voxel(x, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_RIGHT_FRONT;
|
|
|
|
_point_neighbours[P100] = neighbours;
|
|
|
|
neighbours = 0;
|
|
x = _x;
|
|
y = _y + 1;
|
|
z = _z;
|
|
|
|
//010
|
|
if (buffer->get_voxel(x - 1, y, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP;
|
|
|
|
if (buffer->get_voxel(x, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT_FRONT;
|
|
|
|
_point_neighbours[P010] = neighbours;
|
|
|
|
neighbours = 0;
|
|
x = _x;
|
|
y = _y;
|
|
z = _z;
|
|
|
|
//110
|
|
if (buffer->get_voxel(x - 1, y, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP;
|
|
|
|
if (buffer->get_voxel(x, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_FRONT;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_RIGHT_FRONT;
|
|
|
|
_point_neighbours[P110] = neighbours;
|
|
|
|
neighbours = 0;
|
|
x = _x;
|
|
y = _y;
|
|
z = _z + 1;
|
|
|
|
//001
|
|
if (buffer->get_voxel(x - 1, y, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM;
|
|
|
|
if (buffer->get_voxel(x, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT_BACK;
|
|
|
|
_point_neighbours[P001] = neighbours;
|
|
|
|
|
|
neighbours = 0;
|
|
x = _x + 1;
|
|
y = _y;
|
|
z = _z + 1;
|
|
|
|
//101
|
|
if (buffer->get_voxel(x - 1, y, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM;
|
|
|
|
if (buffer->get_voxel(x, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BOTTOM_RIGHT_BACK;
|
|
|
|
_point_neighbours[P101] = neighbours;
|
|
|
|
neighbours = 0;
|
|
x = _x;
|
|
y = _y + 1;
|
|
z = _z + 1;
|
|
|
|
//011
|
|
if (buffer->get_voxel(x - 1, y, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP;
|
|
|
|
if (buffer->get_voxel(x, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_LEFT_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_LEFT_BACK;
|
|
|
|
_point_neighbours[P011] = neighbours;
|
|
|
|
|
|
neighbours = 0;
|
|
x = _x + 1;
|
|
y = _y + 1;
|
|
z = _z + 1;
|
|
|
|
//111
|
|
if (buffer->get_voxel(x - 1, y, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP;
|
|
|
|
if (buffer->get_voxel(x, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_RIGHT_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_RIGHT;
|
|
|
|
if (buffer->get_voxel(x, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_BACK;
|
|
|
|
if (buffer->get_voxel(x - 1, y - 1, z - 1, VoxelBuffer::CHANNEL_TYPE) != 0)
|
|
neighbours = neighbours | VOXEL_NEIGHBOUR_TOP_RIGHT_BACK;
|
|
|
|
_point_neighbours[P111] = neighbours;
|
|
}
|
|
|
|
void VoxelCubePoints::setup(const Ref<VoxelBuffer> buffer, int x, int y, int z, int size) {
|
|
ERR_FAIL_COND(size <= 0);
|
|
|
|
reset();
|
|
|
|
_x = x;
|
|
_y = y;
|
|
_z = z;
|
|
_size = size;
|
|
|
|
_point_types[P000] = buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_TYPE);
|
|
_point_types[P100] = buffer->get_voxel(x + size, y, z, VoxelBuffer::CHANNEL_TYPE);
|
|
_point_types[P010] = buffer->get_voxel(x, y + size, z, VoxelBuffer::CHANNEL_TYPE);
|
|
_point_types[P001] = buffer->get_voxel(x, y, z + size, VoxelBuffer::CHANNEL_TYPE);
|
|
_point_types[P110] = buffer->get_voxel(x + size, y + size, z, VoxelBuffer::CHANNEL_TYPE);
|
|
_point_types[P011] = buffer->get_voxel(x, y + size, z + size, VoxelBuffer::CHANNEL_TYPE);
|
|
_point_types[P101] = buffer->get_voxel(x + size, y, z + size, VoxelBuffer::CHANNEL_TYPE);
|
|
_point_types[P111] = buffer->get_voxel(x + size, y + size, z + size, VoxelBuffer::CHANNEL_TYPE);
|
|
|
|
if (!has_points())
|
|
return;
|
|
|
|
_point_fills[P000] = buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_ISOLEVEL);
|
|
_point_fills[P100] = buffer->get_voxel(x + size, y, z, VoxelBuffer::CHANNEL_ISOLEVEL);
|
|
_point_fills[P010] = buffer->get_voxel(x, y + size, z, VoxelBuffer::CHANNEL_ISOLEVEL);
|
|
_point_fills[P001] = buffer->get_voxel(x, y, z + size, VoxelBuffer::CHANNEL_ISOLEVEL);
|
|
_point_fills[P110] = buffer->get_voxel(x + size, y + size, z, VoxelBuffer::CHANNEL_ISOLEVEL);
|
|
_point_fills[P011] = buffer->get_voxel(x, y + size, z + size, VoxelBuffer::CHANNEL_ISOLEVEL);
|
|
_point_fills[P101] = buffer->get_voxel(x + size, y, z + size, VoxelBuffer::CHANNEL_ISOLEVEL);
|
|
_point_fills[P111] = buffer->get_voxel(x + size, y + size, z + size, VoxelBuffer::CHANNEL_ISOLEVEL);
|
|
|
|
refresh_neighbours(buffer);
|
|
|
|
refresh_points();
|
|
}
|
|
|
|
|
|
void VoxelCubePoints::reset() {
|
|
for (int i = 0; i < POINT_COUNT; ++i) {
|
|
_point_types[i] = 0;
|
|
_point_fills[i] = 0;
|
|
_point_neighbours[i] = 0;
|
|
}
|
|
|
|
_x = 0;
|
|
_y = 0;
|
|
_z = 0;
|
|
_size = 1;
|
|
}
|
|
|
|
int VoxelCubePoints::get_point_index(int face, int index) {
|
|
ERR_FAIL_INDEX_V(face, VOXEL_FACE_COUNT, 0);
|
|
ERR_FAIL_INDEX_V(index, 4, 0);
|
|
|
|
return index_table[face][index];
|
|
}
|
|
|
|
Vector3i VoxelCubePoints::get_points_for_face(int face, int index) {
|
|
return _points[get_point_index(face, index)];
|
|
}
|
|
|
|
Vector3 VoxelCubePoints::get_points_for_face_bind(int face, int index) {
|
|
return _points[get_point_index(face, index)].to_vec3();
|
|
}
|
|
|
|
|
|
bool VoxelCubePoints::is_face_visible(int face) {
|
|
ERR_FAIL_INDEX_V(face, VOXEL_FACE_COUNT, false);
|
|
|
|
int target_neighbour = visibility_table[face];
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
int indx = get_point_index(face, i);
|
|
int neighbour_mask = _point_neighbours[indx];
|
|
|
|
if ((neighbour_mask & target_neighbour) == 0)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool VoxelCubePoints::is_sub_voxel_point_vec(Vector3i point) {
|
|
for (int i = 0; i < POINT_COUNT; i += 1) {
|
|
if (get_point(i) == (point)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool VoxelCubePoints::is_sub_voxel_point(int x, int y, int z) {
|
|
for (int i = 0; i < POINT_COUNT; i += 1) {
|
|
if (get_point(i) == Vector3i(x, y, z)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void VoxelCubePoints::set_point(int point, int x, int y, int z) {
|
|
_points[point] = Vector3i(x, y, z);
|
|
}
|
|
|
|
int VoxelCubePoints::get_point_id_vec(Vector3i point) {
|
|
for (int i = 0; i < POINT_COUNT; ++i) {
|
|
if (get_point(i) == point) {
|
|
return i;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int VoxelCubePoints::get_point_id(int x, int y, int z) {
|
|
for (int i = 0; i < POINT_COUNT; ++i) {
|
|
if (get_point(i) == Vector3i(x, y, z)) {
|
|
return i;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Vector3 VoxelCubePoints::get_vector3_for_point(int face, int index) {
|
|
Vector3i a = get_point_index(face, index);
|
|
|
|
Vector3 b(a.x, a.y, a.z);
|
|
|
|
return b;
|
|
}
|
|
|
|
Vector3 VoxelCubePoints::get_vertex_vector3_for_point(int face, int index) {
|
|
int point_index = get_point_index(face, index);
|
|
|
|
Vector3i a = get_point(point_index);
|
|
|
|
Vector3 vector(a.x, a.y, a.z);
|
|
|
|
float num = (float)255;
|
|
float num2 = num / (float)2;
|
|
vector.x -= num2;
|
|
vector.y -= num2;
|
|
vector.z -= num2;
|
|
vector /= num;
|
|
return vector;
|
|
}
|
|
|
|
Vector3i VoxelCubePoints::get_point(int index) {
|
|
return _points[index];
|
|
}
|
|
|
|
Vector3i VoxelCubePoints::get_top_left_point(int face) {
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return _points[P011];
|
|
}
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return _points[P010];
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return _points[P111];
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return _points[P010];
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return _points[P010];
|
|
}
|
|
if (face == VOXEL_FACE_BOTTOM) {
|
|
return _points[P000];
|
|
}
|
|
return _points[0];
|
|
}
|
|
|
|
Vector3i VoxelCubePoints::get_top_right_point(int face) {
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return _points[P111];
|
|
}
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return _points[P110];
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return _points[P110];
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return _points[P011];
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return _points[P110];
|
|
}
|
|
if (face == VOXEL_FACE_BOTTOM) {
|
|
return _points[P100];
|
|
}
|
|
return _points[0];
|
|
}
|
|
|
|
Vector3i VoxelCubePoints::get_bottom_left_point(int face) {
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return _points[P001];
|
|
}
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return _points[P000];
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return _points[P101];
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return _points[P001];
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return _points[P011];
|
|
}
|
|
if (face == VOXEL_FACE_BOTTOM) {
|
|
return _points[P001];
|
|
}
|
|
return _points[0];
|
|
}
|
|
|
|
Vector3i VoxelCubePoints::get_bottom_right_point(int face) {
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return _points[P101];
|
|
}
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return _points[P100];
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return _points[P100];
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return _points[P001];
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return _points[P111];
|
|
}
|
|
if (face == VOXEL_FACE_BOTTOM) {
|
|
return _points[P101];
|
|
}
|
|
return _points[P000];
|
|
}
|
|
|
|
Vector3 VoxelCubePoints::get_point_bind(int index) {
|
|
return _points[index].to_vec3();
|
|
}
|
|
|
|
Vector3 VoxelCubePoints::get_top_left_point_bind(int face) {
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return _points[P011].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return _points[P010].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return _points[P111].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return _points[P010].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return _points[P010].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_BOTTOM) {
|
|
return _points[P000].to_vec3();
|
|
}
|
|
return _points[0].to_vec3();
|
|
}
|
|
|
|
Vector3 VoxelCubePoints::get_top_right_point_bind(int face) {
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return _points[P111].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return _points[P110].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return _points[P110].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return _points[P011].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return _points[P110].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_BOTTOM) {
|
|
return _points[P100].to_vec3();
|
|
}
|
|
return _points[0].to_vec3();
|
|
}
|
|
|
|
Vector3 VoxelCubePoints::get_bottom_left_point_bind(int face) {
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return _points[P001].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return _points[P000].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return _points[P101].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return _points[P001].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return _points[P011].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_BOTTOM) {
|
|
return _points[P001].to_vec3();
|
|
}
|
|
return _points[0].to_vec3();
|
|
}
|
|
|
|
Vector3 VoxelCubePoints::get_bottom_right_point_bind(int face) {
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return _points[P101].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return _points[P100].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return _points[P100].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return _points[P001].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return _points[P111].to_vec3();
|
|
}
|
|
if (face == VOXEL_FACE_BOTTOM) {
|
|
return _points[P101].to_vec3();
|
|
}
|
|
return _points[P000].to_vec3();
|
|
}
|
|
|
|
bool VoxelCubePoints::has_points() {
|
|
return (_point_types[P000] != 0 && _point_types[P100] != 0 && _point_types[P010] != 0 && _point_types[P001] != 0 &&
|
|
_point_types[P110] != 0 && _point_types[P011] != 0 && _point_types[P101] != 0 && _point_types[P111] != 0);
|
|
}
|
|
|
|
int VoxelCubePoints::get_opposite_face(int face) {
|
|
if (face == VOXEL_FACE_FRONT) {
|
|
return VOXEL_FACE_BACK;
|
|
}
|
|
if (face == VOXEL_FACE_BACK) {
|
|
return VOXEL_FACE_FRONT;
|
|
}
|
|
if (face == VOXEL_FACE_LEFT) {
|
|
return VOXEL_FACE_RIGHT;
|
|
}
|
|
if (face == VOXEL_FACE_RIGHT) {
|
|
return VOXEL_FACE_LEFT;
|
|
}
|
|
if (face == VOXEL_FACE_TOP) {
|
|
return VOXEL_FACE_BOTTOM;
|
|
}
|
|
|
|
return VOXEL_FACE_BOTTOM;
|
|
}
|
|
|
|
VoxelCubePoints::VoxelCubePoints() {
|
|
reset();
|
|
}
|
|
|
|
VoxelCubePoints::~VoxelCubePoints() {
|
|
}
|
|
|
|
|
|
void VoxelCubePoints::_bind_methods() {
|
|
|
|
ClassDB::bind_method(D_METHOD("get_x"), &VoxelCubePoints::get_x);
|
|
ClassDB::bind_method(D_METHOD("set_x", "value"), &VoxelCubePoints::set_x);
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "x"), "set_x", "get_x");
|
|
|
|
ClassDB::bind_method(D_METHOD("get_y"), &VoxelCubePoints::get_y);
|
|
ClassDB::bind_method(D_METHOD("set_y", "value"), &VoxelCubePoints::set_y);
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "y"), "set_y", "get_y");
|
|
|
|
ClassDB::bind_method(D_METHOD("get_z"), &VoxelCubePoints::get_z);
|
|
ClassDB::bind_method(D_METHOD("set_z", "value"), &VoxelCubePoints::set_z);
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "z"), "set_z", "get_z");
|
|
|
|
ClassDB::bind_method(D_METHOD("get_size"), &VoxelCubePoints::get_size);
|
|
ClassDB::bind_method(D_METHOD("set_size", "value"), &VoxelCubePoints::set_size);
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "size"), "set_size", "get_size");
|
|
|
|
ClassDB::bind_method(D_METHOD("refresh_points"), &VoxelCubePoints::refresh_points);
|
|
ClassDB::bind_method(D_METHOD("setup", "buffer", "x", "y", "z", "size"), &VoxelCubePoints::setup, DEFVAL(1));
|
|
|
|
ClassDB::bind_method(D_METHOD("get_point_index", "face", "index"), &VoxelCubePoints::get_point_index);
|
|
ClassDB::bind_method(D_METHOD("get_points_for_face", "face", "index"), &VoxelCubePoints::get_points_for_face_bind);
|
|
|
|
ClassDB::bind_method(D_METHOD("face_fully_covered", "face"), &VoxelCubePoints::is_face_visible);
|
|
|
|
ClassDB::bind_method(D_METHOD("is_sub_voxel_point", "x", "y", "z"), &VoxelCubePoints::is_sub_voxel_point);
|
|
ClassDB::bind_method(D_METHOD("set_point", "point", "x", "y", "z"), &VoxelCubePoints::set_point);
|
|
ClassDB::bind_method(D_METHOD("get_point_id", "x", "y", "z"), &VoxelCubePoints::get_point_id);
|
|
|
|
ClassDB::bind_method(D_METHOD("get_vector3_for_point", "face", "index"), &VoxelCubePoints::get_vector3_for_point);
|
|
ClassDB::bind_method(D_METHOD("get_vertex_vector3_for_point", "face", "index"), &VoxelCubePoints::get_vertex_vector3_for_point);
|
|
|
|
ClassDB::bind_method(D_METHOD("get_point", "index"), &VoxelCubePoints::get_point_bind);
|
|
|
|
ClassDB::bind_method(D_METHOD("get_top_left_point", "face"), &VoxelCubePoints::get_top_left_point_bind);
|
|
ClassDB::bind_method(D_METHOD("get_top_right_point", "face"), &VoxelCubePoints::get_top_right_point_bind);
|
|
ClassDB::bind_method(D_METHOD("get_bottom_left_point", "face"), &VoxelCubePoints::get_bottom_left_point_bind);
|
|
ClassDB::bind_method(D_METHOD("get_bottom_right_point", "face"), &VoxelCubePoints::get_bottom_right_point_bind);
|
|
|
|
ClassDB::bind_method(D_METHOD("has_points"), &VoxelCubePoints::has_points);
|
|
ClassDB::bind_method(D_METHOD("get_opposite_face", "face"), &VoxelCubePoints::get_opposite_face);
|
|
|
|
BIND_ENUM_CONSTANT(P000);
|
|
BIND_ENUM_CONSTANT(P100);
|
|
BIND_ENUM_CONSTANT(P010);
|
|
BIND_ENUM_CONSTANT(P001);
|
|
BIND_ENUM_CONSTANT(P110);
|
|
BIND_ENUM_CONSTANT(P011);
|
|
BIND_ENUM_CONSTANT(P101);
|
|
BIND_ENUM_CONSTANT(P111);
|
|
BIND_ENUM_CONSTANT(POINT_COUNT);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_FACE_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_FACE_RIGHT);
|
|
BIND_ENUM_CONSTANT(VOXEL_FACE_BACK);
|
|
BIND_ENUM_CONSTANT(VOXEL_FACE_LEFT);
|
|
BIND_ENUM_CONSTANT(VOXEL_FACE_TOP);
|
|
BIND_ENUM_CONSTANT(VOXEL_FACE_BOTTOM);
|
|
BIND_ENUM_CONSTANT(VOXEL_FACE_COUNT);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_NONE);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_LEFT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_RIGHT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BACK);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_LEFT_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_LEFT_BACK);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_RIGHT_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_RIGHT_BACK);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP_LEFT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP_RIGHT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP_BACK);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM_LEFT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM_RIGHT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM_BACK);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM_LEFT_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM_LEFT_BACK);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM_RIGHT_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_BOTTOM_RIGHT_BACK);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP_LEFT_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP_LEFT_BACK);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP_RIGHT_FRONT);
|
|
BIND_ENUM_CONSTANT(VOXEL_NEIGHBOUR_TOP_RIGHT_BACK);
|
|
|
|
BIND_ENUM_CONSTANT(VOXEL_FULL_NEIGHBOURS_CROSS);
|
|
BIND_ENUM_CONSTANT(VOXEL_FULL_SIDE_NEIGHBOURS);
|
|
BIND_ENUM_CONSTANT(VOXEL_FULL_SIDE_NEIGHBOURS_TOP);
|
|
BIND_ENUM_CONSTANT(VOXEL_FULL_SIDE_NEIGHBOURS_DOWN);
|
|
}
|