Skip to content

Commit

Permalink
Merge pull request #52254 from godotengine/revert-51985-coll
Browse files Browse the repository at this point in the history
Revert " Improve collision generation usability in the new 3D scene import workflow."
  • Loading branch information
reduz committed Aug 30, 2021
2 parents b60a51f + 6dab6e4 commit efc8748
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 495 deletions.
2 changes: 1 addition & 1 deletion core/templates/vector.h
Expand Up @@ -229,7 +229,7 @@ class Vector {
_FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return elem_ptr == b.elem_ptr; }
_FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return elem_ptr != b.elem_ptr; }

ConstIterator(const T *p_ptr) { elem_ptr = p_ptr; }
ConstIterator(T *p_ptr) { elem_ptr = p_ptr; }
ConstIterator() {}
ConstIterator(const ConstIterator &p_it) { elem_ptr = p_it.elem_ptr; }

Expand Down
189 changes: 33 additions & 156 deletions editor/import/resource_importer_scene.cpp

Large diffs are not rendered by default.

202 changes: 4 additions & 198 deletions editor/import/resource_importer_scene.h
Expand Up @@ -63,6 +63,7 @@ class EditorSceneImporter : public RefCounted {
IMPORT_FAIL_ON_MISSING_DEPENDENCIES = 4,
IMPORT_GENERATE_TANGENT_ARRAYS = 8,
IMPORT_USE_NAMED_SKIN_BINDS = 16,

};

virtual uint32_t get_import_flags() const;
Expand Down Expand Up @@ -124,25 +125,9 @@ class ResourceImporterScene : public ResourceImporter {
MESH_OVERRIDE_DISABLE,
};

enum BodyType {
BODY_TYPE_STATIC,
BODY_TYPE_DYNAMIC,
BODY_TYPE_AREA
};

enum ShapeType {
SHAPE_TYPE_DECOMPOSE_CONVEX,
SHAPE_TYPE_SIMPLE_CONVEX,
SHAPE_TYPE_TRIMESH,
SHAPE_TYPE_BOX,
SHAPE_TYPE_SPHERE,
SHAPE_TYPE_CYLINDER,
SHAPE_TYPE_CAPSULE,
};

void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
void _generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches);
void _add_shapes(Node *p_node, const Vector<Ref<Shape3D>> &p_shapes);
void _add_shapes(Node *p_node, const List<Ref<Shape3D>> &p_shapes);

public:
static ResourceImporterScene *get_singleton() { return singleton; }
Expand Down Expand Up @@ -174,15 +159,14 @@ class ResourceImporterScene : public ResourceImporter {

void get_internal_import_options(InternalImportCategory p_category, List<ImportOption> *r_options) const;
bool get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const;
bool get_internal_option_update_view(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const;

virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
// Import scenes *after* everything else (such as textures).
virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; }

Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, Vector<Ref<Shape3D>>> &collision_map);
Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<EditorSceneImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> &collision_map);
Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> &collision_map, Set<Ref<EditorSceneImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);

Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks);
void _create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all);
Expand All @@ -200,12 +184,6 @@ class ResourceImporterScene : public ResourceImporter {
virtual bool can_import_threaded() const override { return false; }

ResourceImporterScene();

template <class M>
static Vector<Ref<Shape3D>> get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options);

template <class M>
static Transform3D get_collision_shapes_transform(const M &p_options);
};

class EditorSceneImporterESCN : public EditorSceneImporter {
Expand All @@ -218,176 +196,4 @@ class EditorSceneImporterESCN : public EditorSceneImporter {
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override;
};

#include "scene/resources/box_shape_3d.h"
#include "scene/resources/capsule_shape_3d.h"
#include "scene/resources/cylinder_shape_3d.h"
#include "scene/resources/sphere_shape_3d.h"

template <class M>
Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options) {
ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
if (p_options.has(SNAME("physics/shape_type"))) {
generate_shape_type = (ShapeType)p_options[SNAME("physics/shape_type")].operator int();
}

if (generate_shape_type == SHAPE_TYPE_DECOMPOSE_CONVEX) {
Mesh::ConvexDecompositionSettings decomposition_settings;
bool advanced = false;
if (p_options.has(SNAME("decomposition/advanced"))) {
advanced = p_options[SNAME("decomposition/advanced")];
}

if (advanced) {
if (p_options.has(SNAME("decomposition/max_concavity"))) {
decomposition_settings.max_concavity = p_options[SNAME("decomposition/max_concavity")];
}

if (p_options.has(SNAME("decomposition/symmetry_planes_clipping_bias"))) {
decomposition_settings.symmetry_planes_clipping_bias = p_options[SNAME("decomposition/symmetry_planes_clipping_bias")];
}

if (p_options.has(SNAME("decomposition/revolution_axes_clipping_bias"))) {
decomposition_settings.revolution_axes_clipping_bias = p_options[SNAME("decomposition/revolution_axes_clipping_bias")];
}

if (p_options.has(SNAME("decomposition/min_volume_per_convex_hull"))) {
decomposition_settings.min_volume_per_convex_hull = p_options[SNAME("decomposition/min_volume_per_convex_hull")];
}

if (p_options.has(SNAME("decomposition/resolution"))) {
decomposition_settings.resolution = p_options[SNAME("decomposition/resolution")];
}

if (p_options.has(SNAME("decomposition/max_num_vertices_per_convex_hull"))) {
decomposition_settings.max_num_vertices_per_convex_hull = p_options[SNAME("decomposition/max_num_vertices_per_convex_hull")];
}

if (p_options.has(SNAME("decomposition/plane_downsampling"))) {
decomposition_settings.plane_downsampling = p_options[SNAME("decomposition/plane_downsampling")];
}

if (p_options.has(SNAME("decomposition/convexhull_downsampling"))) {
decomposition_settings.convexhull_downsampling = p_options[SNAME("decomposition/convexhull_downsampling")];
}

if (p_options.has(SNAME("decomposition/normalize_mesh"))) {
decomposition_settings.normalize_mesh = p_options[SNAME("decomposition/normalize_mesh")];
}

if (p_options.has(SNAME("decomposition/mode"))) {
decomposition_settings.mode = (Mesh::ConvexDecompositionSettings::Mode)p_options[SNAME("decomposition/mode")].operator int();
}

if (p_options.has(SNAME("decomposition/convexhull_approximation"))) {
decomposition_settings.convexhull_approximation = p_options[SNAME("decomposition/convexhull_approximation")];
}

if (p_options.has(SNAME("decomposition/max_convex_hulls"))) {
decomposition_settings.max_convex_hulls = p_options[SNAME("decomposition/max_convex_hulls")];
}

if (p_options.has(SNAME("decomposition/project_hull_vertices"))) {
decomposition_settings.project_hull_vertices = p_options[SNAME("decomposition/project_hull_vertices")];
}
} else {
int precision_level = 5;
if (p_options.has(SNAME("decomposition/precision"))) {
precision_level = p_options[SNAME("decomposition/precision")];
}

const real_t precision = real_t(precision_level - 1) / 9.0;

decomposition_settings.max_concavity = Math::lerp(real_t(1.0), real_t(0.001), precision);
decomposition_settings.min_volume_per_convex_hull = Math::lerp(real_t(0.01), real_t(0.0001), precision);
decomposition_settings.resolution = Math::lerp(10'000, 100'000, precision);
decomposition_settings.max_num_vertices_per_convex_hull = Math::lerp(32, 64, precision);
decomposition_settings.plane_downsampling = Math::lerp(3, 16, precision);
decomposition_settings.convexhull_downsampling = Math::lerp(3, 16, precision);
decomposition_settings.max_convex_hulls = Math::lerp(1, 32, precision);
}

return p_mesh->convex_decompose(decomposition_settings);
} else if (generate_shape_type == SHAPE_TYPE_SIMPLE_CONVEX) {
Vector<Ref<Shape3D>> shapes;
shapes.push_back(p_mesh->create_convex_shape(true, /*Passing false, otherwise VHACD will be used to simplify (Decompose) the Mesh.*/ false));
return shapes;
} else if (generate_shape_type == SHAPE_TYPE_TRIMESH) {
Vector<Ref<Shape3D>> shapes;
shapes.push_back(p_mesh->create_trimesh_shape());
return shapes;
} else if (generate_shape_type == SHAPE_TYPE_BOX) {
Ref<BoxShape3D> box;
box.instantiate();
if (p_options.has(SNAME("primitive/size"))) {
box->set_size(p_options[SNAME("primitive/size")]);
}

Vector<Ref<Shape3D>> shapes;
shapes.push_back(box);
return shapes;

} else if (generate_shape_type == SHAPE_TYPE_SPHERE) {
Ref<SphereShape3D> sphere;
sphere.instantiate();
if (p_options.has(SNAME("primitive/radius"))) {
sphere->set_radius(p_options[SNAME("primitive/radius")]);
}

Vector<Ref<Shape3D>> shapes;
shapes.push_back(sphere);
return shapes;
} else if (generate_shape_type == SHAPE_TYPE_CYLINDER) {
Ref<CylinderShape3D> cylinder;
cylinder.instantiate();
if (p_options.has(SNAME("primitive/height"))) {
cylinder->set_height(p_options[SNAME("primitive/height")]);
}
if (p_options.has(SNAME("primitive/radius"))) {
cylinder->set_radius(p_options[SNAME("primitive/radius")]);
}

Vector<Ref<Shape3D>> shapes;
shapes.push_back(cylinder);
return shapes;
} else if (generate_shape_type == SHAPE_TYPE_CAPSULE) {
Ref<CapsuleShape3D> capsule;
capsule.instantiate();
if (p_options.has(SNAME("primitive/height"))) {
capsule->set_height(p_options[SNAME("primitive/height")]);
}
if (p_options.has(SNAME("primitive/radius"))) {
capsule->set_radius(p_options[SNAME("primitive/radius")]);
}

Vector<Ref<Shape3D>> shapes;
shapes.push_back(capsule);
return shapes;
}
return Vector<Ref<Shape3D>>();
}

template <class M>
Transform3D ResourceImporterScene::get_collision_shapes_transform(const M &p_options) {
Transform3D transform;

ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
if (p_options.has(SNAME("physics/shape_type"))) {
generate_shape_type = (ShapeType)p_options[SNAME("physics/shape_type")].operator int();
}

if (generate_shape_type == SHAPE_TYPE_BOX ||
generate_shape_type == SHAPE_TYPE_SPHERE ||
generate_shape_type == SHAPE_TYPE_CYLINDER ||
generate_shape_type == SHAPE_TYPE_CAPSULE) {
if (p_options.has(SNAME("primitive/position"))) {
transform.origin = p_options[SNAME("primitive/position")];
}

if (p_options.has(SNAME("primitive/rotation"))) {
transform.basis.set_euler((p_options[SNAME("primitive/rotation")].operator Vector3() / 180.0) * Math_PI);
}
}
return transform;
}

#endif // RESOURCEIMPORTERSCENE_H
74 changes: 0 additions & 74 deletions editor/import/scene_import_settings.cpp
Expand Up @@ -53,11 +53,6 @@ class SceneImportSettingsData : public Object {
}

current[p_name] = p_value;

if (ResourceImporterScene::get_singleton()->get_internal_option_update_view(category, p_name, current)) {
SceneImportSettings::get_singleton()->update_view();
}

return true;
}
return false;
Expand Down Expand Up @@ -322,13 +317,6 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
if (mesh_node && mesh_node->get_mesh().is_valid()) {
_fill_mesh(scene_tree, mesh_node->get_mesh(), item);

// Add the collider view.
MeshInstance3D *collider_view = memnew(MeshInstance3D);
collider_view->set_name("collider_view");
collider_view->set_visible(false);
mesh_node->add_child(collider_view);
collider_view->set_owner(mesh_node);

Transform3D accum_xform;
Node3D *base = mesh_node;
while (base) {
Expand Down Expand Up @@ -358,54 +346,6 @@ void SceneImportSettings::_update_scene() {
_fill_scene(scene, nullptr);
}

void SceneImportSettings::_update_view_gizmos() {
for (const KeyValue<String, NodeData> &e : node_map) {
bool generate_collider = false;
if (e.value.settings.has(SNAME("generate/physics"))) {
generate_collider = e.value.settings[SNAME("generate/physics")];
}

MeshInstance3D *mesh_node = Object::cast_to<MeshInstance3D>(e.value.node);
if (mesh_node == nullptr || mesh_node->get_mesh().is_null()) {
// Nothing to do
continue;
}

MeshInstance3D *collider_view = static_cast<MeshInstance3D *>(mesh_node->find_node("collider_view"));
CRASH_COND_MSG(collider_view == nullptr, "This is unreachable, since the collider view is always created even when the collision is not used! If this is triggered there is a bug on the function `_fill_scene`.");

collider_view->set_visible(generate_collider);
if (generate_collider) {
// This collider_view doesn't have a mesh so we need to generate a new one.

// Generate the mesh collider.
Vector<Ref<Shape3D>> shapes = ResourceImporterScene::get_collision_shapes(mesh_node->get_mesh(), e.value.settings);
const Transform3D transform = ResourceImporterScene::get_collision_shapes_transform(e.value.settings);

Ref<ArrayMesh> collider_view_mesh;
collider_view_mesh.instantiate();
for (Ref<Shape3D> shape : shapes) {
Ref<ArrayMesh> debug_shape_mesh;
if (shape.is_valid()) {
debug_shape_mesh = shape->get_debug_mesh();
}
if (debug_shape_mesh.is_valid()) {
collider_view_mesh->add_surface_from_arrays(
debug_shape_mesh->surface_get_primitive_type(0),
debug_shape_mesh->surface_get_arrays(0));

collider_view_mesh->surface_set_material(
collider_view_mesh->get_surface_count() - 1,
collider_mat);
}
}

collider_view->set_mesh(collider_view_mesh);
collider_view->set_transform(transform);
}
}
}

void SceneImportSettings::_update_camera() {
AABB camera_aabb;

Expand Down Expand Up @@ -464,16 +404,11 @@ void SceneImportSettings::_load_default_subresource_settings(Map<StringName, Var
}
}

void SceneImportSettings::update_view() {
_update_view_gizmos();
}

void SceneImportSettings::open_settings(const String &p_path) {
if (scene) {
memdelete(scene);
scene = nullptr;
}
scene_import_settings_data->settings = nullptr;
scene = ResourceImporterScene::get_singleton()->pre_import(p_path);
if (scene == nullptr) {
EditorNode::get_singleton()->show_warning(TTR("Error opening scene"));
Expand Down Expand Up @@ -528,7 +463,6 @@ void SceneImportSettings::open_settings(const String &p_path) {
}

popup_centered_ratio();
_update_view_gizmos();
_update_camera();

set_title(vformat(TTR("Advanced Import Settings for '%s'"), base_path.get_file()));
Expand Down Expand Up @@ -695,7 +629,6 @@ void SceneImportSettings::_material_tree_selected() {

_select(material_tree, type, import_id);
}

void SceneImportSettings::_mesh_tree_selected() {
if (selecting) {
return;
Expand All @@ -707,7 +640,6 @@ void SceneImportSettings::_mesh_tree_selected() {

_select(mesh_tree, type, import_id);
}

void SceneImportSettings::_scene_tree_selected() {
if (selecting) {
return;
Expand Down Expand Up @@ -1212,12 +1144,6 @@ SceneImportSettings::SceneImportSettings() {
material_preview.instantiate();
}

{
collider_mat.instantiate();
collider_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
collider_mat->set_albedo(Color(0.5, 0.5, 1.0));
}

inspector = memnew(EditorInspector);
inspector->set_custom_minimum_size(Size2(300 * EDSCALE, 0));

Expand Down

0 comments on commit efc8748

Please sign in to comment.