Skip to content

Commit

Permalink
Merge pull request #57627 from JFonS/occluder_improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga authored Feb 8, 2022
2 parents 8907c56 + dd97048 commit 25d4c14
Show file tree
Hide file tree
Showing 23 changed files with 1,195 additions and 186 deletions.
24 changes: 24 additions & 0 deletions doc/classes/ArrayOccluder3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ArrayOccluder3D" inherits="Occluder3D" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="set_arrays">
<return type="void" />
<argument index="0" name="vertices" type="PackedVector3Array" />
<argument index="1" name="indices" type="PackedInt32Array" />
<description>
</description>
</method>
</methods>
<members>
<member name="indices" type="PackedInt32Array" setter="set_indices" getter="get_indices" default="PackedInt32Array()">
</member>
<member name="vertices" type="PackedVector3Array" setter="set_vertices" getter="get_vertices" default="PackedVector3Array()">
</member>
</members>
</class>
13 changes: 13 additions & 0 deletions doc/classes/BoxOccluder3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BoxOccluder3D" inherits="Occluder3D" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<members>
<member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(1, 1, 1)">
</member>
</members>
</class>
18 changes: 12 additions & 6 deletions doc/classes/Occluder3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@
</description>
<tutorials>
</tutorials>
<members>
<member name="indices" type="PackedInt32Array" setter="set_indices" getter="get_indices" default="PackedInt32Array()">
</member>
<member name="vertices" type="PackedVector3Array" setter="set_vertices" getter="get_vertices" default="PackedVector3Array()">
</member>
</members>
<methods>
<method name="get_indices" qualifiers="const">
<return type="PackedInt32Array" />
<description>
</description>
</method>
<method name="get_vertices" qualifiers="const">
<return type="PackedVector3Array" />
<description>
</description>
</method>
</methods>
</class>
2 changes: 2 additions & 0 deletions doc/classes/OccluderInstance3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<members>
<member name="bake_mask" type="int" setter="set_bake_mask" getter="get_bake_mask" default="4294967295">
</member>
<member name="bake_simplification_distance" type="float" setter="set_bake_simplification_distance" getter="get_bake_simplification_distance" default="0.1">
</member>
<member name="occluder" type="Occluder3D" setter="set_occluder" getter="get_occluder">
</member>
</members>
Expand Down
13 changes: 13 additions & 0 deletions doc/classes/PolygonOccluder3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PolygonOccluder3D" inherits="Occluder3D" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<members>
<member name="polygon" type="PackedVector2Array" setter="set_polygon" getter="get_polygon" default="PackedVector2Array()">
</member>
</members>
</class>
13 changes: 13 additions & 0 deletions doc/classes/QuadOccluder3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="QuadOccluder3D" inherits="Occluder3D" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<members>
<member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2(1, 1)">
</member>
</members>
</class>
13 changes: 13 additions & 0 deletions doc/classes/SphereOccluder3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SphereOccluder3D" inherits="Occluder3D" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<members>
<member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
</member>
</members>
</class>
3 changes: 2 additions & 1 deletion editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@
#include "editor/plugins/camera_3d_editor_plugin.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/plugins/collision_polygon_2d_editor_plugin.h"
#include "editor/plugins/collision_polygon_3d_editor_plugin.h"
#include "editor/plugins/collision_shape_2d_editor_plugin.h"
#include "editor/plugins/cpu_particles_2d_editor_plugin.h"
#include "editor/plugins/cpu_particles_3d_editor_plugin.h"
Expand Down Expand Up @@ -162,6 +161,7 @@
#include "editor/plugins/path_3d_editor_plugin.h"
#include "editor/plugins/physical_bone_3d_editor_plugin.h"
#include "editor/plugins/polygon_2d_editor_plugin.h"
#include "editor/plugins/polygon_3d_editor_plugin.h"
#include "editor/plugins/replication_editor_plugin.h"
#include "editor/plugins/resource_preloader_editor_plugin.h"
#include "editor/plugins/root_motion_editor_plugin.h"
Expand Down Expand Up @@ -5676,6 +5676,7 @@ void EditorNode::_feature_profile_changed() {
void EditorNode::_bind_methods() {
GLOBAL_DEF("editor/scene/scene_naming", SCENE_NAME_CASING_SNAKE_CASE);
ProjectSettings::get_singleton()->set_custom_property_info("editor/scene/scene_naming", PropertyInfo(Variant::INT, "editor/scene/scene_naming", PROPERTY_HINT_ENUM, "Auto,PascalCase,snake_case"));
ClassDB::bind_method("edit_current", &EditorNode::edit_current);
ClassDB::bind_method("_editor_select", &EditorNode::_editor_select);
ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed);
ClassDB::bind_method("edit_node", &EditorNode::edit_node);
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_properties_array_dict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ void EditorPropertyArray::_reorder_button_up() {
Variant array = object->get_array();

Variant value_to_move = array.get(reorder_from_index);
array.call("remove", reorder_from_index);
array.call("remove_at", reorder_from_index);
array.call("insert", reorder_to_index, value_to_move);

emit_changed(get_edited_property(), array, "", false);
Expand Down
116 changes: 95 additions & 21 deletions editor/import/resource_importer_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/navigation_region_3d.h"
#include "scene/3d/occluder_instance_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/3d/vehicle_body_3d.h"
#include "scene/animation/animation_player.h"
Expand Down Expand Up @@ -371,10 +372,10 @@ static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r
}
}

Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, List<Pair<NodePath, Node *>> &r_node_renames) {
Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames) {
// Children first.
for (int i = 0; i < p_node->get_child_count(); i++) {
Node *r = _pre_fix_node(p_node->get_child(i), p_root, collision_map, r_node_renames);
Node *r = _pre_fix_node(p_node->get_child(i), p_root, r_collision_map, r_occluder_arrays, r_node_renames);
if (!r) {
i--; // Was erased.
}
Expand Down Expand Up @@ -498,14 +499,14 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I

if (mesh.is_valid()) {
Vector<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
if (r_collision_map.has(mesh)) {
shapes = r_collision_map[mesh];
} else if (_teststr(name, "colonly")) {
_pre_gen_shape_list(mesh, shapes, false);
collision_map[mesh] = shapes;
r_collision_map[mesh] = shapes;
} else if (_teststr(name, "convcolonly")) {
_pre_gen_shape_list(mesh, shapes, true);
collision_map[mesh] = shapes;
r_collision_map[mesh] = shapes;
}

if (shapes.size()) {
Expand Down Expand Up @@ -560,8 +561,8 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I

if (mesh.is_valid()) {
Vector<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
if (r_collision_map.has(mesh)) {
shapes = r_collision_map[mesh];
} else {
_pre_gen_shape_list(mesh, shapes, true);
}
Expand All @@ -586,14 +587,14 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
if (mesh.is_valid()) {
Vector<Ref<Shape3D>> shapes;
String fixed_name;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
if (r_collision_map.has(mesh)) {
shapes = r_collision_map[mesh];
} else if (_teststr(name, "col")) {
_pre_gen_shape_list(mesh, shapes, false);
collision_map[mesh] = shapes;
r_collision_map[mesh] = shapes;
} else if (_teststr(name, "convcol")) {
_pre_gen_shape_list(mesh, shapes, true);
collision_map[mesh] = shapes;
r_collision_map[mesh] = shapes;
}

if (_teststr(name, "col")) {
Expand Down Expand Up @@ -635,7 +636,31 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
p_node->replace_by(nmi);
memdelete(p_node);
p_node = nmi;
} else if (_teststr(name, "occ") || _teststr(name, "occonly")) {
if (isroot) {
return p_node;
}
ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
if (mi) {
Ref<ImporterMesh> mesh = mi->get_mesh();

if (mesh.is_valid()) {
if (r_occluder_arrays) {
OccluderInstance3D::bake_single_node(mi, 0.0f, r_occluder_arrays->first, r_occluder_arrays->second);
}
if (_teststr(name, "occ")) {
String fixed_name = _fixstr(name, "occ");
if (!fixed_name.is_empty()) {
if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) {
mi->set_name(fixed_name);
}
}
} else {
memdelete(p_node);
p_node = nullptr;
}
}
}
} else if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
//last attempt, maybe collision inside the mesh data

Expand All @@ -644,16 +669,21 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
Ref<ImporterMesh> mesh = mi->get_mesh();
if (!mesh.is_null()) {
Vector<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
if (r_collision_map.has(mesh)) {
shapes = r_collision_map[mesh];
} else if (_teststr(mesh->get_name(), "col")) {
_pre_gen_shape_list(mesh, shapes, false);
collision_map[mesh] = shapes;
r_collision_map[mesh] = shapes;
mesh->set_name(_fixstr(mesh->get_name(), "col"));
} else if (_teststr(mesh->get_name(), "convcol")) {
_pre_gen_shape_list(mesh, shapes, true);
collision_map[mesh] = shapes;
r_collision_map[mesh] = shapes;
mesh->set_name(_fixstr(mesh->get_name(), "convcol"));
} else if (_teststr(mesh->get_name(), "occ")) {
if (r_occluder_arrays) {
OccluderInstance3D::bake_single_node(mi, 0.0f, r_occluder_arrays->first, r_occluder_arrays->second);
}
mesh->set_name(_fixstr(mesh->get_name(), "occ"));
}

if (shapes.size()) {
Expand All @@ -677,10 +707,10 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
return p_node;
}

Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) {
Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) {
// children first
for (int i = 0; i < p_node->get_child_count(); i++) {
Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps);
Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_occluder_arrays, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps);
if (!r) {
i--; //was erased
}
Expand Down Expand Up @@ -883,6 +913,32 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
}
}

if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);

Ref<ImporterMesh> m = mi->get_mesh();

if (m.is_valid()) {
if (node_settings.has("generate/occluder")) {
int occluder_mode = node_settings["generate/occluder"];

if (occluder_mode != OCCLUDER_DISABLED) {
float simplification_dist = 0.0f;
if (node_settings.has("occluder/simplification_distance")) {
simplification_dist = node_settings["occluder/simplification_distance"];
}

OccluderInstance3D::bake_single_node(mi, simplification_dist, r_occluder_arrays.first, r_occluder_arrays.second);

if (occluder_mode == OCCLUDER_OCCLUDER_ONLY) {
memdelete(p_node);
p_node = nullptr;
}
}
}
}
}

if (Object::cast_to<AnimationPlayer>(p_node)) {
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);

Expand Down Expand Up @@ -1255,6 +1311,9 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "primitive/radius", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1.0));
r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3()));
r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3()));

r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/occluder", PROPERTY_HINT_ENUM, "Disabled,Mesh + Occluder,Occluder Only", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "occluder/simplification_distance", PROPERTY_HINT_RANGE, "0.0,2.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0.1f));
} break;
case INTERNAL_IMPORT_CATEGORY_MESH: {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
Expand Down Expand Up @@ -1376,6 +1435,11 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
(physics_shape == SHAPE_TYPE_CYLINDER ||
physics_shape == SHAPE_TYPE_CAPSULE);
}

if (p_option == "occluder/simplification_distance") {
// Show only if occluder generation is enabled
return p_options.has("generate/occluder") && p_options["generate/occluder"].operator signed int() != OCCLUDER_DISABLED;
}
} break;
case INTERNAL_IMPORT_CATEGORY_MESH: {
if (p_option == "save_to_file/path" || p_option == "save_to_file/make_streamable") {
Expand Down Expand Up @@ -1869,7 +1933,7 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) {

Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
List<Pair<NodePath, Node *>> node_renames;
_pre_fix_node(scene, scene, collision_map, node_renames);
_pre_fix_node(scene, scene, collision_map, nullptr, node_renames);

return scene;
}
Expand Down Expand Up @@ -1944,15 +2008,16 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p

Set<Ref<ImporterMesh>> scanned_meshes;
Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
Pair<PackedVector3Array, PackedInt32Array> occluder_arrays;
List<Pair<NodePath, Node *>> node_renames;

_pre_fix_node(scene, scene, collision_map, node_renames);
_pre_fix_node(scene, scene, collision_map, &occluder_arrays, node_renames);

for (int i = 0; i < post_importer_plugins.size(); i++) {
post_importer_plugins.write[i]->pre_process(scene, p_options);
}

_post_fix_node(scene, scene, collision_map, scanned_meshes, node_data, material_data, animation_data, fps);
_post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps);

String root_type = p_options["nodes/root_type"];
root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class.
Expand Down Expand Up @@ -1989,6 +2054,15 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
scene->set_name(p_save_path.get_file().get_basename());
}

if (!occluder_arrays.first.is_empty() && !occluder_arrays.second.is_empty()) {
Ref<ArrayOccluder3D> occ = memnew(ArrayOccluder3D);
occ->set_arrays(occluder_arrays.first, occluder_arrays.second);
OccluderInstance3D *occluder_instance = memnew(OccluderInstance3D);
occluder_instance->set_occluder(occ);
scene->add_child(occluder_instance, true);
occluder_instance->set_owner(scene);
}

bool gen_lods = bool(p_options["meshes/generate_lods"]);
bool create_shadow_meshes = bool(p_options["meshes/create_shadow_meshes"]);
int light_bake_mode = p_options["meshes/light_baking"];
Expand Down
Loading

0 comments on commit 25d4c14

Please sign in to comment.