diff options
Diffstat (limited to 'scene')
84 files changed, 2256 insertions, 1507 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(); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index bb8f9f8ccb..6318aad08e 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -407,14 +407,14 @@ void AudioStreamPlayer3D::_notification(int p_what) { for (const Set<Camera3D *>::Element *E = world_3d->get_cameras().front(); E; E = E->next()) { Camera3D *camera = E->get(); Viewport *vp = camera->get_viewport(); - if (!vp->is_audio_listener()) { + if (!vp->is_audio_listener_3d()) { continue; } bool listener_is_camera = true; Node3D *listener_node = camera; - Listener3D *listener = vp->get_listener(); + Listener3D *listener = vp->get_listener_3d(); if (listener) { listener_node = listener; listener_is_camera = false; diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 2e962b96c3..e504277a55 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -153,7 +153,7 @@ Transform3D Camera3D::get_camera_transform() const { return tr; } -void Camera3D::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) { +void Camera3D::set_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far) { if (!force_change && fov == p_fovy_degrees && p_z_near == near && p_z_far == far && mode == PROJECTION_PERSPECTIVE) { return; } @@ -168,7 +168,7 @@ void Camera3D::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_f force_change = false; } -void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) { +void Camera3D::set_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far) { if (!force_change && size == p_size && p_z_near == near && p_z_far == far && mode == PROJECTION_ORTHOGONAL) { return; } @@ -184,7 +184,7 @@ void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) { update_gizmos(); } -void Camera3D::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float p_z_far) { +void Camera3D::set_frustum(real_t p_size, Vector2 p_offset, real_t p_z_near, real_t p_z_far) { if (!force_change && size == p_size && frustum_offset == p_offset && p_z_near == near && p_z_far == far && mode == PROJECTION_FRUSTUM) { return; } @@ -295,7 +295,7 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const { return get_camera_transform().origin; } else { Vector2 pos = cpos / viewport_size; - float vsize, hsize; + real_t vsize, hsize; if (keep_aspect == KEEP_WIDTH) { vsize = size / viewport_size.aspect(); hsize = size; @@ -368,7 +368,7 @@ Point2 Camera3D::unproject_position(const Vector3 &p_pos) const { return res; } -Vector3 Camera3D::project_position(const Point2 &p_point, float p_z_depth) const { +Vector3 Camera3D::project_position(const Point2 &p_point, real_t p_z_depth) const { ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene."); if (p_z_depth == 0 && mode != PROJECTION_ORTHOGONAL) { @@ -531,15 +531,15 @@ void Camera3D::_bind_methods() { BIND_ENUM_CONSTANT(DOPPLER_TRACKING_PHYSICS_STEP); } -float Camera3D::get_fov() const { +real_t Camera3D::get_fov() const { return fov; } -float Camera3D::get_size() const { +real_t Camera3D::get_size() const { return size; } -float Camera3D::get_near() const { +real_t Camera3D::get_near() const { return near; } @@ -547,7 +547,7 @@ Vector2 Camera3D::get_frustum_offset() const { return frustum_offset; } -float Camera3D::get_far() const { +real_t Camera3D::get_far() const { return far; } @@ -555,19 +555,19 @@ Camera3D::Projection Camera3D::get_projection() const { return mode; } -void Camera3D::set_fov(float p_fov) { +void Camera3D::set_fov(real_t p_fov) { ERR_FAIL_COND(p_fov < 1 || p_fov > 179); fov = p_fov; _update_camera_mode(); } -void Camera3D::set_size(float p_size) { +void Camera3D::set_size(real_t p_size) { ERR_FAIL_COND(p_size < 0.1 || p_size > 16384); size = p_size; _update_camera_mode(); } -void Camera3D::set_near(float p_near) { +void Camera3D::set_near(real_t p_near) { near = p_near; _update_camera_mode(); } @@ -577,7 +577,7 @@ void Camera3D::set_frustum_offset(Vector2 p_offset) { _update_camera_mode(); } -void Camera3D::set_far(float p_far) { +void Camera3D::set_far(real_t p_far) { far = p_far; _update_camera_mode(); } @@ -630,21 +630,21 @@ bool Camera3D::is_position_in_frustum(const Vector3 &p_position) const { return true; } -void Camera3D::set_v_offset(float p_offset) { +void Camera3D::set_v_offset(real_t p_offset) { v_offset = p_offset; _update_camera(); } -float Camera3D::get_v_offset() const { +real_t Camera3D::get_v_offset() const { return v_offset; } -void Camera3D::set_h_offset(float p_offset) { +void Camera3D::set_h_offset(real_t p_offset) { h_offset = p_offset; _update_camera(); } -float Camera3D::get_h_offset() const { +real_t Camera3D::get_h_offset() const { return h_offset; } @@ -672,11 +672,11 @@ Camera3D::~Camera3D() { //////////////////////////////////////// -void ClippedCamera3D::set_margin(float p_margin) { +void ClippedCamera3D::set_margin(real_t p_margin) { margin = p_margin; } -float ClippedCamera3D::get_margin() const { +real_t ClippedCamera3D::get_margin() const { return margin; } @@ -746,7 +746,7 @@ void ClippedCamera3D::_notification(int p_what) { xf.origin = ray_from; xf.orthonormalize(); - float closest_safe = 1.0f, closest_unsafe = 1.0f; + real_t closest_safe = 1.0f, closest_unsafe = 1.0f; if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, closest_safe, closest_unsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) { clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from) * closest_safe); } @@ -813,7 +813,7 @@ void ClippedCamera3D::clear_exceptions() { exclude.clear(); } -float ClippedCamera3D::get_clip_offset() const { +real_t ClippedCamera3D::get_clip_offset() const { return clip_offset; } diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index c6efc8f9a9..61e3f51d0b 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -63,13 +63,13 @@ private: Projection mode = PROJECTION_PERSPECTIVE; - float fov = 0.0; - float size = 1.0; + real_t fov = 0.0; + real_t size = 1.0; Vector2 frustum_offset; - float near = 0.0; - float far = 0.0; - float v_offset = 0.0; - float h_offset = 0.0; + real_t near = 0.0; + real_t far = 0.0; + real_t v_offset = 0.0; + real_t h_offset = 0.0; KeepAspect keep_aspect = KEEP_HEIGHT; RID camera; @@ -107,10 +107,9 @@ public: NOTIFICATION_LOST_CURRENT = 51 }; - void set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far); - void set_orthogonal(float p_size, float p_z_near, float p_z_far); - void set_frustum(float p_size, Vector2 p_offset, float p_z_near, - float p_z_far); + void set_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far); + void set_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far); + void set_frustum(real_t p_size, Vector2 p_offset, real_t p_z_near, real_t p_z_far); void set_projection(Camera3D::Projection p_mode); void make_current(); @@ -120,18 +119,18 @@ public: RID get_camera() const; - float get_fov() const; - float get_size() const; - float get_far() const; - float get_near() const; + real_t get_fov() const; + real_t get_size() const; + real_t get_far() const; + real_t get_near() const; Vector2 get_frustum_offset() const; Projection get_projection() const; - void set_fov(float p_fov); - void set_size(float p_size); - void set_far(float p_far); - void set_near(float p_near); + void set_fov(real_t p_fov); + void set_size(real_t p_size); + void set_far(real_t p_far); + void set_near(real_t p_near); void set_frustum_offset(Vector2 p_offset); virtual Transform3D get_camera_transform() const; @@ -141,8 +140,7 @@ public: virtual Vector3 project_local_ray_normal(const Point2 &p_pos) const; virtual Point2 unproject_position(const Vector3 &p_pos) const; bool is_position_behind(const Vector3 &p_pos) const; - virtual Vector3 project_position(const Point2 &p_point, - float p_z_depth) const; + virtual Vector3 project_position(const Point2 &p_point, real_t p_z_depth) const; Vector<Vector3> get_near_plane_points() const; @@ -164,11 +162,11 @@ public: void set_keep_aspect_mode(KeepAspect p_aspect); KeepAspect get_keep_aspect_mode() const; - void set_v_offset(float p_offset); - float get_v_offset() const; + void set_v_offset(real_t p_offset); + real_t get_v_offset() const; - void set_h_offset(float p_offset); - float get_h_offset() const; + void set_h_offset(real_t p_offset); + real_t get_h_offset() const; void set_doppler_tracking(DopplerTracking p_tracking); DopplerTracking get_doppler_tracking() const; @@ -195,8 +193,8 @@ public: private: ClipProcessCallback process_callback = CLIP_PROCESS_PHYSICS; RID pyramid_shape; - float margin = 0.0; - float clip_offset = 0.0; + real_t margin = 0.0; + real_t clip_offset = 0.0; uint32_t collision_mask = 1; bool clip_to_areas = false; bool clip_to_bodies = true; @@ -217,8 +215,8 @@ public: void set_clip_to_bodies(bool p_clip); bool is_clip_to_bodies_enabled() const; - void set_margin(float p_margin); - float get_margin() const; + void set_margin(real_t p_margin); + real_t get_margin() const; void set_process_callback(ClipProcessCallback p_mode); ClipProcessCallback get_process_callback() const; @@ -235,7 +233,7 @@ public: void remove_exception(const Object *p_object); void clear_exceptions(); - float get_clip_offset() const; + real_t get_clip_offset() const; ClippedCamera3D(); ~ClippedCamera3D(); diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 60f8ad8f36..2377c618aa 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -78,7 +78,7 @@ void CPUParticles3D::set_amount(int p_amount) { particle_order.resize(p_amount); } -void CPUParticles3D::set_lifetime(float p_lifetime) { +void CPUParticles3D::set_lifetime(double p_lifetime) { ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0."); lifetime = p_lifetime; } @@ -87,19 +87,19 @@ void CPUParticles3D::set_one_shot(bool p_one_shot) { one_shot = p_one_shot; } -void CPUParticles3D::set_pre_process_time(float p_time) { +void CPUParticles3D::set_pre_process_time(double p_time) { pre_process_time = p_time; } -void CPUParticles3D::set_explosiveness_ratio(float p_ratio) { +void CPUParticles3D::set_explosiveness_ratio(real_t p_ratio) { explosiveness_ratio = p_ratio; } -void CPUParticles3D::set_randomness_ratio(float p_ratio) { +void CPUParticles3D::set_randomness_ratio(real_t p_ratio) { randomness_ratio = p_ratio; } -void CPUParticles3D::set_lifetime_randomness(float p_random) { +void CPUParticles3D::set_lifetime_randomness(double p_random) { lifetime_randomness = p_random; } @@ -107,7 +107,7 @@ void CPUParticles3D::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; } -void CPUParticles3D::set_speed_scale(float p_scale) { +void CPUParticles3D::set_speed_scale(double p_scale) { speed_scale = p_scale; } @@ -119,7 +119,7 @@ int CPUParticles3D::get_amount() const { return particles.size(); } -float CPUParticles3D::get_lifetime() const { +double CPUParticles3D::get_lifetime() const { return lifetime; } @@ -127,19 +127,19 @@ bool CPUParticles3D::get_one_shot() const { return one_shot; } -float CPUParticles3D::get_pre_process_time() const { +double CPUParticles3D::get_pre_process_time() const { return pre_process_time; } -float CPUParticles3D::get_explosiveness_ratio() const { +real_t CPUParticles3D::get_explosiveness_ratio() const { return explosiveness_ratio; } -float CPUParticles3D::get_randomness_ratio() const { +real_t CPUParticles3D::get_randomness_ratio() const { return randomness_ratio; } -float CPUParticles3D::get_lifetime_randomness() const { +double CPUParticles3D::get_lifetime_randomness() const { return lifetime_randomness; } @@ -147,7 +147,7 @@ bool CPUParticles3D::get_use_local_coordinates() const { return local_coords; } -float CPUParticles3D::get_speed_scale() const { +double CPUParticles3D::get_speed_scale() const { return speed_scale; } @@ -247,47 +247,47 @@ Vector3 CPUParticles3D::get_direction() const { return direction; } -void CPUParticles3D::set_spread(float p_spread) { +void CPUParticles3D::set_spread(real_t p_spread) { spread = p_spread; } -float CPUParticles3D::get_spread() const { +real_t CPUParticles3D::get_spread() const { return spread; } -void CPUParticles3D::set_flatness(float p_flatness) { +void CPUParticles3D::set_flatness(real_t p_flatness) { flatness = p_flatness; } -float CPUParticles3D::get_flatness() const { +real_t CPUParticles3D::get_flatness() const { return flatness; } -void CPUParticles3D::set_param(Parameter p_param, float p_value) { +void CPUParticles3D::set_param(Parameter p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); parameters[p_param] = p_value; } -float CPUParticles3D::get_param(Parameter p_param) const { +real_t CPUParticles3D::get_param(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return parameters[p_param]; } -void CPUParticles3D::set_param_randomness(Parameter p_param, float p_value) { +void CPUParticles3D::set_param_randomness(Parameter p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); randomness[p_param] = p_value; } -float CPUParticles3D::get_param_randomness(Parameter p_param) const { +real_t CPUParticles3D::get_param_randomness(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return randomness[p_param]; } -static void _adjust_curve_range(const Ref<Curve> &p_curve, float p_min, float p_max) { +static void _adjust_curve_range(const Ref<Curve> &p_curve, real_t p_min, real_t p_max) { Ref<Curve> curve = p_curve; if (!curve.is_valid()) { return; @@ -381,7 +381,7 @@ void CPUParticles3D::set_emission_shape(EmissionShape p_shape) { emission_shape = p_shape; } -void CPUParticles3D::set_emission_sphere_radius(float p_radius) { +void CPUParticles3D::set_emission_sphere_radius(real_t p_radius) { emission_sphere_radius = p_radius; } @@ -405,19 +405,19 @@ void CPUParticles3D::set_emission_ring_axis(Vector3 p_axis) { emission_ring_axis = p_axis; } -void CPUParticles3D::set_emission_ring_height(float p_height) { +void CPUParticles3D::set_emission_ring_height(real_t p_height) { emission_ring_height = p_height; } -void CPUParticles3D::set_emission_ring_radius(float p_radius) { +void CPUParticles3D::set_emission_ring_radius(real_t p_radius) { emission_ring_radius = p_radius; } -void CPUParticles3D::set_emission_ring_inner_radius(float p_radius) { +void CPUParticles3D::set_emission_ring_inner_radius(real_t p_radius) { emission_ring_inner_radius = p_radius; } -float CPUParticles3D::get_emission_sphere_radius() const { +real_t CPUParticles3D::get_emission_sphere_radius() const { return emission_sphere_radius; } @@ -441,15 +441,15 @@ Vector3 CPUParticles3D::get_emission_ring_axis() const { return emission_ring_axis; } -float CPUParticles3D::get_emission_ring_height() const { +real_t CPUParticles3D::get_emission_ring_height() const { return emission_ring_height; } -float CPUParticles3D::get_emission_ring_radius() const { +real_t CPUParticles3D::get_emission_ring_radius() const { return emission_ring_radius; } -float CPUParticles3D::get_emission_ring_inner_radius() const { +real_t CPUParticles3D::get_emission_ring_inner_radius() const { return emission_ring_inner_radius; } @@ -498,7 +498,7 @@ static uint32_t idhash(uint32_t x) { return x; } -static float rand_from_seed(uint32_t &seed) { +static real_t rand_from_seed(uint32_t &seed) { int k; int s = int(seed); if (s == 0) { @@ -510,7 +510,7 @@ static float rand_from_seed(uint32_t &seed) { s += 2147483647; } seed = uint32_t(s); - return float(seed % uint32_t(65536)) / 65535.0; + return (seed % uint32_t(65536)) / 65535.0; } void CPUParticles3D::_update_internal() { @@ -519,7 +519,7 @@ void CPUParticles3D::_update_internal() { return; } - float delta = get_process_delta_time(); + double delta = get_process_delta_time(); if (emitting) { inactive_time = 0; } else { @@ -541,14 +541,14 @@ void CPUParticles3D::_update_internal() { bool processed = false; 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); @@ -558,16 +558,16 @@ void CPUParticles3D::_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); @@ -587,7 +587,7 @@ void CPUParticles3D::_update_internal() { } } -void CPUParticles3D::_particles_process(float p_delta) { +void CPUParticles3D::_particles_process(double p_delta) { p_delta *= speed_scale; int pcount = particles.size(); @@ -595,7 +595,7 @@ void CPUParticles3D::_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); @@ -613,7 +613,7 @@ void CPUParticles3D::_particles_process(float p_delta) { velocity_xform = emission_xform.basis; } - float system_phase = time / lifetime; + double system_phase = time / lifetime; for (int i = 0; i < pcount; i++) { Particle &p = parray[i]; @@ -622,12 +622,12 @@ void CPUParticles3D::_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. - float restart_phase = float(i) / float(pcount); + double restart_phase = double(i) / double(pcount); if (randomness_ratio > 0.0) { uint32_t seed = cycle; @@ -636,12 +636,12 @@ void CPUParticles3D::_particles_process(float p_delta) { } seed *= uint32_t(pcount); seed += uint32_t(i); - float random = float(idhash(seed) % uint32_t(65536)) / 65536.0; - restart_phase += randomness_ratio * random * 1.0 / float(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) { @@ -682,17 +682,17 @@ void CPUParticles3D::_particles_process(float p_delta) { } p.active = true; - /*float tex_linear_velocity = 0; + /*real_t tex_linear_velocity = 0; if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(0); }*/ - float tex_angle = 0.0; + real_t tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } - float tex_anim_offset = 0.0; + real_t tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv); } @@ -705,26 +705,26 @@ void CPUParticles3D::_particles_process(float p_delta) { p.anim_offset_rand = Math::randf(); if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { - float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); + real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); - p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); + p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); } else { //initiate velocity spread in 3D - float angle1_rad = Math::atan2(direction.x, direction.z) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); - float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * spread); + real_t angle1_rad = Math::atan2(direction.x, direction.z) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); + real_t angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * spread); Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad)); Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad)); direction_yz.z = direction_yz.z / MAX(0.0001, Math::sqrt(ABS(direction_yz.z))); //better uniform distribution Vector3 direction = Vector3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z); direction.normalize(); - p.velocity = direction * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); + p.velocity = direction * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); } - float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, p.angle_rand, randomness[PARAM_ANGLE]); + real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]); p.custom[0] = Math::deg2rad(base_angle); //angle p.custom[1] = 0.0; //phase - p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1) + p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp((real_t)1.0, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1) p.transform = Transform3D(); p.time = 0; p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness); @@ -783,8 +783,8 @@ void CPUParticles3D::_particles_process(float p_delta) { } } break; case EMISSION_SHAPE_RING: { - float ring_random_angle = Math::randf() * 2.0 * Math_PI; - float ring_random_radius = Math::randf() * (emission_ring_radius - emission_ring_inner_radius) + emission_ring_inner_radius; + real_t ring_random_angle = Math::randf() * Math_TAU; + real_t ring_random_radius = Math::randf() * (emission_ring_radius - emission_ring_inner_radius) + emission_ring_inner_radius; Vector3 axis = emission_ring_axis.normalized(); Vector3 ortho_axis = Vector3(); if (axis == Vector3(1.0, 0.0, 0.0)) { @@ -824,53 +824,53 @@ void CPUParticles3D::_particles_process(float p_delta) { p.custom[1] = p.time / lifetime; tv = p.time / p.lifetime; - float tex_linear_velocity = 0.0; + real_t tex_linear_velocity = 0.0; if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv); } - float tex_orbit_velocity = 0.0; + real_t tex_orbit_velocity = 0.0; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv); } } - float tex_angular_velocity = 0.0; + real_t tex_angular_velocity = 0.0; if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) { tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv); } - float tex_linear_accel = 0.0; + real_t tex_linear_accel = 0.0; if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) { tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv); } - float tex_tangential_accel = 0.0; + real_t tex_tangential_accel = 0.0; if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) { tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv); } - float tex_radial_accel = 0.0; + real_t tex_radial_accel = 0.0; if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) { tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv); } - float tex_damping = 0.0; + real_t tex_damping = 0.0; if (curve_parameters[PARAM_DAMPING].is_valid()) { tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv); } - float tex_angle = 0.0; + real_t tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } - float tex_anim_speed = 0.0; + real_t tex_anim_speed = 0.0; if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) { tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv); } - float tex_anim_offset = 0.0; + real_t tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) { tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv); } @@ -881,28 +881,28 @@ void CPUParticles3D::_particles_process(float p_delta) { position.z = 0.0; } //apply linear acceleration - force += p.velocity.length() > 0.0 ? p.velocity.normalized() * (parameters[PARAM_LINEAR_ACCEL] + tex_linear_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_LINEAR_ACCEL]) : Vector3(); + force += p.velocity.length() > 0.0 ? p.velocity.normalized() * (parameters[PARAM_LINEAR_ACCEL] + tex_linear_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_LINEAR_ACCEL]) : Vector3(); //apply radial acceleration Vector3 org = emission_xform.origin; Vector3 diff = position - org; - force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3(); + force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3(); //apply tangential acceleration; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { Vector2 yx = Vector2(diff.y, diff.x); Vector2 yx2 = (yx * Vector2(-1.0, 1.0)).normalized(); - force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3(); + force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3(); } else { Vector3 crossDiff = diff.normalized().cross(gravity.normalized()); - force += crossDiff.length() > 0.0 ? crossDiff.normalized() * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3(); + force += crossDiff.length() > 0.0 ? crossDiff.normalized() * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3(); } //apply attractor forces p.velocity += force * local_delta; //orbit velocity if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { - float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]); + real_t orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]); if (orbit_amount != 0.0) { - float ang = orbit_amount * local_delta * Math_TAU; + real_t ang = orbit_amount * local_delta * Math_TAU; // Not sure why the ParticlesMaterial code uses a clockwise rotation matrix, // but we use -ang here to reproduce its behavior. Transform2D rot = Transform2D(-ang, Vector2()); @@ -915,8 +915,8 @@ void CPUParticles3D::_particles_process(float p_delta) { p.velocity = p.velocity.normalized() * tex_linear_velocity; } if (parameters[PARAM_DAMPING] + tex_damping > 0.0) { - float v = p.velocity.length(); - float damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]); + real_t v = p.velocity.length(); + real_t damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]); v -= damp * local_delta; if (v < 0.0) { p.velocity = Vector3(); @@ -924,27 +924,27 @@ void CPUParticles3D::_particles_process(float p_delta) { p.velocity = p.velocity.normalized() * v; } } - float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, p.angle_rand, randomness[PARAM_ANGLE]); - base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]); + real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]); + base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]); p.custom[0] = Math::deg2rad(base_angle); //angle - p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]); //angle + p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp((real_t)1.0, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]); //angle } //apply color //apply hue rotation - float tex_scale = 1.0; + real_t tex_scale = 1.0; if (curve_parameters[PARAM_SCALE].is_valid()) { tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv); } - float tex_hue_variation = 0.0; + real_t tex_hue_variation = 0.0; if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) { tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv); } - float 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]); - float hue_rot_c = Math::cos(hue_rot_angle); - float hue_rot_s = Math::sin(hue_rot_angle); + 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); Basis hue_rot_mat; { @@ -1013,9 +1013,9 @@ void CPUParticles3D::_particles_process(float p_delta) { } //scale by scale - float base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], 1.0f, p.scale_rand * randomness[PARAM_SCALE]); - if (base_scale < 0.000001) { - base_scale = 0.000001; + real_t base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], (real_t)1.0, p.scale_rand * randomness[PARAM_SCALE]); + if (base_scale < CMP_EPSILON) { + base_scale = CMP_EPSILON; } p.transform.basis.scale(Vector3(1, 1, 1) * base_scale); @@ -1097,7 +1097,7 @@ void CPUParticles3D::_update_particle_data_buffer() { ptr[10] = t.basis.elements[2][2]; ptr[11] = t.origin.z; } else { - memset(ptr, 0, sizeof(float) * 12); + memset(ptr, 0, sizeof(Transform3D)); } Color c = r[idx].color; diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 07d345ba2c..bb6699ddc7 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -86,23 +86,23 @@ private: struct Particle { Transform3D transform; Color color; - float custom[4] = {}; + real_t custom[4] = {}; Vector3 velocity; bool active = false; - float angle_rand = 0.0; - float scale_rand = 0.0; - float hue_rot_rand = 0.0; - float anim_offset_rand = 0.0; - float time = 0.0; - float lifetime = 0.0; + real_t angle_rand = 0.0; + real_t scale_rand = 0.0; + real_t hue_rot_rand = 0.0; + real_t anim_offset_rand = 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; @@ -132,12 +132,12 @@ private: bool one_shot = false; - float lifetime = 1.0; - float pre_process_time = 0.0; - float explosiveness_ratio = 0.0; - float randomness_ratio = 0.0; - float lifetime_randomness = 0.0; - float speed_scale = 1.0; + double lifetime = 1.0; + double pre_process_time = 0.0; + real_t explosiveness_ratio = 0.0; + real_t randomness_ratio = 0.0; + double lifetime_randomness = 0.0; + double speed_scale = 1.0; bool local_coords = true; int fixed_fps = 0; bool fractional_delta = true; @@ -153,11 +153,11 @@ private: //////// Vector3 direction = Vector3(1, 0, 0); - float spread = 45.0; - float flatness = 0.0; + real_t spread = 45.0; + real_t flatness = 0.0; - float parameters[PARAM_MAX]; - float randomness[PARAM_MAX] = {}; + real_t parameters[PARAM_MAX]; + real_t randomness[PARAM_MAX] = {}; Ref<Curve> curve_parameters[PARAM_MAX]; Color color = Color(1, 1, 1, 1); @@ -166,21 +166,21 @@ private: bool particle_flags[PARTICLE_FLAG_MAX] = {}; EmissionShape emission_shape = EMISSION_SHAPE_POINT; - float emission_sphere_radius = 1.0; + real_t emission_sphere_radius = 1.0; Vector3 emission_box_extents = Vector3(1, 1, 1); Vector<Vector3> emission_points; Vector<Vector3> emission_normals; Vector<Color> emission_colors; int emission_point_count = 0; Vector3 emission_ring_axis; - float emission_ring_height; - float emission_ring_radius; - float emission_ring_inner_radius; + real_t emission_ring_height; + real_t emission_ring_radius; + real_t emission_ring_inner_radius; Vector3 gravity = Vector3(0, -9.8, 0); void _update_internal(); - void _particles_process(float p_delta); + void _particles_process(double p_delta); void _update_particle_data_buffer(); Mutex update_mutex; @@ -200,27 +200,27 @@ 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_explosiveness_ratio(float p_ratio); - void set_randomness_ratio(float p_ratio); - void set_lifetime_randomness(float p_random); + 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(double p_random); void set_visibility_aabb(const AABB &p_aabb); void set_use_local_coordinates(bool p_enable); - void set_speed_scale(float 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; - float get_explosiveness_ratio() const; - float get_randomness_ratio() const; - float get_lifetime_randomness() const; + double get_pre_process_time() const; + real_t get_explosiveness_ratio() const; + real_t get_randomness_ratio() const; + double get_lifetime_randomness() const; AABB get_visibility_aabb() const; bool get_use_local_coordinates() const; - float get_speed_scale() const; + double get_speed_scale() const; void set_fixed_fps(int p_count); int get_fixed_fps() const; @@ -242,17 +242,17 @@ public: void set_direction(Vector3 p_direction); Vector3 get_direction() const; - void set_spread(float p_spread); - float get_spread() const; + void set_spread(real_t p_spread); + real_t get_spread() const; - void set_flatness(float p_flatness); - float get_flatness() const; + void set_flatness(real_t p_flatness); + real_t get_flatness() const; - void set_param(Parameter p_param, float p_value); - float get_param(Parameter p_param) const; + void set_param(Parameter p_param, real_t p_value); + real_t get_param(Parameter p_param) const; - void set_param_randomness(Parameter p_param, float p_value); - float get_param_randomness(Parameter p_param) const; + void set_param_randomness(Parameter p_param, real_t p_value); + real_t get_param_randomness(Parameter p_param) const; void set_param_curve(Parameter p_param, const Ref<Curve> &p_curve); Ref<Curve> get_param_curve(Parameter p_param) const; @@ -267,28 +267,28 @@ public: bool get_particle_flag(ParticleFlags p_particle_flag) const; void set_emission_shape(EmissionShape p_shape); - void set_emission_sphere_radius(float p_radius); + void set_emission_sphere_radius(real_t p_radius); void set_emission_box_extents(Vector3 p_extents); void set_emission_points(const Vector<Vector3> &p_points); void set_emission_normals(const Vector<Vector3> &p_normals); void set_emission_colors(const Vector<Color> &p_colors); void set_emission_point_count(int p_count); void set_emission_ring_axis(Vector3 p_axis); - void set_emission_ring_height(float p_height); - void set_emission_ring_radius(float p_radius); - void set_emission_ring_inner_radius(float p_radius); + void set_emission_ring_height(real_t p_height); + void set_emission_ring_radius(real_t p_radius); + void set_emission_ring_inner_radius(real_t p_radius); EmissionShape get_emission_shape() const; - float get_emission_sphere_radius() const; + real_t get_emission_sphere_radius() const; Vector3 get_emission_box_extents() const; Vector<Vector3> get_emission_points() const; Vector<Vector3> get_emission_normals() const; Vector<Color> get_emission_colors() const; int get_emission_point_count() const; Vector3 get_emission_ring_axis() const; - float get_emission_ring_height() const; - float get_emission_ring_radius() const; - float get_emission_ring_inner_radius() const; + real_t get_emission_ring_height() const; + real_t get_emission_ring_radius() const; + real_t get_emission_ring_inner_radius() const; void set_gravity(const Vector3 &p_gravity); Vector3 get_gravity() const; diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index 05f023721b..c94a99a203 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -53,48 +53,48 @@ Ref<Texture2D> Decal::get_texture(DecalTexture p_type) const { return textures[p_type]; } -void Decal::set_emission_energy(float p_energy) { +void Decal::set_emission_energy(real_t p_energy) { emission_energy = p_energy; RS::get_singleton()->decal_set_emission_energy(decal, emission_energy); } -float Decal::get_emission_energy() const { +real_t Decal::get_emission_energy() const { return emission_energy; } -void Decal::set_albedo_mix(float p_mix) { +void Decal::set_albedo_mix(real_t p_mix) { albedo_mix = p_mix; RS::get_singleton()->decal_set_albedo_mix(decal, albedo_mix); } -float Decal::get_albedo_mix() const { +real_t Decal::get_albedo_mix() const { return albedo_mix; } -void Decal::set_upper_fade(float p_fade) { +void Decal::set_upper_fade(real_t p_fade) { upper_fade = p_fade; RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); } -float Decal::get_upper_fade() const { +real_t Decal::get_upper_fade() const { return upper_fade; } -void Decal::set_lower_fade(float p_fade) { +void Decal::set_lower_fade(real_t p_fade) { lower_fade = p_fade; RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); } -float Decal::get_lower_fade() const { +real_t Decal::get_lower_fade() const { return lower_fade; } -void Decal::set_normal_fade(float p_fade) { +void Decal::set_normal_fade(real_t p_fade) { normal_fade = p_fade; RS::get_singleton()->decal_set_normal_fade(decal, normal_fade); } -float Decal::get_normal_fade() const { +real_t Decal::get_normal_fade() const { return normal_fade; } @@ -117,21 +117,21 @@ bool Decal::is_distance_fade_enabled() const { return distance_fade_enabled; } -void Decal::set_distance_fade_begin(float p_distance) { +void Decal::set_distance_fade_begin(real_t p_distance) { distance_fade_begin = p_distance; RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); } -float Decal::get_distance_fade_begin() const { +real_t Decal::get_distance_fade_begin() const { return distance_fade_begin; } -void Decal::set_distance_fade_length(float p_length) { +void Decal::set_distance_fade_length(real_t p_length) { distance_fade_length = p_length; RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); } -float Decal::get_distance_fade_length() const { +real_t Decal::get_distance_fade_length() const { return distance_fade_length; } diff --git a/scene/3d/decal.h b/scene/3d/decal.h index 31a6315213..041c8f97b2 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -51,16 +51,16 @@ private: RID decal; Vector3 extents = Vector3(1, 1, 1); Ref<Texture2D> textures[TEXTURE_MAX]; - float emission_energy = 1.0; - float albedo_mix = 1.0; + real_t emission_energy = 1.0; + real_t albedo_mix = 1.0; Color modulate = Color(1, 1, 1, 1); uint32_t cull_mask = (1 << 20) - 1; - float normal_fade = 0.0; - float upper_fade = 0.3; - float lower_fade = 0.3; + real_t normal_fade = 0.0; + real_t upper_fade = 0.3; + real_t lower_fade = 0.3; bool distance_fade_enabled = false; - float distance_fade_begin = 10.0; - float distance_fade_length = 1.0; + real_t distance_fade_begin = 10.0; + real_t distance_fade_length = 1.0; protected: static void _bind_methods(); @@ -75,32 +75,32 @@ public: void set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture); Ref<Texture2D> get_texture(DecalTexture p_type) const; - void set_emission_energy(float p_energy); - float get_emission_energy() const; + void set_emission_energy(real_t p_energy); + real_t get_emission_energy() const; - void set_albedo_mix(float p_mix); - float get_albedo_mix() const; + void set_albedo_mix(real_t p_mix); + real_t get_albedo_mix() const; void set_modulate(Color p_modulate); Color get_modulate() const; - void set_upper_fade(float p_energy); - float get_upper_fade() const; + void set_upper_fade(real_t p_energy); + real_t get_upper_fade() const; - void set_lower_fade(float p_fade); - float get_lower_fade() const; + void set_lower_fade(real_t p_fade); + real_t get_lower_fade() const; - void set_normal_fade(float p_fade); - float get_normal_fade() const; + void set_normal_fade(real_t p_fade); + real_t get_normal_fade() const; void set_enable_distance_fade(bool p_enable); bool is_distance_fade_enabled() const; - void set_distance_fade_begin(float p_distance); - float get_distance_fade_begin() const; + void set_distance_fade_begin(real_t p_distance); + real_t get_distance_fade_begin() const; - void set_distance_fade_length(float p_length); - float get_distance_fade_length() const; + void set_distance_fade_length(real_t p_length); + real_t get_distance_fade_length() const; void set_cull_mask(uint32_t p_layers); uint32_t get_cull_mask() const; diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 44cd7c10d8..8b8b53c3bf 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -59,7 +59,7 @@ void GPUParticles3D::set_amount(int p_amount) { RS::get_singleton()->particles_set_amount(particles, amount); } -void GPUParticles3D::set_lifetime(float p_lifetime) { +void GPUParticles3D::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); @@ -81,7 +81,7 @@ void GPUParticles3D::set_one_shot(bool p_one_shot) { } } -void GPUParticles3D::set_pre_process_time(float p_time) { +void GPUParticles3D::set_pre_process_time(double p_time) { pre_process_time = p_time; RS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time); } @@ -118,7 +118,7 @@ void GPUParticles3D::set_process_material(const Ref<Material> &p_material) { update_configuration_warnings(); } -void GPUParticles3D::set_speed_scale(float p_scale) { +void GPUParticles3D::set_speed_scale(double p_scale) { speed_scale = p_scale; RS::get_singleton()->particles_set_speed_scale(particles, p_scale); } @@ -136,7 +136,7 @@ int GPUParticles3D::get_amount() const { return amount; } -float GPUParticles3D::get_lifetime() const { +double GPUParticles3D::get_lifetime() const { return lifetime; } @@ -144,7 +144,7 @@ bool GPUParticles3D::get_one_shot() const { return one_shot; } -float GPUParticles3D::get_pre_process_time() const { +double GPUParticles3D::get_pre_process_time() const { return pre_process_time; } @@ -168,7 +168,7 @@ Ref<Material> GPUParticles3D::get_process_material() const { return process_material; } -float GPUParticles3D::get_speed_scale() const { +double GPUParticles3D::get_speed_scale() const { return speed_scale; } diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index 7b21cf03f1..31e0e2abf5 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -64,11 +64,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; AABB visibility_aabb; bool local_coords; int fixed_fps; @@ -104,30 +104,30 @@ 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(float p_ratio); void set_randomness_ratio(float p_ratio); void set_visibility_aabb(const AABB &p_aabb); 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_speed_scale(double p_scale); void set_collision_base_size(float p_ratio); void set_trail_enabled(bool p_enabled); void set_trail_length(float p_seconds); 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; float get_explosiveness_ratio() const; float get_randomness_ratio() const; AABB get_visibility_aabb() 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; bool is_trail_enabled() const; float get_trail_length() const; diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index c2943a9606..40f33dfa72 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -38,7 +38,7 @@ bool Light3D::_can_gizmo_scale() const { return false; } -void Light3D::set_param(Param p_param, float p_value) { +void Light3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); param[p_param] = p_value; @@ -53,7 +53,7 @@ void Light3D::set_param(Param p_param, float p_value) { } } -float Light3D::get_param(Param p_param) const { +real_t Light3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return param[p_param]; } @@ -128,8 +128,8 @@ AABB Light3D::get_aabb() const { return AABB(Vector3(-1, -1, -1) * param[PARAM_RANGE], Vector3(2, 2, 2) * param[PARAM_RANGE]); } else if (type == RenderingServer::LIGHT_SPOT) { - float len = param[PARAM_RANGE]; - float size = Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE])) * len; + real_t len = param[PARAM_RANGE]; + real_t size = Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE])) * len; return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index d0308a3025..51ed2fcf50 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -71,7 +71,7 @@ public: private: Color color; - float param[PARAM_MAX] = {}; + real_t param[PARAM_MAX] = {}; Color shadow_color; bool shadow = false; bool negative = false; @@ -102,8 +102,8 @@ public: void set_editor_only(bool p_editor_only); bool is_editor_only() const; - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; void set_shadow(bool p_enable); bool has_shadow() const; diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp index 636be083ab..43d6f262d8 100644 --- a/scene/3d/listener_3d.cpp +++ b/scene/3d/listener_3d.cpp @@ -73,14 +73,14 @@ void Listener3D::_get_property_list(List<PropertyInfo> *p_list) const { void Listener3D::_update_listener() { if (is_inside_tree() && is_current()) { - get_viewport()->_listener_transform_changed_notify(); + get_viewport()->_listener_transform_3d_changed_notify(); } } void Listener3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { - bool first_listener = get_viewport()->_listener_add(this); + bool first_listener = get_viewport()->_listener_3d_add(this); if (!get_tree()->is_node_being_edited(this) && (current || first_listener)) { make_current(); } @@ -99,7 +99,7 @@ void Listener3D::_notification(int p_what) { } } - get_viewport()->_listener_remove(this); + get_viewport()->_listener_3d_remove(this); } break; } @@ -116,7 +116,7 @@ void Listener3D::make_current() { return; } - get_viewport()->_listener_set(this); + get_viewport()->_listener_3d_set(this); } void Listener3D::clear_current() { @@ -125,15 +125,15 @@ void Listener3D::clear_current() { return; } - if (get_viewport()->get_listener() == this) { - get_viewport()->_listener_set(nullptr); - get_viewport()->_listener_make_next_current(this); + if (get_viewport()->get_listener_3d() == this) { + get_viewport()->_listener_3d_set(nullptr); + get_viewport()->_listener_3d_make_next_current(this); } } bool Listener3D::is_current() const { if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) { - return get_viewport()->get_listener() == this; + return get_viewport()->get_listener_3d() == this; } else { return current; } diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 0daee69ee5..8f186199db 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -588,31 +588,31 @@ bool Node3D::is_visible() const { return data.visible; } -void Node3D::rotate_object_local(const Vector3 &p_axis, float p_angle) { +void Node3D::rotate_object_local(const Vector3 &p_axis, real_t p_angle) { Transform3D t = get_transform(); t.basis.rotate_local(p_axis, p_angle); set_transform(t); } -void Node3D::rotate(const Vector3 &p_axis, float p_angle) { +void Node3D::rotate(const Vector3 &p_axis, real_t p_angle) { Transform3D t = get_transform(); t.basis.rotate(p_axis, p_angle); set_transform(t); } -void Node3D::rotate_x(float p_angle) { +void Node3D::rotate_x(real_t p_angle) { Transform3D t = get_transform(); t.basis.rotate(Vector3(1, 0, 0), p_angle); set_transform(t); } -void Node3D::rotate_y(float p_angle) { +void Node3D::rotate_y(real_t p_angle) { Transform3D t = get_transform(); t.basis.rotate(Vector3(0, 1, 0), p_angle); set_transform(t); } -void Node3D::rotate_z(float p_angle) { +void Node3D::rotate_z(real_t p_angle) { Transform3D t = get_transform(); t.basis.rotate(Vector3(0, 0, 1), p_angle); set_transform(t); @@ -644,7 +644,7 @@ void Node3D::scale_object_local(const Vector3 &p_scale) { set_transform(t); } -void Node3D::global_rotate(const Vector3 &p_axis, float p_angle) { +void Node3D::global_rotate(const Vector3 &p_axis, real_t p_angle) { Transform3D t = get_global_transform(); t.basis.rotate(p_axis, p_angle); set_global_transform(t); @@ -673,19 +673,17 @@ void Node3D::set_identity() { } void Node3D::look_at(const Vector3 &p_target, const Vector3 &p_up) { - Vector3 origin(get_global_transform().origin); + Vector3 origin = get_global_transform().origin; look_at_from_position(origin, p_target, p_up); } void Node3D::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up) { - ERR_FAIL_COND_MSG(p_pos == p_target, "Node origin and target are in the same position, look_at() failed."); - ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos) == Vector3(), "Up vector and direction between node origin and target are aligned, look_at() failed."); + ERR_FAIL_COND_MSG(p_pos.is_equal_approx(p_target), "Node origin and target are in the same position, look_at() failed."); + ERR_FAIL_COND_MSG(p_up.is_equal_approx(Vector3()), "The up vector can't be zero, look_at() failed."); + ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos).is_equal_approx(Vector3()), "Up vector and direction between node origin and target are aligned, look_at() failed."); - Transform3D lookat; - lookat.origin = p_pos; - - Vector3 original_scale(get_scale()); - lookat = lookat.looking_at(p_target, p_up); + Transform3D lookat = Transform3D(Basis::looking_at(p_target - p_pos, p_up), p_pos); + Vector3 original_scale = get_scale(); set_global_transform(lookat); set_scale(original_scale); } diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index 282f4805cc..da54452abb 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -167,18 +167,18 @@ public: Transform3D get_relative_transform(const Node *p_parent) const; - void rotate(const Vector3 &p_axis, float p_angle); - void rotate_x(float p_angle); - void rotate_y(float p_angle); - void rotate_z(float p_angle); + void rotate(const Vector3 &p_axis, real_t p_angle); + void rotate_x(real_t p_angle); + void rotate_y(real_t p_angle); + void rotate_z(real_t p_angle); void translate(const Vector3 &p_offset); void scale(const Vector3 &p_ratio); - void rotate_object_local(const Vector3 &p_axis, float p_angle); + void rotate_object_local(const Vector3 &p_axis, real_t p_angle); void scale_object_local(const Vector3 &p_scale); void translate_object_local(const Vector3 &p_offset); - void global_rotate(const Vector3 &p_axis, float p_angle); + void global_rotate(const Vector3 &p_axis, real_t p_angle); void global_scale(const Vector3 &p_scale); void global_translate(const Vector3 &p_offset); diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 589135710f..6818acf69d 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -94,13 +94,13 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) { return; } - float bl = c->get_baked_length(); + real_t bl = c->get_baked_length(); if (bl == 0.0) { return; } - float bi = c->get_bake_interval(); - float o_next = offset + bi; - float o_prev = offset - bi; + real_t bi = c->get_bake_interval(); + real_t o_next = offset + bi; + real_t o_prev = offset - bi; if (loop) { o_next = Math::fposmod(o_next, bl); @@ -169,8 +169,8 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) { Vector3 t_cur = (c->interpolate_baked(offset + delta_offset, cubic) - pos).normalized(); Vector3 axis = t_prev.cross(t_cur); - float dot = t_prev.dot(t_cur); - float angle = Math::acos(CLAMP(dot, -1, 1)); + real_t dot = t_prev.dot(t_cur); + real_t angle = Math::acos(CLAMP(dot, -1, 1)); if (likely(!Math::is_zero_approx(angle))) { if (rotation_mode == ROTATION_Y) { @@ -189,7 +189,7 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) { } // do the additional tilting - float tilt_angle = c->interpolate_baked_tilt(offset); + real_t tilt_angle = c->interpolate_baked_tilt(offset); Vector3 tilt_axis = t_cur; // not sure what tilt is supposed to do, is this correct?? if (likely(!Math::is_zero_approx(Math::abs(tilt_angle)))) { @@ -244,7 +244,7 @@ bool PathFollow3D::get_cubic_interpolation() const { void PathFollow3D::_validate_property(PropertyInfo &property) const { if (property.name == "offset") { - float max = 10000; + real_t max = 10000; if (path && path->get_curve().is_valid()) { max = path->get_curve()->get_baked_length(); } @@ -307,13 +307,13 @@ void PathFollow3D::_bind_methods() { BIND_ENUM_CONSTANT(ROTATION_ORIENTED); } -void PathFollow3D::set_offset(float p_offset) { +void PathFollow3D::set_offset(real_t p_offset) { delta_offset = p_offset - offset; offset = p_offset; if (path) { if (path->get_curve().is_valid()) { - float path_length = path->get_curve()->get_baked_length(); + real_t path_length = path->get_curve()->get_baked_length(); if (loop) { offset = Math::fposmod(offset, path_length); @@ -329,39 +329,39 @@ void PathFollow3D::set_offset(float p_offset) { } } -void PathFollow3D::set_h_offset(float p_h_offset) { +void PathFollow3D::set_h_offset(real_t p_h_offset) { h_offset = p_h_offset; if (path) { _update_transform(); } } -float PathFollow3D::get_h_offset() const { +real_t PathFollow3D::get_h_offset() const { return h_offset; } -void PathFollow3D::set_v_offset(float p_v_offset) { +void PathFollow3D::set_v_offset(real_t p_v_offset) { v_offset = p_v_offset; if (path) { _update_transform(); } } -float PathFollow3D::get_v_offset() const { +real_t PathFollow3D::get_v_offset() const { return v_offset; } -float PathFollow3D::get_offset() const { +real_t PathFollow3D::get_offset() const { return offset; } -void PathFollow3D::set_unit_offset(float p_unit_offset) { +void PathFollow3D::set_unit_offset(real_t p_unit_offset) { if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { set_offset(p_unit_offset * path->get_curve()->get_baked_length()); } } -float PathFollow3D::get_unit_offset() const { +real_t PathFollow3D::get_unit_offset() const { if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { return get_offset() / path->get_curve()->get_baked_length(); } else { diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h index 8545370a4a..1ffe291100 100644 --- a/scene/3d/path_3d.h +++ b/scene/3d/path_3d.h @@ -83,17 +83,17 @@ protected: static void _bind_methods(); public: - void set_offset(float p_offset); - float get_offset() const; + void set_offset(real_t p_offset); + real_t get_offset() const; - void set_h_offset(float p_h_offset); - float get_h_offset() const; + void set_h_offset(real_t p_h_offset); + real_t get_h_offset() const; - void set_v_offset(float p_v_offset); - float get_v_offset() const; + void set_v_offset(real_t p_v_offset); + real_t get_v_offset() const; - void set_unit_offset(float p_unit_offset); - float get_unit_offset() const; + void set_unit_offset(real_t p_unit_offset); + real_t get_unit_offset() const; void set_loop(bool p_loop); bool has_loop() const; diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 100e3563a3..53ec07f1ce 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -117,9 +117,9 @@ Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_i return Ref<KinematicCollision3D>(); } -bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding) { +bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding, const Set<RID> &p_exclude) { Transform3D gt = get_global_transform(); - bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes); + bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes, p_exclude); // Restore direction of motion to be along original motion, // in order to avoid sliding due to recovery, @@ -1090,6 +1090,9 @@ void CharacterBody3D::move_and_slide() { 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 + float delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time(); + for (int i = 0; i < 3; i++) { if (locked_axis & (1 << i)) { linear_velocity[i] = 0.0; @@ -1097,28 +1100,40 @@ void CharacterBody3D::move_and_slide() { } Vector3 current_floor_velocity = floor_velocity; - if (on_floor && on_floor_body.is_valid()) { + 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 PhysicsDirectBodyState3D *bs = PhysicsServer3D::get_singleton()->body_get_direct_state(on_floor_body); if (bs) { - current_floor_velocity = bs->get_linear_velocity(); + Transform3D gt = get_global_transform(); + Vector3 local_position = gt.origin - bs->get_transform().origin; + current_floor_velocity = bs->get_velocity_at_local_position(local_position); } } - // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky - Vector3 motion = (floor_velocity + linear_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); - + motion_results.clear(); on_floor = false; - on_floor_body = RID(); on_ceiling = false; on_wall = false; - motion_results.clear(); floor_normal = Vector3(); floor_velocity = Vector3(); + if (current_floor_velocity != Vector3() && on_floor_body.is_valid()) { + PhysicsServer3D::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)) { + motion_results.push_back(floor_result); + _set_collision_direction(floor_result); + } + } + + on_floor_body = RID(); + Vector3 motion = linear_velocity * delta; + // No sliding on first attempt to keep floor motion stable when possible, // when stop on slope is enabled. bool sliding_enabled = !stop_on_slope; + for (int iteration = 0; iteration < max_slides; ++iteration) { PhysicsServer3D::MotionResult result; bool found_collision = false; @@ -1142,35 +1157,19 @@ void CharacterBody3D::move_and_slide() { found_collision = true; motion_results.push_back(result); - - if (up_direction == Vector3()) { - //all is a wall - on_wall = true; - } else { - if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor - - on_floor = true; - floor_normal = result.collision_normal; - on_floor_body = result.collider; - floor_velocity = result.collider_velocity; - - if (stop_on_slope) { - if ((body_velocity_normal + up_direction).length() < 0.01) { - Transform3D gt = get_global_transform(); - if (result.motion.length() > margin) { - gt.origin -= result.motion.slide(up_direction); - } else { - gt.origin -= result.motion; - } - set_global_transform(gt); - linear_velocity = Vector3(); - return; - } + _set_collision_direction(result); + + if (on_floor && stop_on_slope) { + if ((body_velocity_normal + up_direction).length() < 0.01) { + Transform3D gt = get_global_transform(); + if (result.motion.length() > margin) { + gt.origin -= result.motion.slide(up_direction); + } else { + gt.origin -= result.motion; } - } else if (Math::acos(result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling - on_ceiling = true; - } else { - on_wall = true; + set_global_transform(gt); + linear_velocity = Vector3(); + return; } } @@ -1196,6 +1195,11 @@ void CharacterBody3D::move_and_slide() { } } + if (!on_floor && !on_wall) { + // Add last platform velocity when just left a moving platform. + linear_velocity += current_floor_velocity; + } + if (!was_on_floor || snap == Vector3()) { return; } @@ -1231,6 +1235,29 @@ void CharacterBody3D::move_and_slide() { } } +void CharacterBody3D::_set_collision_direction(const PhysicsServer3D::MotionResult &p_result) { + on_floor = false; + on_ceiling = false; + on_wall = false; + if (up_direction == Vector3()) { + //all is a wall + on_wall = 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; + } + } +} + bool CharacterBody3D::separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result) { PhysicsServer3D::SeparationResult sep_res[8]; //max 8 rays diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 0ef9c78f3b..227e6d43b6 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -53,7 +53,7 @@ protected: Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.001); public: - bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true); + bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true, const Set<RID> &p_exclude = Set<RID>()); bool test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001); void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); @@ -298,6 +298,8 @@ private: Ref<KinematicCollision3D> _get_slide_collision(int p_bounce); + void _set_collision_direction(const PhysicsServer3D::MotionResult &p_result); + bool separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result); void set_safe_margin(real_t p_margin); diff --git a/scene/3d/proximity_group_3d.h b/scene/3d/proximity_group_3d.h index 05aa00b228..e45adc3040 100644 --- a/scene/3d/proximity_group_3d.h +++ b/scene/3d/proximity_group_3d.h @@ -49,7 +49,7 @@ private: DispatchMode dispatch_mode = MODE_PROXY; Vector3 grid_radius = Vector3(1, 1, 1); - float cell_size = 1.0; + real_t cell_size = 1.0; uint32_t group_version = 0; void _clear_groups(); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 9ce4c37457..86e2af7df5 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -366,7 +366,7 @@ void Skeleton3D::clear_bones_global_pose_override() { _make_dirty(); } -void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, float p_amount, bool p_persistent) { +void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent) { ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].global_pose_override_amount = p_amount; bones.write[p_bone].global_pose_override = p_pose; diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 2f6e416c8c..3fdf5321a5 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -85,7 +85,7 @@ private: bool custom_pose_enable = false; Transform3D custom_pose; - float global_pose_override_amount = 0.0; + real_t global_pose_override_amount = 0.0; bool global_pose_override_reset = false; Transform3D global_pose_override; @@ -147,7 +147,7 @@ public: Transform3D get_bone_global_pose_no_override(int p_bone) const; void clear_bones_global_pose_override(); - void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, float p_amount, bool p_persistent = false); + void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent = false); void set_bone_enabled(int p_bone, bool p_enabled); bool is_bone_enabled(int p_bone) const; diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 1005d51e63..a891566633 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -85,7 +85,7 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain chain_sub_tip = p_task->skeleton->get_bone_parent(chain_sub_tip); } - BoneId middle_chain_item_id = (((float)sub_chain_size) * 0.5); + BoneId middle_chain_item_id = (BoneId)(sub_chain_size * 0.5); // Build chain by reading chain ids in reverse order // For each chain item id will be created a ChainItem if doesn't exists diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index a901920dbe..a28382f4cb 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -132,12 +132,12 @@ Color SpriteBase3D::get_modulate() const { return modulate; } -void SpriteBase3D::set_pixel_size(float p_amount) { +void SpriteBase3D::set_pixel_size(real_t p_amount) { pixel_size = p_amount; _queue_update(); } -float SpriteBase3D::get_pixel_size() const { +real_t SpriteBase3D::get_pixel_size() const { return pixel_size; } @@ -203,7 +203,7 @@ Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const { return Ref<TriangleMesh>(); } - float pixel_size = get_pixel_size(); + real_t pixel_size = get_pixel_size(); Vector2 vertices[4] = { @@ -470,7 +470,7 @@ void Sprite3D::_draw() { Color color = _get_color_accum(); color.a *= get_opacity(); - float pixel_size = get_pixel_size(); + real_t pixel_size = get_pixel_size(); Vector2 vertices[4] = { @@ -837,7 +837,7 @@ void AnimatedSprite3D::_draw() { Color color = _get_color_accum(); color.a *= get_opacity(); - float pixel_size = get_pixel_size(); + real_t pixel_size = get_pixel_size(); Vector2 vertices[4] = { @@ -1037,7 +1037,7 @@ void AnimatedSprite3D::_notification(int p_what) { return; //do nothing } - float remaining = get_process_delta_time(); + double remaining = get_process_delta_time(); while (remaining) { if (timeout <= 0) { @@ -1059,7 +1059,7 @@ void AnimatedSprite3D::_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; } diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 404ef57e6a..d35b9ffe1b 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -72,7 +72,7 @@ private: float opacity = 1.0; Vector3::Axis axis = Vector3::AXIS_Z; - float pixel_size = 0.01; + real_t pixel_size = 0.01; AABB aabb; RID mesh; @@ -130,8 +130,8 @@ public: void set_opacity(float p_amount); float get_opacity() const; - void set_pixel_size(float p_amount); - float get_pixel_size() const; + void set_pixel_size(real_t p_amount); + real_t get_pixel_size() const; void set_axis(Vector3::Axis p_axis); Vector3::Axis get_axis() const; @@ -213,7 +213,7 @@ class AnimatedSprite3D : public SpriteBase3D { bool centered = false; - float timeout = 0; + double timeout = 0.0; void _res_changed(); diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp index 5b5cc06456..a027749eaa 100644 --- a/scene/3d/velocity_tracker_3d.cpp +++ b/scene/3d/velocity_tracker_3d.cpp @@ -61,16 +61,16 @@ void VelocityTracker3D::update_position(const Vector3 &p_position) { Vector3 VelocityTracker3D::get_tracked_linear_velocity() const { Vector3 linear_velocity; - float max_time = 1 / 5.0; //maximum time to interpolate a velocity + double max_time = 1 / 5.0; //maximum time to interpolate a velocity Vector3 distance_accum; - float time_accum = 0.0; - float base_time = 0.0; + double time_accum = 0.0; + double base_time = 0.0; if (position_history_len) { if (physics_step) { uint64_t base = Engine::get_singleton()->get_physics_frames(); - base_time = float(base - position_history[0].frame) / Engine::get_singleton()->get_iterations_per_second(); + base_time = double(base - position_history[0].frame) / Engine::get_singleton()->get_iterations_per_second(); } else { uint64_t base = Engine::get_singleton()->get_frame_ticks(); base_time = double(base - position_history[0].frame) / 1000000.0; @@ -78,12 +78,12 @@ Vector3 VelocityTracker3D::get_tracked_linear_velocity() const { } for (int i = 0; i < position_history_len - 1; i++) { - float delta = 0.0; + double delta = 0.0; uint64_t diff = position_history[i].frame - position_history[i + 1].frame; Vector3 distance = position_history[i].position - position_history[i + 1].position; if (physics_step) { - delta = float(diff) / Engine::get_singleton()->get_iterations_per_second(); + delta = double(diff) / Engine::get_singleton()->get_iterations_per_second(); } else { delta = double(diff) / 1000000.0; } diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index f1b9708f91..6124326d2d 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -56,20 +56,20 @@ static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3 Vector3 v1 = p_vtx[2] - p_vtx[0]; Vector3 v2 = p_pos - p_vtx[0]; - float d00 = v0.dot(v0); - float d01 = v0.dot(v1); - float d11 = v1.dot(v1); - float d20 = v2.dot(v0); - float d21 = v2.dot(v1); - float denom = (d00 * d11 - d01 * d01); + real_t d00 = v0.dot(v0); + real_t d01 = v0.dot(v1); + real_t d11 = v1.dot(v1); + real_t d20 = v2.dot(v0); + real_t d21 = v2.dot(v1); + real_t denom = (d00 * d11 - d01 * d01); if (denom == 0) { r_uv = p_uv[0]; r_normal = p_normal[0]; return; } - float v = (d11 * d20 - d01 * d21) / denom; - float w = (d00 * d21 - d01 * d20) / denom; - float u = 1.0f - v - w; + real_t v = (d11 * d20 - d01 * d21) / denom; + real_t w = (d00 * d21 - d01 * d20) / denom; + real_t u = 1.0f - v - w; r_uv = p_uv[0] * u + p_uv[1] * v + p_uv[2] * w; r_normal = (p_normal[0] * u + p_normal[1] * v + p_normal[2] * w).normalized(); @@ -81,7 +81,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co //find best axis to map to, for scanning values int closest_axis = 0; - float closest_dot = 0; + real_t closest_dot = 0; Plane plane = Plane(p_vtx[0], p_vtx[1], p_vtx[2]); Vector3 normal = plane.normal; @@ -89,7 +89,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co for (int i = 0; i < 3; i++) { Vector3 axis; axis[i] = 1.0; - float dot = ABS(normal.dot(axis)); + real_t dot = ABS(normal.dot(axis)); if (i == 0 || dot > closest_dot) { closest_axis = i; closest_dot = dot; @@ -103,8 +103,8 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co Vector3 t2; t2[(closest_axis + 2) % 3] = 1.0; - t1 *= p_aabb.size[(closest_axis + 1) % 3] / float(color_scan_cell_width); - t2 *= p_aabb.size[(closest_axis + 2) % 3] / float(color_scan_cell_width); + t1 *= p_aabb.size[(closest_axis + 1) % 3] / real_t(color_scan_cell_width); + t2 *= p_aabb.size[(closest_axis + 2) % 3] / real_t(color_scan_cell_width); Color albedo_accum; Color emission_accum; @@ -114,10 +114,10 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co //map to a grid average in the best axis for this face for (int i = 0; i < color_scan_cell_width; i++) { - Vector3 ofs_i = float(i) * t1; + Vector3 ofs_i = real_t(i) * t1; for (int j = 0; j < color_scan_cell_width; j++) { - Vector3 ofs_j = float(j) * t2; + Vector3 ofs_j = real_t(j) * t2; Vector3 from = p_aabb.position + ofs_i + ofs_j; Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis]; @@ -155,8 +155,8 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co lnormal = normal; } - int uv_x = CLAMP(int(Math::fposmod(uv.x, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); - int uv_y = CLAMP(int(Math::fposmod(uv.y, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); + int uv_x = CLAMP(int(Math::fposmod(uv.x, (real_t)1.0) * bake_texture_size), 0, bake_texture_size - 1); + int uv_y = CLAMP(int(Math::fposmod(uv.y, (real_t)1.0) * bake_texture_size), 0, bake_texture_size - 1); int ofs = uv_y * bake_texture_size + uv_x; albedo_accum.r += p_material.albedo[ofs].r; @@ -187,8 +187,8 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co lnormal = normal; } - int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); - int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); + int uv_x = CLAMP(Math::fposmod(uv.x, (real_t)1.0) * bake_texture_size, 0, bake_texture_size - 1); + int uv_y = CLAMP(Math::fposmod(uv.y, (real_t)1.0) * bake_texture_size, 0, bake_texture_size - 1); int ofs = uv_y * bake_texture_size + uv_x; @@ -636,7 +636,7 @@ void Voxelizer::begin_bake(int p_subdiv, const AABB &p_bounds) { } axis_cell_size[i] = axis_cell_size[longest_axis]; - float axis_size = po2_bounds.size[longest_axis]; + real_t axis_size = po2_bounds.size[longest_axis]; //shrink until fit subdiv while (axis_size / 2.0 >= po2_bounds.size[i]) { @@ -954,7 +954,7 @@ Ref<MultiMesh> Voxelizer::create_debug_multimesh() { Vector3 face_points[4]; for (int j = 0; j < 4; j++) { - float v[3]; + real_t v[3]; v[0] = 1.0; v[1] = 1 - 2 * ((j >> 1) & 1); v[2] = v[1] * (1 - 2 * (j & 1)); diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index b04c7e2858..e620f33478 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -124,7 +124,7 @@ Point2 XRCamera3D::unproject_position(const Vector3 &p_pos) const { return res; }; -Vector3 XRCamera3D::project_position(const Point2 &p_point, float p_z_depth) const { +Vector3 XRCamera3D::project_position(const Point2 &p_point, real_t p_z_depth) const { // get our XRServer XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, Vector3()); @@ -544,7 +544,7 @@ void XROrigin3D::clear_tracked_camera_if(XRCamera3D *p_tracked_camera) { }; }; -float XROrigin3D::get_world_scale() const { +real_t XROrigin3D::get_world_scale() const { // get our XRServer XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, 1.0); @@ -552,7 +552,7 @@ float XROrigin3D::get_world_scale() const { return xr_server->get_world_scale(); }; -void XROrigin3D::set_world_scale(float p_world_scale) { +void XROrigin3D::set_world_scale(real_t p_world_scale) { // get our XRServer XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h index 90079f5fe9..312287a93b 100644 --- a/scene/3d/xr_nodes.h +++ b/scene/3d/xr_nodes.h @@ -54,7 +54,7 @@ public: virtual Vector3 project_local_ray_normal(const Point2 &p_pos) const override; virtual Point2 unproject_position(const Vector3 &p_pos) const override; - virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const override; + virtual Vector3 project_position(const Point2 &p_point, real_t p_z_depth) const override; virtual Vector<Plane> get_frustum() const override; XRCamera3D() {} @@ -163,8 +163,8 @@ public: void set_tracked_camera(XRCamera3D *p_tracked_camera); void clear_tracked_camera_if(XRCamera3D *p_tracked_camera); - float get_world_scale() const; - void set_world_scale(float p_world_scale); + real_t get_world_scale() const; + void set_world_scale(real_t p_world_scale); XROrigin3D() {} ~XROrigin3D() {} diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index 6e5d964b76..0167992baf 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -219,7 +219,7 @@ void AnimationNodeBlendSpace1D::_add_blend_point(int p_index, const Ref<Animatio } } -float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) { +double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek) { if (blend_points_used == 0) { return 0.0; } @@ -229,7 +229,7 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) { return blend_node(blend_points[0].name, blend_points[0].node, p_time, p_seek, 1.0, FILTER_IGNORE, false); } - float blend_pos = get_parameter(blend_position); + double blend_pos = get_parameter(blend_position); float weights[MAX_BLEND_POINTS] = {}; diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h index 8886e6c679..6730c09fd4 100644 --- a/scene/animation/animation_blend_space_1d.h +++ b/scene/animation/animation_blend_space_1d.h @@ -93,7 +93,7 @@ public: void set_value_label(const String &p_label); String get_value_label() const; - float process(float p_time, bool p_seek) override; + double process(double p_time, bool p_seek) override; String get_caption() const override; Ref<AnimationNode> get_child_by_name(const StringName &p_name) override; diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index d88a9badf4..145e7c605b 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -431,12 +431,12 @@ void AnimationNodeBlendSpace2D::_blend_triangle(const Vector2 &p_pos, const Vect r_weights[2] = w; } -float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { +double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek) { _update_triangles(); Vector2 blend_pos = get_parameter(blend_position); int closest = get_parameter(this->closest); - float length_internal = get_parameter(this->length_internal); + double length_internal = get_parameter(this->length_internal); float mind = 0.0; //time of min distance point if (blend_mode == BLEND_MODE_INTERPOLATED) { diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h index 65d09a550d..a919fff1d2 100644 --- a/scene/animation/animation_blend_space_2d.h +++ b/scene/animation/animation_blend_space_2d.h @@ -126,7 +126,7 @@ public: void set_y_label(const String &p_label); String get_y_label() const; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; virtual String get_caption() const override; Vector2 get_closest_point(const Vector2 &p_point); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 4bddae3b14..049f3483ff 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -63,11 +63,11 @@ void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const { } } -float AnimationNodeAnimation::process(float p_time, bool p_seek) { +double AnimationNodeAnimation::process(double p_time, bool p_seek) { AnimationPlayer *ap = state->player; ERR_FAIL_COND_V(!ap, 0); - float time = get_parameter(this->time); + double time = get_parameter(this->time); if (!ap->has_animation(animation)) { AnimationNodeBlendTree *tree = Object::cast_to<AnimationNodeBlendTree>(parent); @@ -84,7 +84,7 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) { Ref<Animation> anim = ap->get_animation(animation); - float step; + double step; if (p_seek) { time = p_time; @@ -94,7 +94,7 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) { step = p_time; } - float anim_size = anim->get_length(); + double anim_size = anim->get_length(); if (anim->has_loop()) { if (anim_size) { @@ -202,12 +202,12 @@ bool AnimationNodeOneShot::has_filter() const { return true; } -float AnimationNodeOneShot::process(float p_time, bool p_seek) { +double AnimationNodeOneShot::process(double p_time, bool p_seek) { bool active = get_parameter(this->active); bool prev_active = get_parameter(this->prev_active); - float time = get_parameter(this->time); - float remaining = get_parameter(this->remaining); - float time_to_restart = get_parameter(this->time_to_restart); + double time = get_parameter(this->time); + double remaining = get_parameter(this->remaining); + double time_to_restart = get_parameter(this->time_to_restart); if (!active) { //make it as if this node doesn't exist, pass input 0 by. @@ -370,9 +370,9 @@ bool AnimationNodeAdd2::has_filter() const { return true; } -float AnimationNodeAdd2::process(float p_time, bool p_seek) { - float amount = get_parameter(add_amount); - float rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); +double AnimationNodeAdd2::process(double p_time, bool p_seek) { + double amount = get_parameter(add_amount); + double rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync); return rem0; @@ -416,10 +416,10 @@ bool AnimationNodeAdd3::has_filter() const { return true; } -float AnimationNodeAdd3::process(float p_time, bool p_seek) { - float amount = get_parameter(add_amount); +double AnimationNodeAdd3::process(double p_time, bool p_seek) { + double amount = get_parameter(add_amount); blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_PASS, !sync); - float rem0 = blend_input(1, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); + double rem0 = blend_input(1, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); blend_input(2, p_time, p_seek, MAX(0, amount), FILTER_PASS, !sync); return rem0; @@ -452,11 +452,11 @@ String AnimationNodeBlend2::get_caption() const { return "Blend2"; } -float AnimationNodeBlend2::process(float p_time, bool p_seek) { - float amount = get_parameter(blend_amount); +double AnimationNodeBlend2::process(double p_time, bool p_seek) { + double amount = get_parameter(blend_amount); - float rem0 = blend_input(0, p_time, p_seek, 1.0 - amount, FILTER_BLEND, !sync); - float rem1 = blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync); + double rem0 = blend_input(0, p_time, p_seek, 1.0 - amount, FILTER_BLEND, !sync); + double rem1 = blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync); return amount > 0.5 ? rem1 : rem0; //hacky but good enough } @@ -507,11 +507,11 @@ bool AnimationNodeBlend3::is_using_sync() const { return sync; } -float AnimationNodeBlend3::process(float p_time, bool p_seek) { - float amount = get_parameter(blend_amount); - float rem0 = blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_IGNORE, !sync); - float rem1 = blend_input(1, p_time, p_seek, 1.0 - ABS(amount), FILTER_IGNORE, !sync); - float rem2 = blend_input(2, p_time, p_seek, MAX(0, amount), FILTER_IGNORE, !sync); +double AnimationNodeBlend3::process(double p_time, bool p_seek) { + double amount = get_parameter(blend_amount); + double rem0 = blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_IGNORE, !sync); + double rem1 = blend_input(1, p_time, p_seek, 1.0 - ABS(amount), FILTER_IGNORE, !sync); + double rem2 = blend_input(2, p_time, p_seek, MAX(0, amount), FILTER_IGNORE, !sync); return amount > 0.5 ? rem2 : (amount < -0.5 ? rem0 : rem1); //hacky but good enough } @@ -545,8 +545,8 @@ String AnimationNodeTimeScale::get_caption() const { return "TimeScale"; } -float AnimationNodeTimeScale::process(float p_time, bool p_seek) { - float scale = get_parameter(this->scale); +double AnimationNodeTimeScale::process(double p_time, bool p_seek) { + double scale = get_parameter(this->scale); if (p_seek) { return blend_input(0, p_time, true, 1.0, FILTER_IGNORE, false); } else { @@ -575,12 +575,12 @@ String AnimationNodeTimeSeek::get_caption() const { return "Seek"; } -float AnimationNodeTimeSeek::process(float p_time, bool p_seek) { - float seek_pos = get_parameter(this->seek_pos); +double AnimationNodeTimeSeek::process(double p_time, bool p_seek) { + double seek_pos = get_parameter(this->seek_pos); if (p_seek) { return blend_input(0, p_time, true, 1.0, FILTER_IGNORE, false); } else if (seek_pos >= 0) { - float ret = blend_input(0, seek_pos, true, 1.0, FILTER_IGNORE, false); + double ret = blend_input(0, seek_pos, true, 1.0, FILTER_IGNORE, false); set_parameter(this->seek_pos, -1.0); //reset return ret; } else { @@ -676,13 +676,13 @@ float AnimationNodeTransition::get_cross_fade_time() const { return xfade; } -float AnimationNodeTransition::process(float p_time, bool p_seek) { +double AnimationNodeTransition::process(double p_time, bool p_seek) { int current = get_parameter(this->current); int prev = get_parameter(this->prev); int prev_current = get_parameter(this->prev_current); - float time = get_parameter(this->time); - float prev_xfading = get_parameter(this->prev_xfading); + double time = get_parameter(this->time); + double prev_xfading = get_parameter(this->prev_xfading); bool switched = current != prev_current; @@ -794,7 +794,7 @@ String AnimationNodeOutput::get_caption() const { return "Output"; } -float AnimationNodeOutput::process(float p_time, bool p_seek) { +double AnimationNodeOutput::process(double p_time, bool p_seek) { return blend_input(0, p_time, p_seek, 1.0); } @@ -1007,7 +1007,7 @@ String AnimationNodeBlendTree::get_caption() const { return "BlendTree"; } -float AnimationNodeBlendTree::process(float p_time, bool p_seek) { +double AnimationNodeBlendTree::process(double p_time, bool p_seek) { Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node; return _blend_node("output", nodes[SceneStringNames::get_singleton()->output].connections, this, output, p_time, p_seek, 1.0); } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index d82658c8c2..8508aaf71b 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -53,7 +53,7 @@ public: static Vector<String> (*get_editable_animation_list)(); virtual String get_caption() const override; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; void set_animation(const StringName &p_name); StringName get_animation() const; @@ -122,7 +122,7 @@ public: bool is_using_sync() const; virtual bool has_filter() const override; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; AnimationNodeOneShot(); }; @@ -148,7 +148,7 @@ public: bool is_using_sync() const; virtual bool has_filter() const override; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; AnimationNodeAdd2(); }; @@ -172,7 +172,7 @@ public: bool is_using_sync() const; virtual bool has_filter() const override; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; AnimationNodeAdd3(); }; @@ -191,7 +191,7 @@ public: virtual Variant get_parameter_default_value(const StringName &p_parameter) const override; virtual String get_caption() const override; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; void set_use_sync(bool p_sync); bool is_using_sync() const; @@ -218,7 +218,7 @@ public: void set_use_sync(bool p_sync); bool is_using_sync() const; - float process(float p_time, bool p_seek) override; + double process(double p_time, bool p_seek) override; AnimationNodeBlend3(); }; @@ -236,7 +236,7 @@ public: virtual String get_caption() const override; - float process(float p_time, bool p_seek) override; + double process(double p_time, bool p_seek) override; AnimationNodeTimeScale(); }; @@ -255,7 +255,7 @@ public: virtual String get_caption() const override; - float process(float p_time, bool p_seek) override; + double process(double p_time, bool p_seek) override; AnimationNodeTimeSeek(); }; @@ -313,7 +313,7 @@ public: void set_cross_fade_time(float p_fade); float get_cross_fade_time() const; - float process(float p_time, bool p_seek) override; + double process(double p_time, bool p_seek) override; AnimationNodeTransition(); }; @@ -323,7 +323,7 @@ class AnimationNodeOutput : public AnimationNode { public: virtual String get_caption() const override; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; AnimationNodeOutput(); }; @@ -390,7 +390,7 @@ public: void get_node_connections(List<NodeConnection> *r_connections) const; virtual String get_caption() const override; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; void get_node_list(List<StringName> *r_list); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index bf53b554bf..9fc1dbd0c6 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -286,7 +286,7 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta return true; } -float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_state_machine, float p_time, bool p_seek) { +double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek) { //if not playing and it can restart, then restart if (!playing && start_request == StringName()) { if (!stop_request && p_state_machine->start_node) { @@ -790,7 +790,7 @@ Vector2 AnimationNodeStateMachine::get_graph_offset() const { return graph_offset; } -float AnimationNodeStateMachine::process(float p_time, bool p_seek) { +double AnimationNodeStateMachine::process(double p_time, bool p_seek) { Ref<AnimationNodeStateMachinePlayback> playback = get_parameter(this->playback); ERR_FAIL_COND_V(playback.is_null(), 0.0); diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index 9c1bca63c3..6f0e3107fd 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -114,7 +114,7 @@ class AnimationNodeStateMachinePlayback : public Resource { bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel); - float process(AnimationNodeStateMachine *p_state_machine, float p_time, bool p_seek); + double process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek); protected: static void _bind_methods(); @@ -210,7 +210,7 @@ public: void set_graph_offset(const Vector2 &p_offset); Vector2 get_graph_offset() const; - virtual float process(float p_time, bool p_seek) override; + virtual double process(double p_time, bool p_seek) override; virtual String get_caption() const override; virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) override; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 67b6205a65..5d200ebf86 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -341,7 +341,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov } } -void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started) { +void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started) { _ensure_node_caches(p_anim); ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count()); @@ -723,7 +723,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float continue; } - float pos = a->track_get_key_time(i, idx); + double pos = a->track_get_key_time(i, idx); StringName anim_name = a->animation_track_get_key_animation(i, idx); if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) { @@ -732,12 +732,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float Ref<Animation> anim = player->get_animation(anim_name); - float at_anim_pos; + double at_anim_pos; if (anim->has_loop()) { - at_anim_pos = Math::fposmod(p_time - pos, anim->get_length()); //seek to loop + at_anim_pos = Math::fposmod(p_time - pos, (double)anim->get_length()); //seek to loop } else { - at_anim_pos = MAX(anim->get_length(), p_time - pos); //seek to end + at_anim_pos = MAX((double)anim->get_length(), p_time - pos); //seek to end } if (player->is_playing() || p_seeked) { @@ -776,11 +776,11 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float } } -void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, bool p_started) { - float delta = p_delta * speed_scale * cd.speed_scale; - float next_pos = cd.pos + delta; +void AnimationPlayer::_animation_process_data(PlaybackData &cd, double p_delta, float p_blend, bool p_seeked, bool p_started) { + double delta = p_delta * speed_scale * cd.speed_scale; + double next_pos = cd.pos + delta; - float len = cd.from->animation->get_length(); + real_t len = cd.from->animation->get_length(); bool loop = cd.from->animation->has_loop(); if (!loop) { @@ -808,7 +808,7 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f } } else { - float looped_next_pos = Math::fposmod(next_pos, len); + double looped_next_pos = Math::fposmod(next_pos, (double)len); if (looped_next_pos == 0 && next_pos != 0) { // Loop multiples of the length to it, rather than 0 // so state at time=length is previewable in the editor @@ -823,7 +823,7 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f _animation_process_animation(cd.from, cd.pos, delta, p_blend, &cd == &playback.current, p_seeked, p_started); } -void AnimationPlayer::_animation_process2(float p_delta, bool p_started) { +void AnimationPlayer::_animation_process2(double p_delta, bool p_started) { Playback &c = playback; accum_pass++; @@ -927,7 +927,7 @@ void AnimationPlayer::_animation_update_transforms() { cache_update_bezier_size = 0; } -void AnimationPlayer::_animation_process(float p_delta) { +void AnimationPlayer::_animation_process(double p_delta) { if (playback.current.from) { end_reached = false; end_notify = false; @@ -1283,7 +1283,7 @@ float AnimationPlayer::get_playing_speed() const { return speed_scale * playback.current.speed_scale; } -void AnimationPlayer::seek(float p_time, bool p_update) { +void AnimationPlayer::seek(double p_time, bool p_update) { if (!playback.current.from) { if (playback.assigned) { ERR_FAIL_COND(!animation_set.has(playback.assigned)); @@ -1299,7 +1299,7 @@ void AnimationPlayer::seek(float p_time, bool p_update) { } } -void AnimationPlayer::seek_delta(float p_time, float p_delta) { +void AnimationPlayer::seek_delta(double p_time, float p_delta) { if (!playback.current.from) { if (playback.assigned) { ERR_FAIL_COND(!animation_set.has(playback.assigned)); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 7cd9de1fa1..b693e29bdf 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -215,13 +215,13 @@ private: NodePath root; - void _animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_is_current = true, bool p_seeked = false, bool p_started = false); + void _animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current = true, bool p_seeked = false, bool p_started = false); void _ensure_node_caches(AnimationData *p_anim, Node *p_root_override = nullptr); - void _animation_process_data(PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, bool p_started); - void _animation_process2(float p_delta, bool p_started); + void _animation_process_data(PlaybackData &cd, double p_delta, float p_blend, bool p_seeked, bool p_started); + void _animation_process2(double p_delta, bool p_started); void _animation_update_transforms(); - void _animation_process(float p_delta); + void _animation_process(double p_delta); void _node_removed(Node *p_node); void _stop_playing_caches(); @@ -306,8 +306,8 @@ public: void set_method_call_mode(AnimationMethodCallMode p_mode); AnimationMethodCallMode get_method_call_mode() const; - void seek(float p_time, bool p_update = false); - void seek_delta(float p_time, float p_delta); + void seek(double p_time, bool p_update = false); + void seek_delta(double p_time, float p_delta); float get_current_animation_position() const; float get_current_animation_length() const; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index e623309888..543545b90f 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -85,7 +85,7 @@ void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) { } } -void AnimationNode::blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend) { +void AnimationNode::blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend) { ERR_FAIL_COND(!state); ERR_FAIL_COND(!state->player->has_animation(p_animation)); @@ -115,13 +115,13 @@ void AnimationNode::blend_animation(const StringName &p_animation, float p_time, state->animation_states.push_back(anim_state); } -float AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections) { +real_t AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, real_t p_time, bool p_seek, const Vector<StringName> &p_connections) { base_path = p_base_path; parent = p_parent; connections = p_connections; state = p_state; - float t = process(p_time, p_seek); + real_t t = process(p_time, p_seek); state = nullptr; parent = nullptr; @@ -140,7 +140,7 @@ void AnimationNode::make_invalid(const String &p_reason) { state->invalid_reasons += String::utf8("• ") + p_reason; } -float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) { +real_t AnimationNode::blend_input(int p_input, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize) { ERR_FAIL_INDEX_V(p_input, inputs.size(), 0); ERR_FAIL_COND_V(!state, 0); @@ -158,8 +158,8 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p Ref<AnimationNode> node = blend_tree->get_node(node_name); //inputs.write[p_input].last_pass = state->last_pass; - float activity = 0.0; - float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity); + real_t activity = 0.0; + real_t ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity); Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path); @@ -170,11 +170,11 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p return ret; } -float AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) { +real_t AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize) { return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_blend, p_filter, p_optimize); } -float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize, float *r_max) { +real_t AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize, real_t *r_max) { ERR_FAIL_COND_V(!p_node.is_valid(), 0); ERR_FAIL_COND_V(!state, 0); @@ -184,8 +184,8 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin p_node->blends.resize(blend_count); } - float *blendw = p_node->blends.ptrw(); - const float *blendr = blends.ptr(); + real_t *blendw = p_node->blends.ptrw(); + const real_t *blendr = blends.ptr(); bool any_valid = false; @@ -328,7 +328,7 @@ void AnimationNode::remove_input(int p_index) { emit_changed(); } -float AnimationNode::process(float p_time, bool p_seek) { +double AnimationNode::process(double p_time, bool p_seek) { if (get_script_instance()) { return get_script_instance()->call("_process", p_time, p_seek); } @@ -718,7 +718,7 @@ void AnimationTree::_clear_caches() { cache_valid = false; } -void AnimationTree::_process_graph(float p_delta) { +void AnimationTree::_process_graph(real_t p_delta) { _update_properties(); //if properties need updating, update them //check all tracks, see if they need modification @@ -790,7 +790,7 @@ void AnimationTree::_process_graph(float p_delta) { // root source blends root->blends.resize(state.track_count); - float *src_blendsw = root->blends.ptrw(); + real_t *src_blendsw = root->blends.ptrw(); for (int i = 0; i < state.track_count; i++) { src_blendsw[i] = 1.0; //by default all go to 1 for the root input } @@ -818,9 +818,9 @@ void AnimationTree::_process_graph(float p_delta) { for (const AnimationNode::AnimationState &as : state.animation_states) { Ref<Animation> a = as.animation; - float time = as.time; - float delta = as.delta; - float weight = as.blend; + double time = as.time; + double delta = as.delta; + real_t weight = as.blend; bool seeked = as.seeked; for (int i = 0; i < a->get_track_count(); i++) { @@ -840,7 +840,7 @@ void AnimationTree::_process_graph(float p_delta) { ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count); - float blend = (*as.track_blends)[blend_idx] * weight; + real_t blend = (*as.track_blends)[blend_idx] * weight; if (blend < CMP_EPSILON) { continue; //nothing to blend @@ -860,7 +860,7 @@ void AnimationTree::_process_graph(float p_delta) { t->scale = Vector3(1, 1, 1); } - float prev_time = time - delta; + real_t prev_time = time - delta; if (prev_time < 0) { if (!a->has_loop()) { prev_time = 0; @@ -928,7 +928,7 @@ void AnimationTree::_process_graph(float p_delta) { t->rot = rot; t->rot_blend_accum = blend; } else { - float rot_total = t->rot_blend_accum + blend; + real_t rot_total = t->rot_blend_accum + blend; t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized(); t->rot_blend_accum = rot_total; } @@ -1003,7 +1003,7 @@ void AnimationTree::_process_graph(float p_delta) { case Animation::TYPE_BEZIER: { TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track); - float bezier = a->bezier_track_interpolate(i, time); + real_t bezier = a->bezier_track_interpolate(i, time); if (t->process_pass != process_pass) { t->value = bezier; @@ -1029,10 +1029,10 @@ void AnimationTree::_process_graph(float p_delta) { t->playing = false; playing_caches.erase(t); } else { - float start_ofs = a->audio_track_get_key_start_offset(i, idx); + real_t start_ofs = a->audio_track_get_key_start_offset(i, idx); start_ofs += time - a->track_get_key_time(i, idx); - float end_ofs = a->audio_track_get_key_end_offset(i, idx); - float len = stream->get_length(); + real_t end_ofs = a->audio_track_get_key_end_offset(i, idx); + real_t len = stream->get_length(); if (start_ofs > len - end_ofs) { t->object->call("stop"); @@ -1068,9 +1068,9 @@ void AnimationTree::_process_graph(float p_delta) { t->playing = false; playing_caches.erase(t); } else { - float start_ofs = a->audio_track_get_key_start_offset(i, idx); - float end_ofs = a->audio_track_get_key_end_offset(i, idx); - float len = stream->get_length(); + real_t start_ofs = a->audio_track_get_key_start_offset(i, idx); + real_t end_ofs = a->audio_track_get_key_end_offset(i, idx); + real_t len = stream->get_length(); t->object->call("set_stream", stream); t->object->call("play", start_ofs); @@ -1093,7 +1093,7 @@ void AnimationTree::_process_graph(float p_delta) { if (!loop && time < t->start) { stop = true; } else if (t->len > 0) { - float len = t->start > time ? (a->get_length() - t->start) + time : time - t->start; + real_t len = t->start > time ? (a->get_length() - t->start) + time : time - t->start; if (len > t->len) { stop = true; @@ -1109,7 +1109,7 @@ void AnimationTree::_process_graph(float p_delta) { } } - float db = Math::linear2db(MAX(blend, 0.00001)); + real_t db = Math::linear2db(MAX(blend, 0.00001)); if (t->object->has_method("set_unit_db")) { t->object->call("set_unit_db", db); } else { @@ -1132,7 +1132,7 @@ void AnimationTree::_process_graph(float p_delta) { continue; } - float pos = a->track_get_key_time(i, idx); + double pos = a->track_get_key_time(i, idx); StringName anim_name = a->animation_track_get_key_animation(i, idx); if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) { @@ -1141,10 +1141,10 @@ void AnimationTree::_process_graph(float p_delta) { Ref<Animation> anim = player2->get_animation(anim_name); - float at_anim_pos; + real_t at_anim_pos; if (anim->has_loop()) { - at_anim_pos = Math::fposmod(time - pos, anim->get_length()); //seek to loop + at_anim_pos = Math::fposmod(time - pos, (double)anim->get_length()); //seek to loop } else { at_anim_pos = MAX(anim->get_length(), time - pos); //seek to end } @@ -1238,7 +1238,7 @@ void AnimationTree::_process_graph(float p_delta) { } } -void AnimationTree::advance(float p_time) { +void AnimationTree::advance(real_t p_time) { _process_graph(p_time); } @@ -1443,7 +1443,7 @@ void AnimationTree::rename_parameter(const String &p_base, const String &p_new_b _update_properties(); } -float AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const { +real_t AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const { if (!input_activity_map_get.has(p_path)) { return 0; } diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 60e0c7200a..59bbc5b4da 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -57,16 +57,16 @@ public: Vector<Input> inputs; - float process_input(int p_input, float p_time, bool p_seek, float p_blend); + real_t process_input(int p_input, real_t p_time, bool p_seek, real_t p_blend); friend class AnimationTree; struct AnimationState { Ref<Animation> animation; - float time = 0.0; - float delta = 0.0; - const Vector<float> *track_blends = nullptr; - float blend = 0.0; + double time = 0.0; + double delta = 0.0; + const Vector<real_t> *track_blends = nullptr; + real_t blend = 0.0; bool seeked = false; }; @@ -81,10 +81,10 @@ public: uint64_t last_pass = 0; }; - Vector<float> blends; + Vector<real_t> blends; State *state = nullptr; - float _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections); + real_t _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, real_t p_time, bool p_seek, const Vector<StringName> &p_connections); void _pre_update_animations(HashMap<NodePath, int> *track_map); //all this is temporary @@ -98,12 +98,12 @@ public: Array _get_filters() const; void _set_filters(const Array &p_filters); friend class AnimationNodeBlendTree; - float _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, float *r_max = nullptr); + real_t _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, real_t *r_max = nullptr); protected: - void blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend); - float blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true); - float blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true); + void blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend); + real_t blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true); + real_t blend_input(int p_input, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true); void make_invalid(const String &p_reason); static void _bind_methods(); @@ -126,7 +126,7 @@ public: virtual void get_child_nodes(List<ChildNode> *r_child_nodes); - virtual float process(float p_time, bool p_seek); + virtual double process(double p_time, bool p_seek); virtual String get_caption() const; int get_input_count() const; @@ -191,7 +191,7 @@ private: int bone_idx = -1; Vector3 loc; Quaternion rot; - float rot_blend_accum = 0.0; + real_t rot_blend_accum = 0.0; Vector3 scale; TrackCacheTransform() { @@ -210,7 +210,7 @@ private: }; struct TrackCacheBezier : public TrackCache { - float value = 0.0; + real_t value = 0.0; Vector<StringName> subpath; TrackCacheBezier() { type = Animation::TYPE_BEZIER; @@ -219,8 +219,8 @@ private: struct TrackCacheAudio : public TrackCache { bool playing = false; - float start = 0.0; - float len = 0.0; + real_t start = 0.0; + real_t len = 0.0; TrackCacheAudio() { type = Animation::TYPE_AUDIO; @@ -251,7 +251,7 @@ private: void _clear_caches(); bool _update_caches(AnimationPlayer *player); - void _process_graph(float p_delta); + void _process_graph(real_t p_delta); uint64_t setup_pass = 1; uint64_t process_pass = 1; @@ -271,7 +271,7 @@ private: struct Activity { uint64_t last_pass = 0; - float activity = 0.0; + real_t activity = 0.0; }; HashMap<StringName, Vector<Activity>> input_activity_map; @@ -312,8 +312,8 @@ public: Transform3D get_root_motion_transform() const; - float get_connection_activity(const StringName &p_path, int p_connection) const; - void advance(float p_time); + real_t get_connection_activity(const StringName &p_path, int p_connection) const; + void advance(real_t p_time); void rename_parameter(const String &p_base, const String &p_new_base); diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index 55fd2d2b73..d64c8bc675 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -39,8 +39,8 @@ class RootMotionView : public VisualInstance3D { public: Ref<ImmediateMesh> immediate; NodePath path; - float cell_size = 1.0; - float radius = 10.0; + real_t cell_size = 1.0; + real_t radius = 10.0; bool use_in_game = false; Color color = Color(0.5, 0.5, 1.0); bool first = true; diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index ce2b320c96..869f2f68f7 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -94,7 +94,7 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra } else if (p_msg == "override_camera_3D:set") { ERR_FAIL_COND_V(p_args.size() < 1, ERR_INVALID_DATA); bool enable = p_args[0]; - scene_tree->get_root()->enable_camera_override(enable); + scene_tree->get_root()->enable_camera_3d_override(enable); } else if (p_msg == "override_camera_3D:transform") { ERR_FAIL_COND_V(p_args.size() < 5, ERR_INVALID_DATA); @@ -104,11 +104,11 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra float near = p_args[3]; float far = p_args[4]; if (is_perspective) { - scene_tree->get_root()->set_camera_override_perspective(size_or_fov, near, far); + scene_tree->get_root()->set_camera_3d_override_perspective(size_or_fov, near, far); } else { - scene_tree->get_root()->set_camera_override_orthogonal(size_or_fov, near, far); + scene_tree->get_root()->set_camera_3d_override_orthogonal(size_or_fov, near, far); } - scene_tree->get_root()->set_camera_override_transform(transform); + scene_tree->get_root()->set_camera_3d_override_transform(transform); } else if (p_msg == "set_object_property") { ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 82f4a216b8..871ad889ca 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -145,6 +145,9 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) { if (status.press_attempt && status.pressing_inside) { if (toggle_mode) { + if (Object::cast_to<InputEventShortcut>(*p_event)) { + action_mode = ACTION_MODE_BUTTON_PRESS; // HACK. + } if ((p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_PRESS) || (!p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_RELEASE)) { if (action_mode == ACTION_MODE_BUTTON_PRESS) { status.press_attempt = false; diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index 706d3b48c2..635f3c51b9 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -308,7 +308,7 @@ void GradientEdit::_notification(int p_what) { int total_w = get_size().width - get_size().height - SPACING; //Draw checker pattern for ramp - draw_texture_rect(get_theme_icon("GuiMiniCheckerboard", "EditorIcons"), Rect2(0, 0, total_w, h), true); + draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(0, 0, total_w, h), true); //Draw color ramp Gradient::Point prev; @@ -375,7 +375,7 @@ void GradientEdit::_notification(int p_what) { } //Draw "button" for color selector - draw_texture_rect(get_theme_icon("GuiMiniCheckerboard", "EditorIcons"), Rect2(total_w + SPACING, 0, h, h), true); + draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(total_w + SPACING, 0, h, h), true); if (grabbed != -1) { //Draw with selection color draw_rect(Rect2(total_w + SPACING, 0, h, h), points[grabbed].color); @@ -415,7 +415,7 @@ void GradientEdit::_color_changed(const Color &p_color) { emit_signal(SNAME("ramp_changed")); } -void GradientEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) { +void GradientEdit::set_ramp(const Vector<real_t> &p_offsets, const Vector<Color> &p_colors) { ERR_FAIL_COND(p_offsets.size() != p_colors.size()); points.clear(); for (int i = 0; i < p_offsets.size(); i++) { @@ -429,8 +429,8 @@ void GradientEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> update(); } -Vector<float> GradientEdit::get_offsets() const { - Vector<float> ret; +Vector<real_t> GradientEdit::get_offsets() const { + Vector<real_t> ret; for (int i = 0; i < points.size(); i++) { ret.push_back(points[i].offset); } diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index 3d83a02429..b0ee2c4abb 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -57,8 +57,8 @@ protected: static void _bind_methods(); public: - void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors); - Vector<float> get_offsets() const; + void set_ramp(const Vector<real_t> &p_offsets, const Vector<Color> &p_colors); + Vector<real_t> get_offsets() const; Vector<Color> get_colors() const; void set_points(Vector<Gradient::Point> &p_points); Vector<Gradient::Point> &get_points(); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 1fac2b9129..cdb8f7046b 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -450,6 +450,7 @@ void GraphEdit::_notification(int p_what) { zoom_plus->set_icon(get_theme_icon(SNAME("more"))); snap_button->set_icon(get_theme_icon(SNAME("snap"))); minimap_button->set_icon(get_theme_icon(SNAME("minimap"))); + layout_button->set_icon(get_theme_icon(SNAME("layout"))); } if (p_what == NOTIFICATION_READY) { Size2 hmin = h_scroll->get_combined_minimum_size(); @@ -1646,6 +1647,500 @@ HBoxContainer *GraphEdit::get_zoom_hbox() { return zoom_hb; } +int GraphEdit::_set_operations(SET_OPERATIONS p_operation, Set<StringName> &r_u, const Set<StringName> &r_v) { + switch (p_operation) { + case GraphEdit::IS_EQUAL: { + for (Set<StringName>::Element *E = r_u.front(); E; E = E->next()) { + if (!r_v.has(E->get())) + return 0; + } + return r_u.size() == r_v.size(); + } break; + case GraphEdit::IS_SUBSET: { + if (r_u.size() == r_v.size() && !r_u.size()) { + return 1; + } + for (Set<StringName>::Element *E = r_u.front(); E; E = E->next()) { + if (!r_v.has(E->get())) + return 0; + } + return 1; + } break; + case GraphEdit::DIFFERENCE: { + for (Set<StringName>::Element *E = r_u.front(); E; E = E->next()) { + if (r_v.has(E->get())) { + r_u.erase(E->get()); + } + } + return r_u.size(); + } break; + case GraphEdit::UNION: { + for (Set<StringName>::Element *E = r_v.front(); E; E = E->next()) { + if (!r_u.has(E->get())) { + r_u.insert(E->get()); + } + } + return r_v.size(); + } break; + default: + break; + } + return -1; +} + +HashMap<int, Vector<StringName>> GraphEdit::_layering(const Set<StringName> &r_selected_nodes, const HashMap<StringName, Set<StringName>> &r_upper_neighbours) { + HashMap<int, Vector<StringName>> l; + + Set<StringName> p = r_selected_nodes, q = r_selected_nodes, u, z; + int current_layer = 0; + bool selected = false; + + while (!_set_operations(GraphEdit::IS_EQUAL, q, u)) { + _set_operations(GraphEdit::DIFFERENCE, p, u); + for (const Set<StringName>::Element *E = p.front(); E; E = E->next()) { + Set<StringName> n = r_upper_neighbours[E->get()]; + if (_set_operations(GraphEdit::IS_SUBSET, n, z)) { + Vector<StringName> t; + t.push_back(E->get()); + if (!l.has(current_layer)) { + l.set(current_layer, Vector<StringName>{}); + } + selected = true; + t.append_array(l[current_layer]); + l.set(current_layer, t); + Set<StringName> V; + V.insert(E->get()); + _set_operations(GraphEdit::UNION, u, V); + } + } + if (!selected) { + current_layer++; + _set_operations(GraphEdit::UNION, z, u); + } + selected = false; + } + + return l; +} + +Vector<StringName> GraphEdit::_split(const Vector<StringName> &r_layer, const HashMap<StringName, Dictionary> &r_crossings) { + if (!r_layer.size()) { + return Vector<StringName>(); + } + + StringName p = r_layer[Math::random(0, r_layer.size() - 1)]; + Vector<StringName> left; + Vector<StringName> right; + + for (int i = 0; i < r_layer.size(); i++) { + if (p != r_layer[i]) { + StringName q = r_layer[i]; + int cross_pq = r_crossings[p][q]; + int cross_qp = r_crossings[q][p]; + if (cross_pq > cross_qp) { + left.push_back(q); + } else { + right.push_back(q); + } + } + } + + left.push_back(p); + left.append_array(right); + return left; +} + +void GraphEdit::_horizontal_alignment(Dictionary &r_root, Dictionary &r_align, const HashMap<int, Vector<StringName>> &r_layers, const HashMap<StringName, Set<StringName>> &r_upper_neighbours, const Set<StringName> &r_selected_nodes) { + for (const Set<StringName>::Element *E = r_selected_nodes.front(); E; E = E->next()) { + r_root[E->get()] = E->get(); + r_align[E->get()] = E->get(); + } + + if (r_layers.size() == 1) { + return; + } + + for (unsigned int i = 1; i < r_layers.size(); i++) { + Vector<StringName> lower_layer = r_layers[i]; + Vector<StringName> upper_layer = r_layers[i - 1]; + int r = -1; + + for (int j = 0; j < lower_layer.size(); j++) { + Vector<Pair<int, StringName>> up; + StringName current_node = lower_layer[j]; + for (int k = 0; k < upper_layer.size(); k++) { + StringName adjacent_neighbour = upper_layer[k]; + if (r_upper_neighbours[current_node].has(adjacent_neighbour)) { + up.push_back(Pair<int, StringName>(k, adjacent_neighbour)); + } + } + + int start = up.size() / 2; + int end = up.size() % 2 ? start : start + 1; + for (int p = start; p <= end; p++) { + StringName Align = r_align[current_node]; + if (Align == current_node && r < up[p].first) { + r_align[up[p].second] = lower_layer[j]; + r_root[current_node] = r_root[up[p].second]; + r_align[current_node] = r_root[up[p].second]; + r = up[p].first; + } + } + } + } +} + +void GraphEdit::_crossing_minimisation(HashMap<int, Vector<StringName>> &r_layers, const HashMap<StringName, Set<StringName>> &r_upper_neighbours) { + if (r_layers.size() == 1) { + return; + } + + for (unsigned int i = 1; i < r_layers.size(); i++) { + Vector<StringName> upper_layer = r_layers[i - 1]; + Vector<StringName> lower_layer = r_layers[i]; + HashMap<StringName, Dictionary> c; + + for (int j = 0; j < lower_layer.size(); j++) { + StringName p = lower_layer[j]; + Dictionary d; + + for (int k = 0; k < lower_layer.size(); k++) { + unsigned int crossings = 0; + StringName q = lower_layer[k]; + + if (j != k) { + for (int h = 1; h < upper_layer.size(); h++) { + if (r_upper_neighbours[p].has(upper_layer[h])) { + for (int g = 0; g < h; g++) { + if (r_upper_neighbours[q].has(upper_layer[g])) { + crossings++; + } + } + } + } + } + d[q] = crossings; + } + c.set(p, d); + } + + r_layers.set(i, _split(lower_layer, c)); + } +} + +void GraphEdit::_calculate_inner_shifts(Dictionary &r_inner_shifts, const Dictionary &r_root, const Dictionary &r_node_names, const Dictionary &r_align, const Set<StringName> &r_block_heads, const HashMap<StringName, Pair<int, int>> &r_port_info) { + for (const Set<StringName>::Element *E = r_block_heads.front(); E; E = E->next()) { + real_t left = 0; + StringName u = E->get(); + StringName v = r_align[u]; + while (u != v && (StringName)r_root[u] != v) { + String _connection = String(u) + " " + String(v); + GraphNode *gfrom = Object::cast_to<GraphNode>(r_node_names[u]); + GraphNode *gto = Object::cast_to<GraphNode>(r_node_names[v]); + + Pair<int, int> ports = r_port_info[_connection]; + int pfrom = ports.first; + int pto = ports.second; + Vector2 frompos = gfrom->get_connection_output_position(pfrom); + Vector2 topos = gto->get_connection_input_position(pto); + + real_t s = (real_t)r_inner_shifts[u] + (frompos.y - topos.y) / zoom; + r_inner_shifts[v] = s; + left = MIN(left, s); + + u = v; + v = (StringName)r_align[v]; + } + + u = E->get(); + do { + r_inner_shifts[u] = (real_t)r_inner_shifts[u] - left; + u = (StringName)r_align[u]; + } while (u != E->get()); + } +} + +float GraphEdit::_calculate_threshold(StringName p_v, StringName p_w, const Dictionary &r_node_names, const HashMap<int, Vector<StringName>> &r_layers, const Dictionary &r_root, const Dictionary &r_align, const Dictionary &r_inner_shift, real_t p_current_threshold, const HashMap<StringName, Vector2> &r_node_positions) { +#define MAX_ORDER 2147483647 +#define ORDER(node, layers) \ + for (unsigned int i = 0; i < layers.size(); i++) { \ + int index = layers[i].find(node); \ + if (index > 0) { \ + order = index; \ + break; \ + } \ + order = MAX_ORDER; \ + } + + int order = MAX_ORDER; + float threshold = p_current_threshold; + if (p_v == p_w) { + int min_order = MAX_ORDER; + Connection incoming; + for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { + if (E->get().to == p_w) { + ORDER(E->get().from, r_layers); + if (min_order > order) { + min_order = order; + incoming = E->get(); + } + } + } + + if (incoming.from != StringName()) { + GraphNode *gfrom = Object::cast_to<GraphNode>(r_node_names[incoming.from]); + GraphNode *gto = Object::cast_to<GraphNode>(r_node_names[p_w]); + Vector2 frompos = gfrom->get_connection_output_position(incoming.from_port); + Vector2 topos = gto->get_connection_input_position(incoming.to_port); + + //If connected block node is selected, calculate thershold or add current block to list + if (gfrom->is_selected()) { + Vector2 connected_block_pos = r_node_positions[r_root[incoming.from]]; + if (connected_block_pos.y != FLT_MAX) { + //Connected block is placed. Calculate threshold + threshold = connected_block_pos.y + (real_t)r_inner_shift[incoming.from] - (real_t)r_inner_shift[p_w] + frompos.y - topos.y; + } + } + } + } + if (threshold == FLT_MIN && (StringName)r_align[p_w] == p_v) { + //This time, pick an outgoing edge and repeat as above! + int min_order = MAX_ORDER; + Connection outgoing; + for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { + if (E->get().from == p_w) { + ORDER(E->get().to, r_layers); + if (min_order > order) { + min_order = order; + outgoing = E->get(); + } + } + } + + if (outgoing.to != StringName()) { + GraphNode *gfrom = Object::cast_to<GraphNode>(r_node_names[p_w]); + GraphNode *gto = Object::cast_to<GraphNode>(r_node_names[outgoing.to]); + Vector2 frompos = gfrom->get_connection_output_position(outgoing.from_port); + Vector2 topos = gto->get_connection_input_position(outgoing.to_port); + + //If connected block node is selected, calculate thershold or add current block to list + if (gto->is_selected()) { + Vector2 connected_block_pos = r_node_positions[r_root[outgoing.to]]; + if (connected_block_pos.y != FLT_MAX) { + //Connected block is placed. Calculate threshold + threshold = connected_block_pos.y + (real_t)r_inner_shift[outgoing.to] - (real_t)r_inner_shift[p_w] + frompos.y - topos.y; + } + } + } + } +#undef MAX_ORDER +#undef ORDER + return threshold; +} + +void GraphEdit::_place_block(StringName p_v, float p_delta, const HashMap<int, Vector<StringName>> &r_layers, const Dictionary &r_root, const Dictionary &r_align, const Dictionary &r_node_name, const Dictionary &r_inner_shift, Dictionary &r_sink, Dictionary &r_shift, HashMap<StringName, Vector2> &r_node_positions) { +#define PRED(node, layers) \ + for (unsigned int i = 0; i < layers.size(); i++) { \ + int index = layers[i].find(node); \ + if (index > 0) { \ + predecessor = layers[i][index - 1]; \ + break; \ + } \ + predecessor = StringName(); \ + } + + StringName predecessor; + StringName successor; + Vector2 pos = r_node_positions[p_v]; + + if (pos.y == FLT_MAX) { + pos.y = 0; + bool initial = false; + StringName w = p_v; + real_t threshold = FLT_MIN; + do { + PRED(w, r_layers); + if (predecessor != StringName()) { + StringName u = r_root[predecessor]; + _place_block(u, p_delta, r_layers, r_root, r_align, r_node_name, r_inner_shift, r_sink, r_shift, r_node_positions); + threshold = _calculate_threshold(p_v, w, r_node_name, r_layers, r_root, r_align, r_inner_shift, threshold, r_node_positions); + if ((StringName)r_sink[p_v] == p_v) { + r_sink[p_v] = r_sink[u]; + } + + Vector2 predecessor_root_pos = r_node_positions[u]; + Vector2 predecessor_node_size = Object::cast_to<GraphNode>(r_node_name[predecessor])->get_size(); + if (r_sink[p_v] != r_sink[u]) { + real_t sc = pos.y + (real_t)r_inner_shift[w] - predecessor_root_pos.y - (real_t)r_inner_shift[predecessor] - predecessor_node_size.y - p_delta; + r_shift[r_sink[u]] = MIN(sc, (real_t)r_shift[r_sink[u]]); + } else { + real_t sb = predecessor_root_pos.y + (real_t)r_inner_shift[predecessor] + predecessor_node_size.y - (real_t)r_inner_shift[w] + p_delta; + sb = MAX(sb, threshold); + if (initial) { + pos.y = sb; + } else { + pos.y = MAX(pos.y, sb); + } + initial = false; + } + } + threshold = _calculate_threshold(p_v, w, r_node_name, r_layers, r_root, r_align, r_inner_shift, threshold, r_node_positions); + w = r_align[w]; + } while (w != p_v); + r_node_positions.set(p_v, pos); + } + +#undef PRED +} + +void GraphEdit::arrange_nodes() { + if (!arranging_graph) { + arranging_graph = true; + } else { + return; + } + + Dictionary node_names; + Set<StringName> selected_nodes; + + for (int i = get_child_count() - 1; i >= 0; i--) { + GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); + if (!gn) { + continue; + } + + node_names[gn->get_name()] = gn; + } + + HashMap<StringName, Set<StringName>> upper_neighbours; + HashMap<StringName, Pair<int, int>> port_info; + Vector2 origin(FLT_MAX, FLT_MAX); + + float gap_v = 100.0f; + float gap_h = 100.0f; + + for (int i = get_child_count() - 1; i >= 0; i--) { + GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); + if (!gn) { + continue; + } + + if (gn->is_selected()) { + selected_nodes.insert(gn->get_name()); + origin = origin < gn->get_position_offset() ? origin : gn->get_position_offset(); + Set<StringName> s; + for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { + GraphNode *p_from = Object::cast_to<GraphNode>(node_names[E->get().from]); + if (E->get().to == gn->get_name() && p_from->is_selected()) { + if (!s.has(p_from->get_name())) { + s.insert(p_from->get_name()); + } + String s_connection = String(p_from->get_name()) + " " + String(E->get().to); + StringName _connection(s_connection); + Pair<int, int> ports(E->get().from_port, E->get().to_port); + if (port_info.has(_connection)) { + Pair<int, int> p_ports = port_info[_connection]; + if (p_ports.first < ports.first) { + ports = p_ports; + } + } + port_info.set(_connection, ports); + } + } + upper_neighbours.set(gn->get_name(), s); + } + } + + HashMap<int, Vector<StringName>> layers = _layering(selected_nodes, upper_neighbours); + _crossing_minimisation(layers, upper_neighbours); + + Dictionary root, align, sink, shift; + _horizontal_alignment(root, align, layers, upper_neighbours, selected_nodes); + + HashMap<StringName, Vector2> new_positions; + Vector2 default_position(FLT_MAX, FLT_MAX); + Dictionary inner_shift; + Set<StringName> block_heads; + + for (const Set<StringName>::Element *E = selected_nodes.front(); E; E = E->next()) { + inner_shift[E->get()] = 0.0f; + sink[E->get()] = E->get(); + shift[E->get()] = FLT_MAX; + new_positions.set(E->get(), default_position); + if ((StringName)root[E->get()] == E->get()) { + block_heads.insert(E->get()); + } + } + + _calculate_inner_shifts(inner_shift, root, node_names, align, block_heads, port_info); + + for (const Set<StringName>::Element *E = block_heads.front(); E; E = E->next()) { + _place_block(E->get(), gap_v, layers, root, align, node_names, inner_shift, sink, shift, new_positions); + } + + for (const Set<StringName>::Element *E = block_heads.front(); E; E = E->next()) { + StringName u = E->get(); + StringName prev = u; + float start_from = origin.y + new_positions[E->get()].y; + do { + Vector2 cal_pos; + cal_pos.y = start_from + (real_t)inner_shift[u]; + new_positions.set(u, cal_pos); + prev = u; + u = align[u]; + } while (u != E->get()); + } + + //Compute horizontal co-ordinates individually for layers to get uniform gap + float start_from = origin.x; + float largest_node_size = 0.0f; + + for (unsigned int i = 0; i < layers.size(); i++) { + Vector<StringName> layer = layers[i]; + for (int j = 0; j < layer.size(); j++) { + float current_node_size = Object::cast_to<GraphNode>(node_names[layer[j]])->get_size().x; + largest_node_size = MAX(largest_node_size, current_node_size); + } + + for (int j = 0; j < layer.size(); j++) { + float current_node_size = Object::cast_to<GraphNode>(node_names[layer[j]])->get_size().x; + Vector2 cal_pos = new_positions[layer[j]]; + + if (current_node_size == largest_node_size) { + cal_pos.x = start_from; + } else { + float current_node_start_pos; + if (current_node_size >= largest_node_size / 2) { + current_node_start_pos = start_from; + } else { + current_node_start_pos = start_from + largest_node_size - current_node_size; + } + cal_pos.x = current_node_start_pos; + } + new_positions.set(layer[j], cal_pos); + } + + start_from += largest_node_size + gap_h; + largest_node_size = 0.0f; + } + + emit_signal("begin_node_move"); + for (const Set<StringName>::Element *E = selected_nodes.front(); E; E = E->next()) { + GraphNode *gn = Object::cast_to<GraphNode>(node_names[E->get()]); + gn->set_drag(true); + Vector2 pos = (new_positions[E->get()]); + + if (is_using_snap()) { + const int snap = get_snap(); + pos = pos.snapped(Vector2(snap, snap)); + } + gn->set_position_offset(pos); + gn->set_drag(false); + } + emit_signal("end_node_move"); + arranging_graph = false; +} + void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("connect_node", "from", "from_port", "to", "to_port"), &GraphEdit::connect_node); ClassDB::bind_method(D_METHOD("is_node_connected", "from", "from_port", "to", "to_port"), &GraphEdit::is_node_connected); @@ -1707,6 +2202,8 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_zoom_hbox"), &GraphEdit::get_zoom_hbox); + ClassDB::bind_method(D_METHOD("arrange_nodes"), &GraphEdit::arrange_nodes); + ClassDB::bind_method(D_METHOD("set_selected", "node"), &GraphEdit::set_selected); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "right_disconnects"), "set_right_disconnects", "is_right_disconnects_enabled"); @@ -1851,6 +2348,13 @@ GraphEdit::GraphEdit() { minimap_button->set_focus_mode(FOCUS_NONE); zoom_hb->add_child(minimap_button); + layout_button = memnew(Button); + layout_button->set_flat(true); + zoom_hb->add_child(layout_button); + layout_button->set_tooltip(RTR("Arrange nodes.")); + layout_button->connect("pressed", callable_mp(this, &GraphEdit::arrange_nodes)); + layout_button->set_focus_mode(FOCUS_NONE); + Vector2 minimap_size = Vector2(240, 160); float minimap_opacity = 0.65; diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 5251de1722..aeb35f2e02 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -116,6 +116,8 @@ private: Button *minimap_button; + Button *layout_button; + HScrollBar *h_scroll; VScrollBar *v_scroll; @@ -230,6 +232,24 @@ private: bool _check_clickable_control(Control *p_control, const Vector2 &pos); + bool arranging_graph = false; + + enum SET_OPERATIONS { + IS_EQUAL, + IS_SUBSET, + DIFFERENCE, + UNION, + }; + + int _set_operations(SET_OPERATIONS p_operation, Set<StringName> &r_u, const Set<StringName> &r_v); + HashMap<int, Vector<StringName>> _layering(const Set<StringName> &r_selected_nodes, const HashMap<StringName, Set<StringName>> &r_upper_neighbours); + Vector<StringName> _split(const Vector<StringName> &r_layer, const HashMap<StringName, Dictionary> &r_crossings); + void _horizontal_alignment(Dictionary &r_root, Dictionary &r_align, const HashMap<int, Vector<StringName>> &r_layers, const HashMap<StringName, Set<StringName>> &r_upper_neighbours, const Set<StringName> &r_selected_nodes); + void _crossing_minimisation(HashMap<int, Vector<StringName>> &r_layers, const HashMap<StringName, Set<StringName>> &r_upper_neighbours); + void _calculate_inner_shifts(Dictionary &r_inner_shifts, const Dictionary &r_root, const Dictionary &r_node_names, const Dictionary &r_align, const Set<StringName> &r_block_heads, const HashMap<StringName, Pair<int, int>> &r_port_info); + float _calculate_threshold(StringName p_v, StringName p_w, const Dictionary &r_node_names, const HashMap<int, Vector<StringName>> &r_layers, const Dictionary &r_root, const Dictionary &r_align, const Dictionary &r_inner_shift, real_t p_current_threshold, const HashMap<StringName, Vector2> &r_node_positions); + void _place_block(StringName p_v, float p_delta, const HashMap<int, Vector<StringName>> &r_layers, const Dictionary &r_root, const Dictionary &r_align, const Dictionary &r_node_name, const Dictionary &r_inner_shift, Dictionary &r_sink, Dictionary &r_shift, HashMap<StringName, Vector2> &r_node_positions); + protected: static void _bind_methods(); virtual void add_child_notify(Node *p_child) override; @@ -304,6 +324,8 @@ public: HBoxContainer *get_zoom_hbox(); + void arrange_nodes(); + GraphEdit(); }; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index cf1f41d0fc..63b5793b3e 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -44,7 +44,7 @@ void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) { return; } - if (p_event->is_pressed() && !p_event->is_echo() && (Object::cast_to<InputEventKey>(p_event.ptr()) || Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventAction>(*p_event))) { + if (p_event->is_pressed() && !p_event->is_echo() && (Object::cast_to<InputEventKey>(p_event.ptr()) || Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventAction>(*p_event) || Object::cast_to<InputEventShortcut>(*p_event))) { if (!get_parent() || !is_visible_in_tree() || is_disabled()) { return; } diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h index d809fd502f..67323e7f93 100644 --- a/scene/gui/rich_text_effect.h +++ b/scene/gui/rich_text_effect.h @@ -59,7 +59,7 @@ public: bool outline = false; Point2 offset; Color color; - float elapsed_time = 0.0f; + double elapsed_time = 0.0f; Dictionary environment; uint32_t glpyh_index = 0; RID font; @@ -69,8 +69,8 @@ public: Vector2i get_range() { return range; } void set_range(const Vector2i &p_range) { range = p_range; } - float get_elapsed_time() { return elapsed_time; } - void set_elapsed_time(float p_elapsed_time) { elapsed_time = p_elapsed_time; } + double get_elapsed_time() { return elapsed_time; } + void set_elapsed_time(double p_elapsed_time) { elapsed_time = p_elapsed_time; } bool is_visible() { return visibility; } void set_visibility(bool p_visibility) { visibility = p_visibility; } bool is_outline() { return outline; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 3cb1f7d2bc..cf2a1481a1 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1323,7 +1323,7 @@ void RichTextLabel::_update_scroll() { } } -void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, float p_delta_time) { +void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, double p_delta_time) { Item *it = p_frame; while (it) { ItemFX *ifx = nullptr; @@ -1441,7 +1441,7 @@ void RichTextLabel::_notification(int p_what) { } break; case NOTIFICATION_INTERNAL_PROCESS: { if (is_visible_in_tree()) { - float dt = get_process_delta_time(); + double dt = get_process_delta_time(); _update_fx(main, dt); update(); } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index a73176ba7e..28dfe74b08 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -260,7 +260,7 @@ private: }; struct ItemFX : public Item { - float elapsed_time = 0.f; + double elapsed_time = 0.f; }; struct ItemShake : public ItemFX { @@ -440,7 +440,7 @@ private: void _fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack); void _update_scroll(); - void _update_fx(ItemFrame *p_frame, float p_delta_time); + void _update_fx(ItemFrame *p_frame, double p_delta_time); void _scroll_changed(double); void _gui_input(Ref<InputEvent> p_event); diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp index 885a51e058..1c29870682 100644 --- a/scene/gui/shortcut.cpp +++ b/scene/gui/shortcut.cpp @@ -29,10 +29,10 @@ /*************************************************************************/ #include "shortcut.h" - #include "core/os/keyboard.h" void Shortcut::set_event(const Ref<InputEvent> &p_event) { + ERR_FAIL_COND(Object::cast_to<InputEventShortcut>(*p_event)); event = p_event; emit_changed(); } @@ -42,6 +42,12 @@ Ref<InputEvent> Shortcut::get_event() const { } bool Shortcut::matches_event(const Ref<InputEvent> &p_event) const { + Ref<InputEventShortcut> ies = p_event; + if (ies != nullptr) { + if (ies->get_shortcut().ptr() == this) { + return true; + } + } return event.is_valid() && event->is_match(p_event, true); } diff --git a/scene/main/node.cpp b/scene/main/node.cpp index f1e5574351..cbd5fa7425 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -116,6 +116,9 @@ void Node::_notification(int p_notification) { memdelete(data.path_cache); data.path_cache = nullptr; } + if (data.filename.length()) { + get_multiplayer()->scene_enter_exit_notify(data.filename, this, false); + } } break; case NOTIFICATION_PATH_CHANGED: { if (data.path_cache) { @@ -147,6 +150,10 @@ void Node::_notification(int p_notification) { get_script_instance()->call(SceneStringNames::get_singleton()->_ready); } + if (data.filename.length()) { + ERR_FAIL_COND(!is_inside_tree()); + get_multiplayer()->scene_enter_exit_notify(data.filename, this, true); + } } break; case NOTIFICATION_POSTINITIALIZE: { @@ -705,7 +712,7 @@ bool Node::is_enabled() const { return _is_enabled(); } -float Node::get_physics_process_delta_time() const { +double Node::get_physics_process_delta_time() const { if (data.tree) { return data.tree->get_physics_process_time(); } else { @@ -713,7 +720,7 @@ float Node::get_physics_process_delta_time() const { } } -float Node::get_process_delta_time() const { +double Node::get_process_delta_time() const { if (data.tree) { return data.tree->get_process_time(); } else { diff --git a/scene/main/node.h b/scene/main/node.h index 0a88553ea1..9997f4e055 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -202,6 +202,7 @@ protected: static String _get_name_num_separator(); friend class SceneState; + friend class MultiplayerAPI; void _add_child_nocheck(Node *p_child, const StringName &p_name); void _set_owner_nocheck(Node *p_owner); @@ -339,11 +340,11 @@ public: /* PROCESSING */ void set_physics_process(bool p_process); - float get_physics_process_delta_time() const; + double get_physics_process_delta_time() const; bool is_physics_processing() const; void set_process(bool p_process); - float get_process_delta_time() const; + double get_process_delta_time() const; bool is_processing() const; void set_physics_process_internal(bool p_process_internal); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index dcbbebbc55..420516cbcd 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1341,7 +1341,7 @@ SceneTree::SceneTree() { set_multiplayer(Ref<MultiplayerAPI>(memnew(MultiplayerAPI))); //root->set_world_2d( Ref<World2D>( memnew( World2D ))); - root->set_as_audio_listener(true); + root->set_as_audio_listener_3d(true); root->set_as_audio_listener_2d(true); current_scene = nullptr; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 8e7182df46..908950a714 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -184,24 +184,6 @@ public: ///////////////////////////////////// -void Viewport::_collision_object_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) { - Transform3D object_transform = p_object->get_global_transform(); - Transform3D camera_transform = p_camera->get_global_transform(); - ObjectID id = p_object->get_instance_id(); - - //avoid sending the fake event unnecessarily if nothing really changed in the context - if (object_transform == physics_last_object_transform && camera_transform == physics_last_camera_transform && physics_last_id == id) { - Ref<InputEventMouseMotion> mm = p_input_event; - if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) { - return; //discarded - } - } - p_object->_input_event(camera_3d, p_input_event, p_pos, p_normal, p_shape); - physics_last_object_transform = object_transform; - physics_last_camera_transform = camera_transform; - physics_last_id = id; -} - void Viewport::_sub_window_update_order() { for (int i = 0; i < gui.sub_windows.size(); i++) { RS::get_singleton()->canvas_item_set_draw_index(gui.sub_windows[i].canvas_item, i); @@ -388,27 +370,6 @@ void Viewport::_sub_window_remove(Window *p_window) { RenderingServer::get_singleton()->viewport_set_parent_viewport(p_window->viewport, p_window->parent ? p_window->parent->viewport : RID()); } -void Viewport::_own_world_3d_changed() { - ERR_FAIL_COND(world_3d.is_null()); - ERR_FAIL_COND(own_world_3d.is_null()); - - if (is_inside_tree()) { - _propagate_exit_world(this); - } - - own_world_3d = world_3d->duplicate(); - - if (is_inside_tree()) { - _propagate_enter_world(this); - } - - if (is_inside_tree()) { - RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); - } - - _update_listener(); -} - void Viewport::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -422,19 +383,16 @@ void Viewport::_notification(int p_what) { } current_canvas = find_world_2d()->get_canvas(); - RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas); - - _update_listener(); _update_listener_2d(); + RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); + _update_listener_3d(); add_to_group("_viewports"); if (get_tree()->is_debugging_collisions_hint()) { - //2D PhysicsServer2D::get_singleton()->space_set_debug_contacts(find_world_2d()->get_space(), get_tree()->get_collision_debug_contact_count()); contact_2d_debug = RenderingServer::get_singleton()->canvas_item_create(); RenderingServer::get_singleton()->canvas_item_set_parent(contact_2d_debug, find_world_2d()->get_canvas()); - //3D PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count()); contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create(); RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true); @@ -444,15 +402,13 @@ void Viewport::_notification(int p_what) { RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh); RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario()); //RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true); - set_physics_process_internal(true); } } break; case NOTIFICATION_READY: { -#ifndef _3D_DISABLED - if (listeners.size() && !listener) { + if (listener_3d_set.size() && !listener_3d) { Listener3D *first = nullptr; - for (Set<Listener3D *>::Element *E = listeners.front(); E; E = E->next()) { + for (Set<Listener3D *>::Element *E = listener_3d_set.front(); E; E = E->next()) { if (first == nullptr || first->is_greater_than(E->get())) { first = E->get(); } @@ -463,10 +419,10 @@ void Viewport::_notification(int p_what) { } } - if (cameras.size() && !camera_3d) { + if (camera_3d_set.size() && !camera_3d) { //there are cameras but no current camera, pick first in tree and make it current Camera3D *first = nullptr; - for (Set<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) { + for (Set<Camera3D *>::Element *E = camera_3d_set.front(); E; E = E->next()) { if (first == nullptr || first->is_greater_than(E->get())) { first = E->get(); } @@ -476,7 +432,6 @@ void Viewport::_notification(int p_what) { first->make_current(); } } -#endif } break; case NOTIFICATION_EXIT_TREE: { @@ -515,7 +470,6 @@ void Viewport::_notification(int p_what) { RenderingServer::get_singleton()->canvas_item_add_rect(contact_2d_debug, Rect2(points[i] - Vector2(2, 2), Vector2(5, 5)), ccol); } } - if (get_tree()->is_debugging_collisions_hint() && contact_3d_debug_multimesh.is_valid()) { Vector<Vector3> points = PhysicsServer3D::get_singleton()->space_get_contacts(find_world_3d()->get_space()); int point_count = PhysicsServer3D::get_singleton()->space_get_contact_count(find_world_3d()->get_space()); @@ -560,11 +514,9 @@ void Viewport::_process_picking() { _drop_physics_mouseover(true); -#ifndef _3D_DISABLED Vector2 last_pos(1e20, 1e20); CollisionObject3D *last_object = nullptr; ObjectID last_id; -#endif PhysicsDirectSpaceState3D::RayResult result; PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); @@ -725,13 +677,12 @@ void Viewport::_process_picking() { } } -#ifndef _3D_DISABLED bool captured = false; if (physics_object_capture.is_valid()) { CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); if (co && camera_3d) { - _collision_object_input_event(co, camera_3d, ev, Vector3(), Vector3(), 0); + _collision_object_3d_input_event(co, camera_3d, ev, Vector3(), Vector3(), 0); captured = true; if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { physics_object_capture = ObjectID(); @@ -748,7 +699,7 @@ void Viewport::_process_picking() { if (last_id.is_valid()) { if (ObjectDB::get_instance(last_id) && last_object) { //good, exists - _collision_object_input_event(last_object, camera_3d, ev, result.position, result.normal, result.shape); + _collision_object_3d_input_event(last_object, camera_3d, ev, result.position, result.normal, result.shape); if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { physics_object_capture = last_id; } @@ -765,8 +716,8 @@ void Viewport::_process_picking() { ObjectID new_collider; if (col) { CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); - if (co) { - _collision_object_input_event(co, camera_3d, ev, result.position, result.normal, result.shape); + if (co && co->can_process()) { + _collision_object_3d_input_event(co, camera_3d, ev, result.position, result.normal, result.shape); last_object = co; last_id = result.collider_id; new_collider = last_id; @@ -798,7 +749,6 @@ void Viewport::_process_picking() { last_pos = pos; } } -#endif } } @@ -865,31 +815,15 @@ Rect2 Viewport::get_visible_rect() const { return r; } -void Viewport::_update_listener() { -} - void Viewport::_update_listener_2d() { /* - if (is_inside_tree() && audio_listener && (!get_parent() || (Object::cast_to<Control>(get_parent()) && Object::cast_to<Control>(get_parent())->is_visible_in_tree()))) + if (is_inside_tree() && audio_listener_3d && (!get_parent() || (Object::cast_to<Control>(get_parent()) && Object::cast_to<Control>(get_parent())->is_visible_in_tree()))) SpatialSound2DServer::get_singleton()->listener_set_space(internal_listener_2d, find_world_2d()->get_sound_space()); else SpatialSound2DServer::get_singleton()->listener_set_space(internal_listener_2d, RID()); */ } -void Viewport::set_as_audio_listener(bool p_enable) { - if (p_enable == audio_listener) { - return; - } - - audio_listener = p_enable; - _update_listener(); -} - -bool Viewport::is_audio_listener() const { - return audio_listener; -} - void Viewport::set_as_audio_listener_2d(bool p_enable) { if (p_enable == audio_listener_2d) { return; @@ -904,15 +838,6 @@ bool Viewport::is_audio_listener_2d() const { return audio_listener_2d; } -void Viewport::set_disable_3d(bool p_disable) { - disable_3d = p_disable; - RenderingServer::get_singleton()->viewport_set_disable_3d(viewport, disable_3d); -} - -bool Viewport::is_3d_disabled() const { - return disable_3d; -} - void Viewport::enable_canvas_transform_override(bool p_enable) { if (override_canvas_transform == p_enable) { return; @@ -973,131 +898,10 @@ Transform2D Viewport::get_global_canvas_transform() const { return global_canvas_transform; } -void Viewport::_listener_transform_changed_notify() { -} - -void Viewport::_listener_set(Listener3D *p_listener) { -#ifndef _3D_DISABLED - - if (listener == p_listener) { - return; - } - - listener = p_listener; - - _update_listener(); - _listener_transform_changed_notify(); -#endif -} - -bool Viewport::_listener_add(Listener3D *p_listener) { - listeners.insert(p_listener); - return listeners.size() == 1; -} - -void Viewport::_listener_remove(Listener3D *p_listener) { - listeners.erase(p_listener); - if (listener == p_listener) { - listener = nullptr; - } -} - -#ifndef _3D_DISABLED -void Viewport::_listener_make_next_current(Listener3D *p_exclude) { - if (listeners.size() > 0) { - for (Set<Listener3D *>::Element *E = listeners.front(); E; E = E->next()) { - if (p_exclude == E->get()) { - continue; - } - if (!E->get()->is_inside_tree()) { - continue; - } - if (listener != nullptr) { - return; - } - - E->get()->make_current(); - } - } else { - // Attempt to reset listener to the camera position - if (camera_3d != nullptr) { - _update_listener(); - _camera_3d_transform_changed_notify(); - } - } -} -#endif - -void Viewport::_camera_3d_transform_changed_notify() { -#ifndef _3D_DISABLED -#endif -} - -void Viewport::_camera_3d_set(Camera3D *p_camera) { -#ifndef _3D_DISABLED - - if (camera_3d == p_camera) { - return; - } - - if (camera_3d) { - camera_3d->notification(Camera3D::NOTIFICATION_LOST_CURRENT); - } - - camera_3d = p_camera; - - if (!camera_override) { - if (camera_3d) { - RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d->get_camera()); - } else { - RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID()); - } - } - - if (camera_3d) { - camera_3d->notification(Camera3D::NOTIFICATION_BECAME_CURRENT); - } - - _update_listener(); - _camera_3d_transform_changed_notify(); -#endif -} - void Viewport::_camera_2d_set(Camera2D *p_camera_2d) { camera_2d = p_camera_2d; } -bool Viewport::_camera_3d_add(Camera3D *p_camera) { - cameras.insert(p_camera); - return cameras.size() == 1; -} - -void Viewport::_camera_3d_remove(Camera3D *p_camera) { - cameras.erase(p_camera); - if (camera_3d == p_camera) { - camera_3d->notification(Camera3D::NOTIFICATION_LOST_CURRENT); - camera_3d = nullptr; - } -} - -#ifndef _3D_DISABLED -void Viewport::_camera_3d_make_next_current(Camera3D *p_exclude) { - for (Set<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) { - if (p_exclude == E->get()) { - continue; - } - if (!E->get()->is_inside_tree()) { - continue; - } - if (camera_3d != nullptr) { - return; - } - - E->get()->make_current(); - } -} -#endif - void Viewport::_canvas_layer_add(CanvasLayer *p_canvas_layer) { canvas_layers.insert(p_canvas_layer); } @@ -1121,7 +925,7 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) { } if (parent && parent->find_world_2d() == p_world_2d) { - WARN_PRINT("Unable to use parent world_3d as world_2d"); + WARN_PRINT("Unable to use parent world_2d as world_2d"); return; } @@ -1154,33 +958,6 @@ Ref<World2D> Viewport::find_world_2d() const { } } -void Viewport::_propagate_enter_world(Node *p_node) { - if (p_node != this) { - if (!p_node->is_inside_tree()) { //may not have entered scene yet - return; - } - -#ifndef _3D_DISABLED - if (Object::cast_to<Node3D>(p_node) || Object::cast_to<WorldEnvironment>(p_node)) { - p_node->notification(Node3D::NOTIFICATION_ENTER_WORLD); - } else { -#endif - Viewport *v = Object::cast_to<Viewport>(p_node); - if (v) { - if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) { - return; - } - } -#ifndef _3D_DISABLED - } -#endif - } - - for (int i = 0; i < p_node->get_child_count(); i++) { - _propagate_enter_world(p_node->get_child(i)); - } -} - void Viewport::_propagate_viewport_notification(Node *p_node, int p_what) { p_node->notification(p_what); for (int i = 0; i < p_node->get_child_count(); i++) { @@ -1192,174 +969,14 @@ void Viewport::_propagate_viewport_notification(Node *p_node, int p_what) { } } -void Viewport::_propagate_exit_world(Node *p_node) { - if (p_node != this) { - if (!p_node->is_inside_tree()) { //may have exited scene already - return; - } - -#ifndef _3D_DISABLED - if (Object::cast_to<Node3D>(p_node) || Object::cast_to<WorldEnvironment>(p_node)) { - p_node->notification(Node3D::NOTIFICATION_EXIT_WORLD); - } else { -#endif - Viewport *v = Object::cast_to<Viewport>(p_node); - if (v) { - if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) { - return; - } - } -#ifndef _3D_DISABLED - } -#endif - } - - for (int i = 0; i < p_node->get_child_count(); i++) { - _propagate_exit_world(p_node->get_child(i)); - } -} - -void Viewport::set_world_3d(const Ref<World3D> &p_world_3d) { - if (world_3d == p_world_3d) { - return; - } - - if (is_inside_tree()) { - _propagate_exit_world(this); - } - - if (own_world_3d.is_valid() && world_3d.is_valid()) { - world_3d->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed)); - } - - world_3d = p_world_3d; - - if (own_world_3d.is_valid()) { - if (world_3d.is_valid()) { - own_world_3d = world_3d->duplicate(); - world_3d->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed)); - } else { - own_world_3d = Ref<World3D>(memnew(World3D)); - } - } - - if (is_inside_tree()) { - _propagate_enter_world(this); - } - - if (is_inside_tree()) { - RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); - } - - _update_listener(); -} - -Ref<World3D> Viewport::get_world_3d() const { - return world_3d; -} - Ref<World2D> Viewport::get_world_2d() const { return world_2d; } -Ref<World3D> Viewport::find_world_3d() const { - if (own_world_3d.is_valid()) { - return own_world_3d; - } else if (world_3d.is_valid()) { - return world_3d; - } else if (parent) { - return parent->find_world_3d(); - } else { - return Ref<World3D>(); - } -} - -Listener3D *Viewport::get_listener() const { - return listener; -} - -Camera3D *Viewport::get_camera_3d() const { - return camera_3d; -} - Camera2D *Viewport::get_camera_2d() const { return camera_2d; } -void Viewport::enable_camera_override(bool p_enable) { -#ifndef _3D_DISABLED - if (p_enable == camera_override) { - return; - } - - if (p_enable) { - camera_override.rid = RenderingServer::get_singleton()->camera_create(); - } else { - RenderingServer::get_singleton()->free(camera_override.rid); - camera_override.rid = RID(); - } - - if (p_enable) { - RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_override.rid); - } else if (camera_3d) { - RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d->get_camera()); - } else { - RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID()); - } -#endif -} - -bool Viewport::is_camera_override_enabled() const { - return camera_override; -} - -void Viewport::set_camera_override_transform(const Transform3D &p_transform) { - if (camera_override) { - camera_override.transform = p_transform; - RenderingServer::get_singleton()->camera_set_transform(camera_override.rid, p_transform); - } -} - -Transform3D Viewport::get_camera_override_transform() const { - if (camera_override) { - return camera_override.transform; - } - - return Transform3D(); -} - -void Viewport::set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) { - if (camera_override) { - if (camera_override.fov == p_fovy_degrees && camera_override.z_near == p_z_near && - camera_override.z_far == p_z_far && camera_override.projection == CameraOverrideData::PROJECTION_PERSPECTIVE) { - return; - } - - camera_override.fov = p_fovy_degrees; - camera_override.z_near = p_z_near; - camera_override.z_far = p_z_far; - camera_override.projection = CameraOverrideData::PROJECTION_PERSPECTIVE; - - RenderingServer::get_singleton()->camera_set_perspective(camera_override.rid, camera_override.fov, camera_override.z_near, camera_override.z_far); - } -} - -void Viewport::set_camera_override_orthogonal(float p_size, float p_z_near, float p_z_far) { - if (camera_override) { - if (camera_override.size == p_size && camera_override.z_near == p_z_near && - camera_override.z_far == p_z_far && camera_override.projection == CameraOverrideData::PROJECTION_ORTHOGONAL) { - return; - } - - camera_override.size = p_size; - camera_override.z_near = p_z_near; - camera_override.z_far = p_z_far; - camera_override.projection = CameraOverrideData::PROJECTION_ORTHOGONAL; - - RenderingServer::get_singleton()->camera_set_orthogonal(camera_override.rid, camera_override.size, camera_override.z_near, camera_override.z_far); - } -} - Transform2D Viewport::get_final_transform() const { return stretch_transform * global_canvas_transform; } @@ -1384,16 +1001,6 @@ void Viewport::_update_canvas_items(Node *p_node) { } } -void Viewport::set_use_xr(bool p_use_xr) { - use_xr = p_use_xr; - - RS::get_singleton()->viewport_set_use_xr(viewport, use_xr); -} - -bool Viewport::is_using_xr() { - return use_xr; -} - Ref<ViewportTexture> Viewport::get_texture() const { return default_texture; } @@ -2605,7 +2212,6 @@ void Viewport::_drop_physics_mouseover(bool p_paused_only) { _cleanup_mouseover_colliders(true, p_paused_only); -#ifndef _3D_DISABLED if (physics_object_over.is_valid()) { CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); if (co) { @@ -2616,7 +2222,6 @@ void Viewport::_drop_physics_mouseover(bool p_paused_only) { } } } -#endif } void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference) { @@ -3099,6 +2704,7 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) { void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) { ERR_FAIL_COND(p_event.is_null()); ERR_FAIL_COND(!is_inside_tree()); + local_input_handled = false; if (disable_input || !_can_consume_input_events()) { return; @@ -3118,8 +2724,8 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coor // Unhandled Input get_tree()->_call_input_pause(unhandled_input_group, "_unhandled_input", ev, this); - // Unhandled key Input - used for performance reasons - This is called a lot less then _unhandled_input since it ignores MouseMotion, etc - if (!is_input_handled() && Object::cast_to<InputEventKey>(*ev) != nullptr) { + // Unhandled key Input - used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, etc + if (!is_input_handled() && (Object::cast_to<InputEventKey>(*ev) != nullptr || Object::cast_to<InputEventShortcut>(*ev) != nullptr)) { get_tree()->_call_input_pause(unhandled_key_input_group, "_unhandled_key_input", ev, this); } @@ -3137,44 +2743,6 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coor } } -void Viewport::set_use_own_world_3d(bool p_world_3d) { - if (p_world_3d == own_world_3d.is_valid()) { - return; - } - - if (is_inside_tree()) { - _propagate_exit_world(this); - } - - if (!p_world_3d) { - own_world_3d = Ref<World3D>(); - if (world_3d.is_valid()) { - world_3d->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed)); - } - } else { - if (world_3d.is_valid()) { - own_world_3d = world_3d->duplicate(); - world_3d->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed)); - } else { - own_world_3d = Ref<World3D>(memnew(World3D)); - } - } - - if (is_inside_tree()) { - _propagate_enter_world(this); - } - - if (is_inside_tree()) { - RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); - } - - _update_listener(); -} - -bool Viewport::is_using_own_world_3d() const { - return own_world_3d.is_valid(); -} - void Viewport::set_physics_object_picking(bool p_enable) { physics_object_picking = p_enable; if (physics_object_picking) { @@ -3275,6 +2843,7 @@ void Viewport::set_lod_threshold(float p_pixels) { lod_threshold = p_pixels; RS::get_singleton()->viewport_set_lod_threshold(viewport, lod_threshold); } + float Viewport::get_lod_threshold() const { return lod_threshold; } @@ -3487,6 +3056,7 @@ void Viewport::set_sdf_oversize(SDFOversize p_sdf_oversize) { sdf_oversize = p_sdf_oversize; RS::get_singleton()->viewport_set_sdf_oversize_and_scale(viewport, RS::ViewportSDFOversize(sdf_oversize), RS::ViewportSDFScale(sdf_scale)); } + Viewport::SDFOversize Viewport::get_sdf_oversize() const { return sdf_oversize; } @@ -3496,17 +3066,413 @@ void Viewport::set_sdf_scale(SDFScale p_sdf_scale) { sdf_scale = p_sdf_scale; RS::get_singleton()->viewport_set_sdf_oversize_and_scale(viewport, RS::ViewportSDFOversize(sdf_oversize), RS::ViewportSDFScale(sdf_scale)); } + Viewport::SDFScale Viewport::get_sdf_scale() const { return sdf_scale; } +Listener3D *Viewport::get_listener_3d() const { + return listener_3d; +} + +void Viewport::set_as_audio_listener_3d(bool p_enable) { + if (p_enable == audio_listener_3d) { + return; + } + + audio_listener_3d = p_enable; + _update_listener_3d(); +} + +bool Viewport::is_audio_listener_3d() const { + return audio_listener_3d; +} + +void Viewport::_update_listener_3d() { +} + +void Viewport::_listener_transform_3d_changed_notify() { +} + +void Viewport::_listener_3d_set(Listener3D *p_listener) { + if (listener_3d == p_listener) { + return; + } + + listener_3d = p_listener; + + _update_listener_3d(); + _listener_transform_3d_changed_notify(); +} + +bool Viewport::_listener_3d_add(Listener3D *p_listener) { + listener_3d_set.insert(p_listener); + return listener_3d_set.size() == 1; +} + +void Viewport::_listener_3d_remove(Listener3D *p_listener) { + listener_3d_set.erase(p_listener); + if (listener_3d == p_listener) { + listener_3d = nullptr; + } +} + +void Viewport::_listener_3d_make_next_current(Listener3D *p_exclude) { + if (listener_3d_set.size() > 0) { + for (Set<Listener3D *>::Element *E = listener_3d_set.front(); E; E = E->next()) { + if (p_exclude == E->get()) { + continue; + } + if (!E->get()->is_inside_tree()) { + continue; + } + if (listener_3d != nullptr) { + return; + } + + E->get()->make_current(); + } + } else { + // Attempt to reset listener to the camera position + if (camera_3d != nullptr) { + _update_listener_3d(); + _camera_3d_transform_changed_notify(); + } + } +} + +void Viewport::_collision_object_3d_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) { + Transform3D object_transform = p_object->get_global_transform(); + Transform3D camera_transform = p_camera->get_global_transform(); + ObjectID id = p_object->get_instance_id(); + + //avoid sending the fake event unnecessarily if nothing really changed in the context + if (object_transform == physics_last_object_transform && camera_transform == physics_last_camera_transform && physics_last_id == id) { + Ref<InputEventMouseMotion> mm = p_input_event; + if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) { + return; //discarded + } + } + p_object->_input_event(camera_3d, p_input_event, p_pos, p_normal, p_shape); + physics_last_object_transform = object_transform; + physics_last_camera_transform = camera_transform; + physics_last_id = id; +} + +Camera3D *Viewport::get_camera_3d() const { + return camera_3d; +} + +void Viewport::_camera_3d_transform_changed_notify() { +} + +void Viewport::_camera_3d_set(Camera3D *p_camera) { + if (camera_3d == p_camera) { + return; + } + + if (camera_3d) { + camera_3d->notification(Camera3D::NOTIFICATION_LOST_CURRENT); + } + + camera_3d = p_camera; + + if (!camera_3d_override) { + if (camera_3d) { + RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d->get_camera()); + } else { + RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID()); + } + } + + if (camera_3d) { + camera_3d->notification(Camera3D::NOTIFICATION_BECAME_CURRENT); + } + + _update_listener_3d(); + _camera_3d_transform_changed_notify(); +} + +bool Viewport::_camera_3d_add(Camera3D *p_camera) { + camera_3d_set.insert(p_camera); + return camera_3d_set.size() == 1; +} + +void Viewport::_camera_3d_remove(Camera3D *p_camera) { + camera_3d_set.erase(p_camera); + if (camera_3d == p_camera) { + camera_3d->notification(Camera3D::NOTIFICATION_LOST_CURRENT); + camera_3d = nullptr; + } +} + +void Viewport::_camera_3d_make_next_current(Camera3D *p_exclude) { + for (Set<Camera3D *>::Element *E = camera_3d_set.front(); E; E = E->next()) { + if (p_exclude == E->get()) { + continue; + } + if (!E->get()->is_inside_tree()) { + continue; + } + if (camera_3d != nullptr) { + return; + } + + E->get()->make_current(); + } +} + +void Viewport::enable_camera_3d_override(bool p_enable) { + if (p_enable == camera_3d_override) { + return; + } + + if (p_enable) { + camera_3d_override.rid = RenderingServer::get_singleton()->camera_create(); + } else { + RenderingServer::get_singleton()->free(camera_3d_override.rid); + camera_3d_override.rid = RID(); + } + + if (p_enable) { + RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d_override.rid); + } else if (camera_3d) { + RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d->get_camera()); + } else { + RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID()); + } +} + +void Viewport::set_camera_3d_override_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far) { + if (camera_3d_override) { + if (camera_3d_override.fov == p_fovy_degrees && camera_3d_override.z_near == p_z_near && + camera_3d_override.z_far == p_z_far && camera_3d_override.projection == Camera3DOverrideData::PROJECTION_PERSPECTIVE) { + return; + } + + camera_3d_override.fov = p_fovy_degrees; + camera_3d_override.z_near = p_z_near; + camera_3d_override.z_far = p_z_far; + camera_3d_override.projection = Camera3DOverrideData::PROJECTION_PERSPECTIVE; + + RenderingServer::get_singleton()->camera_set_perspective(camera_3d_override.rid, camera_3d_override.fov, camera_3d_override.z_near, camera_3d_override.z_far); + } +} + +void Viewport::set_camera_3d_override_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far) { + if (camera_3d_override) { + if (camera_3d_override.size == p_size && camera_3d_override.z_near == p_z_near && + camera_3d_override.z_far == p_z_far && camera_3d_override.projection == Camera3DOverrideData::PROJECTION_ORTHOGONAL) { + return; + } + + camera_3d_override.size = p_size; + camera_3d_override.z_near = p_z_near; + camera_3d_override.z_far = p_z_far; + camera_3d_override.projection = Camera3DOverrideData::PROJECTION_ORTHOGONAL; + + RenderingServer::get_singleton()->camera_set_orthogonal(camera_3d_override.rid, camera_3d_override.size, camera_3d_override.z_near, camera_3d_override.z_far); + } +} + +void Viewport::set_disable_3d(bool p_disable) { + disable_3d = p_disable; + RenderingServer::get_singleton()->viewport_set_disable_3d(viewport, disable_3d); +} + +bool Viewport::is_3d_disabled() const { + return disable_3d; +} + +bool Viewport::is_camera_3d_override_enabled() const { + return camera_3d_override; +} + +void Viewport::set_camera_3d_override_transform(const Transform3D &p_transform) { + if (camera_3d_override) { + camera_3d_override.transform = p_transform; + RenderingServer::get_singleton()->camera_set_transform(camera_3d_override.rid, p_transform); + } +} + +Transform3D Viewport::get_camera_3d_override_transform() const { + if (camera_3d_override) { + return camera_3d_override.transform; + } + + return Transform3D(); +} + +Ref<World3D> Viewport::get_world_3d() const { + return world_3d; +} + +Ref<World3D> Viewport::find_world_3d() const { + if (own_world_3d.is_valid()) { + return own_world_3d; + } else if (world_3d.is_valid()) { + return world_3d; + } else if (parent) { + return parent->find_world_3d(); + } else { + return Ref<World3D>(); + } +} + +void Viewport::set_world_3d(const Ref<World3D> &p_world_3d) { + if (world_3d == p_world_3d) { + return; + } + + if (is_inside_tree()) { + _propagate_exit_world_3d(this); + } + + if (own_world_3d.is_valid() && world_3d.is_valid()) { + world_3d->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed)); + } + + world_3d = p_world_3d; + + if (own_world_3d.is_valid()) { + if (world_3d.is_valid()) { + own_world_3d = world_3d->duplicate(); + world_3d->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed)); + } else { + own_world_3d = Ref<World3D>(memnew(World3D)); + } + } + + if (is_inside_tree()) { + _propagate_enter_world_3d(this); + } + + if (is_inside_tree()) { + RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); + } + + _update_listener_3d(); +} + +void Viewport::_own_world_3d_changed() { + ERR_FAIL_COND(world_3d.is_null()); + ERR_FAIL_COND(own_world_3d.is_null()); + + if (is_inside_tree()) { + _propagate_exit_world_3d(this); + } + + own_world_3d = world_3d->duplicate(); + + if (is_inside_tree()) { + _propagate_enter_world_3d(this); + } + + if (is_inside_tree()) { + RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); + } + + _update_listener_3d(); +} + +void Viewport::set_use_own_world_3d(bool p_world_3d) { + if (p_world_3d == own_world_3d.is_valid()) { + return; + } + + if (is_inside_tree()) { + _propagate_exit_world_3d(this); + } + + if (!p_world_3d) { + own_world_3d = Ref<World3D>(); + if (world_3d.is_valid()) { + world_3d->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed)); + } + } else { + if (world_3d.is_valid()) { + own_world_3d = world_3d->duplicate(); + world_3d->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed)); + } else { + own_world_3d = Ref<World3D>(memnew(World3D)); + } + } + + if (is_inside_tree()) { + _propagate_enter_world_3d(this); + } + + if (is_inside_tree()) { + RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); + } + + _update_listener_3d(); +} + +bool Viewport::is_using_own_world_3d() const { + return own_world_3d.is_valid(); +} + +void Viewport::_propagate_enter_world_3d(Node *p_node) { + if (p_node != this) { + if (!p_node->is_inside_tree()) { //may not have entered scene yet + return; + } + + if (Object::cast_to<Node3D>(p_node) || Object::cast_to<WorldEnvironment>(p_node)) { + p_node->notification(Node3D::NOTIFICATION_ENTER_WORLD); + } else { + Viewport *v = Object::cast_to<Viewport>(p_node); + if (v) { + if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) { + return; + } + } + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _propagate_enter_world_3d(p_node->get_child(i)); + } +} + +void Viewport::_propagate_exit_world_3d(Node *p_node) { + if (p_node != this) { + if (!p_node->is_inside_tree()) { //may have exited scene already + return; + } + + if (Object::cast_to<Node3D>(p_node) || Object::cast_to<WorldEnvironment>(p_node)) { + p_node->notification(Node3D::NOTIFICATION_EXIT_WORLD); + } else { + Viewport *v = Object::cast_to<Viewport>(p_node); + if (v) { + if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) { + return; + } + } + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _propagate_exit_world_3d(p_node->get_child(i)); + } +} + +void Viewport::set_use_xr(bool p_use_xr) { + use_xr = p_use_xr; + + RS::get_singleton()->viewport_set_use_xr(viewport, use_xr); +} + +bool Viewport::is_using_xr() { + return use_xr; +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d); ClassDB::bind_method(D_METHOD("get_world_2d"), &Viewport::get_world_2d); ClassDB::bind_method(D_METHOD("find_world_2d"), &Viewport::find_world_2d); - ClassDB::bind_method(D_METHOD("set_world_3d", "world_3d"), &Viewport::set_world_3d); - ClassDB::bind_method(D_METHOD("get_world_3d"), &Viewport::get_world_3d); - ClassDB::bind_method(D_METHOD("find_world_3d"), &Viewport::find_world_3d); ClassDB::bind_method(D_METHOD("set_canvas_transform", "xform"), &Viewport::set_canvas_transform); ClassDB::bind_method(D_METHOD("get_canvas_transform"), &Viewport::get_canvas_transform); @@ -3536,9 +3502,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("get_render_info", "type", "info"), &Viewport::get_render_info); - ClassDB::bind_method(D_METHOD("set_use_xr", "use"), &Viewport::set_use_xr); - ClassDB::bind_method(D_METHOD("is_using_xr"), &Viewport::is_using_xr); - ClassDB::bind_method(D_METHOD("get_texture"), &Viewport::get_texture); ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking); @@ -3549,21 +3512,10 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("input", "event", "in_local_coords"), &Viewport::input, DEFVAL(false)); ClassDB::bind_method(D_METHOD("unhandled_input", "event", "in_local_coords"), &Viewport::unhandled_input, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d); - ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d); - - ClassDB::bind_method(D_METHOD("get_camera_3d"), &Viewport::get_camera_3d); ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d); - - ClassDB::bind_method(D_METHOD("set_as_audio_listener", "enable"), &Viewport::set_as_audio_listener); - ClassDB::bind_method(D_METHOD("is_audio_listener"), &Viewport::is_audio_listener); - ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d); ClassDB::bind_method(D_METHOD("is_audio_listener_2d"), &Viewport::is_audio_listener_2d); - ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d); - ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled); - ClassDB::bind_method(D_METHOD("get_mouse_position"), &Viewport::get_mouse_position); ClassDB::bind_method(D_METHOD("warp_mouse", "to_position"), &Viewport::warp_mouse); @@ -3621,7 +3573,26 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking); + ClassDB::bind_method(D_METHOD("set_world_3d", "world_3d"), &Viewport::set_world_3d); + ClassDB::bind_method(D_METHOD("get_world_3d"), &Viewport::get_world_3d); + ClassDB::bind_method(D_METHOD("find_world_3d"), &Viewport::find_world_3d); + + ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d); + ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d); + + ClassDB::bind_method(D_METHOD("get_camera_3d"), &Viewport::get_camera_3d); + ClassDB::bind_method(D_METHOD("set_as_audio_listener_3d", "enable"), &Viewport::set_as_audio_listener_3d); + ClassDB::bind_method(D_METHOD("is_audio_listener_3d"), &Viewport::is_audio_listener_3d); + + ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d); + ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled); + + ClassDB::bind_method(D_METHOD("set_use_xr", "use"), &Viewport::set_use_xr); + ClassDB::bind_method(D_METHOD("is_using_xr"), &Viewport::is_using_xr); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener_3d", "is_audio_listener_3d"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", PROPERTY_USAGE_NONE), "set_world_2d", "get_world_2d"); @@ -3630,7 +3601,6 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled"); ADD_GROUP("Rendering", ""); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)"), "set_msaa", "get_msaa"); ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding"); @@ -3642,7 +3612,6 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirror"), "set_default_canvas_item_texture_repeat", "get_default_canvas_item_texture_repeat"); ADD_GROUP("Audio Listener", "audio_listener_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_2d"), "set_as_audio_listener_2d", "is_audio_listener_2d"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener", "is_audio_listener"); ADD_GROUP("Physics", "physics_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking"); ADD_GROUP("GUI", "gui_"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index b5c49a8a97..7a25f5aa00 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -194,39 +194,13 @@ private: Viewport *parent = nullptr; - Listener3D *listener = nullptr; - Set<Listener3D *> listeners; - - struct CameraOverrideData { - Transform3D transform; - enum Projection { - PROJECTION_PERSPECTIVE, - PROJECTION_ORTHOGONAL - }; - Projection projection = Projection::PROJECTION_PERSPECTIVE; - float fov = 0.0; - float size = 0.0; - float z_near = 0.0; - float z_far = 0.0; - RID rid; - - operator bool() const { - return rid != RID(); - } - } camera_override; - - Camera3D *camera_3d = nullptr; Camera2D *camera_2d = nullptr; - Set<Camera3D *> cameras; Set<CanvasLayer *> canvas_layers; RID viewport; RID current_canvas; RID subwindow_canvas; - bool audio_listener = false; - RID internal_listener; - bool audio_listener_2d = false; RID internal_listener_2d; @@ -240,7 +214,6 @@ private: Size2i size = Size2i(512, 512); Size2i size_2d_override; bool size_allocated = false; - bool use_xr = false; RID contact_2d_debug; RID contact_3d_debug_multimesh; @@ -274,8 +247,6 @@ private: } physics_last_mouse_state; - void _collision_object_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape); - bool handle_input_locally = true; bool local_input_handled = false; @@ -287,8 +258,6 @@ private: void _cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference = 0); Ref<World2D> world_2d; - Ref<World3D> world_3d; - Ref<World3D> own_world_3d; Rect2i to_screen_rect; StringName input_group; @@ -296,13 +265,10 @@ private: StringName unhandled_input_group; StringName unhandled_key_input_group; - void _update_listener(); void _update_listener_2d(); bool disable_3d = false; - void _propagate_enter_world(Node *p_node); - void _propagate_exit_world(Node *p_node); void _propagate_viewport_notification(Node *p_node, int p_what); void _update_global_transform(); @@ -375,7 +341,7 @@ private: Variant drag_data; ObjectID drag_preview_id; Ref<SceneTreeTimer> tooltip_timer; - float tooltip_delay = 0.0; + double tooltip_delay = 0.0; Transform2D focus_inv_xform; bool roots_order_dirty = false; List<Control *> roots; @@ -443,20 +409,6 @@ private: bool _gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check); - friend class Listener3D; - void _listener_transform_changed_notify(); - void _listener_set(Listener3D *p_listener); - bool _listener_add(Listener3D *p_listener); //true if first - void _listener_remove(Listener3D *p_listener); - void _listener_make_next_current(Listener3D *p_exclude); - - friend class Camera3D; - void _camera_3d_transform_changed_notify(); - void _camera_3d_set(Camera3D *p_camera); - bool _camera_3d_add(Camera3D *p_camera); //true if first - void _camera_3d_remove(Camera3D *p_camera); - void _camera_3d_make_next_current(Camera3D *p_exclude); - friend class Camera2D; void _camera_2d_set(Camera2D *p_camera_2d); @@ -471,8 +423,6 @@ private: void _gui_set_root_order_dirty(); - void _own_world_3d_changed(); - friend class Window; void _sub_window_update_order(); @@ -500,38 +450,16 @@ protected: public: uint64_t get_processed_events_count() const { return event_count; } - Listener3D *get_listener() const; - Camera3D *get_camera_3d() const; Camera2D *get_camera_2d() const; - - void enable_camera_override(bool p_enable); - bool is_camera_override_enabled() const; - - void set_camera_override_transform(const Transform3D &p_transform); - Transform3D get_camera_override_transform() const; - - void set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far); - void set_camera_override_orthogonal(float p_size, float p_z_near, float p_z_far); - - void set_as_audio_listener(bool p_enable); - bool is_audio_listener() const; - void set_as_audio_listener_2d(bool p_enable); bool is_audio_listener_2d() const; - void set_disable_3d(bool p_disable); - bool is_3d_disabled() const; - void update_canvas_items(); Rect2 get_visible_rect() const; RID get_viewport_rid() const; - void set_world_3d(const Ref<World3D> &p_world_3d); void set_world_2d(const Ref<World2D> &p_world_2d); - Ref<World3D> get_world_3d() const; - Ref<World3D> find_world_3d() const; - Ref<World2D> get_world_2d() const; Ref<World2D> find_world_2d() const; @@ -552,9 +480,6 @@ public: void set_transparent_background(bool p_enable); bool has_transparent_background() const; - void set_use_xr(bool p_use_xr); - bool is_using_xr(); - Ref<ViewportTexture> get_texture() const; void set_shadow_atlas_size(int p_size); @@ -584,9 +509,6 @@ public: Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; - void set_use_own_world_3d(bool p_world_3d); - bool is_using_own_world_3d() const; - void input_text(const String &p_text); void input(const Ref<InputEvent> &p_event, bool p_local_coords = false); void unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords = false); @@ -654,6 +576,78 @@ public: void pass_mouse_focus_to(Viewport *p_viewport, Control *p_control); + bool use_xr = false; + friend class Listener3D; + Listener3D *listener_3d = nullptr; + Set<Listener3D *> listener_3d_set; + bool audio_listener_3d = false; + RID internal_listener_3d; + Listener3D *get_listener_3d() const; + void set_as_audio_listener_3d(bool p_enable); + bool is_audio_listener_3d() const; + void _update_listener_3d(); + void _listener_transform_3d_changed_notify(); + void _listener_3d_set(Listener3D *p_listener); + bool _listener_3d_add(Listener3D *p_listener); //true if first + void _listener_3d_remove(Listener3D *p_listener); + void _listener_3d_make_next_current(Listener3D *p_exclude); + + void _collision_object_3d_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape); + + struct Camera3DOverrideData { + Transform3D transform; + enum Projection { + PROJECTION_PERSPECTIVE, + PROJECTION_ORTHOGONAL + }; + Projection projection = Projection::PROJECTION_PERSPECTIVE; + real_t fov = 0.0; + real_t size = 0.0; + real_t z_near = 0.0; + real_t z_far = 0.0; + RID rid; + + operator bool() const { + return rid != RID(); + } + } camera_3d_override; + + friend class Camera3D; + Camera3D *camera_3d = nullptr; + Set<Camera3D *> camera_3d_set; + Camera3D *get_camera_3d() const; + void _camera_3d_transform_changed_notify(); + void _camera_3d_set(Camera3D *p_camera); + bool _camera_3d_add(Camera3D *p_camera); //true if first + void _camera_3d_remove(Camera3D *p_camera); + void _camera_3d_make_next_current(Camera3D *p_exclude); + + void enable_camera_3d_override(bool p_enable); + bool is_camera_3d_override_enabled() const; + + void set_camera_3d_override_transform(const Transform3D &p_transform); + Transform3D get_camera_3d_override_transform() const; + + void set_camera_3d_override_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far); + void set_camera_3d_override_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far); + + void set_disable_3d(bool p_disable); + bool is_3d_disabled() const; + + Ref<World3D> world_3d; + Ref<World3D> own_world_3d; + void set_world_3d(const Ref<World3D> &p_world_3d); + Ref<World3D> get_world_3d() const; + Ref<World3D> find_world_3d() const; + void _own_world_3d_changed(); + void set_use_own_world_3d(bool p_world_3d); + bool is_using_own_world_3d() const; + void _propagate_enter_world_3d(Node *p_node); + void _propagate_exit_world_3d(Node *p_node); + + void set_use_xr(bool p_use_xr); + bool is_using_xr(); + Viewport(); ~Viewport(); }; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 640ec50eb9..e6a74e7685 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -77,17 +77,17 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { } else if (what == "keys" || what == "key_values") { if (track_get_type(track) == TYPE_TRANSFORM3D) { TransformTrack *tt = static_cast<TransformTrack *>(tracks[track]); - Vector<float> values = p_value; + Vector<real_t> values = p_value; int vcount = values.size(); - ERR_FAIL_COND_V(vcount % 12, false); // should be multiple of 11 + ERR_FAIL_COND_V(vcount % 12, false); // should be multiple of 12 - const float *r = values.ptr(); + const real_t *r = values.ptr(); tt->transforms.resize(vcount / 12); for (int i = 0; i < (vcount / 12); i++) { TKey<TransformKey> &tk = tt->transforms.write[i]; - const float *ofs = &r[i * 12]; + const real_t *ofs = &r[i * 12]; tk.time = ofs[0]; tk.transition = ofs[1]; @@ -125,7 +125,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { vt->update_mode = UpdateMode(um); } - Vector<float> times = d["times"]; + Vector<real_t> times = d["times"]; Array values = d["values"]; ERR_FAIL_COND_V(times.size() != values.size(), false); @@ -133,7 +133,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { if (times.size()) { int valcount = times.size(); - const float *rt = times.ptr(); + const real_t *rt = times.ptr(); vt->values.resize(valcount); @@ -143,10 +143,10 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { } if (d.has("transitions")) { - Vector<float> transitions = d["transitions"]; + Vector<real_t> transitions = d["transitions"]; ERR_FAIL_COND_V(transitions.size() != valcount, false); - const float *rtr = transitions.ptr(); + const real_t *rtr = transitions.ptr(); for (int i = 0; i < valcount; i++) { vt->values.write[i].transition = rtr[i]; @@ -165,7 +165,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("times"), false); ERR_FAIL_COND_V(!d.has("values"), false); - Vector<float> times = d["times"]; + Vector<real_t> times = d["times"]; Array values = d["values"]; ERR_FAIL_COND_V(times.size() != values.size(), false); @@ -173,17 +173,17 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { if (times.size()) { int valcount = times.size(); - const float *rt = times.ptr(); + const real_t *rt = times.ptr(); for (int i = 0; i < valcount; i++) { track_insert_key(track, rt[i], values[i]); } if (d.has("transitions")) { - Vector<float> transitions = d["transitions"]; + Vector<real_t> transitions = d["transitions"]; ERR_FAIL_COND_V(transitions.size() != valcount, false); - const float *rtr = transitions.ptr(); + const real_t *rtr = transitions.ptr(); for (int i = 0; i < valcount; i++) { track_set_key_transition(track, i, rtr[i]); @@ -196,16 +196,16 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("times"), false); ERR_FAIL_COND_V(!d.has("points"), false); - Vector<float> times = d["times"]; - PackedFloat32Array values = d["points"]; + Vector<real_t> times = d["times"]; + Vector<real_t> values = d["points"]; ERR_FAIL_COND_V(times.size() * 5 != values.size(), false); if (times.size()) { int valcount = times.size(); - const float *rt = times.ptr(); - const float *rv = values.ptr(); + const real_t *rt = times.ptr(); + const real_t *rv = values.ptr(); bt->values.resize(valcount); @@ -227,7 +227,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("times"), false); ERR_FAIL_COND_V(!d.has("clips"), false); - Vector<float> times = d["times"]; + Vector<real_t> times = d["times"]; Array clips = d["clips"]; ERR_FAIL_COND_V(clips.size() != times.size(), false); @@ -235,7 +235,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { if (times.size()) { int valcount = times.size(); - const float *rt = times.ptr(); + const real_t *rt = times.ptr(); ad->values.clear(); @@ -268,7 +268,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("times"), false); ERR_FAIL_COND_V(!d.has("clips"), false); - Vector<float> times = d["times"]; + Vector<real_t> times = d["times"]; Vector<String> clips = d["clips"]; ERR_FAIL_COND_V(clips.size() != times.size(), false); @@ -276,7 +276,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { if (times.size()) { int valcount = times.size(); - const float *rt = times.ptr(); + const real_t *rt = times.ptr(); const String *rc = clips.ptr(); an->values.resize(valcount); @@ -352,9 +352,9 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { r_ret = track_is_enabled(track); } else if (what == "keys") { if (track_get_type(track) == TYPE_TRANSFORM3D) { - Vector<float> keys; + Vector<real_t> keys; int kk = track_get_key_count(track); - keys.resize(kk * 12); + keys.resize(kk * sizeof(Transform3D)); real_t *w = keys.ptrw(); @@ -389,8 +389,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - Vector<float> key_times; - Vector<float> key_transitions; + Vector<real_t> key_times; + Vector<real_t> key_transitions; Array key_values; int kk = vt->values.size(); @@ -399,8 +399,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { key_transitions.resize(kk); key_values.resize(kk); - float *wti = key_times.ptrw(); - float *wtr = key_transitions.ptrw(); + real_t *wti = key_times.ptrw(); + real_t *wtr = key_transitions.ptrw(); int idx = 0; @@ -427,8 +427,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { } else if (track_get_type(track) == TYPE_METHOD) { Dictionary d; - Vector<float> key_times; - Vector<float> key_transitions; + Vector<real_t> key_times; + Vector<real_t> key_transitions; Array key_values; int kk = track_get_key_count(track); @@ -437,8 +437,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { key_transitions.resize(kk); key_values.resize(kk); - float *wti = key_times.ptrw(); - float *wtr = key_transitions.ptrw(); + real_t *wti = key_times.ptrw(); + real_t *wtr = key_transitions.ptrw(); int idx = 0; for (int i = 0; i < track_get_key_count(track); i++) { @@ -463,16 +463,16 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - Vector<float> key_times; - Vector<float> key_points; + Vector<real_t> key_times; + Vector<real_t> key_points; int kk = bt->values.size(); key_times.resize(kk); key_points.resize(kk * 5); - float *wti = key_times.ptrw(); - float *wpo = key_points.ptrw(); + real_t *wti = key_times.ptrw(); + real_t *wpo = key_points.ptrw(); int idx = 0; @@ -499,14 +499,14 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - Vector<float> key_times; + Vector<real_t> key_times; Array clips; int kk = ad->values.size(); key_times.resize(kk); - float *wti = key_times.ptrw(); + real_t *wti = key_times.ptrw(); int idx = 0; @@ -533,7 +533,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - Vector<float> key_times; + Vector<real_t> key_times; Vector<String> clips; int kk = an->values.size(); @@ -541,7 +541,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { key_times.resize(kk); clips.resize(kk); - float *wti = key_times.ptrw(); + real_t *wti = key_times.ptrw(); String *wcl = clips.ptrw(); const TKey<StringName> *vls = an->values.ptr(); @@ -722,7 +722,7 @@ bool Animation::track_get_interpolation_loop_wrap(int p_track) const { // transform /* template<class T> -int Animation::_insert_pos(float p_time, T& p_keys) { +int Animation::_insert_pos(double p_time, T& p_keys) { // simple, linear time inset that should be fast enough in reality. int idx=p_keys.size(); @@ -745,12 +745,12 @@ int Animation::_insert_pos(float p_time, T& p_keys) { */ template <class T, class V> -int Animation::_insert(float p_time, T &p_keys, const V &p_value) { +int Animation::_insert(double p_time, T &p_keys, const V &p_value) { int idx = p_keys.size(); while (true) { // Condition for replacement. - if (idx > 0 && Math::is_equal_approx(p_keys[idx - 1].time, p_time)) { + if (idx > 0 && Math::is_equal_approx((double)p_keys[idx - 1].time, p_time)) { float transition = p_keys[idx - 1].transition; p_keys.write[idx - 1] = p_value; p_keys.write[idx - 1].transition = transition; @@ -794,7 +794,7 @@ Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, return OK; } -int Animation::transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quaternion &p_rot, const Vector3 &p_scale) { +int Animation::transform_track_insert_key(int p_track, double p_time, const Vector3 &p_loc, const Quaternion &p_rot, const Vector3 &p_scale) { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM3D, -1); @@ -812,7 +812,7 @@ int Animation::transform_track_insert_key(int p_track, float p_time, const Vecto return ret; } -void Animation::track_remove_key_at_time(int p_track, float p_time) { +void Animation::track_remove_key_at_time(int p_track, double p_time) { int idx = track_find_key(p_track, p_time, true); ERR_FAIL_COND(idx < 0); track_remove_key(p_track, idx); @@ -864,7 +864,7 @@ void Animation::track_remove_key(int p_track, int p_idx) { emit_changed(); } -int Animation::track_find_key(int p_track, float p_time, bool p_exact) const { +int Animation::track_find_key(int p_track, double p_time, bool p_exact) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; @@ -946,7 +946,7 @@ int Animation::track_find_key(int p_track, float p_time, bool p_exact) const { return -1; } -void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition) { +void Animation::track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; @@ -1151,7 +1151,7 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const { ERR_FAIL_V(Variant()); } -float Animation::track_get_key_time(int p_track, int p_key_idx) const { +double Animation::track_get_key_time(int p_track, int p_key_idx) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; @@ -1196,7 +1196,7 @@ float Animation::track_get_key_time(int p_track, int p_key_idx) const { ERR_FAIL_V(-1); } -void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) { +void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; @@ -1260,7 +1260,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) { ERR_FAIL(); } -float Animation::track_get_key_transition(int p_track, int p_key_idx) const { +real_t Animation::track_get_key_transition(int p_track, int p_key_idx) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; @@ -1379,7 +1379,7 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p emit_changed(); } -void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_transition) { +void Animation::track_set_key_transition(int p_track, int p_key_idx, real_t p_transition) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; @@ -1412,7 +1412,7 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_tra } template <class K> -int Animation::_find(const Vector<K> &p_keys, float p_time) const { +int Animation::_find(const Vector<K> &p_keys, double p_time) const { int len = p_keys.size(); if (len == 0) { return -2; @@ -1433,7 +1433,7 @@ int Animation::_find(const Vector<K> &p_keys, float p_time) const { while (low <= high) { middle = (low + high) / 2; - if (Math::is_equal_approx(p_time, keys[middle].time)) { //match + if (Math::is_equal_approx(p_time, (double)keys[middle].time)) { //match return middle; } else if (p_time < keys[middle].time) { high = middle - 1; //search low end of array @@ -1449,7 +1449,7 @@ int Animation::_find(const Vector<K> &p_keys, float p_time) const { return middle; } -Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, float p_c) const { +Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, real_t p_c) const { TransformKey ret; ret.loc = _interpolate(p_a.loc, p_b.loc, p_c); ret.rot = _interpolate(p_a.rot, p_b.rot, p_c); @@ -1458,25 +1458,25 @@ Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p return ret; } -Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const { +Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, real_t p_c) const { return p_a.lerp(p_b, p_c); } -Quaternion Animation::_interpolate(const Quaternion &p_a, const Quaternion &p_b, float p_c) const { +Quaternion Animation::_interpolate(const Quaternion &p_a, const Quaternion &p_b, real_t p_c) const { return p_a.slerp(p_b, p_c); } -Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, float p_c) const { +Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, real_t p_c) const { Variant dst; Variant::interpolate(p_a, p_b, p_c, dst); return dst; } -float Animation::_interpolate(const float &p_a, const float &p_b, float p_c) const { +real_t Animation::_interpolate(const real_t &p_a, const real_t &p_b, real_t p_c) const { return p_a * (1.0 - p_c) + p_b * p_c; } -Animation::TransformKey Animation::_cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, float p_c) const { +Animation::TransformKey Animation::_cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, real_t p_c) const { Animation::TransformKey tk; tk.loc = p_a.loc.cubic_interpolate(p_b.loc, p_pre_a.loc, p_post_b.loc, p_c); @@ -1486,15 +1486,15 @@ Animation::TransformKey Animation::_cubic_interpolate(const Animation::Transform return tk; } -Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const { +Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c) const { return p_a.cubic_interpolate(p_b, p_pre_a, p_post_b, p_c); } -Quaternion Animation::_cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, float p_c) const { +Quaternion Animation::_cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c) const { return p_a.cubic_slerp(p_b, p_pre_a, p_post_b, p_c); } -Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const { +Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c) const { Variant::Type type_a = p_a.get_type(); Variant::Type type_b = p_b.get_type(); Variant::Type type_pa = p_pre_a.get_type(); @@ -1515,9 +1515,9 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a real_t p2 = p_b; real_t p3 = p_post_b; - float t = p_c; - float t2 = t * t; - float t3 = t2 * t; + real_t t = p_c; + real_t t2 = t * t; + real_t t3 = t2 * t; return 0.5f * ((p1 * 2.0f) + (-p0 + p2) * t + @@ -1579,12 +1579,12 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a } } -float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const { +real_t Animation::_cubic_interpolate(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c) const { return _interpolate(p_a, p_b, p_c); } template <class T> -T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const { +T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const { int len = _find(p_keys, length) + 1; // try to find last key (there may be more past the end) if (len <= 0) { @@ -1608,7 +1608,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola bool result = true; int next = 0; - float c = 0.0; + real_t c = 0.0; // prepare for all cases of interpolation if (loop && p_loop_wrap) { @@ -1616,8 +1616,8 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola if (idx >= 0) { if ((idx + 1) < len) { next = idx + 1; - float delta = p_keys[next].time - p_keys[idx].time; - float from = p_time - p_keys[idx].time; + real_t delta = p_keys[next].time - p_keys[idx].time; + real_t from = p_time - p_keys[idx].time; if (Math::is_zero_approx(delta)) { c = 0; @@ -1627,8 +1627,8 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola } else { next = 0; - float delta = (length - p_keys[idx].time) + p_keys[next].time; - float from = p_time - p_keys[idx].time; + real_t delta = (length - p_keys[idx].time) + p_keys[next].time; + real_t from = p_time - p_keys[idx].time; if (Math::is_zero_approx(delta)) { c = 0; @@ -1641,12 +1641,12 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola // on loop, behind first key idx = len - 1; next = 0; - float endtime = (length - p_keys[idx].time); + real_t endtime = (length - p_keys[idx].time); if (endtime < 0) { // may be keys past the end endtime = 0; } - float delta = endtime + p_keys[next].time; - float from = endtime + p_time; + real_t delta = endtime + p_keys[next].time; + real_t from = endtime + p_time; if (Math::is_zero_approx(delta)) { c = 0; @@ -1660,8 +1660,8 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola if (idx >= 0) { if ((idx + 1) < len) { next = idx + 1; - float delta = p_keys[next].time - p_keys[idx].time; - float from = p_time - p_keys[idx].time; + real_t delta = p_keys[next].time - p_keys[idx].time; + real_t from = p_time - p_keys[idx].time; if (Math::is_zero_approx(delta)) { c = 0; @@ -1690,7 +1690,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola return T(); } - float tr = p_keys[idx].transition; + real_t tr = p_keys[idx].transition; if (tr == 0 || idx == next) { // don't interpolate if not needed @@ -1728,7 +1728,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola // do a barrel roll } -Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const { +Error Animation::transform_track_interpolate(int p_track, double p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM3D, ERR_INVALID_PARAMETER); @@ -1758,7 +1758,7 @@ Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3 return OK; } -Variant Animation::value_track_interpolate(int p_track, float p_time) const { +Variant Animation::value_track_interpolate(int p_track, double p_time) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), 0); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_VALUE, Variant()); @@ -1775,7 +1775,7 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const { return Variant(); } -void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const { +void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, double from_time, double to_time, List<int> *p_indices) const { if (from_time != length && to_time == length) { to_time = length * 1.001; //include a little more if at the end } @@ -1812,15 +1812,15 @@ void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, floa } } -void Animation::value_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const { +void Animation::value_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices) const { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_VALUE); ValueTrack *vt = static_cast<ValueTrack *>(t); - float from_time = p_time - p_delta; - float to_time = p_time; + double from_time = p_time - p_delta; + double to_time = p_time; if (from_time > to_time) { SWAP(from_time, to_time); @@ -1875,7 +1875,7 @@ Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const } template <class T> -void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, float from_time, float to_time, List<int> *p_indices) const { +void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices) const { if (from_time != length && to_time == length) { to_time = length * 1.01; //include a little more if at the end } @@ -1908,12 +1908,12 @@ void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, float } } -void Animation::track_get_key_indices_in_range(int p_track, float p_time, float p_delta, List<int> *p_indices) const { +void Animation::track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices) const { ERR_FAIL_INDEX(p_track, tracks.size()); const Track *t = tracks[p_track]; - float from_time = p_time - p_delta; - float to_time = p_time; + double from_time = p_time - p_delta; + double to_time = p_time; if (from_time > to_time) { SWAP(from_time, to_time); @@ -2021,7 +2021,7 @@ void Animation::track_get_key_indices_in_range(int p_track, float p_time, float } } -void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const { +void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, double from_time, double to_time, List<int> *p_indices) const { if (from_time != length && to_time == length) { to_time = length * 1.01; //include a little more if at the end } @@ -2054,15 +2054,15 @@ void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, fl } } -void Animation::method_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const { +void Animation::method_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices) const { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_METHOD); MethodTrack *mt = static_cast<MethodTrack *>(t); - float from_time = p_time - p_delta; - float to_time = p_time; + double from_time = p_time - p_delta; + double to_time = p_time; if (from_time > to_time) { SWAP(from_time, to_time); @@ -2128,7 +2128,7 @@ StringName Animation::method_track_get_name(int p_track, int p_key_idx) const { return pm->methods[p_key_idx].method; } -int Animation::bezier_track_insert_key(int p_track, float p_time, float p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle) { +int Animation::bezier_track_insert_key(int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle) { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_BEZIER, -1); @@ -2154,7 +2154,7 @@ int Animation::bezier_track_insert_key(int p_track, float p_time, float p_value, return key; } -void Animation::bezier_track_set_key_value(int p_track, int p_index, float p_value) { +void Animation::bezier_track_set_key_value(int p_track, int p_index, real_t p_value) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_BEZIER); @@ -2199,7 +2199,7 @@ void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const emit_changed(); } -float Animation::bezier_track_get_key_value(int p_track, int p_index) const { +real_t Animation::bezier_track_get_key_value(int p_track, int p_index) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), 0); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_BEZIER, 0); @@ -2246,7 +2246,7 @@ static _FORCE_INLINE_ Vector2 _bezier_interp(real_t t, const Vector2 &start, con return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3; } -float Animation::bezier_track_interpolate(int p_track, float p_time) const { +real_t Animation::bezier_track_interpolate(int p_track, double p_time) const { //this uses a different interpolation scheme ERR_FAIL_INDEX_V(p_track, tracks.size(), 0); Track *track = tracks[p_track]; @@ -2277,14 +2277,14 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const { return bt->values[bt->values.size() - 1].value.value; } - float t = p_time - bt->values[idx].time; + double t = p_time - bt->values[idx].time; int iterations = 10; - float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes - float low = 0.0; // 0% of the current animation segment - float high = 1.0; // 100% of the current animation segment - float middle; + real_t duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes + real_t low = 0.0; // 0% of the current animation segment + real_t high = 1.0; // 100% of the current animation segment + real_t middle; Vector2 start(0, bt->values[idx].value.value); Vector2 start_out = start + bt->values[idx].value.out_handle; @@ -2307,12 +2307,12 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const { //interpolate the result: Vector2 low_pos = _bezier_interp(low, start, start_out, end_in, end); Vector2 high_pos = _bezier_interp(high, start, start_out, end_in, end); - float c = (t - low_pos.x) / (high_pos.x - low_pos.x); + real_t c = (t - low_pos.x) / (high_pos.x - low_pos.x); return low_pos.lerp(high_pos, c).y; } -int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_stream, float p_start_offset, float p_end_offset) { +int Animation::audio_track_insert_key(int p_track, double p_time, const RES &p_stream, real_t p_start_offset, real_t p_end_offset) { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_AUDIO, -1); @@ -2352,7 +2352,7 @@ void Animation::audio_track_set_key_stream(int p_track, int p_key, const RES &p_ emit_changed(); } -void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p_offset) { +void Animation::audio_track_set_key_start_offset(int p_track, int p_key, real_t p_offset) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_AUDIO); @@ -2370,7 +2370,7 @@ void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p emit_changed(); } -void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_offset) { +void Animation::audio_track_set_key_end_offset(int p_track, int p_key, real_t p_offset) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_AUDIO); @@ -2400,7 +2400,7 @@ RES Animation::audio_track_get_key_stream(int p_track, int p_key) const { return at->values[p_key].value.stream; } -float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const { +real_t Animation::audio_track_get_key_start_offset(int p_track, int p_key) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), 0); const Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0); @@ -2412,7 +2412,7 @@ float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const return at->values[p_key].value.start_offset; } -float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const { +real_t Animation::audio_track_get_key_end_offset(int p_track, int p_key) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), 0); const Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0); @@ -2426,7 +2426,7 @@ float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const { // -int Animation::animation_track_insert_key(int p_track, float p_time, const StringName &p_animation) { +int Animation::animation_track_insert_key(int p_track, double p_time, const StringName &p_animation) { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, -1); @@ -2470,7 +2470,7 @@ StringName Animation::animation_track_get_key_animation(int p_track, int p_key) return at->values[p_key].value; } -void Animation::set_length(float p_length) { +void Animation::set_length(real_t p_length) { if (p_length < ANIM_MIN_LENGTH) { p_length = ANIM_MIN_LENGTH; } @@ -2478,7 +2478,7 @@ void Animation::set_length(float p_length) { emit_changed(); } -float Animation::get_length() const { +real_t Animation::get_length() const { return length; } @@ -2558,12 +2558,12 @@ void Animation::track_swap(int p_track, int p_with_track) { emit_signal(SceneStringNames::get_singleton()->tracks_changed); } -void Animation::set_step(float p_step) { +void Animation::set_step(real_t p_step) { step = p_step; emit_changed(); } -float Animation::get_step() const { +real_t Animation::get_step() const { return step; } @@ -2708,7 +2708,7 @@ void Animation::clear() { emit_signal(SceneStringNames::get_singleton()->tracks_changed); } -bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err, float p_alowed_angular_err, float p_max_optimizable_angle, const Vector3 &p_norm) { +bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, real_t p_alowed_linear_err, real_t p_alowed_angular_err, real_t p_max_optimizable_angle, const Vector3 &p_norm) { real_t c = (t1.time - t0.time) / (t2.time - t0.time); real_t t[3] = { -1, -1, -1 }; @@ -2727,9 +2727,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons } else { Vector3 pd = (v2 - v0); - float d0 = pd.dot(v0); - float d1 = pd.dot(v1); - float d2 = pd.dot(v2); + real_t d0 = pd.dot(v0); + real_t d1 = pd.dot(v1); + real_t d2 = pd.dot(v2); if (d1 < d0 || d1 > d2) { return false; } @@ -2817,9 +2817,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons } else { Vector3 pd = (v2 - v0); - float d0 = pd.dot(v0); - float d1 = pd.dot(v1); - float d2 = pd.dot(v2); + real_t d0 = pd.dot(v0); + real_t d1 = pd.dot(v1); + real_t d2 = pd.dot(v2); if (d1 < d0 || d1 > d2) { return false; //beyond segment range } @@ -2875,7 +2875,7 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons return erase; } -void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) { +void Animation::_transform_track_optimize(int p_idx, real_t p_allowed_linear_err, real_t p_allowed_angular_err, real_t p_max_optimizable_angle) { ERR_FAIL_INDEX(p_idx, tracks.size()); ERR_FAIL_COND(tracks[p_idx]->type != TYPE_TRANSFORM3D); TransformTrack *tt = static_cast<TransformTrack *>(tracks[p_idx]); @@ -2915,7 +2915,7 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err, } } -void Animation::optimize(float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) { +void Animation::optimize(real_t p_allowed_linear_err, real_t p_allowed_angular_err, real_t p_max_optimizable_angle) { for (int i = 0; i < tracks.size(); i++) { if (tracks[i]->type == TYPE_TRANSFORM3D) { _transform_track_optimize(i, p_allowed_linear_err, p_allowed_angular_err, p_max_optimizable_angle); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 920ee2e5ab..6227f6967f 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -76,8 +76,8 @@ private: }; struct Key { - float transition = 1.0; - float time = 0.0; // time in secs + real_t transition = 1.0; + double time = 0.0; // time in secs }; // transform key holds either Vector3 or Quaternion @@ -129,7 +129,7 @@ private: struct BezierKey { Vector2 in_handle; //relative (x always <0) Vector2 out_handle; //relative (x always >0) - float value = 0.0; + real_t value = 0.0; }; struct BezierTrack : public Track { @@ -144,8 +144,8 @@ private: struct AudioKey { RES stream; - float start_offset = 0.0; //offset from start - float end_offset = 0.0; //offset from end, if 0 then full length or infinite + real_t start_offset = 0.0; //offset from start + real_t end_offset = 0.0; //offset from end, if 0 then full length or infinite AudioKey() { } }; @@ -172,46 +172,46 @@ private: /* template<class T> - int _insert_pos(float p_time, T& p_keys);*/ + int _insert_pos(double p_time, T& p_keys);*/ template <class T> void _clear(T &p_keys); template <class T, class V> - int _insert(float p_time, T &p_keys, const V &p_value); + int _insert(double p_time, T &p_keys, const V &p_value); template <class K> - inline int _find(const Vector<K> &p_keys, float p_time) const; + inline int _find(const Vector<K> &p_keys, double p_time) const; - _FORCE_INLINE_ Animation::TransformKey _interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, float p_c) const; + _FORCE_INLINE_ Animation::TransformKey _interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, real_t p_c) const; - _FORCE_INLINE_ Vector3 _interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const; - _FORCE_INLINE_ Quaternion _interpolate(const Quaternion &p_a, const Quaternion &p_b, float p_c) const; - _FORCE_INLINE_ Variant _interpolate(const Variant &p_a, const Variant &p_b, float p_c) const; - _FORCE_INLINE_ float _interpolate(const float &p_a, const float &p_b, float p_c) const; + _FORCE_INLINE_ Vector3 _interpolate(const Vector3 &p_a, const Vector3 &p_b, real_t p_c) const; + _FORCE_INLINE_ Quaternion _interpolate(const Quaternion &p_a, const Quaternion &p_b, real_t p_c) const; + _FORCE_INLINE_ Variant _interpolate(const Variant &p_a, const Variant &p_b, real_t p_c) const; + _FORCE_INLINE_ real_t _interpolate(const real_t &p_a, const real_t &p_b, real_t p_c) const; - _FORCE_INLINE_ Animation::TransformKey _cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, float p_c) const; - _FORCE_INLINE_ Vector3 _cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const; - _FORCE_INLINE_ Quaternion _cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, float p_c) const; - _FORCE_INLINE_ Variant _cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const; - _FORCE_INLINE_ float _cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const; + _FORCE_INLINE_ Animation::TransformKey _cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, real_t p_c) const; + _FORCE_INLINE_ Vector3 _cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c) const; + _FORCE_INLINE_ Quaternion _cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c) const; + _FORCE_INLINE_ Variant _cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c) const; + _FORCE_INLINE_ real_t _cubic_interpolate(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c) const; template <class T> - _FORCE_INLINE_ T _interpolate(const Vector<TKey<T>> &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const; + _FORCE_INLINE_ T _interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const; template <class T> - _FORCE_INLINE_ void _track_get_key_indices_in_range(const Vector<T> &p_array, float from_time, float to_time, List<int> *p_indices) const; + _FORCE_INLINE_ void _track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices) const; - _FORCE_INLINE_ void _value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const; - _FORCE_INLINE_ void _method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const; + _FORCE_INLINE_ void _value_track_get_key_indices_in_range(const ValueTrack *vt, double from_time, double to_time, List<int> *p_indices) const; + _FORCE_INLINE_ void _method_track_get_key_indices_in_range(const MethodTrack *mt, double from_time, double to_time, List<int> *p_indices) const; - float length = 1.0; - float step = 0.1; + double length = 1.0; + real_t step = 0.1; bool loop = false; // bind helpers private: - Array _transform_track_interpolate(int p_track, float p_time) const { + Array _transform_track_interpolate(int p_track, double p_time) const { Vector3 loc; Quaternion rot; Vector3 scale; @@ -223,7 +223,7 @@ private: return ret; } - Vector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const { + Vector<int> _value_track_get_key_indices(int p_track, double p_time, double p_delta) const { List<int> idxs; value_track_get_key_indices(p_track, p_time, p_delta, &idxs); Vector<int> idxr; @@ -233,7 +233,7 @@ private: } return idxr; } - Vector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const { + Vector<int> _method_track_get_key_indices(int p_track, double p_time, double p_delta) const { List<int> idxs; method_track_get_key_indices(p_track, p_time, p_delta, &idxs); Vector<int> idxr; @@ -244,8 +244,8 @@ private: return idxr; } - bool _transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err, float p_alowed_angular_err, float p_max_optimizable_angle, const Vector3 &p_norm); - void _transform_track_optimize(int p_idx, float p_allowed_linear_err = 0.05, float p_allowed_angular_err = 0.01, float p_max_optimizable_angle = Math_PI * 0.125); + bool _transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, real_t p_alowed_linear_err, real_t p_alowed_angular_err, real_t p_max_optimizable_angle, const Vector3 &p_norm); + void _transform_track_optimize(int p_idx, real_t p_allowed_linear_err = 0.05, real_t p_allowed_angular_err = 0.01, real_t p_max_optimizable_angle = Math_PI * 0.125); protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -279,75 +279,75 @@ public: void track_set_enabled(int p_track, bool p_enabled); bool track_is_enabled(int p_track) const; - void track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition = 1); - void track_set_key_transition(int p_track, int p_key_idx, float p_transition); + void track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition = 1); + void track_set_key_transition(int p_track, int p_key_idx, real_t p_transition); void track_set_key_value(int p_track, int p_key_idx, const Variant &p_value); - void track_set_key_time(int p_track, int p_key_idx, float p_time); - int track_find_key(int p_track, float p_time, bool p_exact = false) const; + void track_set_key_time(int p_track, int p_key_idx, double p_time); + int track_find_key(int p_track, double p_time, bool p_exact = false) const; void track_remove_key(int p_track, int p_idx); - void track_remove_key_at_time(int p_track, float p_time); + void track_remove_key_at_time(int p_track, double p_time); int track_get_key_count(int p_track) const; Variant track_get_key_value(int p_track, int p_key_idx) const; - float track_get_key_time(int p_track, int p_key_idx) const; - float track_get_key_transition(int p_track, int p_key_idx) const; + double track_get_key_time(int p_track, int p_key_idx) const; + real_t track_get_key_transition(int p_track, int p_key_idx) const; - int transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quaternion &p_rot = Quaternion(), const Vector3 &p_scale = Vector3()); + int transform_track_insert_key(int p_track, double p_time, const Vector3 &p_loc, const Quaternion &p_rot = Quaternion(), const Vector3 &p_scale = Vector3()); Error transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const; void track_set_interpolation_type(int p_track, InterpolationType p_interp); InterpolationType track_get_interpolation_type(int p_track) const; - int bezier_track_insert_key(int p_track, float p_time, float p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle); - void bezier_track_set_key_value(int p_track, int p_index, float p_value); + int bezier_track_insert_key(int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle); + void bezier_track_set_key_value(int p_track, int p_index, real_t p_value); void bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle); void bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle); - float bezier_track_get_key_value(int p_track, int p_index) const; + real_t bezier_track_get_key_value(int p_track, int p_index) const; Vector2 bezier_track_get_key_in_handle(int p_track, int p_index) const; Vector2 bezier_track_get_key_out_handle(int p_track, int p_index) const; - float bezier_track_interpolate(int p_track, float p_time) const; + real_t bezier_track_interpolate(int p_track, double p_time) const; - int audio_track_insert_key(int p_track, float p_time, const RES &p_stream, float p_start_offset = 0, float p_end_offset = 0); + int audio_track_insert_key(int p_track, double p_time, const RES &p_stream, real_t p_start_offset = 0, real_t p_end_offset = 0); void audio_track_set_key_stream(int p_track, int p_key, const RES &p_stream); - void audio_track_set_key_start_offset(int p_track, int p_key, float p_offset); - void audio_track_set_key_end_offset(int p_track, int p_key, float p_offset); + void audio_track_set_key_start_offset(int p_track, int p_key, real_t p_offset); + void audio_track_set_key_end_offset(int p_track, int p_key, real_t p_offset); RES audio_track_get_key_stream(int p_track, int p_key) const; - float audio_track_get_key_start_offset(int p_track, int p_key) const; - float audio_track_get_key_end_offset(int p_track, int p_key) const; + real_t audio_track_get_key_start_offset(int p_track, int p_key) const; + real_t audio_track_get_key_end_offset(int p_track, int p_key) const; - int animation_track_insert_key(int p_track, float p_time, const StringName &p_animation); + int animation_track_insert_key(int p_track, double p_time, const StringName &p_animation); void animation_track_set_key_animation(int p_track, int p_key, const StringName &p_animation); StringName animation_track_get_key_animation(int p_track, int p_key) const; void track_set_interpolation_loop_wrap(int p_track, bool p_enable); bool track_get_interpolation_loop_wrap(int p_track) const; - Error transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const; + Error transform_track_interpolate(int p_track, double p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const; - Variant value_track_interpolate(int p_track, float p_time) const; - void value_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const; + Variant value_track_interpolate(int p_track, double p_time) const; + void value_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices) const; void value_track_set_update_mode(int p_track, UpdateMode p_mode); UpdateMode value_track_get_update_mode(int p_track) const; - void method_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const; + void method_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices) const; Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const; StringName method_track_get_name(int p_track, int p_key_idx) const; void copy_track(int p_track, Ref<Animation> p_to_animation); - void track_get_key_indices_in_range(int p_track, float p_time, float p_delta, List<int> *p_indices) const; + void track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices) const; - void set_length(float p_length); - float get_length() const; + void set_length(real_t p_length); + real_t get_length() const; void set_loop(bool p_enabled); bool has_loop() const; - void set_step(float p_step); - float get_step() const; + void set_step(real_t p_step); + real_t get_step() const; void clear(); - void optimize(float p_allowed_linear_err = 0.05, float p_allowed_angular_err = 0.01, float p_max_optimizable_angle = Math_PI * 0.125); + void optimize(real_t p_allowed_linear_err = 0.05, real_t p_allowed_angular_err = 0.01, real_t p_max_optimizable_angle = Math_PI * 0.125); Animation(); ~Animation(); diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index c13db83d6d..3b666640f8 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -1366,7 +1366,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const { frac /= bake_interval; } - return Math::lerp(r[idx], r[idx + 1], frac); + return Math::lerp(r[idx], r[idx + 1], (real_t)frac); } Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) const { @@ -1424,7 +1424,7 @@ PackedVector3Array Curve3D::get_baked_points() const { return baked_point_cache; } -PackedFloat32Array Curve3D::get_baked_tilts() const { +Vector<real_t> Curve3D::get_baked_tilts() const { if (baked_cache_dirty) { _bake(); } @@ -1545,7 +1545,7 @@ Dictionary Curve3D::_get_data() const { PackedVector3Array d; d.resize(points.size() * 3); Vector3 *w = d.ptrw(); - PackedFloat32Array t; + Vector<real_t> t; t.resize(points.size()); real_t *wt = t.ptrw(); @@ -1571,7 +1571,7 @@ void Curve3D::_set_data(const Dictionary &p_data) { ERR_FAIL_COND(pc % 3 != 0); points.resize(pc / 3); const Vector3 *r = rp.ptr(); - PackedFloat32Array rtl = p_data["tilts"]; + Vector<real_t> rtl = p_data["tilts"]; const real_t *rt = rtl.ptr(); for (int i = 0; i < points.size(); i++) { diff --git a/scene/resources/curve.h b/scene/resources/curve.h index 746c6fa597..c25d307608 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -222,7 +222,7 @@ class Curve3D : public Resource { mutable bool baked_cache_dirty = false; mutable PackedVector3Array baked_point_cache; - mutable PackedFloat32Array baked_tilt_cache; + mutable Vector<real_t> baked_tilt_cache; mutable PackedVector3Array baked_up_vector_cache; mutable float baked_max_ofs = 0.0; @@ -265,7 +265,7 @@ public: float interpolate_baked_tilt(float p_offset) const; Vector3 interpolate_baked_up_vector(float p_offset, bool p_apply_tilt = false) const; PackedVector3Array get_baked_points() const; //useful for going through - PackedFloat32Array get_baked_tilts() const; //useful for going through + Vector<real_t> get_baked_tilts() const; //useful for going through PackedVector3Array get_baked_up_vectors() const; Vector3 get_closest_point(const Vector3 &p_to_point) const; float get_closest_offset(const Vector3 &p_to_point) const; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index efc37709a5..ceb4c0faa3 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -955,6 +955,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("more", "GraphEdit", make_icon(icon_zoom_more_png)); theme->set_icon("snap", "GraphEdit", make_icon(icon_snap_grid_png)); theme->set_icon("minimap", "GraphEdit", make_icon(icon_grid_minimap_png)); + theme->set_icon("layout", "GraphEdit", make_icon(icon_grid_layout_png)); theme->set_stylebox("bg", "GraphEdit", make_stylebox(tree_bg_png, 4, 4, 4, 5)); theme->set_color("grid_minor", "GraphEdit", Color(1, 1, 1, 0.05)); theme->set_color("grid_major", "GraphEdit", Color(1, 1, 1, 0.2)); diff --git a/scene/resources/default_theme/icon_grid_layout.png b/scene/resources/default_theme/icon_grid_layout.png Binary files differnew file mode 100644 index 0000000000..00a6179d5e --- /dev/null +++ b/scene/resources/default_theme/icon_grid_layout.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 97e64e4746..865ee86c76 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -182,6 +182,10 @@ static const unsigned char icon_grid_minimap_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc3, 0x0, 0x0, 0xe, 0xc3, 0x1, 0xc7, 0x6f, 0xa8, 0x64, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x2, 0xd, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x75, 0x93, 0x31, 0x68, 0x14, 0x51, 0x10, 0x86, 0xbf, 0xd9, 0xd, 0xbb, 0xde, 0x76, 0x82, 0x21, 0xf8, 0xe0, 0xbc, 0x5d, 0x8b, 0x80, 0x69, 0x6c, 0xd2, 0x5a, 0x6a, 0x91, 0xc3, 0xd2, 0x46, 0x22, 0x8, 0x9, 0x89, 0x70, 0x85, 0x10, 0x41, 0xd, 0x24, 0x45, 0xb0, 0xb, 0x68, 0x11, 0x14, 0x24, 0x10, 0x22, 0x62, 0x21, 0x41, 0xe, 0x4b, 0x21, 0xa4, 0xb7, 0x49, 0x17, 0xb1, 0x8, 0xb9, 0xdd, 0xc7, 0x86, 0x33, 0x21, 0xe1, 0x3a, 0x8f, 0x64, 0x61, 0x6f, 0x2c, 0xbc, 0x3b, 0x36, 0xb9, 0xdc, 0xc0, 0x2b, 0xde, 0xcc, 0xfc, 0xf3, 0xff, 0xfc, 0xcc, 0x48, 0xa3, 0xd1, 0x78, 0x20, 0x22, 0x13, 0xbe, 0xef, 0xaf, 0xdf, 0xac, 0xd7, 0x1f, 0xe1, 0x38, 0xd3, 0xa8, 0x2a, 0xf0, 0x45, 0x6a, 0xb5, 0xcf, 0x5c, 0x11, 0xcd, 0x66, 0x33, 0x38, 0x3f, 0x3f, 0x9f, 0x13, 0x91, 0x7d, 0xb1, 0xd6, 0x6e, 0xaa, 0xea, 0xd3, 0xe0, 0xe8, 0xe8, 0xde, 0xe8, 0xee, 0xee, 0x37, 0xc0, 0xe9, 0xf6, 0x75, 0xf0, 0xfd, 0x9, 0x99, 0x9d, 0x6d, 0x15, 0x81, 0x59, 0x96, 0x3d, 0x3, 0x5e, 0x2, 0x63, 0x22, 0xf2, 0x69, 0xa4, 0x57, 0x1c, 0xdd, 0xdb, 0xfb, 0x5b, 0x0, 0x3, 0x38, 0x67, 0x41, 0x30, 0x11, 0xc7, 0xf1, 0x13, 0x0, 0x11, 0x71, 0xb2, 0x2c, 0x7b, 0xd8, 0xad, 0xad, 0x2, 0x6f, 0xb9, 0x0, 0x38, 0x3c, 0xfc, 0x5, 0x9c, 0xf6, 0xff, 0x22, 0x27, 0x27, 0xe3, 0xe3, 0x7f, 0xa, 0x3, 0x67, 0x45, 0xe4, 0xbb, 0xe7, 0x79, 0xb7, 0xc3, 0x30, 0x7c, 0xd7, 0x67, 0xe9, 0xe3, 0x67, 0x66, 0x5c, 0x60, 0x1, 0x50, 0x40, 0x51, 0x7d, 0x71, 0x6b, 0x72, 0xf2, 0x20, 0x8a, 0xa2, 0xf9, 0x28, 0x8a, 0xe6, 0x1, 0x3a, 0x9d, 0xce, 0x4f, 0x63, 0x4c, 0x3b, 0x4d, 0xd3, 0xd2, 0xc0, 0x80, 0x3c, 0xcf, 0xf, 0x92, 0xa9, 0xa9, 0x31, 0x60, 0x5, 0x58, 0x91, 0x5a, 0xed, 0xc7, 0x15, 0xfe, 0x95, 0xac, 0xb5, 0xcf, 0xf3, 0x3c, 0x3f, 0xe8, 0x25, 0x46, 0xa, 0xc5, 0xd, 0x11, 0x59, 0xb3, 0xd5, 0xea, 0x1b, 0xa0, 0x95, 0x54, 0xab, 0x5b, 0x97, 0xd1, 0x22, 0xb2, 0xa6, 0xaa, 0x6d, 0x60, 0xd, 0x58, 0xba, 0xa0, 0x20, 0xc, 0xc3, 0x65, 0xd7, 0x75, 0x23, 0xe0, 0x2e, 0xb0, 0x1, 0x5c, 0xbf, 0xf4, 0x0, 0xbe, 0xba, 0xae, 0x1b, 0x85, 0x61, 0xb8, 0x3c, 0xa0, 0x20, 0x4d, 0xd3, 0x52, 0xb9, 0x5c, 0x6e, 0xc5, 0x71, 0xbc, 0x23, 0x22, 0xd3, 0x61, 0x18, 0xde, 0x2f, 0xb2, 0x27, 0x49, 0xa2, 0xaa, 0xba, 0x53, 0x2e, 0x97, 0x5b, 0x69, 0x9a, 0x96, 0xf2, 0x3c, 0x1f, 0xf0, 0xc0, 0x5a, 0x6b, 0x5f, 0x1, 0x25, 0x86, 0x84, 0xe3, 0x38, 0x9e, 0xb5, 0x76, 0x2e, 0xcf, 0xf3, 0xfd, 0x1, 0x5, 0x22, 0xb2, 0xa1, 0xaa, 0x4b, 0x22, 0x72, 0xad, 0xcb, 0x38, 0xe0, 0x81, 0xaa, 0x7e, 0x0, 0xce, 0x44, 0xe4, 0xbd, 0xaa, 0xbe, 0xbe, 0xa0, 0xa0, 0x52, 0xa9, 0x2c, 0x7a, 0x9e, 0x17, 0x1, 0x3d, 0xe0, 0x55, 0x1e, 0x6c, 0x79, 0x9e, 0x17, 0x55, 0x2a, 0x95, 0xc5, 0x1, 0x5, 0xcd, 0x66, 0x33, 0x30, 0xc6, 0x9c, 0xc6, 0x71, 0xbc, 0x2d, 0x22, 0x8f, 0x87, 0x78, 0xb0, 0x6d, 0x8c, 0x39, 0xed, 0xae, 0x74, 0xdf, 0x83, 0x3a, 0x70, 0x9c, 0x65, 0x59, 0x23, 0x49, 0x92, 0x5, 0x11, 0x9, 0x86, 0x79, 0x20, 0x22, 0x41, 0x92, 0x24, 0xb, 0x59, 0x96, 0x35, 0x80, 0x63, 0xa0, 0x2e, 0x3d, 0xf6, 0xc2, 0x91, 0xdc, 0x0, 0x5c, 0x55, 0x5d, 0xbf, 0x4, 0x9e, 0x3, 0x72, 0xfe, 0xaf, 0xfb, 0xaa, 0xe7, 0x79, 0x1f, 0x8d, 0x31, 0x6d, 0x29, 0x36, 0xf5, 0xce, 0x14, 0xb8, 0x33, 0x44, 0xc4, 0x6f, 0xdf, 0xf7, 0xd7, 0x8d, 0x31, 0xed, 0x5e, 0xe2, 0x1f, 0xb, 0x5c, 0xe2, 0xcb, 0xd, 0x9b, 0x69, 0xcb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; +static const unsigned char icon_grid_layout_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc3, 0x0, 0x0, 0xe, 0xc3, 0x1, 0xc7, 0x6f, 0xa8, 0x64, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x2, 0xd, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x75, 0x93, 0x31, 0x68, 0x14, 0x51, 0x10, 0x86, 0xbf, 0xd9, 0xd, 0xbb, 0xde, 0x76, 0x82, 0x21, 0xf8, 0xe0, 0xbc, 0x5d, 0x8b, 0x80, 0x69, 0x6c, 0xd2, 0x5a, 0x6a, 0x91, 0xc3, 0xd2, 0x46, 0x22, 0x8, 0x9, 0x89, 0x70, 0x85, 0x10, 0x41, 0xd, 0x24, 0x45, 0xb0, 0xb, 0x68, 0x11, 0x14, 0x24, 0x10, 0x22, 0x62, 0x21, 0x41, 0xe, 0x4b, 0x21, 0xa4, 0xb7, 0x49, 0x17, 0xb1, 0x8, 0xb9, 0xdd, 0xc7, 0x86, 0x33, 0x21, 0xe1, 0x3a, 0x8f, 0x64, 0x61, 0x6f, 0x2c, 0xbc, 0x3b, 0x36, 0xb9, 0xdc, 0xc0, 0x2b, 0xde, 0xcc, 0xfc, 0xf3, 0xff, 0xfc, 0xcc, 0x48, 0xa3, 0xd1, 0x78, 0x20, 0x22, 0x13, 0xbe, 0xef, 0xaf, 0xdf, 0xac, 0xd7, 0x1f, 0xe1, 0x38, 0xd3, 0xa8, 0x2a, 0xf0, 0x45, 0x6a, 0xb5, 0xcf, 0x5c, 0x11, 0xcd, 0x66, 0x33, 0x38, 0x3f, 0x3f, 0x9f, 0x13, 0x91, 0x7d, 0xb1, 0xd6, 0x6e, 0xaa, 0xea, 0xd3, 0xe0, 0xe8, 0xe8, 0xde, 0xe8, 0xee, 0xee, 0x37, 0xc0, 0xe9, 0xf6, 0x75, 0xf0, 0xfd, 0x9, 0x99, 0x9d, 0x6d, 0x15, 0x81, 0x59, 0x96, 0x3d, 0x3, 0x5e, 0x2, 0x63, 0x22, 0xf2, 0x69, 0xa4, 0x57, 0x1c, 0xdd, 0xdb, 0xfb, 0x5b, 0x0, 0x3, 0x38, 0x67, 0x41, 0x30, 0x11, 0xc7, 0xf1, 0x13, 0x0, 0x11, 0x71, 0xb2, 0x2c, 0x7b, 0xd8, 0xad, 0xad, 0x2, 0x6f, 0xb9, 0x0, 0x38, 0x3c, 0xfc, 0x5, 0x9c, 0xf6, 0xff, 0x22, 0x27, 0x27, 0xe3, 0xe3, 0x7f, 0xa, 0x3, 0x67, 0x45, 0xe4, 0xbb, 0xe7, 0x79, 0xb7, 0xc3, 0x30, 0x7c, 0xd7, 0x67, 0xe9, 0xe3, 0x67, 0x66, 0x5c, 0x60, 0x1, 0x50, 0x40, 0x51, 0x7d, 0x71, 0x6b, 0x72, 0xf2, 0x20, 0x8a, 0xa2, 0xf9, 0x28, 0x8a, 0xe6, 0x1, 0x3a, 0x9d, 0xce, 0x4f, 0x63, 0x4c, 0x3b, 0x4d, 0xd3, 0xd2, 0xc0, 0x80, 0x3c, 0xcf, 0xf, 0x92, 0xa9, 0xa9, 0x31, 0x60, 0x5, 0x58, 0x91, 0x5a, 0xed, 0xc7, 0x15, 0xfe, 0x95, 0xac, 0xb5, 0xcf, 0xf3, 0x3c, 0x3f, 0xe8, 0x25, 0x46, 0xa, 0xc5, 0xd, 0x11, 0x59, 0xb3, 0xd5, 0xea, 0x1b, 0xa0, 0x95, 0x54, 0xab, 0x5b, 0x97, 0xd1, 0x22, 0xb2, 0xa6, 0xaa, 0x6d, 0x60, 0xd, 0x58, 0xba, 0xa0, 0x20, 0xc, 0xc3, 0x65, 0xd7, 0x75, 0x23, 0xe0, 0x2e, 0xb0, 0x1, 0x5c, 0xbf, 0xf4, 0x0, 0xbe, 0xba, 0xae, 0x1b, 0x85, 0x61, 0xb8, 0x3c, 0xa0, 0x20, 0x4d, 0xd3, 0x52, 0xb9, 0x5c, 0x6e, 0xc5, 0x71, 0xbc, 0x23, 0x22, 0xd3, 0x61, 0x18, 0xde, 0x2f, 0xb2, 0x27, 0x49, 0xa2, 0xaa, 0xba, 0x53, 0x2e, 0x97, 0x5b, 0x69, 0x9a, 0x96, 0xf2, 0x3c, 0x1f, 0xf0, 0xc0, 0x5a, 0x6b, 0x5f, 0x1, 0x25, 0x86, 0x84, 0xe3, 0x38, 0x9e, 0xb5, 0x76, 0x2e, 0xcf, 0xf3, 0xfd, 0x1, 0x5, 0x22, 0xb2, 0xa1, 0xaa, 0x4b, 0x22, 0x72, 0xad, 0xcb, 0x38, 0xe0, 0x81, 0xaa, 0x7e, 0x0, 0xce, 0x44, 0xe4, 0xbd, 0xaa, 0xbe, 0xbe, 0xa0, 0xa0, 0x52, 0xa9, 0x2c, 0x7a, 0x9e, 0x17, 0x1, 0x3d, 0xe0, 0x55, 0x1e, 0x6c, 0x79, 0x9e, 0x17, 0x55, 0x2a, 0x95, 0xc5, 0x1, 0x5, 0xcd, 0x66, 0x33, 0x30, 0xc6, 0x9c, 0xc6, 0x71, 0xbc, 0x2d, 0x22, 0x8f, 0x87, 0x78, 0xb0, 0x6d, 0x8c, 0x39, 0xed, 0xae, 0x74, 0xdf, 0x83, 0x3a, 0x70, 0x9c, 0x65, 0x59, 0x23, 0x49, 0x92, 0x5, 0x11, 0x9, 0x86, 0x79, 0x20, 0x22, 0x41, 0x92, 0x24, 0xb, 0x59, 0x96, 0x35, 0x80, 0x63, 0xa0, 0x2e, 0x3d, 0xf6, 0xc2, 0x91, 0xdc, 0x0, 0x5c, 0x55, 0x5d, 0xbf, 0x4, 0x9e, 0x3, 0x72, 0xfe, 0xaf, 0xfb, 0xaa, 0xe7, 0x79, 0x1f, 0x8d, 0x31, 0x6d, 0x29, 0x36, 0xf5, 0xce, 0x14, 0xb8, 0x33, 0x44, 0xc4, 0x6f, 0xdf, 0xf7, 0xd7, 0x8d, 0x31, 0xed, 0x5e, 0xe2, 0x1f, 0xb, 0x5c, 0xe2, 0xcb, 0xd, 0x9b, 0x69, 0xcb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + static const unsigned char icon_parent_folder_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x68, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x33, 0xb8, 0x27, 0xfe, 0xe0, 0xfc, 0x83, 0x73, 0xf7, 0xc4, 0x71, 0x48, 0xdf, 0x11, 0x7b, 0x78, 0xe9, 0xc1, 0x3f, 0x20, 0xbc, 0xfe, 0x40, 0x12, 0x8f, 0x34, 0x4c, 0x9, 0xa6, 0xe1, 0x57, 0x80, 0x12, 0x17, 0x81, 0xf8, 0x2f, 0x58, 0xe1, 0x15, 0x34, 0x8b, 0x1e, 0x9c, 0x5, 0xa, 0x5e, 0xb8, 0x23, 0x6, 0x52, 0x70, 0x5b, 0x14, 0xac, 0xf0, 0xc, 0xaa, 0x82, 0x7d, 0xf, 0x8e, 0xde, 0x14, 0xf9, 0xcf, 0x8, 0x52, 0xc0, 0xc0, 0x70, 0x5b, 0xf4, 0xe1, 0xc9, 0x7, 0x47, 0xb1, 0xb8, 0x3, 0xaa, 0x0, 0xa, 0x48, 0x52, 0x80, 0xb0, 0xea, 0xc8, 0xc3, 0x83, 0xc, 0x83, 0xe, 0x0, 0x0, 0xb8, 0x27, 0x55, 0x4c, 0xbe, 0xc0, 0xd2, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; diff --git a/scene/resources/height_map_shape_3d.cpp b/scene/resources/height_map_shape_3d.cpp index de5da944bc..d1a958ad38 100644 --- a/scene/resources/height_map_shape_3d.cpp +++ b/scene/resources/height_map_shape_3d.cpp @@ -41,7 +41,7 @@ Vector<Vector3> HeightMapShape3D::get_debug_mesh_lines() const { Vector2 size(map_width - 1, map_depth - 1); Vector2 start = size * -0.5; - const float *r = map_data.ptr(); + const real_t *r = map_data.ptr(); // reserve some memory for our points.. points.resize(((map_width - 1) * map_depth * 2) + (map_width * (map_depth - 1) * 2) + ((map_width - 1) * (map_depth - 1) * 2)); @@ -105,7 +105,7 @@ void HeightMapShape3D::set_map_width(int p_new) { int new_size = map_width * map_depth; map_data.resize(map_width * map_depth); - float *w = map_data.ptrw(); + real_t *w = map_data.ptrw(); while (was_size < new_size) { w[was_size++] = 0.0; } @@ -129,7 +129,7 @@ void HeightMapShape3D::set_map_depth(int p_new) { int new_size = map_width * map_depth; map_data.resize(new_size); - float *w = map_data.ptrw(); + real_t *w = map_data.ptrw(); while (was_size < new_size) { w[was_size++] = 0.0; } @@ -143,7 +143,7 @@ int HeightMapShape3D::get_map_depth() const { return map_depth; } -void HeightMapShape3D::set_map_data(PackedFloat32Array p_new) { +void HeightMapShape3D::set_map_data(Vector<real_t> p_new) { int size = (map_width * map_depth); if (p_new.size() != size) { // fail @@ -151,10 +151,10 @@ void HeightMapShape3D::set_map_data(PackedFloat32Array p_new) { } // copy - float *w = map_data.ptrw(); - const float *r = p_new.ptr(); + real_t *w = map_data.ptrw(); + const real_t *r = p_new.ptr(); for (int i = 0; i < size; i++) { - float val = r[i]; + real_t val = r[i]; w[i] = val; if (i == 0) { min_height = val; @@ -174,7 +174,7 @@ void HeightMapShape3D::set_map_data(PackedFloat32Array p_new) { notify_change_to_owners(); } -PackedFloat32Array HeightMapShape3D::get_map_data() const { +Vector<real_t> HeightMapShape3D::get_map_data() const { return map_data; } @@ -194,7 +194,7 @@ void HeightMapShape3D::_bind_methods() { HeightMapShape3D::HeightMapShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_HEIGHTMAP)) { map_data.resize(map_width * map_depth); - float *w = map_data.ptrw(); + real_t *w = map_data.ptrw(); w[0] = 0.0; w[1] = 0.0; w[2] = 0.0; diff --git a/scene/resources/height_map_shape_3d.h b/scene/resources/height_map_shape_3d.h index 1219791c56..1273aee040 100644 --- a/scene/resources/height_map_shape_3d.h +++ b/scene/resources/height_map_shape_3d.h @@ -38,7 +38,7 @@ class HeightMapShape3D : public Shape3D { int map_width = 2; int map_depth = 2; - PackedFloat32Array map_data; + Vector<real_t> map_data; real_t min_height = 0.0; real_t max_height = 0.0; @@ -51,8 +51,8 @@ public: int get_map_width() const; void set_map_depth(int p_new); int get_map_depth() const; - void set_map_data(PackedFloat32Array p_new); - PackedFloat32Array get_map_data() const; + void set_map_data(Vector<real_t> p_new); + Vector<real_t> get_map_data() const; virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 2f92872ad5..ad589a605e 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -653,6 +653,7 @@ enum OldArrayFormat { }; +#ifndef DISABLE_DEPRECATED static Array _convert_old_array(const Array &p_old) { Array new_array; new_array.resize(Mesh::ARRAY_MAX); @@ -677,6 +678,7 @@ static Mesh::PrimitiveType _old_primitives[7] = { Mesh::PRIMITIVE_TRIANGLE_STRIP, Mesh::PRIMITIVE_TRIANGLE_STRIP }; +#endif // DISABLE_DEPRECATED void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_format, uint32_t p_new_format, uint32_t p_elements, Vector<uint8_t> &vertex_data, Vector<uint8_t> &attribute_data, Vector<uint8_t> &skin_data) { uint32_t dst_vertex_stride; diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index 3fb4f8f211..04b2437ae8 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -107,9 +107,9 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf bo = arrays[Mesh::ARRAY_BONES].operator Vector<int>().ptr(); } - const real_t *we = nullptr; + const float *we = nullptr; if (arrays[Mesh::ARRAY_WEIGHTS].get_type() != Variant::NIL) { - we = arrays[Mesh::ARRAY_WEIGHTS].operator Vector<real_t>().ptr(); + we = arrays[Mesh::ARRAY_WEIGHTS].operator Vector<float>().ptr(); } vertices.resize(vcount); diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index a08684a506..4dd3c874cb 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -417,9 +417,9 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) { } if (p_data.has("penalties")) { - Vector<float> penalties = p_data["penalties"]; + Vector<real_t> penalties = p_data["penalties"]; if (penalties.size() == pc) { - const float *pr2 = penalties.ptr(); + const real_t *pr2 = penalties.ptr(); for (int i = 0; i < pc; i++) { points.write[i].penalty = pr2[i]; } @@ -445,11 +445,11 @@ Dictionary PolygonPathFinder::_get_data() const { p.resize(MAX(0, points.size() - 2)); connections.resize(MAX(0, points.size() - 2)); ind.resize(edges.size() * 2); - Vector<float> penalties; + Vector<real_t> penalties; penalties.resize(MAX(0, points.size() - 2)); { Vector2 *wp = p.ptrw(); - float *pw = penalties.ptrw(); + real_t *pw = penalties.ptrw(); for (int i = 0; i < points.size() - 2; i++) { wp[i] = points[i].pos; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 2b93414906..dbe118a262 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -558,6 +558,12 @@ Error ResourceLoaderText::load() { resource_current++; + int_resources[id] = res; //always assign int resources + if (do_assign && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { + res->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); + res->set_scene_unique_id(id); + } + while (true) { String assign; Variant value; @@ -585,12 +591,6 @@ Error ResourceLoaderText::load() { } } - int_resources[id] = res; //always assign int resources - if (do_assign && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { - res->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); - res->set_scene_unique_id(id); - } - if (progress && resources_total > 0) { *progress = resource_current / float(resources_total); } diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp index e9adf67559..140c6f821f 100644 --- a/scene/resources/sprite_frames.cpp +++ b/scene/resources/sprite_frames.cpp @@ -122,14 +122,14 @@ Vector<String> SpriteFrames::get_animation_names() const { return names; } -void SpriteFrames::set_animation_speed(const StringName &p_anim, float p_fps) { +void SpriteFrames::set_animation_speed(const StringName &p_anim, double p_fps) { ERR_FAIL_COND_MSG(p_fps < 0, "Animation speed cannot be negative (" + itos(p_fps) + ")."); Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); E->get().speed = p_fps; } -float SpriteFrames::get_animation_speed(const StringName &p_anim) const { +double SpriteFrames::get_animation_speed(const StringName &p_anim) const { const Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist."); return E->get().speed; diff --git a/scene/resources/sprite_frames.h b/scene/resources/sprite_frames.h index 282c5f20ab..fdfd6af5ab 100644 --- a/scene/resources/sprite_frames.h +++ b/scene/resources/sprite_frames.h @@ -37,7 +37,7 @@ class SpriteFrames : public Resource { GDCLASS(SpriteFrames, Resource); struct Anim { - float speed = 5.0; + double speed = 5.0; bool loop = true; Vector<Ref<Texture2D>> frames; }; @@ -64,8 +64,8 @@ public: void get_animation_list(List<StringName> *r_animations) const; Vector<String> get_animation_names() const; - void set_animation_speed(const StringName &p_anim, float p_fps); - float get_animation_speed(const StringName &p_anim) const; + void set_animation_speed(const StringName &p_anim, double p_fps); + double get_animation_speed(const StringName &p_anim) const; void set_animation_loop(const StringName &p_anim, bool p_loop); bool get_animation_loop(const StringName &p_anim) const; |