Moved away from using ImmediateGeometry for debug meshes. Also implemented debugging mdr colliders.

This commit is contained in:
Relintai 2020-06-29 23:08:52 +02:00
parent 2e69796d08
commit b54a1021d4
2 changed files with 139 additions and 52 deletions

View File

@ -721,6 +721,10 @@ void VoxelChunkDefault::update_transforms() {
PhysicsServer::get_singleton()->body_set_state(c.body, PhysicsServer::BODY_STATE_TRANSFORM, get_transform() * c.transform); PhysicsServer::get_singleton()->body_set_state(c.body, PhysicsServer::BODY_STATE_TRANSFORM, get_transform() * c.transform);
} }
if (_debug_mesh_instance != RID()) {
VS::get_singleton()->instance_set_transform(_debug_mesh_instance, get_transform());
}
} }
//Lights //Lights
@ -733,65 +737,105 @@ int VoxelChunkDefault::get_light_count() const {
return _lights.size(); return _lights.size();
} }
void VoxelChunkDefault::create_debug_immediate_geometry() { void VoxelChunkDefault::debug_mesh_allocate() {
ERR_FAIL_COND(_voxel_world == NULL); if (_debug_mesh_rid == RID()) {
ERR_FAIL_COND(_debug_drawer != NULL); _debug_mesh_rid = VisualServer::get_singleton()->mesh_create();
}
_debug_drawer = memnew(ImmediateGeometry()); if (_debug_mesh_instance == RID()) {
_debug_mesh_instance = VisualServer::get_singleton()->instance_create();
_voxel_world->add_child(_debug_drawer); if (get_voxel_world()->GET_WORLD().is_valid())
VS::get_singleton()->instance_set_scenario(_debug_mesh_instance, get_voxel_world()->GET_WORLD()->get_scenario());
if (Engine::get_singleton()->is_editor_hint()) VS::get_singleton()->instance_set_base(_debug_mesh_instance, _debug_mesh_rid);
_debug_drawer->set_owner(_voxel_world->get_tree()->get_edited_scene_root()); VS::get_singleton()->instance_set_transform(_debug_mesh_instance, get_transform());
VS::get_singleton()->instance_set_visible(_debug_mesh_instance, true);
//_debug_drawer->set_transform(Transform(Basis(), Vector3(_position.x * _size.x * _voxel_scale, _position.y * _size.y * _voxel_scale, _position.z * _size.z * _voxel_scale))); }
//_debug_drawer->set_transform(Transform(Basis(), Vector3(_position.x * _size.x * _voxel_scale, _position.y * _size.y * _voxel_scale, _position.z * _size.z * _voxel_scale)));
} }
void VoxelChunkDefault::debug_mesh_free() {
if (_debug_mesh_instance != RID()) {
VisualServer::get_singleton()->free(_debug_mesh_instance);
}
void VoxelChunkDefault::free_debug_immediate_geometry() { if (_debug_mesh_rid != RID()) {
if (_debug_drawer != NULL) { VisualServer::get_singleton()->free(_debug_mesh_rid);
_debug_drawer->queue_delete(); }
}
bool VoxelChunkDefault::debug_mesh_has() {
return _debug_mesh_rid != RID();
}
void VoxelChunkDefault::debug_mesh_clear() {
if (_debug_mesh_rid != RID()) {
VisualServer::get_singleton()->mesh_clear(_debug_mesh_rid);
}
}
void VoxelChunkDefault::debug_mesh_array_clear() {
_debug_mesh_array.resize(0);
}
void VoxelChunkDefault::debug_mesh_add_vertices_to(const PoolVector3Array &arr) {
_debug_mesh_array.append_array(arr);
}
void VoxelChunkDefault::debug_mesh_send() {
debug_mesh_allocate();
debug_mesh_clear();
_debug_drawer = NULL; if (_debug_mesh_array.size() == 0)
return;
SceneTree *st = SceneTree::get_singleton();
Array arr;
arr.resize(VisualServer::ARRAY_MAX);
arr[VisualServer::ARRAY_VERTEX] = _debug_mesh_array;
VisualServer::get_singleton()->mesh_add_surface_from_arrays(_debug_mesh_rid, VisualServer::PRIMITIVE_LINES, arr);
if (st) {
VisualServer::get_singleton()->mesh_surface_set_material(_debug_mesh_rid, 0, SceneTree::get_singleton()->get_debug_collision_material()->get_rid());
} }
} }
void VoxelChunkDefault::draw_cross_voxels(Vector3 pos) { void VoxelChunkDefault::draw_cross_voxels(Vector3 pos) {
pos *= _voxel_scale; pos *= _voxel_scale;
_debug_drawer->add_vertex(pos + Vector3(0, 0, -0.2)); int size = _debug_mesh_array.size();
_debug_drawer->add_vertex(pos + Vector3(0, 0, 0.2)); _debug_mesh_array.resize(_debug_mesh_array.size() + 6);
_debug_drawer->add_vertex(pos + Vector3(0, -0.2, 0)); _debug_mesh_array.set(size, pos + Vector3(0, 0, -0.2));
_debug_drawer->add_vertex(pos + Vector3(0, 0.2, 0)); _debug_mesh_array.set(size + 1, pos + Vector3(0, 0, 0.2));
_debug_drawer->add_vertex(pos + Vector3(-0.2, 0, 0)); _debug_mesh_array.set(size + 2, pos + Vector3(0, -0.2, 0));
_debug_drawer->add_vertex(pos + Vector3(0.2, 0, 0)); _debug_mesh_array.set(size + 3, pos + Vector3(0, 0.2, 0));
_debug_mesh_array.set(size + 4, pos + Vector3(-0.2, 0, 0));
_debug_mesh_array.set(size + 5, pos + Vector3(0.2, 0, 0));
} }
void VoxelChunkDefault::draw_cross_voxels_fill(Vector3 pos, float fill) { void VoxelChunkDefault::draw_cross_voxels_fill(Vector3 pos, float fill) {
pos *= _voxel_scale; pos *= _voxel_scale;
_debug_drawer->add_vertex(pos + Vector3(0, 0, -0.5 * fill)); int size = _debug_mesh_array.size();
_debug_drawer->add_vertex(pos + Vector3(0, 0, 0.5 * fill)); _debug_mesh_array.resize(_debug_mesh_array.size() + 6);
_debug_drawer->add_vertex(pos + Vector3(0, -0.5 * fill, 0)); _debug_mesh_array.set(size, pos + Vector3(0, 0, -0.2 * fill));
_debug_drawer->add_vertex(pos + Vector3(0, 0.5 * fill, 0)); _debug_mesh_array.set(size + 1, pos + Vector3(0, 0, 0.2 * fill));
_debug_drawer->add_vertex(pos + Vector3(-0.5 * fill, 0, 0)); _debug_mesh_array.set(size + 2, pos + Vector3(0, -0.2 * fill, 0));
_debug_drawer->add_vertex(pos + Vector3(0.5 * fill, 0, 0)); _debug_mesh_array.set(size + 3, pos + Vector3(0, 0.2 * fill, 0));
_debug_mesh_array.set(size + 4, pos + Vector3(-0.2 * fill, 0, 0));
_debug_mesh_array.set(size + 5, pos + Vector3(0.2 * fill, 0, 0));
} }
void VoxelChunkDefault::draw_debug_voxels(int max, Color color) { void VoxelChunkDefault::draw_debug_voxels(int max, Color color) {
if (_debug_drawer == NULL) { if (!debug_mesh_has()) {
create_debug_immediate_geometry(); debug_mesh_allocate();
} }
ERR_FAIL_COND(_debug_drawer == NULL); //debug_mesh_array_clear();
_debug_drawer->clear(); //_debug_drawer->begin(Mesh::PRIMITIVE_LINES);
_debug_drawer->begin(Mesh::PRIMITIVE_LINES);
_debug_drawer->set_color(color);
int a = 0; int a = 0;
@ -819,19 +863,17 @@ void VoxelChunkDefault::draw_debug_voxels(int max, Color color) {
} }
} }
_debug_drawer->end(); debug_mesh_send();
} }
void VoxelChunkDefault::draw_debug_voxel_lights() { void VoxelChunkDefault::draw_debug_voxel_lights() {
if (_debug_drawer == NULL) { if (!debug_mesh_has()) {
create_debug_immediate_geometry(); debug_mesh_allocate();
} }
ERR_FAIL_COND(_debug_drawer == NULL); //debug_mesh_array_clear();
_debug_drawer->clear(); //_debug_drawer->begin(Mesh::PrimitiveType::PRIMITIVE_LINES);
_debug_drawer->begin(Mesh::PrimitiveType::PRIMITIVE_LINES);
_debug_drawer->set_color(Color(1, 1, 1));
for (int i = 0; i < _lights.size(); ++i) { for (int i = 0; i < _lights.size(); ++i) {
Ref<VoxelLight> v = _lights[i]; Ref<VoxelLight> v = _lights[i];
@ -843,12 +885,35 @@ void VoxelChunkDefault::draw_debug_voxel_lights() {
draw_cross_voxels_fill(Vector3(pos_x, pos_y, pos_z), 1.0); draw_cross_voxels_fill(Vector3(pos_x, pos_y, pos_z), 1.0);
} }
if (has_method("_draw_debug_voxel_lights")) debug_mesh_send();
call("_draw_debug_voxel_lights", _debug_drawer);
_debug_drawer->end();
} }
#ifdef MESH_DATA_RESOURCE_PRESENT
void VoxelChunkDefault::draw_debug_mdr_colliders() {
if (!debug_mesh_has()) {
debug_mesh_allocate();
}
for (int i = 0; i < get_mesh_data_resource_count(); ++i) {
Ref<MeshDataResource> mdr = get_mesh_data_resource(i);
if (!mdr.is_valid())
continue;
Transform t = get_mesh_data_resource_transform(i);
for (int j = 0; j < mdr->get_collision_shape_count(); ++j) {
Ref<Shape> shape = mdr->get_collision_shape(j);
if (!shape.is_valid())
continue;
shape->add_vertices_to_array(_debug_mesh_array, t);
}
}
}
#endif
void VoxelChunkDefault::_visibility_changed(bool visible) { void VoxelChunkDefault::_visibility_changed(bool visible) {
if (visible) { if (visible) {
set_current_lod_level(_current_lod_level); set_current_lod_level(_current_lod_level);
@ -1071,7 +1136,6 @@ VoxelChunkDefault::VoxelChunkDefault() {
_voxel_scale = 1; _voxel_scale = 1;
_lod_size = 1; _lod_size = 1;
_debug_drawer = NULL;
_voxel_world = NULL; _voxel_world = NULL;
_position_x = 0; _position_x = 0;
@ -1676,6 +1740,14 @@ void VoxelChunkDefault::_build_phase_physics_process(int phase) {
_collider_bodies.push_back(c); _collider_bodies.push_back(c);
} }
} }
#if TOOLS_ENABLED
if (SceneTree::get_singleton()->is_debugging_collisions_hint() && _collider_bodies.size() > 0) {
draw_debug_mdr_colliders();
debug_mesh_send();
}
#endif
#endif #endif
set_active_build_phase_type(BUILD_PHASE_TYPE_NORMAL); set_active_build_phase_type(BUILD_PHASE_TYPE_NORMAL);
@ -1811,16 +1883,23 @@ void VoxelChunkDefault::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_light_count"), &VoxelChunkDefault::get_light_count); ClassDB::bind_method(D_METHOD("get_light_count"), &VoxelChunkDefault::get_light_count);
//Debug //Debug
ClassDB::bind_method(D_METHOD("create_debug_immediate_geometry"), &VoxelChunkDefault::create_debug_immediate_geometry); ClassDB::bind_method(D_METHOD("debug_mesh_allocate"), &VoxelChunkDefault::debug_mesh_allocate);
ClassDB::bind_method(D_METHOD("free_debug_immediate_geometry"), &VoxelChunkDefault::free_debug_immediate_geometry); ClassDB::bind_method(D_METHOD("debug_mesh_free"), &VoxelChunkDefault::debug_mesh_free);
BIND_VMETHOD(MethodInfo("_draw_debug_voxel_lights", PropertyInfo(Variant::OBJECT, "debug_drawer", PROPERTY_HINT_RESOURCE_TYPE, "ImmediateGeometry"))); ClassDB::bind_method(D_METHOD("debug_mesh_has"), &VoxelChunkDefault::debug_mesh_has);
ClassDB::bind_method(D_METHOD("debug_mesh_clear"), &VoxelChunkDefault::debug_mesh_clear);
ClassDB::bind_method(D_METHOD("debug_mesh_array_clear"), &VoxelChunkDefault::debug_mesh_array_clear);
ClassDB::bind_method(D_METHOD("debug_mesh_add_vertices_to", "arr"), &VoxelChunkDefault::debug_mesh_add_vertices_to);
ClassDB::bind_method(D_METHOD("debug_mesh_send"), &VoxelChunkDefault::debug_mesh_send);
ClassDB::bind_method(D_METHOD("draw_cross_voxels", "max"), &VoxelChunkDefault::draw_cross_voxels); ClassDB::bind_method(D_METHOD("draw_cross_voxels", "max"), &VoxelChunkDefault::draw_cross_voxels);
ClassDB::bind_method(D_METHOD("draw_cross_voxels_fill", "max", "fill"), &VoxelChunkDefault::draw_cross_voxels_fill); ClassDB::bind_method(D_METHOD("draw_cross_voxels_fill", "max", "fill"), &VoxelChunkDefault::draw_cross_voxels_fill);
ClassDB::bind_method(D_METHOD("draw_debug_voxels", "max", "color"), &VoxelChunkDefault::draw_debug_voxels, DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_debug_voxels", "max", "color"), &VoxelChunkDefault::draw_debug_voxels, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunkDefault::draw_debug_voxel_lights); ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunkDefault::draw_debug_voxel_lights);
#ifdef MESH_DATA_RESOURCE_PRESENT
ClassDB::bind_method(D_METHOD("draw_debug_mdr_colliders"), &VoxelChunkDefault::draw_debug_mdr_colliders);
#endif
//Free //Free
ClassDB::bind_method(D_METHOD("free_chunk"), &VoxelChunkDefault::free_chunk); ClassDB::bind_method(D_METHOD("free_chunk"), &VoxelChunkDefault::free_chunk);

View File

@ -27,8 +27,6 @@ SOFTWARE.
#include "../../defines.h" #include "../../defines.h"
#include immediate_geometry_h
#include "core/engine.h" #include "core/engine.h"
#include "core/os/mutex.h" #include "core/os/mutex.h"
#include "core/os/thread.h" #include "core/os/thread.h"
@ -205,13 +203,21 @@ public:
int get_light_count() const; int get_light_count() const;
//Debug //Debug
void create_debug_immediate_geometry(); void debug_mesh_allocate();
void free_debug_immediate_geometry(); void debug_mesh_free();
bool debug_mesh_has();
void debug_mesh_clear();
void debug_mesh_array_clear();
void debug_mesh_add_vertices_to(const PoolVector3Array &arr);
void debug_mesh_send();
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();
#ifdef MESH_DATA_RESOURCE_PRESENT
void draw_debug_mdr_colliders();
#endif
//Visibility //Visibility
void visibility_changed(bool visible); void visibility_changed(bool visible);
@ -285,7 +291,9 @@ protected:
Dictionary _rids; Dictionary _rids;
//debug //debug
ImmediateGeometry *_debug_drawer; RID _debug_mesh_rid;
RID _debug_mesh_instance;
PoolVector3Array _debug_mesh_array;
bool _build_prioritized; bool _build_prioritized;
bool _build_phase_done; bool _build_phase_done;