diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/animated_sprite_2d.cpp | 16 | ||||
-rw-r--r-- | scene/2d/animated_sprite_2d.h | 6 | ||||
-rw-r--r-- | scene/2d/cpu_particles_2d.cpp | 48 | ||||
-rw-r--r-- | scene/2d/cpu_particles_2d.h | 38 | ||||
-rw-r--r-- | scene/2d/gpu_particles_2d.cpp | 29 | ||||
-rw-r--r-- | scene/2d/gpu_particles_2d.h | 30 | ||||
-rw-r--r-- | scene/2d/navigation_region_2d.cpp | 4 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 366 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.h | 42 | ||||
-rw-r--r-- | scene/2d/ray_cast_2d.cpp | 8 | ||||
-rw-r--r-- | scene/2d/skeleton_2d.cpp | 20 | ||||
-rw-r--r-- | scene/2d/skeleton_2d.h | 18 |
12 files changed, 418 insertions, 207 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index da2ab6ada8..026f0a85a6 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -159,12 +159,12 @@ void AnimatedSprite2D::_notification(int p_what) { return; } - float speed = frames->get_animation_speed(animation) * speed_scale; + double speed = frames->get_animation_speed(animation) * speed_scale; if (speed == 0) { return; //do nothing } - float remaining = get_process_delta_time(); + double remaining = get_process_delta_time(); while (remaining) { if (timeout <= 0) { @@ -205,7 +205,7 @@ void AnimatedSprite2D::_notification(int p_what) { emit_signal(SceneStringNames::get_singleton()->frame_changed); } - float to_process = MIN(timeout, remaining); + double to_process = MIN(timeout, remaining); remaining -= to_process; timeout -= to_process; } @@ -310,8 +310,8 @@ int AnimatedSprite2D::get_frame() const { return frame; } -void AnimatedSprite2D::set_speed_scale(float p_speed_scale) { - float elapsed = _get_frame_duration() - timeout; +void AnimatedSprite2D::set_speed_scale(double p_speed_scale) { + double elapsed = _get_frame_duration() - timeout; speed_scale = MAX(p_speed_scale, 0.0f); @@ -320,7 +320,7 @@ void AnimatedSprite2D::set_speed_scale(float p_speed_scale) { timeout -= elapsed; } -float AnimatedSprite2D::get_speed_scale() const { +double AnimatedSprite2D::get_speed_scale() const { return speed_scale; } @@ -402,9 +402,9 @@ bool AnimatedSprite2D::is_playing() const { return playing; } -float AnimatedSprite2D::_get_frame_duration() { +double AnimatedSprite2D::_get_frame_duration() { if (frames.is_valid() && frames->has_animation(animation)) { - float speed = frames->get_animation_speed(animation) * speed_scale; + double speed = frames->get_animation_speed(animation) * speed_scale; if (speed > 0) { return 1.0 / speed; } diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h index ef0027edf1..0769b19b50 100644 --- a/scene/2d/animated_sprite_2d.h +++ b/scene/2d/animated_sprite_2d.h @@ -56,7 +56,7 @@ class AnimatedSprite2D : public Node2D { void _res_changed(); - float _get_frame_duration(); + double _get_frame_duration(); void _reset_timeout(); void _set_playing(bool p_playing); bool _is_playing() const; @@ -94,8 +94,8 @@ public: void set_frame(int p_frame); int get_frame() const; - void set_speed_scale(float p_speed_scale); - float get_speed_scale() const; + void set_speed_scale(double p_speed_scale); + double get_speed_scale() const; void set_centered(bool p_center); bool is_centered() const; diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index a341ba69ac..ced1c5cb81 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -65,7 +65,7 @@ void CPUParticles2D::set_amount(int p_amount) { particle_order.resize(p_amount); } -void CPUParticles2D::set_lifetime(float p_lifetime) { +void CPUParticles2D::set_lifetime(double p_lifetime) { ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0."); lifetime = p_lifetime; } @@ -74,7 +74,7 @@ void CPUParticles2D::set_one_shot(bool p_one_shot) { one_shot = p_one_shot; } -void CPUParticles2D::set_pre_process_time(float p_time) { +void CPUParticles2D::set_pre_process_time(double p_time) { pre_process_time = p_time; } @@ -86,7 +86,7 @@ void CPUParticles2D::set_randomness_ratio(real_t p_ratio) { randomness_ratio = p_ratio; } -void CPUParticles2D::set_lifetime_randomness(float p_random) { +void CPUParticles2D::set_lifetime_randomness(double p_random) { lifetime_randomness = p_random; } @@ -95,7 +95,7 @@ void CPUParticles2D::set_use_local_coordinates(bool p_enable) { set_notify_transform(!p_enable); } -void CPUParticles2D::set_speed_scale(real_t p_scale) { +void CPUParticles2D::set_speed_scale(double p_scale) { speed_scale = p_scale; } @@ -107,7 +107,7 @@ int CPUParticles2D::get_amount() const { return particles.size(); } -float CPUParticles2D::get_lifetime() const { +double CPUParticles2D::get_lifetime() const { return lifetime; } @@ -115,7 +115,7 @@ bool CPUParticles2D::get_one_shot() const { return one_shot; } -float CPUParticles2D::get_pre_process_time() const { +double CPUParticles2D::get_pre_process_time() const { return pre_process_time; } @@ -127,7 +127,7 @@ real_t CPUParticles2D::get_randomness_ratio() const { return randomness_ratio; } -float CPUParticles2D::get_lifetime_randomness() const { +double CPUParticles2D::get_lifetime_randomness() const { return lifetime_randomness; } @@ -135,7 +135,7 @@ bool CPUParticles2D::get_use_local_coordinates() const { return local_coords; } -real_t CPUParticles2D::get_speed_scale() const { +double CPUParticles2D::get_speed_scale() const { return speed_scale; } @@ -516,7 +516,7 @@ void CPUParticles2D::_update_internal() { return; } - float delta = get_process_delta_time(); + double delta = get_process_delta_time(); if (emitting) { inactive_time = 0; } else { @@ -536,14 +536,14 @@ void CPUParticles2D::_update_internal() { _set_redraw(true); if (time == 0 && pre_process_time > 0.0) { - float frame_time; + double frame_time; if (fixed_fps > 0) { frame_time = 1.0 / fixed_fps; } else { frame_time = 1.0 / 30.0; } - float todo = pre_process_time; + double todo = pre_process_time; while (todo >= 0) { _particles_process(frame_time); @@ -552,16 +552,16 @@ void CPUParticles2D::_update_internal() { } if (fixed_fps > 0) { - float frame_time = 1.0 / fixed_fps; - float decr = frame_time; + double frame_time = 1.0 / fixed_fps; + double decr = frame_time; - float ldelta = delta; + double ldelta = delta; if (ldelta > 0.1) { //avoid recursive stalls if fps goes below 10 ldelta = 0.1; } else if (ldelta <= 0.0) { //unlikely but.. ldelta = 0.001; } - float todo = frame_remainder + ldelta; + double todo = frame_remainder + ldelta; while (todo >= frame_time) { _particles_process(frame_time); @@ -577,7 +577,7 @@ void CPUParticles2D::_update_internal() { _update_particle_data_buffer(); } -void CPUParticles2D::_particles_process(float p_delta) { +void CPUParticles2D::_particles_process(double p_delta) { p_delta *= speed_scale; int pcount = particles.size(); @@ -585,7 +585,7 @@ void CPUParticles2D::_particles_process(float p_delta) { Particle *parray = w; - float prev_time = time; + double prev_time = time; time += p_delta; if (time > lifetime) { time = Math::fmod(time, lifetime); @@ -604,7 +604,7 @@ void CPUParticles2D::_particles_process(float p_delta) { velocity_xform[2] = Vector2(); } - float system_phase = time / lifetime; + double system_phase = time / lifetime; for (int i = 0; i < pcount; i++) { Particle &p = parray[i]; @@ -613,12 +613,12 @@ void CPUParticles2D::_particles_process(float p_delta) { continue; } - float local_delta = p_delta; + double local_delta = p_delta; // The phase is a ratio between 0 (birth) and 1 (end of life) for each particle. // While we use time in tests later on, for randomness we use the phase as done in the // original shader code, and we later multiply by lifetime to get the time. - real_t restart_phase = real_t(i) / real_t(pcount); + double restart_phase = double(i) / double(pcount); if (randomness_ratio > 0.0) { uint32_t seed = cycle; @@ -627,12 +627,12 @@ void CPUParticles2D::_particles_process(float p_delta) { } seed *= uint32_t(pcount); seed += uint32_t(i); - real_t random = (idhash(seed) % uint32_t(65536)) / 65536.0; - restart_phase += randomness_ratio * random * 1.0 / pcount; + double random = double(idhash(seed) % uint32_t(65536)) / 65536.0; + restart_phase += randomness_ratio * random * 1.0 / double(pcount); } restart_phase *= (1.0 - explosiveness_ratio); - float restart_time = restart_phase * lifetime; + double restart_time = restart_phase * lifetime; bool restart = false; if (time > prev_time) { @@ -874,7 +874,7 @@ void CPUParticles2D::_particles_process(float p_delta) { tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv); } - real_t hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); + real_t hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); real_t hue_rot_c = Math::cos(hue_rot_angle); real_t hue_rot_s = Math::sin(hue_rot_angle); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 92b8be77cf..1a1f35fca5 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -83,7 +83,7 @@ private: struct Particle { Transform2D transform; Color color; - float custom[4] = {}; + real_t custom[4] = {}; real_t rotation = 0.0; Vector2 velocity; bool active = false; @@ -91,16 +91,16 @@ private: real_t scale_rand = 0.0; real_t hue_rot_rand = 0.0; real_t anim_offset_rand = 0.0; - float time = 0.0; - float lifetime = 0.0; + double time = 0.0; + double lifetime = 0.0; Color base_color; uint32_t seed = 0; }; - float time = 0.0; - float inactive_time = 0.0; - float frame_remainder = 0.0; + double time = 0.0; + double inactive_time = 0.0; + double frame_remainder = 0.0; int cycle = 0; bool redraw = false; @@ -131,12 +131,12 @@ private: bool one_shot = false; - float lifetime = 1.0; - float pre_process_time = 0.0; + double lifetime = 1.0; + double pre_process_time = 0.0; real_t explosiveness_ratio = 0.0; real_t randomness_ratio = 0.0; - real_t lifetime_randomness = 0.0; - real_t speed_scale = 1.0; + double lifetime_randomness = 0.0; + double speed_scale = 1.0; bool local_coords; int fixed_fps = 0; bool fractional_delta = true; @@ -172,7 +172,7 @@ private: Vector2 gravity = Vector2(0, 980); void _update_internal(); - void _particles_process(float p_delta); + void _particles_process(double p_delta); void _update_particle_data_buffer(); Mutex update_mutex; @@ -193,27 +193,27 @@ protected: public: void set_emitting(bool p_emitting); void set_amount(int p_amount); - void set_lifetime(float p_lifetime); + void set_lifetime(double p_lifetime); void set_one_shot(bool p_one_shot); - void set_pre_process_time(float p_time); + void set_pre_process_time(double p_time); void set_explosiveness_ratio(real_t p_ratio); void set_randomness_ratio(real_t p_ratio); - void set_lifetime_randomness(float p_random); + void set_lifetime_randomness(double p_random); void set_visibility_aabb(const Rect2 &p_aabb); void set_use_local_coordinates(bool p_enable); - void set_speed_scale(real_t p_scale); + void set_speed_scale(double p_scale); bool is_emitting() const; int get_amount() const; - float get_lifetime() const; + double get_lifetime() const; bool get_one_shot() const; - float get_pre_process_time() const; + double get_pre_process_time() const; real_t get_explosiveness_ratio() const; real_t get_randomness_ratio() const; - float get_lifetime_randomness() const; + double get_lifetime_randomness() const; Rect2 get_visibility_aabb() const; bool get_use_local_coordinates() const; - real_t get_speed_scale() const; + double get_speed_scale() const; void set_fixed_fps(int p_count); int get_fixed_fps() const; diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index adfb94d574..4739d3dd46 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -54,7 +54,7 @@ void GPUParticles2D::set_amount(int p_amount) { RS::get_singleton()->particles_set_amount(particles, amount); } -void GPUParticles2D::set_lifetime(float p_lifetime) { +void GPUParticles2D::set_lifetime(double p_lifetime) { ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0."); lifetime = p_lifetime; RS::get_singleton()->particles_set_lifetime(particles, lifetime); @@ -76,7 +76,7 @@ void GPUParticles2D::set_one_shot(bool p_enable) { } } -void GPUParticles2D::set_pre_process_time(float p_time) { +void GPUParticles2D::set_pre_process_time(double p_time) { pre_process_time = p_time; RS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time); } @@ -148,7 +148,8 @@ void GPUParticles2D::set_trail_enabled(bool p_enabled) { RS::get_singleton()->particles_set_transform_align(particles, p_enabled ? RS::PARTICLES_TRANSFORM_ALIGN_Y_TO_VELOCITY : RS::PARTICLES_TRANSFORM_ALIGN_DISABLED); } -void GPUParticles2D::set_trail_length(float p_seconds) { + +void GPUParticles2D::set_trail_length(double p_seconds) { ERR_FAIL_COND(p_seconds < 0.001); trail_length = p_seconds; RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length); @@ -162,6 +163,7 @@ void GPUParticles2D::set_trail_sections(int p_sections) { trail_sections = p_sections; update(); } + void GPUParticles2D::set_trail_section_subdivisions(int p_subdivisions) { ERR_FAIL_COND(trail_section_subdivisions < 1); ERR_FAIL_COND(trail_section_subdivisions > 1024); @@ -173,12 +175,13 @@ void GPUParticles2D::set_trail_section_subdivisions(int p_subdivisions) { bool GPUParticles2D::is_trail_enabled() const { return trail_enabled; } -float GPUParticles2D::get_trail_length() const { + +real_t GPUParticles2D::get_trail_length() const { return trail_length; } void GPUParticles2D::_update_collision_size() { - float csize = collision_base_size; + real_t csize = collision_base_size; if (texture.is_valid()) { csize *= (texture->get_width() + texture->get_height()) / 4.0; //half size since its a radius @@ -187,16 +190,16 @@ void GPUParticles2D::_update_collision_size() { RS::get_singleton()->particles_set_collision_base_size(particles, csize); } -void GPUParticles2D::set_collision_base_size(float p_size) { +void GPUParticles2D::set_collision_base_size(real_t p_size) { collision_base_size = p_size; _update_collision_size(); } -float GPUParticles2D::get_collision_base_size() const { +real_t GPUParticles2D::get_collision_base_size() const { return collision_base_size; } -void GPUParticles2D::set_speed_scale(float p_scale) { +void GPUParticles2D::set_speed_scale(double p_scale) { speed_scale = p_scale; RS::get_singleton()->particles_set_speed_scale(particles, p_scale); } @@ -209,7 +212,7 @@ int GPUParticles2D::get_amount() const { return amount; } -float GPUParticles2D::get_lifetime() const { +double GPUParticles2D::get_lifetime() const { return lifetime; } @@ -224,15 +227,15 @@ bool GPUParticles2D::get_one_shot() const { return one_shot; } -float GPUParticles2D::get_pre_process_time() const { +double GPUParticles2D::get_pre_process_time() const { return pre_process_time; } -float GPUParticles2D::get_explosiveness_ratio() const { +real_t GPUParticles2D::get_explosiveness_ratio() const { return explosiveness_ratio; } -float GPUParticles2D::get_randomness_ratio() const { +real_t GPUParticles2D::get_randomness_ratio() const { return randomness_ratio; } @@ -248,7 +251,7 @@ Ref<Material> GPUParticles2D::get_process_material() const { return process_material; } -float GPUParticles2D::get_speed_scale() const { +double GPUParticles2D::get_speed_scale() const { return speed_scale; } diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index 9d8e61daf7..a80e52d60c 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -51,11 +51,11 @@ private: bool one_shot; int amount; - float lifetime; - float pre_process_time; + double lifetime; + double pre_process_time; float explosiveness_ratio; float randomness_ratio; - float speed_scale; + double speed_scale; Rect2 visibility_rect; bool local_coords; int fixed_fps; @@ -89,36 +89,36 @@ protected: public: void set_emitting(bool p_emitting); void set_amount(int p_amount); - void set_lifetime(float p_lifetime); + void set_lifetime(double p_lifetime); void set_one_shot(bool p_enable); - void set_pre_process_time(float p_time); + void set_pre_process_time(double p_time); void set_explosiveness_ratio(float p_ratio); void set_randomness_ratio(float p_ratio); void set_visibility_rect(const Rect2 &p_visibility_rect); void set_use_local_coordinates(bool p_enable); void set_process_material(const Ref<Material> &p_material); - void set_speed_scale(float p_scale); - void set_collision_base_size(float p_ratio); + void set_speed_scale(double p_scale); + void set_collision_base_size(real_t p_ratio); void set_trail_enabled(bool p_enabled); - void set_trail_length(float p_seconds); + void set_trail_length(double p_seconds); void set_trail_sections(int p_sections); void set_trail_section_subdivisions(int p_subdivisions); bool is_emitting() const; int get_amount() const; - float get_lifetime() const; + double get_lifetime() const; bool get_one_shot() const; - float get_pre_process_time() const; - float get_explosiveness_ratio() const; - float get_randomness_ratio() const; + double get_pre_process_time() const; + real_t get_explosiveness_ratio() const; + real_t get_randomness_ratio() const; Rect2 get_visibility_rect() const; bool get_use_local_coordinates() const; Ref<Material> get_process_material() const; - float get_speed_scale() const; + double get_speed_scale() const; - float get_collision_base_size() const; + real_t get_collision_base_size() const; bool is_trail_enabled() const; - float get_trail_length() const; + real_t get_trail_length() const; int get_trail_sections() const; int get_trail_section_subdivisions() const; diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index ea639ae3a3..58b20ccad0 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -455,7 +455,7 @@ void NavigationRegion2D::_notification(int p_what) { // Draw the region Transform2D xform = get_global_transform(); const NavigationServer2D *ns = NavigationServer2D::get_singleton(); - float radius = ns->map_get_edge_connection_margin(get_world_2d()->get_navigation_map()) / 2.0; + real_t radius = ns->map_get_edge_connection_margin(get_world_2d()->get_navigation_map()) / 2.0; for (int i = 0; i < ns->region_get_connections_count(region); i++) { // Two main points Vector2 a = ns->region_get_connection_pathway_start(region, i); @@ -465,7 +465,7 @@ void NavigationRegion2D::_notification(int p_what) { draw_line(a, b, doors_color); // Draw a circle to illustrate the margins. - float angle = (b - a).angle(); + real_t angle = (b - a).angle(); draw_arc(a, radius, angle + Math_PI / 2.0, angle - Math_PI / 2.0 + Math_TAU, 10, doors_color); draw_arc(b, radius, angle - Math_PI / 2.0, angle + Math_PI / 2.0, 10, doors_color); } diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index a382fb2f1e..2d3feb30a1 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -69,7 +69,6 @@ Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_i } motion_cache->result = result; - return motion_cache; } @@ -1046,137 +1045,240 @@ void RigidBody2D::_reload_physics_characteristics() { ////////////////////////// -//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. +// So, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 void CharacterBody2D::move_and_slide() { - Vector2 body_velocity_normal = linear_velocity.normalized(); - bool was_on_floor = on_floor; - - // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky + // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky. float delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time(); - Vector2 current_floor_velocity = floor_velocity; - - if ((on_floor || on_wall) && on_floor_body.is_valid()) { - //this approach makes sure there is less delay between the actual body velocity and the one we saved - PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(on_floor_body); - if (bs) { - current_floor_velocity = bs->get_linear_velocity(); + Vector2 current_platform_velocity = platform_velocity; + + if ((on_floor || on_wall) && platform_rid.is_valid()) { + bool excluded = (exclude_body_layers & platform_layer) != 0; + if (!excluded) { + // This approach makes sure there is less delay between the actual body velocity and the one we saved. + PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(platform_rid); + if (bs) { + Transform2D gt = get_global_transform(); + Vector2 local_position = gt.elements[2] - bs->get_transform().elements[2]; + current_platform_velocity = bs->get_velocity_at_local_position(local_position); + } + } else { + current_platform_velocity = Vector2(); } } motion_results.clear(); + + bool was_on_floor = on_floor; on_floor = false; on_ceiling = false; on_wall = false; - floor_normal = Vector2(); - floor_velocity = Vector2(); - if (current_floor_velocity != Vector2()) { + if (!current_platform_velocity.is_equal_approx(Vector2())) { PhysicsServer2D::MotionResult floor_result; Set<RID> exclude; - exclude.insert(on_floor_body); - if (move_and_collide(current_floor_velocity * delta, infinite_inertia, floor_result, true, false, false, false, exclude)) { + exclude.insert(platform_rid); + if (move_and_collide(current_platform_velocity * delta, infinite_inertia, floor_result, true, false, false, false, exclude)) { motion_results.push_back(floor_result); _set_collision_direction(floor_result); } } - on_floor_body = RID(); Vector2 motion = linear_velocity * delta; + Vector2 motion_slide_up = motion.slide(up_direction); + + Vector2 prev_platform_velocity = current_platform_velocity; + Vector2 prev_floor_normal = floor_normal; + RID prev_platform_rid = platform_rid; + int prev_platform_layer = platform_layer; + + platform_rid = RID(); + floor_normal = Vector2(); + platform_velocity = Vector2(); // No sliding on first attempt to keep floor motion stable when possible, - // when stop on slope is enabled. - bool sliding_enabled = !stop_on_slope; + // When stop on slope is enabled or when there is no up direction. + bool sliding_enabled = !stop_on_slope || up_direction == Vector2(); + // Constant speed can be applied only the first time sliding is enabled. + bool can_apply_constant_speed = sliding_enabled; + bool first_slide = true; + bool vel_dir_facing_up = linear_velocity.dot(up_direction) > 0; + Vector2 last_travel; for (int iteration = 0; iteration < max_slides; ++iteration) { PhysicsServer2D::MotionResult result; bool found_collision = false; + Vector2 prev_position = get_global_transform().elements[2]; + for (int i = 0; i < 2; ++i) { bool collided; - if (i == 0) { //collide + if (i == 0) { // Collide. collided = move_and_collide(motion, infinite_inertia, result, margin, true, false, !sliding_enabled); - if (!collided) { - motion = Vector2(); //clear because no collision happened and motion completed - } - } else { //separate raycasts (if any) + } else { // Separate raycasts (if any). collided = separate_raycast_shapes(result); if (collided) { - result.remainder = motion; //keep + result.remainder = motion; // Keep. result.motion = Vector2(); } } if (collided) { found_collision = true; - motion_results.push_back(result); _set_collision_direction(result); - if (on_floor && stop_on_slope) { - if ((body_velocity_normal + up_direction).length() < 0.01) { - Transform2D gt = get_global_transform(); - if (result.motion.length() > margin) { - gt.elements[2] -= result.motion.slide(up_direction); - } else { + if (on_floor && stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) { + Transform2D gt = get_global_transform(); + if (result.motion.length() > margin) { + gt.elements[2] -= result.motion.slide(up_direction); + } else { + gt.elements[2] -= result.motion; + } + set_global_transform(gt); + linear_velocity = Vector2(); + motion = Vector2(); + break; + } + + if (result.remainder.is_equal_approx(Vector2())) { + motion = Vector2(); + break; + } + + // Move on floor only checks. + if (move_on_floor_only && on_wall && motion_slide_up.dot(result.collision_normal) <= 0) { + // Avoid to move forward on a wall if move_on_floor_only is true. + if (was_on_floor && !is_on_floor_only() && !vel_dir_facing_up) { + // If the movement is large the body can be prevented from reaching the walls. + if (result.motion.length() <= margin) { + // Cancels the motion. + Transform2D gt = get_global_transform(); gt.elements[2] -= result.motion; + set_global_transform(gt); } - set_global_transform(gt); + on_floor = true; + platform_rid = prev_platform_rid; + platform_layer = prev_platform_layer; + + platform_velocity = prev_platform_velocity; + floor_normal = prev_floor_normal; linear_velocity = Vector2(); - return; + motion = Vector2(); + break; + } + // Prevents the body from being able to climb a slope when it moves forward against the wall. + else if (!is_on_floor_only()) { + motion = up_direction * up_direction.dot(result.remainder); + motion = motion.slide(result.collision_normal); + } else { + motion = result.remainder; } } - - if (sliding_enabled || !on_floor) { - motion = result.remainder.slide(result.collision_normal); - linear_velocity = linear_velocity.slide(result.collision_normal); - } else { + // Constant Speed when the slope is upward. + else if (constant_speed_on_floor && is_on_floor_only() && can_apply_constant_speed && was_on_floor && motion.dot(result.collision_normal) < 0) { + can_apply_constant_speed = false; + Vector2 motion_slide_norm = result.remainder.slide(result.collision_normal).normalized(); + if (!motion_slide_norm.is_equal_approx(Vector2())) { + motion = motion_slide_norm * (motion_slide_up.length() - result.motion.slide(up_direction).length() - last_travel.slide(up_direction).length()); + } + } + // Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling. + else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up)) { + Vector2 slide_motion = result.remainder.slide(result.collision_normal); + if (slide_motion.dot(linear_velocity) > 0.0) { + motion = slide_motion; + } else { + motion = Vector2(); + } + if (slide_on_ceiling && on_ceiling) { + // Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall. + if (vel_dir_facing_up) { + linear_velocity = linear_velocity.slide(result.collision_normal); + } else { + // Avoid acceleration in slope when falling. + linear_velocity = up_direction * up_direction.dot(linear_velocity); + } + } + } + // No sliding on first attempt to keep floor motion stable when possible. + else { motion = result.remainder; + if (on_ceiling && !slide_on_ceiling && vel_dir_facing_up) { + linear_velocity = linear_velocity.slide(up_direction); + motion = motion.slide(up_direction); + } } - } - sliding_enabled = true; + last_travel = result.motion; + } + // When you move forward in a downward slope you don’t collide because you will be in the air. + // This test ensures that constant speed is applied, only if the player is still on the ground after the snap is applied. + else if (i == 0 && constant_speed_on_floor && first_slide && _on_floor_if_snapped(was_on_floor, vel_dir_facing_up)) { + can_apply_constant_speed = false; + sliding_enabled = true; + Transform2D gt = get_global_transform(); + gt.elements[2] = prev_position; + set_global_transform(gt); + + Vector2 motion_slide_norm = motion.slide(prev_floor_normal).normalized(); + if (!motion_slide_norm.is_equal_approx(Vector2())) { + motion = motion_slide_norm * (motion_slide_up.length()); + found_collision = true; + } + } } + can_apply_constant_speed = !can_apply_constant_speed && !sliding_enabled; + sliding_enabled = true; + first_slide = false; - if (!found_collision || motion == Vector2()) { + if (!found_collision || motion.is_equal_approx(Vector2())) { break; } } + _snap_on_floor(was_on_floor, vel_dir_facing_up); + if (!on_floor && !on_wall) { // Add last platform velocity when just left a moving platform. - linear_velocity += current_floor_velocity; + linear_velocity += current_platform_velocity; } - if (!was_on_floor || snap == Vector2()) { + // Reset the gravity accumulation when touching the ground. + if (on_floor && !vel_dir_facing_up) { + linear_velocity = linear_velocity.slide(up_direction); + } +} + +void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up) { + if (Math::is_equal_approx(floor_snap_length, 0) || up_direction == Vector2() || on_floor || !was_on_floor || vel_dir_facing_up) { return; } - // Apply snap. Transform2D gt = get_global_transform(); PhysicsServer2D::MotionResult result; - if (move_and_collide(snap, infinite_inertia, result, margin, false, true, false)) { + if (move_and_collide(up_direction * -floor_snap_length, infinite_inertia, result, margin, false, true, false)) { bool apply = true; - if (up_direction != Vector2()) { - if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { - on_floor = true; - floor_normal = result.collision_normal; - on_floor_body = result.collider; - floor_velocity = result.collider_velocity; - if (stop_on_slope) { - // move and collide may stray the object a bit because of pre un-stucking, - // so only ensure that motion happens on floor direction in this case. - if (result.motion.length() > margin) { - result.motion = up_direction * up_direction.dot(result.motion); - } else { - result.motion = Vector2(); - } + float collision_angle = Math::acos(result.collision_normal.dot(up_direction)); + if (collision_angle <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { + on_floor = true; + floor_normal = result.collision_normal; + platform_velocity = result.collider_velocity; + _set_platform_data(result); + + if (stop_on_slope) { + // move and collide may stray the object a bit because of pre un-stucking, + // so only ensure that motion happens on floor direction in this case. + if (result.motion.length() > margin) { + result.motion = up_direction * up_direction.dot(result.motion); + } else { + result.motion = Vector2(); } - } else { - apply = false; } + } else { + apply = false; } if (apply) { @@ -1186,23 +1288,46 @@ void CharacterBody2D::move_and_slide() { } } +bool CharacterBody2D::_on_floor_if_snapped(bool was_on_floor, bool vel_dir_facing_up) { + if (Math::is_equal_approx(floor_snap_length, 0) || up_direction == Vector2() || on_floor || !was_on_floor || vel_dir_facing_up) { + return false; + } + + PhysicsServer2D::MotionResult result; + if (move_and_collide(up_direction * -floor_snap_length, infinite_inertia, result, margin, false, true, false)) { + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { + return true; + } + } + + return false; +} + void CharacterBody2D::_set_collision_direction(const PhysicsServer2D::MotionResult &p_result) { if (up_direction == Vector2()) { - //all is a wall - on_wall = true; + return; + } + + if (Math::acos(p_result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor + on_floor = true; + floor_normal = p_result.collision_normal; + platform_velocity = p_result.collider_velocity; + _set_platform_data(p_result); + } else if (Math::acos(p_result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling + on_ceiling = true; } else { - if (Math::acos(p_result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor - on_floor = true; - floor_normal = p_result.collision_normal; - on_floor_body = p_result.collider; - floor_velocity = p_result.collider_velocity; - } else if (Math::acos(p_result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling - on_ceiling = true; - } else { - on_wall = true; - on_floor_body = p_result.collider; - floor_velocity = p_result.collider_velocity; - } + on_wall = true; + platform_velocity = p_result.collider_velocity; + _set_platform_data(p_result); + } +} + +void CharacterBody2D::_set_platform_data(const PhysicsServer2D::MotionResult &p_result) { + platform_rid = p_result.collider; + platform_layer = 0; + CollisionObject2D *collision_object = Object::cast_to<CollisionObject2D>(ObjectDB::get_instance(p_result.collider_id)); + if (collision_object) { + platform_layer = collision_object->get_collision_layer(); } } @@ -1254,20 +1379,32 @@ bool CharacterBody2D::is_on_floor() const { return on_floor; } +bool CharacterBody2D::is_on_floor_only() const { + return on_floor && !on_wall && !on_ceiling; +} + bool CharacterBody2D::is_on_wall() const { return on_wall; } +bool CharacterBody2D::is_on_wall_only() const { + return on_wall && !on_floor && !on_ceiling; +} + bool CharacterBody2D::is_on_ceiling() const { return on_ceiling; } +bool CharacterBody2D::is_on_ceiling_only() const { + return on_ceiling && !on_floor && !on_wall; +} + Vector2 CharacterBody2D::get_floor_normal() const { return floor_normal; } -Vector2 CharacterBody2D::get_floor_velocity() const { - return floor_velocity; +Vector2 CharacterBody2D::get_platform_velocity() const { + return platform_velocity; } int CharacterBody2D::get_slide_count() const { @@ -1317,6 +1454,35 @@ void CharacterBody2D::set_infinite_inertia_enabled(bool p_enabled) { infinite_inertia = p_enabled; } +bool CharacterBody2D::is_constant_speed_on_floor_enabled() const { + return constant_speed_on_floor; +} +void CharacterBody2D::set_constant_speed_on_floor_enabled(bool p_enabled) { + constant_speed_on_floor = p_enabled; +} + +bool CharacterBody2D::is_move_on_floor_only_enabled() const { + return move_on_floor_only; +} +void CharacterBody2D::set_move_on_floor_only_enabled(bool p_enabled) { + move_on_floor_only = p_enabled; +} + +bool CharacterBody2D::is_slide_on_ceiling_enabled() const { + return slide_on_ceiling; +} +void CharacterBody2D::set_slide_on_ceiling_enabled(bool p_enabled) { + slide_on_ceiling = p_enabled; +} + +uint32_t CharacterBody2D::get_exclude_body_layers() const { + return exclude_body_layers; +} + +void CharacterBody2D::set_exclude_body_layers(uint32_t p_exclude_layers) { + exclude_body_layers = p_exclude_layers; +} + int CharacterBody2D::get_max_slides() const { return max_slides; } @@ -1334,12 +1500,13 @@ void CharacterBody2D::set_floor_max_angle(real_t p_radians) { floor_max_angle = p_radians; } -const Vector2 &CharacterBody2D::get_snap() const { - return snap; +real_t CharacterBody2D::get_floor_snap_length() { + return floor_snap_length; } -void CharacterBody2D::set_snap(const Vector2 &p_snap) { - snap = p_snap; +void CharacterBody2D::set_floor_snap_length(real_t p_floor_snap_length) { + ERR_FAIL_COND(p_floor_snap_length < 0); + floor_snap_length = p_floor_snap_length; } const Vector2 &CharacterBody2D::get_up_direction() const { @@ -1355,11 +1522,11 @@ void CharacterBody2D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { // Reset move_and_slide() data. on_floor = false; - on_floor_body = RID(); + platform_rid = RID(); on_ceiling = false; on_wall = false; motion_results.clear(); - floor_velocity = Vector2(); + platform_velocity = Vector2(); } break; } } @@ -1375,31 +1542,48 @@ void CharacterBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_stop_on_slope_enabled"), &CharacterBody2D::is_stop_on_slope_enabled); ClassDB::bind_method(D_METHOD("set_stop_on_slope_enabled", "enabled"), &CharacterBody2D::set_stop_on_slope_enabled); ClassDB::bind_method(D_METHOD("is_infinite_inertia_enabled"), &CharacterBody2D::is_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("set_constant_speed_on_floor_enabled", "enabled"), &CharacterBody2D::set_constant_speed_on_floor_enabled); + ClassDB::bind_method(D_METHOD("is_constant_speed_on_floor_enabled"), &CharacterBody2D::is_constant_speed_on_floor_enabled); + ClassDB::bind_method(D_METHOD("set_move_on_floor_only_enabled", "enabled"), &CharacterBody2D::set_move_on_floor_only_enabled); + ClassDB::bind_method(D_METHOD("is_move_on_floor_only_enabled"), &CharacterBody2D::is_move_on_floor_only_enabled); + ClassDB::bind_method(D_METHOD("set_slide_on_ceiling_enabled", "enabled"), &CharacterBody2D::set_slide_on_ceiling_enabled); + ClassDB::bind_method(D_METHOD("is_slide_on_ceiling_enabled"), &CharacterBody2D::is_slide_on_ceiling_enabled); + + ClassDB::bind_method(D_METHOD("set_exclude_body_layers", "exclude_layer"), &CharacterBody2D::set_exclude_body_layers); + ClassDB::bind_method(D_METHOD("get_exclude_body_layers"), &CharacterBody2D::get_exclude_body_layers); + ClassDB::bind_method(D_METHOD("set_infinite_inertia_enabled", "enabled"), &CharacterBody2D::set_infinite_inertia_enabled); ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody2D::get_max_slides); ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody2D::set_max_slides); ClassDB::bind_method(D_METHOD("get_floor_max_angle"), &CharacterBody2D::get_floor_max_angle); ClassDB::bind_method(D_METHOD("set_floor_max_angle", "radians"), &CharacterBody2D::set_floor_max_angle); - ClassDB::bind_method(D_METHOD("get_snap"), &CharacterBody2D::get_snap); - ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CharacterBody2D::set_snap); + ClassDB::bind_method(D_METHOD("get_floor_snap_length"), &CharacterBody2D::get_floor_snap_length); + ClassDB::bind_method(D_METHOD("set_floor_snap_length", "floor_snap_length"), &CharacterBody2D::set_floor_snap_length); ClassDB::bind_method(D_METHOD("get_up_direction"), &CharacterBody2D::get_up_direction); ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody2D::set_up_direction); ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody2D::is_on_floor); + ClassDB::bind_method(D_METHOD("is_on_floor_only"), &CharacterBody2D::is_on_floor_only); ClassDB::bind_method(D_METHOD("is_on_ceiling"), &CharacterBody2D::is_on_ceiling); + ClassDB::bind_method(D_METHOD("is_on_ceiling_only"), &CharacterBody2D::is_on_ceiling_only); ClassDB::bind_method(D_METHOD("is_on_wall"), &CharacterBody2D::is_on_wall); + ClassDB::bind_method(D_METHOD("is_on_wall_only"), &CharacterBody2D::is_on_wall_only); ClassDB::bind_method(D_METHOD("get_floor_normal"), &CharacterBody2D::get_floor_normal); - ClassDB::bind_method(D_METHOD("get_floor_velocity"), &CharacterBody2D::get_floor_velocity); + ClassDB::bind_method(D_METHOD("get_platform_velocity"), &CharacterBody2D::get_platform_velocity); ClassDB::bind_method(D_METHOD("get_slide_count"), &CharacterBody2D::get_slide_count); ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &CharacterBody2D::_get_slide_collision); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stop_on_slope"), "set_stop_on_slope_enabled", "is_stop_on_slope_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "infinite_inertia"), "set_infinite_inertia_enabled", "is_infinite_inertia_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "constant_speed_on_floor"), "set_constant_speed_on_floor_enabled", "is_constant_speed_on_floor_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "move_on_floor_only"), "set_move_on_floor_only_enabled", "is_move_on_floor_only_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_RANGE, "1,8,1,or_greater"), "set_max_slides", "get_max_slides"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_floor_max_angle", "get_floor_max_angle"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "snap"), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_snap_length", PROPERTY_HINT_RANGE, "0,1000,0.1"), "set_floor_snap_length", "get_floor_snap_length"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "exclude_body_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_exclude_body_layers", "get_exclude_body_layers"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 7a319aabc9..00948b4344 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -273,16 +273,20 @@ private: bool stop_on_slope = false; bool infinite_inertia = true; + bool constant_speed_on_floor = false; + bool move_on_floor_only = true; + bool slide_on_ceiling = true; int max_slides = 4; + int platform_layer; real_t floor_max_angle = Math::deg2rad((real_t)45.0); - Vector2 snap; + float floor_snap_length = 0; Vector2 up_direction = Vector2(0.0, -1.0); - + uint32_t exclude_body_layers = 0; Vector2 linear_velocity; Vector2 floor_normal; - Vector2 floor_velocity; - RID on_floor_body; + Vector2 platform_velocity; + RID platform_rid; bool on_floor = false; bool on_ceiling = false; bool on_wall = false; @@ -290,8 +294,6 @@ private: Vector<PhysicsServer2D::MotionResult> motion_results; Vector<Ref<KinematicCollision2D>> slide_colliders; - Ref<KinematicCollision2D> _get_slide_collision(int p_bounce); - bool separate_raycast_shapes(PhysicsServer2D::MotionResult &r_result); void set_safe_margin(real_t p_margin); @@ -303,18 +305,37 @@ private: bool is_infinite_inertia_enabled() const; void set_infinite_inertia_enabled(bool p_enabled); + bool is_constant_speed_on_floor_enabled() const; + void set_constant_speed_on_floor_enabled(bool p_enabled); + + bool is_move_on_floor_only_enabled() const; + void set_move_on_floor_only_enabled(bool p_enabled); + + bool is_slide_on_ceiling_enabled() const; + void set_slide_on_ceiling_enabled(bool p_enabled); + int get_max_slides() const; void set_max_slides(int p_max_slides); + real_t get_move_max_angle() const; + void set_move_max_angle(real_t p_radians); + real_t get_floor_max_angle() const; void set_floor_max_angle(real_t p_radians); - const Vector2 &get_snap() const; - void set_snap(const Vector2 &p_snap); + real_t get_floor_snap_length(); + void set_floor_snap_length(real_t p_floor_snap_length); + uint32_t get_exclude_body_layers() const; + void set_exclude_body_layers(const uint32_t p_exclude_layer); + + Ref<KinematicCollision2D> _get_slide_collision(int p_bounce); const Vector2 &get_up_direction() const; + bool _on_floor_if_snapped(bool was_on_floor, bool vel_dir_facing_up); void set_up_direction(const Vector2 &p_up_direction); void _set_collision_direction(const PhysicsServer2D::MotionResult &p_result); + void _set_platform_data(const PhysicsServer2D::MotionResult &p_result); + void _snap_on_floor(bool was_on_floor, bool vel_dir_facing_up); protected: void _notification(int p_what); @@ -327,10 +348,13 @@ public: void set_linear_velocity(const Vector2 &p_velocity); bool is_on_floor() const; + bool is_on_floor_only() const; bool is_on_wall() const; + bool is_on_wall_only() const; bool is_on_ceiling() const; + bool is_on_ceiling_only() const; Vector2 get_floor_normal() const; - Vector2 get_floor_velocity() const; + Vector2 get_platform_velocity() const; int get_slide_count() const; PhysicsServer2D::MotionResult get_slide_collision(int p_bounce) const; diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index f6740040c1..602a0f2115 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -212,17 +212,17 @@ void RayCast2D::_update_raycast_state() { void RayCast2D::_draw_debug_shape() { Color draw_col = collided ? Color(1.0, 0.01, 0) : get_tree()->get_debug_collisions_color(); if (!enabled) { - float g = draw_col.get_v(); + const float g = draw_col.get_v(); draw_col.r = g; draw_col.g = g; draw_col.b = g; } // Draw an arrow indicating where the RayCast is pointing to - const float max_arrow_size = 6; - const float line_width = 1.4; + const real_t max_arrow_size = 6; + const real_t line_width = 1.4; bool no_line = target_position.length() < line_width; - float arrow_size = CLAMP(target_position.length() * 2 / 3, line_width, max_arrow_size); + real_t arrow_size = CLAMP(target_position.length() * 2 / 3, line_width, max_arrow_size); if (no_line) { arrow_size = target_position.length(); diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 15cbdf535e..85d632af00 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -45,7 +45,7 @@ bool Bone2D::_set(const StringName &p_path, const Variant &p_value) { } else if (path.begins_with("length")) { set_length(p_value); } else if (path.begins_with("bone_angle")) { - set_bone_angle(Math::deg2rad(float(p_value))); + set_bone_angle(Math::deg2rad(real_t(p_value))); } else if (path.begins_with("default_length")) { set_length(p_value); } @@ -330,7 +330,7 @@ bool Bone2D::_editor_get_bone_shape(Vector<Vector2> *p_shape, Vector<Vector2> *p rel = (p_other_bone->get_global_transform().get_origin() - get_global_transform().get_origin()); rel = rel.rotated(-get_global_rotation()); // Undo Bone2D node's rotation so its drawn correctly regardless of the node's rotation } else { - float angle_to_use = get_rotation() + bone_angle; + real_t angle_to_use = get_rotation() + bone_angle; rel = Vector2(cos(angle_to_use), sin(angle_to_use)) * (length * MIN(get_global_scale().x, get_global_scale().y)); rel = rel.rotated(-get_rotation()); // Undo Bone2D node's rotation so its drawn correctly regardless of the node's rotation } @@ -414,12 +414,12 @@ void Bone2D::apply_rest() { set_transform(rest); } -void Bone2D::set_default_length(float p_length) { +void Bone2D::set_default_length(real_t p_length) { WARN_DEPRECATED_MSG("set_default_length is deprecated. Please use set_length instead!"); set_length(p_length); } -float Bone2D::get_default_length() const { +real_t Bone2D::get_default_length() const { WARN_DEPRECATED_MSG("get_default_length is deprecated. Please use get_length instead!"); return get_length(); } @@ -485,7 +485,7 @@ bool Bone2D::get_autocalculate_length_and_angle() const { return autocalculate_length_and_angle; } -void Bone2D::set_length(float p_length) { +void Bone2D::set_length(real_t p_length) { length = p_length; #ifdef TOOLS_ENABLED @@ -493,11 +493,11 @@ void Bone2D::set_length(float p_length) { #endif // TOOLS_ENABLED } -float Bone2D::get_length() const { +real_t Bone2D::get_length() const { return length; } -void Bone2D::set_bone_angle(float p_angle) { +void Bone2D::set_bone_angle(real_t p_angle) { bone_angle = p_angle; #ifdef TOOLS_ENABLED @@ -505,7 +505,7 @@ void Bone2D::set_bone_angle(float p_angle) { #endif // TOOLS_ENABLED } -float Bone2D::get_bone_angle() const { +real_t Bone2D::get_bone_angle() const { return bone_angle; } @@ -690,7 +690,7 @@ RID Skeleton2D::get_skeleton() const { return skeleton; } -void Skeleton2D::set_bone_local_pose_override(int p_bone_idx, Transform2D p_override, float p_amount, bool p_persistent) { +void Skeleton2D::set_bone_local_pose_override(int p_bone_idx, Transform2D p_override, real_t p_amount, bool p_persistent) { ERR_FAIL_INDEX_MSG(p_bone_idx, bones.size(), "Bone index is out of range!"); bones.write[p_bone_idx].local_pose_override = p_override; bones.write[p_bone_idx].local_pose_override_amount = p_amount; @@ -728,7 +728,7 @@ Ref<SkeletonModificationStack2D> Skeleton2D::get_modification_stack() const { return modification_stack; } -void Skeleton2D::execute_modifications(float p_delta, int p_execution_mode) { +void Skeleton2D::execute_modifications(real_t p_delta, int p_execution_mode) { if (!modification_stack.is_valid()) { return; } diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index 59bd711960..56fd0e8504 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -49,8 +49,8 @@ class Bone2D : public Node2D { Transform2D rest; bool autocalculate_length_and_angle = true; - float length = 16; - float bone_angle = 0; + real_t length = 16; + real_t bone_angle = 0; int skeleton_index = -1; @@ -85,10 +85,10 @@ public: void set_autocalculate_length_and_angle(bool p_autocalculate); bool get_autocalculate_length_and_angle() const; - void set_length(float p_length); - float get_length() const; - void set_bone_angle(float p_angle); - float get_bone_angle() const; + void set_length(real_t p_length); + real_t get_length() const; + void set_bone_angle(real_t p_angle); + real_t get_bone_angle() const; int get_index_in_skeleton() const; @@ -122,7 +122,7 @@ class Skeleton2D : public Node2D { //Transform2D local_pose_cache; Transform2D local_pose_override; - float local_pose_override_amount = 0; + real_t local_pose_override_amount = 0; bool local_pose_override_persistent = false; }; @@ -153,12 +153,12 @@ public: RID get_skeleton() const; - void set_bone_local_pose_override(int p_bone_idx, Transform2D p_override, float p_amount, bool p_persistent = true); + void set_bone_local_pose_override(int p_bone_idx, Transform2D p_override, real_t p_amount, bool p_persistent = true); Transform2D get_bone_local_pose_override(int p_bone_idx); Ref<SkeletonModificationStack2D> get_modification_stack() const; void set_modification_stack(Ref<SkeletonModificationStack2D> p_stack); - void execute_modifications(float p_delta, int p_execution_mode); + void execute_modifications(real_t p_delta, int p_execution_mode); Skeleton2D(); ~Skeleton2D(); |