mirror of
https://github.com/Relintai/godot_voxel.git
synced 2025-05-01 17:57:55 +02:00
Drop gradient channels, fix misconception about what gradient is
This commit is contained in:
parent
572dcbf680
commit
bed8ac8cb9
@ -17,19 +17,28 @@ struct HermiteValue {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline HermiteValue get_hermite_value(const VoxelBuffer &voxels, unsigned int x, unsigned int y, unsigned int z) {
|
inline float get_isolevel_clamped(const VoxelBuffer &voxels, unsigned int x, unsigned int y, unsigned int z) {
|
||||||
|
|
||||||
x = x >= voxels.get_size().x ? voxels.get_size().x - 1 : x;
|
x = x >= voxels.get_size().x ? voxels.get_size().x - 1 : x;
|
||||||
x = x >= voxels.get_size().y ? voxels.get_size().y - 1 : x;
|
y = y >= voxels.get_size().y ? voxels.get_size().y - 1 : y;
|
||||||
x = x >= voxels.get_size().z ? voxels.get_size().z - 1 : x;
|
z = z >= voxels.get_size().z ? voxels.get_size().z - 1 : z;
|
||||||
|
|
||||||
|
return voxels.get_voxel(x, y, z, VoxelBuffer::CHANNEL_ISOLEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline HermiteValue get_hermite_value(const VoxelBuffer &voxels, unsigned int x, unsigned int y, unsigned int z) {
|
||||||
|
|
||||||
HermiteValue v;
|
HermiteValue v;
|
||||||
|
|
||||||
v.value = voxels.get_voxel_iso(x, y, z, VoxelBuffer::CHANNEL_ISOLEVEL);
|
v.value = voxels.get_voxel_iso(x, y, z, VoxelBuffer::CHANNEL_ISOLEVEL);
|
||||||
// TODO It looks like this gradient should not be a normalized vector!
|
|
||||||
v.gradient.x = voxels.get_voxel_iso(x, y, z, VoxelBuffer::CHANNEL_GRADIENT_X);
|
Vector3 gradient;
|
||||||
v.gradient.y = voxels.get_voxel_iso(x, y, z, VoxelBuffer::CHANNEL_GRADIENT_Y);
|
|
||||||
v.gradient.z = voxels.get_voxel_iso(x, y, z, VoxelBuffer::CHANNEL_GRADIENT_Z);
|
gradient.x = get_isolevel_clamped(voxels, x + 1, y, z) - get_isolevel_clamped(voxels, x - 1, y, z);
|
||||||
|
gradient.y = get_isolevel_clamped(voxels, x, y + 1, z) - get_isolevel_clamped(voxels, x, y - 1, z);
|
||||||
|
gradient.z = get_isolevel_clamped(voxels, x, y, z + 1) - get_isolevel_clamped(voxels, x, y, z - 1);
|
||||||
|
|
||||||
|
v.gradient = gradient;
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@ -44,6 +53,8 @@ inline HermiteValue get_interpolated_hermite_value(const VoxelBuffer &voxels, Ve
|
|||||||
int y1 = static_cast<int>(Math::ceil(pos.y));
|
int y1 = static_cast<int>(Math::ceil(pos.y));
|
||||||
int z1 = static_cast<int>(Math::ceil(pos.z));
|
int z1 = static_cast<int>(Math::ceil(pos.z));
|
||||||
|
|
||||||
|
// TODO There are lots of hidden grid accesses here, could be optimized
|
||||||
|
|
||||||
HermiteValue v0 = get_hermite_value(voxels, x0, y0, z0);
|
HermiteValue v0 = get_hermite_value(voxels, x0, y0, z0);
|
||||||
HermiteValue v1 = get_hermite_value(voxels, x1, y0, z0);
|
HermiteValue v1 = get_hermite_value(voxels, x1, y0, z0);
|
||||||
HermiteValue v2 = get_hermite_value(voxels, x1, y0, z1);
|
HermiteValue v2 = get_hermite_value(voxels, x1, y0, z1);
|
||||||
|
@ -92,11 +92,11 @@ bool can_split(Vector3i node_origin, int node_size, const VoxelAccess &voxels, f
|
|||||||
int channel = VoxelBuffer::CHANNEL_ISOLEVEL;
|
int channel = VoxelBuffer::CHANNEL_ISOLEVEL;
|
||||||
|
|
||||||
// Don't split if nothing is inside, i.e isolevel distance is greater than the size of the cube we are in
|
// Don't split if nothing is inside, i.e isolevel distance is greater than the size of the cube we are in
|
||||||
// Vector3i center_pos = node_origin + Vector3i(node_size / 2);
|
Vector3i center_pos = node_origin + Vector3i(node_size / 2);
|
||||||
// HermiteValue center_value = voxels.get_hermite_value(center_pos.x, center_pos.y, center_pos.z);
|
HermiteValue center_value = voxels.get_hermite_value(center_pos.x, center_pos.y, center_pos.z);
|
||||||
// if (Math::abs(center_value.value) > SQRT3 * (float)node_size) {
|
if (Math::abs(center_value.value) > SQRT3 * (float)node_size) {
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Fighting with Clang-format here /**/
|
// Fighting with Clang-format here /**/
|
||||||
|
|
||||||
|
@ -281,79 +281,6 @@ void VoxelBuffer::delete_channel(int i) {
|
|||||||
channel.data = NULL;
|
channel.data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelBuffer::compute_gradients() {
|
|
||||||
|
|
||||||
const Channel &iso_channel = _channels[CHANNEL_ISOLEVEL];
|
|
||||||
|
|
||||||
const int gradient_x_channel = CHANNEL_GRADIENT_X;
|
|
||||||
const int gradient_y_channel = CHANNEL_GRADIENT_Y;
|
|
||||||
const int gradient_z_channel = CHANNEL_GRADIENT_Z;
|
|
||||||
|
|
||||||
if (iso_channel.data == nullptr) {
|
|
||||||
|
|
||||||
// The channel is uniform, gradient will be zero
|
|
||||||
fill(0, gradient_x_channel);
|
|
||||||
fill(0, gradient_y_channel);
|
|
||||||
fill(0, gradient_z_channel);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (_channels[gradient_x_channel].data == nullptr) {
|
|
||||||
create_channel_noinit(gradient_x_channel, _size);
|
|
||||||
}
|
|
||||||
if (_channels[gradient_y_channel].data == nullptr) {
|
|
||||||
create_channel_noinit(gradient_y_channel, _size);
|
|
||||||
}
|
|
||||||
if (_channels[gradient_z_channel].data == nullptr) {
|
|
||||||
create_channel_noinit(gradient_z_channel, _size);
|
|
||||||
}
|
|
||||||
|
|
||||||
Channel &gx_channel = _channels[gradient_x_channel];
|
|
||||||
Channel &gy_channel = _channels[gradient_y_channel];
|
|
||||||
Channel &gz_channel = _channels[gradient_z_channel];
|
|
||||||
|
|
||||||
const int padding = 1;
|
|
||||||
|
|
||||||
const int min_x = padding;
|
|
||||||
const int min_y = padding;
|
|
||||||
const int min_z = padding;
|
|
||||||
|
|
||||||
const int max_z = _size.z - padding;
|
|
||||||
const int max_x = _size.x - padding;
|
|
||||||
const int max_y = _size.y - padding;
|
|
||||||
|
|
||||||
const int lookup_left = -_size.x;
|
|
||||||
const int lookup_right = -lookup_left;
|
|
||||||
const int lookup_back = -_size.z * _size.x;
|
|
||||||
const int lookup_front = -lookup_back;
|
|
||||||
const int lookup_down = -1;
|
|
||||||
const int lookup_up = -lookup_down;
|
|
||||||
|
|
||||||
for (int z = min_z; z < max_z; ++z) {
|
|
||||||
for (int x = min_x; x < max_x; ++x) {
|
|
||||||
|
|
||||||
int i = index(x, min_y, z);
|
|
||||||
|
|
||||||
for (int y = min_y; y < max_y; ++y) {
|
|
||||||
|
|
||||||
Vector3 v(
|
|
||||||
byte_to_iso(iso_channel.data[i + lookup_right]) - byte_to_iso(iso_channel.data[i + lookup_left]),
|
|
||||||
byte_to_iso(iso_channel.data[i + lookup_up]) - byte_to_iso(iso_channel.data[i + lookup_down]),
|
|
||||||
byte_to_iso(iso_channel.data[i + lookup_front]) - byte_to_iso(iso_channel.data[i + lookup_back]));
|
|
||||||
|
|
||||||
v.normalize();
|
|
||||||
|
|
||||||
gx_channel.data[i] = iso_to_byte(v.x);
|
|
||||||
gy_channel.data[i] = iso_to_byte(v.y);
|
|
||||||
gz_channel.data[i] = iso_to_byte(v.z);
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelBuffer::_bind_methods() {
|
void VoxelBuffer::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("create", "sx", "sy", "sz"), &VoxelBuffer::create);
|
ClassDB::bind_method(D_METHOD("create", "sx", "sy", "sz"), &VoxelBuffer::create);
|
||||||
@ -377,16 +304,15 @@ void VoxelBuffer::_bind_methods() {
|
|||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("is_uniform", "channel"), &VoxelBuffer::is_uniform, DEFVAL(0));
|
ClassDB::bind_method(D_METHOD("is_uniform", "channel"), &VoxelBuffer::is_uniform, DEFVAL(0));
|
||||||
ClassDB::bind_method(D_METHOD("optimize"), &VoxelBuffer::optimize);
|
ClassDB::bind_method(D_METHOD("optimize"), &VoxelBuffer::optimize);
|
||||||
ClassDB::bind_method(D_METHOD("compute_gradients"), &VoxelBuffer::compute_gradients);
|
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(CHANNEL_TYPE);
|
BIND_ENUM_CONSTANT(CHANNEL_TYPE);
|
||||||
BIND_ENUM_CONSTANT(CHANNEL_ISOLEVEL);
|
BIND_ENUM_CONSTANT(CHANNEL_ISOLEVEL);
|
||||||
BIND_ENUM_CONSTANT(CHANNEL_GRADIENT_X);
|
|
||||||
BIND_ENUM_CONSTANT(CHANNEL_GRADIENT_Y);
|
|
||||||
BIND_ENUM_CONSTANT(CHANNEL_GRADIENT_Z);
|
|
||||||
BIND_ENUM_CONSTANT(CHANNEL_DATA);
|
|
||||||
BIND_ENUM_CONSTANT(CHANNEL_DATA2);
|
BIND_ENUM_CONSTANT(CHANNEL_DATA2);
|
||||||
BIND_ENUM_CONSTANT(CHANNEL_DATA3);
|
BIND_ENUM_CONSTANT(CHANNEL_DATA3);
|
||||||
|
BIND_ENUM_CONSTANT(CHANNEL_DATA4);
|
||||||
|
BIND_ENUM_CONSTANT(CHANNEL_DATA5);
|
||||||
|
BIND_ENUM_CONSTANT(CHANNEL_DATA6);
|
||||||
|
BIND_ENUM_CONSTANT(CHANNEL_DATA7);
|
||||||
BIND_ENUM_CONSTANT(MAX_CHANNELS);
|
BIND_ENUM_CONSTANT(MAX_CHANNELS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,16 +16,23 @@ public:
|
|||||||
enum ChannelId {
|
enum ChannelId {
|
||||||
CHANNEL_TYPE = 0,
|
CHANNEL_TYPE = 0,
|
||||||
CHANNEL_ISOLEVEL,
|
CHANNEL_ISOLEVEL,
|
||||||
CHANNEL_GRADIENT_X,
|
|
||||||
CHANNEL_GRADIENT_Y,
|
|
||||||
CHANNEL_GRADIENT_Z,
|
|
||||||
CHANNEL_DATA,
|
|
||||||
CHANNEL_DATA2,
|
CHANNEL_DATA2,
|
||||||
CHANNEL_DATA3,
|
CHANNEL_DATA3,
|
||||||
|
CHANNEL_DATA4,
|
||||||
|
CHANNEL_DATA5,
|
||||||
|
CHANNEL_DATA6,
|
||||||
|
CHANNEL_DATA7,
|
||||||
// Arbitrary value, 8 should be enough. Tweak for your needs.
|
// Arbitrary value, 8 should be enough. Tweak for your needs.
|
||||||
MAX_CHANNELS
|
MAX_CHANNELS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO Quantification options
|
||||||
|
// enum ChannelFormat {
|
||||||
|
// FORMAT_I8_Q255U, // 0..255 integer
|
||||||
|
// FORMAT_F8_Q1S, // -1..1 float stored in 8 bits
|
||||||
|
// FORMAT_F16_Q128S // -128..128 float stored in 16 bits
|
||||||
|
// };
|
||||||
|
|
||||||
// Converts -1..1 float into 0..255 integer
|
// Converts -1..1 float into 0..255 integer
|
||||||
static inline int iso_to_byte(real_t iso) {
|
static inline int iso_to_byte(real_t iso) {
|
||||||
int v = static_cast<int>(128.f * iso + 128.f);
|
int v = static_cast<int>(128.f * iso + 128.f);
|
||||||
@ -94,8 +101,6 @@ public:
|
|||||||
|
|
||||||
uint8_t *get_channel_raw(unsigned int channel_index) const;
|
uint8_t *get_channel_raw(unsigned int channel_index) const;
|
||||||
|
|
||||||
void compute_gradients();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create_channel_noinit(int i, Vector3i size);
|
void create_channel_noinit(int i, Vector3i size);
|
||||||
void create_channel(int i, Vector3i size, uint8_t defval);
|
void create_channel(int i, Vector3i size, uint8_t defval);
|
||||||
|
Loading…
Reference in New Issue
Block a user