Now VoxelChunk uses the VisualServer, and PhysicsServer directly.

This commit is contained in:
Relintai 2019-07-18 01:43:58 +02:00
parent 7db42b88a1
commit 9c036f0706
4 changed files with 145 additions and 135 deletions

View File

@ -32,7 +32,11 @@ VoxelMesher::~VoxelMesher() {
} }
} }
Ref<ArrayMesh> VoxelMesher::build_mesh() { void VoxelMesher::build_mesh(RID mesh) {
ERR_FAIL_COND(mesh == RID());
VS::get_singleton()->mesh_clear(mesh);
_surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES); _surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
_surface_tool->set_material(_library->get_material()); _surface_tool->set_material(_library->get_material());
@ -62,9 +66,9 @@ Ref<ArrayMesh> VoxelMesher::build_mesh() {
_surface_tool->generate_normals(); _surface_tool->generate_normals();
} }
Ref<ArrayMesh> m = _surface_tool->commit(); Array arr = _surface_tool->commit_to_arrays();
return m; VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VisualServer::PRIMITIVE_TRIANGLES, arr);
} }
void VoxelMesher::reset() { void VoxelMesher::reset() {
@ -96,7 +100,9 @@ void VoxelMesher::set_lod_size(const int lod_size) {
_lod_size = lod_size; _lod_size = lod_size;
} }
void VoxelMesher::create_trimesh_shape(Ref<ConcavePolygonShape> shape) const { void VoxelMesher::build_collider(RID shape) const {
ERR_FAIL_COND(shape == RID());
if (_vertices.size() == 0) if (_vertices.size() == 0)
return; return;
@ -117,7 +123,7 @@ void VoxelMesher::create_trimesh_shape(Ref<ConcavePolygonShape> shape) const {
face_points.push_back(_vertices.get((i * 4) + 2)); face_points.push_back(_vertices.get((i * 4) + 2));
} }
shape->set_faces(face_points); PhysicsServer::get_singleton()->shape_set_data(shape, face_points);
return; return;
} }
@ -127,7 +133,7 @@ void VoxelMesher::create_trimesh_shape(Ref<ConcavePolygonShape> shape) const {
face_points.set(i, _vertices.get(_indices.get(i))); face_points.set(i, _vertices.get(_indices.get(i)));
} }
shape->set_faces(face_points); PhysicsServer::get_singleton()->shape_set_data(shape, face_points);
} }
void VoxelMesher::bake_lights(MeshInstance *node, Vector<Ref<VoxelLight> > &lights) { void VoxelMesher::bake_lights(MeshInstance *node, Vector<Ref<VoxelLight> > &lights) {
@ -364,5 +370,5 @@ void VoxelMesher::_bind_methods() {
//ClassDB::bind_method(D_METHOD("calculate_vertex_ambient_occlusion", "meshinstance_path", "radius", "intensity", "sampleCount"), &VoxelMesher::calculate_vertex_ambient_occlusion_path); //ClassDB::bind_method(D_METHOD("calculate_vertex_ambient_occlusion", "meshinstance_path", "radius", "intensity", "sampleCount"), &VoxelMesher::calculate_vertex_ambient_occlusion_path);
ClassDB::bind_method(D_METHOD("build_mesh"), &VoxelMesher::build_mesh); ClassDB::bind_method(D_METHOD("build_mesh", "mesh_rid"), &VoxelMesher::build_mesh);
} }

View File

@ -42,10 +42,11 @@ public:
int get_lod_size() const; int get_lod_size() const;
void set_lod_size(const int lod_size); void set_lod_size(const int lod_size);
void create_trimesh_shape(Ref<ConcavePolygonShape> shape) const; void build_collider(RID shape) const;
void bake_lights(MeshInstance *node, Vector<Ref<VoxelLight> > &lights); void bake_lights(MeshInstance *node, Vector<Ref<VoxelLight> > &lights);
Ref<ArrayMesh> build_mesh(); void build_mesh(RID mesh);
Vector<Vector3> *get_vertices(); Vector<Vector3> *get_vertices();
int get_vertex_count(); int get_vertex_count();

View File

@ -60,13 +60,6 @@ void VoxelChunk::set_chunk_size(int x, int y, int z) {
_chunk_size.z = z; _chunk_size.z = z;
} }
NodePath VoxelChunk::get_mesh_instance_path() const {
return _mesh_instance_path;
}
void VoxelChunk::set_mesh_instance_path(NodePath value) {
_mesh_instance_path = value;
}
Ref<VoxelmanLibrary> VoxelChunk::get_library() { Ref<VoxelmanLibrary> VoxelChunk::get_library() {
return _library; return _library;
} }
@ -124,13 +117,6 @@ void VoxelChunk::set_bake_lights(bool value) {
_bake_lights = value; _bake_lights = value;
} }
NodePath VoxelChunk::get_debug_drawer_path() {
return _debug_drawer_path;
}
void VoxelChunk::set_debug_drawer_path(NodePath value) {
_debug_drawer_path = value;
}
Ref<VoxelBuffer> VoxelChunk::get_buffer() const { Ref<VoxelBuffer> VoxelChunk::get_buffer() const {
return _buffer; return _buffer;
} }
@ -148,14 +134,6 @@ void VoxelChunk::build() {
_mesher->set_library(_library); _mesher->set_library(_library);
if (_debug_drawer == NULL) {
Node *n = get_node_or_null(_debug_drawer_path);
if (n != NULL) {
_debug_drawer = Object::cast_to<ImmediateGeometry>(n);
}
}
if (get_build_mesh()) { if (get_build_mesh()) {
if (has_method("_create_mesh")) { if (has_method("_create_mesh")) {
call("_create_mesh"); call("_create_mesh");
@ -167,7 +145,11 @@ void VoxelChunk::build() {
} }
if (get_create_collider()) { if (get_create_collider()) {
update_collider(); if (_body_rid == RID()) {
create_colliders();
}
build_collider();
} }
} }
@ -187,50 +169,38 @@ void VoxelChunk::_create_mesher() {
void VoxelChunk::finalize_mesh() { void VoxelChunk::finalize_mesh() {
_mesher->set_library(_library); _mesher->set_library(_library);
Node *node = get_node(_mesh_instance_path); if (_mesh_rid == RID()) {
create_meshes();
ERR_FAIL_COND(node == NULL);
_mesh_instance = Object::cast_to<MeshInstance>(node);
ERR_FAIL_COND(_mesh_instance == NULL);
//if (get_bake_ambient_occlusion()) {
// set_enabled(true);
//} else {
Ref<ArrayMesh> mesh = get_mesher()->build_mesh();
_mesh_instance->set_mesh(mesh);
//}
}
void VoxelChunk::update_collider() {
//_mesh_instance->create_trimesh_collision();
//StaticBody *static_body = Object::cast_to<StaticBody>(create_trimesh_collision_node());
StaticBody *static_body = create_trimesh_collision_node();
ERR_FAIL_COND(!static_body);
static_body->set_name(String(get_name()) + "_col");
add_child(static_body);
if (get_owner()) {
CollisionShape *cshape = Object::cast_to<CollisionShape>(static_body->get_child(0));
static_body->set_owner(get_owner());
cshape->set_owner(get_owner());
} }
get_mesher()->build_mesh(_mesh_rid);
} }
StaticBody *VoxelChunk::create_trimesh_collision_node() { void VoxelChunk::create_colliders() {
_shape_rid = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON);
_body_rid = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
Ref<ConcavePolygonShape> shape = memnew(ConcavePolygonShape); PhysicsServer::get_singleton()->body_set_collision_layer(_body_rid, 1);
PhysicsServer::get_singleton()->body_set_collision_mask(_body_rid, 1);
_mesher->create_trimesh_shape(shape); PhysicsServer::get_singleton()->body_add_shape(_body_rid, _shape_rid);
StaticBody *static_body = memnew(StaticBody); PhysicsServer::get_singleton()->body_set_state(_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, 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)));
CollisionShape *cshape = memnew(CollisionShape); PhysicsServer::get_singleton()->body_set_space(_body_rid, get_world()->get_space());
cshape->set_shape(shape); }
static_body->add_child(cshape);
return static_body; void VoxelChunk::build_collider() {
_mesher->build_collider(_shape_rid);
}
void VoxelChunk::remove_colliders() {
if (_body_rid != RID()) {
PhysicsServer::get_singleton()->free(_body_rid);
PhysicsServer::get_singleton()->free(_shape_rid);
_body_rid = RID();
_shape_rid = RID();
}
} }
void VoxelChunk::set_enabled(bool p_enabled) { void VoxelChunk::set_enabled(bool p_enabled) {
@ -291,7 +261,6 @@ void VoxelChunk::bake_light(Ref<VoxelLight> light) {
int wpy = wp.y - (_chunk_position.y * _chunk_size.y); int wpy = wp.y - (_chunk_position.y * _chunk_size.y);
int wpz = wp.z - (_chunk_position.z * _chunk_size.z); int wpz = wp.z - (_chunk_position.z * _chunk_size.z);
//int wpx = (int)(wp.x / _chunk_size.x) - _chunk_position.x; //int wpx = (int)(wp.x / _chunk_size.x) - _chunk_position.x;
//int wpy = (int)(wp.y / _chunk_size.y) - _chunk_position.y; //int wpy = (int)(wp.y / _chunk_size.y) - _chunk_position.y;
//int wpz = (int)(wp.z / _chunk_size.z) - _chunk_position.z; //int wpz = (int)(wp.z / _chunk_size.z) - _chunk_position.z;
@ -303,6 +272,54 @@ void VoxelChunk::clear_baked_lights() {
_buffer->clear_lights(); _buffer->clear_lights();
} }
void VoxelChunk::create_meshes() {
ERR_FAIL_COND(!get_library().is_valid());
_mesh_instance_rid = VS::get_singleton()->instance_create();
if (get_library()->get_material().is_valid()) {
VS::get_singleton()->instance_geometry_set_material_override(_mesh_instance_rid, get_library()->get_material()->get_rid());
}
if (get_world().is_valid())
VS::get_singleton()->instance_set_scenario(_mesh_instance_rid, get_world()->get_scenario());
_mesh_rid = VS::get_singleton()->mesh_create();
VS::get_singleton()->instance_set_base(_mesh_instance_rid, _mesh_rid);
VS::get_singleton()->instance_set_transform(_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::remove_meshes() {
if (_mesh_instance_rid != RID()) {
VS::get_singleton()->free(_mesh_instance_rid);
VS::get_singleton()->free(_mesh_rid);
_mesh_instance_rid = RID();
_mesh_rid = RID();
}
}
void VoxelChunk::create_debug_immediate_geometry() {
ERR_FAIL_COND(_debug_drawer != NULL);
_debug_drawer = memnew(ImmediateGeometry());
get_parent()->add_child(_debug_drawer);
_debug_drawer->set_owner(get_parent());
_debug_drawer->set_transform(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::free_debug_immediate_geometry() {
if (_debug_drawer != NULL) {
_debug_drawer->queue_delete();
_debug_drawer = NULL;
}
}
void VoxelChunk::draw_cross_voxels(Vector3 pos) { void VoxelChunk::draw_cross_voxels(Vector3 pos) {
pos *= _voxel_scale; pos *= _voxel_scale;
@ -331,11 +348,7 @@ void VoxelChunk::draw_cross_voxels(Vector3 pos, float fill) {
void VoxelChunk::draw_debug_voxels(int max, Color color) { void VoxelChunk::draw_debug_voxels(int max, Color color) {
if (_debug_drawer == NULL) { if (_debug_drawer == NULL) {
Node *n = get_node(_debug_drawer_path); create_debug_immediate_geometry();
if (n != NULL) {
_debug_drawer = Object::cast_to<ImmediateGeometry>(n);
}
} }
ERR_FAIL_COND(_debug_drawer == NULL); ERR_FAIL_COND(_debug_drawer == NULL);
@ -373,11 +386,7 @@ void VoxelChunk::draw_debug_voxels(int max, Color color) {
void VoxelChunk::draw_debug_voxel_lights() { void VoxelChunk::draw_debug_voxel_lights() {
if (_debug_drawer == NULL) { if (_debug_drawer == NULL) {
Node *n = get_node(_debug_drawer_path); create_debug_immediate_geometry();
if (n != NULL) {
_debug_drawer = Object::cast_to<ImmediateGeometry>(n);
}
} }
ERR_FAIL_COND(_debug_drawer == NULL); ERR_FAIL_COND(_debug_drawer == NULL);
@ -401,6 +410,36 @@ void VoxelChunk::draw_debug_voxel_lights() {
_debug_drawer->end(); _debug_drawer->end();
} }
VoxelChunk::VoxelChunk() {
_build_mesh = true;
_create_collider = true;
_bake_lights = true;
_voxel_scale = 1;
_lod_size = 1;
_buffer.instance();
_debug_drawer = NULL;
}
VoxelChunk::~VoxelChunk() {
remove_meshes();
remove_colliders();
_voxel_lights.clear();
if (_mesher.is_valid()) {
_mesher.unref();
}
_buffer.unref();
if (_library.is_valid()) {
_library.unref();
}
}
void VoxelChunk::_bind_methods() { void VoxelChunk::_bind_methods() {
BIND_VMETHOD(MethodInfo("_create_mesh")); BIND_VMETHOD(MethodInfo("_create_mesh"));
BIND_VMETHOD(MethodInfo("_create_mesher")); BIND_VMETHOD(MethodInfo("_create_mesher"));
@ -435,10 +474,6 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_chunk_size", "x", "y", "z"), &VoxelChunk::set_chunk_size); ClassDB::bind_method(D_METHOD("set_chunk_size", "x", "y", "z"), &VoxelChunk::set_chunk_size);
ClassDB::bind_method(D_METHOD("get_mesh_instance_path"), &VoxelChunk::get_mesh_instance_path);
ClassDB::bind_method(D_METHOD("set_mesh_instance_path", "value"), &VoxelChunk::set_mesh_instance_path);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "mesh_instance_path"), "set_mesh_instance_path", "get_mesh_instance_path");
ClassDB::bind_method(D_METHOD("get_library"), &VoxelChunk::get_library); ClassDB::bind_method(D_METHOD("get_library"), &VoxelChunk::get_library);
ClassDB::bind_method(D_METHOD("set_library", "value"), &VoxelChunk::set_library); ClassDB::bind_method(D_METHOD("set_library", "value"), &VoxelChunk::set_library);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanLibrary"), "set_library", "get_library"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanLibrary"), "set_library", "get_library");
@ -469,10 +504,6 @@ void VoxelChunk::_bind_methods() {
ADD_GROUP("Settings", "setting"); ADD_GROUP("Settings", "setting");
ClassDB::bind_method(D_METHOD("get_debug_drawer_path"), &VoxelChunk::get_debug_drawer_path);
ClassDB::bind_method(D_METHOD("set_debug_drawer_path", "value"), &VoxelChunk::set_debug_drawer_path);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "debug_drawer_path"), "set_debug_drawer_path", "get_debug_drawer_path");
ClassDB::bind_method(D_METHOD("get_mesher"), &VoxelChunk::get_mesher); ClassDB::bind_method(D_METHOD("get_mesher"), &VoxelChunk::get_mesher);
ClassDB::bind_method(D_METHOD("set_mesher", "Mesher"), &VoxelChunk::set_mesher); ClassDB::bind_method(D_METHOD("set_mesher", "Mesher"), &VoxelChunk::set_mesher);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesher", PROPERTY_HINT_RESOURCE_TYPE, "VoxelMesher"), "set_mesher", "get_mesher"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesher", PROPERTY_HINT_RESOURCE_TYPE, "VoxelMesher"), "set_mesher", "get_mesher");
@ -495,36 +526,7 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_debug_voxels", "max"), &VoxelChunk::draw_debug_voxels, DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_debug_voxels", "max"), &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);
}
ClassDB::bind_method(D_METHOD("create_debug_immediate_geometry"), &VoxelChunk::create_debug_immediate_geometry);
VoxelChunk::VoxelChunk() { ClassDB::bind_method(D_METHOD("free_debug_immediate_geometry"), &VoxelChunk::free_debug_immediate_geometry);
_build_mesh = true;
_create_collider = true;
_bake_lights = true;
_voxel_scale = 1;
_buffer.instance();
_debug_drawer = NULL;
}
VoxelChunk::~VoxelChunk() {
_voxel_lights.clear();
if (_mesher.is_valid()) {
_mesher.unref();
}
_buffer.unref();
_debug_drawer = NULL;
if (_library.is_valid()) {
_library.unref();
}
if (_mesh.is_valid()) {
_mesh.unref();
}
} }

View File

@ -46,9 +46,6 @@ public:
Vector3i get_chunk_size() const; Vector3i get_chunk_size() const;
void set_chunk_size(int x, int y, int z); void set_chunk_size(int x, int y, int z);
NodePath get_mesh_instance_path() const;
void set_mesh_instance_path(NodePath value);
Ref<VoxelmanLibrary> get_library(); Ref<VoxelmanLibrary> get_library();
void set_library(Ref<VoxelmanLibrary> value); void set_library(Ref<VoxelmanLibrary> value);
@ -70,9 +67,6 @@ public:
bool get_bake_lights() const; bool get_bake_lights() const;
void set_bake_lights(bool value); void set_bake_lights(bool value);
NodePath get_debug_drawer_path();
void set_debug_drawer_path(NodePath value);
Ref<VoxelBuffer> get_buffer() const; Ref<VoxelBuffer> get_buffer() const;
void create_mesher(); void create_mesher();
@ -83,7 +77,9 @@ public:
void clear(); void clear();
void build(); void build();
void update_collider(); void create_colliders();
void build_collider();
void remove_colliders();
void set_enabled(bool p_enabled); void set_enabled(bool p_enabled);
bool is_enabled() const; bool is_enabled() const;
@ -99,16 +95,20 @@ public:
void bake_light(Ref<VoxelLight> light); void bake_light(Ref<VoxelLight> light);
void clear_baked_lights(); void clear_baked_lights();
StaticBody *create_trimesh_collision_node(); void create_meshes();
void remove_meshes();
VoxelChunk(); void create_debug_immediate_geometry();
~VoxelChunk(); void free_debug_immediate_geometry();
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();
void draw_cross_voxels(Vector3 pos); void draw_cross_voxels(Vector3 pos);
void draw_cross_voxels(Vector3 pos, float fill); void draw_cross_voxels(Vector3 pos, float fill);
VoxelChunk();
~VoxelChunk();
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -126,14 +126,15 @@ protected:
NodePath _library_path; NodePath _library_path;
Ref<VoxelmanLibrary> _library; Ref<VoxelmanLibrary> _library;
NodePath _mesh_instance_path; RID _mesh_rid;
MeshInstance *_mesh_instance; RID _mesh_instance_rid;
Ref<ArrayMesh> _mesh;
RID _shape_rid;
RID _body_rid;
Ref<VoxelMesher> _mesher; Ref<VoxelMesher> _mesher;
ImmediateGeometry *_debug_drawer; ImmediateGeometry *_debug_drawer;
NodePath _debug_drawer_path;
bool _build_mesh; bool _build_mesh;
bool _create_collider; bool _create_collider;