From f5b49af99fb63980ab05d8f909621393e4bfc2a6 Mon Sep 17 00:00:00 2001 From: "Silc Lizard (Tokage) Renew" <61938263+TokageItLab@users.noreply.github.com> Date: Sat, 5 Oct 2024 06:00:39 +0900 Subject: Add RetargetModifier3D for realtime retarget to keep original rest --- scene/resources/animation_library.cpp | 5 +++++ scene/resources/animation_library.h | 1 + scene/resources/skeleton_profile.cpp | 8 ++++++++ scene/resources/skeleton_profile.h | 1 + 4 files changed, 15 insertions(+) (limited to 'scene/resources') diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp index 22666876ae..92612fc3d7 100644 --- a/scene/resources/animation_library.cpp +++ b/scene/resources/animation_library.cpp @@ -125,6 +125,10 @@ void AnimationLibrary::get_animation_list(List *p_animations) const } } +int AnimationLibrary::get_animation_list_size() const { + return animations.size(); +} + void AnimationLibrary::_set_data(const Dictionary &p_data) { for (KeyValue> &K : animations) { K.value->disconnect_changed(callable_mp(this, &AnimationLibrary::_animation_changed)); @@ -166,6 +170,7 @@ void AnimationLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("has_animation", "name"), &AnimationLibrary::has_animation); ClassDB::bind_method(D_METHOD("get_animation", "name"), &AnimationLibrary::get_animation); ClassDB::bind_method(D_METHOD("get_animation_list"), &AnimationLibrary::_get_animation_list); + ClassDB::bind_method(D_METHOD("get_animation_list_size"), &AnimationLibrary::get_animation_list_size); ClassDB::bind_method(D_METHOD("_set_data", "data"), &AnimationLibrary::_set_data); ClassDB::bind_method(D_METHOD("_get_data"), &AnimationLibrary::_get_data); diff --git a/scene/resources/animation_library.h b/scene/resources/animation_library.h index 00baf9d302..794f142744 100644 --- a/scene/resources/animation_library.h +++ b/scene/resources/animation_library.h @@ -61,6 +61,7 @@ public: bool has_animation(const StringName &p_name) const; Ref get_animation(const StringName &p_name) const; void get_animation_list(List *p_animations) const; + int get_animation_list_size() const; #ifdef TOOLS_ENABLED virtual void get_argument_options(const StringName &p_function, int p_idx, List *r_options) const override; diff --git a/scene/resources/skeleton_profile.cpp b/scene/resources/skeleton_profile.cpp index c2d77ec7ff..2a1b64078a 100644 --- a/scene/resources/skeleton_profile.cpp +++ b/scene/resources/skeleton_profile.cpp @@ -269,6 +269,14 @@ int SkeletonProfile::find_bone(const StringName &p_bone_name) const { return -1; } +PackedStringArray SkeletonProfile::get_bone_names() { + PackedStringArray s; + for (const SkeletonProfileBone &bone : bones) { + s.push_back(bone.bone_name); + } + return s; +} + StringName SkeletonProfile::get_bone_name(int p_bone_idx) const { ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName()); return bones[p_bone_idx].bone_name; diff --git a/scene/resources/skeleton_profile.h b/scene/resources/skeleton_profile.h index b5a3bce940..9361c6a9ce 100644 --- a/scene/resources/skeleton_profile.h +++ b/scene/resources/skeleton_profile.h @@ -97,6 +97,7 @@ public: int find_bone(const StringName &p_bone_name) const; + PackedStringArray get_bone_names(); StringName get_bone_name(int p_bone_idx) const; void set_bone_name(int p_bone_idx, const StringName &p_bone_name); -- cgit v1.2.3 From 0fc082e1ee3af5bb6a4b52f85756d24dc02b230f Mon Sep 17 00:00:00 2001 From: Jamie Greunbaum Date: Tue, 2 Apr 2024 03:26:10 -0400 Subject: Add CollisionShape3D custom debug colours This allows changing the display colour of a CollisionShape3D node on a per-shape basis. It also adds the ability to display a solid coloured preview of a CollisionShape3D. Closes https://github.com/godotengine/godot-proposals/issues/906 --- scene/resources/3d/box_shape_3d.cpp | 20 +++++++ scene/resources/3d/box_shape_3d.h | 1 + scene/resources/3d/capsule_shape_3d.cpp | 19 ++++++ scene/resources/3d/capsule_shape_3d.h | 3 + scene/resources/3d/concave_polygon_shape_3d.cpp | 18 ++++++ scene/resources/3d/concave_polygon_shape_3d.h | 3 + scene/resources/3d/convex_polygon_shape_3d.cpp | 39 ++++++++++++ scene/resources/3d/convex_polygon_shape_3d.h | 3 + scene/resources/3d/cylinder_shape_3d.cpp | 19 ++++++ scene/resources/3d/cylinder_shape_3d.h | 3 + scene/resources/3d/height_map_shape_3d.cpp | 55 +++++++++++++++++ scene/resources/3d/height_map_shape_3d.h | 2 + scene/resources/3d/separation_ray_shape_3d.cpp | 5 ++ scene/resources/3d/separation_ray_shape_3d.h | 3 + scene/resources/3d/shape_3d.cpp | 80 +++++++++++++++++++++---- scene/resources/3d/shape_3d.h | 16 +++++ scene/resources/3d/sphere_shape_3d.cpp | 20 +++++++ scene/resources/3d/sphere_shape_3d.h | 3 + scene/resources/3d/world_boundary_shape_3d.cpp | 48 +++++++++++++++ scene/resources/3d/world_boundary_shape_3d.h | 3 + 20 files changed, 351 insertions(+), 12 deletions(-) (limited to 'scene/resources') diff --git a/scene/resources/3d/box_shape_3d.cpp b/scene/resources/3d/box_shape_3d.cpp index 313aeb1bca..afb03a8ba1 100644 --- a/scene/resources/3d/box_shape_3d.cpp +++ b/scene/resources/3d/box_shape_3d.cpp @@ -29,6 +29,8 @@ /**************************************************************************/ #include "box_shape_3d.h" + +#include "scene/resources/3d/primitive_meshes.h" #include "servers/physics_server_3d.h" Vector BoxShape3D::get_debug_mesh_lines() const { @@ -47,6 +49,24 @@ Vector BoxShape3D::get_debug_mesh_lines() const { return lines; } +Ref BoxShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + Array box_array; + box_array.resize(RS::ARRAY_MAX); + BoxMesh::create_mesh_array(box_array, size); + + Vector colors; + const PackedVector3Array &verts = box_array[RS::ARRAY_VERTEX]; + const int32_t verts_size = verts.size(); + for (int i = 0; i < verts_size; i++) { + colors.append(p_modulate); + } + + Ref box_mesh = memnew(ArrayMesh); + box_array[RS::ARRAY_COLOR] = colors; + box_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, box_array); + return box_mesh; +} + real_t BoxShape3D::get_enclosing_radius() const { return size.length() / 2; } diff --git a/scene/resources/3d/box_shape_3d.h b/scene/resources/3d/box_shape_3d.h index 45c1cde5d7..a9137fdcaf 100644 --- a/scene/resources/3d/box_shape_3d.h +++ b/scene/resources/3d/box_shape_3d.h @@ -51,6 +51,7 @@ public: Vector3 get_size() const; virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override; BoxShape3D(); diff --git a/scene/resources/3d/capsule_shape_3d.cpp b/scene/resources/3d/capsule_shape_3d.cpp index 9e16801060..b63bf69aee 100644 --- a/scene/resources/3d/capsule_shape_3d.cpp +++ b/scene/resources/3d/capsule_shape_3d.cpp @@ -30,6 +30,7 @@ #include "capsule_shape_3d.h" +#include "scene/resources/3d/primitive_meshes.h" #include "servers/physics_server_3d.h" Vector CapsuleShape3D::get_debug_mesh_lines() const { @@ -67,6 +68,24 @@ Vector CapsuleShape3D::get_debug_mesh_lines() const { return points; } +Ref CapsuleShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + Array capsule_array; + capsule_array.resize(RS::ARRAY_MAX); + CapsuleMesh::create_mesh_array(capsule_array, radius, height, 32, 8); + + Vector colors; + const PackedVector3Array &verts = capsule_array[RS::ARRAY_VERTEX]; + const int32_t verts_size = verts.size(); + for (int i = 0; i < verts_size; i++) { + colors.append(p_modulate); + } + + Ref capsule_mesh = memnew(ArrayMesh); + capsule_array[RS::ARRAY_COLOR] = colors; + capsule_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, capsule_array); + return capsule_mesh; +} + real_t CapsuleShape3D::get_enclosing_radius() const { return height * 0.5; } diff --git a/scene/resources/3d/capsule_shape_3d.h b/scene/resources/3d/capsule_shape_3d.h index 90ee3b584a..2ad7fa452c 100644 --- a/scene/resources/3d/capsule_shape_3d.h +++ b/scene/resources/3d/capsule_shape_3d.h @@ -33,6 +33,8 @@ #include "scene/resources/3d/shape_3d.h" +class ArrayMesh; + class CapsuleShape3D : public Shape3D { GDCLASS(CapsuleShape3D, Shape3D); float radius = 0.5; @@ -50,6 +52,7 @@ public: float get_height() const; virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override; CapsuleShape3D(); diff --git a/scene/resources/3d/concave_polygon_shape_3d.cpp b/scene/resources/3d/concave_polygon_shape_3d.cpp index 82b125905f..1254cc4306 100644 --- a/scene/resources/3d/concave_polygon_shape_3d.cpp +++ b/scene/resources/3d/concave_polygon_shape_3d.cpp @@ -30,6 +30,7 @@ #include "concave_polygon_shape_3d.h" +#include "scene/resources/mesh.h" #include "servers/physics_server_3d.h" Vector ConcavePolygonShape3D::get_debug_mesh_lines() const { @@ -59,6 +60,23 @@ Vector ConcavePolygonShape3D::get_debug_mesh_lines() const { return points; } +Ref ConcavePolygonShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + Vector colors; + + for (int i = 0; i < faces.size(); i++) { + colors.push_back(p_modulate); + } + + Ref mesh = memnew(ArrayMesh); + Array a; + a.resize(Mesh::ARRAY_MAX); + a[RS::ARRAY_VERTEX] = faces; + a[RS::ARRAY_COLOR] = colors; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a); + + return mesh; +} + real_t ConcavePolygonShape3D::get_enclosing_radius() const { Vector data = get_faces(); const Vector3 *read = data.ptr(); diff --git a/scene/resources/3d/concave_polygon_shape_3d.h b/scene/resources/3d/concave_polygon_shape_3d.h index a5e46474d5..d5e5bc394b 100644 --- a/scene/resources/3d/concave_polygon_shape_3d.h +++ b/scene/resources/3d/concave_polygon_shape_3d.h @@ -33,6 +33,8 @@ #include "scene/resources/3d/shape_3d.h" +class ArrayMesh; + class ConcavePolygonShape3D : public Shape3D { GDCLASS(ConcavePolygonShape3D, Shape3D); @@ -72,6 +74,7 @@ public: bool is_backface_collision_enabled() const; virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override; ConcavePolygonShape3D(); diff --git a/scene/resources/3d/convex_polygon_shape_3d.cpp b/scene/resources/3d/convex_polygon_shape_3d.cpp index 586d5f4678..809c089e6c 100644 --- a/scene/resources/3d/convex_polygon_shape_3d.cpp +++ b/scene/resources/3d/convex_polygon_shape_3d.cpp @@ -30,6 +30,7 @@ #include "convex_polygon_shape_3d.h" #include "core/math/convex_hull.h" +#include "scene/resources/mesh.h" #include "servers/physics_server_3d.h" Vector ConvexPolygonShape3D::get_debug_mesh_lines() const { @@ -53,6 +54,44 @@ Vector ConvexPolygonShape3D::get_debug_mesh_lines() const { return Vector(); } +Ref ConvexPolygonShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + const Vector hull_points = get_points(); + + Vector verts; + Vector colors; + Vector indices; + + if (hull_points.size() >= 3) { + Geometry3D::MeshData md; + Error err = ConvexHullComputer::convex_hull(hull_points, md); + if (err == OK) { + verts = md.vertices; + for (int i = 0; i < verts.size(); i++) { + colors.push_back(p_modulate); + } + for (const Geometry3D::MeshData::Face &face : md.faces) { + const int first_point = face.indices[0]; + const int indices_count = face.indices.size(); + for (int i = 1; i < indices_count - 1; i++) { + indices.push_back(first_point); + indices.push_back(face.indices[i]); + indices.push_back(face.indices[i + 1]); + } + } + } + } + + Ref mesh = memnew(ArrayMesh); + Array a; + a.resize(Mesh::ARRAY_MAX); + a[RS::ARRAY_VERTEX] = verts; + a[RS::ARRAY_COLOR] = colors; + a[RS::ARRAY_INDEX] = indices; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a); + + return mesh; +} + real_t ConvexPolygonShape3D::get_enclosing_radius() const { Vector data = get_points(); const Vector3 *read = data.ptr(); diff --git a/scene/resources/3d/convex_polygon_shape_3d.h b/scene/resources/3d/convex_polygon_shape_3d.h index 7d1ac123c6..2dd4ce66db 100644 --- a/scene/resources/3d/convex_polygon_shape_3d.h +++ b/scene/resources/3d/convex_polygon_shape_3d.h @@ -33,6 +33,8 @@ #include "scene/resources/3d/shape_3d.h" +class ArrayMesh; + class ConvexPolygonShape3D : public Shape3D { GDCLASS(ConvexPolygonShape3D, Shape3D); Vector points; @@ -47,6 +49,7 @@ public: Vector get_points() const; virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override; ConvexPolygonShape3D(); diff --git a/scene/resources/3d/cylinder_shape_3d.cpp b/scene/resources/3d/cylinder_shape_3d.cpp index a91282fd33..700ff5884d 100644 --- a/scene/resources/3d/cylinder_shape_3d.cpp +++ b/scene/resources/3d/cylinder_shape_3d.cpp @@ -30,6 +30,7 @@ #include "cylinder_shape_3d.h" +#include "scene/resources/3d/primitive_meshes.h" #include "servers/physics_server_3d.h" Vector CylinderShape3D::get_debug_mesh_lines() const { @@ -60,6 +61,24 @@ Vector CylinderShape3D::get_debug_mesh_lines() const { return points; } +Ref CylinderShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + Array cylinder_array; + cylinder_array.resize(RS::ARRAY_MAX); + CylinderMesh::create_mesh_array(cylinder_array, radius, radius, height, 32); + + Vector colors; + const PackedVector3Array &verts = cylinder_array[RS::ARRAY_VERTEX]; + const int32_t verts_size = verts.size(); + for (int i = 0; i < verts_size; i++) { + colors.append(p_modulate); + } + + Ref cylinder_mesh = memnew(ArrayMesh); + cylinder_array[RS::ARRAY_COLOR] = colors; + cylinder_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, cylinder_array); + return cylinder_mesh; +} + real_t CylinderShape3D::get_enclosing_radius() const { return Vector2(radius, height * 0.5).length(); } diff --git a/scene/resources/3d/cylinder_shape_3d.h b/scene/resources/3d/cylinder_shape_3d.h index bd57bc2a97..9388cab368 100644 --- a/scene/resources/3d/cylinder_shape_3d.h +++ b/scene/resources/3d/cylinder_shape_3d.h @@ -33,6 +33,8 @@ #include "scene/resources/3d/shape_3d.h" +class ArrayMesh; + class CylinderShape3D : public Shape3D { GDCLASS(CylinderShape3D, Shape3D); float radius = 0.5; @@ -49,6 +51,7 @@ public: float get_height() const; virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override; CylinderShape3D(); diff --git a/scene/resources/3d/height_map_shape_3d.cpp b/scene/resources/3d/height_map_shape_3d.cpp index 5b55b66152..65b1425670 100644 --- a/scene/resources/3d/height_map_shape_3d.cpp +++ b/scene/resources/3d/height_map_shape_3d.cpp @@ -31,6 +31,7 @@ #include "height_map_shape_3d.h" #include "core/io/image.h" +#include "scene/resources/mesh.h" #include "servers/physics_server_3d.h" Vector HeightMapShape3D::get_debug_mesh_lines() const { @@ -82,6 +83,60 @@ Vector HeightMapShape3D::get_debug_mesh_lines() const { return points; } +Ref HeightMapShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + Vector verts; + Vector colors; + Vector indices; + + // This will be slow for large maps... + + if ((map_width != 0) && (map_depth != 0)) { + Vector2 size = Vector2(map_width - 1, map_depth - 1) * -0.5; + const real_t *r = map_data.ptr(); + + for (int d = 0; d <= map_depth - 2; d++) { + const int this_row_offset = map_width * d; + const int next_row_offset = this_row_offset + map_width; + + for (int w = 0; w <= map_width - 2; w++) { + const float height_tl = r[next_row_offset + w]; + const float height_bl = r[this_row_offset + w]; + const float height_br = r[this_row_offset + w + 1]; + const float height_tr = r[next_row_offset + w + 1]; + + const int index_offset = verts.size(); + + verts.push_back(Vector3(size.x + w, height_tl, size.y + d + 1)); + verts.push_back(Vector3(size.x + w, height_bl, size.y + d)); + verts.push_back(Vector3(size.x + w + 1, height_br, size.y + d)); + verts.push_back(Vector3(size.x + w + 1, height_tr, size.y + d + 1)); + + colors.push_back(p_modulate); + colors.push_back(p_modulate); + colors.push_back(p_modulate); + colors.push_back(p_modulate); + + indices.push_back(index_offset); + indices.push_back(index_offset + 1); + indices.push_back(index_offset + 2); + indices.push_back(index_offset); + indices.push_back(index_offset + 2); + indices.push_back(index_offset + 3); + } + } + } + + Ref mesh = memnew(ArrayMesh); + Array a; + a.resize(Mesh::ARRAY_MAX); + a[RS::ARRAY_VERTEX] = verts; + a[RS::ARRAY_COLOR] = colors; + a[RS::ARRAY_INDEX] = indices; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a); + + return mesh; +} + real_t HeightMapShape3D::get_enclosing_radius() const { return Vector3(real_t(map_width), max_height - min_height, real_t(map_depth)).length(); } diff --git a/scene/resources/3d/height_map_shape_3d.h b/scene/resources/3d/height_map_shape_3d.h index 33ba9c4472..b5be53092d 100644 --- a/scene/resources/3d/height_map_shape_3d.h +++ b/scene/resources/3d/height_map_shape_3d.h @@ -33,6 +33,7 @@ #include "scene/resources/3d/shape_3d.h" +class ArrayMesh; class Image; class HeightMapShape3D : public Shape3D { @@ -62,6 +63,7 @@ public: void update_map_data_from_image(const Ref &p_image, real_t p_height_min, real_t p_height_max); virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override; HeightMapShape3D(); diff --git a/scene/resources/3d/separation_ray_shape_3d.cpp b/scene/resources/3d/separation_ray_shape_3d.cpp index 07e93b8b79..55529be624 100644 --- a/scene/resources/3d/separation_ray_shape_3d.cpp +++ b/scene/resources/3d/separation_ray_shape_3d.cpp @@ -30,6 +30,7 @@ #include "separation_ray_shape_3d.h" +#include "scene/resources/mesh.h" #include "servers/physics_server_3d.h" Vector SeparationRayShape3D::get_debug_mesh_lines() const { @@ -41,6 +42,10 @@ Vector SeparationRayShape3D::get_debug_mesh_lines() const { return points; } +Ref SeparationRayShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + return memnew(ArrayMesh); +} + real_t SeparationRayShape3D::get_enclosing_radius() const { return length; } diff --git a/scene/resources/3d/separation_ray_shape_3d.h b/scene/resources/3d/separation_ray_shape_3d.h index f24f0eae9e..c1c273c448 100644 --- a/scene/resources/3d/separation_ray_shape_3d.h +++ b/scene/resources/3d/separation_ray_shape_3d.h @@ -33,6 +33,8 @@ #include "scene/resources/3d/shape_3d.h" +class ArrayMesh; + class SeparationRayShape3D : public Shape3D { GDCLASS(SeparationRayShape3D, Shape3D); float length = 1.0; @@ -50,6 +52,7 @@ public: bool get_slide_on_slope() const; virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override; SeparationRayShape3D(); diff --git a/scene/resources/3d/shape_3d.cpp b/scene/resources/3d/shape_3d.cpp index 259d82b7a0..a1ee7b85dd 100644 --- a/scene/resources/3d/shape_3d.cpp +++ b/scene/resources/3d/shape_3d.cpp @@ -66,6 +66,34 @@ void Shape3D::set_margin(real_t p_margin) { PhysicsServer3D::get_singleton()->shape_set_margin(shape, margin); } +#ifdef DEBUG_ENABLED +void Shape3D::set_debug_color(const Color &p_color) { + if (p_color == debug_color) { + return; + } + + debug_color = p_color; + _update_shape(); +} + +Color Shape3D::get_debug_color() const { + return debug_color; +} + +void Shape3D::set_debug_fill(bool p_fill) { + if (p_fill == debug_fill) { + return; + } + + debug_fill = p_fill; + _update_shape(); +} + +bool Shape3D::get_debug_fill() const { + return debug_fill; +} +#endif // DEBUG_ENABLED + Ref Shape3D::get_debug_mesh() { if (debug_mesh_cache.is_valid()) { return debug_mesh_cache; @@ -79,29 +107,57 @@ Ref Shape3D::get_debug_mesh() { //make mesh Vector array; array.resize(lines.size()); - { - Vector3 *w = array.ptrw(); - for (int i = 0; i < lines.size(); i++) { - w[i] = lines[i]; - } + Vector3 *v = array.ptrw(); + + Vector arraycol; + arraycol.resize(lines.size()); + Color *c = arraycol.ptrw(); + + for (int i = 0; i < lines.size(); i++) { + v[i] = lines[i]; + c[i] = debug_color; } - Array arr; - arr.resize(Mesh::ARRAY_MAX); - arr[Mesh::ARRAY_VERTEX] = array; + Array lines_array; + lines_array.resize(Mesh::ARRAY_MAX); + lines_array[Mesh::ARRAY_VERTEX] = array; + lines_array[Mesh::ARRAY_COLOR] = arraycol; - SceneTree *st = Object::cast_to(OS::get_singleton()->get_main_loop()); + Ref material = get_debug_collision_material(); - debug_mesh_cache->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, arr); + debug_mesh_cache->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, lines_array); + debug_mesh_cache->surface_set_material(0, material); - if (st) { - debug_mesh_cache->surface_set_material(0, st->get_debug_collision_material()); + if (debug_fill) { + Array solid_array = get_debug_arraymesh_faces(debug_color * Color(1.0, 1.0, 1.0, 0.0625))->surface_get_arrays(0); + debug_mesh_cache->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, solid_array); + debug_mesh_cache->surface_set_material(1, material); } } return debug_mesh_cache; } +Ref Shape3D::get_debug_collision_material() { + if (collision_material.is_valid()) { + return collision_material; + } + + Ref material = memnew(StandardMaterial3D); + material->set_albedo(Color(1.0, 1.0, 1.0)); + material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MIN + 1); + material->set_cull_mode(StandardMaterial3D::CULL_BACK); + material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); + material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + + collision_material = material; + + return collision_material; +} + void Shape3D::_update_shape() { emit_changed(); debug_mesh_cache.unref(); diff --git a/scene/resources/3d/shape_3d.h b/scene/resources/3d/shape_3d.h index 5e6cdbe421..e956f4c322 100644 --- a/scene/resources/3d/shape_3d.h +++ b/scene/resources/3d/shape_3d.h @@ -34,6 +34,7 @@ #include "core/io/resource.h" class ArrayMesh; +class Material; class Shape3D : public Resource { GDCLASS(Shape3D, Resource); @@ -44,6 +45,10 @@ class Shape3D : public Resource { real_t margin = 0.04; Ref debug_mesh_cache; + Ref collision_material; + + Color debug_color = Color(0.0, 0.0, 0.0, 0.0); + bool debug_fill = true; protected: static void _bind_methods(); @@ -51,6 +56,8 @@ protected: _FORCE_INLINE_ RID get_shape() const { return shape; } Shape3D(RID p_shape); + Ref get_debug_collision_material(); + virtual void _update_shape(); public: @@ -58,6 +65,7 @@ public: Ref get_debug_mesh(); virtual Vector get_debug_mesh_lines() const = 0; // { return Vector(); } + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const = 0; /// Returns the radius of a sphere that fully enclose this shape virtual real_t get_enclosing_radius() const = 0; @@ -69,6 +77,14 @@ public: real_t get_margin() const; void set_margin(real_t p_margin); +#ifdef DEBUG_ENABLED + void set_debug_color(const Color &p_color); + Color get_debug_color() const; + + void set_debug_fill(bool p_fill); + bool get_debug_fill() const; +#endif // DEBUG_ENABLED + Shape3D(); ~Shape3D(); }; diff --git a/scene/resources/3d/sphere_shape_3d.cpp b/scene/resources/3d/sphere_shape_3d.cpp index 56b78471ec..bdce41c16f 100644 --- a/scene/resources/3d/sphere_shape_3d.cpp +++ b/scene/resources/3d/sphere_shape_3d.cpp @@ -30,6 +30,8 @@ #include "sphere_shape_3d.h" +#include "scene/resources/3d/primitive_meshes.h" +#include "scene/resources/material.h" #include "servers/physics_server_3d.h" Vector SphereShape3D::get_debug_mesh_lines() const { @@ -54,6 +56,24 @@ Vector SphereShape3D::get_debug_mesh_lines() const { return points; } +Ref SphereShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + Array sphere_array; + sphere_array.resize(RS::ARRAY_MAX); + SphereMesh::create_mesh_array(sphere_array, radius, radius * 2, 32); + + Vector colors; + const PackedVector3Array &verts = sphere_array[RS::ARRAY_VERTEX]; + const int32_t verts_size = verts.size(); + for (int i = 0; i < verts_size; i++) { + colors.append(p_modulate); + } + + Ref sphere_mesh = memnew(ArrayMesh); + sphere_array[RS::ARRAY_COLOR] = colors; + sphere_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, sphere_array); + return sphere_mesh; +} + real_t SphereShape3D::get_enclosing_radius() const { return radius; } diff --git a/scene/resources/3d/sphere_shape_3d.h b/scene/resources/3d/sphere_shape_3d.h index 8e95cea608..cb0685287d 100644 --- a/scene/resources/3d/sphere_shape_3d.h +++ b/scene/resources/3d/sphere_shape_3d.h @@ -33,6 +33,8 @@ #include "scene/resources/3d/shape_3d.h" +class ArrayMesh; + class SphereShape3D : public Shape3D { GDCLASS(SphereShape3D, Shape3D); float radius = 0.5f; @@ -47,6 +49,7 @@ public: float get_radius() const; virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override; SphereShape3D(); diff --git a/scene/resources/3d/world_boundary_shape_3d.cpp b/scene/resources/3d/world_boundary_shape_3d.cpp index beaaddc95e..25f060aa97 100644 --- a/scene/resources/3d/world_boundary_shape_3d.cpp +++ b/scene/resources/3d/world_boundary_shape_3d.cpp @@ -30,6 +30,7 @@ #include "world_boundary_shape_3d.h" +#include "scene/resources/mesh.h" #include "servers/physics_server_3d.h" Vector WorldBoundaryShape3D::get_debug_mesh_lines() const { @@ -61,6 +62,53 @@ Vector WorldBoundaryShape3D::get_debug_mesh_lines() const { return points; } +Ref WorldBoundaryShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const { + Plane p = get_plane(); + + Vector3 n1 = p.get_any_perpendicular_normal(); + Vector3 n2 = p.normal.cross(n1).normalized(); + + Vector3 pface[4] = { + p.normal * p.d + n1 * 10.0 + n2 * 10.0, + p.normal * p.d + n1 * 10.0 + n2 * -10.0, + p.normal * p.d + n1 * -10.0 + n2 * -10.0, + p.normal * p.d + n1 * -10.0 + n2 * 10.0, + }; + + Vector points = { + pface[0], + pface[1], + pface[2], + pface[3], + }; + + Vector colors = { + p_modulate, + p_modulate, + p_modulate, + p_modulate, + }; + + Vector indices = { + 0, + 1, + 2, + 0, + 2, + 3, + }; + + Ref mesh = memnew(ArrayMesh); + Array a; + a.resize(Mesh::ARRAY_MAX); + a[RS::ARRAY_VERTEX] = points; + a[RS::ARRAY_COLOR] = colors; + a[RS::ARRAY_INDEX] = indices; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a); + + return mesh; +} + void WorldBoundaryShape3D::_update_shape() { PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), plane); Shape3D::_update_shape(); diff --git a/scene/resources/3d/world_boundary_shape_3d.h b/scene/resources/3d/world_boundary_shape_3d.h index 06cff6aa9a..456316df2e 100644 --- a/scene/resources/3d/world_boundary_shape_3d.h +++ b/scene/resources/3d/world_boundary_shape_3d.h @@ -33,6 +33,8 @@ #include "scene/resources/3d/shape_3d.h" +class ArrayMesh; + class WorldBoundaryShape3D : public Shape3D { GDCLASS(WorldBoundaryShape3D, Shape3D); Plane plane; @@ -46,6 +48,7 @@ public: const Plane &get_plane() const; virtual Vector get_debug_mesh_lines() const override; + virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; virtual real_t get_enclosing_radius() const override { // Should be infinite? return 0; -- cgit v1.2.3 From 612981c1ea7d1beb927b53a2e4056827ed6ca32a Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Mon, 27 Nov 2023 19:37:52 +0100 Subject: Add ShadowCastingSetting to MeshLibrary / GridMap items Adds ShadowCastingSetting to MeshLibrary / GridMap items. --- scene/resources/3d/mesh_library.cpp | 34 ++++++++++++++++++++++++++++++++++ scene/resources/3d/mesh_library.h | 4 ++++ 2 files changed, 38 insertions(+) (limited to 'scene/resources') diff --git a/scene/resources/3d/mesh_library.cpp b/scene/resources/3d/mesh_library.cpp index c2f721a80f..446abc1330 100644 --- a/scene/resources/3d/mesh_library.cpp +++ b/scene/resources/3d/mesh_library.cpp @@ -47,6 +47,24 @@ bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) { set_item_mesh(idx, p_value); } else if (what == "mesh_transform") { set_item_mesh_transform(idx, p_value); + } else if (what == "mesh_cast_shadow") { + switch ((int)p_value) { + case 0: { + set_item_mesh_cast_shadow(idx, RS::ShadowCastingSetting::SHADOW_CASTING_SETTING_OFF); + } break; + case 1: { + set_item_mesh_cast_shadow(idx, RS::ShadowCastingSetting::SHADOW_CASTING_SETTING_ON); + } break; + case 2: { + set_item_mesh_cast_shadow(idx, RS::ShadowCastingSetting::SHADOW_CASTING_SETTING_DOUBLE_SIDED); + } break; + case 3: { + set_item_mesh_cast_shadow(idx, RS::ShadowCastingSetting::SHADOW_CASTING_SETTING_SHADOWS_ONLY); + } break; + default: { + set_item_mesh_cast_shadow(idx, RS::ShadowCastingSetting::SHADOW_CASTING_SETTING_ON); + } break; + } } else if (what == "shape") { Vector shapes; ShapeData sd; @@ -91,6 +109,8 @@ bool MeshLibrary::_get(const StringName &p_name, Variant &r_ret) const { r_ret = get_item_mesh(idx); } else if (what == "mesh_transform") { r_ret = get_item_mesh_transform(idx); + } else if (what == "mesh_cast_shadow") { + r_ret = (int)get_item_mesh_cast_shadow(idx); } else if (what == "shapes") { r_ret = _get_item_shapes(idx); } else if (what == "navigation_mesh") { @@ -120,6 +140,7 @@ void MeshLibrary::_get_property_list(List *p_list) const { p_list->push_back(PropertyInfo(Variant::STRING, prop_name + PNAME("name"))); p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + PNAME("mesh"), PROPERTY_HINT_RESOURCE_TYPE, "Mesh")); p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prop_name + PNAME("mesh_transform"), PROPERTY_HINT_NONE, "suffix:m")); + p_list->push_back(PropertyInfo(Variant::INT, prop_name + PNAME("mesh_cast_shadow"), PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only")); p_list->push_back(PropertyInfo(Variant::ARRAY, prop_name + PNAME("shapes"))); p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + PNAME("navigation_mesh"), PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh")); p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prop_name + PNAME("navigation_mesh_transform"), PROPERTY_HINT_NONE, "suffix:m")); @@ -154,6 +175,12 @@ void MeshLibrary::set_item_mesh_transform(int p_item, const Transform3D &p_trans emit_changed(); } +void MeshLibrary::set_item_mesh_cast_shadow(int p_item, RS::ShadowCastingSetting p_shadow_casting_setting) { + ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); + item_map[p_item].mesh_cast_shadow = p_shadow_casting_setting; + emit_changed(); +} + void MeshLibrary::set_item_shapes(int p_item, const Vector &p_shapes) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].shapes = p_shapes; @@ -200,6 +227,11 @@ Transform3D MeshLibrary::get_item_mesh_transform(int p_item) const { return item_map[p_item].mesh_transform; } +RS::ShadowCastingSetting MeshLibrary::get_item_mesh_cast_shadow(int p_item) const { + ERR_FAIL_COND_V_MSG(!item_map.has(p_item), RS::ShadowCastingSetting::SHADOW_CASTING_SETTING_ON, "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); + return item_map[p_item].mesh_cast_shadow; +} + Vector MeshLibrary::get_item_shapes(int p_item) const { ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Vector(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); return item_map[p_item].shapes; @@ -328,6 +360,7 @@ void MeshLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_name", "id", "name"), &MeshLibrary::set_item_name); ClassDB::bind_method(D_METHOD("set_item_mesh", "id", "mesh"), &MeshLibrary::set_item_mesh); ClassDB::bind_method(D_METHOD("set_item_mesh_transform", "id", "mesh_transform"), &MeshLibrary::set_item_mesh_transform); + ClassDB::bind_method(D_METHOD("set_item_mesh_cast_shadow", "id", "shadow_casting_setting"), &MeshLibrary::set_item_mesh_cast_shadow); ClassDB::bind_method(D_METHOD("set_item_navigation_mesh", "id", "navigation_mesh"), &MeshLibrary::set_item_navigation_mesh); ClassDB::bind_method(D_METHOD("set_item_navigation_mesh_transform", "id", "navigation_mesh"), &MeshLibrary::set_item_navigation_mesh_transform); ClassDB::bind_method(D_METHOD("set_item_navigation_layers", "id", "navigation_layers"), &MeshLibrary::set_item_navigation_layers); @@ -336,6 +369,7 @@ void MeshLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_name", "id"), &MeshLibrary::get_item_name); ClassDB::bind_method(D_METHOD("get_item_mesh", "id"), &MeshLibrary::get_item_mesh); ClassDB::bind_method(D_METHOD("get_item_mesh_transform", "id"), &MeshLibrary::get_item_mesh_transform); + ClassDB::bind_method(D_METHOD("get_item_mesh_cast_shadow", "id"), &MeshLibrary::get_item_mesh_cast_shadow); ClassDB::bind_method(D_METHOD("get_item_navigation_mesh", "id"), &MeshLibrary::get_item_navigation_mesh); ClassDB::bind_method(D_METHOD("get_item_navigation_mesh_transform", "id"), &MeshLibrary::get_item_navigation_mesh_transform); ClassDB::bind_method(D_METHOD("get_item_navigation_layers", "id"), &MeshLibrary::get_item_navigation_layers); diff --git a/scene/resources/3d/mesh_library.h b/scene/resources/3d/mesh_library.h index f1a1e3e273..fc38b848a2 100644 --- a/scene/resources/3d/mesh_library.h +++ b/scene/resources/3d/mesh_library.h @@ -35,6 +35,7 @@ #include "core/templates/rb_map.h" #include "scene/3d/navigation_region_3d.h" #include "scene/resources/mesh.h" +#include "servers/rendering_server.h" #include "shape_3d.h" class MeshLibrary : public Resource { @@ -50,6 +51,7 @@ public: String name; Ref mesh; Transform3D mesh_transform; + RS::ShadowCastingSetting mesh_cast_shadow = RS::ShadowCastingSetting::SHADOW_CASTING_SETTING_ON; Vector shapes; Ref preview; Ref navigation_mesh; @@ -75,6 +77,7 @@ public: void set_item_name(int p_item, const String &p_name); void set_item_mesh(int p_item, const Ref &p_mesh); void set_item_mesh_transform(int p_item, const Transform3D &p_transform); + void set_item_mesh_cast_shadow(int p_item, RS::ShadowCastingSetting p_shadow_casting_setting); void set_item_navigation_mesh(int p_item, const Ref &p_navigation_mesh); void set_item_navigation_mesh_transform(int p_item, const Transform3D &p_transform); void set_item_navigation_layers(int p_item, uint32_t p_navigation_layers); @@ -83,6 +86,7 @@ public: String get_item_name(int p_item) const; Ref get_item_mesh(int p_item) const; Transform3D get_item_mesh_transform(int p_item) const; + RS::ShadowCastingSetting get_item_mesh_cast_shadow(int p_item) const; Ref get_item_navigation_mesh(int p_item) const; Transform3D get_item_navigation_mesh_transform(int p_item) const; uint32_t get_item_navigation_layers(int p_item) const; -- cgit v1.2.3 From 9e34e454805f0dc6aad459170e7a2bbdaf2d4575 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Tue, 26 Nov 2024 21:43:46 -0800 Subject: Use Vector4 for texture mask in BaseMaterial to avoid converting to and from Plane --- scene/resources/material.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'scene/resources') diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index ecc1982aa5..96719a9e76 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -2737,13 +2737,13 @@ float BaseMaterial3D::get_grow() const { return grow; } -static Plane _get_texture_mask(BaseMaterial3D::TextureChannel p_channel) { - static const Plane masks[5] = { - Plane(1, 0, 0, 0), - Plane(0, 1, 0, 0), - Plane(0, 0, 1, 0), - Plane(0, 0, 0, 1), - Plane(0.3333333, 0.3333333, 0.3333333, 0), +static Vector4 _get_texture_mask(BaseMaterial3D::TextureChannel p_channel) { + static const Vector4 masks[5] = { + Vector4(1, 0, 0, 0), + Vector4(0, 1, 0, 0), + Vector4(0, 0, 1, 0), + Vector4(0, 0, 0, 1), + Vector4(0.3333333, 0.3333333, 0.3333333, 0), }; return masks[p_channel]; -- cgit v1.2.3