From 3fc8fa0ce22b477a8ad12403dafc64a2ffb5bfc0 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 29 Jun 2020 00:16:09 +0200 Subject: [PATCH] Implemented collision shape scaling. --- plugin_collada/editor_import_collada_mdr.cpp | 82 +++++++++++++++++- plugin_collada/editor_import_collada_mdr.h | 1 + plugin_gltf/editor_import_gltf_mdr.cpp | 90 +++++++++++++++++++- plugin_gltf/editor_import_gltf_mdr.h | 1 + 4 files changed, 170 insertions(+), 4 deletions(-) diff --git a/plugin_collada/editor_import_collada_mdr.cpp b/plugin_collada/editor_import_collada_mdr.cpp index f918fee..232a34b 100644 --- a/plugin_collada/editor_import_collada_mdr.cpp +++ b/plugin_collada/editor_import_collada_mdr.cpp @@ -71,6 +71,8 @@ Error EditorImportColladaMdr::import(const String &p_source_file, const String & Node *n = _importer->import_scene(p_source_file, 0, 15); + Vector3 scale = p_options["scale"]; + if (n == NULL) { n->queue_delete(); return Error::ERR_PARSE_ERROR; @@ -104,7 +106,7 @@ Error EditorImportColladaMdr::import(const String &p_source_file, const String & Ref shape = m->create_trimesh_shape(); if (!shape.is_null()) { - mdr->add_collision_shape(shape); + mdr->add_collision_shape(scale_shape(shape, scale)); } } else if (collider_type == MeshDataResource::COLLIDER_TYPE_SINGLE_CONVEX_COLLISION_SHAPE) { Ref m; @@ -114,7 +116,7 @@ Error EditorImportColladaMdr::import(const String &p_source_file, const String & Ref shape = mesh->create_convex_shape(); if (!shape.is_null()) { - mdr->add_collision_shape(shape); + mdr->add_collision_shape(scale_shape(shape, scale)); } } else if (collider_type == MeshDataResource::COLLIDER_TYPE_MULTIPLE_CONVEX_COLLISION_SHAPES) { Ref m; @@ -123,6 +125,10 @@ Error EditorImportColladaMdr::import(const String &p_source_file, const String & Vector > shapes = mesh->convex_decompose(); + for (int j = 0; j < shapes.size(); ++j) { + scale_shape(shapes[j], scale); + } + mdr->set_collision_shapes(shapes); } @@ -188,6 +194,78 @@ Array EditorImportColladaMdr::apply_transforms(Array &array, const Map EditorImportColladaMdr::scale_shape(Ref shape, const Vector3 &scale) { + + if (shape.is_null()) + return shape; + + if (Object::cast_to(*shape)) { + + Ref ss = shape; + + ss->set_radius(ss->get_radius() * MAX(scale.x, MAX(scale.y, scale.z))); + } + + if (Object::cast_to(*shape)) { + + Ref bs = shape; + + bs->set_extents(bs->get_extents() * scale); + } + + if (Object::cast_to(*shape)) { + + Ref cs = shape; + + float sc = MAX(scale.x, MAX(scale.y, scale.z)); + + cs->set_radius(cs->get_radius() * sc); + cs->set_height(cs->get_height() * sc); + } + + if (Object::cast_to(*shape)) { + + Ref cs = shape; + + float sc = MAX(scale.x, MAX(scale.y, scale.z)); + + cs->set_radius(cs->get_radius() * sc); + cs->set_height(cs->get_height() * sc); + } + + if (Object::cast_to(*shape)) { + + Ref cps = shape; + + PoolVector3Array arr = cps->get_faces(); + + Basis b = Basis().scaled(scale); + + for (int i = 0; i < arr.size(); ++i) { + arr.set(i, b.xform(arr[i])); + } + + cps->set_faces(arr); + } + + if (Object::cast_to(*shape)) { + + Ref cps = shape; + + PoolVector3Array arr = cps->get_points(); + + Basis b = Basis().scaled(scale); + + for (int i = 0; i < arr.size(); ++i) { + arr.set(i, b.xform(arr[i])); + } + + cps->set_points(arr); + } + + return shape; +} + EditorImportColladaMdr::EditorImportColladaMdr() { _importer.instance(); } diff --git a/plugin_collada/editor_import_collada_mdr.h b/plugin_collada/editor_import_collada_mdr.h index 0abaf79..6968fd1 100644 --- a/plugin_collada/editor_import_collada_mdr.h +++ b/plugin_collada/editor_import_collada_mdr.h @@ -66,6 +66,7 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const Map &p_options, List *r_platform_variants, List *r_gen_files = NULL, Variant *r_metadata = NULL); Array apply_transforms(Array &array, const Map &p_options); + Ref scale_shape(Ref shape, const Vector3 &scale); EditorImportColladaMdr(); ~EditorImportColladaMdr(); diff --git a/plugin_gltf/editor_import_gltf_mdr.cpp b/plugin_gltf/editor_import_gltf_mdr.cpp index 4a24e22..53c26d5 100644 --- a/plugin_gltf/editor_import_gltf_mdr.cpp +++ b/plugin_gltf/editor_import_gltf_mdr.cpp @@ -22,6 +22,14 @@ SOFTWARE. #include "editor_import_gltf_mdr.h" +#include "scene/resources/box_shape.h" +#include "scene/resources/capsule_shape.h" +#include "scene/resources/concave_polygon_shape.h" +#include "scene/resources/convex_polygon_shape.h" +#include "scene/resources/cylinder_shape.h" +#include "scene/resources/shape.h" +#include "scene/resources/sphere_shape.h" + String EditorImportGLTFMdr::get_importer_name() const { return "gltf_mdr"; } @@ -72,6 +80,8 @@ Error EditorImportGLTFMdr::import(const String &p_source_file, const String &p_s Node *n = _importer->import_scene(p_source_file, 0, 15); + Vector3 scale = p_options["scale"]; + if (n == NULL) { n->queue_delete(); return Error::ERR_PARSE_ERROR; @@ -105,7 +115,7 @@ Error EditorImportGLTFMdr::import(const String &p_source_file, const String &p_s Ref shape = m->create_trimesh_shape(); if (!shape.is_null()) { - mdr->add_collision_shape(shape); + mdr->add_collision_shape(scale_shape(shape, scale)); } } else if (collider_type == MeshDataResource::COLLIDER_TYPE_SINGLE_CONVEX_COLLISION_SHAPE) { Ref m; @@ -115,7 +125,7 @@ Error EditorImportGLTFMdr::import(const String &p_source_file, const String &p_s Ref shape = mesh->create_convex_shape(); if (!shape.is_null()) { - mdr->add_collision_shape(shape); + mdr->add_collision_shape(scale_shape(shape, scale)); } } else if (collider_type == MeshDataResource::COLLIDER_TYPE_MULTIPLE_CONVEX_COLLISION_SHAPES) { Ref m; @@ -124,6 +134,10 @@ Error EditorImportGLTFMdr::import(const String &p_source_file, const String &p_s Vector > shapes = mesh->convex_decompose(); + for (int j = 0; j < shapes.size(); ++j) { + scale_shape(shapes[j], scale); + } + mdr->set_collision_shapes(shapes); } @@ -188,6 +202,78 @@ Array EditorImportGLTFMdr::apply_transforms(Array &array, const Map EditorImportGLTFMdr::scale_shape(Ref shape, const Vector3 &scale) { + + if (shape.is_null()) + return shape; + + if (Object::cast_to(*shape)) { + + Ref ss = shape; + + ss->set_radius(ss->get_radius() * MAX(scale.x, MAX(scale.y, scale.z))); + } + + if (Object::cast_to(*shape)) { + + Ref bs = shape; + + bs->set_extents(bs->get_extents() * scale); + } + + if (Object::cast_to(*shape)) { + + Ref cs = shape; + + float sc = MAX(scale.x, MAX(scale.y, scale.z)); + + cs->set_radius(cs->get_radius() * sc); + cs->set_height(cs->get_height() * sc); + } + + if (Object::cast_to(*shape)) { + + Ref cs = shape; + + float sc = MAX(scale.x, MAX(scale.y, scale.z)); + + cs->set_radius(cs->get_radius() * sc); + cs->set_height(cs->get_height() * sc); + } + + if (Object::cast_to(*shape)) { + + Ref cps = shape; + + PoolVector3Array arr = cps->get_faces(); + + Basis b = Basis().scaled(scale); + + for (int i = 0; i < arr.size(); ++i) { + arr.set(i, b.xform(arr[i])); + } + + cps->set_faces(arr); + } + + if (Object::cast_to(*shape)) { + + Ref cps = shape; + + PoolVector3Array arr = cps->get_points(); + + Basis b = Basis().scaled(scale); + + for (int i = 0; i < arr.size(); ++i) { + arr.set(i, b.xform(arr[i])); + } + + cps->set_points(arr); + } + + return shape; +} + EditorImportGLTFMdr::EditorImportGLTFMdr() { _importer.instance(); } diff --git a/plugin_gltf/editor_import_gltf_mdr.h b/plugin_gltf/editor_import_gltf_mdr.h index 2323a7d..8cfd89b 100644 --- a/plugin_gltf/editor_import_gltf_mdr.h +++ b/plugin_gltf/editor_import_gltf_mdr.h @@ -66,6 +66,7 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const Map &p_options, List *r_platform_variants, List *r_gen_files = NULL, Variant *r_metadata = NULL); Array apply_transforms(Array &array, const Map &p_options); + Ref scale_shape(Ref shape, const Vector3 &scale); EditorImportGLTFMdr(); ~EditorImportGLTFMdr();