diff --git a/doc/classes/CapsuleShape2D.xml b/doc/classes/CapsuleShape2D.xml index 52ea7af2921..c8652e4ec45 100644 --- a/doc/classes/CapsuleShape2D.xml +++ b/doc/classes/CapsuleShape2D.xml @@ -11,7 +11,10 @@ - The capsule's height. + The capsule's full height, including the semicircles. + + + The capsule's height, excluding the semicircles. This is the height of the central rectangular part in the middle of the capsule, and is the distance between the centers of the two semicircles. This is a wrapper for [member height]. The capsule's radius. diff --git a/doc/classes/CapsuleShape3D.xml b/doc/classes/CapsuleShape3D.xml index 4c6b3a870f5..4e7c3d2edb3 100644 --- a/doc/classes/CapsuleShape3D.xml +++ b/doc/classes/CapsuleShape3D.xml @@ -12,7 +12,10 @@ - The capsule's height. + The capsule's full height, including the hemispheres. + + + The capsule's height, excluding the hemispheres. This is the height of the central cylindrical part in the middle of the capsule, and is the distance between the centers of the two hemispheres. This is a wrapper for [member height]. The capsule's radius. diff --git a/doc/classes/SpringBoneCollisionCapsule3D.xml b/doc/classes/SpringBoneCollisionCapsule3D.xml index 9af9aca331a..1e5767cf8cd 100644 --- a/doc/classes/SpringBoneCollisionCapsule3D.xml +++ b/doc/classes/SpringBoneCollisionCapsule3D.xml @@ -10,11 +10,14 @@ - The capsule's height. + The capsule's full height, including the hemispheres. If [code]true[/code], the collision acts to trap the joint within the collision. + + The capsule's height, excluding the hemispheres. This is the height of the central cylindrical part in the middle of the capsule, and is the distance between the centers of the two hemispheres. This is a wrapper for [member height]. + The capsule's radius. diff --git a/scene/3d/spring_bone_collision_capsule_3d.cpp b/scene/3d/spring_bone_collision_capsule_3d.cpp index 39acc5acebb..c238eb0962f 100644 --- a/scene/3d/spring_bone_collision_capsule_3d.cpp +++ b/scene/3d/spring_bone_collision_capsule_3d.cpp @@ -60,6 +60,18 @@ float SpringBoneCollisionCapsule3D::get_height() const { return height; } +void SpringBoneCollisionCapsule3D::set_mid_height(real_t p_mid_height) { + ERR_FAIL_COND_MSG(p_mid_height < 0.0f, "SpringBoneCollisionCapsule3D mid-height cannot be negative."); + height = p_mid_height + radius * 2.0f; +#ifdef TOOLS_ENABLED + update_gizmos(); +#endif // TOOLS_ENABLED +} + +real_t SpringBoneCollisionCapsule3D::get_mid_height() const { + return height - radius * 2.0f; +} + void SpringBoneCollisionCapsule3D::set_inside(bool p_enabled) { inside = p_enabled; #ifdef TOOLS_ENABLED @@ -83,11 +95,14 @@ void SpringBoneCollisionCapsule3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_radius"), &SpringBoneCollisionCapsule3D::get_radius); ClassDB::bind_method(D_METHOD("set_height", "height"), &SpringBoneCollisionCapsule3D::set_height); ClassDB::bind_method(D_METHOD("get_height"), &SpringBoneCollisionCapsule3D::get_height); + ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &SpringBoneCollisionCapsule3D::set_mid_height); + ClassDB::bind_method(D_METHOD("get_mid_height"), &SpringBoneCollisionCapsule3D::get_mid_height); ClassDB::bind_method(D_METHOD("set_inside", "enabled"), &SpringBoneCollisionCapsule3D::set_inside); ClassDB::bind_method(D_METHOD("is_inside"), &SpringBoneCollisionCapsule3D::is_inside); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m", PROPERTY_USAGE_NONE), "set_mid_height", "get_mid_height"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "inside"), "set_inside", "is_inside"); } diff --git a/scene/3d/spring_bone_collision_capsule_3d.h b/scene/3d/spring_bone_collision_capsule_3d.h index 61ee79cd3bc..5ea7bd9b557 100644 --- a/scene/3d/spring_bone_collision_capsule_3d.h +++ b/scene/3d/spring_bone_collision_capsule_3d.h @@ -49,6 +49,8 @@ public: float get_radius() const; void set_height(float p_height); float get_height() const; + void set_mid_height(real_t p_mid_height); + real_t get_mid_height() const; void set_inside(bool p_enabled); bool is_inside() const; diff --git a/scene/resources/2d/capsule_shape_2d.cpp b/scene/resources/2d/capsule_shape_2d.cpp index 369acf714ec..917cd86f195 100644 --- a/scene/resources/2d/capsule_shape_2d.cpp +++ b/scene/resources/2d/capsule_shape_2d.cpp @@ -38,7 +38,7 @@ Vector CapsuleShape2D::_get_points() const { Vector points; const real_t turn_step = Math::TAU / 24.0; for (int i = 0; i < 24; i++) { - Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -height * 0.5 + radius : height * 0.5 - radius); + Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -height * 0.5f + radius : height * 0.5f - radius); points.push_back(Vector2(Math::sin(i * turn_step), Math::cos(i * turn_step)) * radius + ofs); if (i == 6 || i == 18) { @@ -59,13 +59,13 @@ void CapsuleShape2D::_update_shape() { } void CapsuleShape2D::set_radius(real_t p_radius) { - ERR_FAIL_COND_MSG(p_radius < 0, "CapsuleShape2D radius cannot be negative."); + ERR_FAIL_COND_MSG(p_radius < 0.0f, "CapsuleShape2D radius cannot be negative."); if (radius == p_radius) { return; } radius = p_radius; - if (radius > height * 0.5) { - height = radius * 2.0; + if (height < radius * 2.0f) { + height = radius * 2.0f; } _update_shape(); } @@ -75,13 +75,13 @@ real_t CapsuleShape2D::get_radius() const { } void CapsuleShape2D::set_height(real_t p_height) { - ERR_FAIL_COND_MSG(p_height < 0, "CapsuleShape2D height cannot be negative."); + ERR_FAIL_COND_MSG(p_height < 0.0f, "CapsuleShape2D height cannot be negative."); if (height == p_height) { return; } height = p_height; - if (radius > height * 0.5) { - radius = height * 0.5; + if (radius > height * 0.5f) { + radius = height * 0.5f; } _update_shape(); } @@ -90,6 +90,16 @@ real_t CapsuleShape2D::get_height() const { return height; } +void CapsuleShape2D::set_mid_height(real_t p_mid_height) { + ERR_FAIL_COND_MSG(p_mid_height < 0.0f, "CapsuleShape2D mid-height cannot be negative."); + height = p_mid_height + radius * 2.0f; + _update_shape(); +} + +real_t CapsuleShape2D::get_mid_height() const { + return height - radius * 2.0f; +} + void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector points = _get_points(); Vector col = { p_color }; @@ -97,18 +107,18 @@ void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) { if (is_collision_outline_enabled()) { points.push_back(points[0]); - col = { Color(p_color, 1.0) }; + col = { Color(p_color, 1.0f) }; RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col); } } Rect2 CapsuleShape2D::get_rect() const { - const Vector2 half_size = Vector2(radius, height * 0.5); - return Rect2(-half_size, half_size * 2.0); + const Vector2 half_size = Vector2(radius, height * 0.5f); + return Rect2(-half_size, half_size * 2.0f); } real_t CapsuleShape2D::get_enclosing_radius() const { - return height * 0.5; + return height * 0.5f; } void CapsuleShape2D::_bind_methods() { @@ -118,8 +128,12 @@ void CapsuleShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape2D::set_height); ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape2D::get_height); + ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &CapsuleShape2D::set_mid_height); + ClassDB::bind_method(D_METHOD("get_mid_height"), &CapsuleShape2D::get_mid_height); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:px"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:px"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:px", PROPERTY_USAGE_NONE), "set_mid_height", "get_mid_height"); ADD_LINKED_PROPERTY("radius", "height"); ADD_LINKED_PROPERTY("height", "radius"); } diff --git a/scene/resources/2d/capsule_shape_2d.h b/scene/resources/2d/capsule_shape_2d.h index a6f4a92487f..b55771f32d9 100644 --- a/scene/resources/2d/capsule_shape_2d.h +++ b/scene/resources/2d/capsule_shape_2d.h @@ -53,6 +53,9 @@ public: void set_radius(real_t p_radius); real_t get_radius() const; + void set_mid_height(real_t p_mid_height); + real_t get_mid_height() const; + virtual void draw(const RID &p_to_rid, const Color &p_color) override; virtual Rect2 get_rect() const override; virtual real_t get_enclosing_radius() const override; diff --git a/scene/resources/3d/capsule_shape_3d.cpp b/scene/resources/3d/capsule_shape_3d.cpp index b63bf69aeed..2a7e36cf0fc 100644 --- a/scene/resources/3d/capsule_shape_3d.cpp +++ b/scene/resources/3d/capsule_shape_3d.cpp @@ -39,7 +39,7 @@ Vector CapsuleShape3D::get_debug_mesh_lines() const { Vector points; - Vector3 d(0, c_height * 0.5 - c_radius, 0); + Vector3 d(0, c_height * 0.5f - c_radius, 0); for (int i = 0; i < 360; i++) { float ra = Math::deg_to_rad((float)i); float rb = Math::deg_to_rad((float)i + 1); @@ -87,7 +87,7 @@ Ref CapsuleShape3D::get_debug_arraymesh_faces(const Color &p_modulate } real_t CapsuleShape3D::get_enclosing_radius() const { - return height * 0.5; + return height * 0.5f; } void CapsuleShape3D::_update_shape() { @@ -99,10 +99,10 @@ void CapsuleShape3D::_update_shape() { } void CapsuleShape3D::set_radius(float p_radius) { - ERR_FAIL_COND_MSG(p_radius < 0, "CapsuleShape3D radius cannot be negative."); + ERR_FAIL_COND_MSG(p_radius < 0.0f, "CapsuleShape3D radius cannot be negative."); radius = p_radius; - if (radius > height * 0.5) { - height = radius * 2.0; + if (height < radius * 2.0f) { + height = radius * 2.0f; } _update_shape(); emit_changed(); @@ -113,10 +113,10 @@ float CapsuleShape3D::get_radius() const { } void CapsuleShape3D::set_height(float p_height) { - ERR_FAIL_COND_MSG(p_height < 0, "CapsuleShape3D height cannot be negative."); + ERR_FAIL_COND_MSG(p_height < 0.0f, "CapsuleShape3D height cannot be negative."); height = p_height; - if (radius > height * 0.5) { - radius = height * 0.5; + if (radius > height * 0.5f) { + radius = height * 0.5f; } _update_shape(); emit_changed(); @@ -126,14 +126,28 @@ float CapsuleShape3D::get_height() const { return height; } +void CapsuleShape3D::set_mid_height(real_t p_mid_height) { + ERR_FAIL_COND_MSG(p_mid_height < 0.0f, "CapsuleShape3D mid-height cannot be negative."); + height = p_mid_height + radius * 2.0f; + _update_shape(); + emit_changed(); +} + +real_t CapsuleShape3D::get_mid_height() const { + return height - radius * 2.0f; +} + void CapsuleShape3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape3D::set_radius); ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape3D::get_radius); ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape3D::set_height); ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape3D::get_height); + ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &CapsuleShape3D::set_mid_height); + ClassDB::bind_method(D_METHOD("get_mid_height"), &CapsuleShape3D::get_mid_height); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m", PROPERTY_USAGE_NONE), "set_mid_height", "get_mid_height"); ADD_LINKED_PROPERTY("radius", "height"); ADD_LINKED_PROPERTY("height", "radius"); } diff --git a/scene/resources/3d/capsule_shape_3d.h b/scene/resources/3d/capsule_shape_3d.h index 16f58bc95d8..56ac5e4c90b 100644 --- a/scene/resources/3d/capsule_shape_3d.h +++ b/scene/resources/3d/capsule_shape_3d.h @@ -49,6 +49,8 @@ public: float get_radius() const; void set_height(float p_height); float get_height() const; + void set_mid_height(real_t p_mid_height); + real_t get_mid_height() const; virtual Vector get_debug_mesh_lines() const override; virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override;