diff options
Diffstat (limited to 'core')
48 files changed, 388 insertions, 423 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 0a13becf6d..d9abf5e5e9 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -186,6 +186,10 @@ bool Engine::is_abort_on_gpu_errors_enabled() const { return abort_on_gpu_errors; } +int32_t Engine::get_gpu_index() const { + return gpu_idx; +} + bool Engine::is_validation_layers_enabled() const { return use_validation_layers; } diff --git a/core/config/engine.h b/core/config/engine.h index 3ec522eafc..65ca58ba1a 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -63,6 +63,7 @@ private: double _physics_interpolation_fraction = 0.0f; bool abort_on_gpu_errors = false; bool use_validation_layers = false; + int32_t gpu_idx = -1; uint64_t _process_frames = 0; bool _in_physics = false; @@ -135,6 +136,7 @@ public: bool is_abort_on_gpu_errors_enabled() const; bool is_validation_layers_enabled() const; + int32_t get_gpu_index() const; Engine(); virtual ~Engine() {} diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 5e3e4b3964..9a3234d4a2 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -224,14 +224,14 @@ Error OS::shell_open(String p_uri) { return ::OS::get_singleton()->shell_open(p_uri); } -int OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r_output, bool p_read_stderr) { +int OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r_output, bool p_read_stderr, bool p_open_console) { List<String> args; for (int i = 0; i < p_arguments.size(); i++) { args.push_back(p_arguments[i]); } String pipe; int exitcode = 0; - Error err = ::OS::get_singleton()->execute(p_path, args, &pipe, &exitcode, p_read_stderr); + Error err = ::OS::get_singleton()->execute(p_path, args, &pipe, &exitcode, p_read_stderr, nullptr, p_open_console); r_output.push_back(pipe); if (err != OK) { return -1; @@ -252,13 +252,13 @@ int OS::create_instance(const Vector<String> &p_arguments) { return pid; } -int OS::create_process(const String &p_path, const Vector<String> &p_arguments) { +int OS::create_process(const String &p_path, const Vector<String> &p_arguments, bool p_open_console) { List<String> args; for (int i = 0; i < p_arguments.size(); i++) { args.push_back(p_arguments[i]); } ::OS::ProcessID pid = 0; - Error err = ::OS::get_singleton()->create_process(p_path, args, &pid); + Error err = ::OS::get_singleton()->create_process(p_path, args, &pid, p_open_console); if (err != OK) { return -1; } @@ -557,8 +557,8 @@ void OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_processor_count"), &OS::get_processor_count); ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path); - ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr"), &OS::execute, DEFVAL(Array()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("create_process", "path", "arguments"), &OS::create_process); + ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr", "open_console"), &OS::execute, DEFVAL(Array()), DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("create_process", "path", "arguments", "open_console"), &OS::create_process, DEFVAL(false)); ClassDB::bind_method(D_METHOD("create_instance", "arguments"), &OS::create_instance); ClassDB::bind_method(D_METHOD("kill", "pid"), &OS::kill); ClassDB::bind_method(D_METHOD("shell_open", "uri"), &OS::shell_open); @@ -698,10 +698,7 @@ Variant Geometry2D::line_intersects_line(const Vector2 &p_from_a, const Vector2 Vector<Vector2> Geometry2D::get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) { Vector2 r1, r2; ::Geometry2D::get_closest_points_between_segments(p1, q1, p2, q2, r1, r2); - Vector<Vector2> r; - r.resize(2); - r.set(0, r1); - r.set(1, r2); + Vector<Vector2> r = { r1, r2 }; return r; } @@ -923,10 +920,7 @@ Vector<Plane> Geometry3D::build_capsule_planes(float p_radius, float p_height, i Vector<Vector3> Geometry3D::get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2) { Vector3 r1, r2; ::Geometry3D::get_closest_points_between_segments(p1, p2, q1, q2, r1, r2); - Vector<Vector3> r; - r.resize(2); - r.set(0, r1); - r.set(1, r2); + Vector<Vector3> r = { r1, r2 }; return r; } @@ -1672,9 +1666,9 @@ void Directory::_bind_methods() { ClassDB::bind_method(D_METHOD("rename", "from", "to"), &Directory::rename); ClassDB::bind_method(D_METHOD("remove", "path"), &Directory::remove); - ClassDB::bind_method(D_METHOD("set_include_navigational"), &Directory::set_include_navigational); + ClassDB::bind_method(D_METHOD("set_include_navigational", "enable"), &Directory::set_include_navigational); ClassDB::bind_method(D_METHOD("get_include_navigational"), &Directory::get_include_navigational); - ClassDB::bind_method(D_METHOD("set_include_hidden"), &Directory::set_include_hidden); + ClassDB::bind_method(D_METHOD("set_include_hidden", "enable"), &Directory::set_include_hidden); ClassDB::bind_method(D_METHOD("get_include_hidden"), &Directory::get_include_hidden); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_navigational"), "set_include_navigational", "get_include_navigational"); @@ -1894,7 +1888,7 @@ void Thread::_start_func(void *ud) { Error Thread::start(const Callable &p_callable, const Variant &p_userdata, Priority p_priority) { ERR_FAIL_COND_V_MSG(is_started(), ERR_ALREADY_IN_USE, "Thread already started."); - ERR_FAIL_COND_V(p_callable.is_null(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(!p_callable.is_valid(), ERR_INVALID_PARAMETER); ERR_FAIL_INDEX_V(p_priority, PRIORITY_MAX, ERR_INVALID_PARAMETER); ret = Variant(); diff --git a/core/core_bind.h b/core/core_bind.h index c7a406b2f3..ac0e92a87a 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -164,8 +164,8 @@ public: void crash(const String &p_message); String get_executable_path() const; - int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false); - int create_process(const String &p_path, const Vector<String> &p_arguments); + int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false, bool p_open_console = false); + int create_process(const String &p_path, const Vector<String> &p_arguments, bool p_open_console = false); int create_instance(const Vector<String> &p_arguments); Error kill(int p_pid); Error shell_open(String p_uri); diff --git a/core/core_constants.cpp b/core/core_constants.cpp index e49c0a14fd..6f26288eb7 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -476,6 +476,17 @@ void register_global_constants() { BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, PROGRAM_CHANGE); BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, CHANNEL_PRESSURE); BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, PITCH_BEND); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, SYSTEM_EXCLUSIVE); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, QUARTER_FRAME); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, SONG_POSITION_POINTER); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, SONG_SELECT); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, TUNE_REQUEST); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, TIMING_CLOCK); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, START); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, CONTINUE); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, STOP); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, ACTIVE_SENSING); + BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, SYSTEM_RESET); // error list @@ -658,15 +669,15 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_SIGNAL", Variant::SIGNAL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_DICTIONARY", Variant::DICTIONARY); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_ARRAY", Variant::ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RAW_ARRAY", Variant::PACKED_BYTE_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT32_ARRAY", Variant::PACKED_INT32_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT64_ARRAY", Variant::PACKED_INT64_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT32_ARRAY", Variant::PACKED_FLOAT32_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT64_ARRAY", Variant::PACKED_FLOAT64_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING_ARRAY", Variant::PACKED_STRING_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2_ARRAY", Variant::PACKED_VECTOR2_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3_ARRAY", Variant::PACKED_VECTOR3_ARRAY); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_COLOR_ARRAY", Variant::PACKED_COLOR_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_BYTE_ARRAY", Variant::PACKED_BYTE_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_INT32_ARRAY", Variant::PACKED_INT32_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_INT64_ARRAY", Variant::PACKED_INT64_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_FLOAT32_ARRAY", Variant::PACKED_FLOAT32_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_FLOAT64_ARRAY", Variant::PACKED_FLOAT64_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_STRING_ARRAY", Variant::PACKED_STRING_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_VECTOR2_ARRAY", Variant::PACKED_VECTOR2_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_VECTOR3_ARRAY", Variant::PACKED_VECTOR3_ARRAY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_COLOR_ARRAY", Variant::PACKED_COLOR_ARRAY); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_MAX", Variant::VARIANT_MAX); //comparison diff --git a/core/crypto/SCsub b/core/crypto/SCsub index 4f3104d84b..1fe2fa5b23 100644 --- a/core/crypto/SCsub +++ b/core/crypto/SCsub @@ -30,6 +30,7 @@ if not has_module: thirdparty_mbedtls_sources = [ "aes.c", "base64.c", + "constant_time.c", "md5.c", "sha1.c", "sha256.c", diff --git a/core/input/input.cpp b/core/input/input.cpp index c5540f926d..fa2f00bf8d 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -121,7 +121,7 @@ void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("set_accelerometer", "value"), &Input::set_accelerometer); ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer); ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope); - ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &Input::get_last_mouse_speed); + ClassDB::bind_method(D_METHOD("get_last_mouse_velocity"), &Input::get_last_mouse_velocity); ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask); ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode); ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode); @@ -183,7 +183,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S } } -void Input::SpeedTrack::update(const Vector2 &p_delta_p) { +void Input::VelocityTrack::update(const Vector2 &p_delta_p) { uint64_t tick = OS::get_singleton()->get_ticks_usec(); uint32_t tdiff = tick - last_tick; float delta_t = tdiff / 1000000.0; @@ -202,17 +202,17 @@ void Input::SpeedTrack::update(const Vector2 &p_delta_p) { accum = accum - slice; accum_t -= min_ref_frame; - speed = (slice / min_ref_frame).lerp(speed, min_ref_frame / max_ref_frame); + velocity = (slice / min_ref_frame).lerp(velocity, min_ref_frame / max_ref_frame); } } -void Input::SpeedTrack::reset() { +void Input::VelocityTrack::reset() { last_tick = OS::get_singleton()->get_ticks_usec(); - speed = Vector2(); + velocity = Vector2(); accum_t = 0; } -Input::SpeedTrack::SpeedTrack() { +Input::VelocityTrack::VelocityTrack() { min_ref_frame = 0.1; max_ref_frame = 0.3; reset(); @@ -515,7 +515,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em drag_event->set_position(mm->get_position()); drag_event->set_relative(mm->get_relative()); - drag_event->set_speed(mm->get_speed()); + drag_event->set_velocity(mm->get_velocity()); event_dispatch_function(drag_event); } @@ -525,12 +525,12 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em if (st.is_valid()) { if (st->is_pressed()) { - SpeedTrack &track = touch_speed_track[st->get_index()]; + VelocityTrack &track = touch_velocity_track[st->get_index()]; track.reset(); } else { // Since a pointer index may not occur again (OSs may or may not reuse them), // imperatively remove it from the map to keep no fossil entries in it - touch_speed_track.erase(st->get_index()); + touch_velocity_track.erase(st->get_index()); } if (emulate_mouse_from_touch) { @@ -570,9 +570,9 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em Ref<InputEventScreenDrag> sd = p_event; if (sd.is_valid()) { - SpeedTrack &track = touch_speed_track[sd->get_index()]; + VelocityTrack &track = touch_velocity_track[sd->get_index()]; track.update(sd->get_relative()); - sd->set_speed(track.speed); + sd->set_velocity(track.velocity); if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) { Ref<InputEventMouseMotion> motion_event; @@ -582,7 +582,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em motion_event->set_position(sd->get_position()); motion_event->set_global_position(sd->get_position()); motion_event->set_relative(sd->get_relative()); - motion_event->set_speed(sd->get_speed()); + motion_event->set_velocity(sd->get_velocity()); motion_event->set_button_mask(mouse_button_mask); _parse_input_event_impl(motion_event, true); @@ -696,7 +696,7 @@ void Input::set_gyroscope(const Vector3 &p_gyroscope) { } void Input::set_mouse_position(const Point2 &p_posf) { - mouse_speed_track.update(p_posf - mouse_pos); + mouse_velocity_track.update(p_posf - mouse_pos); mouse_pos = p_posf; } @@ -704,8 +704,8 @@ Point2 Input::get_mouse_position() const { return mouse_pos; } -Point2 Input::get_last_mouse_speed() const { - return mouse_speed_track.speed; +Point2 Input::get_last_mouse_velocity() const { + return mouse_velocity_track.velocity; } MouseButton Input::get_mouse_button_mask() const { @@ -892,7 +892,8 @@ void Input::set_event_dispatch_function(EventDispatchFunc p_function) { void Input::joy_button(int p_device, JoyButton p_button, bool p_pressed) { _THREAD_SAFE_METHOD_; Joypad &joy = joy_names[p_device]; - //printf("got button %i, mapping is %i\n", p_button, joy.mapping); + ERR_FAIL_INDEX((int)p_button, (int)JoyButton::MAX); + if (joy.last_buttons[(size_t)p_button] == p_pressed) { return; } @@ -915,40 +916,25 @@ void Input::joy_button(int p_device, JoyButton p_button, bool p_pressed) { // no event? } -void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value) { +void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) { _THREAD_SAFE_METHOD_; ERR_FAIL_INDEX((int)p_axis, (int)JoyAxis::MAX); Joypad &joy = joy_names[p_device]; - if (joy.last_axis[(size_t)p_axis] == p_value.value) { + if (joy.last_axis[(size_t)p_axis] == p_value) { return; } - //when changing direction quickly, insert fake event to release pending inputmap actions - float last = joy.last_axis[(size_t)p_axis]; - if (p_value.min == 0 && (last < 0.25 || last > 0.75) && (last - 0.5) * (p_value.value - 0.5) < 0) { - JoyAxisValue jx; - jx.min = p_value.min; - jx.value = p_value.value < 0.5 ? 0.6 : 0.4; - joy_axis(p_device, p_axis, jx); - } else if (ABS(last) > 0.5 && last * p_value.value <= 0) { - JoyAxisValue jx; - jx.min = p_value.min; - jx.value = last > 0 ? 0.1 : -0.1; - joy_axis(p_device, p_axis, jx); - } - - joy.last_axis[(size_t)p_axis] = p_value.value; - float val = p_value.min == 0 ? -1.0f + 2.0f * p_value.value : p_value.value; + joy.last_axis[(size_t)p_axis] = p_value; if (joy.mapping == -1) { - _axis_event(p_device, p_axis, val); + _axis_event(p_device, p_axis, p_value); return; } - JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, val); + JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value); if (map.type == TYPE_BUTTON) { bool pressed = map.value > 0.5; @@ -988,10 +974,15 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value) } if (map.type == TYPE_AXIS) { - _axis_event(p_device, (JoyAxis)map.index, map.value); + JoyAxis axis = JoyAxis(map.index); + float value = map.value; + if (axis == JoyAxis::TRIGGER_LEFT || axis == JoyAxis::TRIGGER_RIGHT) { + // Convert to a value between 0.0f and 1.0f. + value = 0.5f + value / 2.0f; + } + _axis_event(p_device, axis, value); return; } - //printf("invalid mapping\n"); } void Input::joy_hat(int p_device, HatMask p_val) { diff --git a/core/input/input.h b/core/input/input.h index b723fb563a..e5ef31ab4f 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -77,11 +77,6 @@ public: JOYPADS_MAX = 16, }; - struct JoyAxisValue { - int min; - float value; - }; - typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event); private: @@ -117,9 +112,9 @@ private: int mouse_from_touch_index = -1; - struct SpeedTrack { + struct VelocityTrack { uint64_t last_tick; - Vector2 speed; + Vector2 velocity; Vector2 accum; float accum_t; float min_ref_frame; @@ -127,7 +122,7 @@ private: void update(const Vector2 &p_delta_p); void reset(); - SpeedTrack(); + VelocityTrack(); }; struct Joypad { @@ -141,8 +136,8 @@ private: int hat_current = 0; }; - SpeedTrack mouse_speed_track; - Map<int, SpeedTrack> touch_speed_track; + VelocityTrack mouse_velocity_track; + Map<int, VelocityTrack> touch_velocity_track; Map<int, Joypad> joy_names; int fallback_mapping = -1; @@ -274,7 +269,7 @@ public: Vector3 get_gyroscope() const; Point2 get_mouse_position() const; - Point2 get_last_mouse_speed() const; + Vector2 get_last_mouse_velocity() const; MouseButton get_mouse_button_mask() const; void warp_mouse_position(const Vector2 &p_to); @@ -313,7 +308,7 @@ public: void parse_mapping(String p_mapping); void joy_button(int p_device, JoyButton p_button, bool p_pressed); - void joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value); + void joy_axis(int p_device, JoyAxis p_axis, float p_value); void joy_hat(int p_device, HatMask p_val); void add_joy_mapping(String p_mapping, bool p_update_existing = false); diff --git a/core/input/input_enums.h b/core/input/input_enums.h index 6b2dd2728e..0282de2176 100644 --- a/core/input/input_enums.h +++ b/core/input/input_enums.h @@ -83,7 +83,7 @@ enum class JoyButton { PADDLE4 = 19, TOUCHPAD = 20, SDL_MAX = 21, - MAX = 36, // Android supports up to 36 buttons. + MAX = 128, // Android supports up to 36 buttons. DirectInput supports up to 128 buttons. }; enum class MIDIMessage { @@ -95,6 +95,17 @@ enum class MIDIMessage { PROGRAM_CHANGE = 0xC, CHANNEL_PRESSURE = 0xD, PITCH_BEND = 0xE, + SYSTEM_EXCLUSIVE = 0xF0, + QUARTER_FRAME = 0xF1, + SONG_POSITION_POINTER = 0xF2, + SONG_SELECT = 0xF3, + TUNE_REQUEST = 0xF6, + TIMING_CLOCK = 0xF8, + START = 0xFA, + CONTINUE = 0xFB, + STOP = 0xFC, + ACTIVE_SENSING = 0xFE, + SYSTEM_RESET = 0xFF, }; enum class MouseButton { diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 794ed0275d..c608076a21 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -739,20 +739,15 @@ Vector2 InputEventMouseMotion::get_relative() const { return relative; } -void InputEventMouseMotion::set_speed(const Vector2 &p_speed) { - speed = p_speed; +void InputEventMouseMotion::set_velocity(const Vector2 &p_velocity) { + velocity = p_velocity; } -Vector2 InputEventMouseMotion::get_speed() const { - return speed; +Vector2 InputEventMouseMotion::get_velocity() const { + return velocity; } Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - Vector2 g = get_global_position(); - Vector2 l = p_xform.xform(get_position() + p_local_ofs); - Vector2 r = p_xform.basis_xform(get_relative()); - Vector2 s = p_xform.basis_xform(get_speed()); - Ref<InputEventMouseMotion> mm; mm.instantiate(); @@ -761,20 +756,20 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co mm->set_modifiers_from_event(this); - mm->set_position(l); + mm->set_position(p_xform.xform(get_position() + p_local_ofs)); mm->set_pressure(get_pressure()); mm->set_tilt(get_tilt()); - mm->set_global_position(g); + mm->set_global_position(get_global_position()); mm->set_button_mask(get_button_mask()); - mm->set_relative(r); - mm->set_speed(s); + mm->set_relative(p_xform.basis_xform(get_relative())); + mm->set_velocity(p_xform.basis_xform(get_velocity())); return mm; } String InputEventMouseMotion::as_text() const { - return vformat(RTR("Mouse motion at position (%s) with speed (%s)"), String(get_position()), String(get_speed())); + return vformat(RTR("Mouse motion at position (%s) with velocity (%s)"), String(get_position()), String(get_velocity())); } String InputEventMouseMotion::to_string() { @@ -802,7 +797,7 @@ String InputEventMouseMotion::to_string() { // Work around the fact vformat can only take 5 substitutions but 6 need to be passed. String mask_and_position = vformat("button_mask=%s, position=(%s)", button_mask_string, String(get_position())); - return vformat("InputEventMouseMotion: %s, relative=(%s), speed=(%s), pressure=%.2f, tilt=(%s)", mask_and_position, String(get_relative()), String(get_speed()), get_pressure(), String(get_tilt())); + return vformat("InputEventMouseMotion: %s, relative=(%s), velocity=(%s), pressure=%.2f, tilt=(%s)", mask_and_position, String(get_relative()), String(get_velocity()), get_pressure(), String(get_tilt())); } bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { @@ -841,7 +836,7 @@ bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { set_position(motion->get_position()); set_global_position(motion->get_global_position()); - set_speed(motion->get_speed()); + set_velocity(motion->get_velocity()); relative += motion->get_relative(); return true; @@ -857,13 +852,13 @@ void InputEventMouseMotion::_bind_methods() { ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative); ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative); - ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventMouseMotion::set_speed); - ClassDB::bind_method(D_METHOD("get_speed"), &InputEventMouseMotion::get_speed); + ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventMouseMotion::set_velocity); + ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventMouseMotion::get_velocity); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity"), "set_velocity", "get_velocity"); } /////////////////////////////////// @@ -1188,12 +1183,12 @@ Vector2 InputEventScreenDrag::get_relative() const { return relative; } -void InputEventScreenDrag::set_speed(const Vector2 &p_speed) { - speed = p_speed; +void InputEventScreenDrag::set_velocity(const Vector2 &p_velocity) { + velocity = p_velocity; } -Vector2 InputEventScreenDrag::get_speed() const { - return speed; +Vector2 InputEventScreenDrag::get_velocity() const { + return velocity; } Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { @@ -1207,17 +1202,17 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con sd->set_index(index); sd->set_position(p_xform.xform(pos + p_local_ofs)); sd->set_relative(p_xform.basis_xform(relative)); - sd->set_speed(p_xform.basis_xform(speed)); + sd->set_velocity(p_xform.basis_xform(velocity)); return sd; } String InputEventScreenDrag::as_text() const { - return vformat(RTR("Screen dragged with %s touch points at position (%s) with speed of (%s)"), itos(index), String(get_position()), String(get_speed())); + return vformat(RTR("Screen dragged with %s touch points at position (%s) with velocity of (%s)"), itos(index), String(get_position()), String(get_velocity())); } String InputEventScreenDrag::to_string() { - return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), speed=(%s)", index, String(get_position()), String(get_relative()), String(get_speed())); + return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), velocity=(%s)", index, String(get_position()), String(get_relative()), String(get_velocity())); } bool InputEventScreenDrag::accumulate(const Ref<InputEvent> &p_event) { @@ -1230,7 +1225,7 @@ bool InputEventScreenDrag::accumulate(const Ref<InputEvent> &p_event) { } set_position(drag->get_position()); - set_speed(drag->get_speed()); + set_velocity(drag->get_velocity()); relative += drag->get_relative(); return true; @@ -1246,13 +1241,13 @@ void InputEventScreenDrag::_bind_methods() { ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventScreenDrag::set_relative); ClassDB::bind_method(D_METHOD("get_relative"), &InputEventScreenDrag::get_relative); - ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventScreenDrag::set_speed); - ClassDB::bind_method(D_METHOD("get_speed"), &InputEventScreenDrag::get_speed); + ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventScreenDrag::set_velocity); + ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventScreenDrag::get_velocity); ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity"), "set_velocity", "get_velocity"); } /////////////////////////////////// diff --git a/core/input/input_event.h b/core/input/input_event.h index 184d883af8..29450dfc52 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -271,7 +271,7 @@ class InputEventMouseMotion : public InputEventMouse { Vector2 tilt; float pressure = 0; Vector2 relative; - Vector2 speed; + Vector2 velocity; protected: static void _bind_methods(); @@ -286,8 +286,8 @@ public: void set_relative(const Vector2 &p_relative); Vector2 get_relative() const; - void set_speed(const Vector2 &p_speed); - Vector2 get_speed() const; + void set_velocity(const Vector2 &p_velocity); + Vector2 get_velocity() const; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; @@ -388,7 +388,7 @@ class InputEventScreenDrag : public InputEventFromWindow { int index = 0; Vector2 pos; Vector2 relative; - Vector2 speed; + Vector2 velocity; protected: static void _bind_methods(); @@ -403,8 +403,8 @@ public: void set_relative(const Vector2 &p_relative); Vector2 get_relative() const; - void set_speed(const Vector2 &p_speed); - Vector2 get_speed() const; + void set_velocity(const Vector2 &p_velocity); + Vector2 get_velocity() const; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 715468f71d..526952b14f 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -312,10 +312,10 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con } else { read_block--; at_end = true; - if (i < p_length - 1) { + if (i + 1 < p_length) { read_eof = true; } - return i; + return i + 1; } } } diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index d90a0c9110..6347862775 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -189,7 +189,7 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, uint6 f.package = pkg_num; unzGetFilePos(zfile, &f.file_pos); - String fname = String("res://") + filename_inzip; + String fname = String("res://") + String::utf8(filename_inzip); files[fname] = f; uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/core/io/http_client_tcp.h b/core/io/http_client_tcp.h index 31ad9143db..886ad0ef48 100644 --- a/core/io/http_client_tcp.h +++ b/core/io/http_client_tcp.h @@ -58,8 +58,8 @@ private: Vector<uint8_t> chunk; int chunk_left = 0; bool chunk_trailer_part = false; - int body_size = -1; - int body_left = 0; + int64_t body_size = -1; + int64_t body_left = 0; bool read_until_eof = false; Ref<StreamPeerTCP> tcp_connection; diff --git a/core/io/image.cpp b/core/io/image.cpp index 4a1f129245..7956d0bad7 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -65,10 +65,6 @@ const char *Image::format_names[Image::FORMAT_MAX] = { "BPTC_RGBA", "BPTC_RGBF", "BPTC_RGBFU", - "PVRTC1_2", //pvrtc - "PVRTC1_2A", - "PVRTC1_4", - "PVRTC1_4A", "ETC", //etc1 "ETC2_R11", //etc2 "ETC2_R11S", //signed", NOT srgb. @@ -148,14 +144,6 @@ int Image::get_format_pixel_size(Format p_format) { return 1; //float / case FORMAT_BPTC_RGBFU: return 1; //unsigned float - case FORMAT_PVRTC1_2: - return 1; //pvrtc - case FORMAT_PVRTC1_2A: - return 1; - case FORMAT_PVRTC1_4: - return 1; - case FORMAT_PVRTC1_4A: - return 1; case FORMAT_ETC: return 1; //etc1 case FORMAT_ETC2_R11: @@ -193,16 +181,6 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { r_w = 4; r_h = 4; } break; - case FORMAT_PVRTC1_2: - case FORMAT_PVRTC1_2A: { - r_w = 16; - r_h = 8; - } break; - case FORMAT_PVRTC1_4A: - case FORMAT_PVRTC1_4: { - r_w = 8; - r_h = 8; - } break; case FORMAT_ETC: { r_w = 4; r_h = 4; @@ -235,10 +213,8 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { } int Image::get_format_pixel_rshift(Format p_format) { - if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC1_4 || p_format == FORMAT_PVRTC1_4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) { + if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) { return 1; - } else if (p_format == FORMAT_PVRTC1_2 || p_format == FORMAT_PVRTC1_2A) { - return 2; } else { return 0; } @@ -254,14 +230,6 @@ int Image::get_format_block_size(Format p_format) { return 4; } - case FORMAT_PVRTC1_2: - case FORMAT_PVRTC1_2A: { - return 4; - } - case FORMAT_PVRTC1_4A: - case FORMAT_PVRTC1_4: { - return 4; - } case FORMAT_ETC: { return 4; } @@ -2222,8 +2190,6 @@ bool Image::is_invisible() const { } break; - case FORMAT_PVRTC1_2A: - case FORMAT_PVRTC1_4A: case FORMAT_DXT3: case FORMAT_DXT5: { detected = true; @@ -2264,8 +2230,6 @@ Image::AlphaMode Image::detect_alpha() const { } } break; - case FORMAT_PVRTC1_2A: - case FORMAT_PVRTC1_4A: case FORMAT_DXT3: case FORMAT_DXT5: { detected = true; @@ -2361,8 +2325,6 @@ Error Image::decompress() { _image_decompress_bc(this); } else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc) { _image_decompress_bptc(this); - } else if (format >= FORMAT_PVRTC1_2 && format <= FORMAT_PVRTC1_4A && _image_decompress_pvrtc) { - _image_decompress_pvrtc(this); } else if (format == FORMAT_ETC && _image_decompress_etc1) { _image_decompress_etc1(this); } else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RA_AS_RG && _image_decompress_etc2) { @@ -2385,10 +2347,6 @@ Error Image::compress_from_channels(CompressMode p_mode, UsedChannels p_channels ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); _image_compress_bc_func(this, p_lossy_quality, p_channels); } break; - case COMPRESS_PVRTC1_4: { - ERR_FAIL_COND_V(!_image_compress_pvrtc1_4bpp_func, ERR_UNAVAILABLE); - _image_compress_pvrtc1_4bpp_func(this); - } break; case COMPRESS_ETC: { ERR_FAIL_COND_V(!_image_compress_etc1_func, ERR_UNAVAILABLE); _image_compress_etc1_func(this, p_lossy_quality); @@ -2752,10 +2710,8 @@ ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr; void (*Image::_image_compress_bc_func)(Image *, float, Image::UsedChannels) = nullptr; void (*Image::_image_compress_bptc_func)(Image *, float, Image::UsedChannels) = nullptr; -void (*Image::_image_compress_pvrtc1_4bpp_func)(Image *) = nullptr; void (*Image::_image_compress_etc1_func)(Image *, float) = nullptr; void (*Image::_image_compress_etc2_func)(Image *, float, Image::UsedChannels) = nullptr; -void (*Image::_image_decompress_pvrtc)(Image *) = nullptr; void (*Image::_image_decompress_bc)(Image *) = nullptr; void (*Image::_image_decompress_bptc)(Image *) = nullptr; void (*Image::_image_decompress_etc1)(Image *) = nullptr; @@ -3238,10 +3194,6 @@ void Image::_bind_methods() { BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBF); //float / BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBFU); //unsigned float - BIND_ENUM_CONSTANT(FORMAT_PVRTC1_2); //pvrtc - BIND_ENUM_CONSTANT(FORMAT_PVRTC1_2A); - BIND_ENUM_CONSTANT(FORMAT_PVRTC1_4); - BIND_ENUM_CONSTANT(FORMAT_PVRTC1_4A); BIND_ENUM_CONSTANT(FORMAT_ETC); //etc1 BIND_ENUM_CONSTANT(FORMAT_ETC2_R11); //etc2 BIND_ENUM_CONSTANT(FORMAT_ETC2_R11S); //signed ); NOT srgb. @@ -3265,7 +3217,6 @@ void Image::_bind_methods() { BIND_ENUM_CONSTANT(ALPHA_BLEND); BIND_ENUM_CONSTANT(COMPRESS_S3TC); - BIND_ENUM_CONSTANT(COMPRESS_PVRTC1_4); BIND_ENUM_CONSTANT(COMPRESS_ETC); BIND_ENUM_CONSTANT(COMPRESS_ETC2); BIND_ENUM_CONSTANT(COMPRESS_BPTC); diff --git a/core/io/image.h b/core/io/image.h index dffc5a6a5f..ddfb2bb01d 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -36,8 +36,6 @@ #include "core/math/rect2.h" /** - * @author Juan Linietsky <reduzio@gmail.com> - * * Image storage class. This is used to store an image in user memory, as well as * providing some basic methods for image manipulation. * Images can be loaded from a file, or registered into the Render object as textures. @@ -91,10 +89,6 @@ public: FORMAT_BPTC_RGBA, //btpc bc7 FORMAT_BPTC_RGBF, //float bc6h FORMAT_BPTC_RGBFU, //unsigned float bc6hu - FORMAT_PVRTC1_2, //pvrtc1 - FORMAT_PVRTC1_2A, - FORMAT_PVRTC1_4, - FORMAT_PVRTC1_4A, FORMAT_ETC, //etc1 FORMAT_ETC2_R11, //etc2 FORMAT_ETC2_R11S, //signed, NOT srgb. @@ -138,11 +132,9 @@ public: static void (*_image_compress_bc_func)(Image *, float, UsedChannels p_channels); static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, UsedChannels p_channels); - static void (*_image_compress_pvrtc1_4bpp_func)(Image *); static void (*_image_compress_etc1_func)(Image *, float); static void (*_image_compress_etc2_func)(Image *, float, UsedChannels p_channels); - static void (*_image_decompress_pvrtc)(Image *); static void (*_image_decompress_bc)(Image *); static void (*_image_decompress_bptc)(Image *); static void (*_image_decompress_etc1)(Image *); @@ -334,7 +326,6 @@ public: enum CompressMode { COMPRESS_S3TC, - COMPRESS_PVRTC1_4, COMPRESS_ETC, COMPRESS_ETC2, COMPRESS_BPTC, diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 311d71638b..66d5c54b53 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -520,8 +520,8 @@ void ResourceCache::dump(const char *p_file, bool p_short) { FileAccess *f = nullptr; if (p_file) { - f = FileAccess::open(p_file, FileAccess::WRITE); - ERR_FAIL_COND_MSG(!f, "Cannot create file at path '" + String(p_file) + "'."); + f = FileAccess::open(String::utf8(p_file), FileAccess::WRITE); + ERR_FAIL_COND_MSG(!f, "Cannot create file at path '" + String::utf8(p_file) + "'."); } const String *K = nullptr; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 65eb27ef4e..200d5fafde 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -53,9 +53,9 @@ enum { VARIANT_PLANE = 13, VARIANT_QUATERNION = 14, VARIANT_AABB = 15, - VARIANT_MATRIX3 = 16, - VARIANT_TRANSFORM = 17, - VARIANT_MATRIX32 = 18, + VARIANT_BASIS = 16, + VARIANT_TRANSFORM3D = 17, + VARIANT_TRANSFORM2D = 18, VARIANT_COLOR = 20, VARIANT_NODE_PATH = 22, VARIANT_RID = 23, @@ -63,13 +63,13 @@ enum { VARIANT_INPUT_EVENT = 25, VARIANT_DICTIONARY = 26, VARIANT_ARRAY = 30, - VARIANT_RAW_ARRAY = 31, - VARIANT_INT32_ARRAY = 32, - VARIANT_FLOAT32_ARRAY = 33, - VARIANT_STRING_ARRAY = 34, - VARIANT_VECTOR3_ARRAY = 35, - VARIANT_COLOR_ARRAY = 36, - VARIANT_VECTOR2_ARRAY = 37, + VARIANT_PACKED_BYTE_ARRAY = 31, + VARIANT_PACKED_INT32_ARRAY = 32, + VARIANT_PACKED_FLOAT32_ARRAY = 33, + VARIANT_PACKED_STRING_ARRAY = 34, + VARIANT_PACKED_VECTOR3_ARRAY = 35, + VARIANT_PACKED_COLOR_ARRAY = 36, + VARIANT_PACKED_VECTOR2_ARRAY = 37, VARIANT_INT64 = 40, VARIANT_DOUBLE = 41, VARIANT_CALLABLE = 42, @@ -78,8 +78,8 @@ enum { VARIANT_VECTOR2I = 45, VARIANT_RECT2I = 46, VARIANT_VECTOR3I = 47, - VARIANT_INT64_ARRAY = 48, - VARIANT_FLOAT64_ARRAY = 49, + VARIANT_PACKED_INT64_ARRAY = 48, + VARIANT_PACKED_FLOAT64_ARRAY = 49, OBJECT_EMPTY = 0, OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, @@ -220,7 +220,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_MATRIX32: { + case VARIANT_TRANSFORM2D: { Transform2D v; v.elements[0].x = f->get_real(); v.elements[0].y = f->get_real(); @@ -231,7 +231,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_MATRIX3: { + case VARIANT_BASIS: { Basis v; v.elements[0].x = f->get_real(); v.elements[0].y = f->get_real(); @@ -245,7 +245,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_TRANSFORM: { + case VARIANT_TRANSFORM3D: { Transform3D v; v.basis.elements[0].x = f->get_real(); v.basis.elements[0].y = f->get_real(); @@ -422,7 +422,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = a; } break; - case VARIANT_RAW_ARRAY: { + case VARIANT_PACKED_BYTE_ARRAY: { uint32_t len = f->get_32(); Vector<uint8_t> array; @@ -434,7 +434,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_INT32_ARRAY: { + case VARIANT_PACKED_INT32_ARRAY: { uint32_t len = f->get_32(); Vector<int32_t> array; @@ -453,7 +453,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_INT64_ARRAY: { + case VARIANT_PACKED_INT64_ARRAY: { uint32_t len = f->get_32(); Vector<int64_t> array; @@ -472,7 +472,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_FLOAT32_ARRAY: { + case VARIANT_PACKED_FLOAT32_ARRAY: { uint32_t len = f->get_32(); Vector<float> array; @@ -491,7 +491,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_FLOAT64_ARRAY: { + case VARIANT_PACKED_FLOAT64_ARRAY: { uint32_t len = f->get_32(); Vector<double> array; @@ -510,7 +510,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_STRING_ARRAY: { + case VARIANT_PACKED_STRING_ARRAY: { uint32_t len = f->get_32(); Vector<String> array; array.resize(len); @@ -522,7 +522,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_VECTOR2_ARRAY: { + case VARIANT_PACKED_VECTOR2_ARRAY: { uint32_t len = f->get_32(); Vector<Vector2> array; @@ -547,7 +547,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_VECTOR3_ARRAY: { + case VARIANT_PACKED_VECTOR3_ARRAY: { uint32_t len = f->get_32(); Vector<Vector3> array; @@ -572,7 +572,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_COLOR_ARRAY: { + case VARIANT_PACKED_COLOR_ARRAY: { uint32_t len = f->get_32(); Vector<Color> array; @@ -1476,7 +1476,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::TRANSFORM2D: { - f->store_32(VARIANT_MATRIX32); + f->store_32(VARIANT_TRANSFORM2D); Transform2D val = p_property; f->store_real(val.elements[0].x); f->store_real(val.elements[0].y); @@ -1487,7 +1487,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::BASIS: { - f->store_32(VARIANT_MATRIX3); + f->store_32(VARIANT_BASIS); Basis val = p_property; f->store_real(val.elements[0].x); f->store_real(val.elements[0].y); @@ -1501,7 +1501,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::TRANSFORM3D: { - f->store_32(VARIANT_TRANSFORM); + f->store_32(VARIANT_TRANSFORM3D); Transform3D val = p_property; f->store_real(val.basis.elements[0].x); f->store_real(val.basis.elements[0].y); @@ -1625,7 +1625,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_BYTE_ARRAY: { - f->store_32(VARIANT_RAW_ARRAY); + f->store_32(VARIANT_PACKED_BYTE_ARRAY); Vector<uint8_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1635,7 +1635,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_INT32_ARRAY: { - f->store_32(VARIANT_INT32_ARRAY); + f->store_32(VARIANT_PACKED_INT32_ARRAY); Vector<int32_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1646,7 +1646,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_INT64_ARRAY: { - f->store_32(VARIANT_INT64_ARRAY); + f->store_32(VARIANT_PACKED_INT64_ARRAY); Vector<int64_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1657,7 +1657,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_FLOAT32_ARRAY: { - f->store_32(VARIANT_FLOAT32_ARRAY); + f->store_32(VARIANT_PACKED_FLOAT32_ARRAY); Vector<float> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1668,7 +1668,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_FLOAT64_ARRAY: { - f->store_32(VARIANT_FLOAT64_ARRAY); + f->store_32(VARIANT_PACKED_FLOAT64_ARRAY); Vector<double> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1679,7 +1679,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_STRING_ARRAY: { - f->store_32(VARIANT_STRING_ARRAY); + f->store_32(VARIANT_PACKED_STRING_ARRAY); Vector<String> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1690,7 +1690,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_VECTOR3_ARRAY: { - f->store_32(VARIANT_VECTOR3_ARRAY); + f->store_32(VARIANT_PACKED_VECTOR3_ARRAY); Vector<Vector3> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1703,7 +1703,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_VECTOR2_ARRAY: { - f->store_32(VARIANT_VECTOR2_ARRAY); + f->store_32(VARIANT_PACKED_VECTOR2_ARRAY); Vector<Vector2> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1715,7 +1715,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_COLOR_ARRAY: { - f->store_32(VARIANT_COLOR_ARRAY); + f->store_32(VARIANT_PACKED_COLOR_ARRAY); Vector<Color> arr = p_property; int len = arr.size(); f->store_32(len); diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index ebe88fcf66..ce2435216b 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -699,8 +699,7 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) { ERR_FAIL_COND_V_MSG(!to_exists, Vector<Vector2>(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_to_id)); if (a == b) { - Vector<Vector2> ret; - ret.push_back(Vector2(a->pos.x, a->pos.y)); + Vector<Vector2> ret = { Vector2(a->pos.x, a->pos.y) }; return ret; } diff --git a/core/math/a_star.h b/core/math/a_star.h index 1839ec7e04..130c202a61 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -37,9 +37,7 @@ #include "core/templates/oa_hash_map.h" /** - A* pathfinding algorithm - - @author Juan Linietsky <reduzio@gmail.com> + A* pathfinding algorithm. */ class AStar : public RefCounted { diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 6159e78bab..a9b4651664 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -94,6 +94,18 @@ Basis Basis::orthonormalized() const { return c; } +void Basis::orthogonalize() { + Vector3 scl = get_scale(); + orthonormalize(); + scale_local(scl); +} + +Basis Basis::orthogonalized() const { + Basis c = *this; + c.orthogonalize(); + return c; +} + bool Basis::is_orthogonal() const { Basis identity; Basis m = (*this) * transposed(); @@ -237,6 +249,24 @@ void Basis::scale_local(const Vector3 &p_scale) { *this = scaled_local(p_scale); } +void Basis::scale_orthogonal(const Vector3 &p_scale) { + *this = scaled_orthogonal(p_scale); +} + +Basis Basis::scaled_orthogonal(const Vector3 &p_scale) const { + Basis m = *this; + Vector3 s = Vector3(-1, -1, -1) + p_scale; + Vector3 dots; + Basis b; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + dots[j] += s[i] * abs(m.get_axis(i).normalized().dot(b.get_axis(j))); + } + } + m.scale_local(Vector3(1, 1, 1) + dots); + return m; +} + float Basis::get_uniform_scale() const { return (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0; } @@ -931,6 +961,15 @@ void Basis::_set_diagonal(const Vector3 &p_diag) { elements[2][2] = p_diag.z; } +Basis Basis::lerp(const Basis &p_to, const real_t &p_weight) const { + Basis b; + b.elements[0] = elements[0].lerp(p_to.elements[0], p_weight); + b.elements[1] = elements[1].lerp(p_to.elements[1], p_weight); + b.elements[2] = elements[2].lerp(p_to.elements[2], p_weight); + + return b; +} + Basis Basis::slerp(const Basis &p_to, const real_t &p_weight) const { //consider scale Quaternion from(*this); diff --git a/core/math/basis.h b/core/math/basis.h index 48367631d5..709f2cb3cf 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -123,6 +123,9 @@ public: void scale_local(const Vector3 &p_scale); Basis scaled_local(const Vector3 &p_scale) const; + void scale_orthogonal(const Vector3 &p_scale); + Basis scaled_orthogonal(const Vector3 &p_scale) const; + void make_scale_uniform(); float get_uniform_scale() const; @@ -168,6 +171,7 @@ public: bool is_diagonal() const; bool is_rotation() const; + Basis lerp(const Basis &p_to, const real_t &p_weight) const; Basis slerp(const Basis &p_to, const real_t &p_weight) const; void rotate_sh(real_t *p_values); @@ -233,6 +237,9 @@ public: void orthonormalize(); Basis orthonormalized() const; + void orthogonalize(); + Basis orthogonalized() const; + #ifdef MATH_CHECKS bool is_symmetric() const; #endif diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index b968156887..2902ca59b9 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -346,6 +346,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform */ Vector<Plane> planes; + planes.resize(6); const real_t *matrix = (const real_t *)this->matrix; @@ -360,7 +361,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[0] = p_transform.xform(new_plane); ///////--- Far Plane ---/////// new_plane = Plane(matrix[3] - matrix[2], @@ -371,7 +372,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[1] = p_transform.xform(new_plane); ///////--- Left Plane ---/////// new_plane = Plane(matrix[3] + matrix[0], @@ -382,7 +383,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[2] = p_transform.xform(new_plane); ///////--- Top Plane ---/////// new_plane = Plane(matrix[3] - matrix[1], @@ -393,7 +394,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[3] = p_transform.xform(new_plane); ///////--- Right Plane ---/////// new_plane = Plane(matrix[3] - matrix[0], @@ -404,7 +405,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[4] = p_transform.xform(new_plane); ///////--- Bottom Plane ---/////// new_plane = Plane(matrix[3] + matrix[1], @@ -415,7 +416,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[5] = p_transform.xform(new_plane); return planes; } diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h index d16c5d3d62..8657dc068e 100644 --- a/core/math/disjoint_set.h +++ b/core/math/disjoint_set.h @@ -34,10 +34,6 @@ #include "core/templates/map.h" #include "core/templates/vector.h" -/** - @author Marios Staikopoulos <marios@staik.net> -*/ - /* This DisjointSet class uses Find with path compression and Union by rank */ template <typename T, class C = Comparator<T>, class AL = DefaultAllocator> class DisjointSet { diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index e1bce81b6b..98a2c27d93 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -644,14 +644,15 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes Vector3 right = p.normal.cross(ref).normalized(); Vector3 up = p.normal.cross(right).normalized(); - Vector<Vector3> vertices; - Vector3 center = p.center(); + // make a quad clockwise - vertices.push_back(center - up * subplane_size + right * subplane_size); - vertices.push_back(center - up * subplane_size - right * subplane_size); - vertices.push_back(center + up * subplane_size - right * subplane_size); - vertices.push_back(center + up * subplane_size + right * subplane_size); + Vector<Vector3> vertices = { + center - up * subplane_size + right * subplane_size, + center - up * subplane_size - right * subplane_size, + center + up * subplane_size - right * subplane_size, + center + up * subplane_size + right * subplane_size + }; for (int j = 0; j < p_planes.size(); j++) { if (j == i) { @@ -762,14 +763,14 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes } Vector<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) { - Vector<Plane> planes; - - planes.push_back(Plane(Vector3(1, 0, 0), p_extents.x)); - planes.push_back(Plane(Vector3(-1, 0, 0), p_extents.x)); - planes.push_back(Plane(Vector3(0, 1, 0), p_extents.y)); - planes.push_back(Plane(Vector3(0, -1, 0), p_extents.y)); - planes.push_back(Plane(Vector3(0, 0, 1), p_extents.z)); - planes.push_back(Plane(Vector3(0, 0, -1), p_extents.z)); + Vector<Plane> planes = { + Plane(Vector3(1, 0, 0), p_extents.x), + Plane(Vector3(-1, 0, 0), p_extents.x), + Plane(Vector3(0, 1, 0), p_extents.y), + Plane(Vector3(0, -1, 0), p_extents.y), + Plane(Vector3(0, 0, 1), p_extents.z), + Plane(Vector3(0, 0, -1), p_extents.z) + }; return planes; } diff --git a/core/math/octree.h b/core/math/octree.h index 7861c35e07..23ba4c1aa3 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -103,7 +103,7 @@ private: Octant *parent = nullptr; Octant *children[8] = { nullptr }; - int children_count = 0; // cache for amount of childrens (fast check for removal) + int children_count = 0; // cache for amount of children (fast check for removal) int parent_index = -1; // cache for parent index (fast check for removal) List<Element *, AL> pairable_elements; diff --git a/core/math/rect2.h b/core/math/rect2.h index 1f14a01103..f34550bef1 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -207,11 +207,6 @@ struct Rect2 { bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } inline Rect2 grow(real_t p_amount) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); - } -#endif Rect2 g = *this; g.grow_by(p_amount); return g; @@ -238,11 +233,6 @@ struct Rect2 { } inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); - } -#endif Rect2 g = *this; g.position.x -= p_left; g.position.y -= p_top; @@ -488,11 +478,6 @@ struct Rect2i { bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } Rect2i grow(int p_amount) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif Rect2i g = *this; g.position.x -= p_amount; g.position.y -= p_amount; @@ -515,11 +500,6 @@ struct Rect2i { } inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif Rect2i g = *this; g.position.x -= p_left; g.position.y -= p_top; diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index 1e0ee13504..e5374315e2 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -80,9 +80,11 @@ void Transform3D::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, con origin = p_eye; } -Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const { +Transform3D Transform3D::sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const { /* not sure if very "efficient" but good enough? */ + Transform3D interp; + Vector3 src_scale = basis.get_scale(); Quaternion src_rot = basis.get_rotation_quaternion(); Vector3 src_loc = origin; @@ -91,13 +93,21 @@ Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t Quaternion dst_rot = p_transform.basis.get_rotation_quaternion(); Vector3 dst_loc = p_transform.origin; - Transform3D interp; interp.basis.set_quaternion_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.lerp(dst_scale, p_c)); interp.origin = src_loc.lerp(dst_loc, p_c); return interp; } +Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const { + Transform3D interp; + + interp.basis = basis.lerp(p_transform.basis, p_c); + interp.origin = origin.lerp(p_transform.origin, p_c); + + return interp; +} + void Transform3D::scale(const Vector3 &p_scale) { basis.scale(p_scale); origin *= p_scale; @@ -139,6 +149,16 @@ Transform3D Transform3D::orthonormalized() const { return _copy; } +void Transform3D::orthogonalize() { + basis.orthogonalize(); +} + +Transform3D Transform3D::orthogonalized() const { + Transform3D _copy = *this; + _copy.orthogonalize(); + return _copy; +} + bool Transform3D::is_equal_approx(const Transform3D &p_transform) const { return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin); } diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index 4356aa4e79..c0ef2ecfc1 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -69,6 +69,8 @@ public: void orthonormalize(); Transform3D orthonormalized() const; + void orthogonalize(); + Transform3D orthogonalized() const; bool is_equal_approx(const Transform3D &p_transform) const; bool operator==(const Transform3D &p_transform) const; @@ -99,6 +101,7 @@ public: void operator*=(const real_t p_val); Transform3D operator*(const real_t p_val) const; + Transform3D sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const; Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; _FORCE_INLINE_ Transform3D inverse_xform(const Transform3D &t) const { diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 38dad893f5..676a0004ea 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -210,6 +210,14 @@ Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const { CLAMP(y, p_min.y, p_max.y)); } +int64_t Vector2i::length_squared() const { + return x * (int64_t)x + y * (int64_t)y; +} + +double Vector2i::length() const { + return Math::sqrt((double)length_squared()); +} + Vector2i Vector2i::operator+(const Vector2i &p_v) const { return Vector2i(x + p_v.x, y + p_v.y); } diff --git a/core/math/vector2.h b/core/math/vector2.h index 493e0af27d..a340036ac7 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -261,11 +261,16 @@ Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const { } Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(!is_normalized(), Vector2(), "The start Vector2 must be normalized."); -#endif - real_t theta = angle_to(p_to); - return rotated(theta * p_weight); + real_t start_length_sq = length_squared(); + real_t end_length_sq = p_to.length_squared(); + if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) { + // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. + return lerp(p_to, p_weight); + } + real_t start_length = Math::sqrt(start_length_sq); + real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight); + real_t angle = angle_to(p_to); + return rotated(angle * p_weight) * (result_length / start_length); } Vector2 Vector2::direction_to(const Vector2 &p_to) const { @@ -344,6 +349,9 @@ struct Vector2i { bool operator==(const Vector2i &p_vec2) const; bool operator!=(const Vector2i &p_vec2) const; + int64_t length_squared() const; + double length() const; + real_t aspect() const { return width / (real_t)height; } Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); } Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); } diff --git a/core/math/vector3.h b/core/math/vector3.h index 1861627718..d7a72b05a8 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -240,8 +240,16 @@ Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const { } Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const { - real_t theta = angle_to(p_to); - return rotated(cross(p_to).normalized(), theta * p_weight); + real_t start_length_sq = length_squared(); + real_t end_length_sq = p_to.length_squared(); + if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) { + // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. + return lerp(p_to, p_weight); + } + real_t start_length = Math::sqrt(start_length_sq); + real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight); + real_t angle = angle_to(p_to); + return rotated(cross(p_to).normalized(), angle * p_weight) * (result_length / start_length); } real_t Vector3::distance_to(const Vector3 &p_to) const { diff --git a/core/math/vector3i.h b/core/math/vector3i.h index 0f9caa349b..1416c98057 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -31,6 +31,7 @@ #ifndef VECTOR3I_H #define VECTOR3I_H +#include "core/math/math_funcs.h" #include "core/string/ustring.h" #include "core/typedefs.h" @@ -65,6 +66,9 @@ struct Vector3i { Vector3i::Axis min_axis_index() const; Vector3i::Axis max_axis_index() const; + _FORCE_INLINE_ int64_t length_squared() const; + _FORCE_INLINE_ double length() const; + _FORCE_INLINE_ void zero(); _FORCE_INLINE_ Vector3i abs() const; @@ -110,6 +114,14 @@ struct Vector3i { } }; +int64_t Vector3i::length_squared() const { + return x * (int64_t)x + y * (int64_t)y + z * (int64_t)z; +} + +double Vector3i::length() const { + return Math::sqrt((double)length_squared()); +} + Vector3i Vector3i::abs() const { return Vector3i(ABS(x), ABS(y), ABS(z)); } diff --git a/core/object/object.h b/core/object/object.h index ab94f2aa00..602bd3cda1 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -52,10 +52,6 @@ #define VARIANT_ARGPTRS_PASS *argptr[0], *argptr[1], *argptr[2], *argptr[3], *argptr[4], *argptr[5], *argptr[6]], *argptr[7] #define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0], m_arr[1], m_arr[2], m_arr[3], m_arr[4], m_arr[5], m_arr[6], m_arr[7] -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ - enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range. @@ -359,9 +355,6 @@ public: } \ return category; \ } \ - static String inherits_static() { \ - return String(#m_inherits); \ - } \ virtual bool is_class(const String &p_class) const override { \ if (_get_extension() && _get_extension()->is_class(p_class)) { \ return true; \ diff --git a/core/object/script_language.h b/core/object/script_language.h index 23c8667afd..4b18d9a5e8 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -227,6 +227,7 @@ struct ScriptCodeCompletionOption { Color font_color; RES icon; Variant default_value; + Vector<Pair<int, int>> matches; ScriptCodeCompletionOption() {} diff --git a/core/os/os.cpp b/core/os/os.cpp index 506e968bf6..0032e8e4bc 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -346,7 +346,7 @@ String OS::get_model_name() const { } void OS::set_cmdline(const char *p_execpath, const List<String> &p_args) { - _execpath = p_execpath; + _execpath = String::utf8(p_execpath); _cmdline = p_args; } diff --git a/core/os/os.h b/core/os/os.h index b4ad2c7345..6b4e2798bd 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -149,8 +149,8 @@ public: virtual int get_low_processor_usage_mode_sleep_usec() const; virtual String get_executable_path() const; - virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) = 0; - virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) = 0; + virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) = 0; + virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) = 0; virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) { return create_process(get_executable_path(), p_arguments, r_child_id); }; virtual Error kill(const ProcessID &p_pid) = 0; virtual int get_process_id() const; diff --git a/core/os/pool_allocator.h b/core/os/pool_allocator.h index 25b5061f62..11a252bc54 100644 --- a/core/os/pool_allocator.h +++ b/core/os/pool_allocator.h @@ -34,13 +34,12 @@ #include "core/typedefs.h" /** - @author Juan Linietsky <reduzio@gmail.com> * Generic Pool Allocator. * This is a generic memory pool allocator, with locking, compacting and alignment. (@TODO alignment) * It used as a standard way to manage allocation in a specific region of memory, such as texture memory, * audio sample memory, or just any kind of memory overall. * (@TODO) abstraction should be greater, because in many platforms, you need to manage a nonreachable memory. -*/ + */ enum { POOL_ALLOCATOR_INVALID_ID = -1 ///< default invalid value. use INVALID_ID( id ) to test diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 0949980713..658dbc98cf 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1527,115 +1527,24 @@ String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) { } String String::num_real(double p_num, bool p_trailing) { - if (Math::is_nan(p_num)) { - return "nan"; - } - - if (Math::is_inf(p_num)) { - if (signbit(p_num)) { - return "-inf"; + if (p_num == (double)(int64_t)p_num) { + if (p_trailing) { + return num_int64((int64_t)p_num) + ".0"; } else { - return "inf"; + return num_int64((int64_t)p_num); } } - - String s; - String sd; - - // Integer part. - - bool neg = p_num < 0; - p_num = ABS(p_num); - int64_t intn = (int64_t)p_num; - - // Decimal part. - - if (intn != p_num) { - double dec = p_num - (double)intn; - - int digit = 0; - #ifdef REAL_T_IS_DOUBLE - int decimals = 14; - double tolerance = 1e-14; + int decimals = 14; #else - int decimals = 6; - double tolerance = 1e-6; + int decimals = 6; #endif - // We want to align the digits to the above sane default, so we only - // need to subtract log10 for numbers with a positive power of ten. - if (p_num > 10) { - decimals -= (int)floor(log10(p_num)); - } - - if (decimals > MAX_DECIMALS) { - decimals = MAX_DECIMALS; - } - - // In case the value ends up ending in "99999", we want to add a - // tiny bit to the value we're checking when deciding when to stop, - // so we multiply by slightly above 1 (1 + 1e-7 or 1e-15). - double check_multiplier = 1 + tolerance / 10; - - int64_t dec_int = 0; - int64_t dec_max = 0; - - while (true) { - dec *= 10.0; - dec_int = dec_int * 10 + (int64_t)dec % 10; - dec_max = dec_max * 10 + 9; - digit++; - - if ((dec - (double)(int64_t)(dec * check_multiplier)) < tolerance) { - break; - } - - if (digit == decimals) { - break; - } - } - - dec *= 10; - int last = (int64_t)dec % 10; - - if (last > 5) { - if (dec_int == dec_max) { - dec_int = 0; - intn++; - } else { - dec_int++; - } - } - - String decimal; - for (int i = 0; i < digit; i++) { - char num[2] = { 0, 0 }; - num[0] = '0' + dec_int % 10; - decimal = num + decimal; - dec_int /= 10; - } - sd = '.' + decimal; - } else if (p_trailing) { - sd = ".0"; - } else { - sd = ""; + // We want to align the digits to the above sane default, so we only + // need to subtract log10 for numbers with a positive power of ten. + if (p_num > 10) { + decimals -= (int)floor(log10(p_num)); } - - if (intn == 0) { - s = "0"; - } else { - while (intn) { - char32_t num = '0' + (intn % 10); - intn /= 10; - s = num + s; - } - } - - s = s + sd; - if (neg) { - s = "-" + s; - } - return s; + return num(p_num, decimals); } String String::num_scientific(double p_num) { diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h index 82b3546f9d..fa5677cc70 100644 --- a/core/templates/hash_map.h +++ b/core/templates/hash_map.h @@ -40,7 +40,6 @@ /** * @class HashMap - * @author Juan Linietsky <reduzio@gmail.com> * * Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key. * The implementation provides hashers for the default types, if you need a special kind of hasher, provide @@ -48,7 +47,8 @@ * @param TKey Key, search is based on it, needs to be hasheable. It is unique in this container. * @param TData Data, data associated with the key * @param Hasher Hasher object, needs to provide a valid static hash function for TKey - * @param Comparator comparator object, needs to be able to safely compare two TKey values. It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check. + * @param Comparator comparator object, needs to be able to safely compare two TKey values. + * It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check. * @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter. * @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP * times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER. diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index 1a19f29f3b..f4e0748c27 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -36,6 +36,8 @@ #include "core/templates/sort_array.h" #include "core/templates/vector.h" +#include <initializer_list> + template <class T, class U = uint32_t, bool force_trivial = false> class LocalVector { private: @@ -228,6 +230,12 @@ public: } _FORCE_INLINE_ LocalVector() {} + _FORCE_INLINE_ LocalVector(std::initializer_list<T> p_init) { + reserve(p_init.size()); + for (const T &element : p_init) { + push_back(element); + } + } _FORCE_INLINE_ LocalVector(const LocalVector &p_from) { resize(p_from.size()); for (U i = 0; i < p_from.count; i++) { diff --git a/core/templates/set.h b/core/templates/set.h index 9107459884..cdc6e8447d 100644 --- a/core/templates/set.h +++ b/core/templates/set.h @@ -582,6 +582,9 @@ public: } Element *lower_bound(const T &p_value) const { + if (!_data._root) { + return nullptr; + } return _lower_bound(p_value); } diff --git a/core/templates/vector.h b/core/templates/vector.h index 18b731c458..bd4c6ade86 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -33,7 +33,6 @@ /** * @class Vector - * @author Juan Linietsky * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use Vector for large arrays. */ @@ -43,6 +42,9 @@ #include "core/templates/search_array.h" #include "core/templates/sort_array.h" +#include <climits> +#include <initializer_list> + template <class T> class VectorWriteProxy { public: @@ -143,25 +145,29 @@ public: return ret; } - Vector<T> slice(int p_begin, int p_end) const { + Vector<T> slice(int p_begin, int p_end = INT_MAX) const { Vector<T> result; - if (p_end < 0) { - p_end += size() + 1; - } + const int s = size(); - ERR_FAIL_INDEX_V(p_begin, size(), result); - ERR_FAIL_INDEX_V(p_end, size() + 1, result); + int begin = CLAMP(p_begin, -s, s); + if (begin < 0) { + begin += s; + } + int end = CLAMP(p_end, -s, s); + if (end < 0) { + end += s; + } - ERR_FAIL_COND_V(p_begin > p_end, result); + ERR_FAIL_COND_V(begin > end, result); - int result_size = p_end - p_begin; + int result_size = end - begin; result.resize(result_size); const T *const r = ptr(); T *const w = result.ptrw(); for (int i = 0; i < result_size; ++i) { - w[i] = r[p_begin + i]; + w[i] = r[begin + i]; } return result; @@ -258,6 +264,15 @@ public: } _FORCE_INLINE_ Vector() {} + _FORCE_INLINE_ Vector(std::initializer_list<T> p_init) { + Error err = _cowdata.resize(p_init.size()); + ERR_FAIL_COND(err); + + int i = 0; + for (const T &element : p_init) { + _cowdata.set(i++, element); + } + } _FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); } _FORCE_INLINE_ ~Vector() {} diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 8d20b1bc79..3d2f337442 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -370,20 +370,24 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { ERR_FAIL_COND_V_MSG(p_step == 0, result, "Slice step cannot be zero."); - if (p_end < 0) { - p_end += size() + 1; - } + const int s = size(); - ERR_FAIL_INDEX_V(p_begin, size(), result); - ERR_FAIL_INDEX_V(p_end, size() + 1, result); + int begin = CLAMP(p_begin, -s, s); + if (begin < 0) { + begin += s; + } + int end = CLAMP(p_end, -s, s); + if (end < 0) { + end += s; + } - ERR_FAIL_COND_V_MSG(p_step > 0 && p_begin > p_end, result, "Slice is positive, but bounds is decreasing"); - ERR_FAIL_COND_V_MSG(p_step < 0 && p_begin < p_end, result, "Slice is negative, but bounds is increasing"); + ERR_FAIL_COND_V_MSG(p_step > 0 && begin > end, result, "Slice is positive, but bounds is decreasing."); + ERR_FAIL_COND_V_MSG(p_step < 0 && begin < end, result, "Slice is negative, but bounds is increasing."); - int result_size = (p_end - p_begin) / p_step; + int result_size = (end - begin) / p_step; result.resize(result_size); - for (int src_idx = p_begin, dest_idx = 0; dest_idx < result_size; ++dest_idx) { + for (int src_idx = begin, dest_idx = 0; dest_idx < result_size; ++dest_idx) { result[dest_idx] = p_deep ? get(src_idx).duplicate(true) : get(src_idx); src_idx += p_step; } diff --git a/core/variant/array.h b/core/variant/array.h index f48444bb39..72bed5932c 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -33,6 +33,8 @@ #include "core/typedefs.h" +#include <climits> + class Variant; class ArrayPrivate; class Object; @@ -102,7 +104,7 @@ public: Array duplicate(bool p_deep = false) const; Array recursive_duplicate(bool p_deep, int recursion_count) const; - Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const; + Array slice(int p_begin, int p_end = INT_MAX, int p_step = 1, bool p_deep = false) const; Array filter(const Callable &p_callable) const; Array map(const Callable &p_callable) const; Variant reduce(const Callable &p_callable, const Variant &p_accum) const; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 64522a9908..8dd48a4c28 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1513,6 +1513,8 @@ static void _register_variant_builtin_methods() { bind_method(Vector2i, aspect, sarray(), varray()); bind_method(Vector2i, max_axis_index, sarray(), varray()); bind_method(Vector2i, min_axis_index, sarray(), varray()); + bind_method(Vector2i, length, sarray(), varray()); + bind_method(Vector2i, length_squared, sarray(), varray()); bind_method(Vector2i, sign, sarray(), varray()); bind_method(Vector2i, abs, sarray(), varray()); bind_method(Vector2i, clamp, sarray("min", "max"), varray()); @@ -1594,6 +1596,8 @@ static void _register_variant_builtin_methods() { bind_method(Vector3i, min_axis_index, sarray(), varray()); bind_method(Vector3i, max_axis_index, sarray(), varray()); + bind_method(Vector3i, length, sarray(), varray()); + bind_method(Vector3i, length_squared, sarray(), varray()); bind_method(Vector3i, sign, sarray(), varray()); bind_method(Vector3i, abs, sarray(), varray()); bind_method(Vector3i, clamp, sarray("min", "max"), varray()); @@ -1834,7 +1838,7 @@ static void _register_variant_builtin_methods() { bind_method(Array, bsearch_custom, sarray("value", "func", "before"), varray(true)); bind_method(Array, reverse, sarray(), varray()); bind_method(Array, duplicate, sarray("deep"), varray(false)); - bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false)); + bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(INT_MAX, 1, false)); bind_method(Array, filter, sarray("method"), varray()); bind_method(Array, map, sarray("method"), varray()); bind_method(Array, reduce, sarray("method", "accum"), varray(Variant())); @@ -1854,7 +1858,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedByteArray, resize, sarray("new_size"), varray()); bind_method(PackedByteArray, has, sarray("value"), varray()); bind_method(PackedByteArray, reverse, sarray(), varray()); - bind_method(PackedByteArray, slice, sarray("begin", "end"), varray()); + bind_method(PackedByteArray, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedByteArray, sort, sarray(), varray()); bind_method(PackedByteArray, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedByteArray, duplicate, sarray(), varray()); @@ -1915,7 +1919,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt32Array, resize, sarray("new_size"), varray()); bind_method(PackedInt32Array, has, sarray("value"), varray()); bind_method(PackedInt32Array, reverse, sarray(), varray()); - bind_method(PackedInt32Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedInt32Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedInt32Array, to_byte_array, sarray(), varray()); bind_method(PackedInt32Array, sort, sarray(), varray()); bind_method(PackedInt32Array, bsearch, sarray("value", "before"), varray(true)); @@ -1935,7 +1939,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt64Array, resize, sarray("new_size"), varray()); bind_method(PackedInt64Array, has, sarray("value"), varray()); bind_method(PackedInt64Array, reverse, sarray(), varray()); - bind_method(PackedInt64Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedInt64Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedInt64Array, to_byte_array, sarray(), varray()); bind_method(PackedInt64Array, sort, sarray(), varray()); bind_method(PackedInt64Array, bsearch, sarray("value", "before"), varray(true)); @@ -1955,7 +1959,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat32Array, resize, sarray("new_size"), varray()); bind_method(PackedFloat32Array, has, sarray("value"), varray()); bind_method(PackedFloat32Array, reverse, sarray(), varray()); - bind_method(PackedFloat32Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedFloat32Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedFloat32Array, to_byte_array, sarray(), varray()); bind_method(PackedFloat32Array, sort, sarray(), varray()); bind_method(PackedFloat32Array, bsearch, sarray("value", "before"), varray(true)); @@ -1975,7 +1979,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat64Array, resize, sarray("new_size"), varray()); bind_method(PackedFloat64Array, has, sarray("value"), varray()); bind_method(PackedFloat64Array, reverse, sarray(), varray()); - bind_method(PackedFloat64Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedFloat64Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedFloat64Array, to_byte_array, sarray(), varray()); bind_method(PackedFloat64Array, sort, sarray(), varray()); bind_method(PackedFloat64Array, bsearch, sarray("value", "before"), varray(true)); @@ -1995,7 +1999,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedStringArray, resize, sarray("new_size"), varray()); bind_method(PackedStringArray, has, sarray("value"), varray()); bind_method(PackedStringArray, reverse, sarray(), varray()); - bind_method(PackedStringArray, slice, sarray("begin", "end"), varray()); + bind_method(PackedStringArray, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedStringArray, to_byte_array, sarray(), varray()); bind_method(PackedStringArray, sort, sarray(), varray()); bind_method(PackedStringArray, bsearch, sarray("value", "before"), varray(true)); @@ -2015,7 +2019,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector2Array, resize, sarray("new_size"), varray()); bind_method(PackedVector2Array, has, sarray("value"), varray()); bind_method(PackedVector2Array, reverse, sarray(), varray()); - bind_method(PackedVector2Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedVector2Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedVector2Array, to_byte_array, sarray(), varray()); bind_method(PackedVector2Array, sort, sarray(), varray()); bind_method(PackedVector2Array, bsearch, sarray("value", "before"), varray(true)); @@ -2035,7 +2039,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector3Array, resize, sarray("new_size"), varray()); bind_method(PackedVector3Array, has, sarray("value"), varray()); bind_method(PackedVector3Array, reverse, sarray(), varray()); - bind_method(PackedVector3Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedVector3Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedVector3Array, to_byte_array, sarray(), varray()); bind_method(PackedVector3Array, sort, sarray(), varray()); bind_method(PackedVector3Array, bsearch, sarray("value", "before"), varray(true)); @@ -2055,7 +2059,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedColorArray, resize, sarray("new_size"), varray()); bind_method(PackedColorArray, has, sarray("value"), varray()); bind_method(PackedColorArray, reverse, sarray(), varray()); - bind_method(PackedColorArray, slice, sarray("begin", "end"), varray()); + bind_method(PackedColorArray, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedColorArray, to_byte_array, sarray(), varray()); bind_method(PackedColorArray, sort, sarray(), varray()); bind_method(PackedColorArray, bsearch, sarray("value", "before"), varray(true)); diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h index 9791cb67b3..f72a92d31a 100644 --- a/core/variant/variant_op.h +++ b/core/variant/variant_op.h @@ -775,6 +775,7 @@ public: r_valid = true; } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *r_ret = Array(); _add_arrays(*VariantGetInternalPtr<Array>::get_ptr(r_ret), *VariantGetInternalPtr<Array>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right)); } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index dff46f2042..fa8d26a72b 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -2120,7 +2120,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case BASIS: { - r_dst = Transform3D(*a._data._basis).interpolate_with(Transform3D(*b._data._basis), c).basis; + r_dst = a._data._basis->lerp(*b._data._basis, c); } return; case TRANSFORM3D: { |