More work on fixing compile.

This commit is contained in:
Relintai 2019-11-18 22:22:41 +01:00
parent 9103db635f
commit d5acb28a90
12 changed files with 75 additions and 435 deletions

1
SCsub
View File

@ -15,7 +15,6 @@ env.add_source_files(env.modules_sources,"data/voxel_light.cpp")
env.add_source_files(env.modules_sources,"meshers/voxel_mesher.cpp") env.add_source_files(env.modules_sources,"meshers/voxel_mesher.cpp")
env.add_source_files(env.modules_sources,"meshers/transvoxel_cell_data.cpp") env.add_source_files(env.modules_sources,"meshers/transvoxel_cell_data.cpp")
env.add_source_files(env.modules_sources,"meshers/voxel_mesher_transvoxel.cpp") env.add_source_files(env.modules_sources,"meshers/voxel_mesher_transvoxel.cpp")
env.add_source_files(env.modules_sources,"meshers/voxel_mesher_transvoxel_terrarin.cpp")
env.add_source_files(env.modules_sources,"meshers/transvoxel_tables.cpp") env.add_source_files(env.modules_sources,"meshers/transvoxel_tables.cpp")
env.add_source_files(env.modules_sources,"world/voxel_world.cpp") env.add_source_files(env.modules_sources,"world/voxel_world.cpp")

View File

@ -118,12 +118,11 @@ void VoxelMesher::reset() {
void VoxelMesher::add_chunk_bind(Node *chunk) { void VoxelMesher::add_chunk_bind(Node *chunk) {
VoxelChunk *vchunk = Object::cast_to<VoxelChunk>(chunk); VoxelChunk *vchunk = Object::cast_to<VoxelChunk>(chunk);
ERR_FAIL_COND(!ObjectDB::instance_validate(vchunk));
add_chunk(vchunk); add_chunk(vchunk);
} }
void VoxelMesher::add_chunk(VoxelChunk *chunk) { void VoxelMesher::add_chunk(VoxelChunk *chunk) {
ERR_FAIL_COND(!has_method("_add_chunk")); ERR_FAIL_COND(!has_method("_add_chunk"));
ERR_FAIL_COND(!ObjectDB::instance_validate(chunk));
call("_add_chunk", chunk); call("_add_chunk", chunk);
} }
@ -131,12 +130,11 @@ void VoxelMesher::add_chunk(VoxelChunk *chunk) {
void VoxelMesher::add_chunk_liquid_bind(Node *chunk) { void VoxelMesher::add_chunk_liquid_bind(Node *chunk) {
VoxelChunk *vchunk = Object::cast_to<VoxelChunk>(chunk); VoxelChunk *vchunk = Object::cast_to<VoxelChunk>(chunk);
ERR_FAIL_COND(!ObjectDB::instance_validate(vchunk));
add_chunk_liquid(vchunk); add_chunk_liquid(vchunk);
} }
void VoxelMesher::add_chunk_liquid(VoxelChunk *chunk) { void VoxelMesher::add_chunk_liquid(VoxelChunk *chunk) {
ERR_FAIL_COND(!has_method("_add_chunk_liquid")); ERR_FAIL_COND(!has_method("_add_chunk_liquid"));
ERR_FAIL_COND(!ObjectDB::instance_validate(chunk));
call("_add_chunk_liquid", chunk); call("_add_chunk_liquid", chunk);
} }
@ -273,15 +271,19 @@ void VoxelMesher::add_mesh_data_resource_transform(Ref<MeshDataResource> mesh, c
void VoxelMesher::bake_colors_bind(Node *chunk) { void VoxelMesher::bake_colors_bind(Node *chunk) {
VoxelChunk *vchunk = Object::cast_to<VoxelChunk>(chunk); VoxelChunk *vchunk = Object::cast_to<VoxelChunk>(chunk);
ERR_FAIL_COND(!ObjectDB::instance_validate(vchunk));
bake_colors(vchunk); bake_colors(vchunk);
} }
void VoxelMesher::bake_colors(VoxelChunk *chunk) { void VoxelMesher::bake_colors(VoxelChunk *chunk) {
ERR_FAIL_COND(!ObjectDB::instance_validate(chunk));
if (has_method("_bake_colors")) if (has_method("_bake_colors"))
call("_bake_colors", chunk); call("_bake_colors", chunk);
} }
void VoxelMesher::_bake_colors(VoxelChunk *chunk) { void VoxelMesher::_bake_colors(Node *p_chunk) {
VoxelChunk *chunk = Object::cast_to<VoxelChunk>(p_chunk);
ERR_FAIL_COND(!ObjectDB::instance_validate(chunk));
Color base_light(_base_light_value, _base_light_value, _base_light_value); Color base_light(_base_light_value, _base_light_value, _base_light_value);
ERR_FAIL_COND(_vertices.size() != _normals.size()); ERR_FAIL_COND(_vertices.size() != _normals.size());
@ -339,15 +341,19 @@ void VoxelMesher::_bake_colors(VoxelChunk *chunk) {
void VoxelMesher::bake_liquid_colors_bind(Node *chunk) { void VoxelMesher::bake_liquid_colors_bind(Node *chunk) {
VoxelChunk *vchunk = Object::cast_to<VoxelChunk>(chunk); VoxelChunk *vchunk = Object::cast_to<VoxelChunk>(chunk);
ERR_FAIL_COND(!ObjectDB::instance_validate(vchunk));
bake_liquid_colors(vchunk); bake_liquid_colors(vchunk);
} }
void VoxelMesher::bake_liquid_colors(VoxelChunk *chunk) { void VoxelMesher::bake_liquid_colors(VoxelChunk *chunk) {
ERR_FAIL_COND(!ObjectDB::instance_validate(chunk));
if (has_method("_bake_liquid_colors")) if (has_method("_bake_liquid_colors"))
call("_bake_liquid_colors", chunk); call("_bake_liquid_colors", chunk);
} }
void VoxelMesher::_bake_liquid_colors(VoxelChunk *chunk) { void VoxelMesher::_bake_liquid_colors(Node *p_chunk) {
VoxelChunk *chunk = Object::cast_to<VoxelChunk>(p_chunk);
ERR_FAIL_COND(!ObjectDB::instance_validate(chunk));
Color base_light(_base_light_value, _base_light_value, _base_light_value); Color base_light(_base_light_value, _base_light_value, _base_light_value);
ERR_FAIL_COND(_vertices.size() != _normals.size()); ERR_FAIL_COND(_vertices.size() != _normals.size());

View File

@ -63,11 +63,11 @@ public:
void bake_colors_bind(Node *chunk); void bake_colors_bind(Node *chunk);
void bake_colors(VoxelChunk *chunk); void bake_colors(VoxelChunk *chunk);
void _bake_colors(VoxelChunk *chunk); void _bake_colors(Node *p_chunk);
void bake_liquid_colors_bind(Node *chunk); void bake_liquid_colors_bind(Node *chunk);
void bake_liquid_colors(VoxelChunk *chunk); void bake_liquid_colors(VoxelChunk *chunk);
void _bake_liquid_colors(VoxelChunk *chunk); void _bake_liquid_colors(Node *p_chunk);
void build_collider(RID shape) const; void build_collider(RID shape) const;

View File

@ -1,354 +0,0 @@
#include "voxel_mesher_transvoxel_terrarin.h"
#include <core/os/os.h>
// This is a very partial implementation, it is barely equivalent to marching cubes.
// It doesn't include transition cells.
namespace {
inline float tof(int8_t v) {
return static_cast<float>(v) / 256.f;
}
inline int8_t tos(uint8_t v) {
return v - 128;
}
// Values considered negative have a sign bit of 1
inline uint8_t sign(int8_t v) {
return (v >> 7) & 1;
}
//
// 6-------7
// /| /|
// / | / | Corners
// 4-------5 |
// | 2----|--3
// | / | / z y
// |/ |/ |/
// 0-------1 o--x
//
const Vector3i g_corner_dirs[8] = {
Vector3i(0, 0, 0),
Vector3i(1, 0, 0),
Vector3i(0, 1, 0),
Vector3i(1, 1, 0),
Vector3i(0, 0, 1),
Vector3i(1, 0, 1),
Vector3i(0, 1, 1),
Vector3i(1, 1, 1)
};
inline Vector3i dir_to_prev_vec(uint8_t dir) {
//return g_corner_dirs[mask] - Vector3(1,1,1);
return Vector3i(
-(dir & 1),
-((dir >> 1) & 1),
-((dir >> 2) & 1));
}
template <typename T>
void copy_to(PoolVector<T> &to, Vector<T> &from) {
to.resize(from.size());
typename PoolVector<T>::Write w = to.write();
for (unsigned int i = 0; i < from.size(); ++i) {
w[i] = from[i];
}
}
} // namespace
VoxelMesherTransvoxelTerrarin::ReuseCell::ReuseCell() {
case_index = 0;
for (unsigned int i = 0; i < 4; ++i) {
vertices[i] = -1;
}
}
/*
int VoxelMesherTransvoxelTerrarin::get_minimum_padding() const {
return MINIMUM_PADDING;
}*/
void VoxelMesherTransvoxelTerrarin::_add_buffer(Ref<VoxelBuffer> buffer) {
ERR_FAIL_COND(padding < MINIMUM_PADDING);
int channel = VoxelBuffer::CHANNEL_ISOLEVEL;
build_internal(buffer, channel);
}
void VoxelMesherTransvoxelTerrarin::build_internal(Ref<VoxelBuffer> buffer, unsigned int channel) {
// Each 2x2 voxel group is a "cell"
const VoxelBuffer &voxels = *(buffer.ptr());
if (voxels.is_uniform(channel)) {
// Nothing to extract, because constant isolevels never cross the threshold and describe no surface
return;
}
const Vector3i block_size = voxels.get_size();
// TODO No lod yet, but it's planned
const int lod_index = 0;
const int lod_scale = 1 << lod_index;
// Prepare vertex reuse cache
m_block_size = block_size;
unsigned int deck_area = block_size.x * block_size.y;
for (int i = 0; i < 2; ++i) {
if (m_cache[i].size() != deck_area) {
m_cache[i].clear(); // Clear any previous data
m_cache[i].resize(deck_area);
}
}
// Iterate all cells with padding (expected to be neighbors)
Vector3i pos;
for (pos.z = PAD.z; pos.z < block_size.z - 2; ++pos.z) {
for (pos.y = PAD.y; pos.y < block_size.y - 2; ++pos.y) {
for (pos.x = PAD.x; pos.x < block_size.x - 2; ++pos.x) {
// Get the value of cells.
// Negative values are "solid" and positive are "air".
// Due to raw cells being unsigned 8-bit, they get converted to signed.
int8_t cell_samples[8] = {
tos(voxels.get_voxel(pos.x, pos.y, pos.z, channel)),
tos(voxels.get_voxel(pos.x + 1, pos.y, pos.z, channel)),
tos(voxels.get_voxel(pos.x, pos.y + 1, pos.z, channel)),
tos(voxels.get_voxel(pos.x + 1, pos.y + 1, pos.z, channel)),
tos(voxels.get_voxel(pos.x, pos.y, pos.z + 1, channel)),
tos(voxels.get_voxel(pos.x + 1, pos.y, pos.z + 1, channel)),
tos(voxels.get_voxel(pos.x, pos.y + 1, pos.z + 1, channel)),
tos(voxels.get_voxel(pos.x + 1, pos.y + 1, pos.z + 1, channel))
};
// Concatenate the sign of cell values to obtain the case code.
// Index 0 is the less significant bit, and index 7 is the most significant bit.
uint8_t case_code = sign(cell_samples[0]);
case_code |= (sign(cell_samples[1]) << 1);
case_code |= (sign(cell_samples[2]) << 2);
case_code |= (sign(cell_samples[3]) << 3);
case_code |= (sign(cell_samples[4]) << 4);
case_code |= (sign(cell_samples[5]) << 5);
case_code |= (sign(cell_samples[6]) << 6);
case_code |= (sign(cell_samples[7]) << 7);
{
ReuseCell &rc = get_reuse_cell(pos);
rc.case_index = case_code;
}
if (case_code == 0 || case_code == 255) {
// If the case_code is 0 or 255, there is no triangulation to do
continue;
}
// TODO We might not always need all of them
// Compute normals
Vector3 corner_normals[8];
for (unsigned int i = 0; i < 8; ++i) {
Vector3i p = pos + g_corner_dirs[i];
float nx = tof(tos(voxels.get_voxel(p - Vector3i(1, 0, 0), channel))) - tof(tos(voxels.get_voxel(p + Vector3i(1, 0, 0), channel)));
float ny = tof(tos(voxels.get_voxel(p - Vector3i(0, 1, 0), channel))) - tof(tos(voxels.get_voxel(p + Vector3i(0, 1, 0), channel)));
float nz = tof(tos(voxels.get_voxel(p - Vector3i(0, 0, 1), channel))) - tof(tos(voxels.get_voxel(p + Vector3i(0, 0, 1), channel)));
corner_normals[i] = Vector3(nx, ny, nz);
corner_normals[i].normalize();
}
// For cells occurring along the minimal boundaries of a block,
// the preceding cells needed for vertex reuse may not exist.
// In these cases, we allow new vertex creation on additional edges of a cell.
// While iterating through the cells in a block, a 3-bit mask is maintained whose bits indicate
// whether corresponding bits in a direction code are valid
uint8_t direction_validity_mask =
(pos.x > 1 ? 1 : 0) | ((pos.y > 1 ? 1 : 0) << 1) | ((pos.z > 1 ? 1 : 0) << 2);
uint8_t regular_cell_class_index = Transvoxel::regularCellClass[case_code];
Transvoxel::RegularCellData regular_cell_class = Transvoxel::regularCellData[regular_cell_class_index];
uint8_t triangle_count = regular_cell_class.geometryCounts & 0x0f;
uint8_t vertex_count = (regular_cell_class.geometryCounts & 0xf0) >> 4;
int cell_mesh_indices[12];
// For each vertex in the case
for (unsigned int i = 0; i < vertex_count; ++i) {
// The case index maps to a list of 16-bit codes providing information about the edges on which the vertices lie.
// The low byte of each 16-bit code contains the corner indexes of the edges endpoints in one nibble each,
// and the high byte contains the mapping code shown in Figure 3.8(b)
unsigned short rvd = Transvoxel::regularVertexData[case_code][i];
unsigned short edge_code_low = rvd & 0xff;
unsigned short edge_code_high = (rvd >> 8) & 0xff;
// Get corner indexes in the low nibble (always ordered so the higher comes last)
uint8_t v0 = (edge_code_low >> 4) & 0xf;
uint8_t v1 = edge_code_low & 0xf;
ERR_FAIL_COND(v1 <= v0);
// Get voxel values at the corners
int sample0 = cell_samples[v0]; // called d0 in the paper
int sample1 = cell_samples[v1]; // called d1 in the paper
// TODO Zero-division is not mentionned in the paper??
ERR_FAIL_COND(sample1 == sample0);
ERR_FAIL_COND(sample1 == 0 && sample0 == 0);
// Get interpolation position
// We use an 8-bit fraction, allowing the new vertex to be located at one of 257 possible
// positions along the edge when both endpoints are included.
int t = (sample1 << 8) / (sample1 - sample0);
float t0 = static_cast<float>(t) / 256.f;
float t1 = static_cast<float>(0x0100 - t) / 256.f;
Vector3i p0 = pos + g_corner_dirs[v0];
Vector3i p1 = pos + g_corner_dirs[v1];
if (t & 0xff) {
//OS::get_singleton()->print("A");
// Vertex lies in the interior of the edge.
// Each edge of a cell is assigned an 8-bit code, as shown in Figure 3.8(b),
// that provides a mapping to a preceding cell and the coincident edge on that preceding cell
// for which new vertex creation was allowed.
// The high nibble of this code indicates which direction to go in order to reach the correct preceding cell.
// The bit values 1, 2, and 4 in this nibble indicate that we must subtract one
// from the x, y, and/or z coordinate, respectively.
uint8_t reuse_dir = (edge_code_high >> 4) & 0xf;
uint8_t reuse_vertex_index = edge_code_high & 0xf;
bool can_reuse = (reuse_dir & direction_validity_mask) == reuse_dir;
if (can_reuse) {
Vector3i cache_pos = pos + dir_to_prev_vec(reuse_dir);
ReuseCell &prev_cell = get_reuse_cell(cache_pos);
if (prev_cell.case_index == 0 || prev_cell.case_index == 255) {
// TODO I don't think this can happen for non-corner vertices.
cell_mesh_indices[i] = -1;
} else {
// Will reuse a previous vertice
cell_mesh_indices[i] = prev_cell.vertices[reuse_vertex_index];
}
}
if (!can_reuse || cell_mesh_indices[i] == -1) {
// Going to create a new vertice
cell_mesh_indices[i] = _vertices.size();
Vector3 pi = p0.to_vec3() * t0 + p1.to_vec3() * t1;
Vector3 primary = pi; //pos.to_vec3() + pi;
Vector3 normal = corner_normals[v0] * t0 + corner_normals[v1] * t1;
emit_vertex(primary, normal);
if (reuse_dir & 8) {
// Store the generated vertex so that other cells can reuse it.
ReuseCell &rc = get_reuse_cell(pos);
rc.vertices[reuse_vertex_index] = cell_mesh_indices[i];
}
}
} else if (t == 0 && v1 == 7) {
//OS::get_singleton()->print("B");
// This cell owns the vertex, so it should be created.
cell_mesh_indices[i] = _vertices.size();
Vector3 pi = p0.to_vec3() * t0 + p1.to_vec3() * t1;
Vector3 primary = pi; //pos.to_vec3() + pi;
Vector3 normal = corner_normals[v0] * t0 + corner_normals[v1] * t1;
emit_vertex(primary, normal);
ReuseCell &rc = get_reuse_cell(pos);
rc.vertices[0] = cell_mesh_indices[i];
} else {
// Always try to reuse previous vertices in these cases
//OS::get_singleton()->print("C");
// A 3-bit direction code leading to the proper cell can easily be obtained by
// inverting the 3-bit corner index (bitwise, by exclusive ORing with the number 7).
// The corner index depends on the value of t, t = 0 means that we're at the higher
// numbered endpoint.
uint8_t reuse_dir = (t == 0 ? v1 ^ 7 : v0 ^ 7);
bool can_reuse = (reuse_dir & direction_validity_mask) == reuse_dir;
// Note: the only difference with similar code above is that we take vertice 0 in the `else`
if (can_reuse) {
Vector3i cache_pos = pos + dir_to_prev_vec(reuse_dir);
ReuseCell prev_cell = get_reuse_cell(cache_pos);
// The previous cell might not have any geometry, and we
// might therefore have to create a new vertex anyway.
if (prev_cell.case_index == 0 || prev_cell.case_index == 255) {
cell_mesh_indices[i] = -1;
} else {
cell_mesh_indices[i] = prev_cell.vertices[0];
}
}
if (!can_reuse || cell_mesh_indices[i] < 0) {
cell_mesh_indices[i] = _vertices.size();
Vector3 pi = p0.to_vec3() * t0 + p1.to_vec3() * t1;
Vector3 primary = pi; //pos.to_vec3() + pi;
Vector3 normal = corner_normals[v0] * t0 + corner_normals[v1] * t1;
emit_vertex(primary, normal);
}
}
} // for each cell vertice
//OS::get_singleton()->print("_");
for (int t = 0; t < triangle_count; ++t) {
for (int i = 0; i < 3; ++i) {
int index = cell_mesh_indices[regular_cell_class.vertexIndex[t * 3 + i]];
_indices.push_back(index);
}
}
} // x
} // y
} // z
//OS::get_singleton()->print("\n");
}
VoxelMesherTransvoxelTerrarin::ReuseCell &VoxelMesherTransvoxelTerrarin::get_reuse_cell(Vector3i pos) {
int j = pos.z & 1;
int i = pos.y * m_block_size.y + pos.x;
return m_cache[j].write[i];
}
void VoxelMesherTransvoxelTerrarin::emit_vertex(Vector3 primary, Vector3 normal) {
_vertices.push_back(primary - PAD.to_vec3());
_normals.push_back(normal);
}
VoxelMesherTransvoxelTerrarin::VoxelMesherTransvoxelTerrarin() {
padding = MINIMUM_PADDING;
}
void VoxelMesherTransvoxelTerrarin::_bind_methods() {
ClassDB::bind_method(D_METHOD("_add_buffer", "buffer"), &VoxelMesherTransvoxelTerrarin::_add_buffer);
}

View File

@ -1,43 +0,0 @@
#ifndef VOXEL_MESHER_TRANSVOXEL_TERRARIN_H
#define VOXEL_MESHER_TRANSVOXEL_TERRARIN_H
#include <scene/resources/mesh.h>
#include "voxel_mesher.h"
#include "transvoxel_tables.h"
class VoxelMesherTransvoxelTerrarin : public VoxelMesher {
GDCLASS(VoxelMesherTransvoxelTerrarin, VoxelMesher)
public:
static const int MINIMUM_PADDING = 2;
void _add_buffer(Ref<VoxelBuffer> buffer);
//int get_minimum_padding() const override;
VoxelMesherTransvoxelTerrarin();
protected:
static void _bind_methods();
private:
struct ReuseCell {
int vertices[4];
int case_index;
ReuseCell();
};
void build_internal(Ref<VoxelBuffer> buffer, unsigned int channel);
ReuseCell &get_reuse_cell(Vector3i pos);
void emit_vertex(Vector3 primary, Vector3 normal);
private:
int padding;
const Vector3i PAD = Vector3i(1, 1, 1);
Vector<ReuseCell> m_cache[2];
Vector3i m_block_size;
};
#endif // VOXEL_MESHER_TRANSVOXEL_TERRARIN_H

View File

@ -12,7 +12,6 @@
#include "meshers/voxel_mesher.h" #include "meshers/voxel_mesher.h"
#include "meshers/transvoxel_cell_data.h" #include "meshers/transvoxel_cell_data.h"
#include "meshers/voxel_mesher_transvoxel.h" #include "meshers/voxel_mesher_transvoxel.h"
#include "meshers/voxel_mesher_transvoxel_terrarin.h"
#include "world/voxel_world.h" #include "world/voxel_world.h"
#include "world/voxel_chunk.h" #include "world/voxel_chunk.h"
@ -42,7 +41,6 @@
void register_voxelman_types() { void register_voxelman_types() {
ClassDB::register_class<VoxelMesher>(); ClassDB::register_class<VoxelMesher>();
ClassDB::register_class<VoxelMesherTransvoxel>(); ClassDB::register_class<VoxelMesherTransvoxel>();
ClassDB::register_class<VoxelMesherTransvoxelTerrarin>();
ClassDB::register_class<TransvoxelCellData>(); ClassDB::register_class<TransvoxelCellData>();
ClassDB::register_class<VoxelSurface>(); ClassDB::register_class<VoxelSurface>();

View File

@ -19,12 +19,21 @@ _FORCE_INLINE_ void VoxelChunk::set_state(int value) {
_FORCE_INLINE_ int VoxelChunk::get_position_x() { _FORCE_INLINE_ int VoxelChunk::get_position_x() {
return _position_x; return _position_x;
} }
void VoxelChunk::set_position_x(int value) {
_position_x = value;
}
_FORCE_INLINE_ int VoxelChunk::get_position_y() { _FORCE_INLINE_ int VoxelChunk::get_position_y() {
return _position_y; return _position_y;
} }
void VoxelChunk::set_position_y(int value) {
_position_y = value;
}
_FORCE_INLINE_ int VoxelChunk::get_position_z() { _FORCE_INLINE_ int VoxelChunk::get_position_z() {
return _position_z; return _position_z;
} }
void VoxelChunk::set_position_z(int value) {
_position_z = value;
}
_FORCE_INLINE_ Vector3 VoxelChunk::get_position() const { _FORCE_INLINE_ Vector3 VoxelChunk::get_position() const {
return Vector3(_position_x, _position_y, _position_z); return Vector3(_position_x, _position_y, _position_z);
@ -58,6 +67,12 @@ _FORCE_INLINE_ Vector3 VoxelChunk::get_data_size() const {
return Vector3(_data_size_x, _data_size_y, _data_size_z); return Vector3(_data_size_x, _data_size_y, _data_size_z);
} }
void VoxelChunk::set_position(int x, int y, int z) {
_position_x = x;
_position_y = y;
_position_z = z;
}
_FORCE_INLINE_ int VoxelChunk::get_margin_start() const { _FORCE_INLINE_ int VoxelChunk::get_margin_start() const {
return _margin_start; return _margin_start;
} }
@ -178,16 +193,16 @@ RID VoxelChunk::get_clutter_mesh_instance_rid() {
} }
//Voxel Data //Voxel Data
void VoxelChunk::set_size(int size_x, int size_y, int siye_z, int margin_start = 0, int margin_end = 0) { void VoxelChunk::set_size(int size_x, int size_y, int siye_z, int margin_start, int margin_end) {
} }
_FORCE_INLINE_ bool VoxelChunk::validate_channel_position(int x, int y, int z) const { _FORCE_INLINE_ bool VoxelChunk::validate_channel_position(int x, int y, int z) const {
return false;
} }
_FORCE_INLINE_ uint8_t VoxelChunk::get_voxel(int x, int y, int z, int channel_index) const { _FORCE_INLINE_ uint8_t VoxelChunk::get_voxel(int x, int y, int z, int channel_index) const {
return 0;
} }
_FORCE_INLINE_ void VoxelChunk::set_voxel(uint8_t value, int x, int y, int z, int channel_index) { _FORCE_INLINE_ void VoxelChunk::set_voxel(uint8_t value, int x, int y, int z, int channel_index) {
@ -196,7 +211,7 @@ _FORCE_INLINE_ void VoxelChunk::set_voxel(uint8_t value, int x, int y, int z, in
void VoxelChunk::set_channel_count(int count) { void VoxelChunk::set_channel_count(int count) {
} }
void VoxelChunk::allocate_channel(int channel_index, uint8_t value = 0) { void VoxelChunk::allocate_channel(int channel_index, uint8_t value) {
} }
void VoxelChunk::fill_channel(uint8_t value, int channel_index) { void VoxelChunk::fill_channel(uint8_t value, int channel_index) {
@ -207,10 +222,10 @@ void VoxelChunk::dealloc_channel(int channel_index) {
} }
uint8_t *VoxelChunk::get_channel(int channel_index) { uint8_t *VoxelChunk::get_channel(int channel_index) {
return NULL;
} }
uint8_t *VoxelChunk::get_valid_channel(int channel_index) { uint8_t *VoxelChunk::get_valid_channel(int channel_index) {
return NULL;
} }
//Data Management functions //Data Management functions
@ -966,13 +981,16 @@ void VoxelChunk::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "state"), "set_state", "get_state"); ADD_PROPERTY(PropertyInfo(Variant::INT, "state"), "set_state", "get_state");
ClassDB::bind_method(D_METHOD("get_position_x"), &VoxelChunk::get_position_x); ClassDB::bind_method(D_METHOD("get_position_x"), &VoxelChunk::get_position_x);
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_x"), "", "get_position_x"); ClassDB::bind_method(D_METHOD("set_position_x", "value"), &VoxelChunk::set_position_x);
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_x"), "set_position_x", "get_position_x");
ClassDB::bind_method(D_METHOD("get_position_y"), &VoxelChunk::get_position_y); ClassDB::bind_method(D_METHOD("get_position_y"), &VoxelChunk::get_position_y);
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_y"), "", "get_position_y"); ClassDB::bind_method(D_METHOD("set_position_y", "value"), &VoxelChunk::set_position_y);
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_y"), "set_position_y", "get_position_y");
ClassDB::bind_method(D_METHOD("get_position_z"), &VoxelChunk::get_position_z); ClassDB::bind_method(D_METHOD("get_position_z"), &VoxelChunk::get_position_z);
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_z"), "", "get_position_z"); ClassDB::bind_method(D_METHOD("set_position_z", "value"), &VoxelChunk::set_position_z);
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_z"), "set_position_z", "get_position_z");
ClassDB::bind_method(D_METHOD("get_size_x"), &VoxelChunk::get_size_x); ClassDB::bind_method(D_METHOD("get_size_x"), &VoxelChunk::get_size_x);
ADD_PROPERTY(PropertyInfo(Variant::INT, "size_x"), "", "get_size_x"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_x"), "", "get_size_x");

View File

@ -82,8 +82,11 @@ public:
void set_state(int value); void set_state(int value);
int get_position_x(); int get_position_x();
void set_position_x(int value);
int get_position_y(); int get_position_y();
void set_position_y(int value);
int get_position_z(); int get_position_z();
void set_position_z(int value);
int get_size_x(); int get_size_x();
int get_size_y(); int get_size_y();
@ -96,6 +99,7 @@ public:
Vector3 get_position() const; Vector3 get_position() const;
Vector3 get_size() const; Vector3 get_size() const;
Vector3 get_data_size() const; Vector3 get_data_size() const;
void set_position(int x, int y, int z);
int get_margin_start() const; int get_margin_start() const;
int get_margin_end() const; int get_margin_end() const;

View File

@ -70,6 +70,9 @@ void VoxelStructure::set_voxel(int value, int x, int y, int z, unsigned int chan
return b->set_voxel(value, x, y, z, channel_index); return b->set_voxel(value, x, y, z, channel_index);
} }
void add_chunk_bind(Node *chunk, const int x, const int y, const int z) {
}
void VoxelStructure::add_chunk(VoxelChunk *chunk, const int x, const int y, const int z) { void VoxelStructure::add_chunk(VoxelChunk *chunk, const int x, const int y, const int z) {
//_chunks.set(Vector3i(x, y, z), chunk); //_chunks.set(Vector3i(x, y, z), chunk);
@ -109,6 +112,7 @@ VoxelChunk *VoxelStructure::remove_chunk(const int x, const int y, const int z)
VoxelChunk *VoxelStructure::get_chunk_index(const int index) { VoxelChunk *VoxelStructure::get_chunk_index(const int index) {
//return _chunks_vector.get(index).chunk; //return _chunks_vector.get(index).chunk;
return NULL;
} }
int VoxelStructure::get_chunk_count() const { int VoxelStructure::get_chunk_count() const {
return _chunks_vector.size(); return _chunks_vector.size();
@ -169,7 +173,7 @@ void VoxelStructure::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_voxel", "value", "x", "y", "z", "channel_index"), &VoxelStructure::set_voxel, DEFVAL(0)); ClassDB::bind_method(D_METHOD("set_voxel", "value", "x", "y", "z", "channel_index"), &VoxelStructure::set_voxel, DEFVAL(0));
ClassDB::bind_method(D_METHOD("set_voxel_v", "value", "pos", "channel_index"), &VoxelStructure::set_voxel_v, DEFVAL(0)); ClassDB::bind_method(D_METHOD("set_voxel_v", "value", "pos", "channel_index"), &VoxelStructure::set_voxel_v, DEFVAL(0));
ClassDB::bind_method(D_METHOD("add_chunk", "chunk", "x", "y", "z"), &VoxelStructure::add_chunk); ClassDB::bind_method(D_METHOD("add_chunk", "chunk", "x", "y", "z"), &VoxelStructure::add_chunk_bind);
ClassDB::bind_method(D_METHOD("get_chunk", "x", "y", "z"), &VoxelStructure::get_chunk); ClassDB::bind_method(D_METHOD("get_chunk", "x", "y", "z"), &VoxelStructure::get_chunk);
ClassDB::bind_method(D_METHOD("remove_chunk", "x", "y", "z"), &VoxelStructure::remove_chunk); ClassDB::bind_method(D_METHOD("remove_chunk", "x", "y", "z"), &VoxelStructure::remove_chunk);

View File

@ -35,6 +35,7 @@ public:
void set_voxel(int value, int x, int y, int z, unsigned int channel_index = 0); void set_voxel(int value, int x, int y, int z, unsigned int channel_index = 0);
void set_voxel_v(int value, Vector3 pos, unsigned int channel_index = 0); void set_voxel_v(int value, Vector3 pos, unsigned int channel_index = 0);
void add_chunk_bind(Node *chunk, const int x, const int y, const int z);
void add_chunk(VoxelChunk *chunk, const int x, const int y, const int z); void add_chunk(VoxelChunk *chunk, const int x, const int y, const int z);
VoxelChunk *get_chunk(const int x, const int y, const int z); VoxelChunk *get_chunk(const int x, const int y, const int z);
VoxelChunk *remove_chunk(const int x, const int y, const int z); VoxelChunk *remove_chunk(const int x, const int y, const int z);

View File

@ -3,24 +3,24 @@
#include "voxel_chunk.h" #include "voxel_chunk.h"
int VoxelWorld::get_chunk_size_x() const { int VoxelWorld::get_chunk_size_x() const {
return _chunk_size.x; return _chunk_size_x;
} }
void VoxelWorld::set_chunk_size_x(const int value) { void VoxelWorld::set_chunk_size_x(const int value) {
_chunk_size.x = value; _chunk_size_x = value;
} }
int VoxelWorld::get_chunk_size_y() const { int VoxelWorld::get_chunk_size_y() const {
return _chunk_size.y; return _chunk_size_y;
} }
void VoxelWorld::set_chunk_size_y(const int value) { void VoxelWorld::set_chunk_size_y(const int value) {
_chunk_size.y = value; _chunk_size_y = value;
} }
int VoxelWorld::get_chunk_size_z() const { int VoxelWorld::get_chunk_size_z() const {
return _chunk_size.z; return _chunk_size_z;
} }
void VoxelWorld::set_chunk_size_z(const int value) { void VoxelWorld::set_chunk_size_z(const int value) {
_chunk_size.z = value; _chunk_size_z = value;
} }
Ref<VoxelmanLibrary> VoxelWorld::get_library() const { Ref<VoxelmanLibrary> VoxelWorld::get_library() const {
@ -90,9 +90,9 @@ int VoxelWorld::get_world_area_count() const {
} }
void VoxelWorld::add_chunk(VoxelChunk *chunk, const int x, const int y, const int z) { void VoxelWorld::add_chunk(VoxelChunk *chunk, const int x, const int y, const int z) {
chunk->set_chunk_position(x, y, z); chunk->set_position(x, y, z);
_chunks.set(Vector3i(x, y, z), chunk); _chunks.set(IntPos(x, y, z), chunk);
_chunks_vector.push_back(chunk); _chunks_vector.push_back(chunk);
} }
void VoxelWorld::add_chunk_bind(Node *chunk, const int x, const int y, const int z) { void VoxelWorld::add_chunk_bind(Node *chunk, const int x, const int y, const int z) {
@ -103,15 +103,15 @@ void VoxelWorld::add_chunk_bind(Node *chunk, const int x, const int y, const int
add_chunk(v, x, y, z); add_chunk(v, x, y, z);
} }
VoxelChunk *VoxelWorld::get_chunk(const int x, const int y, const int z) const { VoxelChunk *VoxelWorld::get_chunk(const int x, const int y, const int z) const {
if (_chunks.has(Vector3i(x, y, z))) if (_chunks.has(IntPos(x, y, z)))
return _chunks.get(Vector3i(x, y, z)); return _chunks.get(IntPos(x, y, z));
return NULL; return NULL;
} }
VoxelChunk *VoxelWorld::remove_chunk(const int x, const int y, const int z) { VoxelChunk *VoxelWorld::remove_chunk(const int x, const int y, const int z) {
ERR_FAIL_COND_V(!_chunks.has(Vector3i(x, y, z)), NULL); ERR_FAIL_COND_V(!_chunks.has(IntPos(x, y, z)), NULL);
VoxelChunk *chunk = _chunks.get(Vector3i(x, y, z)); VoxelChunk *chunk = _chunks.get(IntPos(x, y, z));
for (int i = 0; i < _chunks_vector.size(); ++i) { for (int i = 0; i < _chunks_vector.size(); ++i) {
if (_chunks_vector.get(i) == chunk) { if (_chunks_vector.get(i) == chunk) {
@ -143,7 +143,9 @@ void VoxelWorld::clear_chunks() {
} }
VoxelWorld::VoxelWorld() { VoxelWorld::VoxelWorld() {
_chunk_size = Vector3i(16, 16, 16); _chunk_size_x = 16;
_chunk_size_y = 16;
_chunk_size_z = 16;
_voxel_scale = 1; _voxel_scale = 1;
_chunk_spawn_range = 4; _chunk_spawn_range = 4;

View File

@ -64,6 +64,7 @@ public:
protected: protected:
static void _bind_methods(); static void _bind_methods();
public:
struct IntPos { struct IntPos {
int x; int x;
int y; int y;
@ -109,4 +110,8 @@ private:
Spatial *_player; Spatial *_player;
}; };
_FORCE_INLINE_ bool operator==(const VoxelWorld::IntPos &a, const VoxelWorld::IntPos &b) {
return a.x == b.x && a.y == b.y && a.z == b.z;
}
#endif #endif