Reworked the way chung handles props, and made chunk building fully scriptable.

This commit is contained in:
Relintai 2019-10-10 23:51:05 +02:00
parent cf9e3e8f19
commit fd3a162126
12 changed files with 531 additions and 162 deletions

1
SCsub
View File

@ -20,6 +20,7 @@ env.add_source_files(env.modules_sources,"world/voxel_world.cpp")
env.add_source_files(env.modules_sources,"world/voxel_chunk.cpp") env.add_source_files(env.modules_sources,"world/voxel_chunk.cpp")
env.add_source_files(env.modules_sources,"world/voxel_structure.cpp") env.add_source_files(env.modules_sources,"world/voxel_structure.cpp")
env.add_source_files(env.modules_sources,"world/environment_data.cpp") env.add_source_files(env.modules_sources,"world/environment_data.cpp")
env.add_source_files(env.modules_sources,"world/voxel_chunk_prop_data.cpp")
env.add_source_files(env.modules_sources,"meshers/cubic_mesher/voxel_mesher_cubic.cpp") env.add_source_files(env.modules_sources,"meshers/cubic_mesher/voxel_mesher_cubic.cpp")

View File

@ -1,5 +1,19 @@
#include "voxelman_prop.h" #include "voxelman_prop.h"
bool VoxelmanProp::get_snap_to_mesh() {
return _snap_to_mesh;
}
void VoxelmanProp::set_snap_to_mesh(bool value) {
_snap_to_mesh = value;
}
Vector3 VoxelmanProp::get_snap_axis() {
return _snap_axis;
}
void VoxelmanProp::set_snap_axis(Vector3 value) {
_snap_axis = value;
}
Ref<VoxelmanPropEntry> VoxelmanProp::get_prop(const int index) const { Ref<VoxelmanPropEntry> VoxelmanProp::get_prop(const int index) const {
ERR_FAIL_INDEX_V(index, _props.size(), Ref<VoxelmanPropEntry>()); ERR_FAIL_INDEX_V(index, _props.size(), Ref<VoxelmanPropEntry>());
@ -40,12 +54,22 @@ void VoxelmanProp::set_props(const Vector<Variant> &props) {
} }
VoxelmanProp::VoxelmanProp() { VoxelmanProp::VoxelmanProp() {
_snap_to_mesh = true;
_snap_axis = Vector3(0, 1, 0);
} }
VoxelmanProp::~VoxelmanProp() { VoxelmanProp::~VoxelmanProp() {
_props.clear(); _props.clear();
} }
void VoxelmanProp::_bind_methods() { void VoxelmanProp::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &VoxelmanProp::get_snap_to_mesh);
ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &VoxelmanProp::set_snap_to_mesh);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh");
ClassDB::bind_method(D_METHOD("get_snap_axis"), &VoxelmanProp::get_snap_axis);
ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &VoxelmanProp::set_snap_axis);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis");
ClassDB::bind_method(D_METHOD("get_prop", "index"), &VoxelmanProp::get_prop); ClassDB::bind_method(D_METHOD("get_prop", "index"), &VoxelmanProp::get_prop);
ClassDB::bind_method(D_METHOD("set_prop", "index", "spell"), &VoxelmanProp::set_prop); ClassDB::bind_method(D_METHOD("set_prop", "index", "spell"), &VoxelmanProp::set_prop);
ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelmanProp::add_prop); ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelmanProp::add_prop);

View File

@ -10,6 +10,12 @@ class VoxelmanProp : public Resource {
GDCLASS(VoxelmanProp, Resource); GDCLASS(VoxelmanProp, Resource);
public: public:
bool get_snap_to_mesh();
void set_snap_to_mesh(bool value);
Vector3 get_snap_axis();
void set_snap_axis(Vector3 value);
Ref<VoxelmanPropEntry> get_prop(const int index) const; Ref<VoxelmanPropEntry> get_prop(const int index) const;
void set_prop(const int index, const Ref<VoxelmanPropEntry> prop); void set_prop(const int index, const Ref<VoxelmanPropEntry> prop);
void add_prop(const Ref<VoxelmanPropEntry> prop); void add_prop(const Ref<VoxelmanPropEntry> prop);
@ -27,6 +33,9 @@ protected:
static void _bind_methods(); static void _bind_methods();
private: private:
bool _snap_to_mesh;
Vector3 _snap_axis;
Vector<Ref<VoxelmanPropEntry> > _props; Vector<Ref<VoxelmanPropEntry> > _props;
}; };

View File

@ -7,7 +7,23 @@ void VoxelmanPropMesh::set_mesh(const Ref<MeshDataResource> mesh) {
_mesh = mesh; _mesh = mesh;
} }
bool VoxelmanPropMesh::get_snap_to_mesh() {
return _snap_to_mesh;
}
void VoxelmanPropMesh::set_snap_to_mesh(bool value) {
_snap_to_mesh = value;
}
Vector3 VoxelmanPropMesh::get_snap_axis() {
return _snap_axis;
}
void VoxelmanPropMesh::set_snap_axis(Vector3 value) {
_snap_axis = value;
}
VoxelmanPropMesh::VoxelmanPropMesh() { VoxelmanPropMesh::VoxelmanPropMesh() {
_snap_to_mesh = true;
_snap_axis = Vector3(0, 1, 0);
} }
VoxelmanPropMesh::~VoxelmanPropMesh() { VoxelmanPropMesh::~VoxelmanPropMesh() {
if (_mesh.is_valid()) if (_mesh.is_valid())
@ -18,4 +34,12 @@ void VoxelmanPropMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mesh"), &VoxelmanPropMesh::get_mesh); ClassDB::bind_method(D_METHOD("get_mesh"), &VoxelmanPropMesh::get_mesh);
ClassDB::bind_method(D_METHOD("set_mesh", "value"), &VoxelmanPropMesh::set_mesh); ClassDB::bind_method(D_METHOD("set_mesh", "value"), &VoxelmanPropMesh::set_mesh);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "MeshDataResource"), "set_mesh", "get_mesh"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "MeshDataResource"), "set_mesh", "get_mesh");
ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &VoxelmanPropMesh::get_snap_to_mesh);
ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &VoxelmanPropMesh::set_snap_to_mesh);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh");
ClassDB::bind_method(D_METHOD("get_snap_axis"), &VoxelmanPropMesh::get_snap_axis);
ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &VoxelmanPropMesh::set_snap_axis);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis");
} }

View File

@ -2,6 +2,7 @@
#define VOXELMAN_PROP_MESH_H #define VOXELMAN_PROP_MESH_H
#include "voxelman_prop_entry.h" #include "voxelman_prop_entry.h"
#include "core/math/vector3.h"
#include "../../entity_spell_system/meshes/mesh_data_resource.h" #include "../../entity_spell_system/meshes/mesh_data_resource.h"
@ -12,6 +13,12 @@ public:
Ref<MeshDataResource> get_mesh() const; Ref<MeshDataResource> get_mesh() const;
void set_mesh(const Ref<MeshDataResource> mesh); void set_mesh(const Ref<MeshDataResource> mesh);
bool get_snap_to_mesh();
void set_snap_to_mesh(bool value);
Vector3 get_snap_axis();
void set_snap_axis(Vector3 value);
VoxelmanPropMesh(); VoxelmanPropMesh();
~VoxelmanPropMesh(); ~VoxelmanPropMesh();
@ -19,6 +26,8 @@ protected:
static void _bind_methods(); static void _bind_methods();
private: private:
bool _snap_to_mesh;
Vector3 _snap_axis;
Ref<MeshDataResource> _mesh; Ref<MeshDataResource> _mesh;
}; };

View File

@ -7,7 +7,23 @@ void VoxelmanPropScene::set_scene(const Ref<PackedScene> value) {
_scene = value; _scene = value;
} }
bool VoxelmanPropScene::get_snap_to_mesh() {
return _snap_to_mesh;
}
void VoxelmanPropScene::set_snap_to_mesh(bool value) {
_snap_to_mesh = value;
}
Vector3 VoxelmanPropScene::get_snap_axis() {
return _snap_axis;
}
void VoxelmanPropScene::set_snap_axis(Vector3 value) {
_snap_axis = value;
}
VoxelmanPropScene::VoxelmanPropScene() { VoxelmanPropScene::VoxelmanPropScene() {
_snap_to_mesh = true;
_snap_axis = Vector3(0, 1, 0);
} }
VoxelmanPropScene::~VoxelmanPropScene() { VoxelmanPropScene::~VoxelmanPropScene() {
if (_scene.is_valid()) if (_scene.is_valid())
@ -18,4 +34,12 @@ void VoxelmanPropScene::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_scene"), &VoxelmanPropScene::get_scene); ClassDB::bind_method(D_METHOD("get_scene"), &VoxelmanPropScene::get_scene);
ClassDB::bind_method(D_METHOD("set_scene", "value"), &VoxelmanPropScene::set_scene); ClassDB::bind_method(D_METHOD("set_scene", "value"), &VoxelmanPropScene::set_scene);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scene", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_scene", "get_scene"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scene", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_scene", "get_scene");
ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &VoxelmanPropScene::get_snap_to_mesh);
ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &VoxelmanPropScene::set_snap_to_mesh);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh");
ClassDB::bind_method(D_METHOD("get_snap_axis"), &VoxelmanPropScene::get_snap_axis);
ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &VoxelmanPropScene::set_snap_axis);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis");
} }

View File

@ -2,6 +2,7 @@
#define VOXELMAN_PROP_SCENE_H #define VOXELMAN_PROP_SCENE_H
#include "voxelman_prop_entry.h" #include "voxelman_prop_entry.h"
#include "core/math/vector3.h"
#include "scene/resources/packed_scene.h" #include "scene/resources/packed_scene.h"
@ -12,6 +13,12 @@ public:
Ref<PackedScene> get_scene() const; Ref<PackedScene> get_scene() const;
void set_scene(const Ref<PackedScene> value); void set_scene(const Ref<PackedScene> value);
bool get_snap_to_mesh();
void set_snap_to_mesh(bool value);
Vector3 get_snap_axis();
void set_snap_axis(Vector3 value);
VoxelmanPropScene(); VoxelmanPropScene();
~VoxelmanPropScene(); ~VoxelmanPropScene();
@ -19,6 +26,8 @@ protected:
static void _bind_methods(); static void _bind_methods();
private: private:
bool _snap_to_mesh;
Vector3 _snap_axis;
Ref<PackedScene> _scene; Ref<PackedScene> _scene;
}; };

View File

@ -14,6 +14,7 @@
#include "world/voxel_chunk.h" #include "world/voxel_chunk.h"
#include "world/voxel_structure.h" #include "world/voxel_structure.h"
#include "world/environment_data.h" #include "world/environment_data.h"
#include "world/voxel_chunk_prop_data.h"
#include "meshers/cubic_mesher/voxel_mesher_cubic.h" #include "meshers/cubic_mesher/voxel_mesher_cubic.h"
#include "meshers/cubic_mesher/voxel_cube_points.h" #include "meshers/cubic_mesher/voxel_cube_points.h"
@ -42,6 +43,7 @@ void register_voxelman_types() {
ClassDB::register_class<VoxelChunk>(); ClassDB::register_class<VoxelChunk>();
ClassDB::register_class<VoxelStructure>(); ClassDB::register_class<VoxelStructure>();
ClassDB::register_class<EnvironmentData>(); ClassDB::register_class<EnvironmentData>();
ClassDB::register_class<VoxelChunkPropData>();
ClassDB::register_class<VoxelMesherCubic>(); ClassDB::register_class<VoxelMesherCubic>();
ClassDB::register_class<VoxelCubePoints>(); ClassDB::register_class<VoxelCubePoints>();

View File

@ -91,6 +91,13 @@ void VoxelChunk::set_voxel_scale(float value) {
} }
} }
int VoxelChunk::get_current_build_phase() {
return _current_build_phase;
}
void VoxelChunk::set_current_build_phase(int value) {
_current_build_phase = value;
}
Ref<VoxelMesher> VoxelChunk::get_mesher() const { Ref<VoxelMesher> VoxelChunk::get_mesher() const {
return _mesher; return _mesher;
} }
@ -131,6 +138,32 @@ Ref<VoxelBuffer> VoxelChunk::get_buffer() const {
return _buffer; return _buffer;
} }
RID VoxelChunk::get_mesh_rid() {
return _mesh_rid;
}
RID VoxelChunk::get_mesh_instance_rid() {
return _mesh_instance_rid;
}
RID VoxelChunk::get_shape_rid() {
return _shape_rid;
}
RID VoxelChunk::get_body_rid() {
return _body_rid;
}
RID VoxelChunk::get_prop_mesh_rid() {
return _prop_mesh_rid;
}
RID VoxelChunk::get_prop_mesh_instance_rid() {
return _prop_mesh_instance_rid;
}
RID VoxelChunk::get_prop_shape_rid() {
return _prop_shape_rid;
}
RID VoxelChunk::get_prop_body_rid() {
return _prop_body_rid;
}
void VoxelChunk::create_mesher() { void VoxelChunk::create_mesher() {
call("_create_mesher"); call("_create_mesher");
@ -155,40 +188,102 @@ void VoxelChunk::finalize_mesh() {
} }
void VoxelChunk::build() { void VoxelChunk::build() {
if (_current_build_phase == BUILD_PHASE_DONE) {
next_phase();
}
}
void VoxelChunk::build_phase(int phase) {
call("_build_phase", phase);
}
void VoxelChunk::_build_phase(int phase) {
ERR_FAIL_COND(!_library.is_valid()); ERR_FAIL_COND(!_library.is_valid());
if (!_mesher.is_valid()) { switch (phase) {
create_mesher(); case BUILD_PHASE_DONE:
} return;
case BUILD_PHASE_SETUP: {
if (!_mesher.is_valid()) {
create_mesher();
}
_mesher->set_library(_library); _mesher->set_library(_library);
_mesher->reset(); _mesher->reset();
if (has_method("_create_mesh")) { next_phase();
call("_create_mesh");
} else {
_mesher->add_buffer(_buffer);
}
finalize_mesh(); return;
}
case BUILD_PHASE_TERRARIN_MESH: {
if (get_create_collider()) { if (has_method("_create_mesh")) {
build_collider(); call("_create_mesh");
} } else {
_mesher->add_buffer(_buffer);
}
_mesher->reset(); finalize_mesh();
if (_props.size() > 0) { next_phase();
process_props();
build_prop_meshes();
if (get_create_collider()) { return;
build_prop_collider(); }
case BUILD_PHASE_TERRARIN_MESH_COLLIDER: {
if (get_create_collider()) {
build_collider();
}
next_phase();
return;
}
case BUILD_PHASE_PROP_MESH: {
_mesher->reset();
if (_props.size() > 0) {
process_props();
build_prop_meshes();
}
next_phase();
return;
}
case BUILD_PHASE_PROP_COLLIDER: {
if (_props.size() > 0) {
if (get_create_collider()) {
build_prop_collider();
}
}
_mesher->reset();
next_phase();
return;
} }
} }
_mesher->reset(); next_phase();
}
void VoxelChunk::next_phase() {
++_current_build_phase;
if (_current_build_phase >= BUILD_PHASE_MAX) {
_current_build_phase = BUILD_PHASE_DONE;
emit_signal("mesh_generation_finished", Ref<VoxelChunk>(this));
return;
}
build_phase(_current_build_phase);
} }
void VoxelChunk::clear() { void VoxelChunk::clear() {
@ -332,36 +427,18 @@ void VoxelChunk::clear_baked_lights() {
_buffer->clear_lights(); _buffer->clear_lights();
} }
void VoxelChunk::add_prop_mesh(const Ref<MeshDataResource> mesh, const Vector3 position, const Vector3 rotation, const Vector3 scale) { void VoxelChunk::add_prop(Ref<VoxelChunkPropData> prop) {
VCPropData data; _props.push_back(prop);
data.transform = Transform(Basis(rotation).scaled(scale), position);
data.mesh = mesh;
_props.push_back(data);
} }
Ref<VoxelChunkPropData> VoxelChunk::get_prop(int index) {
void VoxelChunk::add_prop_spawned(const Ref<PackedScene> scene, const Vector3 position, const Vector3 rotation, const Vector3 scale) { return _props.get(index);
VCPropData data;
data.transform = Transform(Basis(rotation).scaled(scale), position);
data.scene = scene;
_props.push_back(data);
} }
int VoxelChunk::get_prop_count() {
void VoxelChunk::add_prop(const Ref<VoxelmanProp> prop, const Vector3 position, const Vector3 rotation, const Vector3 scale) { return _props.size();
VCPropData data; }
void VoxelChunk::remove_prop(int index) {
data.transform = Transform(Basis(rotation).scaled(scale), position); return _props.remove(index);
data.mesh = prop;
_props.push_back(data);
} }
void VoxelChunk::clear_props() { void VoxelChunk::clear_props() {
_props.clear(); _props.clear();
} }
@ -387,94 +464,20 @@ void VoxelChunk::allocate_prop_mesh() {
VS::get_singleton()->instance_set_transform(_prop_mesh_instance_rid, Transform(Basis(), Vector3(_chunk_position.x * _chunk_size.x * _voxel_scale, _chunk_position.y * _chunk_size.y * _voxel_scale, _chunk_position.z * _chunk_size.z * _voxel_scale))); VS::get_singleton()->instance_set_transform(_prop_mesh_instance_rid, Transform(Basis(), Vector3(_chunk_position.x * _chunk_size.x * _voxel_scale, _chunk_position.y * _chunk_size.y * _voxel_scale, _chunk_position.z * _chunk_size.z * _voxel_scale)));
} }
void VoxelChunk::process_prop_lights() {
Transform transform(Basis().scaled(Vector3(_voxel_scale, _voxel_scale, _voxel_scale)), Vector3(_chunk_position.x * _chunk_size.x, _chunk_position.y * _chunk_size.y, _chunk_position.z * _chunk_size.z));
for (int i = 0; i < _props.size(); ++i) {
VCPropData prop = _props[i];
if (prop.prop.is_valid()) {
process_prop_light(prop.prop, transform);
}
}
}
void VoxelChunk::process_props() { void VoxelChunk::process_props() {
ERR_FAIL_COND(!has_method("_process_props"));
if (_prop_mesh_rid == RID()) { if (_prop_mesh_rid == RID()) {
allocate_prop_mesh(); allocate_prop_mesh();
} }
for (int i = 0; i < _props.size(); ++i) { call("_process_props");
VCPropData prop = _props[i];
process_prop(prop.prop, prop.transform);
}
_mesher->bake_colors(_buffer); _mesher->bake_colors(_buffer);
_mesher->build_mesh(_prop_mesh_rid); _mesher->build_mesh(_prop_mesh_rid);
} }
void VoxelChunk::process_prop_light(Ref<VoxelmanPropLight> prop, const Transform transform) {
ERR_FAIL_COND(!prop.is_valid());
Transform pt = prop->get_transform();
pt = transform * pt;
Vector3 lp = pt.xform_inv(Vector3());
create_voxel_light(prop->get_light_color(), prop->get_light_size(), (int)lp.x, (int)lp.y, (int)lp.z);
}
void VoxelChunk::process_prop(Ref<VoxelmanProp> prop, const Transform transform) {
ERR_FAIL_COND(!prop.is_valid());
for (int i = 0; i < prop->get_prop_count(); ++i) {
Ref<VoxelmanPropEntry> data = prop->get_prop(i);
if (!data.is_valid())
continue;
Transform pt = data->get_transform();
Ref<VoxelmanPropMesh> mesh = data;
if (mesh.is_valid()) {
_mesher->add_mesh_data_resource_transform(mesh->get_mesh(), pt);
}
Ref<VoxelmanPropScene> scene = data;
if (scene.is_valid()) {
spawn_prop(scene->get_scene(), pt);
}
Ref<VoxelmanPropLight> light = data;
if (light.is_valid()) {
process_prop_light(data, transform);
}
}
}
void VoxelChunk::spawn_prop(const Ref<PackedScene> scene, const Transform transform) {
ERR_FAIL_COND(!scene.is_valid());
ERR_FAIL_COND(get_voxel_world() == NULL);
Node *n = scene->instance();
ERR_FAIL_COND(n == NULL);
get_voxel_world()->add_child(n);
n->set_owner(get_voxel_world());
_spawned_props.push_back(n);
Spatial *spatial = Object::cast_to<Spatial>(n);
ERR_FAIL_COND(spatial == NULL);
spatial->set_transform(transform);
}
void VoxelChunk::build_prop_meshes() { void VoxelChunk::build_prop_meshes() {
if (_prop_mesh_rid == RID()) { if (_prop_mesh_rid == RID()) {
allocate_prop_mesh(); allocate_prop_mesh();
@ -586,15 +589,6 @@ void VoxelChunk::free_debug_immediate_geometry() {
} }
} }
void VoxelChunk::free_chunk() {
free_debug_immediate_geometry();
free_main_mesh();
remove_colliders();
free_prop_mesh();
free_prop_colliders();
free_spawn_props();
}
void VoxelChunk::draw_cross_voxels(Vector3 pos) { void VoxelChunk::draw_cross_voxels(Vector3 pos) {
pos *= _voxel_scale; pos *= _voxel_scale;
@ -685,10 +679,20 @@ void VoxelChunk::draw_debug_voxel_lights() {
_debug_drawer->end(); _debug_drawer->end();
} }
void VoxelChunk::free_chunk() {
free_debug_immediate_geometry();
free_main_mesh();
remove_colliders();
free_prop_mesh();
free_prop_colliders();
free_spawn_props();
}
VoxelChunk::VoxelChunk() { VoxelChunk::VoxelChunk() {
_build_mesh = true; _build_mesh = true;
_create_collider = true; _create_collider = true;
_bake_lights = true; _bake_lights = true;
_current_build_phase = BUILD_PHASE_DONE;
_voxel_scale = 1; _voxel_scale = 1;
_lod_size = 1; _lod_size = 1;
@ -717,9 +721,13 @@ VoxelChunk::~VoxelChunk() {
if (_library.is_valid()) { if (_library.is_valid()) {
_library.unref(); _library.unref();
} }
_props.clear();
} }
void VoxelChunk::_bind_methods() { void VoxelChunk::_bind_methods() {
ADD_SIGNAL(MethodInfo("mesh_generation_finished", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk")));
BIND_VMETHOD(MethodInfo("_create_mesh")); BIND_VMETHOD(MethodInfo("_create_mesh"));
BIND_VMETHOD(MethodInfo("_create_mesher")); BIND_VMETHOD(MethodInfo("_create_mesher"));
@ -765,6 +773,10 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &VoxelChunk::set_voxel_scale); ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &VoxelChunk::set_voxel_scale);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
ClassDB::bind_method(D_METHOD("get_current_build_phase"), &VoxelChunk::get_current_build_phase);
ClassDB::bind_method(D_METHOD("set_current_build_phase", "value"), &VoxelChunk::set_current_build_phase);
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_build_phase"), "set_current_build_phase", "get_current_build_phase");
ClassDB::bind_method(D_METHOD("get_buffer"), &VoxelChunk::get_buffer); ClassDB::bind_method(D_METHOD("get_buffer"), &VoxelChunk::get_buffer);
ADD_GROUP("Meshing", "meshing"); ADD_GROUP("Meshing", "meshing");
@ -787,9 +799,24 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_voxel_world", "world"), &VoxelChunk::set_voxel_world_bind); ClassDB::bind_method(D_METHOD("set_voxel_world", "world"), &VoxelChunk::set_voxel_world_bind);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "voxel_world", PROPERTY_HINT_RESOURCE_TYPE, "VoxelWorld"), "set_voxel_world", "get_voxel_world"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "voxel_world", PROPERTY_HINT_RESOURCE_TYPE, "VoxelWorld"), "set_voxel_world", "get_voxel_world");
ClassDB::bind_method(D_METHOD("get_mesh_rid"), &VoxelChunk::get_mesh_rid);
ClassDB::bind_method(D_METHOD("get_mesh_instance_rid"), &VoxelChunk::get_mesh_instance_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &VoxelChunk::get_shape_rid);
ClassDB::bind_method(D_METHOD("get_body_rid"), &VoxelChunk::get_body_rid);
ClassDB::bind_method(D_METHOD("get_prop_mesh_rid"), &VoxelChunk::get_prop_mesh_rid);
ClassDB::bind_method(D_METHOD("get_prop_mesh_instance_rid"), &VoxelChunk::get_prop_mesh_instance_rid);
ClassDB::bind_method(D_METHOD("get_prop_shape_rid"), &VoxelChunk::get_prop_shape_rid);
ClassDB::bind_method(D_METHOD("get_prop_body_rid"), &VoxelChunk::get_prop_body_rid);
ClassDB::bind_method(D_METHOD("finalize_mesh"), &VoxelChunk::finalize_mesh); ClassDB::bind_method(D_METHOD("finalize_mesh"), &VoxelChunk::finalize_mesh);
BIND_VMETHOD(MethodInfo("_build_phase", PropertyInfo(Variant::INT, "phase")));
ClassDB::bind_method(D_METHOD("build"), &VoxelChunk::build); ClassDB::bind_method(D_METHOD("build"), &VoxelChunk::build);
ClassDB::bind_method(D_METHOD("build_phase", "phase"), &VoxelChunk::build_phase);
ClassDB::bind_method(D_METHOD("_build_phase", "phase"), &VoxelChunk::_build_phase);
ClassDB::bind_method(D_METHOD("next_phase"), &VoxelChunk::next_phase);
ClassDB::bind_method(D_METHOD("clear"), &VoxelChunk::clear); ClassDB::bind_method(D_METHOD("clear"), &VoxelChunk::clear);
ClassDB::bind_method(D_METHOD("create_colliders"), &VoxelChunk::create_colliders); ClassDB::bind_method(D_METHOD("create_colliders"), &VoxelChunk::create_colliders);
@ -810,16 +837,14 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("bake_light", "light"), &VoxelChunk::bake_light); ClassDB::bind_method(D_METHOD("bake_light", "light"), &VoxelChunk::bake_light);
ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunk::clear_baked_lights); ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunk::clear_baked_lights);
ClassDB::bind_method(D_METHOD("add_prop_mesh", "mesh", "position", "rotation", "scale"), &VoxelChunk::add_prop_mesh, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelChunk::add_prop);
ClassDB::bind_method(D_METHOD("add_prop_spawned", "scene", "position", "rotation", "scale"), &VoxelChunk::add_prop_spawned, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); ClassDB::bind_method(D_METHOD("get_prop", "index"), &VoxelChunk::get_prop);
ClassDB::bind_method(D_METHOD("add_prop", "prop", "position", "rotation", "scale"), &VoxelChunk::add_prop, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); ClassDB::bind_method(D_METHOD("get_prop_count"), &VoxelChunk::get_prop_count);
ClassDB::bind_method(D_METHOD("remove_prop", "index"), &VoxelChunk::remove_prop);
ClassDB::bind_method(D_METHOD("clear_props"), &VoxelChunk::clear_props); ClassDB::bind_method(D_METHOD("clear_props"), &VoxelChunk::clear_props);
ClassDB::bind_method(D_METHOD("process_prop_lights"), &VoxelChunk::process_prop_lights); BIND_VMETHOD(MethodInfo("_process_props"));
ClassDB::bind_method(D_METHOD("process_props"), &VoxelChunk::process_props); ClassDB::bind_method(D_METHOD("process_props"), &VoxelChunk::process_props);
ClassDB::bind_method(D_METHOD("process_prop", "prop", "transform"), &VoxelChunk::process_prop, DEFVAL(Transform()));
ClassDB::bind_method(D_METHOD("process_prop_light", "prop", "transform"), &VoxelChunk::process_prop_light, DEFVAL(Transform()));
ClassDB::bind_method(D_METHOD("spawn_prop", "transform"), &VoxelChunk::spawn_prop, DEFVAL(Transform()));
ClassDB::bind_method(D_METHOD("build_prop_meshes"), &VoxelChunk::build_prop_meshes); ClassDB::bind_method(D_METHOD("build_prop_meshes"), &VoxelChunk::build_prop_meshes);
ClassDB::bind_method(D_METHOD("build_prop_collider"), &VoxelChunk::build_prop_collider); ClassDB::bind_method(D_METHOD("build_prop_collider"), &VoxelChunk::build_prop_collider);
@ -846,4 +871,12 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_debug_voxels", "pos", "color"), &VoxelChunk::draw_debug_voxels, DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_debug_voxels", "pos", "color"), &VoxelChunk::draw_debug_voxels, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunk::draw_debug_voxel_lights); ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunk::draw_debug_voxel_lights);
BIND_CONSTANT(BUILD_PHASE_DONE);
BIND_CONSTANT(BUILD_PHASE_SETUP);
BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH);
BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH_COLLIDER);
BIND_CONSTANT(BUILD_PHASE_PROP_MESH);
BIND_CONSTANT(BUILD_PHASE_PROP_COLLIDER);
BIND_CONSTANT(BUILD_PHASE_MAX);
} }

View File

@ -31,6 +31,7 @@
#include "../props/voxelman_prop_scene.h" #include "../props/voxelman_prop_scene.h"
#include "../props/voxelman_prop_mesh.h" #include "../props/voxelman_prop_mesh.h"
#include "../props/voxelman_prop_light.h" #include "../props/voxelman_prop_light.h"
#include "voxel_chunk_prop_data.h"
class VoxelWorld; class VoxelWorld;
@ -38,6 +39,7 @@ class VoxelChunk : public Reference {
GDCLASS(VoxelChunk, Reference); GDCLASS(VoxelChunk, Reference);
public: public:
//Properties
int get_chunk_position_x(); int get_chunk_position_x();
void set_chunk_position_x(int value); void set_chunk_position_x(int value);
int get_chunk_position_y(); int get_chunk_position_y();
@ -67,6 +69,9 @@ public:
float get_voxel_scale() const; float get_voxel_scale() const;
void set_voxel_scale(float value); void set_voxel_scale(float value);
int get_current_build_phase();
void set_current_build_phase(int value);
Ref<VoxelMesher> get_mesher() const; Ref<VoxelMesher> get_mesher() const;
void set_mesher(Ref<VoxelMesher> mesher); void set_mesher(Ref<VoxelMesher> mesher);
@ -82,18 +87,35 @@ public:
Ref<VoxelBuffer> get_buffer() const; Ref<VoxelBuffer> get_buffer() const;
RID get_mesh_rid();
RID get_mesh_instance_rid();
RID get_shape_rid();
RID get_body_rid();
RID get_prop_mesh_rid();
RID get_prop_mesh_instance_rid();
RID get_prop_shape_rid();
RID get_prop_body_rid();
//Meshing
void create_mesher(); void create_mesher();
void _create_mesher(); void _create_mesher();
void finalize_mesh(); void finalize_mesh();
void build(); void build();
void build_phase(int phase);
void _build_phase(int phase);
void next_phase();
void clear(); void clear();
//Colliders
void create_colliders(); void create_colliders();
void build_collider(); void build_collider();
void remove_colliders(); void remove_colliders();
//lights
void add_lights(Array lights); void add_lights(Array lights);
void add_voxel_light(Ref<VoxelLight> light); void add_voxel_light(Ref<VoxelLight> light);
void create_voxel_light(const Color color, const int size, const int x, const int y, const int z); void create_voxel_light(const Color color, const int size, const int x, const int y, const int z);
@ -107,22 +129,21 @@ public:
void bake_lights(); void bake_lights();
void bake_light(Ref<VoxelLight> light); void bake_light(Ref<VoxelLight> light);
void clear_baked_lights(); void clear_baked_lights();
void add_prop_mesh(const Ref<MeshDataResource> mesh, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); //props
void add_prop_spawned(const Ref<PackedScene> scene, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); void add_prop(Ref<VoxelChunkPropData> prop);
void add_prop(const Ref<VoxelmanProp> prop, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); Ref<VoxelChunkPropData> get_prop(int index);
int get_prop_count();
void remove_prop(int index);
void clear_props(); void clear_props();
void process_prop_lights();
void process_props(); void process_props();
void process_prop(Ref<VoxelmanProp> prop, const Transform transform = Transform());
void process_prop_light(Ref<VoxelmanPropLight> prop, const Transform transform = Transform());
void spawn_prop(const Ref<PackedScene> scene, const Transform transform = Transform());
void build_prop_meshes(); void build_prop_meshes();
void build_prop_collider(); void build_prop_collider();
void free_spawn_props(); void free_spawn_props();
//Meshes
void allocate_main_mesh(); void allocate_main_mesh();
void free_main_mesh(); void free_main_mesh();
@ -131,32 +152,36 @@ public:
void allocate_prop_colliders(); void allocate_prop_colliders();
void free_prop_colliders(); void free_prop_colliders();
//Debug
void create_debug_immediate_geometry(); void create_debug_immediate_geometry();
void free_debug_immediate_geometry(); void free_debug_immediate_geometry();
void free_chunk();
void draw_cross_voxels(Vector3 pos); void draw_cross_voxels(Vector3 pos);
void draw_cross_voxels_fill(Vector3 pos, float fill); void draw_cross_voxels_fill(Vector3 pos, float fill);
void draw_debug_voxels(int max, Color color = Color(1, 1, 1)); void draw_debug_voxels(int max, Color color = Color(1, 1, 1));
void draw_debug_voxel_lights(); void draw_debug_voxel_lights();
//free
void free_chunk();
VoxelChunk(); VoxelChunk();
~VoxelChunk(); ~VoxelChunk();
protected: public:
struct VCPropData { enum {
Transform transform; BUILD_PHASE_DONE = 0,
BUILD_PHASE_SETUP = 1,
Ref<MeshDataResource> mesh; BUILD_PHASE_TERRARIN_MESH = 2,
Ref<VoxelmanProp> prop; BUILD_PHASE_TERRARIN_MESH_COLLIDER = 3,
Ref<PackedScene> scene; BUILD_PHASE_PROP_MESH = 4,
BUILD_PHASE_PROP_COLLIDER = 5,
BUILD_PHASE_MAX = 6
}; };
protected: protected:
static void _bind_methods(); static void _bind_methods();
int _current_build_phase;
bool _enabled; bool _enabled;
VoxelWorld *_voxel_world; VoxelWorld *_voxel_world;
@ -183,7 +208,7 @@ protected:
Ref<VoxelMesher> _mesher; Ref<VoxelMesher> _mesher;
//mergeable props //mergeable props
Vector<VCPropData> _props; Vector<Ref<VoxelChunkPropData> > _props;
RID _prop_mesh_rid; RID _prop_mesh_rid;
RID _prop_mesh_instance_rid; RID _prop_mesh_instance_rid;

View File

@ -0,0 +1,138 @@
#include "voxel_chunk_prop_data.h"
int VoxelChunkPropData::get_x() {
return _x;
}
void VoxelChunkPropData::set_x(int value) {
_x = value;
}
int VoxelChunkPropData::get_y() {
return _y;
}
void VoxelChunkPropData::set_y(int value) {
_y = value;
}
int VoxelChunkPropData::get_z() {
return _z;
}
void VoxelChunkPropData::set_z(int value) {
_z = value;
}
Vector3 VoxelChunkPropData::get_rotation() {
return _rotation;
}
void VoxelChunkPropData::set_rotation(Vector3 value) {
_rotation = value;
}
Vector3 VoxelChunkPropData::get_scale() {
return _scale;
}
void VoxelChunkPropData::set_scale(Vector3 value) {
_scale = value;
}
bool VoxelChunkPropData::get_snap_to_mesh() {
return _snap_to_mesh;
}
void VoxelChunkPropData::set_snap_to_mesh(bool value) {
_snap_to_mesh = value;
}
Vector3 VoxelChunkPropData::get_snap_axis() {
return _snap_axis;
}
void VoxelChunkPropData::set_snap_axis(Vector3 value) {
_snap_axis = value;
}
Ref<MeshDataResource> VoxelChunkPropData::get_mesh() const {
return _mesh;
}
void VoxelChunkPropData::set_mesh(const Ref<MeshDataResource> value) {
_mesh = value;
}
Ref<VoxelmanPropLight> VoxelChunkPropData::get_light() const {
return _light;
}
void VoxelChunkPropData::set_light(const Ref<VoxelmanPropLight> value) {
_light = value;
}
Ref<VoxelmanProp> VoxelChunkPropData::get_prop() const {
return _prop;
}
void VoxelChunkPropData::set_prop(const Ref<VoxelmanProp> value) {
_prop = value;
}
Ref<PackedScene> VoxelChunkPropData::get_scene() const {
return _scene;
}
void VoxelChunkPropData::set_scene(const Ref<PackedScene> value) {
_scene = value;
}
VoxelChunkPropData::VoxelChunkPropData() {
_x = 0;
_y = 0;
_z = 0;
_scale = Vector3(1, 1, 1);
_snap_to_mesh = false;
}
VoxelChunkPropData::~VoxelChunkPropData() {
_mesh.unref();
_light.unref();
_prop.unref();
_scene.unref();
}
void VoxelChunkPropData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_x"), &VoxelChunkPropData::get_x);
ClassDB::bind_method(D_METHOD("set_x", "value"), &VoxelChunkPropData::set_x);
ADD_PROPERTY(PropertyInfo(Variant::INT, "x"), "set_x", "get_x");
ClassDB::bind_method(D_METHOD("get_y"), &VoxelChunkPropData::get_y);
ClassDB::bind_method(D_METHOD("set_y", "value"), &VoxelChunkPropData::set_y);
ADD_PROPERTY(PropertyInfo(Variant::INT, "y"), "set_y", "get_y");
ClassDB::bind_method(D_METHOD("get_z"), &VoxelChunkPropData::get_z);
ClassDB::bind_method(D_METHOD("set_z", "value"), &VoxelChunkPropData::set_z);
ADD_PROPERTY(PropertyInfo(Variant::INT, "z"), "set_z", "get_z");
ClassDB::bind_method(D_METHOD("get_rotation"), &VoxelChunkPropData::get_rotation);
ClassDB::bind_method(D_METHOD("set_rotation", "value"), &VoxelChunkPropData::set_rotation);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation"), "set_rotation", "get_rotation");
ClassDB::bind_method(D_METHOD("get_scale"), &VoxelChunkPropData::get_scale);
ClassDB::bind_method(D_METHOD("set_scale", "value"), &VoxelChunkPropData::set_scale);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale"), "set_scale", "get_scale");
ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &VoxelChunkPropData::get_snap_to_mesh);
ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &VoxelChunkPropData::set_snap_to_mesh);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh");
ClassDB::bind_method(D_METHOD("get_snap_axis"), &VoxelChunkPropData::get_snap_axis);
ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &VoxelChunkPropData::set_snap_axis);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis");
ClassDB::bind_method(D_METHOD("get_mesh"), &VoxelChunkPropData::get_mesh);
ClassDB::bind_method(D_METHOD("set_mesh", "value"), &VoxelChunkPropData::set_scene);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "MeshDataResource"), "set_mesh", "get_mesh");
ClassDB::bind_method(D_METHOD("get_light"), &VoxelChunkPropData::get_light);
ClassDB::bind_method(D_METHOD("set_light", "value"), &VoxelChunkPropData::set_scene);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanPropLight"), "set_light", "get_light");
ClassDB::bind_method(D_METHOD("get_prop"), &VoxelChunkPropData::get_prop);
ClassDB::bind_method(D_METHOD("set_prop", "value"), &VoxelChunkPropData::set_prop);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "prop", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanProp"), "set_prop", "get_prop");
ClassDB::bind_method(D_METHOD("get_scene"), &VoxelChunkPropData::get_scene);
ClassDB::bind_method(D_METHOD("set_scene", "value"), &VoxelChunkPropData::set_scene);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scene", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_scene", "get_scene");
}

View File

@ -0,0 +1,71 @@
#ifndef VOXEL_CHUNK_PROP_DATA_H
#define VOXEL_CHUNK_PROP_DATA_H
#include "core/reference.h"
#include "core/math/vector3.h"
#include "scene/resources/packed_scene.h"
#include "../props/voxelman_prop.h"
#include "../props/voxelman_prop_light.h"
#include "../../entity_spell_system/meshes/mesh_data_resource.h"
class VoxelChunkPropData : public Reference {
GDCLASS(VoxelChunkPropData, Reference);
public:
int get_x();
void set_x(int value);
int get_y();
void set_y(int value);
int get_z();
void set_z(int value);
Vector3 get_rotation();
void set_rotation(Vector3 value);
Vector3 get_scale();
void set_scale(Vector3 value);
bool get_snap_to_mesh();
void set_snap_to_mesh(bool value);
Vector3 get_snap_axis();
void set_snap_axis(Vector3 value);
Ref<MeshDataResource> get_mesh() const;
void set_mesh(const Ref<MeshDataResource> value);
Ref<VoxelmanPropLight> get_light() const;
void set_light(const Ref<VoxelmanPropLight> value);
Ref<VoxelmanProp> get_prop() const;
void set_prop(const Ref<VoxelmanProp> value);
Ref<PackedScene> get_scene() const;
void set_scene(const Ref<PackedScene> value);
VoxelChunkPropData();
~VoxelChunkPropData();
protected:
static void _bind_methods();
private:
int _x;
int _y;
int _z;
Vector3 _rotation;
Vector3 _scale;
bool _snap_to_mesh;
Vector3 _snap_axis;
Ref<MeshDataResource> _mesh;
Ref<VoxelmanPropLight> _light;
Ref<VoxelmanProp> _prop;
Ref<PackedScene> _scene;
};
#endif