import: Fix uv2 by avoiding premature ImporterMesh::get_mesh()
Implements create_convex_shape in ImpoterMesh. Note: ImporterMeshInstance3D::get_mesh() is safe. The only dangerous function with side effects is ImpoterMesh::get_mesh()
This commit is contained in:
parent
19c9fd6926
commit
51a4fe1d53
5 changed files with 82 additions and 6 deletions
|
@ -353,13 +353,12 @@ static String _fixstr(const String &p_what, const String &p_str) {
|
||||||
|
|
||||||
static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r_shape_list, bool p_convex) {
|
static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r_shape_list, bool p_convex) {
|
||||||
ERR_FAIL_NULL_MSG(mesh, "Cannot generate shape list with null mesh value");
|
ERR_FAIL_NULL_MSG(mesh, "Cannot generate shape list with null mesh value");
|
||||||
ERR_FAIL_NULL_MSG(mesh->get_mesh(), "Cannot generate shape list with null mesh value");
|
|
||||||
if (!p_convex) {
|
if (!p_convex) {
|
||||||
Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape();
|
Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape();
|
||||||
r_shape_list.push_back(shape);
|
r_shape_list.push_back(shape);
|
||||||
} else {
|
} else {
|
||||||
Vector<Ref<Shape3D>> cd;
|
Vector<Ref<Shape3D>> cd;
|
||||||
cd.push_back(mesh->get_mesh()->create_convex_shape(true, /*Passing false, otherwise VHACD will be used to simplify (Decompose) the Mesh.*/ false));
|
cd.push_back(mesh->create_convex_shape(true, /*Passing false, otherwise VHACD will be used to simplify (Decompose) the Mesh.*/ false));
|
||||||
if (cd.size()) {
|
if (cd.size()) {
|
||||||
for (int i = 0; i < cd.size(); i++) {
|
for (int i = 0; i < cd.size(); i++) {
|
||||||
r_shape_list.push_back(cd[i]);
|
r_shape_list.push_back(cd[i]);
|
||||||
|
@ -1230,7 +1229,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
|
||||||
shapes = collision_map[m];
|
shapes = collision_map[m];
|
||||||
} else {
|
} else {
|
||||||
shapes = get_collision_shapes(
|
shapes = get_collision_shapes(
|
||||||
m->get_mesh(),
|
m,
|
||||||
node_settings,
|
node_settings,
|
||||||
p_applied_root_scale);
|
p_applied_root_scale);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "scene/resources/box_shape_3d.h"
|
#include "scene/resources/box_shape_3d.h"
|
||||||
#include "scene/resources/capsule_shape_3d.h"
|
#include "scene/resources/capsule_shape_3d.h"
|
||||||
#include "scene/resources/cylinder_shape_3d.h"
|
#include "scene/resources/cylinder_shape_3d.h"
|
||||||
|
#include "scene/resources/importer_mesh.h"
|
||||||
#include "scene/resources/mesh.h"
|
#include "scene/resources/mesh.h"
|
||||||
#include "scene/resources/shape_3d.h"
|
#include "scene/resources/shape_3d.h"
|
||||||
#include "scene/resources/sphere_shape_3d.h"
|
#include "scene/resources/sphere_shape_3d.h"
|
||||||
|
@ -298,7 +299,7 @@ public:
|
||||||
ResourceImporterScene(bool p_animation_import = false);
|
ResourceImporterScene(bool p_animation_import = false);
|
||||||
|
|
||||||
template <class M>
|
template <class M>
|
||||||
static Vector<Ref<Shape3D>> get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options, float p_applied_root_scale);
|
static Vector<Ref<Shape3D>> get_collision_shapes(const Ref<ImporterMesh> &p_mesh, const M &p_options, float p_applied_root_scale);
|
||||||
|
|
||||||
template <class M>
|
template <class M>
|
||||||
static Transform3D get_collision_shapes_transform(const M &p_options);
|
static Transform3D get_collision_shapes_transform(const M &p_options);
|
||||||
|
@ -314,7 +315,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class M>
|
template <class M>
|
||||||
Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options, float p_applied_root_scale) {
|
Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<ImporterMesh> &p_mesh, const M &p_options, float p_applied_root_scale) {
|
||||||
|
ERR_FAIL_COND_V(p_mesh.is_null(), Vector<Ref<Shape3D>>());
|
||||||
ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
|
ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
|
||||||
if (p_options.has(SNAME("physics/shape_type"))) {
|
if (p_options.has(SNAME("physics/shape_type"))) {
|
||||||
generate_shape_type = (ShapeType)p_options[SNAME("physics/shape_type")].operator int();
|
generate_shape_type = (ShapeType)p_options[SNAME("physics/shape_type")].operator int();
|
||||||
|
|
|
@ -444,9 +444,45 @@ void SceneImportSettings::_update_view_gizmos() {
|
||||||
collider_view->set_visible(show_collider_view);
|
collider_view->set_visible(show_collider_view);
|
||||||
if (generate_collider) {
|
if (generate_collider) {
|
||||||
// This collider_view doesn't have a mesh so we need to generate a new one.
|
// This collider_view doesn't have a mesh so we need to generate a new one.
|
||||||
|
Ref<ImporterMesh> mesh;
|
||||||
|
mesh.instantiate();
|
||||||
|
// ResourceImporterScene::get_collision_shapes() expects ImporterMesh, not Mesh.
|
||||||
|
// TODO: Duplicate code with EditorSceneFormatImporterESCN::import_scene()
|
||||||
|
// Consider making a utility function to convert from Mesh to ImporterMesh.
|
||||||
|
Ref<Mesh> mesh_3d_mesh = mesh_node->get_mesh();
|
||||||
|
Ref<ArrayMesh> array_mesh_3d_mesh = mesh_3d_mesh;
|
||||||
|
if (array_mesh_3d_mesh.is_valid()) {
|
||||||
|
// For the MeshInstance3D nodes, we need to convert the ArrayMesh to an ImporterMesh specially.
|
||||||
|
mesh->set_name(array_mesh_3d_mesh->get_name());
|
||||||
|
for (int32_t blend_i = 0; blend_i < array_mesh_3d_mesh->get_blend_shape_count(); blend_i++) {
|
||||||
|
mesh->add_blend_shape(array_mesh_3d_mesh->get_blend_shape_name(blend_i));
|
||||||
|
}
|
||||||
|
for (int32_t surface_i = 0; surface_i < array_mesh_3d_mesh->get_surface_count(); surface_i++) {
|
||||||
|
mesh->add_surface(array_mesh_3d_mesh->surface_get_primitive_type(surface_i),
|
||||||
|
array_mesh_3d_mesh->surface_get_arrays(surface_i),
|
||||||
|
array_mesh_3d_mesh->surface_get_blend_shape_arrays(surface_i),
|
||||||
|
array_mesh_3d_mesh->surface_get_lods(surface_i),
|
||||||
|
array_mesh_3d_mesh->surface_get_material(surface_i),
|
||||||
|
array_mesh_3d_mesh->surface_get_name(surface_i),
|
||||||
|
array_mesh_3d_mesh->surface_get_format(surface_i));
|
||||||
|
}
|
||||||
|
mesh->set_blend_shape_mode(array_mesh_3d_mesh->get_blend_shape_mode());
|
||||||
|
} else if (mesh_3d_mesh.is_valid()) {
|
||||||
|
// For the MeshInstance3D nodes, we need to convert the Mesh to an ImporterMesh specially.
|
||||||
|
mesh->set_name(mesh_3d_mesh->get_name());
|
||||||
|
for (int32_t surface_i = 0; surface_i < mesh_3d_mesh->get_surface_count(); surface_i++) {
|
||||||
|
mesh->add_surface(mesh_3d_mesh->surface_get_primitive_type(surface_i),
|
||||||
|
mesh_3d_mesh->surface_get_arrays(surface_i),
|
||||||
|
Array(),
|
||||||
|
mesh_3d_mesh->surface_get_lods(surface_i),
|
||||||
|
mesh_3d_mesh->surface_get_material(surface_i),
|
||||||
|
mesh_3d_mesh->surface_get_material(surface_i).is_valid() ? mesh_3d_mesh->surface_get_material(surface_i)->get_name() : String(),
|
||||||
|
mesh_3d_mesh->surface_get_format(surface_i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the mesh collider.
|
// Generate the mesh collider.
|
||||||
Vector<Ref<Shape3D>> shapes = ResourceImporterScene::get_collision_shapes(mesh_node->get_mesh(), e.value.settings, 1.0);
|
Vector<Ref<Shape3D>> shapes = ResourceImporterScene::get_collision_shapes(mesh, e.value.settings, 1.0);
|
||||||
const Transform3D transform = ResourceImporterScene::get_collision_shapes_transform(e.value.settings);
|
const Transform3D transform = ResourceImporterScene::get_collision_shapes_transform(e.value.settings);
|
||||||
|
|
||||||
Ref<ArrayMesh> collider_view_mesh;
|
Ref<ArrayMesh> collider_view_mesh;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "importer_mesh.h"
|
#include "importer_mesh.h"
|
||||||
|
|
||||||
#include "core/io/marshalls.h"
|
#include "core/io/marshalls.h"
|
||||||
|
#include "core/math/convex_hull.h"
|
||||||
#include "core/math/random_pcg.h"
|
#include "core/math/random_pcg.h"
|
||||||
#include "core/math/static_raycaster.h"
|
#include "core/math/static_raycaster.h"
|
||||||
#include "scene/resources/surface_tool.h"
|
#include "scene/resources/surface_tool.h"
|
||||||
|
@ -984,6 +985,43 @@ Vector<Ref<Shape3D>> ImporterMesh::convex_decompose(const Mesh::ConvexDecomposit
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<ConvexPolygonShape3D> ImporterMesh::create_convex_shape(bool p_clean, bool p_simplify) const {
|
||||||
|
if (p_simplify) {
|
||||||
|
Mesh::ConvexDecompositionSettings settings;
|
||||||
|
settings.max_convex_hulls = 1;
|
||||||
|
Vector<Ref<Shape3D>> decomposed = convex_decompose(settings);
|
||||||
|
if (decomposed.size() == 1) {
|
||||||
|
return decomposed[0];
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("Convex shape simplification failed, falling back to simpler process.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Vector3> vertices;
|
||||||
|
for (int i = 0; i < get_surface_count(); i++) {
|
||||||
|
Array a = get_surface_arrays(i);
|
||||||
|
ERR_FAIL_COND_V(a.is_empty(), Ref<ConvexPolygonShape3D>());
|
||||||
|
Vector<Vector3> v = a[Mesh::ARRAY_VERTEX];
|
||||||
|
vertices.append_array(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D);
|
||||||
|
|
||||||
|
if (p_clean) {
|
||||||
|
Geometry3D::MeshData md;
|
||||||
|
Error err = ConvexHullComputer::convex_hull(vertices, md);
|
||||||
|
if (err == OK) {
|
||||||
|
shape->set_points(md.vertices);
|
||||||
|
return shape;
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("Convex shape cleaning failed, falling back to simpler process.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shape->set_points(vertices);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
Ref<ConcavePolygonShape3D> ImporterMesh::create_trimesh_shape() const {
|
Ref<ConcavePolygonShape3D> ImporterMesh::create_trimesh_shape() const {
|
||||||
Vector<Face3> faces = get_faces();
|
Vector<Face3> faces = get_faces();
|
||||||
if (faces.size() == 0) {
|
if (faces.size() == 0) {
|
||||||
|
|
|
@ -119,6 +119,7 @@ public:
|
||||||
|
|
||||||
Vector<Face3> get_faces() const;
|
Vector<Face3> get_faces() const;
|
||||||
Vector<Ref<Shape3D>> convex_decompose(const Mesh::ConvexDecompositionSettings &p_settings) const;
|
Vector<Ref<Shape3D>> convex_decompose(const Mesh::ConvexDecompositionSettings &p_settings) const;
|
||||||
|
Ref<ConvexPolygonShape3D> create_convex_shape(bool p_clean = true, bool p_simplify = false) const;
|
||||||
Ref<ConcavePolygonShape3D> create_trimesh_shape() const;
|
Ref<ConcavePolygonShape3D> create_trimesh_shape() const;
|
||||||
Ref<NavigationMesh> create_navigation_mesh();
|
Ref<NavigationMesh> create_navigation_mesh();
|
||||||
Error lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache);
|
Error lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache);
|
||||||
|
|
Loading…
Reference in a new issue