diff options
Diffstat (limited to 'modules')
751 files changed, 7834 insertions, 6132 deletions
diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp index 9a13406900..12f9c6fc00 100644 --- a/modules/basis_universal/register_types.cpp +++ b/modules/basis_universal/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -203,7 +203,7 @@ static Ref<Image> basis_universal_unpacker(const Vector<uint8_t> &p_buffer) { format = basist::transcoder_texture_format::cTFETC2; // get this from renderer imgfmt = Image::FORMAT_ETC2_RGBA8; } else { - //gles2 most likely + //opengl most likely format = basist::transcoder_texture_format::cTFRGBA4444; // get this from renderer imgfmt = Image::FORMAT_RGBA4444; } @@ -216,7 +216,7 @@ static Ref<Image> basis_universal_unpacker(const Vector<uint8_t> &p_buffer) { format = basist::transcoder_texture_format::cTFETC2; // get this from renderer imgfmt = Image::FORMAT_ETC2_RGBA8; } else { - //gles2 most likely, bad for normal maps, nothing to do about this. + //opengl most likely, bad for normal maps, nothing to do about this. format = basist::transcoder_texture_format::cTFRGBA32; imgfmt = Image::FORMAT_RGBA8; } diff --git a/modules/basis_universal/register_types.h b/modules/basis_universal/register_types.h index 30b465e344..7275c2ebb7 100644 --- a/modules/basis_universal/register_types.h +++ b/modules/basis_universal/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/basis_universal/texture_basisu.cpp b/modules/basis_universal/texture_basisu.cpp index 9e917420ce..1ac4df8d19 100644 --- a/modules/basis_universal/texture_basisu.cpp +++ b/modules/basis_universal/texture_basisu.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/basis_universal/texture_basisu.h b/modules/basis_universal/texture_basisu.h index 3316035404..8c8be68254 100644 --- a/modules/basis_universal/texture_basisu.h +++ b/modules/basis_universal/texture_basisu.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index bd8342e1aa..ad2c7d6a3e 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -248,8 +248,7 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f, } // Don't rely on sizeof(bmp_file_header) as structure padding // adds 2 bytes offset leading to misaligned color table reading - uint32_t ct_offset = BITMAP_FILE_HEADER_SIZE + - bmp_header.bmp_info_header.bmp_header_size; + uint32_t ct_offset = BITMAP_FILE_HEADER_SIZE + bmp_header.bmp_info_header.bmp_header_size; f->seek(ct_offset); uint32_t color_table_size = 0; @@ -271,8 +270,7 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f, f->seek(bmp_header.bmp_file_header.bmp_file_offset); - uint32_t bmp_buffer_size = (bmp_header.bmp_file_header.bmp_file_size - - bmp_header.bmp_file_header.bmp_file_offset); + uint32_t bmp_buffer_size = (bmp_header.bmp_file_header.bmp_file_size - bmp_header.bmp_file_header.bmp_file_offset); Vector<uint8_t> bmp_buffer; err = bmp_buffer.resize(bmp_buffer_size); diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h index 379e971458..9c9a16a9f5 100644 --- a/modules/bmp/image_loader_bmp.h +++ b/modules/bmp/image_loader_bmp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bmp/register_types.cpp b/modules/bmp/register_types.cpp index d36ce9cdaf..13e44099e5 100644 --- a/modules/bmp/register_types.cpp +++ b/modules/bmp/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bmp/register_types.h b/modules/bmp/register_types.h index 3ce81eba1b..1e53f4c2f7 100644 --- a/modules/bmp/register_types.h +++ b/modules/bmp/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index c3bd84c329..d17e880fc0 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -59,8 +59,8 @@ AreaBullet::AreaBullet() : AreaBullet::~AreaBullet() { // signal are handled by godot, so just clear without notify - for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - overlappingObjects[i].object->on_exit_area(this); + for (int i = 0; i < overlapping_shapes.size(); i++) { + overlapping_shapes[i].other_object->on_exit_area(this); } } @@ -70,89 +70,140 @@ void AreaBullet::dispatch_callbacks() { } isScratched = false; - // Reverse order because I've to remove EXIT objects - for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - OverlappingObjectData &otherObj = overlappingObjects.write[i]; + // Reverse order so items can be removed. + for (int i = overlapping_shapes.size() - 1; i >= 0; i--) { + OverlappingShapeData &overlapping_shape = overlapping_shapes.write[i]; - switch (otherObj.state) { + switch (overlapping_shape.state) { case OVERLAP_STATE_ENTER: - otherObj.state = OVERLAP_STATE_INSIDE; - call_event(otherObj.object, PhysicsServer3D::AREA_BODY_ADDED); - otherObj.object->on_enter_area(this); + overlapping_shape.state = OVERLAP_STATE_INSIDE; + call_event(overlapping_shape, PhysicsServer3D::AREA_BODY_ADDED); + if (_overlapping_shape_count(overlapping_shape.other_object) == 1) { + // This object's first shape being added. + overlapping_shape.other_object->on_enter_area(this); + } break; case OVERLAP_STATE_EXIT: - call_event(otherObj.object, PhysicsServer3D::AREA_BODY_REMOVED); - otherObj.object->on_exit_area(this); - overlappingObjects.remove(i); // Remove after callback + call_event(overlapping_shape, PhysicsServer3D::AREA_BODY_REMOVED); + if (_overlapping_shape_count(overlapping_shape.other_object) == 1) { + // This object's last shape being removed. + overlapping_shape.other_object->on_exit_area(this); + } + overlapping_shapes.remove_at(i); // Remove after callback break; + case OVERLAP_STATE_INSIDE: { + if (overlapping_shape.other_object->getType() == TYPE_RIGID_BODY) { + RigidBodyBullet *body = static_cast<RigidBodyBullet *>(overlapping_shape.other_object); + body->scratch_space_override_modificator(); + } + break; + } case OVERLAP_STATE_DIRTY: - case OVERLAP_STATE_INSIDE: break; } } } -void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status) { - InOutEventCallback &event = eventsCallbacks[static_cast<int>(p_otherObject->getType())]; - Object *areaGodoObject = ObjectDB::get_instance(event.event_callback_id); +void AreaBullet::call_event(const OverlappingShapeData &p_overlapping_shape, PhysicsServer3D::AreaBodyStatus p_status) { + InOutEventCallback &event = eventsCallbacks[static_cast<int>(p_overlapping_shape.other_object->getType())]; - if (!areaGodoObject) { - event.event_callback_id = ObjectID(); + if (!event.event_callback.is_valid()) { + event.event_callback = Callable(); return; } call_event_res[0] = p_status; - call_event_res[1] = p_otherObject->get_self(); // Other body - call_event_res[2] = p_otherObject->get_instance_id(); // instance ID - call_event_res[3] = 0; // other_body_shape ID - call_event_res[4] = 0; // self_shape ID + call_event_res[1] = p_overlapping_shape.other_object->get_self(); // RID + call_event_res[2] = p_overlapping_shape.other_object->get_instance_id(); // Object ID + call_event_res[3] = p_overlapping_shape.other_shape_id; // Other object's shape ID + call_event_res[4] = p_overlapping_shape.our_shape_id; // This area's shape ID Callable::CallError outResp; - areaGodoObject->call(event.event_callback_method, (const Variant **)call_event_res_ptr, 5, outResp); + Variant ret; + event.event_callback.call((const Variant **)call_event_res, 5, ret, outResp); } -void AreaBullet::scratch() { - if (isScratched) { - return; +int AreaBullet::_overlapping_shape_count(CollisionObjectBullet *p_other_object) { + int count = 0; + for (int i = 0; i < overlapping_shapes.size(); i++) { + if (overlapping_shapes[i].other_object == p_other_object) { + count++; + } } - isScratched = true; + return count; } -void AreaBullet::clear_overlaps(bool p_notify) { - for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - if (p_notify) { - call_event(overlappingObjects[i].object, PhysicsServer3D::AREA_BODY_REMOVED); +int AreaBullet::_find_overlapping_shape(CollisionObjectBullet *p_other_object, uint32_t p_other_shape_id, uint32_t p_our_shape_id) { + for (int i = 0; i < overlapping_shapes.size(); i++) { + const OverlappingShapeData &overlapping_shape = overlapping_shapes[i]; + if (overlapping_shape.other_object == p_other_object && overlapping_shape.other_shape_id == p_other_shape_id && overlapping_shape.our_shape_id == p_our_shape_id) { + return i; } - overlappingObjects[i].object->on_exit_area(this); } - overlappingObjects.clear(); + return -1; } -void AreaBullet::remove_overlap(CollisionObjectBullet *p_object, bool p_notify) { - for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - if (overlappingObjects[i].object == p_object) { - if (p_notify) { - call_event(overlappingObjects[i].object, PhysicsServer3D::AREA_BODY_REMOVED); - } - overlappingObjects[i].object->on_exit_area(this); - overlappingObjects.remove(i); - break; +void AreaBullet::mark_all_overlaps_dirty() { + OverlappingShapeData *overlapping_shapes_w = overlapping_shapes.ptrw(); + for (int i = 0; i < overlapping_shapes.size(); i++) { + // Don't overwrite OVERLAP_STATE_ENTER state. + if (overlapping_shapes_w[i].state != OVERLAP_STATE_ENTER) { + overlapping_shapes_w[i].state = OVERLAP_STATE_DIRTY; } } } -int AreaBullet::find_overlapping_object(CollisionObjectBullet *p_colObj) { - const int size = overlappingObjects.size(); - for (int i = 0; i < size; ++i) { - if (overlappingObjects[i].object == p_colObj) { - return i; +void AreaBullet::mark_object_overlaps_inside(CollisionObjectBullet *p_other_object) { + OverlappingShapeData *overlapping_shapes_w = overlapping_shapes.ptrw(); + for (int i = 0; i < overlapping_shapes.size(); i++) { + if (overlapping_shapes_w[i].other_object == p_other_object && overlapping_shapes_w[i].state == OVERLAP_STATE_DIRTY) { + overlapping_shapes_w[i].state = OVERLAP_STATE_INSIDE; } } - return -1; +} + +void AreaBullet::set_overlap(CollisionObjectBullet *p_other_object, uint32_t p_other_shape_id, uint32_t p_our_shape_id) { + int i = _find_overlapping_shape(p_other_object, p_other_shape_id, p_our_shape_id); + if (i == -1) { // Not found, create new one. + OverlappingShapeData overlapping_shape(p_other_object, OVERLAP_STATE_ENTER, p_other_shape_id, p_our_shape_id); + overlapping_shapes.push_back(overlapping_shape); + p_other_object->notify_new_overlap(this); + isScratched = true; + } else { + overlapping_shapes.ptrw()[i].state = OVERLAP_STATE_INSIDE; + } +} + +void AreaBullet::mark_all_dirty_overlaps_as_exit() { + OverlappingShapeData *overlapping_shapes_w = overlapping_shapes.ptrw(); + for (int i = 0; i < overlapping_shapes.size(); i++) { + if (overlapping_shapes[i].state == OVERLAP_STATE_DIRTY) { + overlapping_shapes_w[i].state = OVERLAP_STATE_EXIT; + isScratched = true; + } + } +} + +void AreaBullet::remove_object_overlaps(CollisionObjectBullet *p_object) { + // Reverse order so items can be removed. + for (int i = overlapping_shapes.size() - 1; i >= 0; i--) { + if (overlapping_shapes[i].other_object == p_object) { + overlapping_shapes.remove_at(i); + } + } +} + +void AreaBullet::clear_overlaps() { + for (int i = 0; i < overlapping_shapes.size(); i++) { + call_event(overlapping_shapes[i], PhysicsServer3D::AREA_BODY_REMOVED); + overlapping_shapes[i].other_object->on_exit_area(this); + } + overlapping_shapes.clear(); } void AreaBullet::set_monitorable(bool p_monitorable) { monitorable = p_monitorable; + updated = true; } bool AreaBullet::is_monitoring() const { @@ -162,6 +213,7 @@ bool AreaBullet::is_monitoring() const { void AreaBullet::main_shape_changed() { CRASH_COND(!get_main_shape()); btGhost->setCollisionShape(get_main_shape()); + updated = true; } void AreaBullet::reload_body() { @@ -174,7 +226,7 @@ void AreaBullet::reload_body() { void AreaBullet::set_space(SpaceBullet *p_space) { // Clear the old space if there is one if (space) { - clear_overlaps(false); + clear_overlaps(); isScratched = false; // Remove this object form the physics world @@ -192,24 +244,7 @@ void AreaBullet::on_collision_filters_change() { if (space) { space->reload_collision_filters(this); } -} - -void AreaBullet::add_overlap(CollisionObjectBullet *p_otherObject) { - scratch(); - overlappingObjects.push_back(OverlappingObjectData(p_otherObject, OVERLAP_STATE_ENTER)); - p_otherObject->notify_new_overlap(this); -} - -void AreaBullet::put_overlap_as_exit(int p_index) { - scratch(); - overlappingObjects.write[p_index].state = OVERLAP_STATE_EXIT; -} - -void AreaBullet::put_overlap_as_inside(int p_index) { - // This check is required to be sure this body was inside - if (OVERLAP_STATE_DIRTY == overlappingObjects[p_index].state) { - overlappingObjects.write[p_index].state = OVERLAP_STATE_INSIDE; - } + updated = true; } void AreaBullet::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) { @@ -241,6 +276,7 @@ void AreaBullet::set_param(PhysicsServer3D::AreaParameter p_param, const Variant default: WARN_PRINT("Area doesn't support this parameter in the Bullet backend: " + itos(p_param)); } + isScratched = true; } Variant AreaBullet::get_param(PhysicsServer3D::AreaParameter p_param) const { @@ -267,21 +303,21 @@ Variant AreaBullet::get_param(PhysicsServer3D::AreaParameter p_param) const { } } -void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method) { +void AreaBullet::set_event_callback(Type p_callbackObjectType, const Callable &p_callback) { InOutEventCallback &ev = eventsCallbacks[static_cast<int>(p_callbackObjectType)]; - ev.event_callback_id = p_id; - ev.event_callback_method = p_method; + ev.event_callback = p_callback; /// Set if monitoring - if (eventsCallbacks[0].event_callback_id.is_valid() || eventsCallbacks[1].event_callback_id.is_valid()) { + if (!eventsCallbacks[0].event_callback.is_null() || !eventsCallbacks[1].event_callback.is_null()) { set_godot_object_flags(get_godot_object_flags() | GOF_IS_MONITORING_AREA); } else { set_godot_object_flags(get_godot_object_flags() & (~GOF_IS_MONITORING_AREA)); + clear_overlaps(); } } bool AreaBullet::has_event_callback(Type p_callbackObjectType) { - return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id.is_valid(); + return !eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback.is_null(); } void AreaBullet::on_enter_area(AreaBullet *p_area) { diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index 7cf666c119..caf81ef1be 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,12 +43,9 @@ class btGhostObject; class AreaBullet : public RigidCollisionObjectBullet { - friend void SpaceBullet::check_ghost_overlaps(); - public: struct InOutEventCallback { - ObjectID event_callback_id; - StringName event_callback_method; + Callable event_callback; InOutEventCallback() {} }; @@ -60,21 +57,19 @@ public: OVERLAP_STATE_EXIT // Mark ended overlaps }; - struct OverlappingObjectData { - CollisionObjectBullet *object = nullptr; - OverlapState state = OVERLAP_STATE_ENTER; - - OverlappingObjectData() {} - OverlappingObjectData(CollisionObjectBullet *p_object, OverlapState p_state) : - object(p_object), - state(p_state) {} - OverlappingObjectData(const OverlappingObjectData &other) { - operator=(other); - } - void operator=(const OverlappingObjectData &other) { - object = other.object; - state = other.state; - } + struct OverlappingShapeData { + CollisionObjectBullet *other_object = nullptr; + OverlapState state = OVERLAP_STATE_DIRTY; + uint32_t other_shape_id = 0; + uint32_t our_shape_id = 0; + + OverlappingShapeData() {} + + OverlappingShapeData(CollisionObjectBullet *p_other_object, OverlapState p_state, uint32_t p_other_shape_id, uint32_t p_our_shape_id) : + other_object(p_other_object), + state(p_state), + other_shape_id(p_other_shape_id), + our_shape_id(p_our_shape_id) {} }; private: @@ -83,7 +78,9 @@ private: Variant *call_event_res_ptr[5] = {}; btGhostObject *btGhost = nullptr; - Vector<OverlappingObjectData> overlappingObjects; + Vector<OverlappingShapeData> overlapping_shapes; + int _overlapping_shape_count(CollisionObjectBullet *p_other_object); + int _find_overlapping_shape(CollisionObjectBullet *p_other_object, uint32_t p_other_shape_id, uint32_t p_our_shape_id); bool monitorable = true; PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; @@ -105,7 +102,6 @@ public: ~AreaBullet(); _FORCE_INLINE_ btGhostObject *get_bt_ghost() const { return btGhost; } - int find_overlapping_object(CollisionObjectBullet *p_colObj); void set_monitorable(bool p_monitorable); _FORCE_INLINE_ bool is_monitorable() const { return monitorable; } @@ -144,26 +140,23 @@ public: virtual void set_space(SpaceBullet *p_space); virtual void dispatch_callbacks(); - void call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status); - void set_on_state_change(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant()); - void scratch(); - - void clear_overlaps(bool p_notify); - // Dispatch the callbacks and removes from overlapping list - void remove_overlap(CollisionObjectBullet *p_object, bool p_notify); + void call_event(const OverlappingShapeData &p_overlapping_shape, PhysicsServer3D::AreaBodyStatus p_status); virtual void on_collision_filters_change(); virtual void on_collision_checker_start() {} - virtual void on_collision_checker_end() { isTransformChanged = false; } + virtual void on_collision_checker_end() { updated = false; } - void add_overlap(CollisionObjectBullet *p_otherObject); - void put_overlap_as_exit(int p_index); - void put_overlap_as_inside(int p_index); + void mark_all_overlaps_dirty(); + void mark_object_overlaps_inside(CollisionObjectBullet *p_other_object); + void set_overlap(CollisionObjectBullet *p_other_object, uint32_t p_other_shape_id, uint32_t p_our_shape_id); + void mark_all_dirty_overlaps_as_exit(); + void remove_object_overlaps(CollisionObjectBullet *p_object); + void clear_overlaps(); void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value); Variant get_param(PhysicsServer3D::AreaParameter p_param) const; - void set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method); + void set_event_callback(Type p_callbackObjectType, const Callable &p_callback); bool has_event_callback(Type p_callbackObjectType); virtual void on_enter_area(AreaBullet *p_area); diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp index 109854c9dd..e67c9baacd 100644 --- a/modules/bullet/btRayShape.cpp +++ b/modules/bullet/btRayShape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h index 330755aa31..5d0a05b369 100644 --- a/modules/bullet/btRayShape.h +++ b/modules/bullet/btRayShape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index bb2db49c87..9bf3e186ee 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -413,18 +413,18 @@ void BulletPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) area->set_monitorable(p_monitorable); } -void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { +void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, const Callable &p_callback) { AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); + area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_callback.is_valid() ? p_callback : Callable()); } -void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { +void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) { AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); + area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_callback.is_valid() ? p_callback : Callable()); } void BulletPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) { @@ -837,8 +837,17 @@ void BulletPhysicsServer3D::body_set_ray_pickable(RID p_body, bool p_enable) { } PhysicsDirectBodyState3D *BulletPhysicsServer3D::body_get_direct_state(RID p_body) { + if (!rigid_body_owner.owns(p_body)) { + return nullptr; + } + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, nullptr); + + if (!body->get_space()) { + return nullptr; + } + return BulletPhysicsDirectBodyState3D::get_singleton(body); } diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 7c146de0c3..5840eff815 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -160,8 +160,8 @@ public: virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; virtual void area_set_monitorable(RID p_area, bool p_monitorable) override; - virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override; - virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override; + virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override; + virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override; virtual void area_set_ray_pickable(RID p_area, bool p_enable) override; /* RIGID BODY API */ diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp index 01461767bd..571457f48f 100644 --- a/modules/bullet/bullet_types_converter.cpp +++ b/modules/bullet/bullet_types_converter.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h index e184fe1769..b4d6dccc05 100644 --- a/modules/bullet/bullet_types_converter.h +++ b/modules/bullet/bullet_types_converter.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h index a7c0fafbea..b832d3fc61 100644 --- a/modules/bullet/bullet_utilities.h +++ b/modules/bullet/bullet_utilities.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index c45bd5bbc0..6bf01a63df 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -93,11 +93,9 @@ CollisionObjectBullet::CollisionObjectBullet(Type p_type) : type(p_type) {} CollisionObjectBullet::~CollisionObjectBullet() { - // Remove all overlapping, notify is not required since godot take care of it - for (int i = areasOverlapped.size() - 1; 0 <= i; --i) { - areasOverlapped[i]->remove_overlap(this, /*Notify*/ false); + for (int i = 0; i < areasOverlapped.size(); i++) { + areasOverlapped[i]->remove_object_overlaps(this); } - destroyBulletCollisionObject(); } @@ -178,7 +176,9 @@ bool CollisionObjectBullet::is_collisions_response_enabled() { } void CollisionObjectBullet::notify_new_overlap(AreaBullet *p_area) { - areasOverlapped.push_back(p_area); + if (areasOverlapped.find(p_area) == -1) { + areasOverlapped.push_back(p_area); + } } void CollisionObjectBullet::on_exit_area(AreaBullet *p_area) { @@ -187,6 +187,7 @@ void CollisionObjectBullet::on_exit_area(AreaBullet *p_area) { void CollisionObjectBullet::set_godot_object_flags(int flags) { bt_collision_object->setUserIndex2(flags); + updated = true; } int CollisionObjectBullet::get_godot_object_flags() const { @@ -220,7 +221,7 @@ const btTransform &CollisionObjectBullet::get_transform__bullet() const { } void CollisionObjectBullet::notify_transform_changed() { - isTransformChanged = true; + updated = true; } RigidCollisionObjectBullet::~RigidCollisionObjectBullet() { @@ -272,7 +273,7 @@ void RigidCollisionObjectBullet::remove_shape_full(ShapeBullet *p_shape) { for (int i = shapes.size() - 1; 0 <= i; --i) { if (p_shape == shapes[i].shape) { internal_shape_destroy(i); - shapes.remove(i); + shapes.remove_at(i); } } reload_shapes(); @@ -281,7 +282,7 @@ void RigidCollisionObjectBullet::remove_shape_full(ShapeBullet *p_shape) { void RigidCollisionObjectBullet::remove_shape_full(int p_index) { ERR_FAIL_INDEX(p_index, get_shape_count()); internal_shape_destroy(p_index); - shapes.remove(p_index); + shapes.remove_at(p_index); reload_shapes(); } diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index 944ab89b87..09be2d99d2 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -128,7 +128,7 @@ protected: /// New area is added when overlap with new area (AreaBullet::addOverlap), then is removed when it exit (CollisionObjectBullet::onExitArea) /// This array is used mainly to know which area hold the pointer of this object Vector<AreaBullet *> areasOverlapped; - bool isTransformChanged = false; + bool updated = false; public: CollisionObjectBullet(Type p_type); @@ -206,9 +206,9 @@ public: Transform3D get_transform() const; virtual void set_transform__bullet(const btTransform &p_global_transform); virtual const btTransform &get_transform__bullet() const; - - bool is_transform_changed() const { return isTransformChanged; } virtual void notify_transform_changed(); + + bool is_updated() const { return updated; } }; class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet { diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp index 34516d8b3b..544d711259 100644 --- a/modules/bullet/cone_twist_joint_bullet.cpp +++ b/modules/bullet/cone_twist_joint_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h index 7e51f7d644..ebb51868f4 100644 --- a/modules/bullet/cone_twist_joint_bullet.h +++ b/modules/bullet/cone_twist_joint_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp index e610727685..5b4b0e75bc 100644 --- a/modules/bullet/constraint_bullet.cpp +++ b/modules/bullet/constraint_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h index 6afd8c9b52..5e63d7a1b5 100644 --- a/modules/bullet/constraint_bullet.h +++ b/modules/bullet/constraint_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp index 7e04d57b9d..01e1ecbdf6 100644 --- a/modules/bullet/generic_6dof_joint_bullet.cpp +++ b/modules/bullet/generic_6dof_joint_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h index 00567e3085..b5d1db8fd6 100644 --- a/modules/bullet/generic_6dof_joint_bullet.h +++ b/modules/bullet/generic_6dof_joint_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp index 94f150b712..0e872fa1c1 100644 --- a/modules/bullet/godot_collision_configuration.cpp +++ b/modules/bullet/godot_collision_configuration.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/godot_collision_configuration.h b/modules/bullet/godot_collision_configuration.h index 8ed55cb1da..3b1bc3a97d 100644 --- a/modules/bullet/godot_collision_configuration.h +++ b/modules/bullet/godot_collision_configuration.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/godot_collision_dispatcher.cpp b/modules/bullet/godot_collision_dispatcher.cpp index 423166c408..c926462eda 100644 --- a/modules/bullet/godot_collision_dispatcher.cpp +++ b/modules/bullet/godot_collision_dispatcher.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/godot_collision_dispatcher.h b/modules/bullet/godot_collision_dispatcher.h index 77472a9432..77b8cee0a6 100644 --- a/modules/bullet/godot_collision_dispatcher.h +++ b/modules/bullet/godot_collision_dispatcher.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h index ca17349130..a37fef9d90 100644 --- a/modules/bullet/godot_motion_state.h +++ b/modules/bullet/godot_motion_state.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/godot_ray_world_algorithm.cpp b/modules/bullet/godot_ray_world_algorithm.cpp index a8291d4ab4..3b7513916d 100644 --- a/modules/bullet/godot_ray_world_algorithm.cpp +++ b/modules/bullet/godot_ray_world_algorithm.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/godot_ray_world_algorithm.h b/modules/bullet/godot_ray_world_algorithm.h index 25798aecb4..f554108a75 100644 --- a/modules/bullet/godot_ray_world_algorithm.h +++ b/modules/bullet/godot_ray_world_algorithm.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index 1f962772e7..d4b6e90117 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -107,7 +107,14 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo PhysicsDirectSpaceState3D::ShapeResult &result = m_results[count]; - result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is an odd name but contains the compound shape ID + // Triangle index is an odd name but contains the compound shape ID. + // A shape part of -1 indicates the index is a shape index and not a triangle index. + if (convexResult.m_localShapeInfo && convexResult.m_localShapeInfo->m_shapePart == -1) { + result.shape = convexResult.m_localShapeInfo->m_triangleIndex; + } else { + result.shape = 0; + } + result.rid = gObj->get_self(); result.collider_id = gObj->get_instance_id(); result.collider = result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(result.collider_id); @@ -171,11 +178,14 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) } btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) { - if (convexResult.m_localShapeInfo) { - m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is an odd name but contains the compound shape ID + // Triangle index is an odd name but contains the compound shape ID. + // A shape part of -1 indicates the index is a shape index and not a triangle index. + if (convexResult.m_localShapeInfo && convexResult.m_localShapeInfo->m_shapePart == -1) { + m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; } else { m_shapeId = 0; } + return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace); } @@ -219,10 +229,22 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con CollisionObjectBullet *colObj; if (m_self_object == colObj0Wrap->getCollisionObject()) { colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer()); - result.shape = cp.m_index1; + // Checking for compound shape because the index might be uninitialized otherwise. + // A partId of -1 indicates the index is a shape index and not a triangle index. + if (colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId1 == -1) { + result.shape = cp.m_index1; + } else { + result.shape = 0; + } } else { colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer()); - result.shape = cp.m_index0; + // Checking for compound shape because the index might be uninitialized otherwise. + // A partId of -1 indicates the index is a shape index and not a triangle index. + if (colObj0Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId0 == -1) { + result.shape = cp.m_index0; + } else { + result.shape = 0; + } } result.collider_id = colObj->get_instance_id(); @@ -311,14 +333,26 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp CollisionObjectBullet *colObj; if (m_self_object == colObj0Wrap->getCollisionObject()) { colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer()); - m_result->shape = cp.m_index1; + // Checking for compound shape because the index might be uninitialized otherwise. + // A partId of -1 indicates the index is a shape index and not a triangle index. + if (colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId1 == -1) { + m_result->shape = cp.m_index1; + } else { + m_result->shape = 0; + } B_TO_G(cp.getPositionWorldOnB(), m_result->point); B_TO_G(cp.m_normalWorldOnB, m_result->normal); m_rest_info_bt_point = cp.getPositionWorldOnB(); m_rest_info_collision_object = colObj1Wrap->getCollisionObject(); } else { colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer()); - m_result->shape = cp.m_index0; + // Checking for compound shape because the index might be uninitialized otherwise. + // A partId of -1 indicates the index is a shape index and not a triangle index. + if (colObj0Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId0 == -1) { + m_result->shape = cp.m_index0; + } else { + m_result->shape = 0; + } B_TO_G(cp.m_normalWorldOnB * -1, m_result->normal); m_rest_info_bt_point = cp.getPositionWorldOnA(); m_rest_info_collision_object = colObj0Wrap->getCollisionObject(); diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index 96a649d77a..94be993212 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -70,8 +70,10 @@ public: virtual bool needsCollision(btBroadphaseProxy *proxy0) const; virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) { - if (rayResult.m_localShapeInfo) { - m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID + // Triangle index is an odd name but contains the compound shape ID. + // A shape part of -1 indicates the index is a shape index and not a triangle index. + if (rayResult.m_localShapeInfo && rayResult.m_localShapeInfo->m_shapePart == -1) { + m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; } else { m_shapeId = 0; } diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp index b5fe50cf5f..116d8caba7 100644 --- a/modules/bullet/hinge_joint_bullet.cpp +++ b/modules/bullet/hinge_joint_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/hinge_joint_bullet.h b/modules/bullet/hinge_joint_bullet.h index dd0f69ba68..7b87576442 100644 --- a/modules/bullet/hinge_joint_bullet.h +++ b/modules/bullet/hinge_joint_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/joint_bullet.cpp b/modules/bullet/joint_bullet.cpp index ac371658f5..65a891e890 100644 --- a/modules/bullet/joint_bullet.cpp +++ b/modules/bullet/joint_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h index 5bb8b50961..75f6055b2f 100644 --- a/modules/bullet/joint_bullet.h +++ b/modules/bullet/joint_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp index 8e8ff57f11..03853cc830 100644 --- a/modules/bullet/pin_joint_bullet.cpp +++ b/modules/bullet/pin_joint_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/pin_joint_bullet.h b/modules/bullet/pin_joint_bullet.h index 6fbb6f7e02..0510cf99ad 100644 --- a/modules/bullet/pin_joint_bullet.h +++ b/modules/bullet/pin_joint_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp index b5ad5749a6..675a5c8491 100644 --- a/modules/bullet/register_types.cpp +++ b/modules/bullet/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/register_types.h b/modules/bullet/register_types.h index e405996705..739614dc52 100644 --- a/modules/bullet/register_types.h +++ b/modules/bullet/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h index face6b4861..982654441e 100644 --- a/modules/bullet/rid_bullet.h +++ b/modules/bullet/rid_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 7b20fad28c..0112712736 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -420,7 +420,7 @@ void RigidBodyBullet::on_collision_checker_start() { void RigidBodyBullet::on_collision_checker_end() { // Always true if active and not a static or kinematic body - isTransformChanged = btBody->isActive() && !btBody->isStaticOrKinematicObject(); + updated = btBody->isActive() && !btBody->isStaticOrKinematicObject(); } bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const real_t &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) { diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index 01ac1e4836..f41c5ca1c9 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index ec039ba842..2b2a7dd8f1 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index 0822399b5e..93e9bed201 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/shape_owner_bullet.cpp b/modules/bullet/shape_owner_bullet.cpp index ea8821eaec..7f516e83c0 100644 --- a/modules/bullet/shape_owner_bullet.cpp +++ b/modules/bullet/shape_owner_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/shape_owner_bullet.h b/modules/bullet/shape_owner_bullet.h index 4bd583e096..5f8bb61503 100644 --- a/modules/bullet/shape_owner_bullet.h +++ b/modules/bullet/shape_owner_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp index 1d83118468..a3190609a1 100644 --- a/modules/bullet/slider_joint_bullet.cpp +++ b/modules/bullet/slider_joint_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/slider_joint_bullet.h b/modules/bullet/slider_joint_bullet.h index 0c93558449..556f4e9e64 100644 --- a/modules/bullet/slider_joint_bullet.h +++ b/modules/bullet/slider_joint_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index 371800d8f3..ea5a059b9e 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,7 +71,7 @@ void SoftBodyBullet::update_rendering_server(RenderingServerHandler *p_rendering return; } - /// Update visual server vertices + /// Update rendering server vertices const btSoftBody::tNodeArray &nodes(bt_soft_body->m_nodes); const int nodes_count = nodes.size(); @@ -116,6 +116,7 @@ void SoftBodyBullet::set_soft_mesh(RID p_mesh) { } Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0); + ERR_FAIL_COND(arrays.is_empty()); bool success = set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]); if (!success) { @@ -298,11 +299,11 @@ bool SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector ERR_FAIL_COND_V(p_indices.is_empty(), false); ERR_FAIL_COND_V(p_vertices.is_empty(), false); - /// Parse visual server indices to physical indices. - /// Merge all overlapping vertices and create a map of physical vertices to visual server + /// Parse rendering server indices to physical indices. + /// Merge all overlapping vertices and create a map of physical vertices to rendering server { - /// This is the map of visual server indices to physics indices (So it's the inverse of idices_map), Thanks to it I don't need make a heavy search in the indices_map + /// This is the map of rendering server indices to physics indices (So it's the inverse of idices_map), Thanks to it I don't need make a heavy search in the indices_map Vector<int> vs_indices_to_physics_table; { // Map vertices @@ -441,7 +442,7 @@ void SoftBodyBullet::unpin_node(int p_node_index) { } const int id = search_node_pinned(p_node_index); if (-1 != id) { - pinned_nodes.remove(id); + pinned_nodes.remove_at(id); } } diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h index 84da56ae69..fea26e9449 100644 --- a/modules/bullet/soft_body_bullet.h +++ b/modules/bullet/soft_body_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 66d7370bd7..55e822ba5a 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -426,8 +426,6 @@ void SpaceBullet::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_va case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: - case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: - case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: default: WARN_PRINT("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); break; @@ -442,8 +440,6 @@ real_t SpaceBullet::get_param(PhysicsServer3D::SpaceParameter p_param) { case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: - case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: - case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: default: WARN_PRINT("The SpaceBullet doesn't support this get parameter (" + itos(p_param) + "), 0 is returned."); return 0.f; @@ -662,101 +658,77 @@ void SpaceBullet::destroy_world() { } void SpaceBullet::check_ghost_overlaps() { - /// Algorithm support variables - btCollisionShape *other_body_shape; - btConvexShape *area_shape; - btGjkPairDetector::ClosestPointInput gjk_input; - AreaBullet *area; - int x(-1), i(-1), y(-1), z(-1), indexOverlap(-1); - - /// For each areas - for (x = areas.size() - 1; 0 <= x; --x) { - area = areas[x]; - - btVector3 area_scale(area->get_bt_body_scale()); - + // For each area + for (int area_idx = 0; area_idx < areas.size(); area_idx++) { + AreaBullet *area = areas[area_idx]; if (!area->is_monitoring()) { continue; } - /// 1. Reset all states - for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) { - AreaBullet::OverlappingObjectData &otherObj = area->overlappingObjects.write[i]; - // This check prevent the overwrite of ENTER state - // if this function is called more times before dispatchCallbacks - if (otherObj.state != AreaBullet::OVERLAP_STATE_ENTER) { - otherObj.state = AreaBullet::OVERLAP_STATE_DIRTY; - } - } + btGhostObject *bt_ghost = area->get_bt_ghost(); + const btTransform &area_transform = area->get_transform__bullet(); + const btVector3 &area_scale(area->get_bt_body_scale()); - /// 2. Check all overlapping objects using GJK + // Mark all current overlapping shapes dirty. + area->mark_all_overlaps_dirty(); - const btAlignedObjectArray<btCollisionObject *> ghostOverlaps = area->get_bt_ghost()->getOverlappingPairs(); + // Broadphase + const btAlignedObjectArray<btCollisionObject *> overlapping_pairs = bt_ghost->getOverlappingPairs(); + // Narrowphase + for (int pair_idx = 0; pair_idx < overlapping_pairs.size(); pair_idx++) { + btCollisionObject *other_bt_collision_object = overlapping_pairs[pair_idx]; + RigidCollisionObjectBullet *other_object = static_cast<RigidCollisionObjectBullet *>(other_bt_collision_object->getUserPointer()); + const btTransform &other_transform = other_object->get_transform__bullet(); + const btVector3 &other_scale(other_object->get_bt_body_scale()); - // For each overlapping - for (i = ghostOverlaps.size() - 1; 0 <= i; --i) { - bool hasOverlap = false; - btCollisionObject *overlapped_bt_co = ghostOverlaps[i]; - RigidCollisionObjectBullet *otherObject = static_cast<RigidCollisionObjectBullet *>(overlapped_bt_co->getUserPointer()); - btVector3 other_body_scale(otherObject->get_bt_body_scale()); - - if (!area->is_transform_changed() && !otherObject->is_transform_changed()) { - hasOverlap = -1 != area->find_overlapping_object(otherObject); - goto collision_found; + if (!area->is_updated() && !other_object->is_updated()) { + area->mark_object_overlaps_inside(other_object); + continue; } - if (overlapped_bt_co->getUserIndex() == CollisionObjectBullet::TYPE_AREA) { - if (!static_cast<AreaBullet *>(overlapped_bt_co->getUserPointer())->is_monitorable()) { + if (other_bt_collision_object->getUserIndex() == CollisionObjectBullet::TYPE_AREA) { + if (!static_cast<AreaBullet *>(other_bt_collision_object->getUserPointer())->is_monitorable()) { continue; } - } else if (overlapped_bt_co->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY) { + } else if (other_bt_collision_object->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY) { continue; } // For each area shape - for (y = area->get_shape_count() - 1; 0 <= y; --y) { - if (!area->get_bt_shape(y)->isConvex()) { + for (int our_shape_id = 0; our_shape_id < area->get_shape_count(); our_shape_id++) { + btCollisionShape *area_shape = area->get_bt_shape(our_shape_id); + if (!area_shape->isConvex()) { continue; } + btConvexShape *area_convex_shape = static_cast<btConvexShape *>(area_shape); - btTransform area_shape_treansform(area->get_bt_shape_transform(y)); - area_shape_treansform.getOrigin() *= area_scale; - - gjk_input.m_transformA = - area->get_transform__bullet() * - area_shape_treansform; - - area_shape = static_cast<btConvexShape *>(area->get_bt_shape(y)); + btTransform area_shape_transform(area->get_bt_shape_transform(our_shape_id)); + area_shape_transform.getOrigin() *= area_scale; + btGjkPairDetector::ClosestPointInput gjk_input; + gjk_input.m_transformA = area_transform * area_shape_transform; // For each other object shape - for (z = otherObject->get_shape_count() - 1; 0 <= z; --z) { - other_body_shape = static_cast<btCollisionShape *>(otherObject->get_bt_shape(z)); - - btTransform other_shape_transform(otherObject->get_bt_shape_transform(z)); - other_shape_transform.getOrigin() *= other_body_scale; - - gjk_input.m_transformB = - otherObject->get_transform__bullet() * - other_shape_transform; + for (int other_shape_id = 0; other_shape_id < other_object->get_shape_count(); other_shape_id++) { + btCollisionShape *other_shape = other_object->get_bt_shape(other_shape_id); + btTransform other_shape_transform(other_object->get_bt_shape_transform(other_shape_id)); + other_shape_transform.getOrigin() *= other_scale; + gjk_input.m_transformB = other_transform * other_shape_transform; - if (other_body_shape->isConvex()) { + if (other_shape->isConvex()) { btPointCollector result; btGjkPairDetector gjk_pair_detector( - area_shape, - static_cast<btConvexShape *>(other_body_shape), + area_convex_shape, + static_cast<btConvexShape *>(other_shape), gjk_simplex_solver, gjk_epa_pen_solver); - gjk_pair_detector.getClosestPoints(gjk_input, result, nullptr); - if (0 >= result.m_distance) { - hasOverlap = true; - goto collision_found; + gjk_pair_detector.getClosestPoints(gjk_input, result, nullptr); + if (result.m_distance <= 0) { + area->set_overlap(other_object, other_shape_id, our_shape_id); } - - } else { - btCollisionObjectWrapper obA(nullptr, area_shape, area->get_bt_ghost(), gjk_input.m_transformA, -1, y); - btCollisionObjectWrapper obB(nullptr, other_body_shape, otherObject->get_bt_collision_object(), gjk_input.m_transformB, -1, z); - + } else { // Other shape is not convex. + btCollisionObjectWrapper obA(nullptr, area_convex_shape, bt_ghost, gjk_input.m_transformA, -1, our_shape_id); + btCollisionObjectWrapper obB(nullptr, other_shape, other_bt_collision_object, gjk_input.m_transformB, -1, other_shape_id); btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, nullptr, BT_CONTACT_POINT_ALGORITHMS); if (!algorithm) { @@ -765,42 +737,20 @@ void SpaceBullet::check_ghost_overlaps() { GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB); algorithm->processCollision(&obA, &obB, dynamicsWorld->getDispatchInfo(), &contactPointResult); - algorithm->~btCollisionAlgorithm(); dispatcher->freeCollisionAlgorithm(algorithm); if (contactPointResult.hasHit()) { - hasOverlap = true; - goto collision_found; + area->set_overlap(other_object, our_shape_id, other_shape_id); } } + } // End for each other object shape + } // End for each area shape + } // End for each overlapping pair - } // ~For each other object shape - } // ~For each area shape - - collision_found: - if (!hasOverlap) { - continue; - } - - indexOverlap = area->find_overlapping_object(otherObject); - if (-1 == indexOverlap) { - // Not found - area->add_overlap(otherObject); - } else { - // Found - area->put_overlap_as_inside(indexOverlap); - } - } - - /// 3. Remove not overlapping - for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) { - // If the overlap has DIRTY state it means that it's no more overlapping - if (area->overlappingObjects[i].state == AreaBullet::OVERLAP_STATE_DIRTY) { - area->put_overlap_as_exit(i); - } - } - } + // All overlapping shapes still marked dirty must have exited. + area->mark_all_dirty_overlaps_as_exit(); + } // End for each area } void SpaceBullet::check_body_collision() { @@ -835,7 +785,7 @@ void SpaceBullet::check_body_collision() { btManifoldPoint &pt = contactManifold->getContactPoint(0); #endif if ( - pt.getDistance() <= 0.0 || + pt.getDistance() < 0.0 || bodyA->was_colliding(bodyB) || bodyB->was_colliding(bodyA)) { Vector3 collisionWorldPosition; diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index cf8549030d..154bb6f01b 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/camera/camera_osx.h b/modules/camera/camera_osx.h index 84274f0bf6..9d67235839 100644 --- a/modules/camera/camera_osx.h +++ b/modules/camera/camera_osx.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_osx.mm index 02f7287d1b..626cc3f285 100644 --- a/modules/camera/camera_osx.mm +++ b/modules/camera/camera_osx.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -181,7 +181,7 @@ uint8_t *w = img_data[1].ptrw(); memcpy(w, dataCbCr, 2 * new_width * new_height); - ///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion + ///TODO OpenGL doesn't support FORMAT_RG8, need to do some form of conversion img[1].instantiate(); img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]); } diff --git a/modules/camera/camera_win.cpp b/modules/camera/camera_win.cpp index 226a642dcf..ab7cfec01a 100644 --- a/modules/camera/camera_win.cpp +++ b/modules/camera/camera_win.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/camera/camera_win.h b/modules/camera/camera_win.h index 671e7d5beb..9563326acb 100644 --- a/modules/camera/camera_win.h +++ b/modules/camera/camera_win.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/camera/register_types.cpp b/modules/camera/register_types.cpp index 0d33ff9ddc..b0b1276436 100644 --- a/modules/camera/register_types.cpp +++ b/modules/camera/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/camera/register_types.h b/modules/camera/register_types.h index 0ae9aa2c0b..5ee7aec886 100644 --- a/modules/camera/register_types.h +++ b/modules/camera/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 53694035dc..82dc4a4175 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -156,8 +156,8 @@ inline bool is_point_in_triangle(const Vector3 &p_point, const Vector3 p_vertice inline static bool is_triangle_degenerate(const Vector2 p_vertices[3], real_t p_vertex_snap2) { real_t det = p_vertices[0].x * p_vertices[1].y - p_vertices[0].x * p_vertices[2].y + - p_vertices[0].y * p_vertices[2].x - p_vertices[0].y * p_vertices[1].x + - p_vertices[1].x * p_vertices[2].y - p_vertices[1].y * p_vertices[2].x; + p_vertices[0].y * p_vertices[2].x - p_vertices[0].y * p_vertices[1].x + + p_vertices[1].x * p_vertices[2].y - p_vertices[1].y * p_vertices[2].x; return det < p_vertex_snap2; } @@ -408,7 +408,7 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b } break; - case OPERATION_SUBSTRACTION: { + case OPERATION_SUBTRACTION: { int face_count = 0; for (int i = 0; i < mesh_merge.faces.size(); i++) { @@ -933,7 +933,7 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_ merge_faces_idx.sort(); merge_faces_idx.reverse(); for (int i = 0; i < merge_faces_idx.size(); ++i) { - faces.remove(merge_faces_idx[i]); + faces.remove_at(merge_faces_idx[i]); } if (degenerate_points.size() == 0) { @@ -983,7 +983,7 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_ // If new vertex snaps to degenerate vertex, just delete this face. if (degenerate_idx == opposite_vertex_idx) { - faces.remove(face_idx); + faces.remove_at(face_idx); // Update index. --face_idx; break; @@ -999,7 +999,7 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_ right_face.vertex_idx[0] = opposite_vertex_idx; right_face.vertex_idx[1] = face.vertex_idx[face_edge_idx]; right_face.vertex_idx[2] = degenerate_idx; - faces.remove(face_idx); + faces.remove_at(face_idx); faces.insert(face_idx, right_face); faces.insert(face_idx, left_face); @@ -1070,7 +1070,7 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s // If new vertex snaps to opposite vertex, just delete this face. if (new_vertex_idx == opposite_vertex_idx) { - faces.remove(face_idx); + faces.remove_at(face_idx); // Update index. --face_idx; break; @@ -1092,7 +1092,7 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s right_face.vertex_idx[0] = opposite_vertex_idx; right_face.vertex_idx[1] = face.vertex_idx[face_edge_idx]; right_face.vertex_idx[2] = new_vertex_idx; - faces.remove(face_idx); + faces.remove_at(face_idx); faces.insert(face_idx, right_face); faces.insert(face_idx, left_face); @@ -1162,7 +1162,7 @@ int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) { // If new vertex snaps to opposite vertex, just delete this face. if (new_vertex_idx == opposite_vertex_idx) { - faces.remove(face_idx); + faces.remove_at(face_idx); // Update index. --face_idx; break; @@ -1187,7 +1187,7 @@ int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) { right_face.vertex_idx[0] = opposite_vertex_idx; right_face.vertex_idx[1] = face.vertex_idx[face_edge_idx]; right_face.vertex_idx[2] = new_vertex_idx; - faces.remove(face_idx); + faces.remove_at(face_idx); faces.insert(face_idx, right_face); faces.insert(face_idx, left_face); @@ -1222,7 +1222,7 @@ int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) { new_face.vertex_idx[2] = new_vertex_idx; faces.push_back(new_face); } - faces.remove(face_idx); + faces.remove_at(face_idx); // No need to check other faces. break; diff --git a/modules/csg/csg.h b/modules/csg/csg.h index c872860486..9ff7b13a44 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -67,7 +67,7 @@ struct CSGBrushOperation { enum Operation { OPERATION_UNION, OPERATION_INTERSECTION, - OPERATION_SUBSTRACTION, + OPERATION_SUBTRACTION, }; void merge_brushes(Operation p_operation, const CSGBrush &p_brush_a, const CSGBrush &p_brush_b, CSGBrush &r_merged_brush, float p_vertex_snap); diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index 2f8b354bb7..71891c8704 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h index 2a6ab91102..1dcee642c7 100644 --- a/modules/csg/csg_gizmos.h +++ b/modules/csg/csg_gizmos.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index e4297a593e..41b4682c84 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -192,7 +192,7 @@ CSGBrush *CSGShape3D::_get_brush() { bop.merge_brushes(CSGBrushOperation::OPERATION_INTERSECTION, *n, *nn2, *nn, snap); break; case CSGShape3D::OPERATION_SUBTRACTION: - bop.merge_brushes(CSGBrushOperation::OPERATION_SUBSTRACTION, *n, *nn2, *nn, snap); + bop.merge_brushes(CSGBrushOperation::OPERATION_SUBTRACTION, *n, *nn2, *nn, snap); break; } memdelete(n); @@ -572,10 +572,11 @@ void CSGShape3D::_validate_property(PropertyInfo &property) const { bool is_collision_prefixed = property.name.begins_with("collision_"); if ((is_collision_prefixed || property.name.begins_with("use_collision")) && is_inside_tree() && !is_root_shape()) { //hide collision if not root - property.usage = PROPERTY_USAGE_NOEDITOR; + property.usage = PROPERTY_USAGE_NO_EDITOR; } else if (is_collision_prefixed && !bool(get("use_collision"))) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; } + GeometryInstance3D::_validate_property(property); } Array CSGShape3D::get_meshes() const { @@ -1759,7 +1760,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { } int face_count = extrusions * extrusion_face_count + end_count * shape_face_count; - // Intialize variables used to create the mesh. + // Initialize variables used to create the mesh. Ref<Material> material = get_material(); Vector<Vector3> faces; diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h index c85cce776b..eed995a40e 100644 --- a/modules/csg/csg_shape.h +++ b/modules/csg/csg_shape.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/csg/doc_classes/CSGShape3D.xml b/modules/csg/doc_classes/CSGShape3D.xml index 446269f3f0..f5031064d6 100644 --- a/modules/csg/doc_classes/CSGShape3D.xml +++ b/modules/csg/doc_classes/CSGShape3D.xml @@ -59,10 +59,10 @@ <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1"> The physics layers this area is in. Collidable objects can exist in any of 32 different layers. These layers work like a tagging system, and are not visual. A collidable can use these layers to select with which objects it can collide, using the collision_mask property. - A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. + A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1"> - The physics layers this CSG shape scans for collisions. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. + The physics layers this CSG shape scans for collisions. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> <member name="operation" type="int" setter="set_operation" getter="get_operation" enum="CSGShape3D.Operation" default="0"> The operation that is performed on this shape. This is ignored for the first CSG child node as the operation is between this node and the previous child of this nodes parent. diff --git a/modules/csg/register_types.cpp b/modules/csg/register_types.cpp index a47390c2b2..f01907bef3 100644 --- a/modules/csg/register_types.cpp +++ b/modules/csg/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/csg/register_types.h b/modules/csg/register_types.h index 8747b3fade..59d84dd52a 100644 --- a/modules/csg/register_types.h +++ b/modules/csg/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index 3beca3d12a..9e0579740b 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/cvtt/image_compress_cvtt.h b/modules/cvtt/image_compress_cvtt.h index bef5653fa9..a8dbe1d929 100644 --- a/modules/cvtt/image_compress_cvtt.h +++ b/modules/cvtt/image_compress_cvtt.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/cvtt/register_types.cpp b/modules/cvtt/register_types.cpp index 055b5dc6e3..13903f700b 100644 --- a/modules/cvtt/register_types.cpp +++ b/modules/cvtt/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/cvtt/register_types.h b/modules/cvtt/register_types.h index e62e8c0e9a..9cbca75c7b 100644 --- a/modules/cvtt/register_types.h +++ b/modules/cvtt/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/dds/register_types.cpp b/modules/dds/register_types.cpp index 60282c3f36..15a93050ee 100644 --- a/modules/dds/register_types.cpp +++ b/modules/dds/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/dds/register_types.h b/modules/dds/register_types.h index b84bcd06c8..d676346e02 100644 --- a/modules/dds/register_types.h +++ b/modules/dds/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index fced61a600..c422c3bd6b 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h index cf93156423..25ded4e168 100644 --- a/modules/dds/texture_loader_dds.h +++ b/modules/dds/texture_loader_dds.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/denoise/config.py b/modules/denoise/config.py index 49a1f036ed..3aa840acb0 100644 --- a/modules/denoise/config.py +++ b/modules/denoise/config.py @@ -1,11 +1,18 @@ def can_build(env, platform): # Thirdparty dependency OpenImage Denoise includes oneDNN library - # which only supports 64-bit architectures. + # and the version we use only supports x86_64. # It's also only relevant for tools build and desktop platforms, # as doing lightmap generation and denoising on Android or HTML5 # would be a bit far-fetched. desktop_platforms = ["linuxbsd", "osx", "windows"] - return env["tools"] and platform in desktop_platforms and env["bits"] == "64" and env["arch"] != "arm64" + supported_arch = env["bits"] == "64" + if env["arch"] == "arm64": + supported_arch = False + if env["arch"].startswith("ppc"): + supported_arch = False + if env["arch"].startswith("rv"): + supported_arch = False + return env["tools"] and platform in desktop_platforms and supported_arch def configure(env): diff --git a/modules/denoise/denoise_wrapper.cpp b/modules/denoise/denoise_wrapper.cpp index e71fce5958..ef97c1a184 100644 --- a/modules/denoise/denoise_wrapper.cpp +++ b/modules/denoise/denoise_wrapper.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/denoise/denoise_wrapper.h b/modules/denoise/denoise_wrapper.h index 25e342bc93..44e61ce31d 100644 --- a/modules/denoise/denoise_wrapper.h +++ b/modules/denoise/denoise_wrapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/denoise/lightmap_denoiser.cpp b/modules/denoise/lightmap_denoiser.cpp index 71dcc1d75f..a0dbd07b10 100644 --- a/modules/denoise/lightmap_denoiser.cpp +++ b/modules/denoise/lightmap_denoiser.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/denoise/lightmap_denoiser.h b/modules/denoise/lightmap_denoiser.h index f1992a1733..452a7cae85 100644 --- a/modules/denoise/lightmap_denoiser.h +++ b/modules/denoise/lightmap_denoiser.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/denoise/register_types.cpp b/modules/denoise/register_types.cpp index 936e5f604d..07393d0f5c 100644 --- a/modules/denoise/register_types.cpp +++ b/modules/denoise/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/denoise/register_types.h b/modules/denoise/register_types.h index 516a91b134..6ce386dc5d 100644 --- a/modules/denoise/register_types.h +++ b/modules/denoise/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/enet/doc_classes/ENetConnection.xml b/modules/enet/doc_classes/ENetConnection.xml index 00469ab44c..d6b0553eba 100644 --- a/modules/enet/doc_classes/ENetConnection.xml +++ b/modules/enet/doc_classes/ENetConnection.xml @@ -50,8 +50,8 @@ <argument index="2" name="channels" type="int" default="0" /> <argument index="3" name="data" type="int" default="0" /> <description> - Initiates a connection to a foreign [code]address[/code] using the specified [code]port[/code] and allocting the requested [code]channels[/code]. Optional [code]data[/code] can be passed during connection in the form of a 32 bit integer. - Note: You must call either [method create_host] or [method create_host_bound] before calling this method. + Initiates a connection to a foreign [code]address[/code] using the specified [code]port[/code] and allocating the requested [code]channels[/code]. Optional [code]data[/code] can be passed during connection in the form of a 32 bit integer. + [b]Note:[/b] You must call either [method create_host] or [method create_host_bound] before calling this method. </description> </method> <method name="create_host"> @@ -61,7 +61,7 @@ <argument index="2" name="in_bandwidth" type="int" default="0" /> <argument index="3" name="out_bandwidth" type="int" default="0" /> <description> - Create an ENetHost that will allow up to [code]max_peers[/code] connected peers, each allocating up to [code]max_channels[/code] channels, optionally limiting bandwith to [code]in_bandwidth[/code] and [code]out_bandwidth[/code]. + Create an ENetHost that will allow up to [code]max_peers[/code] connected peers, each allocating up to [code]max_channels[/code] channels, optionally limiting bandwidth to [code]in_bandwidth[/code] and [code]out_bandwidth[/code]. </description> </method> <method name="create_host_bound"> @@ -121,7 +121,7 @@ <return type="Array" /> <description> Returns the list of peers associated with this host. - Note: This list might include some peers that are not fully connected or are still being disconnected. + [b]Note:[/b] This list might include some peers that are not fully connected or are still being disconnected. </description> </method> <method name="pop_statistic"> @@ -136,7 +136,7 @@ <argument index="0" name="refuse" type="bool" /> <description> Configures the DTLS server to automatically drop new connections. - Note: This method is only relevant after calling [method dtls_server_setup]. + [b]Note:[/b] This method is only relevant after calling [method dtls_server_setup]. </description> </method> <method name="service"> @@ -174,7 +174,7 @@ A connection request initiated by enet_host_connect has completed. The array will contain the peer which successfully connected. </constant> <constant name="EVENT_DISCONNECT" value="2" enum="EventType"> - A peer has disconnected. This event is generated on a successful completion of a disconnect initiated by [method ENetPacketPeer.peer_disconnect], if a peer has timed out, or if a connection request intialized by [method connect_to_host] has timed out. The array will contain the peer which disconnected. The data field contains user supplied data describing the disconnection, or 0, if none is available. + A peer has disconnected. This event is generated on a successful completion of a disconnect initiated by [method ENetPacketPeer.peer_disconnect], if a peer has timed out, or if a connection request initialized by [method connect_to_host] has timed out. The array will contain the peer which disconnected. The data field contains user supplied data describing the disconnection, or 0, if none is available. </constant> <constant name="EVENT_RECEIVE" value="3" enum="EventType"> A packet has been received from a peer. The array will contain the peer which sent the packet, the channel number upon which the packet was received, and the received packet. diff --git a/modules/enet/doc_classes/ENetMultiplayerPeer.xml b/modules/enet/doc_classes/ENetMultiplayerPeer.xml index f9659c092a..723149843a 100644 --- a/modules/enet/doc_classes/ENetMultiplayerPeer.xml +++ b/modules/enet/doc_classes/ENetMultiplayerPeer.xml @@ -8,7 +8,7 @@ [b]Note:[/b] ENet only uses UDP, not TCP. When forwarding the server port to make your server accessible on the public Internet, you only need to forward the server port in UDP. You can use the [UPNP] class to try to forward the server port automatically when starting the server. </description> <tutorials> - <link title="High-level multiplayer">https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link> + <link title="High-level multiplayer">$DOCS_URL/tutorials/networking/high_level_multiplayer.html</link> <link title="API documentation on the ENet website">http://enet.bespin.org/usergroup0.html</link> </tutorials> <methods> @@ -18,7 +18,7 @@ <argument index="1" name="host" type="ENetConnection" /> <description> Add a new remote peer with the given [code]peer_id[/code] connected to the given [code]host[/code]. - Note: The [code]host[/code] must have exactly one peer in the [constant ENetPacketPeer.STATE_CONNECTED] state. + [b]Note:[/b] The [code]host[/code] must have exactly one peer in the [constant ENetPacketPeer.STATE_CONNECTED] state. </description> </method> <method name="close_connection"> @@ -62,7 +62,7 @@ <return type="ENetPacketPeer" /> <argument index="0" name="id" type="int" /> <description> - Return the [ENetPacketPeer] associated to the given [code]id[/code]. + Returns the [ENetPacketPeer] associated to the given [code]id[/code]. </description> </method> <method name="set_bind_ip"> diff --git a/modules/enet/enet_connection.cpp b/modules/enet/enet_connection.cpp index e833264d6a..629974d7c7 100644 --- a/modules/enet/enet_connection.cpp +++ b/modules/enet/enet_connection.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -117,58 +117,36 @@ Ref<ENetPacketPeer> ENetConnection::connect_to_host(const String &p_address, int return out; } -ENetConnection::EventType ENetConnection::service(int p_timeout, Event &r_event) { - ERR_FAIL_COND_V_MSG(!host, EVENT_ERROR, "The ENetConnection instance isn't currently active."); - ERR_FAIL_COND_V(r_event.peer.is_valid(), EVENT_ERROR); - - // Drop peers that have already been disconnected. - // NOTE: Forcibly disconnected peers (i.e. peers disconnected via - // enet_peer_disconnect*) do not trigger DISCONNECTED events. - List<Ref<ENetPacketPeer>>::Element *E = peers.front(); - while (E) { - if (!E->get()->is_active()) { - peers.erase(E->get()); - } - E = E->next(); - } - - ENetEvent event; - int ret = enet_host_service(host, &event, p_timeout); - - if (ret < 0) { - return EVENT_ERROR; - } else if (ret == 0) { - return EVENT_NONE; - } - switch (event.type) { +ENetConnection::EventType ENetConnection::_parse_event(const ENetEvent &p_event, Event &r_event) { + switch (p_event.type) { case ENET_EVENT_TYPE_CONNECT: { - if (event.peer->data == nullptr) { - Ref<ENetPacketPeer> pp = memnew(ENetPacketPeer(event.peer)); + if (p_event.peer->data == nullptr) { + Ref<ENetPacketPeer> pp = memnew(ENetPacketPeer(p_event.peer)); peers.push_back(pp); } - r_event.peer = Ref<ENetPacketPeer>((ENetPacketPeer *)event.peer->data); - r_event.data = event.data; + r_event.peer = Ref<ENetPacketPeer>((ENetPacketPeer *)p_event.peer->data); + r_event.data = p_event.data; return EVENT_CONNECT; } break; case ENET_EVENT_TYPE_DISCONNECT: { // A peer disconnected. - if (event.peer->data != nullptr) { - Ref<ENetPacketPeer> pp = Ref<ENetPacketPeer>((ENetPacketPeer *)event.peer->data); + if (p_event.peer->data != nullptr) { + Ref<ENetPacketPeer> pp = Ref<ENetPacketPeer>((ENetPacketPeer *)p_event.peer->data); pp->_on_disconnect(); peers.erase(pp); r_event.peer = pp; - r_event.data = event.data; + r_event.data = p_event.data; return EVENT_DISCONNECT; } return EVENT_ERROR; } break; case ENET_EVENT_TYPE_RECEIVE: { // Packet reveived. - if (event.peer->data != nullptr) { - Ref<ENetPacketPeer> pp = Ref<ENetPacketPeer>((ENetPacketPeer *)event.peer->data); - r_event.peer = Ref<ENetPacketPeer>((ENetPacketPeer *)event.peer->data); - r_event.channel_id = event.channelID; - r_event.packet = event.packet; + if (p_event.peer->data != nullptr) { + Ref<ENetPacketPeer> pp = Ref<ENetPacketPeer>((ENetPacketPeer *)p_event.peer->data); + r_event.peer = Ref<ENetPacketPeer>((ENetPacketPeer *)p_event.peer->data); + r_event.channel_id = p_event.channelID; + r_event.packet = p_event.packet; return EVENT_RECEIVE; } return EVENT_ERROR; @@ -180,6 +158,44 @@ ENetConnection::EventType ENetConnection::service(int p_timeout, Event &r_event) } } +ENetConnection::EventType ENetConnection::service(int p_timeout, Event &r_event) { + ERR_FAIL_COND_V_MSG(!host, EVENT_ERROR, "The ENetConnection instance isn't currently active."); + ERR_FAIL_COND_V(r_event.peer.is_valid(), EVENT_ERROR); + + // Drop peers that have already been disconnected. + // NOTE: Forcibly disconnected peers (i.e. peers disconnected via + // enet_peer_disconnect*) do not trigger DISCONNECTED events. + List<Ref<ENetPacketPeer>>::Element *E = peers.front(); + while (E) { + if (!E->get()->is_active()) { + peers.erase(E->get()); + } + E = E->next(); + } + + ENetEvent event; + int ret = enet_host_service(host, &event, p_timeout); + + if (ret < 0) { + return EVENT_ERROR; + } else if (ret == 0) { + return EVENT_NONE; + } + return _parse_event(event, r_event); +} + +int ENetConnection::check_events(EventType &r_type, Event &r_event) { + ERR_FAIL_COND_V_MSG(!host, -1, "The ENetConnection instance isn't currently active."); + ENetEvent event; + int ret = enet_host_check_events(host, &event); + if (ret < 0) { + r_type = EVENT_ERROR; + return ret; + } + r_type = _parse_event(event, r_event); + return ret; +} + void ENetConnection::flush() { ERR_FAIL_COND_MSG(!host, "The ENetConnection instance isn't currently active."); enet_host_flush(host); diff --git a/modules/enet/enet_connection.h b/modules/enet/enet_connection.h index 0f7744953e..0c873b6c55 100644 --- a/modules/enet/enet_connection.h +++ b/modules/enet/enet_connection.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -79,6 +79,7 @@ private: ENetHost *host = nullptr; List<Ref<ENetPacketPeer>> peers; + EventType _parse_event(const ENetEvent &p_event, Event &r_event); Error _create(ENetAddress *p_address, int p_max_peers, int p_max_channels, int p_in_bandwidth, int p_out_bandwidth); Array _service(int p_timeout = 0); void _broadcast(int p_channel, PackedByteArray p_packet, int p_flags); @@ -110,6 +111,7 @@ public: void destroy(); Ref<ENetPacketPeer> connect_to_host(const String &p_address, int p_port, int p_channels, int p_data = 0); EventType service(int p_timeout, Event &r_event); + int check_events(EventType &r_type, Event &r_event); void flush(); void bandwidth_limit(int p_in_bandwidth = 0, int p_out_bandwidth = 0); void channel_limit(int p_max_channels); diff --git a/modules/enet/enet_multiplayer_peer.cpp b/modules/enet/enet_multiplayer_peer.cpp index 2cfae60ad2..cd94cc9425 100644 --- a/modules/enet/enet_multiplayer_peer.cpp +++ b/modules/enet/enet_multiplayer_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -107,39 +107,28 @@ Error ENetMultiplayerPeer::add_mesh_peer(int p_id, Ref<ENetConnection> p_host) { ERR_FAIL_COND_V_MSG(active_mode != MODE_MESH, ERR_UNCONFIGURED, "The multiplayer instance is not configured as a mesh. Call 'create_mesh' first."); List<Ref<ENetPacketPeer>> host_peers; p_host->get_peers(host_peers); - ERR_FAIL_COND_V_MSG(host_peers.size() != 1 || host_peers[0]->get_state() != ENetPacketPeer::STATE_CONNECTED, ERR_INVALID_PARAMETER, "The provided host must have excatly one peer in the connected state."); + ERR_FAIL_COND_V_MSG(host_peers.size() != 1 || host_peers[0]->get_state() != ENetPacketPeer::STATE_CONNECTED, ERR_INVALID_PARAMETER, "The provided host must have exactly one peer in the connected state."); hosts[p_id] = p_host; peers[p_id] = host_peers[0]; emit_signal(SNAME("peer_connected"), p_id); return OK; } -bool ENetMultiplayerPeer::_poll_server() { - for (const KeyValue<int, Ref<ENetPacketPeer>> &E : peers) { - if (!(E.value->is_active())) { - emit_signal(SNAME("peer_disconnected"), E.value->get_meta(SNAME("_net_id"))); - peers.erase(E.key); - } - } - ENetConnection::Event event; - ENetConnection::EventType ret = hosts[0]->service(0, event); - if (ret == ENetConnection::EVENT_ERROR) { - return true; - } - switch (ret) { +bool ENetMultiplayerPeer::_parse_server_event(ENetConnection::EventType p_type, ENetConnection::Event &p_event) { + switch (p_type) { case ENetConnection::EVENT_CONNECT: { if (is_refusing_new_connections()) { - event.peer->reset(); + p_event.peer->reset(); return false; } // Client joined with invalid ID, probably trying to exploit us. - if (event.data < 2 || peers.has((int)event.data)) { - event.peer->reset(); + if (p_event.data < 2 || peers.has((int)p_event.data)) { + p_event.peer->reset(); return false; } - int id = event.data; - event.peer->set_meta(SNAME("_net_id"), id); - peers[id] = event.peer; + int id = p_event.data; + p_event.peer->set_meta(SNAME("_net_id"), id); + peers[id] = p_event.peer; emit_signal(SNAME("peer_connected"), id); if (server_relay) { @@ -148,7 +137,7 @@ bool ENetMultiplayerPeer::_poll_server() { return false; } case ENetConnection::EVENT_DISCONNECT: { - int id = event.peer->get_meta(SNAME("_net_id")); + int id = p_event.peer->get_meta(SNAME("_net_id")); if (!peers.has(id)) { // Never fully connected. return false; @@ -162,28 +151,28 @@ bool ENetMultiplayerPeer::_poll_server() { return false; } case ENetConnection::EVENT_RECEIVE: { - if (event.channel_id == SYSCH_CONFIG) { - _destroy_unused(event.packet); + if (p_event.channel_id == SYSCH_CONFIG) { + _destroy_unused(p_event.packet); ERR_FAIL_V_MSG(false, "Only server can send config messages"); } else { - if (event.packet->dataLength < 8) { - _destroy_unused(event.packet); + if (p_event.packet->dataLength < 8) { + _destroy_unused(p_event.packet); ERR_FAIL_V_MSG(false, "Invalid packet size"); } - uint32_t source = decode_uint32(&event.packet->data[0]); - int target = decode_uint32(&event.packet->data[4]); + uint32_t source = decode_uint32(&p_event.packet->data[0]); + int target = decode_uint32(&p_event.packet->data[4]); - uint32_t id = event.peer->get_meta(SNAME("_net_id")); + uint32_t id = p_event.peer->get_meta(SNAME("_net_id")); // Someone is cheating and trying to fake the source! if (source != id) { - _destroy_unused(event.packet); + _destroy_unused(p_event.packet); ERR_FAIL_V_MSG(false, "Someone is cheating and trying to fake the source!"); } Packet packet; - packet.packet = event.packet; - packet.channel = event.channel_id; + packet.packet = p_event.packet; + packet.channel = p_event.channel_id; packet.from = id; // Even if relaying is disabled, these targets are valid as incoming packets. @@ -194,9 +183,9 @@ bool ENetMultiplayerPeer::_poll_server() { if (server_relay && target != 1) { packet.packet->referenceCount++; - _relay(source, target, event.channel_id, event.packet); + _relay(source, target, p_event.channel_id, p_event.packet); packet.packet->referenceCount--; - _destroy_unused(event.packet); + _destroy_unused(p_event.packet); } // Destroy packet later } @@ -207,23 +196,8 @@ bool ENetMultiplayerPeer::_poll_server() { } } -bool ENetMultiplayerPeer::_poll_client() { - if (peers.has(1) && !peers[1]->is_active()) { - if (connection_status == CONNECTION_CONNECTED) { - // Client just disconnected from server. - emit_signal(SNAME("server_disconnected")); - } else { - emit_signal(SNAME("connection_failed")); - } - close_connection(); - return true; - } - ENetConnection::Event event; - ENetConnection::EventType ret = hosts[0]->service(0, event); - if (ret == ENetConnection::EVENT_ERROR) { - return true; - } - switch (ret) { +bool ENetMultiplayerPeer::_parse_client_event(ENetConnection::EventType p_type, ENetConnection::Event &p_event) { + switch (p_type) { case ENetConnection::EVENT_CONNECT: { connection_status = CONNECTION_CONNECTED; emit_signal(SNAME("peer_connected"), 1); @@ -241,15 +215,15 @@ bool ENetMultiplayerPeer::_poll_client() { return true; } case ENetConnection::EVENT_RECEIVE: { - if (event.channel_id == SYSCH_CONFIG) { + if (p_event.channel_id == SYSCH_CONFIG) { // Config message - if (event.packet->dataLength != 8) { - _destroy_unused(event.packet); + if (p_event.packet->dataLength != 8) { + _destroy_unused(p_event.packet); ERR_FAIL_V(false); } - int msg = decode_uint32(&event.packet->data[0]); - int id = decode_uint32(&event.packet->data[4]); + int msg = decode_uint32(&p_event.packet->data[0]); + int id = decode_uint32(&p_event.packet->data[4]); switch (msg) { case SYSMSG_ADD_PEER: { @@ -262,18 +236,18 @@ bool ENetMultiplayerPeer::_poll_client() { emit_signal(SNAME("peer_disconnected"), id); } break; } - _destroy_unused(event.packet); + _destroy_unused(p_event.packet); } else { - if (event.packet->dataLength < 8) { - _destroy_unused(event.packet); + if (p_event.packet->dataLength < 8) { + _destroy_unused(p_event.packet); ERR_FAIL_V_MSG(false, "Invalid packet size"); } - uint32_t source = decode_uint32(&event.packet->data[0]); + uint32_t source = decode_uint32(&p_event.packet->data[0]); Packet packet; - packet.packet = event.packet; + packet.packet = p_event.packet; packet.from = source; - packet.channel = event.channel_id; + packet.channel = p_event.channel_id; packet.packet->referenceCount++; incoming_packets.push_back(packet); @@ -286,61 +260,37 @@ bool ENetMultiplayerPeer::_poll_client() { } } -bool ENetMultiplayerPeer::_poll_mesh() { - for (const KeyValue<int, Ref<ENetPacketPeer>> &E : peers) { - if (!(E.value->is_active())) { - emit_signal(SNAME("peer_disconnected"), E.key); - peers.erase(E.key); - if (hosts.has(E.key)) { - hosts.erase(E.key); +bool ENetMultiplayerPeer::_parse_mesh_event(ENetConnection::EventType p_type, ENetConnection::Event &p_event, int p_peer_id) { + switch (p_type) { + case ENetConnection::EVENT_CONNECT: + p_event.peer->reset(); + return false; + case ENetConnection::EVENT_DISCONNECT: + if (peers.has(p_peer_id)) { + emit_signal(SNAME("peer_disconnected"), p_peer_id); + peers.erase(p_peer_id); } - } - } - bool should_stop = true; - for (KeyValue<int, Ref<ENetConnection>> &E : hosts) { - ENetConnection::Event event; - ENetConnection::EventType ret = E.value->service(0, event); - if (ret == ENetConnection::EVENT_ERROR) { - if (peers.has(E.key)) { - emit_signal(SNAME("peer_disconnected"), E.key); - peers.erase(E.key); + hosts.erase(p_peer_id); + return true; + case ENetConnection::EVENT_RECEIVE: { + if (p_event.packet->dataLength < 8) { + _destroy_unused(p_event.packet); + ERR_FAIL_V_MSG(false, "Invalid packet size"); } - hosts.erase(E.key); - continue; - } - switch (ret) { - case ENetConnection::EVENT_CONNECT: - should_stop = false; - event.peer->reset(); - break; - case ENetConnection::EVENT_DISCONNECT: - should_stop = false; - if (peers.has(E.key)) { - emit_signal(SNAME("peer_disconnected"), E.key); - peers.erase(E.key); - } - hosts.erase(E.key); - break; - case ENetConnection::EVENT_RECEIVE: { - should_stop = false; - if (event.packet->dataLength < 8) { - _destroy_unused(event.packet); - ERR_CONTINUE_MSG(true, "Invalid packet size"); - } - Packet packet; - packet.packet = event.packet; - packet.from = E.key; - packet.channel = event.channel_id; + Packet packet; + packet.packet = p_event.packet; + packet.from = p_peer_id; + packet.channel = p_event.channel_id; - packet.packet->referenceCount++; - incoming_packets.push_back(packet); - } break; - default: - break; // Nothing to do - } + packet.packet->referenceCount++; + incoming_packets.push_back(packet); + return false; + } break; + default: + // Nothing to do + return true; } - return should_stop; } void ENetMultiplayerPeer::poll() { @@ -348,26 +298,77 @@ void ENetMultiplayerPeer::poll() { _pop_current_packet(); - while (true) { - switch (active_mode) { - case MODE_CLIENT: - if (_poll_client()) { - return; + switch (active_mode) { + case MODE_CLIENT: { + if (peers.has(1) && !peers[1]->is_active()) { + if (connection_status == CONNECTION_CONNECTED) { + // Client just disconnected from server. + emit_signal(SNAME("server_disconnected")); + } else { + emit_signal(SNAME("connection_failed")); } - break; - case MODE_SERVER: - if (_poll_server()) { + close_connection(); + return; + } + ENetConnection::Event event; + ENetConnection::EventType ret = hosts[0]->service(0, event); + if (ret == ENetConnection::EVENT_ERROR) { + return; + } + do { + if (_parse_client_event(ret, event)) { return; } - break; - case MODE_MESH: - if (_poll_mesh()) { - return; + } while (hosts[0]->check_events(ret, event) > 0); + } break; + case MODE_SERVER: { + for (const KeyValue<int, Ref<ENetPacketPeer>> &E : peers) { + if (!(E.value->is_active())) { + emit_signal(SNAME("peer_disconnected"), E.value->get_meta(SNAME("_net_id"))); + peers.erase(E.key); } - break; - default: + } + ENetConnection::Event event; + ENetConnection::EventType ret = hosts[0]->service(0, event); + if (ret == ENetConnection::EVENT_ERROR) { return; - } + } + do { + if (_parse_server_event(ret, event)) { + return; + } + } while (hosts[0]->check_events(ret, event) > 0); + } break; + case MODE_MESH: { + for (const KeyValue<int, Ref<ENetPacketPeer>> &E : peers) { + if (!(E.value->is_active())) { + emit_signal(SNAME("peer_disconnected"), E.key); + peers.erase(E.key); + if (hosts.has(E.key)) { + hosts.erase(E.key); + } + } + } + for (KeyValue<int, Ref<ENetConnection>> &E : hosts) { + ENetConnection::Event event; + ENetConnection::EventType ret = E.value->service(0, event); + if (ret == ENetConnection::EVENT_ERROR) { + if (peers.has(E.key)) { + emit_signal(SNAME("peer_disconnected"), E.key); + peers.erase(E.key); + } + hosts.erase(E.key); + continue; + } + do { + if (_parse_mesh_event(ret, event, E.key)) { + break; // Keep polling the others. + } + } while (E.value->check_events(ret, event) > 0); + } + } break; + default: + return; } } @@ -441,11 +442,11 @@ Error ENetMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size } else { switch (get_transfer_mode()) { case Multiplayer::TRANSFER_MODE_UNRELIABLE: { - packet_flags = ENET_PACKET_FLAG_UNSEQUENCED; + packet_flags = ENET_PACKET_FLAG_UNSEQUENCED | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT; channel = SYSCH_UNRELIABLE; } break; case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: { - packet_flags = 0; + packet_flags = ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT; channel = SYSCH_UNRELIABLE; } break; case Multiplayer::TRANSFER_MODE_RELIABLE: { @@ -455,6 +456,12 @@ Error ENetMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size } } +#ifdef DEBUG_ENABLED + if ((packet_flags & ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT) && p_buffer_size + 8 > ENET_HOST_DEFAULT_MTU) { + WARN_PRINT_ONCE(vformat("Sending %d bytes unrealiably which is above the MTU (%d), this will result in higher packet loss", p_buffer_size + 8, ENET_HOST_DEFAULT_MTU)); + } +#endif + ENetPacket *packet = enet_packet_create(nullptr, p_buffer_size + 8, packet_flags); encode_uint32(unique_id, &packet->data[0]); // Source ID encode_uint32(target_peer, &packet->data[4]); // Dest ID diff --git a/modules/enet/enet_multiplayer_peer.h b/modules/enet/enet_multiplayer_peer.h index 7a60e2359c..e7b61169fb 100644 --- a/modules/enet/enet_multiplayer_peer.h +++ b/modules/enet/enet_multiplayer_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -84,9 +84,9 @@ private: Packet current_packet; void _pop_current_packet(); - bool _poll_server(); - bool _poll_client(); - bool _poll_mesh(); + bool _parse_server_event(ENetConnection::EventType p_event_type, ENetConnection::Event &p_event); + bool _parse_client_event(ENetConnection::EventType p_event_type, ENetConnection::Event &p_event); + bool _parse_mesh_event(ENetConnection::EventType p_event_type, ENetConnection::Event &p_event, int p_peer_id); void _relay(int p_from, int p_to, enet_uint8 p_channel, ENetPacket *p_packet); void _notify_peers(int p_id, bool p_connected); void _destroy_unused(ENetPacket *p_packet); @@ -103,7 +103,7 @@ public: virtual void poll() override; virtual bool is_server() const override; - // Overriden so we can instrument the DTLSServer when needed. + // Overridden so we can instrument the DTLSServer when needed. virtual void set_refuse_new_connections(bool p_enabled) override; virtual ConnectionStatus get_connection_status() const override; diff --git a/modules/enet/enet_packet_peer.cpp b/modules/enet/enet_packet_peer.cpp index d7d2ec9ebe..62c0550edb 100644 --- a/modules/enet/enet_packet_peer.cpp +++ b/modules/enet/enet_packet_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/enet/enet_packet_peer.h b/modules/enet/enet_packet_peer.h index 9af004de2f..eaf70a276a 100644 --- a/modules/enet/enet_packet_peer.h +++ b/modules/enet/enet_packet_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/enet/register_types.cpp b/modules/enet/register_types.cpp index 7570f5b643..36a4e6e6e7 100644 --- a/modules/enet/register_types.cpp +++ b/modules/enet/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/enet/register_types.h b/modules/enet/register_types.h index 75f4cba61b..a94ecccc61 100644 --- a/modules/enet/register_types.h +++ b/modules/enet/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/etcpak/image_compress_etcpak.cpp b/modules/etcpak/image_compress_etcpak.cpp index aff7538fb6..c79d449d41 100644 --- a/modules/etcpak/image_compress_etcpak.cpp +++ b/modules/etcpak/image_compress_etcpak.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/etcpak/image_compress_etcpak.h b/modules/etcpak/image_compress_etcpak.h index ccf157fada..691528c235 100644 --- a/modules/etcpak/image_compress_etcpak.h +++ b/modules/etcpak/image_compress_etcpak.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/etcpak/register_types.cpp b/modules/etcpak/register_types.cpp index d57d2f747a..e835004406 100644 --- a/modules/etcpak/register_types.cpp +++ b/modules/etcpak/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/etcpak/register_types.h b/modules/etcpak/register_types.h index a9e10a4aae..30ce974d08 100644 --- a/modules/etcpak/register_types.h +++ b/modules/etcpak/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/fbx_anim_container.h b/modules/fbx/data/fbx_anim_container.h index 8c25d65871..6559add858 100644 --- a/modules/fbx/data/fbx_anim_container.h +++ b/modules/fbx/data/fbx_anim_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/fbx_bone.cpp b/modules/fbx/data/fbx_bone.cpp index 38dada33af..72aba20fd4 100644 --- a/modules/fbx/data/fbx_bone.cpp +++ b/modules/fbx/data/fbx_bone.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/fbx_bone.h b/modules/fbx/data/fbx_bone.h index 83918ad1e2..6c8f7f7cae 100644 --- a/modules/fbx/data/fbx_bone.h +++ b/modules/fbx/data/fbx_bone.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/fbx_material.cpp b/modules/fbx/data/fbx_material.cpp index 86baec4244..bc638244d8 100644 --- a/modules/fbx/data/fbx_material.cpp +++ b/modules/fbx/data/fbx_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -60,7 +60,7 @@ String find_file(const String &p_base, const String &p_file_to_find) { dir.list_dir_begin(); String n = dir.get_next(); - while (n != String()) { + while (!n.is_empty()) { if (n == "." || n == "..") { n = dir.get_next(); continue; @@ -68,7 +68,7 @@ String find_file(const String &p_base, const String &p_file_to_find) { if (dir.current_is_dir()) { // Don't use `path_to` or the returned path will be wrong. const String f = find_file(p_base + "/" + n, p_file_to_find); - if (f != "") { + if (!f.is_empty()) { return f; } } else if (n == p_file_to_find) { @@ -119,7 +119,7 @@ String FBXMaterial::find_texture_path_by_filename(const String p_filename, const dir.open("res://"); dir.list_dir_begin(); String n = dir.get_next(); - while (n != String()) { + while (!n.is_empty()) { if (n == "." || n == "..") { n = dir.get_next(); continue; @@ -136,7 +136,7 @@ String FBXMaterial::find_texture_path_by_filename(const String p_filename, const lower_n.find("picture") >= 0) { // Don't use `path_to` or the returned path will be wrong. const String f = find_file(String("res://") + n, p_filename); - if (f != "") { + if (!f.is_empty()) { return f; } } diff --git a/modules/fbx/data/fbx_material.h b/modules/fbx/data/fbx_material.h index 5fd4d9212b..e20b43561b 100644 --- a/modules/fbx/data/fbx_material.h +++ b/modules/fbx/data/fbx_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp index 7343bf87af..2b29f4d97e 100644 --- a/modules/fbx/data/fbx_mesh_data.cpp +++ b/modules/fbx/data/fbx_mesh_data.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -167,7 +167,7 @@ ImporterMeshInstance3D *FBXMeshData::create_fbx_mesh(const ImportState &state, c sanitize_vertex_weights(state); - // Re organize polygon vertices to to correctly take into account strange + // Reorganize polygon vertices to correctly take into account strange // UVs. reorganize_vertices( polygon_indices, @@ -357,7 +357,6 @@ ImporterMeshInstance3D *FBXMeshData::create_fbx_mesh(const ImportState &state, c mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); // Add surfaces. - int in_mesh_surface_id = 0; for (const SurfaceId *surface_id = surfaces.next(nullptr); surface_id != nullptr; surface_id = surfaces.next(surface_id)) { SurfaceData *surface = surfaces.getptr(*surface_id); @@ -377,8 +376,6 @@ ImporterMeshInstance3D *FBXMeshData::create_fbx_mesh(const ImportState &state, c } else { mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES, mesh_array, blend_shapes); } - - in_mesh_surface_id += 1; } ImporterMeshInstance3D *godot_mesh = memnew(ImporterMeshInstance3D); diff --git a/modules/fbx/data/fbx_mesh_data.h b/modules/fbx/data/fbx_mesh_data.h index eec7f38cd6..358d0c2cb6 100644 --- a/modules/fbx/data/fbx_mesh_data.h +++ b/modules/fbx/data/fbx_mesh_data.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/fbx_node.h b/modules/fbx/data/fbx_node.h index 75461e397d..7a4139dcdf 100644 --- a/modules/fbx/data/fbx_node.h +++ b/modules/fbx/data/fbx_node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/fbx_skeleton.cpp b/modules/fbx/data/fbx_skeleton.cpp index 3dc163964c..0225df16af 100644 --- a/modules/fbx/data/fbx_skeleton.cpp +++ b/modules/fbx/data/fbx_skeleton.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -104,6 +104,13 @@ void FBXSkeleton::init_skeleton(const ImportState &state) { print_verbose("working on bone: " + itos(bone_index) + " bone name:" + bone->bone_name); skeleton->set_bone_rest(bone->godot_bone_id, get_unscaled_transform(bone->node->pivot_transform->LocalTransform, state.scale)); + { + Transform3D base_xform = bone->node->pivot_transform->LocalTransform; + + skeleton->set_bone_pose_position(bone_index, base_xform.origin); + skeleton->set_bone_pose_rotation(bone_index, base_xform.basis.get_rotation_quaternion()); + skeleton->set_bone_pose_scale(bone_index, base_xform.basis.get_scale()); + } // lookup parent ID if (bone->valid_parent && state.fbx_bone_map.has(bone->parent_bone_id)) { diff --git a/modules/fbx/data/fbx_skeleton.h b/modules/fbx/data/fbx_skeleton.h index b6103df949..e615d0f5e3 100644 --- a/modules/fbx/data/fbx_skeleton.h +++ b/modules/fbx/data/fbx_skeleton.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/import_state.h b/modules/fbx/data/import_state.h index 9ba60eaacf..eff11e3bb8 100644 --- a/modules/fbx/data/import_state.h +++ b/modules/fbx/data/import_state.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/model_abstraction.h b/modules/fbx/data/model_abstraction.h index 528960ab49..4c3f81b163 100644 --- a/modules/fbx/data/model_abstraction.h +++ b/modules/fbx/data/model_abstraction.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/pivot_transform.cpp b/modules/fbx/data/pivot_transform.cpp index 4cf42257a4..9457b19a7f 100644 --- a/modules/fbx/data/pivot_transform.cpp +++ b/modules/fbx/data/pivot_transform.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/data/pivot_transform.h b/modules/fbx/data/pivot_transform.h index 099b268075..df97c8db57 100644 --- a/modules/fbx/data/pivot_transform.h +++ b/modules/fbx/data/pivot_transform.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/doc_classes/EditorSceneImporterFBX.xml b/modules/fbx/doc_classes/EditorSceneImporterFBX.xml deleted file mode 100644 index 6f83871772..0000000000 --- a/modules/fbx/doc_classes/EditorSceneImporterFBX.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorSceneImporterFBX" inherits="EditorSceneImporter" version="4.0"> - <brief_description> - FBX 3D asset importer. - </brief_description> - <description> - This is an FBX 3D asset importer with full support for most FBX features. - If exporting a FBX scene from Autodesk Maya, use these FBX export settings: - [codeblock] - - Smoothing Groups - - Smooth Mesh - - Triangluate (for meshes with blend shapes) - - Bake Animation - - Resample All - - Deformed Models - - Skins - - Blend Shapes - - Curve Filters - - Constant Key Reducer - - Auto Tangents Only - - *Do not check* Constraints (as it will break the file) - - Can check Embed Media (embeds textures into the exported FBX file) - - Note that when importing embedded media, the texture and mesh will be a single immutable file. - - You will have to re-export then re-import the FBX if the texture has changed. - - Units: Centimeters - - Up Axis: Y - - Binary format in FBX 2017 - [/codeblock] - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index e4de204cf1..4cca907bf2 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -56,7 +56,7 @@ #include <string> -void EditorSceneImporterFBX::get_extensions(List<String> *r_extensions) const { +void EditorSceneFormatImporterFBX::get_extensions(List<String> *r_extensions) const { // register FBX as the one and only format for FBX importing const String import_setting_string = "filesystem/import/fbx/"; const String fbx_str = "fbx"; @@ -65,7 +65,7 @@ void EditorSceneImporterFBX::get_extensions(List<String> *r_extensions) const { _register_project_setting_import(fbx_str, import_setting_string, exts, r_extensions, true); } -void EditorSceneImporterFBX::_register_project_setting_import(const String generic, +void EditorSceneFormatImporterFBX::_register_project_setting_import(const String generic, const String import_setting_string, const Vector<String> &exts, List<String> *r_extensions, @@ -79,11 +79,11 @@ void EditorSceneImporterFBX::_register_project_setting_import(const String gener } } -uint32_t EditorSceneImporterFBX::get_import_flags() const { +uint32_t EditorSceneFormatImporterFBX::get_import_flags() const { return IMPORT_SCENE; } -Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, +Node3D *EditorSceneFormatImporterFBX::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { // done for performance when re-importing lots of files when testing importer in verbose only! if (OS::get_singleton()->is_stdout_verbose()) { @@ -232,7 +232,7 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl } template <class T> -struct EditorSceneImporterAssetImportInterpolate { +struct EditorSceneFormatImporterAssetImportInterpolate { T lerp(const T &a, const T &b, float c) const { return a + (b - a) * c; } @@ -258,7 +258,7 @@ struct EditorSceneImporterAssetImportInterpolate { //thank you for existing, partial specialization template <> -struct EditorSceneImporterAssetImportInterpolate<Quaternion> { +struct EditorSceneFormatImporterAssetImportInterpolate<Quaternion> { Quaternion lerp(const Quaternion &a, const Quaternion &b, float c) const { ERR_FAIL_COND_V(!a.is_normalized(), Quaternion()); ERR_FAIL_COND_V(!b.is_normalized(), Quaternion()); @@ -282,7 +282,7 @@ struct EditorSceneImporterAssetImportInterpolate<Quaternion> { }; template <class T> -T EditorSceneImporterFBX::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, +T EditorSceneFormatImporterFBX::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp) { //could use binary search, worth it? int idx = -1; @@ -293,7 +293,7 @@ T EditorSceneImporterFBX::_interpolate_track(const Vector<float> &p_times, const idx++; } - EditorSceneImporterAssetImportInterpolate<T> interp; + EditorSceneFormatImporterAssetImportInterpolate<T> interp; switch (p_interp) { case AssetImportAnimation::INTERP_LINEAR: { @@ -352,7 +352,7 @@ T EditorSceneImporterFBX::_interpolate_track(const Vector<float> &p_times, const ERR_FAIL_V(p_values[0]); } -Node3D *EditorSceneImporterFBX::_generate_scene( +Node3D *EditorSceneFormatImporterFBX::_generate_scene( const String &p_path, const FBXDocParser::Document *p_document, const uint32_t p_flags, @@ -843,7 +843,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( if (state.animation_player == nullptr) { print_verbose("Creating animation player"); state.animation_player = memnew(AnimationPlayer); - state.root->add_child(state.animation_player); + state.root->add_child(state.animation_player, true); state.animation_player->set_owner(state.root_owner); } @@ -1011,9 +1011,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // track count is 5. // next track id is 5. const uint64_t target_id = track.key; - int track_idx = animation->add_track(Animation::TYPE_TRANSFORM3D); - // animation->track_set_path(track_idx, node_path); Ref<FBXBone> bone; // note we must not run the below code if the entry doesn't exist, it will create dummy entries which is very bad. @@ -1037,22 +1035,21 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // if this is a skeleton mapped track we can just set the path for the track. // todo: implement node paths here at some + NodePath track_path; if (state.fbx_bone_map.size() > 0 && state.fbx_bone_map.has(target_id)) { if (bone->fbx_skeleton.is_valid() && bone.is_valid()) { Ref<FBXSkeleton> fbx_skeleton = bone->fbx_skeleton; String bone_path = state.root->get_path_to(fbx_skeleton->skeleton); bone_path += ":" + fbx_skeleton->skeleton->get_bone_name(bone->godot_bone_id); print_verbose("[doc] track bone path: " + bone_path); - NodePath path = bone_path; - animation->track_set_path(track_idx, path); + track_path = bone_path; } } else if (state.fbx_target_map.has(target_id)) { //print_verbose("[doc] we have a valid target for a node animation"); Ref<FBXNode> target_node = state.fbx_target_map[target_id]; if (target_node.is_valid() && target_node->godot_node != nullptr) { String node_path = state.root->get_path_to(target_node->godot_node); - NodePath path = node_path; - animation->track_set_path(track_idx, path); + track_path = node_path; //print_verbose("[doc] node animation path: " + node_path); } } else { @@ -1186,6 +1183,30 @@ Node3D *EditorSceneImporterFBX::_generate_scene( const Vector3 def_scale = scale_keys.has_default ? scale_keys.default_value : bone_rest.basis.get_scale(); print_verbose("track defaults: p(" + def_pos + ") s(" + def_scale + ") r(" + def_rot + ")"); + int position_idx = -1; + if (pos_values.size()) { + position_idx = animation->get_track_count(); + animation->add_track(Animation::TYPE_POSITION_3D); + animation->track_set_path(position_idx, track_path); + animation->track_set_imported(position_idx, true); + } + + int rotation_idx = -1; + if (pos_values.size()) { + rotation_idx = animation->get_track_count(); + animation->add_track(Animation::TYPE_ROTATION_3D); + animation->track_set_path(rotation_idx, track_path); + animation->track_set_imported(rotation_idx, true); + } + + int scale_idx = -1; + if (pos_values.size()) { + scale_idx = animation->get_track_count(); + animation->add_track(Animation::TYPE_SCALE_3D); + animation->track_set_path(scale_idx, track_path); + animation->track_set_imported(scale_idx, true); + } + while (true) { Vector3 pos = def_pos; Quaternion rot = def_rot; @@ -1206,21 +1227,15 @@ Node3D *EditorSceneImporterFBX::_generate_scene( AssetImportAnimation::INTERP_LINEAR); } - // node animations must also include pivots - if (skeleton_bone >= 0) { - Transform3D xform = Transform3D(); - xform.basis.set_quaternion_scale(rot, scale); - xform.origin = pos; - const Transform3D t = bone_rest.affine_inverse() * xform; - - // populate this again - rot = t.basis.get_rotation_quaternion(); - rot.normalize(); - scale = t.basis.get_scale(); - pos = t.origin; + if (position_idx >= 0) { + animation->position_track_insert_key(position_idx, time, pos); + } + if (rotation_idx >= 0) { + animation->rotation_track_insert_key(rotation_idx, time, rot); + } + if (scale_idx >= 0) { + animation->scale_track_insert_key(scale_idx, time, scale); } - - animation->transform_track_insert_key(track_idx, time, pos, rot, scale); if (last) { break; @@ -1279,7 +1294,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( return scene_root; } -void EditorSceneImporterFBX::BuildDocumentBones(Ref<FBXBone> p_parent_bone, +void EditorSceneFormatImporterFBX::BuildDocumentBones(Ref<FBXBone> p_parent_bone, ImportState &state, const FBXDocParser::Document *p_doc, uint64_t p_id) { const std::vector<const FBXDocParser::Connection *> &conns = p_doc->GetConnectionsByDestinationSequenced(p_id, "Model"); @@ -1368,7 +1383,7 @@ void EditorSceneImporterFBX::BuildDocumentBones(Ref<FBXBone> p_parent_bone, } } -void EditorSceneImporterFBX::BuildDocumentNodes( +void EditorSceneFormatImporterFBX::BuildDocumentNodes( Ref<PivotTransform> parent_transform, ImportState &state, const FBXDocParser::Document *p_doc, @@ -1453,3 +1468,8 @@ void EditorSceneImporterFBX::BuildDocumentNodes( } } } +Ref<Animation> EditorSceneFormatImporterFBX::import_animation(const String &p_path, + uint32_t p_flags, const Map<StringName, Variant> &p_options, + int p_bake_fps) { + return Ref<Animation>(); +} diff --git a/modules/fbx/editor_scene_importer_fbx.h b/modules/fbx/editor_scene_importer_fbx.h index 4a3b78480b..eebcb86409 100644 --- a/modules/fbx/editor_scene_importer_fbx.h +++ b/modules/fbx/editor_scene_importer_fbx.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -57,9 +57,9 @@ #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL -class EditorSceneImporterFBX : public EditorSceneImporter { +class EditorSceneFormatImporterFBX : public EditorSceneFormatImporter { private: - GDCLASS(EditorSceneImporterFBX, EditorSceneImporter); + GDCLASS(EditorSceneFormatImporterFBX, EditorSceneFormatImporter); struct AssetImportAnimation { enum Interpolation { @@ -122,12 +122,15 @@ private: void _register_project_setting_import(const String generic, const String import_setting_string, const Vector<String> &exts, List<String> *r_extensions, const bool p_enabled) const; public: - EditorSceneImporterFBX() {} - ~EditorSceneImporterFBX() {} + EditorSceneFormatImporterFBX() {} + ~EditorSceneFormatImporterFBX() {} virtual void get_extensions(List<String> *r_extensions) const override; virtual uint32_t get_import_flags() const override; - virtual Node3D *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; + virtual Node3D *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; + virtual Ref<Animation> import_animation(const String &p_path, + uint32_t p_flags, const Map<StringName, Variant> &p_options, + int p_bake_fps) override; }; #endif // TOOLS_ENABLED diff --git a/modules/fbx/fbx_parser/ByteSwapper.h b/modules/fbx/fbx_parser/ByteSwapper.h index 08d38147d5..21c5557001 100644 --- a/modules/fbx/fbx_parser/ByteSwapper.h +++ b/modules/fbx/fbx_parser/ByteSwapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXAnimation.cpp b/modules/fbx/fbx_parser/FBXAnimation.cpp index 0fbff035fd..8c43aac8f6 100644 --- a/modules/fbx/fbx_parser/FBXAnimation.cpp +++ b/modules/fbx/fbx_parser/FBXAnimation.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp b/modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp index 1eee10b251..f982e0ca4d 100644 --- a/modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp +++ b/modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -82,46 +82,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> namespace FBXDocParser { -//enum Flag -//{ -// e_unknown_0 = 1 << 0, -// e_unknown_1 = 1 << 1, -// e_unknown_2 = 1 << 2, -// e_unknown_3 = 1 << 3, -// e_unknown_4 = 1 << 4, -// e_unknown_5 = 1 << 5, -// e_unknown_6 = 1 << 6, -// e_unknown_7 = 1 << 7, -// e_unknown_8 = 1 << 8, -// e_unknown_9 = 1 << 9, -// e_unknown_10 = 1 << 10, -// e_unknown_11 = 1 << 11, -// e_unknown_12 = 1 << 12, -// e_unknown_13 = 1 << 13, -// e_unknown_14 = 1 << 14, -// e_unknown_15 = 1 << 15, -// e_unknown_16 = 1 << 16, -// e_unknown_17 = 1 << 17, -// e_unknown_18 = 1 << 18, -// e_unknown_19 = 1 << 19, -// e_unknown_20 = 1 << 20, -// e_unknown_21 = 1 << 21, -// e_unknown_22 = 1 << 22, -// e_unknown_23 = 1 << 23, -// e_flag_field_size_64_bit = 1 << 24, // Not sure what is -// e_unknown_25 = 1 << 25, -// e_unknown_26 = 1 << 26, -// e_unknown_27 = 1 << 27, -// e_unknown_28 = 1 << 28, -// e_unknown_29 = 1 << 29, -// e_unknown_30 = 1 << 30, -// e_unknown_31 = 1 << 31 -//}; -// -//bool check_flag(uint32_t flags, Flag to_check) -//{ -// return (flags & to_check) != 0; -//} // ------------------------------------------------------------------------------------------------ Token::Token(const char *sbegin, const char *send, TokenType type, size_t offset) : sbegin(sbegin), @@ -458,12 +418,6 @@ void TokenizeBinary(TokenList &output_tokens, const char *input, size_t length, //TokenizeError("file is too short",0); } - //uint32_t offset = 0x15; - /* const char* cursor = input + 0x15; - const uint32_t flags = ReadWord(input, cursor, input + length); - const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused - const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused*/ - if (strncmp(input, "Kaydara FBX Binary", 18)) { TokenizeError("magic bytes not found", 0); } diff --git a/modules/fbx/fbx_parser/FBXCommon.h b/modules/fbx/fbx_parser/FBXCommon.h index 641d6d351e..d0d4790ba8 100644 --- a/modules/fbx/fbx_parser/FBXCommon.h +++ b/modules/fbx/fbx_parser/FBXCommon.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -70,8 +70,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file FBXCommon.h -* Some useful constants and enums for dealing with FBX files. -*/ + * Some useful constants and enums for dealing with FBX files. + */ #ifndef FBX_COMMON_H #define FBX_COMMON_H diff --git a/modules/fbx/fbx_parser/FBXDeformer.cpp b/modules/fbx/fbx_parser/FBXDeformer.cpp index 4220ba62a7..b888afd90e 100644 --- a/modules/fbx/fbx_parser/FBXDeformer.cpp +++ b/modules/fbx/fbx_parser/FBXDeformer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXDocument.cpp b/modules/fbx/fbx_parser/FBXDocument.cpp index 92c62e68b5..929272c972 100644 --- a/modules/fbx/fbx_parser/FBXDocument.cpp +++ b/modules/fbx/fbx_parser/FBXDocument.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXDocument.h b/modules/fbx/fbx_parser/FBXDocument.h index 885ff8fca4..5bf280a1dc 100644 --- a/modules/fbx/fbx_parser/FBXDocument.h +++ b/modules/fbx/fbx_parser/FBXDocument.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -706,13 +706,13 @@ public: virtual ~AnimationCurve(); /** get list of keyframe positions (time). - * Invariant: |GetKeys()| > 0 */ + * Invariant: |GetKeys()| > 0 */ const KeyTimeList &GetKeys() const { return keys; } /** get list of keyframe values. - * Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/ + * Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/ const KeyValueList &GetValues() const { return values; } @@ -750,8 +750,8 @@ typedef std::weak_ptr<AnimationCurveNode> AnimationCurveNodeWeakPtr; class AnimationCurveNode : public Object { public: /* the optional white list specifies a list of property names for which the caller - wants animations for. If the curve node does not match one of these, std::range_error - will be thrown. */ + wants animations for. If the curve node does not match one of these, std::range_error + will be thrown. */ AnimationCurveNode(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc, const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0); @@ -760,8 +760,8 @@ public: const AnimationMap &Curves() const; /** Object the curve is assigned to, this can be nullptr if the - * target object has no DOM representation or could not - * be read for other reasons.*/ + * target object has no DOM representation or could not + * be read for other reasons.*/ Object *Target() const { return target; } @@ -799,8 +799,8 @@ public: virtual ~AnimationLayer(); /* the optional white list specifies a list of property names for which the caller - wants animations for. Curves not matching this list will not be added to the - animation layer. */ + wants animations for. Curves not matching this list will not be added to the + animation layer. */ const AnimationCurveNodeList Nodes(const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0) const; private: @@ -891,15 +891,15 @@ public: virtual ~Cluster(); /** get the list of deformer weights associated with this cluster. - * Use #GetIndices() to get the associated vertices. Both arrays - * have the same size (and may also be empty). */ + * Use #GetIndices() to get the associated vertices. Both arrays + * have the same size (and may also be empty). */ const std::vector<float> &GetWeights() const { return weights; } /** get indices into the vertex data of the geometry associated - * with this cluster. Use #GetWeights() to get the associated weights. - * Both arrays have the same size (and may also be empty). */ + * with this cluster. Use #GetWeights() to get the associated weights. + * Both arrays have the same size (and may also be empty). */ const std::vector<unsigned int> &GetIndices() const { return indices; } @@ -998,7 +998,7 @@ public: LazyObject *LazyDestinationObject() const; /** return the name of the property the connection is attached to. - * this is an empty string for object to object (OO) connections. */ + * this is an empty string for object to object (OO) connections. */ const std::string &PropertyName() const { return prop; } diff --git a/modules/fbx/fbx_parser/FBXDocumentUtil.cpp b/modules/fbx/fbx_parser/FBXDocumentUtil.cpp index 4a33024969..4ee8a42b33 100644 --- a/modules/fbx/fbx_parser/FBXDocumentUtil.cpp +++ b/modules/fbx/fbx_parser/FBXDocumentUtil.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXDocumentUtil.h b/modules/fbx/fbx_parser/FBXDocumentUtil.h index ba86191c4a..61c92dbc83 100644 --- a/modules/fbx/fbx_parser/FBXDocumentUtil.h +++ b/modules/fbx/fbx_parser/FBXDocumentUtil.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -107,12 +107,12 @@ const T *ProcessSimpleConnection(const Connection &con, const char **propNameOut = nullptr) { if (is_object_property_conn && !con.PropertyName().length()) { DOMWarning("expected incoming " + std::string(name) + - " link to be an object-object connection, ignoring", + " link to be an object-object connection, ignoring", element); return nullptr; } else if (!is_object_property_conn && con.PropertyName().length()) { DOMWarning("expected incoming " + std::string(name) + - " link to be an object-property connection, ignoring", + " link to be an object-property connection, ignoring", element); return nullptr; } diff --git a/modules/fbx/fbx_parser/FBXImportSettings.h b/modules/fbx/fbx_parser/FBXImportSettings.h index b016db174b..fa93f275c2 100644 --- a/modules/fbx/fbx_parser/FBXImportSettings.h +++ b/modules/fbx/fbx_parser/FBXImportSettings.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -81,29 +81,29 @@ namespace FBXDocParser { /** FBX import settings, parts of which are publicly accessible via their corresponding AI_CONFIG constants */ struct ImportSettings { /** enable strict mode: - * - only accept fbx 2012, 2013 files - * - on the slightest error, give up. - * - * Basically, strict mode means that the fbx file will actually - * be validated.*/ + * - only accept fbx 2012, 2013 files + * - on the slightest error, give up. + * + * Basically, strict mode means that the fbx file will actually + * be validated.*/ bool strictMode = true; /** specifies whether all geometry layers are read and scanned for - * usable data channels. The FBX spec indicates that many readers - * will only read the first channel and that this is in some way - * the recommended way- in reality, however, it happens a lot that - * vertex data is spread among multiple layers.*/ + * usable data channels. The FBX spec indicates that many readers + * will only read the first channel and that this is in some way + * the recommended way- in reality, however, it happens a lot that + * vertex data is spread among multiple layers.*/ bool readAllLayers = true; /** specifies whether all materials are read, or only those that - * are referenced by at least one mesh. Reading all materials - * may make FBX reading a lot slower since all objects - * need to be processed. - * This bit is ignored unless readMaterials=true.*/ + * are referenced by at least one mesh. Reading all materials + * may make FBX reading a lot slower since all objects + * need to be processed. + * This bit is ignored unless readMaterials=true.*/ bool readAllMaterials = true; /** import materials (true) or skip them and assign a default - * material.*/ + * material.*/ bool readMaterials = true; /** import embedded textures?*/ @@ -116,35 +116,35 @@ struct ImportSettings { bool readLights = true; /** import animations (i.e. animation curves, the node - * skeleton is always imported).*/ + * skeleton is always imported).*/ bool readAnimations = true; /** read bones (vertex weights and deform info).*/ bool readWeights = true; /** preserve transformation pivots and offsets. Since these can - * not directly be represented in assimp, additional dummy - * nodes will be generated. Note that settings this to false - * can make animation import a lot slower. - * - * The naming scheme for the generated nodes is: - * <OriginalName>_$AssimpFbx$_<TransformName> - * - * where <TransformName> is one of - * RotationPivot - * RotationOffset - * PreRotation - * PostRotation - * ScalingPivot - * ScalingOffset - * Translation - * Scaling - * Rotation - **/ + * not directly be represented in assimp, additional dummy + * nodes will be generated. Note that settings this to false + * can make animation import a lot slower. + * + * The naming scheme for the generated nodes is: + * <OriginalName>_$AssimpFbx$_<TransformName> + * + * where <TransformName> is one of + * RotationPivot + * RotationOffset + * PreRotation + * PostRotation + * ScalingPivot + * ScalingOffset + * Translation + * Scaling + * Rotation + **/ bool preservePivots = true; /** do not import animation curves that specify a constant - * values matching the corresponding node transformation.*/ + * values matching the corresponding node transformation.*/ bool optimizeEmptyAnimationCurves = true; /** use legacy naming for embedded textures eg: (*0, *1, *2).*/ diff --git a/modules/fbx/fbx_parser/FBXMaterial.cpp b/modules/fbx/fbx_parser/FBXMaterial.cpp index bf8922267e..e4ee77e850 100644 --- a/modules/fbx/fbx_parser/FBXMaterial.cpp +++ b/modules/fbx/fbx_parser/FBXMaterial.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp index 2cc25a0690..b3956af762 100644 --- a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp +++ b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -368,7 +368,7 @@ MeshGeometry::MappingData<T> MeshGeometry::resolve_vertex_data_array( // UVIndex, MaterialIndex, NormalIndex, etc.. std::string indexDataElementName; - if (indexOverride != "") { + if (!indexOverride.empty()) { // Colors should become ColorIndex indexDataElementName = indexOverride; } else { diff --git a/modules/fbx/fbx_parser/FBXMeshGeometry.h b/modules/fbx/fbx_parser/FBXMeshGeometry.h index c9b25f008d..9f0242d233 100644 --- a/modules/fbx/fbx_parser/FBXMeshGeometry.h +++ b/modules/fbx/fbx_parser/FBXMeshGeometry.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -226,7 +226,7 @@ public: const std::vector<Vector3> &GetVertices() const; /** Get a list of all vertex normals or an empty array if - * no normals are specified. */ + * no normals are specified. */ const std::vector<Vector3> &GetNormals() const; /** Return list of vertex indices. */ @@ -238,8 +238,8 @@ private: std::vector<unsigned int> m_indices; }; /** -* DOM class for FBX geometry of type "Line" -*/ + * DOM class for FBX geometry of type "Line" + */ class LineGeometry : public Geometry { public: /** The class constructor */ diff --git a/modules/fbx/fbx_parser/FBXModel.cpp b/modules/fbx/fbx_parser/FBXModel.cpp index 03c9de0c35..625ee6237b 100644 --- a/modules/fbx/fbx_parser/FBXModel.cpp +++ b/modules/fbx/fbx_parser/FBXModel.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXNodeAttribute.cpp b/modules/fbx/fbx_parser/FBXNodeAttribute.cpp index 15184a0f5d..c8ea03adec 100644 --- a/modules/fbx/fbx_parser/FBXNodeAttribute.cpp +++ b/modules/fbx/fbx_parser/FBXNodeAttribute.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXParseTools.h b/modules/fbx/fbx_parser/FBXParseTools.h index b4003bbec5..37a7ccad2a 100644 --- a/modules/fbx/fbx_parser/FBXParseTools.h +++ b/modules/fbx/fbx_parser/FBXParseTools.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXParser.cpp b/modules/fbx/fbx_parser/FBXParser.cpp index d9ef025a16..d8ccb4179c 100644 --- a/modules/fbx/fbx_parser/FBXParser.cpp +++ b/modules/fbx/fbx_parser/FBXParser.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -660,13 +660,6 @@ void ParseVectorDataArray(std::vector<Vector3> &out, const ElementPtr el) { static_cast<real_t>(d[1]), static_cast<real_t>(d[2]))); } - // for debugging - /*for ( size_t i = 0; i < out.size(); i++ ) { - aiVector3D vec3( out[ i ] ); - std::stringstream stream; - stream << " vec3.x = " << vec3.x << " vec3.y = " << vec3.y << " vec3.z = " << vec3.z << std::endl; - DefaultLogger::get()->info( stream.str() ); - }*/ } else if (type == 'f') { const float *f = reinterpret_cast<const float *>(&buff[0]); for (unsigned int i = 0; i < count3; ++i, f += 3) { diff --git a/modules/fbx/fbx_parser/FBXParser.h b/modules/fbx/fbx_parser/FBXParser.h index 93836c2205..c5e3f5bf6b 100644 --- a/modules/fbx/fbx_parser/FBXParser.h +++ b/modules/fbx/fbx_parser/FBXParser.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -187,7 +187,7 @@ private: class Parser { public: /** Parse given a token list. Does not take ownership of the tokens - - * the objects must persist during the entire parser lifetime */ + * the objects must persist during the entire parser lifetime */ Parser(const TokenList &tokens, bool is_binary); ~Parser(); diff --git a/modules/fbx/fbx_parser/FBXPose.cpp b/modules/fbx/fbx_parser/FBXPose.cpp index 6d80b85e38..738b9131b6 100644 --- a/modules/fbx/fbx_parser/FBXPose.cpp +++ b/modules/fbx/fbx_parser/FBXPose.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXProperties.cpp b/modules/fbx/fbx_parser/FBXProperties.cpp index 37717e9109..531f0743d6 100644 --- a/modules/fbx/fbx_parser/FBXProperties.cpp +++ b/modules/fbx/fbx_parser/FBXProperties.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -114,12 +114,12 @@ PropertyPtr ReadTypedProperty(const ElementPtr element) { } else if (!strcmp(cs, "KTime")) { return new TypedProperty<int64_t>(ParseTokenAsInt64(tok[4])); } else if (!strcmp(cs, "Vector3D") || - !strcmp(cs, "ColorRGB") || - !strcmp(cs, "Vector") || - !strcmp(cs, "Color") || - !strcmp(cs, "Lcl Translation") || - !strcmp(cs, "Lcl Rotation") || - !strcmp(cs, "Lcl Scaling")) { + !strcmp(cs, "ColorRGB") || + !strcmp(cs, "Vector") || + !strcmp(cs, "Color") || + !strcmp(cs, "Lcl Translation") || + !strcmp(cs, "Lcl Rotation") || + !strcmp(cs, "Lcl Scaling")) { return new TypedProperty<Vector3>(Vector3( ParseTokenAsFloat(tok[4]), ParseTokenAsFloat(tok[5]), diff --git a/modules/fbx/fbx_parser/FBXProperties.h b/modules/fbx/fbx_parser/FBXProperties.h index bfd27ac94e..4d74a1db17 100644 --- a/modules/fbx/fbx_parser/FBXProperties.h +++ b/modules/fbx/fbx_parser/FBXProperties.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXTokenizer.cpp b/modules/fbx/fbx_parser/FBXTokenizer.cpp index 81c5b128e8..bac3e6d5c4 100644 --- a/modules/fbx/fbx_parser/FBXTokenizer.cpp +++ b/modules/fbx/fbx_parser/FBXTokenizer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXTokenizer.h b/modules/fbx/fbx_parser/FBXTokenizer.h index 184d0fd894..789f8b5d9d 100644 --- a/modules/fbx/fbx_parser/FBXTokenizer.h +++ b/modules/fbx/fbx_parser/FBXTokenizer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/fbx_parser/FBXUtil.cpp b/modules/fbx/fbx_parser/FBXUtil.cpp index 1f14a69099..e4958547d4 100644 --- a/modules/fbx/fbx_parser/FBXUtil.cpp +++ b/modules/fbx/fbx_parser/FBXUtil.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -169,10 +169,10 @@ char EncodeBase64(char byte) { } /** Encodes a block of 4 bytes to base64 encoding -* @param bytes Bytes to encode. -* @param out_string String to write encoded values to. -* @param string_pos Position in out_string. -*/ + * @param bytes Bytes to encode. + * @param out_string String to write encoded values to. + * @param string_pos Position in out_string. + */ void EncodeByteBlock(const char *bytes, std::string &out_string, size_t string_pos) { char b0 = (bytes[0] & 0xFC) >> 2; char b1 = (bytes[0] & 0x03) << 4 | ((bytes[1] & 0xF0) >> 4); diff --git a/modules/fbx/fbx_parser/FBXUtil.h b/modules/fbx/fbx_parser/FBXUtil.h index efc131831b..8022233029 100644 --- a/modules/fbx/fbx_parser/FBXUtil.h +++ b/modules/fbx/fbx_parser/FBXUtil.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -87,34 +87,34 @@ namespace Util { const char *TokenTypeString(TokenType t); /** Decode a single Base64-encoded character. -* -* @param ch Character to decode (from base64 to binary). -* @return decoded byte value*/ + * + * @param ch Character to decode (from base64 to binary). + * @return decoded byte value*/ uint8_t DecodeBase64(char ch); /** Compute decoded size of a Base64-encoded string -* -* @param in Characters to decode. -* @param inLength Number of characters to decode. -* @return size of the decoded data (number of bytes)*/ + * + * @param in Characters to decode. + * @param inLength Number of characters to decode. + * @return size of the decoded data (number of bytes)*/ size_t ComputeDecodedSizeBase64(const char *in, size_t inLength); /** Decode a Base64-encoded string -* -* @param in Characters to decode. -* @param inLength Number of characters to decode. -* @param out Pointer where we will store the decoded data. -* @param maxOutLength Size of output buffer. -* @return size of the decoded data (number of bytes)*/ + * + * @param in Characters to decode. + * @param inLength Number of characters to decode. + * @param out Pointer where we will store the decoded data. + * @param maxOutLength Size of output buffer. + * @return size of the decoded data (number of bytes)*/ size_t DecodeBase64(const char *in, size_t inLength, uint8_t *out, size_t maxOutLength); char EncodeBase64(char byte); /** Encode bytes in base64-encoding -* -* @param data Binary data to encode. -* @param inLength Number of bytes to encode. -* @return base64-encoded string*/ + * + * @param data Binary data to encode. + * @param inLength Number of bytes to encode. + * @return base64-encoded string*/ std::string EncodeBase64(const char *data, size_t length); } // namespace Util } // namespace FBXDocParser diff --git a/modules/fbx/register_types.cpp b/modules/fbx/register_types.cpp index a75da8f3a9..3eafb4af45 100644 --- a/modules/fbx/register_types.cpp +++ b/modules/fbx/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,7 +35,7 @@ #ifdef TOOLS_ENABLED static void _editor_init() { - Ref<EditorSceneImporterFBX> import_fbx; + Ref<EditorSceneFormatImporterFBX> import_fbx; import_fbx.instantiate(); ResourceImporterScene::get_singleton()->add_importer(import_fbx); } @@ -46,7 +46,7 @@ void register_fbx_types() { ClassDB::APIType prev_api = ClassDB::get_current_api(); ClassDB::set_current_api(ClassDB::API_EDITOR); - GDREGISTER_CLASS(EditorSceneImporterFBX); + GDREGISTER_CLASS(EditorSceneFormatImporterFBX); ClassDB::set_current_api(prev_api); diff --git a/modules/fbx/register_types.h b/modules/fbx/register_types.h index e5741afd72..6e3cc0dc46 100644 --- a/modules/fbx/register_types.h +++ b/modules/fbx/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/tools/import_utils.cpp b/modules/fbx/tools/import_utils.cpp index 66b0153308..5a49f24c00 100644 --- a/modules/fbx/tools/import_utils.cpp +++ b/modules/fbx/tools/import_utils.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -45,27 +45,27 @@ Basis ImportUtils::EulerToBasis(FBXDocParser::Model::RotOrder mode, const Vector // by simply invert its order: https://www.cs.utexas.edu/~theshark/courses/cs354/lectures/cs354-14.pdf switch (mode) { case FBXDocParser::Model::RotOrder_EulerXYZ: - ret.set_euler_zyx(p_rotation); + ret.set_euler(p_rotation, Basis::EULER_ORDER_XYZ); break; case FBXDocParser::Model::RotOrder_EulerXZY: - ret.set_euler_yzx(p_rotation); + ret.set_euler(p_rotation, Basis::EULER_ORDER_XZY); break; case FBXDocParser::Model::RotOrder_EulerYZX: - ret.set_euler_xzy(p_rotation); + ret.set_euler(p_rotation, Basis::EULER_ORDER_YZX); break; case FBXDocParser::Model::RotOrder_EulerYXZ: - ret.set_euler_zxy(p_rotation); + ret.set_euler(p_rotation, Basis::EULER_ORDER_YXZ); break; case FBXDocParser::Model::RotOrder_EulerZXY: - ret.set_euler_yxz(p_rotation); + ret.set_euler(p_rotation, Basis::EULER_ORDER_ZXY); break; case FBXDocParser::Model::RotOrder_EulerZYX: - ret.set_euler_xyz(p_rotation); + ret.set_euler(p_rotation, Basis::EULER_ORDER_ZYX); break; case FBXDocParser::Model::RotOrder_SphericXYZ: @@ -89,22 +89,22 @@ Vector3 ImportUtils::BasisToEuler(FBXDocParser::Model::RotOrder mode, const Basi // by simply invert its order: https://www.cs.utexas.edu/~theshark/courses/cs354/lectures/cs354-14.pdf switch (mode) { case FBXDocParser::Model::RotOrder_EulerXYZ: - return p_rotation.get_euler_zyx(); + return p_rotation.get_euler(Basis::EULER_ORDER_XYZ); case FBXDocParser::Model::RotOrder_EulerXZY: - return p_rotation.get_euler_yzx(); + return p_rotation.get_euler(Basis::EULER_ORDER_XZY); case FBXDocParser::Model::RotOrder_EulerYZX: - return p_rotation.get_euler_xzy(); + return p_rotation.get_euler(Basis::EULER_ORDER_YZX); case FBXDocParser::Model::RotOrder_EulerYXZ: - return p_rotation.get_euler_zxy(); + return p_rotation.get_euler(Basis::EULER_ORDER_YXZ); case FBXDocParser::Model::RotOrder_EulerZXY: - return p_rotation.get_euler_yxz(); + return p_rotation.get_euler(Basis::EULER_ORDER_ZXY); case FBXDocParser::Model::RotOrder_EulerZYX: - return p_rotation.get_euler_xyz(); + return p_rotation.get_euler(Basis::EULER_ORDER_ZYX); case FBXDocParser::Model::RotOrder_SphericXYZ: // TODO diff --git a/modules/fbx/tools/import_utils.h b/modules/fbx/tools/import_utils.h index fbe7dbd82f..b52263c2ac 100644 --- a/modules/fbx/tools/import_utils.h +++ b/modules/fbx/tools/import_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,7 +43,7 @@ /** * Import Utils * Conversion tools / glue code to convert from FBX to Godot -*/ + */ class ImportUtils { public: /// Convert a vector from degrees to radians. @@ -201,7 +201,7 @@ public: }; /** Get fbx fps for time mode meta data - */ + */ static float get_fbx_fps(int32_t time_mode) { switch (time_mode) { case AssetImportFbx::TIME_MODE_DEFAULT: @@ -258,13 +258,13 @@ public: } /** - * Find hardcoded textures from assimp which could be in many different directories - */ + * Find hardcoded textures from assimp which could be in many different directories + */ /** - * set_texture_mapping_mode - * Helper to check the mapping mode of the texture (repeat, clamp and mirror) - */ + * set_texture_mapping_mode + * Helper to check the mapping mode of the texture (repeat, clamp and mirror) + */ // static void set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<ImageTexture> texture) { // ERR_FAIL_COND(texture.is_null()); // ERR_FAIL_COND(map_mode == nullptr); @@ -282,9 +282,9 @@ public: // } /** - * Load or load from cache image :) - * We need to upgrade this in the later version :) should not be hard - */ + * Load or load from cache image :) + * We need to upgrade this in the later version :) should not be hard + */ //static Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path){ // Map<String, Ref<Image> >::Element *match = state.path_to_image_cache.find(p_path); diff --git a/modules/fbx/tools/validation_tools.cpp b/modules/fbx/tools/validation_tools.cpp index 9dbd8bf544..f775480e69 100644 --- a/modules/fbx/tools/validation_tools.cpp +++ b/modules/fbx/tools/validation_tools.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/fbx/tools/validation_tools.h b/modules/fbx/tools/validation_tools.h index 12d644ee94..69a2673197 100644 --- a/modules/fbx/tools/validation_tools.h +++ b/modules/fbx/tools/validation_tools.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/freetype/register_types.cpp b/modules/freetype/register_types.cpp index e4e6a4c146..28fd1a57c9 100644 --- a/modules/freetype/register_types.cpp +++ b/modules/freetype/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/freetype/register_types.h b/modules/freetype/register_types.h index 7a4f64b54b..c4eb241636 100644 --- a/modules/freetype/register_types.h +++ b/modules/freetype/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/freetype/uwpdef.h b/modules/freetype/uwpdef.h index f829edea67..05aaae61b5 100644 --- a/modules/freetype/uwpdef.h +++ b/modules/freetype/uwpdef.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/android/android_gdn.cpp b/modules/gdnative/android/android_gdn.cpp index fe3b3e7e12..7411fc4031 100644 --- a/modules/gdnative/android/android_gdn.cpp +++ b/modules/gdnative/android/android_gdn.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml index 3654870b09..21df640ebc 100644 --- a/modules/gdnative/doc_classes/GDNativeLibrary.xml +++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml @@ -7,8 +7,8 @@ A GDNative library can implement [NativeScript]s, global functions to call with the [GDNative] class, or low-level engine extensions through interfaces such as XRInterfaceGDNative. The library must be compiled for each platform and architecture that the project will run on. </description> <tutorials> - <link title="GDNative C example">https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-c-example.html</link> - <link title="GDNative C++ example">https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-cpp-example.html</link> + <link title="GDNative C example">$DOCS_URL/tutorials/scripting/gdnative/gdnative_c_example.html</link> + <link title="GDNative C++ example">$DOCS_URL/tutorials/scripting/gdnative/gdnative_cpp_example.html</link> </tutorials> <methods> <method name="get_current_dependencies" qualifiers="const"> diff --git a/modules/gdnative/doc_classes/NativeScript.xml b/modules/gdnative/doc_classes/NativeScript.xml index 9d34e89f02..221374a7a4 100644 --- a/modules/gdnative/doc_classes/NativeScript.xml +++ b/modules/gdnative/doc_classes/NativeScript.xml @@ -38,7 +38,7 @@ <return type="Variant" /> <description> Constructs a new object of the base type with a script of this type already attached. - [i]Note[/i]: Any arguments passed to this function will be ignored and not passed to the native constructor function. This will change with in a future API extension. + [b]Note:[/b] Any arguments passed to this function will be ignored and not passed to the native constructor function. This will change with in a future API extension. </description> </method> </methods> diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 9445fac1c6..3950ce1ade 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 0cc6487ea4..8facd43743 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/aabb.cpp b/modules/gdnative/gdnative/aabb.cpp index c42b874b4b..82aa7215b2 100644 --- a/modules/gdnative/gdnative/aabb.cpp +++ b/modules/gdnative/gdnative/aabb.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp index 76e131dc06..31063e43c1 100644 --- a/modules/gdnative/gdnative/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index 4641f0bacc..af7f9a2399 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/callable.cpp b/modules/gdnative/gdnative/callable.cpp index 85274e5e22..7ae1038a13 100644 --- a/modules/gdnative/gdnative/callable.cpp +++ b/modules/gdnative/gdnative/callable.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp index 502f89c027..8f13610b2c 100644 --- a/modules/gdnative/gdnative/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp index 2bfad6e695..dea01dad43 100644 --- a/modules/gdnative/gdnative/dictionary.cpp +++ b/modules/gdnative/gdnative/dictionary.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index b84ce2d192..8ba41b3224 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -129,13 +129,13 @@ void GDAPI godot_free(void *p_ptr) { // Helper print functions. void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_ERROR); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_ERROR); } void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_WARNING); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_WARNING); } void GDAPI godot_print_script_error(const char *p_description, const char *p_function, const char *p_file, int p_line) { - _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_SCRIPT); + _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_SCRIPT); } void _gdnative_report_version_mismatch(const godot_object *p_library, const char *p_ext, godot_gdnative_api_version p_want, godot_gdnative_api_version p_have) { diff --git a/modules/gdnative/gdnative/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp index 57d67b9abb..3db705f550 100644 --- a/modules/gdnative/gdnative/node_path.cpp +++ b/modules/gdnative/gdnative/node_path.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/packed_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp index f03c94aeb8..bb6f0324a8 100644 --- a/modules/gdnative/gdnative/packed_arrays.cpp +++ b/modules/gdnative/gdnative/packed_arrays.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/plane.cpp b/modules/gdnative/gdnative/plane.cpp index 8b8e84e3c1..9ac5cfb3b7 100644 --- a/modules/gdnative/gdnative/plane.cpp +++ b/modules/gdnative/gdnative/plane.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/quaternion.cpp b/modules/gdnative/gdnative/quaternion.cpp index 62bcbbd382..b91e47e77e 100644 --- a/modules/gdnative/gdnative/quaternion.cpp +++ b/modules/gdnative/gdnative/quaternion.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp index a196a63188..f4674850e3 100644 --- a/modules/gdnative/gdnative/rect2.cpp +++ b/modules/gdnative/gdnative/rect2.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/rid.cpp b/modules/gdnative/gdnative/rid.cpp index f8599afcf9..b40fa7c2c6 100644 --- a/modules/gdnative/gdnative/rid.cpp +++ b/modules/gdnative/gdnative/rid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/signal.cpp b/modules/gdnative/gdnative/signal.cpp index 5963c0e6c6..8293aed439 100644 --- a/modules/gdnative/gdnative/signal.cpp +++ b/modules/gdnative/gdnative/signal.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 1ad1ea8bdf..7a5d8c6703 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp index bd8f69674e..0bdacd2e5d 100644 --- a/modules/gdnative/gdnative/string_name.cpp +++ b/modules/gdnative/gdnative/string_name.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index 2864818831..45ba790dc1 100644 --- a/modules/gdnative/gdnative/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/transform_3d.cpp b/modules/gdnative/gdnative/transform_3d.cpp index 8bd2a68d63..b47e8e69de 100644 --- a/modules/gdnative/gdnative/transform_3d.cpp +++ b/modules/gdnative/gdnative/transform_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index ec9aaa0a55..42fa77a174 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index 6a01a7ad59..eb8ffd74cd 100644 --- a/modules/gdnative/gdnative/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp index fb426c8ac4..26e94d7e5c 100644 --- a/modules/gdnative/gdnative/vector3.cpp +++ b/modules/gdnative/gdnative/vector3.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp index 9dad13a615..f94464826e 100644 --- a/modules/gdnative/gdnative_library_editor_plugin.cpp +++ b/modules/gdnative/gdnative_library_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -110,7 +110,7 @@ void GDNativeLibraryEditor::_update_tree() { TreeItem *new_arch = tree->create_item(platform); new_arch->set_text(0, TTR("Double click to create a new entry")); - new_arch->set_text_align(0, TreeItem::ALIGN_CENTER); + new_arch->set_text_alignment(0, HORIZONTAL_ALIGNMENT_CENTER); new_arch->set_custom_color(0, get_theme_color(SNAME("accent_color"), SNAME("Editor"))); new_arch->set_expand_right(0, true); new_arch->set_metadata(1, E->key()); @@ -335,7 +335,7 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() { hbox->add_child(label); filter = memnew(MenuButton); filter->set_h_size_flags(SIZE_EXPAND_FILL); - filter->set_text_align(filter->ALIGN_LEFT); + filter->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT); hbox->add_child(filter); PopupMenu *filter_list = filter->get_popup(); filter_list->set_hide_on_checkable_item_selection(false); diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h index 61afb1aaaa..27848893fa 100644 --- a/modules/gdnative/gdnative_library_editor_plugin.h +++ b/modules/gdnative/gdnative_library_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative_library_singleton_editor.cpp b/modules/gdnative/gdnative_library_singleton_editor.cpp index f1b4a9a81b..6eb412eccb 100644 --- a/modules/gdnative/gdnative_library_singleton_editor.cpp +++ b/modules/gdnative/gdnative_library_singleton_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/gdnative_library_singleton_editor.h b/modules/gdnative/gdnative_library_singleton_editor.h index 5bb823d920..16155723bc 100644 --- a/modules/gdnative/gdnative_library_singleton_editor.h +++ b/modules/gdnative/gdnative_library_singleton_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/android/godot_android.h b/modules/gdnative/include/android/godot_android.h index 867ef9e03a..859a85ae1e 100644 --- a/modules/gdnative/include/android/godot_android.h +++ b/modules/gdnative/include/android/godot_android.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/aabb.h b/modules/gdnative/include/gdnative/aabb.h index 860675065d..67818f61c8 100644 --- a/modules/gdnative/include/gdnative/aabb.h +++ b/modules/gdnative/include/gdnative/aabb.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h index bf4b852449..cee641a7c5 100644 --- a/modules/gdnative/include/gdnative/array.h +++ b/modules/gdnative/include/gdnative/array.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h index 5477dbf811..50c9aa6408 100644 --- a/modules/gdnative/include/gdnative/basis.h +++ b/modules/gdnative/include/gdnative/basis.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/callable.h b/modules/gdnative/include/gdnative/callable.h index 1d52ca7a68..db068d2ac7 100644 --- a/modules/gdnative/include/gdnative/callable.h +++ b/modules/gdnative/include/gdnative/callable.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h index 3334013147..2d64a323f9 100644 --- a/modules/gdnative/include/gdnative/color.h +++ b/modules/gdnative/include/gdnative/color.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h index b9525fb5e6..4219753f71 100644 --- a/modules/gdnative/include/gdnative/dictionary.h +++ b/modules/gdnative/include/gdnative/dictionary.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index d8c290f6bd..b46a00c185 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/math_defs.h b/modules/gdnative/include/gdnative/math_defs.h index b5cf389506..dee027527e 100644 --- a/modules/gdnative/include/gdnative/math_defs.h +++ b/modules/gdnative/include/gdnative/math_defs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/node_path.h b/modules/gdnative/include/gdnative/node_path.h index a4607c0152..46b693dcf6 100644 --- a/modules/gdnative/include/gdnative/node_path.h +++ b/modules/gdnative/include/gdnative/node_path.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/packed_arrays.h b/modules/gdnative/include/gdnative/packed_arrays.h index f9e4ba3a8d..f4935ee0dc 100644 --- a/modules/gdnative/include/gdnative/packed_arrays.h +++ b/modules/gdnative/include/gdnative/packed_arrays.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/plane.h b/modules/gdnative/include/gdnative/plane.h index 6cd0ed6307..e8f4f13b99 100644 --- a/modules/gdnative/include/gdnative/plane.h +++ b/modules/gdnative/include/gdnative/plane.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/quaternion.h b/modules/gdnative/include/gdnative/quaternion.h index 75754e6ab5..80e99c3a7c 100644 --- a/modules/gdnative/include/gdnative/quaternion.h +++ b/modules/gdnative/include/gdnative/quaternion.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/rect2.h b/modules/gdnative/include/gdnative/rect2.h index 326462be43..a901537fc4 100644 --- a/modules/gdnative/include/gdnative/rect2.h +++ b/modules/gdnative/include/gdnative/rect2.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/rid.h b/modules/gdnative/include/gdnative/rid.h index bc832fbeb9..f3013f36f0 100644 --- a/modules/gdnative/include/gdnative/rid.h +++ b/modules/gdnative/include/gdnative/rid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/signal.h b/modules/gdnative/include/gdnative/signal.h index 41a76d0510..64aef1c918 100644 --- a/modules/gdnative/include/gdnative/signal.h +++ b/modules/gdnative/include/gdnative/signal.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h index 79de52c80f..375e8f94c3 100644 --- a/modules/gdnative/include/gdnative/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/string_name.h b/modules/gdnative/include/gdnative/string_name.h index 346f626e81..6f4d9c64fe 100644 --- a/modules/gdnative/include/gdnative/string_name.h +++ b/modules/gdnative/include/gdnative/string_name.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h index 5acb172081..a083e61a2c 100644 --- a/modules/gdnative/include/gdnative/transform2d.h +++ b/modules/gdnative/include/gdnative/transform2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/transform_3d.h b/modules/gdnative/include/gdnative/transform_3d.h index 97ad451e9b..abd64a4d1d 100644 --- a/modules/gdnative/include/gdnative/transform_3d.h +++ b/modules/gdnative/include/gdnative/transform_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h index a88bd2878a..b716fdaca1 100644 --- a/modules/gdnative/include/gdnative/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/variant_struct.h b/modules/gdnative/include/gdnative/variant_struct.h index 321c76c206..cc75a8c498 100644 --- a/modules/gdnative/include/gdnative/variant_struct.h +++ b/modules/gdnative/include/gdnative/variant_struct.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h index 00faffbad7..f5b55fd4ce 100644 --- a/modules/gdnative/include/gdnative/vector2.h +++ b/modules/gdnative/include/gdnative/vector2.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h index 7db093ce52..d52cd38a72 100644 --- a/modules/gdnative/include/gdnative/vector3.h +++ b/modules/gdnative/include/gdnative/vector3.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 5390d30c9f..eea898475b 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -102,7 +102,7 @@ typedef enum { GODOT_PROPERTY_USAGE_DEFAULT = GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_EDITOR | GODOT_PROPERTY_USAGE_NETWORK, GODOT_PROPERTY_USAGE_DEFAULT_INTL = GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_EDITOR | GODOT_PROPERTY_USAGE_NETWORK | GODOT_PROPERTY_USAGE_INTERNATIONALIZED, - GODOT_PROPERTY_USAGE_NOEDITOR = GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_NETWORK, + GODOT_PROPERTY_USAGE_NO_EDITOR = GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_NETWORK, } godot_nativescript_property_usage_flags; typedef struct { @@ -146,7 +146,7 @@ typedef struct { } godot_nativescript_method_argument; typedef struct { - // instance pointer, method data, user data, num args, args - return result as varaint + // instance pointer, method data, user data, num args, args - return result as variant GDCALLINGCONV godot_variant (*method)(godot_object *, void *, void *, int, godot_variant **); void *method_data; GDCALLINGCONV void (*free_func)(void *); diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h index 02ee4066d0..0042d79966 100644 --- a/modules/gdnative/include/pluginscript/godot_pluginscript.h +++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/include/videodecoder/godot_videodecoder.h b/modules/gdnative/include/videodecoder/godot_videodecoder.h index dc2cf5ec07..16daba0a67 100644 --- a/modules/gdnative/include/videodecoder/godot_videodecoder.h +++ b/modules/gdnative/include/videodecoder/godot_videodecoder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 598f7c7ad0..ddde28811c 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -397,7 +397,7 @@ List<ClassAPI> generate_c_api_classes() { arg_type = "Variant"; } else if (arg_info.type == Variant::OBJECT) { arg_type = arg_info.class_name; - if (arg_type == "") { + if (arg_type.is_empty()) { arg_type = Variant::get_type_name(arg_info.type); } } else { diff --git a/modules/gdnative/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h index 611abb2a2d..58e141f07e 100644 --- a/modules/gdnative/nativescript/api_generator.h +++ b/modules/gdnative/nativescript/api_generator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index dadd1a9d10..992eeba8f4 100644 --- a/modules/gdnative/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index fb46bafb3c..be304a43f0 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -682,7 +682,7 @@ void NativeScriptInstance::get_property_list(List<PropertyInfo> *p_properties) c ERR_CONTINUE(info.type < 0 || info.type >= Variant::VARIANT_MAX); info.name = d["name"]; - ERR_CONTINUE(info.name == ""); + ERR_CONTINUE(info.name.is_empty()); if (d.has("hint")) { info.hint = PropertyHint(d["hint"].operator int64_t()); @@ -1139,15 +1139,12 @@ void NativeScriptLanguage::profiling_start() { MutexLock lock(mutex); profile_data.clear(); - profiling = true; #endif } void NativeScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED MutexLock lock(mutex); - - profiling = false; #endif } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index a7647e8c59..6c47d35abc 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -269,7 +269,6 @@ private: }; Map<StringName, ProfileData> profile_data; - bool profiling = false; public: // These two maps must only be touched on the main thread @@ -295,8 +294,6 @@ public: return singleton; } - void _hacky_api_anchor(); - _FORCE_INLINE_ void set_language_index(int p_idx) { lang_idx = p_idx; } #ifndef NO_THREADS diff --git a/modules/gdnative/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp index 82a3459517..ee63dca9a3 100644 --- a/modules/gdnative/nativescript/register_types.cpp +++ b/modules/gdnative/nativescript/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/nativescript/register_types.h b/modules/gdnative/nativescript/register_types.h index d12ac9eda3..ce6085f62a 100644 --- a/modules/gdnative/nativescript/register_types.h +++ b/modules/gdnative/nativescript/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp index feae81397e..9236aceb3e 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.cpp +++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index bdae265db2..09b051c008 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -69,8 +69,6 @@ public: virtual ScriptLanguage *get_language(); - void set_path(const String &p_path); - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const; virtual void refcount_incremented(); diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 79aba342c9..0e068dec3a 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h index 26ab4a95e3..6039f807a8 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.h +++ b/modules/gdnative/pluginscript/pluginscript_language.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp index 462452a897..a151d551dc 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.cpp +++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h index e5d665c186..bcce742aea 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.h +++ b/modules/gdnative/pluginscript/pluginscript_loader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index 2b4ceda49d..71ab8ef0a2 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -232,8 +232,7 @@ bool PluginScript::instance_has(const Object *p_this) const { } bool PluginScript::has_source_code() const { - bool has = _source != ""; - return has; + return !_source.is_empty(); } String PluginScript::get_source_code() const { @@ -257,11 +256,11 @@ Error PluginScript::reload(bool p_keep_state) { _valid = false; String basedir = _path; - if (basedir == "") { + if (basedir.is_empty()) { basedir = get_path(); } - if (basedir != "") { + if (!basedir.is_empty()) { basedir = basedir.get_base_dir(); } @@ -361,13 +360,6 @@ Error PluginScript::reload(bool p_keep_state) { _properties_default_values[pi.name] = v["default_value"]; } -#ifdef TOOLS_ENABLED -/*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) { - - _update_placeholder(E->get()); - }*/ -#endif - FREE_SCRIPT_MANIFEST(manifest); return OK; #undef FREE_SCRIPT_MANIFEST diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index 1a12a130d1..73c486f6d9 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp index 7faacfdcb9..39c8124c17 100644 --- a/modules/gdnative/pluginscript/register_types.cpp +++ b/modules/gdnative/pluginscript/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,9 +44,9 @@ static List<PluginScriptLanguage *> pluginscript_languages; static Error _check_language_desc(const godot_pluginscript_language_desc *desc) { - ERR_FAIL_COND_V(!desc->name || desc->name == String(), ERR_BUG); - ERR_FAIL_COND_V(!desc->type || desc->type == String(), ERR_BUG); - ERR_FAIL_COND_V(!desc->extension || desc->extension == String(), ERR_BUG); + ERR_FAIL_COND_V(!desc->name, ERR_BUG); + ERR_FAIL_COND_V(!desc->type, ERR_BUG); + ERR_FAIL_COND_V(!desc->extension, ERR_BUG); ERR_FAIL_COND_V(!desc->recognized_extensions || !desc->recognized_extensions[0], ERR_BUG); ERR_FAIL_COND_V(!desc->init, ERR_BUG); ERR_FAIL_COND_V(!desc->finish, ERR_BUG); diff --git a/modules/gdnative/pluginscript/register_types.h b/modules/gdnative/pluginscript/register_types.h index 2118f668e9..49e7357a98 100644 --- a/modules/gdnative/pluginscript/register_types.h +++ b/modules/gdnative/pluginscript/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index a4ab5663ef..fb682beccc 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/register_types.h b/modules/gdnative/register_types.h index 662c638442..0e1cb46a55 100644 --- a/modules/gdnative/register_types.h +++ b/modules/gdnative/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/tests/test_variant.h b/modules/gdnative/tests/test_variant.h index c506882283..fb6537cf42 100644 --- a/modules/gdnative/tests/test_variant.h +++ b/modules/gdnative/tests/test_variant.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/videodecoder/register_types.cpp b/modules/gdnative/videodecoder/register_types.cpp index 54a577a2b6..b28ff99bb8 100644 --- a/modules/gdnative/videodecoder/register_types.cpp +++ b/modules/gdnative/videodecoder/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/videodecoder/register_types.h b/modules/gdnative/videodecoder/register_types.h index 809225c925..b261c36503 100644 --- a/modules/gdnative/videodecoder/register_types.h +++ b/modules/gdnative/videodecoder/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index 4c9bfb395d..d3d295c494 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -341,7 +341,7 @@ void VideoStreamGDNative::_bind_methods() { ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamGDNative::set_file); ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamGDNative::get_file); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_file", "get_file"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_file", "get_file"); } void VideoStreamGDNative::set_audio_track(int p_track) { diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h index c605dbb433..b0a10242be 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.h +++ b/modules/gdnative/videodecoder/video_stream_gdnative.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub index 5c8cbdf869..c6121ec7fe 100644 --- a/modules/gdscript/SCsub +++ b/modules/gdscript/SCsub @@ -21,3 +21,5 @@ if env["tools"]: if env["tests"]: env_gdscript.Append(CPPDEFINES=["TESTS_ENABLED"]) env_gdscript.add_source_files(env.modules_sources, "./tests/*.cpp") + +SConscript("editor_templates/SCsub") diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 631ee4d895..33f4198ac1 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -4,10 +4,10 @@ Built-in GDScript functions. </brief_description> <description> - List of core built-in GDScript functions. Math functions and other utilities. Everything else is provided by objects. (Keywords: builtin, built in, global functions.) + A list of GDScript-specific utility functions accessed in any script. + For the list of the global functions and constants see [@GlobalScope]. </description> <tutorials> - <link title="Random number generation">https://docs.godotengine.org/en/latest/tutorials/math/random_number_generation.html</link> </tutorials> <methods> <method name="Color8"> @@ -98,6 +98,7 @@ [codeblock] [{function:bar, line:12, source:res://script.gd}, {function:foo, line:9, source:res://script.gd}, {function:_ready, line:6, source:res://script.gd}] [/codeblock] + [b]Note:[/b] Not supported for calling from threads. Instead, this will return an empty array. </description> </method> <method name="inst2dict"> @@ -160,17 +161,24 @@ <method name="print_debug" qualifiers="vararg"> <return type="void" /> <description> - Like [method @GlobalScope.print], but prints only when used in debug mode. + Like [method @GlobalScope.print], but includes the current stack frame when running with the debugger turned on. + Output in the console would look something like this: + [codeblock] + Test print + At: res://test.gd:15:_process() + [/codeblock] + [b]Note:[/b] Not supported for calling from threads. Instead of the stack frame, this will print the thread ID. </description> </method> <method name="print_stack"> <return type="void" /> <description> - Prints a stack track at code location, only works when running with debugger turned on. + Prints a stack trace at the current code location. Only works when running with debugger turned on. Output in the console would look something like this: [codeblock] Frame 0 - res://test.gd:16 in function '_process' [/codeblock] + [b]Note:[/b] Not supported for calling from threads. Instead of the stack trace, this will print the thread ID. </description> </method> <method name="range" qualifiers="vararg"> diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml index d45202bd40..5acb29e748 100644 --- a/modules/gdscript/doc_classes/GDScript.xml +++ b/modules/gdscript/doc_classes/GDScript.xml @@ -8,7 +8,7 @@ [method new] creates a new instance of the script. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes. </description> <tutorials> - <link title="GDScript tutorial index">https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/index.html</link> + <link title="GDScript documentation index">$DOCS_URL/tutorials/scripting/gdscript/index.html</link> </tutorials> <methods> <method name="get_as_byte_code" qualifiers="const"> diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 6529154e5c..6425123e63 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -413,7 +413,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l previous_column = j; // ignore if just whitespace - if (text != "") { + if (!text.is_empty()) { previous_text = text; } } @@ -509,7 +509,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { for (const String &comment : comments) { String beg = comment.get_slice(" ", 0); String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String(); - add_color_region(beg, end, comment_color, end == ""); + add_color_region(beg, end, comment_color, end.is_empty()); } /* Strings */ @@ -519,7 +519,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { for (const String &string : strings) { String beg = string.get_slice(" ", 0); String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String(); - add_color_region(beg, end, string_color, end == ""); + add_color_region(beg, end, string_color, end.is_empty()); } const Ref<Script> script = _get_edited_resource(); diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h index 07f21b34ae..ac4995bee7 100644 --- a/modules/gdscript/editor/gdscript_highlighter.h +++ b/modules/gdscript/editor/gdscript_highlighter.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp index 9d0d91162c..a8f4483cf4 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h index caa80fc24c..e7b40aa367 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd b/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd new file mode 100644 index 0000000000..0824d894c5 --- /dev/null +++ b/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd @@ -0,0 +1,29 @@ +# meta-description: Classic movement for gravity games (platformer, ...) + +extends _BASE_ + +const SPEED: float = 300.0 +const JUMP_FORCE: float = -400.0 + +# Get the gravity from the project settings to be synced with RigidDynamicBody nodes. +var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity") + + +func _physics_process(delta: float) -> void: + # Add the gravity. + if not is_on_floor(): + motion_velocity.y += gravity * delta + + # Handle Jump. + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + motion_velocity.y = JUMP_FORCE + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var direction := Input.get_axis("ui_left", "ui_right") + if direction: + motion_velocity.x = direction * SPEED + else: + motion_velocity.x = move_toward(motion_velocity.x, 0, SPEED) + + move_and_slide() diff --git a/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd b/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd new file mode 100644 index 0000000000..ce6d67ae84 --- /dev/null +++ b/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd @@ -0,0 +1,32 @@ +# meta-description: Classic movement for gravity games (FPS, TPS, ...) + +extends _BASE_ + +const SPEED: float = 5.0 +const JUMP_FORCE: float = 4.5 + +# Get the gravity from the project settings to be synced with RigidDynamicBody nodes. +var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity") + + +func _physics_process(delta: float) -> void: + # Add the gravity. + if not is_on_floor(): + motion_velocity.y -= gravity * delta + + # Handle Jump. + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + motion_velocity.y = JUMP_FORCE + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() + if direction: + motion_velocity.x = direction.x * SPEED + motion_velocity.z = direction.z * SPEED + else: + motion_velocity.x = move_toward(motion_velocity.x, 0, SPEED) + motion_velocity.z = move_toward(motion_velocity.z, 0, SPEED) + + move_and_slide() diff --git a/modules/gdscript/editor_templates/EditorPlugin/plugin.gd b/modules/gdscript/editor_templates/EditorPlugin/plugin.gd new file mode 100644 index 0000000000..8614bb8b17 --- /dev/null +++ b/modules/gdscript/editor_templates/EditorPlugin/plugin.gd @@ -0,0 +1,11 @@ +# meta-description: Basic plugin template +@tool +extends EditorPlugin + +func _enter_tree() -> void: + # Initialization of the plugin goes here. + pass + +func _exit_tree() -> void: + # Clean-up of the plugin goes here. + pass diff --git a/modules/gdscript/editor_templates/EditorScript/basic_editor_script.gd b/modules/gdscript/editor_templates/EditorScript/basic_editor_script.gd new file mode 100644 index 0000000000..fdb174c7ed --- /dev/null +++ b/modules/gdscript/editor_templates/EditorScript/basic_editor_script.gd @@ -0,0 +1,7 @@ +# meta-description: Basic editor script template +@tool +extends EditorScript + +func _run() -> void: + # Called when the script is executed (using File -> Run in Script Editor). + pass diff --git a/modules/gdscript/editor_templates/Node/default.gd b/modules/gdscript/editor_templates/Node/default.gd new file mode 100644 index 0000000000..ee5c0b99cc --- /dev/null +++ b/modules/gdscript/editor_templates/Node/default.gd @@ -0,0 +1,11 @@ +# meta-description: Base template for Node with default Godot cycle methods + +extends _BASE_ + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + pass # Replace with function body. + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass diff --git a/modules/gdscript/editor_templates/Object/empty.gd b/modules/gdscript/editor_templates/Object/empty.gd new file mode 100644 index 0000000000..387786b0a4 --- /dev/null +++ b/modules/gdscript/editor_templates/Object/empty.gd @@ -0,0 +1,3 @@ +# meta-description: Empty template suitable for all Objects + +extends _BASE_ diff --git a/modules/gdscript/editor_templates/SCsub b/modules/gdscript/editor_templates/SCsub new file mode 100644 index 0000000000..2266ef2d01 --- /dev/null +++ b/modules/gdscript/editor_templates/SCsub @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +Import("env") + +import editor.template_builders as build_template_gd + +env["BUILDERS"]["MakeGDTemplateBuilder"] = Builder( + action=env.Run(build_template_gd.make_templates, "Generating GDScript templates header."), + suffix=".h", + src_suffix=".gd", +) + +# Template files +templates_sources = Glob("*/*.gd") + +env.Alias("editor_template_gd", [env.MakeGDTemplateBuilder("templates.gen.h", templates_sources)]) diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 2bae838543..6f7e913864 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -49,6 +49,10 @@ #include "tests/gdscript_test_runner.h" #endif +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif + /////////////////////////// GDScriptNativeClass::GDScriptNativeClass(const StringName &p_name) { @@ -361,7 +365,7 @@ ScriptInstance *GDScript::instance_create(Object *p_this) { if (top->native.is_valid()) { if (!ClassDB::is_parent_class(p_this->get_class_name(), top->native->get_name())) { if (EngineDebugger::is_active()) { - GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), 1, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instantiated in object of type: '" + p_this->get_class() + "'"); + GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), 1, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instantiated in object of type: '" + p_this->get_class() + "'"); } ERR_FAIL_V_MSG(nullptr, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instantiated in object of type '" + p_this->get_class() + "'" + "."); } @@ -389,7 +393,7 @@ bool GDScript::instance_has(const Object *p_this) const { } bool GDScript::has_source_code() const { - return source != ""; + return !source.is_empty(); } String GDScript::get_source_code() const { @@ -427,7 +431,7 @@ void GDScript::_add_doc(const DocData::ClassDoc &p_inner_class) { } else { for (int i = 0; i < docs.size(); i++) { if (docs[i].name == p_inner_class.name) { - docs.remove(i); + docs.remove_at(i); break; } } @@ -458,7 +462,7 @@ void GDScript::_update_doc() { doc.is_script_doc = true; if (base.is_valid() && base->is_valid()) { - if (base->doc.name != String()) { + if (!base->doc.name.is_empty()) { doc.inherits = base->doc.name; } else { doc.inherits = base->get_instance_base_type(); @@ -472,7 +476,7 @@ void GDScript::_update_doc() { doc.tutorials = doc_tutorials; for (const KeyValue<String, DocData::EnumDoc> &E : doc_enums) { - if (E.value.description != "") { + if (!E.value.description.is_empty()) { doc.enums[E.key] = E.value.description; } } @@ -545,7 +549,7 @@ void GDScript::_update_doc() { for (int i = 0; i < signals.size(); i++) { DocData::MethodDoc signal_doc; if (doc_signals.has(signals[i].name)) { - DocData::signal_doc_from_methodinfo(signal_doc, signals[i], signals[i].name); + DocData::signal_doc_from_methodinfo(signal_doc, signals[i], doc_signals[signals[i].name]); } else { DocData::signal_doc_from_methodinfo(signal_doc, signals[i], String()); } @@ -616,11 +620,11 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc String basedir = path; - if (basedir == "") { + if (basedir.is_empty()) { basedir = get_path(); } - if (basedir != "") { + if (!basedir.is_empty()) { basedir = basedir.get_base_dir(); } @@ -642,7 +646,7 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc path = c->extends_path; if (path.is_relative_path()) { String base = get_path(); - if (base == "" || base.is_relative_path()) { + if (base.is_empty() || base.is_relative_path()) { ERR_PRINT(("Could not resolve relative path for parent class: " + path).utf8().get_data()); } else { path = base.get_base_dir().plus_file(path); @@ -656,7 +660,7 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc } } - if (path != "") { + if (!path.is_empty()) { if (path != get_path()) { Ref<GDScript> bf = ResourceLoader::load(path); @@ -789,6 +793,14 @@ void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) { } } +String GDScript::_get_debug_path() const { + if (is_built_in() && !get_name().is_empty()) { + return get_name() + " (" + get_path().get_slice("::", 0) + ")"; + } else { + return get_path(); + } +} + Error GDScript::reload(bool p_keep_state) { bool has_instances; { @@ -801,18 +813,24 @@ Error GDScript::reload(bool p_keep_state) { String basedir = path; - if (basedir == "") { + if (basedir.is_empty()) { basedir = get_path(); } - if (basedir != "") { + if (!basedir.is_empty()) { basedir = basedir.get_base_dir(); } - if (source.find("%BASE%") != -1) { - //loading a template, don't parse +// Loading a template, don't parse. +#ifdef TOOLS_ENABLED + if (basedir.begins_with(EditorSettings::get_singleton()->get_project_script_templates_dir())) { + return OK; + } +#else + if (source.find("_BASE_") != -1) { return OK; } +#endif { String source_path = path; @@ -832,10 +850,10 @@ Error GDScript::reload(bool p_keep_state) { Error err = parser.parse(source, path, false); if (err) { if (EngineDebugger::is_active()) { - GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message); + GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message); } // TODO: Show all error messages. - _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT); ERR_FAIL_V(ERR_PARSE_ERROR); } @@ -844,12 +862,12 @@ Error GDScript::reload(bool p_keep_state) { if (err) { if (EngineDebugger::is_active()) { - GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message); + GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message); } const List<GDScriptParser::ParserError>::Element *e = parser.get_errors().front(); while (e != nullptr) { - _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT); e = e->next(); } ERR_FAIL_V(ERR_PARSE_ERROR); @@ -867,9 +885,9 @@ Error GDScript::reload(bool p_keep_state) { if (err) { if (can_run) { if (EngineDebugger::is_active()) { - GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error()); + GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error()); } - _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), false, ERR_HANDLER_SCRIPT); ERR_FAIL_V(ERR_COMPILATION_FAILED); } else { return err; @@ -879,7 +897,7 @@ Error GDScript::reload(bool p_keep_state) { for (const GDScriptWarning &warning : parser.get_warnings()) { if (EngineDebugger::is_active()) { Vector<ScriptLanguage::StackInfo> si; - EngineDebugger::get_script_debugger()->send_error("", get_path(), warning.start_line, warning.get_name(), warning.get_message(), ERR_HANDLER_WARNING, si); + EngineDebugger::get_script_debugger()->send_error("", get_path(), warning.start_line, warning.get_name(), warning.get_message(), false, ERR_HANDLER_WARNING, si); } } #endif @@ -979,7 +997,7 @@ bool GDScript::_set(const StringName &p_name, const Variant &p_value) { } void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const { - p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); + p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); } void GDScript::_bind_methods() { @@ -1114,7 +1132,7 @@ String GDScript::_get_gdscript_reference_class_name(const GDScript *p_gdscript) String class_name; while (p_gdscript) { - if (class_name == "") { + if (class_name.is_empty()) { class_name = p_gdscript->get_script_class_name(); } else { class_name = p_gdscript->get_script_class_name() + "." + class_name; @@ -1257,6 +1275,8 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { call(member->setter, &val, 1, err); if (err.error == Callable::CallError::CALL_OK) { return true; //function exists, call was successful + } else { + return false; } } else { if (member->data_type.has_type) { @@ -1423,7 +1443,7 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const pinfo.type = Variant::Type(d["type"].operator int()); ERR_CONTINUE(pinfo.type < 0 || pinfo.type >= Variant::VARIANT_MAX); pinfo.name = d["name"]; - ERR_CONTINUE(pinfo.name == ""); + ERR_CONTINUE(pinfo.name.is_empty()); if (d.has("hint")) { pinfo.hint = PropertyHint(d["hint"].operator int()); } @@ -2040,15 +2060,15 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { bool GDScriptLanguage::is_control_flow_keyword(String p_keyword) const { return p_keyword == "break" || - p_keyword == "continue" || - p_keyword == "elif" || - p_keyword == "else" || - p_keyword == "if" || - p_keyword == "for" || - p_keyword == "match" || - p_keyword == "pass" || - p_keyword == "return" || - p_keyword == "while"; + p_keyword == "continue" || + p_keyword == "elif" || + p_keyword == "else" || + p_keyword == "if" || + p_keyword == "for" || + p_keyword == "match" || + p_keyword == "pass" || + p_keyword == "return" || + p_keyword == "while"; } bool GDScriptLanguage::handles_global_class_type(const String &p_type) const { @@ -2121,7 +2141,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b const GDScriptParser::ClassNode *inner_class = subclass->members[i].m_class; if (inner_class->identifier->name == extend_classes[0]) { - extend_classes.remove(0); + extend_classes.remove_at(0); found = true; subclass = inner_class; break; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 791f8a1431..2b43e6d21b 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -135,6 +135,7 @@ class GDScript : public Script { GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_is_ref_counted, Callable::CallError &r_error); void _set_subclass_path(Ref<GDScript> &p_sc, const String &p_path); + String _get_debug_path() const; #ifdef TOOLS_ENABLED Set<PlaceHolderScriptInstance *> placeholders; @@ -395,7 +396,7 @@ public: _debug_call_stack_pos--; } - virtual Vector<StackInfo> debug_get_current_stack_info() { + virtual Vector<StackInfo> debug_get_current_stack_info() override { if (Thread::get_main_id() != Thread::get_caller_id()) { return Vector<StackInfo>(); } @@ -429,77 +430,76 @@ public: _FORCE_INLINE_ static GDScriptLanguage *get_singleton() { return singleton; } - virtual String get_name() const; + virtual String get_name() const override; /* LANGUAGE FUNCTIONS */ - virtual void init(); - virtual String get_type() const; - virtual String get_extension() const; - virtual Error execute_file(const String &p_path); - virtual void finish(); + virtual void init() override; + virtual String get_type() const override; + virtual String get_extension() const override; + virtual Error execute_file(const String &p_path) override; + virtual void finish() override; /* EDITOR FUNCTIONS */ - virtual void get_reserved_words(List<String> *p_words) const; - virtual bool is_control_flow_keyword(String p_keywords) const; - virtual void get_comment_delimiters(List<String> *p_delimiters) const; - virtual void get_string_delimiters(List<String> *p_delimiters) const; - virtual String _get_processed_template(const String &p_template, const String &p_base_class_name) const; - virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const; - virtual bool is_using_templates(); - virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script); - virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const; - virtual Script *create_script() const; - virtual bool has_named_classes() const; - virtual bool supports_builtin_mode() const; - virtual bool supports_documentation() const; - virtual bool can_inherit_from_file() const { return true; } - virtual int find_function(const String &p_function, const String &p_code) const; - virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const; - virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint); + virtual void get_reserved_words(List<String> *p_words) const override; + virtual bool is_control_flow_keyword(String p_keywords) const override; + virtual void get_comment_delimiters(List<String> *p_delimiters) const override; + virtual void get_string_delimiters(List<String> *p_delimiters) const override; + virtual bool is_using_templates() override; + virtual Ref<Script> make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const override; + virtual Vector<ScriptTemplate> get_built_in_templates(StringName p_object) override; + virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override; + virtual Script *create_script() const override; + virtual bool has_named_classes() const override; + virtual bool supports_builtin_mode() const override; + virtual bool supports_documentation() const override; + virtual bool can_inherit_from_file() const override { return true; } + virtual int find_function(const String &p_function, const String &p_code) const override; + virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const override; + virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) override; #ifdef TOOLS_ENABLED - virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result); + virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) override; #endif virtual String _get_indentation() const; - virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const; - virtual void add_global_constant(const StringName &p_variable, const Variant &p_value); - virtual void add_named_global_constant(const StringName &p_name, const Variant &p_value); - virtual void remove_named_global_constant(const StringName &p_name); + virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override; + virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) override; + virtual void add_named_global_constant(const StringName &p_name, const Variant &p_value) override; + virtual void remove_named_global_constant(const StringName &p_name) override; /* DEBUGGER FUNCTIONS */ - virtual String debug_get_error() const; - virtual int debug_get_stack_level_count() const; - virtual int debug_get_stack_level_line(int p_level) const; - virtual String debug_get_stack_level_function(int p_level) const; - virtual String debug_get_stack_level_source(int p_level) const; - virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1); - virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1); - virtual ScriptInstance *debug_get_stack_level_instance(int p_level); - virtual void debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1); - virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1); + virtual String debug_get_error() const override; + virtual int debug_get_stack_level_count() const override; + virtual int debug_get_stack_level_line(int p_level) const override; + virtual String debug_get_stack_level_function(int p_level) const override; + virtual String debug_get_stack_level_source(int p_level) const override; + virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; + virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; + virtual ScriptInstance *debug_get_stack_level_instance(int p_level) override; + virtual void debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; + virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1) override; - virtual void reload_all_scripts(); - virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload); + virtual void reload_all_scripts() override; + virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) override; - virtual void frame(); + virtual void frame() override; - virtual void get_public_functions(List<MethodInfo> *p_functions) const; - virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const; + virtual void get_public_functions(List<MethodInfo> *p_functions) const override; + virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override; - virtual void profiling_start(); - virtual void profiling_stop(); + virtual void profiling_start() override; + virtual void profiling_stop() override; - virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max); - virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max); + virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override; + virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override; /* LOADER FUNCTIONS */ - virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; /* GLOBAL CLASSES */ - virtual bool handles_global_class_type(const String &p_type) const; - virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const; + virtual bool handles_global_class_type(const String &p_type) const override; + virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const override; void add_orphan_subclass(const String &p_qualified_name, const ObjectID &p_subclass); Ref<GDScript> get_orphan_subclass(const String &p_qualified_name); diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index c07849bfa8..0bf4f5e1f1 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -244,6 +244,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class, class_type.kind = GDScriptParser::DataType::CLASS; class_type.class_type = p_class; class_type.script_path = parser->script_path; + class_type.builtin_type = Variant::OBJECT; p_class->set_datatype(class_type); if (!p_class->extends_used) { @@ -469,6 +470,8 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type GDScriptParser::DataType container_type = resolve_datatype(p_type->container_type); if (container_type.kind != GDScriptParser::DataType::VARIANT) { + container_type.is_meta_type = false; + container_type.is_constant = false; result.set_container_element_type(container_type); } } @@ -481,7 +484,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type result = parser->head->get_datatype(); } else { Ref<GDScriptParserRef> ref = get_parser_for(ScriptServer::get_global_class_path(first)); - if (ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED) != OK) { + if (!ref.is_valid() || ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED) != OK) { push_error(vformat(R"(Could not parse global class "%s" from "%s".)", first, ScriptServer::get_global_class_path(first)), p_type); return GDScriptParser::DataType(); } @@ -874,18 +877,45 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class) { GDScriptParser::ClassNode *previous_class = parser->current_class; parser->current_class = p_class; - // Do functions now. + // Do functions and properties now. for (int i = 0; i < p_class->members.size(); i++) { GDScriptParser::ClassNode::Member member = p_class->members[i]; - if (member.type != GDScriptParser::ClassNode::Member::FUNCTION) { - continue; - } + if (member.type == GDScriptParser::ClassNode::Member::FUNCTION) { + // Apply annotations. + for (GDScriptParser::AnnotationNode *&E : member.function->annotations) { + E->apply(parser, member.function); + } + +#ifdef DEBUG_ENABLED + Set<uint32_t> previously_ignored = parser->ignored_warning_codes; + for (uint32_t ignored_warning : member.function->ignored_warnings) { + parser->ignored_warning_codes.insert(ignored_warning); + } +#endif // DEBUG_ENABLED - resolve_function_body(member.function); + resolve_function_body(member.function); + +#ifdef DEBUG_ENABLED + parser->ignored_warning_codes = previously_ignored; +#endif // DEBUG_ENABLED + } else if (member.type == GDScriptParser::ClassNode::Member::VARIABLE && member.variable->property != GDScriptParser::VariableNode::PROP_NONE) { + if (member.variable->property == GDScriptParser::VariableNode::PROP_INLINE) { + if (member.variable->getter != nullptr) { + member.variable->getter->set_datatype(member.variable->datatype); + + resolve_function_body(member.variable->getter); + } + if (member.variable->setter != nullptr) { + resolve_function_signature(member.variable->setter); + + if (member.variable->setter->parameters.size() > 0) { + member.variable->setter->parameters[0]->datatype_specifier = member.variable->datatype_specifier; + member.variable->setter->parameters[0]->set_datatype(member.get_datatype()); + } - // Apply annotations. - for (GDScriptParser::AnnotationNode *&E : member.function->annotations) { - E->apply(parser, member.function); + resolve_function_body(member.variable->setter); + } + } } } @@ -901,17 +931,87 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class) { resolve_class_body(member.m_class); } - // Check unused variables. + // Check unused variables and datatypes of property getters and setters. for (int i = 0; i < p_class->members.size(); i++) { GDScriptParser::ClassNode::Member member = p_class->members[i]; - if (member.type != GDScriptParser::ClassNode::Member::VARIABLE) { - continue; - } + if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) { #ifdef DEBUG_ENABLED - if (member.variable->usages == 0 && String(member.variable->identifier->name).begins_with("_")) { - parser->push_warning(member.variable->identifier, GDScriptWarning::UNUSED_PRIVATE_CLASS_VARIABLE, member.variable->identifier->name); - } + Set<uint32_t> previously_ignored = parser->ignored_warning_codes; + for (uint32_t ignored_warning : member.function->ignored_warnings) { + parser->ignored_warning_codes.insert(ignored_warning); + } + if (member.variable->usages == 0 && String(member.variable->identifier->name).begins_with("_")) { + parser->push_warning(member.variable->identifier, GDScriptWarning::UNUSED_PRIVATE_CLASS_VARIABLE, member.variable->identifier->name); + } #endif + + if (member.variable->property == GDScriptParser::VariableNode::PROP_SETGET) { + GDScriptParser::FunctionNode *getter_function = nullptr; + GDScriptParser::FunctionNode *setter_function = nullptr; + + bool has_valid_getter = false; + bool has_valid_setter = false; + + if (member.variable->getter_pointer != nullptr) { + if (p_class->has_function(member.variable->getter_pointer->name)) { + getter_function = p_class->get_member(member.variable->getter_pointer->name).function; + } + + if (getter_function == nullptr) { + push_error(vformat(R"(Getter "%s" not found.)", member.variable->getter_pointer->name), member.variable); + + } else if (getter_function->parameters.size() != 0 || getter_function->datatype.has_no_type()) { + push_error(vformat(R"(Function "%s" cannot be used as getter because of its signature.)", getter_function->identifier->name), member.variable); + + } else if (!is_type_compatible(member.variable->datatype, getter_function->datatype, true)) { + push_error(vformat(R"(Function with return type "%s" cannot be used as getter for a property of type "%s".)", getter_function->datatype.to_string(), member.variable->datatype.to_string()), member.variable); + + } else { + has_valid_getter = true; + +#ifdef DEBUG_ENABLED + if (member.variable->datatype.builtin_type == Variant::INT && getter_function->datatype.builtin_type == Variant::FLOAT) { + parser->push_warning(member.variable, GDScriptWarning::NARROWING_CONVERSION); + } +#endif + } + } + + if (member.variable->setter_pointer != nullptr) { + if (p_class->has_function(member.variable->setter_pointer->name)) { + setter_function = p_class->get_member(member.variable->setter_pointer->name).function; + } + + if (setter_function == nullptr) { + push_error(vformat(R"(Setter "%s" not found.)", member.variable->setter_pointer->name), member.variable); + + } else if (setter_function->parameters.size() != 1) { + push_error(vformat(R"(Function "%s" cannot be used as setter because of its signature.)", setter_function->identifier->name), member.variable); + + } else if (!is_type_compatible(member.variable->datatype, setter_function->parameters[0]->datatype, true)) { + push_error(vformat(R"(Function with argument type "%s" cannot be used as setter for a property of type "%s".)", setter_function->parameters[0]->datatype.to_string(), member.variable->datatype.to_string()), member.variable); + + } else { + has_valid_setter = true; + +#ifdef DEBUG_ENABLED + if (member.variable->datatype.builtin_type == Variant::FLOAT && setter_function->parameters[0]->datatype.builtin_type == Variant::INT) { + parser->push_warning(member.variable, GDScriptWarning::NARROWING_CONVERSION); + } +#endif + } + } + + if (member.variable->datatype.is_variant() && has_valid_getter && has_valid_setter) { + if (!is_type_compatible(getter_function->datatype, setter_function->parameters[0]->datatype, true)) { + push_error(vformat(R"(Getter with type "%s" cannot be used along with setter of type "%s".)", getter_function->datatype.to_string(), setter_function->parameters[0]->datatype.to_string()), member.variable); + } + } +#ifdef DEBUG_ENABLED + parser->ignored_warning_codes = previously_ignored; +#endif // DEBUG_ENABLED + } + } } } @@ -988,7 +1088,7 @@ void GDScriptAnalyzer::resolve_node(GDScriptParser::Node *p_node) { case GDScriptParser::Node::SUBSCRIPT: case GDScriptParser::Node::TERNARY_OPERATOR: case GDScriptParser::Node::UNARY_OPERATOR: - reduce_expression(static_cast<GDScriptParser::ExpressionNode *>(p_node)); + reduce_expression(static_cast<GDScriptParser::ExpressionNode *>(p_node), true); break; case GDScriptParser::Node::BREAK: case GDScriptParser::Node::BREAKPOINT: @@ -1104,7 +1204,23 @@ void GDScriptAnalyzer::decide_suite_type(GDScriptParser::Node *p_suite, GDScript void GDScriptAnalyzer::resolve_suite(GDScriptParser::SuiteNode *p_suite) { for (int i = 0; i < p_suite->statements.size(); i++) { GDScriptParser::Node *stmt = p_suite->statements[i]; + for (GDScriptParser::AnnotationNode *&annotation : stmt->annotations) { + annotation->apply(parser, stmt); + } + +#ifdef DEBUG_ENABLED + Set<uint32_t> previously_ignored = parser->ignored_warning_codes; + for (uint32_t ignored_warning : stmt->ignored_warnings) { + parser->ignored_warning_codes.insert(ignored_warning); + } +#endif // DEBUG_ENABLED + resolve_node(stmt); + +#ifdef DEBUG_ENABLED + parser->ignored_warning_codes = previously_ignored; +#endif // DEBUG_ENABLED + decide_suite_type(p_suite, stmt); } } @@ -1528,12 +1644,20 @@ void GDScriptAnalyzer::resolve_parameter(GDScriptParser::ParameterNode *p_parame void GDScriptAnalyzer::resolve_return(GDScriptParser::ReturnNode *p_return) { GDScriptParser::DataType result; + GDScriptParser::DataType expected_type; + bool has_expected_type = false; + + if (parser->current_function != nullptr) { + expected_type = parser->current_function->get_datatype(); + has_expected_type = true; + } + if (p_return->return_value != nullptr) { reduce_expression(p_return->return_value); if (p_return->return_value->type == GDScriptParser::Node::ARRAY) { // Check if assigned value is an array literal, so we can make it a typed array too if appropriate. - if (parser->current_function->get_datatype().has_container_element_type() && p_return->return_value->type == GDScriptParser::Node::ARRAY) { - update_array_literal_element_type(parser->current_function->get_datatype(), static_cast<GDScriptParser::ArrayNode *>(p_return->return_value)); + if (has_expected_type && expected_type.has_container_element_type() && p_return->return_value->type == GDScriptParser::Node::ARRAY) { + update_array_literal_element_type(expected_type, static_cast<GDScriptParser::ArrayNode *>(p_return->return_value)); } } result = p_return->return_value->get_datatype(); @@ -1545,30 +1669,31 @@ void GDScriptAnalyzer::resolve_return(GDScriptParser::ReturnNode *p_return) { result.is_constant = true; } - GDScriptParser::DataType function_type = parser->current_function->get_datatype(); - function_type.is_meta_type = false; - if (function_type.is_hard_type()) { - if (!is_type_compatible(function_type, result)) { - // Try other way. Okay but not safe. - if (!is_type_compatible(result, function_type)) { - push_error(vformat(R"(Cannot return value of type "%s" because the function return type is "%s".)", result.to_string(), function_type.to_string()), p_return); - } else { - // TODO: Add warning. - mark_node_unsafe(p_return); - } + if (has_expected_type) { + expected_type.is_meta_type = false; + if (expected_type.is_hard_type()) { + if (!is_type_compatible(expected_type, result)) { + // Try other way. Okay but not safe. + if (!is_type_compatible(result, expected_type)) { + push_error(vformat(R"(Cannot return value of type "%s" because the function return type is "%s".)", result.to_string(), expected_type.to_string()), p_return); + } else { + // TODO: Add warning. + mark_node_unsafe(p_return); + } #ifdef DEBUG_ENABLED - } else if (function_type.builtin_type == Variant::INT && result.builtin_type == Variant::FLOAT) { - parser->push_warning(p_return, GDScriptWarning::NARROWING_CONVERSION); - } else if (result.is_variant()) { - mark_node_unsafe(p_return); + } else if (expected_type.builtin_type == Variant::INT && result.builtin_type == Variant::FLOAT) { + parser->push_warning(p_return, GDScriptWarning::NARROWING_CONVERSION); + } else if (result.is_variant()) { + mark_node_unsafe(p_return); #endif + } } } p_return->set_datatype(result); } -void GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode *p_expression) { +void GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode *p_expression, bool p_is_root) { // This one makes some magic happen. if (p_expression == nullptr) { @@ -1596,7 +1721,7 @@ void GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode *p_expre reduce_binary_op(static_cast<GDScriptParser::BinaryOpNode *>(p_expression)); break; case GDScriptParser::Node::CALL: - reduce_call(static_cast<GDScriptParser::CallNode *>(p_expression)); + reduce_call(static_cast<GDScriptParser::CallNode *>(p_expression), p_is_root); break; case GDScriptParser::Node::CAST: reduce_cast(static_cast<GDScriptParser::CastNode *>(p_expression)); @@ -1712,6 +1837,7 @@ void GDScriptAnalyzer::update_array_literal_element_type(const GDScriptParser::D } } if (all_same_type) { + element_type.is_constant = false; array_type.set_container_element_type(element_type); } else if (all_have_type) { push_error(vformat(R"(Variant array is not compatible with an array of type "%s".)", p_base_type.get_container_element_type().to_string()), p_array_literal); @@ -1742,7 +1868,7 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig push_error("Cannot assign a new value to a constant.", p_assignment->assignee); } - if (!assignee_type.is_variant() && !assigned_value_type.is_variant()) { + if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) { bool compatible = true; GDScriptParser::DataType op_type = assigned_value_type; if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { @@ -1794,27 +1920,24 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig case GDScriptParser::IdentifierNode::FUNCTION_PARAMETER: { GDScriptParser::DataType id_type = identifier->parameter_source->get_datatype(); if (!id_type.is_hard_type()) { - id_type = assigned_value_type; - id_type.type_source = GDScriptParser::DataType::INFERRED; - id_type.is_constant = false; + id_type.kind = GDScriptParser::DataType::VARIANT; + id_type.type_source = GDScriptParser::DataType::UNDETECTED; identifier->parameter_source->set_datatype(id_type); } } break; case GDScriptParser::IdentifierNode::LOCAL_VARIABLE: { GDScriptParser::DataType id_type = identifier->variable_source->get_datatype(); if (!id_type.is_hard_type()) { - id_type = assigned_value_type; - id_type.type_source = GDScriptParser::DataType::INFERRED; - id_type.is_constant = false; + id_type.kind = GDScriptParser::DataType::VARIANT; + id_type.type_source = GDScriptParser::DataType::UNDETECTED; identifier->variable_source->set_datatype(id_type); } } break; case GDScriptParser::IdentifierNode::LOCAL_ITERATOR: { GDScriptParser::DataType id_type = identifier->bind_source->get_datatype(); if (!id_type.is_hard_type()) { - id_type = assigned_value_type; - id_type.type_source = GDScriptParser::DataType::INFERRED; - id_type.is_constant = false; + id_type.kind = GDScriptParser::DataType::VARIANT; + id_type.type_source = GDScriptParser::DataType::UNDETECTED; identifier->variable_source->set_datatype(id_type); } } break; @@ -1840,16 +1963,25 @@ void GDScriptAnalyzer::reduce_await(GDScriptParser::AwaitNode *p_await) { p_await->set_datatype(await_type); return; } + + GDScriptParser::DataType awaiting_type; + if (p_await->to_await->type == GDScriptParser::Node::CALL) { reduce_call(static_cast<GDScriptParser::CallNode *>(p_await->to_await), true); + awaiting_type = p_await->to_await->get_datatype(); } else { reduce_expression(p_await->to_await); } - p_await->is_constant = p_await->to_await->is_constant; - p_await->reduced_value = p_await->to_await->reduced_value; + if (p_await->to_await->is_constant) { + p_await->is_constant = p_await->to_await->is_constant; + p_await->reduced_value = p_await->to_await->reduced_value; - GDScriptParser::DataType awaiting_type = p_await->to_await->get_datatype(); + awaiting_type = p_await->to_await->get_datatype(); + } else { + awaiting_type.kind = GDScriptParser::DataType::VARIANT; + awaiting_type.type_source = GDScriptParser::DataType::UNDETECTED; + } p_await->set_datatype(awaiting_type); @@ -1969,7 +2101,7 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o p_binary_op->set_datatype(result); } -void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_await) { +void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_await, bool p_is_root) { bool all_is_constant = true; Map<int, GDScriptParser::ArrayNode *> arrays; // For array literal to potentially type when passing. for (int i = 0; i < p_call->arguments.size(); i++) { @@ -2328,7 +2460,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa } } - if (call_type.is_coroutine && !is_await) { + if (call_type.is_coroutine && !p_is_await && !p_is_root) { push_error(vformat(R"*(Function "%s()" is a coroutine, so it must be called with "await".)*", p_call->function_name), p_call->callee); } @@ -2596,6 +2728,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod p_identifier->is_constant = false; return; } break; + case GDScriptParser::ClassNode::Member::CLASS: { + resolve_class_interface(member.m_class); + p_identifier->set_datatype(member.m_class->get_datatype()); + return; + } break; default: break; } @@ -2610,10 +2747,13 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod const StringName &native = base.native_type; if (class_exists(native)) { - PropertyInfo prop_info; MethodInfo method_info; - if (ClassDB::get_property_info(native, name, &prop_info)) { - p_identifier->set_datatype(type_from_property(prop_info)); + if (ClassDB::has_property(native, name)) { + StringName getter_name = ClassDB::get_property_getter(native, name); + MethodBind *getter = ClassDB::get_method(native, getter_name); + if (getter != nullptr) { + p_identifier->set_datatype(type_from_property(getter->get_return_info())); + } return; } if (ClassDB::get_method_info(native, name, &method_info)) { @@ -2895,7 +3035,7 @@ void GDScriptAnalyzer::reduce_preload(GDScriptParser::PreloadNode *p_preload) { // TODO: Don't load if validating: use completion cache. p_preload->resource = ResourceLoader::load(p_preload->resolved_path); if (p_preload->resource.is_null()) { - push_error(vformat(R"(Could not p_preload resource file "%s".)", p_preload->resolved_path), p_preload->path); + push_error(vformat(R"(Could not preload resource file "%s".)", p_preload->resolved_path), p_preload->path); } } } @@ -2941,7 +3081,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri } else { GDScriptParser::DataType base_type = p_subscript->base->get_datatype(); - if (base_type.is_variant()) { + if (base_type.is_variant() || !base_type.is_hard_type()) { result_type.kind = GDScriptParser::DataType::VARIANT; mark_node_unsafe(p_subscript); } else { @@ -3064,6 +3204,9 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri result_type.kind = GDScriptParser::DataType::BUILTIN; result_type.type_source = base_type.is_hard_type() ? GDScriptParser::DataType::ANNOTATED_INFERRED : GDScriptParser::DataType::INFERRED; + if (base_type.kind != GDScriptParser::DataType::BUILTIN) { + base_type.builtin_type = Variant::OBJECT; + } switch (base_type.builtin_type) { // Can't index at all. case Variant::RID: @@ -3124,6 +3267,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::PLANE: case Variant::COLOR: case Variant::DICTIONARY: + case Variant::OBJECT: result_type.kind = GDScriptParser::DataType::VARIANT; result_type.type_source = GDScriptParser::DataType::UNDETECTED; break; @@ -3138,7 +3282,6 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri } break; // Here for completeness. - case Variant::OBJECT: case Variant::VARIANT_MAX: break; } @@ -3391,6 +3534,7 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo } else { ERR_FAIL_V_MSG(result, "Could not find element type from property hint of a typed array."); } + elem_type.is_constant = false; result.set_container_element_type(elem_type); } } @@ -3581,9 +3725,27 @@ bool GDScriptAnalyzer::validate_call_arg(const List<GDScriptParser::DataType> &p bool GDScriptAnalyzer::is_shadowing(GDScriptParser::IdentifierNode *p_local, const String &p_context) { const StringName &name = p_local->name; GDScriptParser::DataType base = parser->current_class->get_datatype(); - GDScriptParser::ClassNode *base_class = base.class_type; + { + List<MethodInfo> gdscript_funcs; + GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs); + + for (MethodInfo &info : gdscript_funcs) { + if (info.name == name) { + parser->push_warning(p_local, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, p_context, name, "built-in function"); + return true; + } + } + if (Variant::has_utility_function(name)) { + parser->push_warning(p_local, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, p_context, name, "built-in function"); + return true; + } else if (ClassDB::class_exists(name)) { + parser->push_warning(p_local, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, p_context, name, "global class"); + return true; + } + } + while (base_class != nullptr) { if (base_class->has_member(name)) { parser->push_warning(p_local, GDScriptWarning::SHADOWED_VARIABLE, p_context, p_local->name, base_class->get_member(name).get_type_name(), itos(base_class->get_member(name).get_line())); @@ -3828,7 +3990,9 @@ Ref<GDScriptParserRef> GDScriptAnalyzer::get_parser_for(const String &p_path) { } else { Error err = OK; ref = GDScriptCache::get_parser(p_path, GDScriptParserRef::EMPTY, err, parser->script_path); - depended_parsers[p_path] = ref; + if (ref.is_valid()) { + depended_parsers[p_path] = ref; + } } return ref; diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h index 2e17e15452..4cee5cb44a 100644 --- a/modules/gdscript/gdscript_analyzer.h +++ b/modules/gdscript/gdscript_analyzer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -78,12 +78,12 @@ class GDScriptAnalyzer { void resolve_return(GDScriptParser::ReturnNode *p_return); // Reduction functions. - void reduce_expression(GDScriptParser::ExpressionNode *p_expression); + void reduce_expression(GDScriptParser::ExpressionNode *p_expression, bool p_is_root = false); void reduce_array(GDScriptParser::ArrayNode *p_array); void reduce_assignment(GDScriptParser::AssignmentNode *p_assignment); void reduce_await(GDScriptParser::AwaitNode *p_await); void reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_op); - void reduce_call(GDScriptParser::CallNode *p_call, bool is_await = false); + void reduce_call(GDScriptParser::CallNode *p_call, bool p_is_await = false, bool p_is_root = false); void reduce_cast(GDScriptParser::CastNode *p_cast); void reduce_dictionary(GDScriptParser::DictionaryNode *p_dictionary); void reduce_get_node(GDScriptParser::GetNodeNode *p_get_node); diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index b8300cd872..8623122edc 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -692,7 +692,8 @@ void GDScriptByteCodeGenerator::write_end_ternary() { void GDScriptByteCodeGenerator::write_set(const Address &p_target, const Address &p_index, const Address &p_source) { if (HAS_BUILTIN_TYPE(p_target)) { - if (IS_BUILTIN_TYPE(p_index, Variant::INT) && Variant::get_member_validated_indexed_setter(p_target.type.builtin_type)) { + if (IS_BUILTIN_TYPE(p_index, Variant::INT) && Variant::get_member_validated_indexed_setter(p_target.type.builtin_type) && + IS_BUILTIN_TYPE(p_source, Variant::get_indexed_element_type(p_target.type.builtin_type))) { // Use indexed setter instead. Variant::ValidatedIndexedSetter setter = Variant::get_member_validated_indexed_setter(p_target.type.builtin_type); append(GDScriptFunction::OPCODE_SET_INDEXED_VALIDATED, 3); @@ -746,7 +747,8 @@ void GDScriptByteCodeGenerator::write_get(const Address &p_target, const Address } void GDScriptByteCodeGenerator::write_set_named(const Address &p_target, const StringName &p_name, const Address &p_source) { - if (HAS_BUILTIN_TYPE(p_target) && Variant::get_member_validated_setter(p_target.type.builtin_type, p_name)) { + if (HAS_BUILTIN_TYPE(p_target) && Variant::get_member_validated_setter(p_target.type.builtin_type, p_name) && + IS_BUILTIN_TYPE(p_source, Variant::get_member_type(p_target.type.builtin_type, p_name))) { Variant::ValidatedSetter setter = Variant::get_member_validated_setter(p_target.type.builtin_type, p_name); append(GDScriptFunction::OPCODE_SET_NAMED_VALIDATED, 2); append(p_target); diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index fbbf5802fd..db15dc55ef 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 8121053245..4ac5a4a60e 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -58,27 +58,27 @@ Error GDScriptParserRef::raise_status(Status p_new_status) { while (p_new_status > status) { switch (status) { case EMPTY: - result = parser->parse(GDScriptCache::get_source_code(path), path, false); status = PARSED; + result = parser->parse(GDScriptCache::get_source_code(path), path, false); break; case PARSED: { analyzer = memnew(GDScriptAnalyzer(parser)); - Error inheritance_result = analyzer->resolve_inheritance(); status = INHERITANCE_SOLVED; + Error inheritance_result = analyzer->resolve_inheritance(); if (result == OK) { result = inheritance_result; } } break; case INHERITANCE_SOLVED: { - Error interface_result = analyzer->resolve_interface(); status = INTERFACE_SOLVED; + Error interface_result = analyzer->resolve_interface(); if (result == OK) { result = interface_result; } } break; case INTERFACE_SOLVED: { - Error body_result = analyzer->resolve_body(); status = FULLY_SOLVED; + Error body_result = analyzer->resolve_body(); if (result == OK) { result = body_result; } @@ -117,7 +117,7 @@ void GDScriptCache::remove_script(const String &p_path) { Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptParserRef::Status p_status, Error &r_error, const String &p_owner) { MutexLock lock(singleton->lock); Ref<GDScriptParserRef> ref; - if (p_owner != String()) { + if (!p_owner.is_empty()) { singleton->dependencies[p_owner].insert(p_path); } if (singleton->parser_map.has(p_path)) { @@ -163,7 +163,7 @@ String GDScriptCache::get_source_code(const String &p_path) { Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const String &p_owner) { MutexLock lock(singleton->lock); - if (p_owner != String()) { + if (!p_owner.is_empty()) { singleton->dependencies[p_owner].insert(p_path); } if (singleton->full_gdscript_cache.has(p_path)) { @@ -186,7 +186,7 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const Stri Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner) { MutexLock lock(singleton->lock); - if (p_owner != String()) { + if (!p_owner.is_empty()) { singleton->dependencies[p_owner].insert(p_path); } diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h index 9fb661d031..3ce976ee14 100644 --- a/modules/gdscript/gdscript_cache.h +++ b/modules/gdscript/gdscript_cache.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index e6ecc92d55..4542dd94ae 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 9eee0b57f3..af5ada513c 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -65,7 +65,7 @@ bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringNa } void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::Node *p_node) { - if (error != "") { + if (!error.is_empty()) { return; } @@ -109,7 +109,9 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D // Locate class by constructing the path to it and following that path GDScriptParser::ClassNode *class_type = p_datatype.class_type; if (class_type) { - if ((!main_script->path.is_empty() && class_type->fqcn.begins_with(main_script->path)) || (!main_script->name.is_empty() && class_type->fqcn.begins_with(main_script->name))) { + const bool is_inner_by_path = (!main_script->path.is_empty()) && (class_type->fqcn.split("::")[0] == main_script->path); + const bool is_inner_by_name = (!main_script->name.is_empty()) && (class_type->fqcn.split("::")[0] == main_script->name); + if (is_inner_by_path || is_inner_by_name) { // Local class. List<StringName> names; while (class_type->outer) { @@ -486,6 +488,9 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression); GDScriptDataType type = _gdtype_from_datatype(call->get_datatype()); GDScriptCodeGenerator::Address result = codegen.add_temporary(type); + GDScriptCodeGenerator::Address nil = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::NIL); + + GDScriptCodeGenerator::Address return_addr = p_root ? nil : result; Vector<GDScriptCodeGenerator::Address> arguments; for (int i = 0; i < call->arguments.size(); i++) { @@ -536,13 +541,13 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code if (within_await) { gen->write_call_async(result, self, call->function_name, arguments); } else { - gen->write_call(result, self, call->function_name, arguments); + gen->write_call(return_addr, self, call->function_name, arguments); } } else { if (within_await) { gen->write_call_self_async(result, call->function_name, arguments); } else { - gen->write_call_self(result, call->function_name, arguments); + gen->write_call_self(return_addr, call->function_name, arguments); } } } else if (callee->type == GDScriptParser::Node::SUBSCRIPT) { @@ -577,12 +582,12 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code gen->write_call_method_bind(result, base, method, arguments); } } else { - gen->write_call(result, base, call->function_name, arguments); + gen->write_call(return_addr, base, call->function_name, arguments); } } else if (base.type.has_type && base.type.kind == GDScriptDataType::BUILTIN) { gen->write_call_builtin_type(result, base, base.type.builtin_type, call->function_name, arguments); } else { - gen->write_call(result, base, call->function_name, arguments); + gen->write_call(return_addr, base, call->function_name, arguments); } if (base.mode == GDScriptCodeGenerator::Address::TEMPORARY) { gen->pop_temporary(); @@ -2015,7 +2020,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ if (EngineDebugger::is_active()) { String signature; // Path. - if (p_script->get_path() != String()) { + if (!p_script->get_path().is_empty()) { signature += p_script->get_path(); } // Location. @@ -2087,77 +2092,18 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::VariableNode *p_variable, bool p_is_setter) { Error error = OK; - CodeGen codegen; - codegen.generator = memnew(GDScriptByteCodeGenerator); - - codegen.class_node = p_class; - codegen.script = p_script; - StringName func_name; + GDScriptParser::FunctionNode *function; if (p_is_setter) { - func_name = "@" + p_variable->identifier->name + "_setter"; + function = p_variable->setter; } else { - func_name = "@" + p_variable->identifier->name + "_getter"; + function = p_variable->getter; } - codegen.function_name = func_name; + _parse_function(error, p_script, p_class, function); - GDScriptDataType return_type; - if (p_is_setter) { - return_type.has_type = true; - return_type.kind = GDScriptDataType::BUILTIN; - return_type.builtin_type = Variant::NIL; - } else { - return_type = _gdtype_from_datatype(p_variable->get_datatype(), p_script); - } - - codegen.generator->write_start(p_script, func_name, false, Multiplayer::RPCConfig(), return_type); - - if (p_is_setter) { - uint32_t par_addr = codegen.generator->add_parameter(p_variable->setter_parameter->name, false, _gdtype_from_datatype(p_variable->get_datatype())); - codegen.parameters[p_variable->setter_parameter->name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::FUNCTION_PARAMETER, par_addr, _gdtype_from_datatype(p_variable->get_datatype())); - } - - error = _parse_block(codegen, p_is_setter ? p_variable->setter : p_variable->getter); - if (error) { - memdelete(codegen.generator); - return error; - } - - GDScriptFunction *gd_function = codegen.generator->write_end(); - - p_script->member_functions[func_name] = gd_function; - -#ifdef DEBUG_ENABLED - if (EngineDebugger::is_active()) { - String signature; - //path - if (p_script->get_path() != String()) { - signature += p_script->get_path(); - } - //loc - signature += "::" + itos(p_is_setter ? p_variable->setter->start_line : p_variable->getter->start_line); - - //function and class - - if (p_class->identifier) { - signature += "::" + String(p_class->identifier->name) + "." + String(func_name); - } else { - signature += "::" + String(func_name); - } - - codegen.generator->set_signature(signature); - } -#endif - codegen.generator->set_initial_line(p_is_setter ? p_variable->setter->start_line : p_variable->getter->start_line); - -#ifdef TOOLS_ENABLED - p_script->member_lines[func_name] = p_is_setter ? p_variable->setter->start_line : p_variable->getter->start_line; -#endif - memdelete(codegen.generator); - - return OK; + return error; } Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { @@ -2212,7 +2158,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->tool = parser->is_tool(); p_script->name = p_class->identifier ? p_class->identifier->name : ""; - if (p_script->name != "") { + if (!p_script->name.is_empty()) { if (ClassDB::class_exists(p_script->name) && ClassDB::is_class_exposed(p_script->name)) { _set_error("The class '" + p_script->name + "' shadows a native class", p_class); return ERR_ALREADY_EXISTS; @@ -2341,7 +2287,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->constants.insert(name, constant->initializer->reduced_value); #ifdef TOOLS_ENABLED p_script->member_lines[name] = constant->start_line; - if (constant->doc_description != String()) { + if (!constant->doc_description.is_empty()) { p_script->doc_constants[name] = constant->doc_description; } #endif diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index 7d5bee93ac..8d71437344 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp index 9287df2ea0..cc0be94a9e 100644 --- a/modules/gdscript/gdscript_disassembler.cpp +++ b/modules/gdscript/gdscript_disassembler.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index e49bf518a2..81aaef09dc 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,7 @@ #include "core/config/engine.h" #include "core/core_constants.h" #include "core/io/file_access.h" +#include "editor_templates/templates.gen.h" #include "gdscript_analyzer.h" #include "gdscript_compiler.h" #include "gdscript_parser.h" @@ -55,68 +56,44 @@ void GDScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const { p_delimiters->push_back("\"\"\" \"\"\""); } -String GDScriptLanguage::_get_processed_template(const String &p_template, const String &p_base_class_name) const { - String processed_template = p_template; +bool GDScriptLanguage::is_using_templates() { + return true; +} +Ref<Script> GDScriptLanguage::make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const { + Ref<GDScript> script; + script.instantiate(); + String processed_template = p_template; #ifdef TOOLS_ENABLED - if (EDITOR_DEF("text_editor/completion/add_type_hints", false)) { - processed_template = processed_template.replace("%INT_TYPE%", ": int"); - processed_template = processed_template.replace("%STRING_TYPE%", ": String"); - processed_template = processed_template.replace("%FLOAT_TYPE%", ": float"); - processed_template = processed_template.replace("%VOID_RETURN%", " -> void"); - } else { - processed_template = processed_template.replace("%INT_TYPE%", ""); - processed_template = processed_template.replace("%STRING_TYPE%", ""); - processed_template = processed_template.replace("%FLOAT_TYPE%", ""); - processed_template = processed_template.replace("%VOID_RETURN%", ""); + if (!EDITOR_DEF("text_editor/completion/add_type_hints", false)) { + processed_template = processed_template.replace(": int", "") + .replace(": String", "") + .replace(": float", "") + .replace(":=", "=") + .replace(" -> void", ""); } #else - processed_template = processed_template.replace("%INT_TYPE%", ""); - processed_template = processed_template.replace("%STRING_TYPE%", ""); - processed_template = processed_template.replace("%FLOAT_TYPE%", ""); - processed_template = processed_template.replace("%VOID_RETURN%", ""); + processed_template = processed_template.replace(": int", "") + .replace(": String", "") + .replace(": float", "") + .replace(" -> void", ""); #endif - processed_template = processed_template.replace("%BASE%", p_base_class_name); - processed_template = processed_template.replace("%TS%", _get_indentation()); - - return processed_template; -} - -Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const { - String _template = "extends %BASE%\n" - "\n" - "\n" - "# Declare member variables here. Examples:\n" - "# var a%INT_TYPE% = 2\n" - "# var b%STRING_TYPE% = \"text\"\n" - "\n" - "\n" - "# Called when the node enters the scene tree for the first time.\n" - "func _ready()%VOID_RETURN%:\n" - "%TS%pass # Replace with function body.\n" - "\n" - "\n" - "# Called every frame. 'delta' is the elapsed time since the previous frame.\n" - "#func _process(delta%FLOAT_TYPE%)%VOID_RETURN%:\n" - "#%TS%pass\n"; - - _template = _get_processed_template(_template, p_base_class_name); - - Ref<GDScript> script; - script.instantiate(); - script->set_source_code(_template); - + processed_template = processed_template.replace("_BASE_", p_base_class_name) + .replace("_CLASS_", p_class_name) + .replace("_TS_", _get_indentation()); + script->set_source_code(processed_template); return script; } -bool GDScriptLanguage::is_using_templates() { - return true; -} - -void GDScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) { - String _template = _get_processed_template(p_script->get_source_code(), p_base_class_name); - p_script->set_source_code(_template); +Vector<ScriptLanguage::ScriptTemplate> GDScriptLanguage::get_built_in_templates(StringName p_object) { + Vector<ScriptLanguage::ScriptTemplate> templates; + for (int i = 0; i < TEMPLATES_ARRAY_SIZE; i++) { + if (TEMPLATES[i].inherit == p_object) { + templates.append(TEMPLATES[i]); + } + } + return templates; } static void get_function_names_recursively(const GDScriptParser::ClassNode *p_class, const String &p_prefix, Map<int, String> &r_funcs) { @@ -236,7 +213,7 @@ Script *GDScriptLanguage::create_script() const { /* DEBUGGER FUNCTIONS */ bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const String &p_error) { - //break because of parse error + // break because of parse error if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) { _debug_parse_err_line = p_line; @@ -669,6 +646,11 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CLASS); r_result.insert(option.display, option); } + } else if (p_annotation->name == "@warning_ignore") { + for (int warning_code = 0; warning_code < GDScriptWarning::WARNING_MAX; warning_code++) { + ScriptCodeCompletionOption warning(GDScriptWarning::get_name_from_code((GDScriptWarning::Code)warning_code).to_lower(), ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + r_result.insert(warning.display, warning); + } } } @@ -1089,6 +1071,15 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool kwa++; } + List<StringName> utility_func_names; + Variant::get_utility_function_list(&utility_func_names); + + for (List<StringName>::Element *E = utility_func_names.front(); E; E = E->next()) { + ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_FUNCTION); + option.insert_text += "("; + r_result.insert(option.display, option); + } + OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { if (!E.value().is_singleton) { @@ -1356,7 +1347,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, String arg1 = args[0]; if (arg1.begins_with("/root/")) { String which = arg1.get_slice("/", 2); - if (which != "") { + if (!which.is_empty()) { // Try singletons first if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(which)) { r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[which]); @@ -1374,8 +1365,8 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, } if (!script.ends_with(".gd")) { - //not a script, try find the script anyway, - //may have some success + // not a script, try find the script anyway, + // may have some success script = script.get_basename() + ".gd"; } @@ -2325,7 +2316,11 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c GDScriptCompletionIdentifier connect_base; - if (GDScriptUtilityFunctions::function_exists(call->function_name)) { + if (Variant::has_utility_function(call->function_name)) { + MethodInfo info = Variant::get_utility_function_info(call->function_name); + r_arghint = _make_arguments_hint(info, p_argidx); + return; + } else if (GDScriptUtilityFunctions::function_exists(call->function_name)) { MethodInfo info = GDScriptUtilityFunctions::get_function_info(call->function_name); r_arghint = _make_arguments_hint(info, p_argidx); return; @@ -2740,7 +2735,7 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t } String st = l.substr(tc, l.length()).strip_edges(); - if (st == "" || st.begins_with("#")) { + if (st.is_empty() || st.begins_with("#")) { continue; //ignore! } @@ -2757,7 +2752,7 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t } if (indent_stack.size() && indent_stack.back()->get() != tc) { - indent_stack.push_back(tc); //this is not right but gets the job done + indent_stack.push_back(tc); // this is not right but gets the job done } } @@ -2797,6 +2792,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION; r_result.location = base_type.class_type->get_member(p_symbol).get_line(); r_result.class_path = base_type.script_path; + r_result.script = GDScriptCache::get_shallow_script(r_result.class_path); return OK; } base_type = base_type.class_type->base_type; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index a3f0c7dfef..f1877df326 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 9d076a8e4c..db663ca48f 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -192,7 +192,7 @@ public: GDScriptDataType() = default; - GDScriptDataType &operator=(const GDScriptDataType &p_other) { + void operator=(const GDScriptDataType &p_other) { kind = p_other.kind; has_type = p_other.has_type; builtin_type = p_other.builtin_type; @@ -203,7 +203,6 @@ public: if (p_other.has_container_element_type()) { set_container_element_type(p_other.get_container_element_type()); } - return *this; } GDScriptDataType(const GDScriptDataType &p_other) { diff --git a/modules/gdscript/gdscript_lambda_callable.cpp b/modules/gdscript/gdscript_lambda_callable.cpp index 0bc109b6e1..baf93e1098 100644 --- a/modules/gdscript/gdscript_lambda_callable.cpp +++ b/modules/gdscript/gdscript_lambda_callable.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_lambda_callable.h b/modules/gdscript/gdscript_lambda_callable.h index 336778d549..f6a54a1a2f 100644 --- a/modules/gdscript/gdscript_lambda_callable.h +++ b/modules/gdscript/gdscript_lambda_callable.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index ad75e8174c..2faf0febca 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,6 +39,7 @@ #ifdef DEBUG_ENABLED #include "core/os/os.h" #include "core/string/string_builder.h" +#include "gdscript_warning.h" #endif // DEBUG_ENABLED #ifdef TOOLS_ENABLED @@ -132,9 +133,9 @@ GDScriptParser::GDScriptParser() { register_annotation(MethodInfo("@export_flags_3d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_RENDER, Variant::INT>); register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>); register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>); + register_annotation(MethodInfo("@warning_ignore", { Variant::STRING, "warning" }), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, 0, true); // Networking. register_annotation(MethodInfo("@rpc", { Variant::STRING, "mode" }, { Variant::STRING, "sync" }, { Variant::STRING, "transfer_mode" }, { Variant::INT, "transfer_channel" }), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<Multiplayer::RPC_MODE_AUTHORITY>, 4, true); - // TODO: Warning annotations. } GDScriptParser::~GDScriptParser() { @@ -196,6 +197,10 @@ void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_ return; } + if (ignored_warning_codes.has(p_code)) { + return; + } + String warn_name = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)p_code).to_lower(); if (ignored_warnings.has(warn_name)) { return; @@ -701,24 +706,21 @@ void GDScriptParser::parse_extends() { template <class T> void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)(), AnnotationInfo::TargetKind p_target, const String &p_member_kind) { advance(); - T *member = (this->*p_parse_function)(); - if (member == nullptr) { - return; - } + #ifdef TOOLS_ENABLED - int doc_comment_line = member->start_line - 1; + int doc_comment_line = previous.start_line - 1; #endif // TOOLS_ENABLED // Consume annotations. + List<AnnotationNode *> annotations; while (!annotation_stack.is_empty()) { AnnotationNode *last_annotation = annotation_stack.back()->get(); if (last_annotation->applies_to(p_target)) { - member->annotations.push_front(last_annotation); + annotations.push_front(last_annotation); annotation_stack.pop_back(); } else { push_error(vformat(R"(Annotation "%s" cannot be applied to a %s.)", last_annotation->name, p_member_kind)); clear_unused_annotations(); - return; } #ifdef TOOLS_ENABLED if (last_annotation->start_line == doc_comment_line) { @@ -727,6 +729,16 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)() #endif // TOOLS_ENABLED } + T *member = (this->*p_parse_function)(); + if (member == nullptr) { + return; + } + + // Apply annotations. + for (AnnotationNode *&annotation : annotations) { + member->annotations.push_back(annotation); + } + #ifdef TOOLS_ENABLED // Consume doc comments. class_doc_line = MIN(class_doc_line, doc_comment_line - 1); @@ -740,10 +752,26 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)() #endif // TOOLS_ENABLED if (member->identifier != nullptr) { - // Enums may be unnamed. - // TODO: Consider names in outer scope too, for constants and classes (and static functions?) - if (current_class->members_indices.has(member->identifier->name)) { - push_error(vformat(R"(%s "%s" has the same name as a previously declared %s.)", p_member_kind.capitalize(), member->identifier->name, current_class->get_member(member->identifier->name).get_type_name()), member->identifier); + if (!((String)member->identifier->name).is_empty()) { // Enums may be unnamed. + +#ifdef DEBUG_ENABLED + List<MethodInfo> gdscript_funcs; + GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs); + for (MethodInfo &info : gdscript_funcs) { + if (info.name == member->identifier->name) { + push_warning(member->identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, p_member_kind, member->identifier->name, "built-in function"); + } + } + if (Variant::has_utility_function(member->identifier->name)) { + push_warning(member->identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, p_member_kind, member->identifier->name, "built-in function"); + } +#endif + + if (current_class->members_indices.has(member->identifier->name)) { + push_error(vformat(R"(%s "%s" has the same name as a previously declared %s.)", p_member_kind.capitalize(), member->identifier->name, current_class->get_member(member->identifier->name).get_type_name()), member->identifier); + } else { + current_class->add_member(member); + } } else { current_class->add_member(member); } @@ -947,7 +975,7 @@ GDScriptParser::VariableNode *GDScriptParser::parse_property(VariableNode *p_var void GDScriptParser::parse_property_setter(VariableNode *p_variable) { switch (p_variable->property) { - case VariableNode::PROP_INLINE: + case VariableNode::PROP_INLINE: { consume(GDScriptTokenizer::Token::PARENTHESIS_OPEN, R"(Expected "(" after "set".)"); if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected parameter name after "(".)")) { p_variable->setter_parameter = parse_identifier(); @@ -955,9 +983,32 @@ void GDScriptParser::parse_property_setter(VariableNode *p_variable) { consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after parameter name.)*"); consume(GDScriptTokenizer::Token::COLON, R"*(Expected ":" after ")".)*"); - p_variable->setter = parse_suite("setter definition"); - break; + IdentifierNode *identifier = alloc_node<IdentifierNode>(); + identifier->name = "@" + p_variable->identifier->name + "_setter"; + + FunctionNode *function = alloc_node<FunctionNode>(); + function->identifier = identifier; + + FunctionNode *previous_function = current_function; + current_function = function; + + ParameterNode *parameter = alloc_node<ParameterNode>(); + parameter->identifier = p_variable->setter_parameter; + if (parameter->identifier != nullptr) { + function->parameters_indices[parameter->identifier->name] = 0; + function->parameters.push_back(parameter); + + SuiteNode *body = alloc_node<SuiteNode>(); + body->add_local(parameter, function); + + function->body = parse_suite("setter declaration", body); + p_variable->setter = function; + } + + current_function = previous_function; + break; + } case VariableNode::PROP_SETGET: consume(GDScriptTokenizer::Token::EQUAL, R"(Expected "=" after "set")"); make_completion_context(COMPLETION_PROPERTY_METHOD, p_variable); @@ -972,11 +1023,25 @@ void GDScriptParser::parse_property_setter(VariableNode *p_variable) { void GDScriptParser::parse_property_getter(VariableNode *p_variable) { switch (p_variable->property) { - case VariableNode::PROP_INLINE: + case VariableNode::PROP_INLINE: { consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after "get".)"); - p_variable->getter = parse_suite("getter definition"); + IdentifierNode *identifier = alloc_node<IdentifierNode>(); + identifier->name = "@" + p_variable->identifier->name + "_getter"; + + FunctionNode *function = alloc_node<FunctionNode>(); + function->identifier = identifier; + + FunctionNode *previous_function = current_function; + current_function = function; + + SuiteNode *body = alloc_node<SuiteNode>(); + function->body = parse_suite("getter declaration", body); + + p_variable->getter = function; + current_function = previous_function; break; + } case VariableNode::PROP_SETGET: consume(GDScriptTokenizer::Token::EQUAL, R"(Expected "=" after "get")"); make_completion_context(COMPLETION_PROPERTY_METHOD, p_variable); @@ -1108,13 +1173,31 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() { HashMap<StringName, int> elements; +#ifdef DEBUG_ENABLED + List<MethodInfo> gdscript_funcs; + GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs); +#endif + do { if (check(GDScriptTokenizer::Token::BRACE_CLOSE)) { break; // Allow trailing comma. } if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier for enum key.)")) { EnumNode::Value item; - item.identifier = parse_identifier(); + GDScriptParser::IdentifierNode *identifier = parse_identifier(); +#ifdef DEBUG_ENABLED + for (MethodInfo &info : gdscript_funcs) { + if (info.name == identifier->name) { + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "enum member", identifier->name, "built-in function"); + } + } + if (Variant::has_utility_function(identifier->name)) { + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "enum member", identifier->name, "built-in function"); + } else if (ClassDB::class_exists(identifier->name)) { + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "enum member", identifier->name, "global class"); + } +#endif + item.identifier = identifier; item.parent_enum = enum_node; item.line = previous.start_line; item.leftmost_column = previous.leftmost_column; @@ -1436,6 +1519,8 @@ GDScriptParser::Node *GDScriptParser::parse_statement() { bool unreachable = current_suite->has_return && !current_suite->has_unreachable_code; #endif + bool is_annotation = false; + switch (current.type) { case GDScriptTokenizer::Token::PASS: advance(); @@ -1505,6 +1590,7 @@ GDScriptParser::Node *GDScriptParser::parse_statement() { break; case GDScriptTokenizer::Token::ANNOTATION: { advance(); + is_annotation = true; AnnotationNode *annotation = parse_annotation(AnnotationInfo::STATEMENT); if (annotation != nullptr) { annotation_stack.push_back(annotation); @@ -1545,6 +1631,18 @@ GDScriptParser::Node *GDScriptParser::parse_statement() { } } + // Apply annotations to statement. + while (!is_annotation && result != nullptr && !annotation_stack.is_empty()) { + AnnotationNode *last_annotation = annotation_stack.back()->get(); + if (last_annotation->applies_to(AnnotationInfo::STATEMENT)) { + result->annotations.push_front(last_annotation); + annotation_stack.pop_back(); + } else { + push_error(vformat(R"(Annotation "%s" cannot be applied to a statement.)", last_annotation->name)); + clear_unused_annotations(); + } + } + #ifdef DEBUG_ENABLED if (unreachable && result != nullptr) { current_suite->has_unreachable_code = true; @@ -2737,6 +2835,23 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p get_node->chain.push_back(identifier); } while (match(GDScriptTokenizer::Token::SLASH)); return get_node; + } else if (match(GDScriptTokenizer::Token::SLASH)) { + GetNodeNode *get_node = alloc_node<GetNodeNode>(); + IdentifierNode *identifier_root = alloc_node<IdentifierNode>(); + get_node->chain.push_back(identifier_root); + int chain_position = 0; + do { + make_completion_context(COMPLETION_GET_NODE, get_node, chain_position++); + if (!current.is_node_name()) { + push_error(R"(Expect node path after "/".)"); + return nullptr; + } + advance(); + IdentifierNode *identifier = alloc_node<IdentifierNode>(); + identifier->name = previous.get_identifier(); + get_node->chain.push_back(identifier); + } while (match(GDScriptTokenizer::Token::SLASH)); + return get_node; } else { push_error(R"(Expect node path as string or identifier after "$".)"); return nullptr; @@ -2981,7 +3096,7 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String & if (!comments.has(p_line)) { return; } - ERR_FAIL_COND(p_brief != "" || p_desc != "" || p_tutorials.size() != 0); + ERR_FAIL_COND(!p_brief.is_empty() || !p_desc.is_empty() || p_tutorials.size() != 0); int line = p_line; bool in_codeblock = false; @@ -3013,7 +3128,7 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String & String striped_line = doc_line.strip_edges(); // Set the read mode. - if (striped_line.begins_with("@desc:") && p_desc == "") { + if (striped_line.begins_with("@desc:") && p_desc.is_empty()) { mode = DESC; striped_line = striped_line.trim_prefix("@desc:"); in_codeblock = _in_codeblock(doc_line, in_codeblock); @@ -3031,9 +3146,9 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String & } else { /* Syntax: - @tutorial ( The Title Here ) : https://the.url/ - ^ open ^ close ^ colon ^ url - */ + * @tutorial ( The Title Here ) : https://the.url/ + * ^ open ^ close ^ colon ^ url + */ int open_bracket_pos = begin_scan, close_bracket_pos = 0; while (open_bracket_pos < striped_line.length() && (striped_line[open_bracket_pos] == ' ' || striped_line[open_bracket_pos] == '\t')) { open_bracket_pos++; @@ -3294,8 +3409,8 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) Variant::construct(parameter.type, r, &(name), 1, error); p_annotation->resolved_arguments.push_back(r); if (error.error != Callable::CallError::CALL_OK) { - push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); - p_annotation->resolved_arguments.remove(p_annotation->resolved_arguments.size() - 1); + push_error(vformat(R"(Expected %s as argument %d of annotation "%s".)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); + p_annotation->resolved_arguments.remove_at(p_annotation->resolved_arguments.size() - 1); return false; } break; @@ -3303,13 +3418,13 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) [[fallthrough]]; default: { if (argument->type != Node::LITERAL) { - push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); + push_error(vformat(R"(Expected %s as argument %d of annotation "%s".)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); return false; } Variant value = static_cast<LiteralNode *>(argument)->value; if (!Variant::can_convert_strict(value.get_type(), parameter.type)) { - push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); + push_error(vformat(R"(Expected %s as argument %d of annotation "%s".)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); return false; } Callable::CallError error; @@ -3318,8 +3433,8 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) Variant::construct(parameter.type, r, &(args), 1, error); p_annotation->resolved_arguments.push_back(r); if (error.error != Callable::CallError::CALL_OK) { - push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); - p_annotation->resolved_arguments.remove(p_annotation->resolved_arguments.size() - 1); + push_error(vformat(R"(Expected %s as argument %d of annotation "%s".)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); + p_annotation->resolved_arguments.remove_at(p_annotation->resolved_arguments.size() - 1); return false; } break; @@ -3423,7 +3538,7 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node String enum_hint_string; for (const Map<StringName, int>::Element *E = export_type.enum_values.front(); E; E = E->next()) { - enum_hint_string += E->key().operator String().camelcase_to_underscore(true).capitalize().xml_escape(); + enum_hint_string += E->key().operator String().capitalize().xml_escape(); enum_hint_string += ":"; enum_hint_string += String::num_int64(E->get()).xml_escape(); @@ -3464,7 +3579,24 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node } bool GDScriptParser::warning_annotations(const AnnotationNode *p_annotation, Node *p_node) { - ERR_FAIL_V_MSG(false, "Not implemented."); +#ifdef DEBUG_ENABLED + bool has_error = false; + for (const Variant &warning_name : p_annotation->resolved_arguments) { + GDScriptWarning::Code warning = GDScriptWarning::get_code_from_name(String(warning_name).to_upper()); + if (warning == GDScriptWarning::WARNING_MAX) { + push_error(vformat(R"(Invalid warning name: "%s".)", warning_name), p_annotation); + has_error = true; + } else { + p_node->ignored_warnings.push_back(warning); + } + } + + return !has_error; + +#else // ! DEBUG_ENABLED + // Only available in debug builds. + return true; +#endif // DEBUG_ENABLED } template <Multiplayer::RPCMode t_mode> @@ -3490,9 +3622,9 @@ bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Nod } else if (mode == "authority") { rpc_config.rpc_mode = Multiplayer::RPC_MODE_AUTHORITY; } else if (mode == "call_local") { - rpc_config.sync = true; + rpc_config.call_local = true; } else if (mode == "call_remote") { - rpc_config.sync = false; + rpc_config.call_local = false; } else if (mode == "reliable") { rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; } else if (mode == "unreliable") { @@ -3500,7 +3632,7 @@ bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Nod } else if (mode == "unreliable_ordered") { rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED; } else { - push_error(R"(Invalid RPC argument. Must be one of: 'call_local'/'no_call_local' (local calls), 'any_peer'/'authority' (permission), 'reliable'/'unreliable'/'unreliable_ordered' (transfer mode).)", p_annotation); + push_error(R"(Invalid RPC argument. Must be one of: 'call_local'/'call_remote' (local calls), 'any_peer'/'authority' (permission), 'reliable'/'unreliable'/'unreliable_ordered' (transfer mode).)", p_annotation); } } } @@ -4437,7 +4569,7 @@ void GDScriptParser::TreePrinter::print_variable(VariableNode *p_variable) { if (p_variable->property == VariableNode::PROP_INLINE) { push_line(":"); increase_indent(); - print_suite(p_variable->getter); + print_suite(p_variable->getter->body); decrease_indent(); } else { push_line(" ="); @@ -4457,7 +4589,7 @@ void GDScriptParser::TreePrinter::print_variable(VariableNode *p_variable) { } push_line("):"); increase_indent(); - print_suite(p_variable->setter); + print_suite(p_variable->setter->body); decrease_indent(); } else { push_line(" ="); @@ -4496,7 +4628,7 @@ void GDScriptParser::TreePrinter::print_tree(const GDScriptParser &p_parser) { } print_class(p_parser.get_tree()); - print_line(printed); + print_line(String(printed)); } #endif // DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 593fb0cc5e..bf0f670905 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -203,7 +203,7 @@ public: return !(this->operator==(p_other)); } - DataType &operator=(const DataType &p_other) { + void operator=(const DataType &p_other) { kind = p_other.kind; type_source = p_other.type_source; is_constant = p_other.is_constant; @@ -221,7 +221,6 @@ public: if (p_other.has_container_element_type()) { set_container_element_type(p_other.get_container_element_type()); } - return *this; } DataType() = default; @@ -298,6 +297,7 @@ public: int leftmost_column = 0, rightmost_column = 0; Node *next = nullptr; List<AnnotationNode *> annotations; + Vector<uint32_t> ignored_warnings; DataType datatype; @@ -1109,12 +1109,12 @@ public: PropertyStyle property = PROP_NONE; union { - SuiteNode *setter = nullptr; + FunctionNode *setter = nullptr; IdentifierNode *setter_pointer; }; IdentifierNode *setter_parameter = nullptr; union { - SuiteNode *getter = nullptr; + FunctionNode *getter = nullptr; IdentifierNode *getter_pointer; }; @@ -1205,6 +1205,7 @@ private: #ifdef DEBUG_ENABLED List<GDScriptWarning> warnings; Set<String> ignored_warnings; + Set<uint32_t> ignored_warning_codes; Set<int> unsafe_lines; #endif diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index d4a098811a..05ea061798 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -795,6 +795,15 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() { char32_t ch = _peek(); + if (ch == 0x200E || ch == 0x200F || (ch >= 0x202A && ch <= 0x202E) || (ch >= 0x2066 && ch <= 0x2069)) { + Token error = make_error("Invisible text direction control character present in the string, escape it (\"\\u" + String::num_int64(ch, 16) + "\") to avoid confusion."); + error.start_column = column; + error.leftmost_column = error.start_column; + error.end_column = column + 1; + error.rightmost_column = error.end_column; + push_error(error); + } + if (ch == '\\') { // Escape pattern. _advance(); @@ -1064,7 +1073,8 @@ void GDScriptTokenizer::check_indent() { // First time indenting, choose character now. indent_char = current_indent_char; } else if (current_indent_char != indent_char) { - Token error = make_error(vformat("Used \"%s\" for indentation instead \"%s\" as used before in the file.", String(¤t_indent_char, 1).c_escape(), String(&indent_char, 1).c_escape())); + Token error = make_error(vformat("Used %s character for indentation instead of %s as used before in the file.", + _get_indent_char_name(current_indent_char), _get_indent_char_name(indent_char))); error.start_line = line; error.start_column = 1; error.leftmost_column = 1; @@ -1114,6 +1124,12 @@ void GDScriptTokenizer::check_indent() { } } +String GDScriptTokenizer::_get_indent_char_name(char32_t ch) { + ERR_FAIL_COND_V(ch != ' ' && ch != '\t', String(&ch, 1).c_escape()); + + return ch == ' ' ? "space" : "tab"; +} + void GDScriptTokenizer::_skip_whitespace() { if (pending_indents != 0) { // Still have some indent/dedent tokens to give. diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 84b82c07f0..abd090e381 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -233,6 +233,7 @@ private: bool has_error() const { return !error_stack.is_empty(); } Token pop_error(); char32_t _advance(); + String _get_indent_char_name(char32_t ch); void _skip_whitespace(); void check_indent(); diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp index f1b0079536..16b2dac343 100644 --- a/modules/gdscript/gdscript_utility_functions.cpp +++ b/modules/gdscript/gdscript_utility_functions.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -437,9 +437,13 @@ struct GDScriptUtilityFunctionsDefinitions { str += p_args[i]->operator String(); } - ScriptLanguage *script = GDScriptLanguage::get_singleton(); - if (script->debug_get_stack_level_count() > 0) { - str += "\n At: " + script->debug_get_stack_level_source(0) + ":" + itos(script->debug_get_stack_level_line(0)) + ":" + script->debug_get_stack_level_function(0) + "()"; + if (Thread::get_caller_id() == Thread::get_main_id()) { + ScriptLanguage *script = GDScriptLanguage::get_singleton(); + if (script->debug_get_stack_level_count() > 0) { + str += "\n At: " + script->debug_get_stack_level_source(0) + ":" + itos(script->debug_get_stack_level_line(0)) + ":" + script->debug_get_stack_level_function(0) + "()"; + } + } else { + str += "\n At: Cannot retrieve debug info outside the main thread. Thread ID: " + itos(Thread::get_caller_id()); } print_line(str); @@ -448,15 +452,24 @@ struct GDScriptUtilityFunctionsDefinitions { static inline void print_stack(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { VALIDATE_ARG_COUNT(0); + if (Thread::get_caller_id() != Thread::get_main_id()) { + print_line("Cannot retrieve debug info outside the main thread. Thread ID: " + itos(Thread::get_caller_id())); + return; + } ScriptLanguage *script = GDScriptLanguage::get_singleton(); for (int i = 0; i < script->debug_get_stack_level_count(); i++) { print_line("Frame " + itos(i) + " - " + script->debug_get_stack_level_source(i) + ":" + itos(script->debug_get_stack_level_line(i)) + " in function '" + script->debug_get_stack_level_function(i) + "'"); }; + *r_ret = Variant(); } static inline void get_stack(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { VALIDATE_ARG_COUNT(0); + if (Thread::get_caller_id() != Thread::get_main_id()) { + *r_ret = Array(); + return; + } ScriptLanguage *script = GDScriptLanguage::get_singleton(); Array ret; diff --git a/modules/gdscript/gdscript_utility_functions.h b/modules/gdscript/gdscript_utility_functions.h index c6d3718844..9ca7cf33d8 100644 --- a/modules/gdscript/gdscript_utility_functions.h +++ b/modules/gdscript/gdscript_utility_functions.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index c89cf2f25c..014a2ad3b8 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -755,7 +755,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (!valid) { String v = index->operator String(); - if (v != "") { + if (!v.is_empty()) { v = "'" + v + "'"; } else { v = "of type '" + _get_var_type(index) + "'"; @@ -785,7 +785,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (!valid) { String v = index->operator String(); - if (v != "") { + if (!v.is_empty()) { v = "'" + v + "'"; } else { v = "of type '" + _get_var_type(index) + "'"; @@ -817,7 +817,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (oob) { String v = index->operator String(); - if (v != "") { + if (!v.is_empty()) { v = "'" + v + "'"; } else { v = "of type '" + _get_var_type(index) + "'"; @@ -848,7 +848,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (!valid) { String v = index->operator String(); - if (v != "") { + if (!v.is_empty()) { v = "'" + v + "'"; } else { v = "of type '" + _get_var_type(index) + "'"; @@ -884,7 +884,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (!valid) { String v = key->operator String(); - if (v != "") { + if (!v.is_empty()) { v = "'" + v + "'"; } else { v = "of type '" + _get_var_type(key) + "'"; @@ -917,7 +917,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (oob) { String v = index->operator String(); - if (v != "") { + if (!v.is_empty()) { v = "'" + v + "'"; } else { v = "of type '" + _get_var_type(index) + "'"; @@ -1110,7 +1110,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } else { #ifdef DEBUG_ENABLED err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + - "' to a variable of type '" + Variant::get_type_name(var_type) + "'."; + "' to a variable of type '" + Variant::get_type_name(var_type) + "'."; OPCODE_BREAK; } } else { @@ -1132,7 +1132,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (src->get_type() != Variant::ARRAY) { #ifdef DEBUG_ENABLED err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + - "' to a variable of type '" + +"'."; + "' to a variable of type '" + +"'."; #endif OPCODE_BREAK; } @@ -1158,14 +1158,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(!nc); if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) { err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + - "' to a variable of type '" + nc->get_name() + "'."; + "' to a variable of type '" + nc->get_name() + "'."; OPCODE_BREAK; } Object *src_obj = src->operator Object *(); if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) { err_text = "Trying to assign value of type '" + src_obj->get_class_name() + - "' to a variable of type '" + nc->get_name() + "'."; + "' to a variable of type '" + nc->get_name() + "'."; OPCODE_BREAK; } #endif // DEBUG_ENABLED @@ -1195,7 +1195,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a ScriptInstance *scr_inst = src->operator Object *()->get_script_instance(); if (!scr_inst) { err_text = "Trying to assign value of type '" + src->operator Object *()->get_class_name() + - "' to a variable of type '" + base_type->get_path().get_file() + "'."; + "' to a variable of type '" + base_type->get_path().get_file() + "'."; OPCODE_BREAK; } @@ -1212,7 +1212,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (!valid) { err_text = "Trying to assign value of type '" + src->operator Object *()->get_script_instance()->get_script()->get_path().get_file() + - "' to a variable of type '" + base_type->get_path().get_file() + "'."; + "' to a variable of type '" + base_type->get_path().get_file() + "'."; OPCODE_BREAK; } } @@ -1719,6 +1719,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define OPCODE_CALL_PTR(m_type) \ OPCODE(OPCODE_CALL_PTRCALL_##m_type) { \ CHECK_SPACE(3 + instr_arg_count); \ + ip += instr_arg_count; \ int argc = _code_ptr[ip + 1]; \ GET_INSTRUCTION_ARG(base, argc); \ MethodBind *method = _methods_ptr[_code_ptr[ip + 2]]; \ @@ -2097,8 +2098,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (result.get_type() != Variant::SIGNAL) { + // Not async, return immediately using the target from OPCODE_AWAIT_RESUME. + GET_VARIANT_PTR(target, 3); + *target = result; ip += 4; // Skip OPCODE_AWAIT_RESUME and its data. - // The stack pointer should be the same, so we don't need to set a return value. is_signal = false; } else { sig = result; @@ -3292,27 +3295,27 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a //error // function, file, line, error, explanation String err_file; - if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "") { + if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && !p_instance->script->path.is_empty()) { err_file = p_instance->script->path; } else if (script) { err_file = script->path; } - if (err_file == "") { + if (err_file.is_empty()) { err_file = "<built-in>"; } String err_func = name; - if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "") { + if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && !p_instance->script->name.is_empty()) { err_func = p_instance->script->name + "." + err_func; } int err_line = line; - if (err_text == "") { - err_text = "Internal Script Error! - opcode #" + itos(last_opcode) + " (report please)."; + if (err_text.is_empty()) { + err_text = "Internal script error! Opcode: " + itos(last_opcode) + " (please report)."; } if (!GDScriptLanguage::get_singleton()->debug_break(err_text, false)) { // debugger break did not happen - _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, err_text.utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, err_text.utf8().get_data(), false, ERR_HANDLER_SCRIPT); } #endif diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp index 7a483a16ba..73536f5f8e 100644 --- a/modules/gdscript/gdscript_warning.cpp +++ b/modules/gdscript/gdscript_warning.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -148,6 +148,10 @@ String GDScriptWarning::get_message() const { case EMPTY_FILE: { return "Empty script file."; } + case SHADOWED_GLOBAL_IDENTIFIER: { + CHECK_SYMBOLS(3); + return vformat(R"(The %s '%s' has the same name as a %s.)", symbols[0], symbols[1], symbols[2]); + } case WARNING_MAX: break; // Can't happen, but silences warning } @@ -194,6 +198,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) { "ASSERT_ALWAYS_FALSE", "REDUNDANT_AWAIT", "EMPTY_FILE", + "SHADOWED_GLOBAL_IDENTIFIER", }; static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names."); @@ -208,7 +213,7 @@ GDScriptWarning::Code GDScriptWarning::get_code_from_name(const String &p_name) } } - ERR_FAIL_V_MSG(WARNING_MAX, "Invalid GDScript warning name: " + p_name); + return WARNING_MAX; } #endif // DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h index 8de46b08c1..112b40781a 100644 --- a/modules/gdscript/gdscript_warning.h +++ b/modules/gdscript/gdscript_warning.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -69,6 +69,7 @@ public: ASSERT_ALWAYS_FALSE, // Expression for assert argument is always false. REDUNDANT_AWAIT, // await is used but expression is synchronous (not a signal nor a coroutine). EMPTY_FILE, // A script file is empty. + SHADOWED_GLOBAL_IDENTIFIER, // A global class or function has the same name as variable. WARNING_MAX, }; diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index 730e554476..49f5303ae6 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -165,7 +165,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p case ClassNode::Member::VARIABLE: { lsp::DocumentSymbol symbol; symbol.name = m.variable->identifier->name; - symbol.kind = m.variable->property == VariableNode::PropertyStyle::PROP_NONE ? lsp::SymbolKind::Variable : lsp::SymbolKind::Property; + symbol.kind = m.variable->property == VariableNode::PROP_NONE ? lsp::SymbolKind::Variable : lsp::SymbolKind::Property; symbol.deprecated = false; symbol.range.start.line = LINE_NUMBER_TO_INDEX(m.variable->start_line); symbol.range.start.character = LINE_NUMBER_TO_INDEX(m.variable->start_column); @@ -269,7 +269,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p if (j > 0) { symbol.detail += ", "; } - symbol.detail += m.signal->parameters[i]->identifier->name; + symbol.detail += m.signal->parameters[j]->identifier->name; } symbol.detail += ")"; diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h index 5d7b16765b..99b0bf45d0 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.h +++ b/modules/gdscript/language_server/gdscript_extend_parser.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 5cf1e0fc5f..cdddab319d 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -115,7 +115,7 @@ Error GDScriptLanguageProtocol::LSPeer::send_data() { // Response sent if (res_sent >= c_res.size() - 1) { res_sent = 0; - res_queue.remove(0); + res_queue.remove_at(0); } } return OK; diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h index 899446fb42..0fed8597f9 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.h +++ b/modules/gdscript/language_server/gdscript_language_protocol.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -38,7 +38,7 @@ #include "gdscript_workspace.h" #include "lsp.hpp" -#include "modules/modules_enabled.gen.h" +#include "modules/modules_enabled.gen.h" // For jsonrpc. #ifdef MODULE_JSONRPC_ENABLED #include "modules/jsonrpc/jsonrpc.h" #else diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp index 41a2f9e4ad..33c1c834f1 100644 --- a/modules/gdscript/language_server/gdscript_language_server.cpp +++ b/modules/gdscript/language_server/gdscript_language_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/language_server/gdscript_language_server.h b/modules/gdscript/language_server/gdscript_language_server.h index 85a44a8cc1..8de72fc9c9 100644 --- a/modules/gdscript/language_server/gdscript_language_server.h +++ b/modules/gdscript/language_server/gdscript_language_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -45,15 +45,13 @@ class GDScriptLanguageServer : public EditorPlugin { bool started = false; bool use_thread = false; String host = "127.0.0.1"; - int port = 6008; + int port = 6005; static void thread_main(void *p_userdata); private: void _notification(int p_what); - void _iteration(); public: - Error parse_script_file(const String &p_path); GDScriptLanguageServer(); void start(); void stop(); diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 92ce71f395..961295b076 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -428,9 +428,6 @@ GDScriptTextDocument::~GDScriptTextDocument() { void GDScriptTextDocument::sync_script_content(const String &p_path, const String &p_content) { String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_path); - if (!path.begins_with("res://")) { - return; - } GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content); EditorFileSystem::get_singleton()->update_file(path); diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h index 9021c84a3f..eb7b2c0240 100644 --- a/modules/gdscript/language_server/gdscript_text_document.h +++ b/modules/gdscript/language_server/gdscript_text_document.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 371e3de419..a944844226 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,9 +54,13 @@ void GDScriptWorkspace::_bind_methods() { } void GDScriptWorkspace::apply_new_signal(Object *obj, String function, PackedStringArray args) { - String function_signature = "func " + function; Ref<Script> script = obj->get_script(); + if (script->get_language()->get_name() != "GDScript") { + return; + } + + String function_signature = "func " + function; String source = script->get_source_code(); if (source.find(function_signature) != -1) { @@ -338,7 +342,9 @@ Error GDScriptWorkspace::initialize() { } Vector<DocData::MethodDoc> methods_signals; + methods_signals.append_array(class_data.constructors); methods_signals.append_array(class_data.methods); + methods_signals.append_array(class_data.operators); const int signal_start_idx = methods_signals.size(); methods_signals.append_array(class_data.signals); diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index 6f5600b5cf..ce5bba5f00 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index 3710a84a28..8e503a9df9 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -358,21 +358,21 @@ struct Command { namespace TextDocumentSyncKind { /** - * Documents should not be synced at all. - */ + * Documents should not be synced at all. + */ static const int None = 0; /** - * Documents are synced by always sending the full content - * of the document. - */ + * Documents are synced by always sending the full content + * of the document. + */ static const int Full = 1; /** - * Documents are synced by sending the full content on open. - * After that only incremental updates to the document are - * send. - */ + * Documents are synced by sending the full content on open. + * After that only incremental updates to the document are + * send. + */ static const int Incremental = 2; }; // namespace TextDocumentSyncKind @@ -667,20 +667,20 @@ struct TextDocumentContentChangeEvent { // Use namespace instead of enumeration to follow the LSP specifications namespace DiagnosticSeverity { /** - * Reports an error. - */ + * Reports an error. + */ static const int Error = 1; /** - * Reports a warning. - */ + * Reports a warning. + */ static const int Warning = 2; /** - * Reports an information. - */ + * Reports an information. + */ static const int Information = 3; /** - * Reports a hint. - */ + * Reports a hint. + */ static const int Hint = 4; }; // namespace DiagnosticSeverity @@ -871,18 +871,18 @@ static const int TypeParameter = 25; */ namespace InsertTextFormat { /** - * The primary text to be inserted is treated as a plain string. - */ + * The primary text to be inserted is treated as a plain string. + */ static const int PlainText = 1; /** - * The primary text to be inserted is treated as a snippet. - * - * A snippet can define tab stops and placeholders with `$1`, `$2` - * and `${3:foo}`. `$0` defines the final tab stop, it defaults to - * the end of the snippet. Placeholders with equal identifiers are linked, - * that is typing in one will update others too. - */ + * The primary text to be inserted is treated as a snippet. + * + * A snippet can define tab stops and placeholders with `$1`, `$2` + * and `${3:foo}`. `$0` defines the final tab stop, it defaults to + * the end of the snippet. Placeholders with equal identifiers are linked, + * that is typing in one will update others too. + */ static const int Snippet = 2; }; // namespace InsertTextFormat @@ -1359,16 +1359,16 @@ struct NativeSymbolInspectParams { */ namespace FoldingRangeKind { /** - * Folding range for a comment - */ + * Folding range for a comment + */ static const String Comment = "comment"; /** - * Folding range for a imports or includes - */ + * Folding range for a imports or includes + */ static const String Imports = "imports"; /** - * Folding range for a region (e.g. `#region`) - */ + * Folding range for a region (e.g. `#region`) + */ static const String Region = "region"; } // namespace FoldingRangeKind @@ -1419,20 +1419,20 @@ struct FoldingRange { */ namespace CompletionTriggerKind { /** - * Completion was triggered by typing an identifier (24x7 code - * complete), manual invocation (e.g Ctrl+Space) or via API. - */ + * Completion was triggered by typing an identifier (24x7 code + * complete), manual invocation (e.g Ctrl+Space) or via API. + */ static const int Invoked = 1; /** - * Completion was triggered by a trigger character specified by - * the `triggerCharacters` properties of the `CompletionRegistrationOptions`. - */ + * Completion was triggered by a trigger character specified by + * the `triggerCharacters` properties of the `CompletionRegistrationOptions`. + */ static const int TriggerCharacter = 2; /** - * Completion was re-triggered as the current completion list is incomplete. - */ + * Completion was re-triggered as the current completion list is incomplete. + */ static const int TriggerForIncompleteCompletions = 3; } // namespace CompletionTriggerKind @@ -1441,8 +1441,8 @@ static const int TriggerForIncompleteCompletions = 3; */ struct CompletionContext { /** - * How the completion was triggered. - */ + * How the completion was triggered. + */ int triggerKind = CompletionTriggerKind::TriggerCharacter; /** @@ -1906,7 +1906,7 @@ struct GodotNativeClassInfo { struct GodotCapabilities { /** * Native class list - */ + */ List<GodotNativeClassInfo> native_classes; Dictionary to_json() { diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index c2b1981f31..fcf122f567 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/register_types.h b/modules/gdscript/register_types.h index ce1c03d1d0..baa7dcbbd1 100644 --- a/modules/gdscript/register_types.h +++ b/modules/gdscript/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index c383830c82..5845f84605 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -133,13 +133,12 @@ GDScriptTestRunner::GDScriptTestRunner(const String &p_source_dir, bool p_init_l if (do_init_languages) { init_language(p_source_dir); - - // Enable all warnings for GDScript, so we can test them. - ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/enable", true); - for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) { - String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower(); - ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/" + warning, true); - } + } + // Enable all warnings for GDScript, so we can test them. + ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/enable", true); + for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) { + String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower(); + ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/" + warning, true); } // Enable printing to show results @@ -268,7 +267,7 @@ bool GDScriptTestRunner::generate_class_index() { String base_type; String class_name = GDScriptLanguage::get_singleton()->get_global_class_name(test.get_source_file(), &base_type); - if (class_name == String()) { + if (class_name.is_empty()) { continue; } ERR_FAIL_COND_V_MSG(ScriptServer::is_global_class(class_name), false, @@ -335,7 +334,7 @@ void GDScriptTest::print_handler(void *p_this, const String &p_message, bool p_e result->output += p_message + "\n"; } -void GDScriptTest::error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, ErrorHandlerType p_type) { +void GDScriptTest::error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, bool p_editor_notify, ErrorHandlerType p_type) { ErrorHandlerData *data = (ErrorHandlerData *)p_this; GDScriptTest *self = data->self; TestResult *result = data->result; diff --git a/modules/gdscript/tests/gdscript_test_runner.h b/modules/gdscript/tests/gdscript_test_runner.h index 9b2d14a371..1a950c6898 100644 --- a/modules/gdscript/tests/gdscript_test_runner.h +++ b/modules/gdscript/tests/gdscript_test_runner.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -87,7 +87,7 @@ private: public: static void print_handler(void *p_this, const String &p_message, bool p_error); - static void error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, ErrorHandlerType p_type); + static void error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, bool p_editor_notify, ErrorHandlerType p_type); TestResult run_test(); bool generate_output(); diff --git a/modules/gdscript/tests/gdscript_test_runner_suite.h b/modules/gdscript/tests/gdscript_test_runner_suite.h index cf4e61f07d..0722fb800e 100644 --- a/modules/gdscript/tests/gdscript_test_runner_suite.h +++ b/modules/gdscript/tests/gdscript_test_runner_suite.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.gd new file mode 100644 index 0000000000..f1be6aaa0c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.gd @@ -0,0 +1,11 @@ +var _prop : int + +# Getter function has wrong return type. +var prop : String: + get = get_prop + +func get_prop(): + return _prop + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.out b/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.out new file mode 100644 index 0000000000..29eec51ef2 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_function_get_type_error.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Function with return type "int" cannot be used as getter for a property of type "String". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.gd new file mode 100644 index 0000000000..dd190157a1 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.gd @@ -0,0 +1,11 @@ +var _prop : int + +# Setter function has wrong argument type. +var prop : String: + set = set_prop + +func set_prop(value : int): + _prop = value + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.out b/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.out new file mode 100644 index 0000000000..7a25280d55 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_function_set_type_error.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Function with argument type "int" cannot be used as setter for a property of type "String". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.gd new file mode 100644 index 0000000000..7f2b29222a --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.gd @@ -0,0 +1,9 @@ +var _prop : int + +# Inline getter returns int instead of String. +var prop : String: + get: + return _prop + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.out b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.out new file mode 100644 index 0000000000..e0adef1bf8 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_get_type_error.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot return value of type "int" because the function return type is "String". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.gd b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.gd new file mode 100644 index 0000000000..0ce239dbbd --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.gd @@ -0,0 +1,9 @@ +var _prop : int + +# Inline setter assigns String to int. +var prop : String: + set(value): + _prop = value + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.out b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.out new file mode 100644 index 0000000000..bbadf1ce27 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/property_inline_set_type_error.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot assign a value of type "String" to a target of type "int". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/setter_parameter_uses_property_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/setter_parameter_uses_property_type.gd new file mode 100644 index 0000000000..3bbee5f5f7 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/setter_parameter_uses_property_type.gd @@ -0,0 +1,8 @@ +var with_setter := 0: + set(val): + var x: String = val + with_setter = val + +func test(): + with_setter = 1 + print(with_setter) diff --git a/modules/gdscript/tests/scripts/analyzer/errors/setter_parameter_uses_property_type.out b/modules/gdscript/tests/scripts/analyzer/errors/setter_parameter_uses_property_type.out new file mode 100644 index 0000000000..9eb2a42ccd --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/setter_parameter_uses_property_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Value of type "int" cannot be assigned to a variable of type "String". diff --git a/modules/gdscript/tests/scripts/analyzer/features/auto_inferred_type_dont_error.out b/modules/gdscript/tests/scripts/analyzer/features/auto_inferred_type_dont_error.out index 0e9f482af4..481016138a 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/auto_inferred_type_dont_error.out +++ b/modules/gdscript/tests/scripts/analyzer/features/auto_inferred_type_dont_error.out @@ -1,2 +1,6 @@ GDTEST_OK +>> WARNING +>> Line: 6 +>> UNSAFE_METHOD_ACCESS +>> The method 'free' is not present on the inferred type 'Variant' (but may be present on a subtype). Ok diff --git a/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.gd b/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.gd new file mode 100644 index 0000000000..30e7deb05a --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.gd @@ -0,0 +1,19 @@ +class A: + var x = 3 + +class B: + var x = 4 + +class C: + var x = 5 + +class Test: + var a = A.new() + var b: B = B.new() + var c := C.new() + +func test(): + var test_instance := Test.new() + prints(test_instance.a.x) + prints(test_instance.b.x) + prints(test_instance.c.x) diff --git a/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.out b/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.out new file mode 100644 index 0000000000..a078e62cc7 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.out @@ -0,0 +1,4 @@ +GDTEST_OK +3 +4 +5 diff --git a/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.gd b/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.gd new file mode 100644 index 0000000000..630b20c282 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.gd @@ -0,0 +1,11 @@ +# https://github.com/godotengine/godot/issues/43503 + +var test_var = null + + +func test(): + print(test_var.x) + + +func _init(): + test_var = Vector3() diff --git a/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out b/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out new file mode 100644 index 0000000000..94e2ec2af8 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out @@ -0,0 +1,2 @@ +GDTEST_OK +0 diff --git a/modules/gdscript/tests/scripts/analyzer/features/local_inference_is_weak.gd b/modules/gdscript/tests/scripts/analyzer/features/local_inference_is_weak.gd new file mode 100644 index 0000000000..b3784dffa3 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/local_inference_is_weak.gd @@ -0,0 +1,14 @@ +# https://github.com/godotengine/godot/issues/41064 +var x = true + +func test(): + var int_var: int = 0 + var dyn_var = 2 + + if x: + dyn_var = 5 + else: + dyn_var = Node.new() + + int_var = dyn_var + print(int_var) diff --git a/modules/gdscript/tests/scripts/analyzer/features/local_inference_is_weak.out b/modules/gdscript/tests/scripts/analyzer/features/local_inference_is_weak.out new file mode 100644 index 0000000000..952029f665 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/local_inference_is_weak.out @@ -0,0 +1,2 @@ +GDTEST_OK +5 diff --git a/modules/gdscript/tests/scripts/analyzer/features/property_functions.gd b/modules/gdscript/tests/scripts/analyzer/features/property_functions.gd new file mode 100644 index 0000000000..1706087f82 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/property_functions.gd @@ -0,0 +1,16 @@ +var _prop = 1 +var prop: + get = get_prop, set = set_prop + +func get_prop(): + return _prop + +func set_prop(value): + _prop = value + +func test(): + print(prop) + + prop = 2 + + print(prop) diff --git a/modules/gdscript/tests/scripts/analyzer/features/property_functions.out b/modules/gdscript/tests/scripts/analyzer/features/property_functions.out new file mode 100644 index 0000000000..f1253ca57e --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/property_functions.out @@ -0,0 +1,3 @@ +GDTEST_OK +1 +2 diff --git a/modules/gdscript/tests/scripts/analyzer/features/property_inline.gd b/modules/gdscript/tests/scripts/analyzer/features/property_inline.gd new file mode 100644 index 0000000000..23eb011b23 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/property_inline.gd @@ -0,0 +1,46 @@ +# Untyped inline property +var prop1: + get: + return prop1 + set(value): + prop1 = value + +# Typed inline property +var prop2 : int: + get: + return prop2 + set(value): + prop2 = value + +# Typed inline property with default value +var prop3 : int = 1: + get: + return prop3 + set(value): + prop3 = value + +# Typed inline property with backing variable +var _prop4 : int = 2 +var prop4: int: + get: + return _prop4 + set(value): + _prop4 = value + +func test(): + print(prop1) + print(prop2) + print(prop3) + print(prop4) + + print() + + prop1 = 1 + prop2 = 2 + prop3 = 3 + prop4 = 4 + + print(prop1) + print(prop2) + print(prop3) + print(prop4) diff --git a/modules/gdscript/tests/scripts/analyzer/features/property_inline.out b/modules/gdscript/tests/scripts/analyzer/features/property_inline.out new file mode 100644 index 0000000000..5482592e90 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/property_inline.out @@ -0,0 +1,10 @@ +GDTEST_OK +null +0 +1 +2 + +1 +2 +3 +4 diff --git a/modules/gdscript/tests/scripts/analyzer/features/subscript_self.gd b/modules/gdscript/tests/scripts/analyzer/features/subscript_self.gd new file mode 100644 index 0000000000..f9a8b23b92 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/subscript_self.gd @@ -0,0 +1,8 @@ +# https://github.com/godotengine/godot/issues/43221 +extends Node + +func test(): + name = "Node" + print(self["name"]) + self["name"] = "Changed" + print(name) diff --git a/modules/gdscript/tests/scripts/analyzer/features/subscript_self.out b/modules/gdscript/tests/scripts/analyzer/features/subscript_self.out new file mode 100644 index 0000000000..6417f4f8da --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/subscript_self.out @@ -0,0 +1,3 @@ +GDTEST_OK +Node +Changed diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_inferred_access_isnt_constant.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_array_inferred_access_isnt_constant.gd new file mode 100644 index 0000000000..55c40cb971 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_inferred_access_isnt_constant.gd @@ -0,0 +1,6 @@ +# https://github.com/godotengine/godot/issues/53640 + +func test(): + var arr := [0] + arr[0] = 1 + print(arr[0]) diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_inferred_access_isnt_constant.out b/modules/gdscript/tests/scripts/analyzer/features/typed_array_inferred_access_isnt_constant.out new file mode 100644 index 0000000000..a7f1357bb2 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_inferred_access_isnt_constant.out @@ -0,0 +1,2 @@ +GDTEST_OK +1 diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.gd new file mode 100644 index 0000000000..9502f6e196 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.gd @@ -0,0 +1,10 @@ +class Inner: + var prop = "Inner" + + +var array: Array[Inner] = [Inner.new()] + + +func test(): + var element: Inner = array[0] + print(element.prop) diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.out b/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.out new file mode 100644 index 0000000000..8f250d2632 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.out @@ -0,0 +1,2 @@ +GDTEST_OK +Inner diff --git a/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.gd b/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.gd new file mode 100644 index 0000000000..877a4ea221 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.gd @@ -0,0 +1,15 @@ +@warning_ignore(unused_private_class_variable) +var _unused = 2 + +@warning_ignore(unused_variable) +func test(): + print("test") + var unused = 3 + + @warning_ignore(redundant_await) + print(await regular_func()) + + print("done") + +func regular_func(): + return 0 diff --git a/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.out b/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.out new file mode 100644 index 0000000000..42292774a0 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.out @@ -0,0 +1,4 @@ +GDTEST_OK +test +0 +done diff --git a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out index 6390de9788..31bed2dbc7 100644 --- a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out +++ b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out @@ -1,2 +1,2 @@ GDTEST_PARSER_ERROR -Used "\t" for indentation instead " " as used before in the file. +Used tab character for indentation instead of space as used before in the file. diff --git a/modules/gdscript/tests/scripts/parser/features/signal_declaration.gd b/modules/gdscript/tests/scripts/parser/features/signal_declaration.gd index 9ad98b78a8..e4d6a72f90 100644 --- a/modules/gdscript/tests/scripts/parser/features/signal_declaration.gd +++ b/modules/gdscript/tests/scripts/parser/features/signal_declaration.gd @@ -6,7 +6,7 @@ signal a # No parameters. signal b() -# With paramters. +# With parameters. signal c(a, b, c) # With parameters multiline. diff --git a/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.gd b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.gd new file mode 100644 index 0000000000..3c64be571b --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.gd @@ -0,0 +1,2 @@ +func test(): + var abs = "This variable has the same name as the built-in function." diff --git a/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.out b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.out new file mode 100644 index 0000000000..c613140eb8 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.out @@ -0,0 +1,9 @@ +GDTEST_OK +>> WARNING +>> Line: 2 +>> UNUSED_VARIABLE +>> The local variable 'abs' is declared but never used in the block. If this is intended, prefix it with an underscore: '_abs' +>> WARNING +>> Line: 2 +>> SHADOWED_GLOBAL_IDENTIFIER +>> The variable 'abs' has the same name as a built-in function. diff --git a/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.gd b/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.gd new file mode 100644 index 0000000000..18174eae67 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.gd @@ -0,0 +1,32 @@ +# https://github.com/godotengine/godot/issues/48121 + +func test(): + var x := [] + var y := [] + x.push_back(y) + print("TEST ARRAY ADD TO SELF: " + str(len(y))) + x.clear() + + x = Array() + y = Array() + x.push_back(y) + print("TEST ARRAY ADD TO SELF: " + str(len(y))) + x.clear() + + x = Array().duplicate() + y = Array().duplicate() + x.push_back(y) + print("TEST ARRAY ADD TO SELF: " + str(len(y))) + x.clear() + + x = [].duplicate() + y = [].duplicate() + x.push_back(y) + print("TEST ARRAY ADD TO SELF: " + str(len(y))) + x.clear() + + x = Array() + y = Array() + x.push_back(y) + print("TEST ARRAY ADD TO SELF: " + str(len(y))) + x.clear() diff --git a/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.out b/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.out new file mode 100644 index 0000000000..f6b7d3cc39 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.out @@ -0,0 +1,6 @@ +GDTEST_OK +TEST ARRAY ADD TO SELF: 0 +TEST ARRAY ADD TO SELF: 0 +TEST ARRAY ADD TO SELF: 0 +TEST ARRAY ADD TO SELF: 0 +TEST ARRAY ADD TO SELF: 0 diff --git a/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.gd b/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.gd new file mode 100644 index 0000000000..9da61ab184 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.gd @@ -0,0 +1,8 @@ +# https://github.com/godotengine/godot/issues/50894 + +func test(): + print(await not_coroutine()) + + +func not_coroutine(): + return "awaited" diff --git a/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.out b/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.out new file mode 100644 index 0000000000..c2ac488e9b --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.out @@ -0,0 +1,6 @@ +GDTEST_OK +>> WARNING +>> Line: 4 +>> REDUNDANT_AWAIT +>> "await" keyword not needed in this case, because the expression isn't a coroutine nor a signal. +awaited diff --git a/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.gd b/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.gd new file mode 100644 index 0000000000..d5a5f8de64 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.gd @@ -0,0 +1,19 @@ +# https://github.com/godotengine/godot/issues/48121 + +func test(): + var x := Dictionary() + var y := Dictionary() + y[0]=1 + y[1]=1 + y[2]=1 + print("TEST OTHER DICTIONARY: " + str(len(x))) + x.clear() + + x = Dictionary().duplicate() + y = Dictionary().duplicate() + y[0]=1 + y[1]=1 + y[2]=1 + print("TEST OTHER DICTIONARY: " + str(len(x))) + x.clear() + return diff --git a/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.out b/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.out new file mode 100644 index 0000000000..0bf49f5934 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.out @@ -0,0 +1,3 @@ +GDTEST_OK +TEST OTHER DICTIONARY: 0 +TEST OTHER DICTIONARY: 0 diff --git a/modules/gdscript/tests/scripts/runtime/features/lua_assign.gd b/modules/gdscript/tests/scripts/runtime/features/lua_assign.gd new file mode 100644 index 0000000000..c9b5f8481e --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/lua_assign.gd @@ -0,0 +1,4 @@ +func test(): + var dict = {} + dict.test = 1 + print(dict.test) diff --git a/modules/gdscript/tests/scripts/runtime/features/lua_assign.out b/modules/gdscript/tests/scripts/runtime/features/lua_assign.out new file mode 100644 index 0000000000..a7f1357bb2 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/lua_assign.out @@ -0,0 +1,2 @@ +GDTEST_OK +1 diff --git a/modules/gdscript/tests/scripts/runtime/features/stringify.gd b/modules/gdscript/tests/scripts/runtime/features/stringify.gd new file mode 100644 index 0000000000..fead2df854 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/stringify.gd @@ -0,0 +1,42 @@ +func test(): + print(true, false) + print(-1, 0, 1) + print(-1.25, 0.25, 1.25) + print("hello world") + + print(Vector2(0.25, 0.25)) + print(Vector2i(0, 0)) + + print(Rect2(0.25, 0.25, 0.5, 0.5)) + print(Rect2i(0, 0, 0, 0)) + + print(Vector3(0.25, 0.25, 0.25)) + print(Vector3i(0, 0, 0)) + + print(Transform2D.IDENTITY) + print(Plane(1, 2, 3, 4)) + print(Quaternion(1, 2, 3, 4)) + print(AABB(Vector3.ZERO, Vector3.ONE)) + print(Basis.from_euler(Vector3(0, 0, 0))) + print(Transform3D.IDENTITY) + + print(Color(1, 2, 3, 4)) + print(StringName("hello")) + print(NodePath("hello/world")) + var node := Node.new() + print(RID(node)) + print(node.get_name) + print(node.property_list_changed) + node.free() + print({"hello":123}) + print(["hello", 123]) + + print(PackedByteArray([-1, 0, 1])) + print(PackedInt32Array([-1, 0, 1])) + print(PackedInt64Array([-1, 0, 1])) + print(PackedFloat32Array([-1, 0, 1])) + print(PackedFloat64Array([-1, 0, 1])) + print(PackedStringArray(["hello", "world"])) + print(PackedVector2Array([Vector2.ONE, Vector2.ZERO])) + print(PackedVector3Array([Vector3.ONE, Vector3.ZERO])) + print(PackedColorArray([Color.RED, Color.BLUE, Color.GREEN])) diff --git a/modules/gdscript/tests/scripts/runtime/features/stringify.out b/modules/gdscript/tests/scripts/runtime/features/stringify.out new file mode 100644 index 0000000000..7670fc0128 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/stringify.out @@ -0,0 +1,34 @@ +GDTEST_OK +truefalse +-101 +-1.250.251.25 +hello world +(0.25, 0.25) +(0, 0) +[P: (0.25, 0.25), S: (0.5, 0.5)] +[P: (0, 0), S: (0, 0)] +(0.25, 0.25, 0.25) +(0, 0, 0) +[X: (1, 0), Y: (0, 1), O: (0, 0)] +[N: (1, 2, 3), D: 4] +(1, 2, 3, 4) +[P: (0, 0, 0), S: (1, 1, 1)] +[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1)] +[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 0, 0)] +(1, 2, 3, 4) +hello +hello/world +RID(0) +Node::get_name +Node::[signal]property_list_changed +{hello:123} +[hello, 123] +[255, 0, 1] +[-1, 0, 1] +[-1, 0, 1] +[-1, 0, 1] +[-1, 0, 1] +[hello, world] +[(1, 1), (0, 0)] +[(1, 1, 1), (0, 0, 0)] +[(1, 0, 0, 1), (0, 0, 1, 1), (0, 1, 0, 1)] diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index 80eabc1596..4255030b4e 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gdscript/tests/test_gdscript.h b/modules/gdscript/tests/test_gdscript.h index c7ee5a2208..b6b1f26203 100644 --- a/modules/gdscript/tests/test_gdscript.h +++ b/modules/gdscript/tests/test_gdscript.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp index dd545ff431..c67d5ff5ab 100644 --- a/modules/glslang/register_types.cpp +++ b/modules/glslang/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -120,7 +120,7 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage preamble += "#define has_VK_KHR_multiview 1\n"; } - if (preamble != "") { + if (!preamble.empty()) { shader.setPreamble(preamble.c_str()); } diff --git a/modules/glslang/register_types.h b/modules/glslang/register_types.h index a1264b77c9..9d8dc9dc2a 100644 --- a/modules/glslang/register_types.h +++ b/modules/glslang/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/doc_classes/EditorSceneImporterGLTF.xml b/modules/gltf/doc_classes/EditorSceneImporterGLTF.xml deleted file mode 100644 index c85fce7b9d..0000000000 --- a/modules/gltf/doc_classes/EditorSceneImporterGLTF.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorSceneImporterGLTF" inherits="EditorSceneImporter" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml index 8d8e25e8b3..ed7c018cb9 100644 --- a/modules/gltf/doc_classes/GLTFDocument.xml +++ b/modules/gltf/doc_classes/GLTFDocument.xml @@ -3,30 +3,57 @@ <brief_description> </brief_description> <description> + Append a glTF2 3d format from a file, buffer or scene and then write to the filesystem, buffer or scene. </description> <tutorials> </tutorials> <methods> - <method name="import_scene"> - <return type="Node" /> + <method name="append_from_buffer"> + <return type="int" enum="Error" /> + <argument index="0" name="bytes" type="PackedByteArray" /> + <argument index="1" name="base_path" type="String" /> + <argument index="2" name="state" type="GLTFState" /> + <argument index="3" name="flags" type="int" default="0" /> + <argument index="4" name="bake_fps" type="int" default="30" /> + <description> + </description> + </method> + <method name="append_from_file"> + <return type="int" enum="Error" /> <argument index="0" name="path" type="String" /> - <argument index="1" name="flags" type="int" default="0" /> - <argument index="2" name="bake_fps" type="int" default="30" /> - <argument index="3" name="state" type="GLTFState" default="null" /> + <argument index="1" name="state" type="GLTFState" /> + <argument index="2" name="flags" type="int" default="0" /> + <argument index="3" name="bake_fps" type="int" default="30" /> <description> - Import a scene from glTF2 ".gltf" or ".glb" file. </description> </method> - <method name="save_scene"> + <method name="append_from_scene"> <return type="int" enum="Error" /> <argument index="0" name="node" type="Node" /> + <argument index="1" name="state" type="GLTFState" /> + <argument index="2" name="flags" type="int" default="0" /> + <argument index="3" name="bake_fps" type="int" default="30" /> + <description> + </description> + </method> + <method name="generate_buffer"> + <return type="PackedByteArray" /> + <argument index="0" name="state" type="GLTFState" /> + <description> + </description> + </method> + <method name="generate_scene"> + <return type="Node" /> + <argument index="0" name="state" type="GLTFState" /> + <argument index="1" name="bake_fps" type="int" default="30" /> + <description> + </description> + </method> + <method name="write_to_filesystem"> + <return type="int" enum="Error" /> + <argument index="0" name="state" type="GLTFState" /> <argument index="1" name="path" type="String" /> - <argument index="2" name="src_path" type="String" /> - <argument index="3" name="flags" type="int" default="0" /> - <argument index="4" name="bake_fps" type="float" default="30" /> - <argument index="5" name="state" type="GLTFState" default="null" /> <description> - Save a scene as a glTF2 ".glb" or ".gltf" file. </description> </method> </methods> diff --git a/modules/gltf/doc_classes/GLTFMesh.xml b/modules/gltf/doc_classes/GLTFMesh.xml index 1e7199d229..58853217e2 100644 --- a/modules/gltf/doc_classes/GLTFMesh.xml +++ b/modules/gltf/doc_classes/GLTFMesh.xml @@ -9,6 +9,8 @@ <members> <member name="blend_weights" type="PackedFloat32Array" setter="set_blend_weights" getter="get_blend_weights" default="PackedFloat32Array()"> </member> + <member name="instance_materials" type="Array" setter="set_instance_materials" getter="get_instance_materials" default="[]"> + </member> <member name="mesh" type="ImporterMesh" setter="set_mesh" getter="get_mesh"> </member> </members> diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp index 25fda7ef3b..fd5741605c 100644 --- a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp +++ b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,6 +36,7 @@ #include "core/templates/vector.h" #include "editor/editor_file_system.h" #include "gltf_document.h" +#include "gltf_state.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/gui/check_box.h" #include "scene/main/node.h" @@ -75,7 +76,15 @@ void SceneExporterGLTFPlugin::_gltf2_dialog_action(String p_file) { List<String> deps; Ref<GLTFDocument> doc; doc.instantiate(); - Error err = doc->save_scene(root, p_file, p_file, 0, 30.0f, Ref<GLTFState>()); + Ref<GLTFState> state; + state.instantiate(); + int32_t flags = 0; + flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; + Error err = doc->append_from_scene(root, state, flags, 30.0f); + if (err != OK) { + ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err))); + } + err = doc->write_to_filesystem(state, p_file); if (err != OK) { ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err))); } diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.h b/modules/gltf/editor_scene_exporter_gltf_plugin.h index 89a8e27053..e6b15e73c4 100644 --- a/modules/gltf/editor_scene_exporter_gltf_plugin.h +++ b/modules/gltf/editor_scene_exporter_gltf_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/editor_scene_importer_gltf.cpp b/modules/gltf/editor_scene_importer_gltf.cpp index 25875e7396..f063cc1e2b 100644 --- a/modules/gltf/editor_scene_importer_gltf.cpp +++ b/modules/gltf/editor_scene_importer_gltf.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -38,26 +38,34 @@ #include "scene/animation/animation_player.h" #include "scene/resources/animation.h" -uint32_t EditorSceneImporterGLTF::get_import_flags() const { +uint32_t EditorSceneFormatImporterGLTF::get_import_flags() const { return ImportFlags::IMPORT_SCENE | ImportFlags::IMPORT_ANIMATION; } -void EditorSceneImporterGLTF::get_extensions(List<String> *r_extensions) const { +void EditorSceneFormatImporterGLTF::get_extensions(List<String> *r_extensions) const { r_extensions->push_back("gltf"); r_extensions->push_back("glb"); } -Node *EditorSceneImporterGLTF::import_scene(const String &p_path, - uint32_t p_flags, int p_bake_fps, +Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, + uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { Ref<GLTFDocument> doc; doc.instantiate(); - return doc->import_scene_gltf(p_path, p_flags, p_bake_fps, Ref<GLTFState>(), r_missing_deps, r_err); + Ref<GLTFState> state; + state.instantiate(); + Error err = doc->append_from_file(p_path, state, p_flags, p_bake_fps); + if (err != OK) { + *r_err = err; + return nullptr; + } + Node *root = doc->generate_scene(state, p_bake_fps); + return root; } -Ref<Animation> EditorSceneImporterGLTF::import_animation(const String &p_path, - uint32_t p_flags, +Ref<Animation> EditorSceneFormatImporterGLTF::import_animation(const String &p_path, + uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) { return Ref<Animation>(); } diff --git a/modules/gltf/editor_scene_importer_gltf.h b/modules/gltf/editor_scene_importer_gltf.h index 90663612a1..4410559b3d 100644 --- a/modules/gltf/editor_scene_importer_gltf.h +++ b/modules/gltf/editor_scene_importer_gltf.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,15 +41,15 @@ class Animation; -class EditorSceneImporterGLTF : public EditorSceneImporter { - GDCLASS(EditorSceneImporterGLTF, EditorSceneImporter); +class EditorSceneFormatImporterGLTF : public EditorSceneFormatImporter { + GDCLASS(EditorSceneFormatImporterGLTF, EditorSceneFormatImporter); public: virtual uint32_t get_import_flags() const override; virtual void get_extensions(List<String> *r_extensions) const override; - virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; + virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; virtual Ref<Animation> import_animation(const String &p_path, - uint32_t p_flags, int p_bake_fps) override; + uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override; }; #endif // TOOLS_ENABLED #endif // EDITOR_SCENE_IMPORTER_GLTF_H diff --git a/modules/gltf/gltf_accessor.cpp b/modules/gltf/gltf_accessor.cpp index 85cec3fec4..1daf2f90a7 100644 --- a/modules/gltf/gltf_accessor.cpp +++ b/modules/gltf/gltf_accessor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_accessor.h b/modules/gltf/gltf_accessor.h index bec511f974..6bf1bf543a 100644 --- a/modules/gltf/gltf_accessor.h +++ b/modules/gltf/gltf_accessor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_animation.cpp b/modules/gltf/gltf_animation.cpp index 889a8e8870..c857be4b2c 100644 --- a/modules/gltf/gltf_animation.cpp +++ b/modules/gltf/gltf_animation.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_animation.h b/modules/gltf/gltf_animation.h index be0ed2d4c6..ba8ae8a273 100644 --- a/modules/gltf/gltf_animation.h +++ b/modules/gltf/gltf_animation.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -50,7 +50,7 @@ public: template <class T> struct Channel { Interpolation interpolation; - Vector<float> times; + Vector<real_t> times; Vector<T> values; }; @@ -58,7 +58,7 @@ public: Channel<Vector3> position_track; Channel<Quaternion> rotation_track; Channel<Vector3> scale_track; - Vector<Channel<float>> weight_tracks; + Vector<Channel<real_t>> weight_tracks; }; public: diff --git a/modules/gltf/gltf_buffer_view.cpp b/modules/gltf/gltf_buffer_view.cpp index d00e0f040f..fc467367c6 100644 --- a/modules/gltf/gltf_buffer_view.cpp +++ b/modules/gltf/gltf_buffer_view.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_buffer_view.h b/modules/gltf/gltf_buffer_view.h index 63af5e7c0d..560d56f35c 100644 --- a/modules/gltf/gltf_buffer_view.h +++ b/modules/gltf/gltf_buffer_view.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_camera.cpp b/modules/gltf/gltf_camera.cpp index 0f895fb989..f3ea6a1c4c 100644 --- a/modules/gltf/gltf_camera.cpp +++ b/modules/gltf/gltf_camera.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_camera.h b/modules/gltf/gltf_camera.h index 843ff417a4..c696d4cc6b 100644 --- a/modules/gltf/gltf_camera.h +++ b/modules/gltf/gltf_camera.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index ba98592600..833bcb00e6 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -48,6 +48,7 @@ #include "core/error/error_macros.h" #include "core/io/dir_access.h" #include "core/io/file_access.h" +#include "core/io/file_access_memory.h" #include "core/io/json.h" #include "core/math/disjoint_set.h" #include "core/math/vector2.h" @@ -62,13 +63,14 @@ #include "scene/3d/camera_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" +#include "scene/3d/node_3d.h" #include "scene/animation/animation_player.h" #include "scene/resources/importer_mesh.h" #include "scene/resources/mesh.h" #include "scene/resources/multimesh.h" #include "scene/resources/surface_tool.h" -#include "modules/modules_enabled.gen.h" +#include "modules/modules_enabled.gen.h" // For csg, gridmap. #ifdef MODULE_CSG_ENABLED #include "modules/csg/csg_shape.h" @@ -82,13 +84,7 @@ #include <cstdint> #include <limits> -Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &p_path) { - uint64_t begin_time = OS::get_singleton()->get_ticks_usec(); - - state->skeleton3d_to_gltf_skeleton.clear(); - state->skin_and_skeleton3d_to_gltf_skin.clear(); - - _convert_scene_node(state, p_root, -1, -1); +Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) { if (!state->buffers.size()) { state->buffers.push_back(Vector<uint8_t>()); } @@ -120,26 +116,26 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String & return Error::FAILED; } - /* STEP 7 SERIALIZE IMAGES */ - err = _serialize_images(state, p_path); + /* STEP 7 SERIALIZE ANIMATIONS */ + err = _serialize_animations(state); if (err != OK) { return Error::FAILED; } - /* STEP 8 SERIALIZE TEXTURES */ - err = _serialize_textures(state); + /* STEP 8 SERIALIZE ACCESSORS */ + err = _encode_accessors(state); if (err != OK) { return Error::FAILED; } - // /* STEP 9 SERIALIZE ANIMATIONS */ - err = _serialize_animations(state); + /* STEP 9 SERIALIZE IMAGES */ + err = _serialize_images(state, p_path); if (err != OK) { return Error::FAILED; } - /* STEP 10 SERIALIZE ACCESSORS */ - err = _encode_accessors(state); + /* STEP 10 SERIALIZE TEXTURES */ + err = _serialize_textures(state); if (err != OK) { return Error::FAILED; } @@ -184,16 +180,6 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String & return Error::FAILED; } - /* STEP 17 SERIALIZE FILE */ - err = _serialize_file(state, p_path); - if (err != OK) { - return Error::FAILED; - } - uint64_t elapsed = OS::get_singleton()->get_ticks_usec() - begin_time; - float elapsed_sec = double(elapsed) / 1000000.0; - elapsed_sec = Math::snapped(elapsed_sec, 0.01f); - print_line("glTF: Export time elapsed seconds " + rtos(elapsed_sec).pad_decimals(2)); - return OK; } @@ -247,7 +233,7 @@ Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> state) { JSON json; err = json.parse(text); if (err != OK) { - _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); return err; } state->json = json.get_data(); @@ -255,18 +241,14 @@ Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> state) { return OK; } -Error GLTFDocument::_parse_glb(const String &p_path, Ref<GLTFState> state) { - Error err; - FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err); - if (!f) { - return err; - } - +Error GLTFDocument::_parse_glb(FileAccess *f, Ref<GLTFState> state) { + ERR_FAIL_NULL_V(f, ERR_INVALID_PARAMETER); + ERR_FAIL_NULL_V(state, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(f->get_position() != 0, ERR_FILE_CANT_READ); uint32_t magic = f->get_32(); ERR_FAIL_COND_V(magic != 0x46546C67, ERR_FILE_UNRECOGNIZED); //glTF f->get_32(); // version f->get_32(); // length - uint32_t chunk_length = f->get_32(); uint32_t chunk_type = f->get_32(); @@ -280,9 +262,9 @@ Error GLTFDocument::_parse_glb(const String &p_path, Ref<GLTFState> state) { text.parse_utf8((const char *)json_data.ptr(), json_data.size()); JSON json; - err = json.parse(text); + Error err = json.parse(text); if (err != OK) { - _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error("", "", json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); return err; } @@ -753,6 +735,8 @@ Error GLTFDocument::_parse_buffers(Ref<GLTFState> state, const String &p_base_pa } buffer_data = _parse_base64_uri(uri); } else { // Relative path to an external image file. + ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER); + uri = uri.uri_decode(); uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows. buffer_data = FileAccess::get_file_as_array(uri); ERR_FAIL_COND_V_MSG(buffer.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri); @@ -795,6 +779,9 @@ Error GLTFDocument::_encode_buffer_views(Ref<GLTFState> state) { buffers.push_back(d); } print_verbose("glTF: Total buffer views: " + itos(state->buffer_views.size())); + if (!buffers.size()) { + return OK; + } state->json["bufferViews"] = buffers; return OK; } @@ -884,6 +871,9 @@ Error GLTFDocument::_encode_accessors(Ref<GLTFState> state) { accessors.push_back(d); } + if (!accessors.size()) { + return OK; + } state->json["accessors"] = accessors; ERR_FAIL_COND_V(!state->json.has("accessors"), ERR_FILE_CORRUPT); print_verbose("glTF: Total accessors: " + itos(state->accessors.size())); @@ -2112,6 +2102,7 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { if (import_mesh.is_null()) { continue; } + Array instance_materials = state->meshes.write[gltf_mesh_i]->get_instance_materials(); Array primitives; Dictionary gltf_mesh; Array target_names; @@ -2431,7 +2422,14 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { } } - Ref<BaseMaterial3D> mat = import_mesh->get_surface_material(surface_i); + Variant v; + if (surface_i < instance_materials.size()) { + v = instance_materials.get(surface_i); + } + Ref<BaseMaterial3D> mat = v; + if (!mat.is_valid()) { + mat = import_mesh->get_surface_material(surface_i); + } if (mat.is_valid()) { Map<Ref<BaseMaterial3D>, GLTFMaterialIndex>::Element *material_cache_i = state->material_cache.find(mat); if (material_cache_i && material_cache_i->get() != -1) { @@ -2475,6 +2473,9 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { meshes.push_back(gltf_mesh); } + if (!meshes.size()) { + return OK; + } state->json["meshes"] = meshes; print_verbose("glTF: Total meshes: " + itos(meshes.size())); @@ -2498,8 +2499,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) { ERR_FAIL_COND_V(!d.has("primitives"), ERR_PARSE_ERROR); Array primitives = d["primitives"]; - const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : - Dictionary(); + const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary(); Ref<ImporterMesh> import_mesh; import_mesh.instantiate(); String mesh_name = "mesh"; @@ -2523,14 +2523,16 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) { if (p.has("mode")) { const int mode = p["mode"]; ERR_FAIL_INDEX_V(mode, 7, ERR_FILE_CORRUPT); + // Convert mesh.primitive.mode to Godot Mesh enum. See: + // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode static const Mesh::PrimitiveType primitives2[7] = { - Mesh::PRIMITIVE_POINTS, - Mesh::PRIMITIVE_LINES, - Mesh::PRIMITIVE_LINES, //loop not supported, should ce converted - Mesh::PRIMITIVE_LINES, - Mesh::PRIMITIVE_TRIANGLES, - Mesh::PRIMITIVE_TRIANGLE_STRIP, - Mesh::PRIMITIVE_TRIANGLES, //fan not supported, should be converted + Mesh::PRIMITIVE_POINTS, // 0 POINTS + Mesh::PRIMITIVE_LINES, // 1 LINES + Mesh::PRIMITIVE_LINES, // 2 LINE_LOOP; loop not supported, should be converted + Mesh::PRIMITIVE_LINE_STRIP, // 3 LINE_STRIP + Mesh::PRIMITIVE_TRIANGLES, // 4 TRIANGLES + Mesh::PRIMITIVE_TRIANGLE_STRIP, // 5 TRIANGLE_STRIP + Mesh::PRIMITIVE_TRIANGLES, // 6 TRIANGLE_FAN fan not supported, should be converted #ifndef _MSC_VER #warning line loop and triangle fan are not supported and need to be converted to lines and triangles #endif @@ -2936,7 +2938,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path Ref<Image> image = state->images[i]->get_image(); ERR_CONTINUE(image.is_null()); - if (p_path.to_lower().ends_with("glb")) { + if (p_path.to_lower().ends_with("glb") || p_path.is_empty()) { GLTFBufferViewIndex bvi; Ref<GLTFBufferView> bv; @@ -2965,6 +2967,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path d["bufferView"] = bvi; d["mimeType"] = "image/png"; } else { + ERR_FAIL_COND_V(p_path.is_empty(), ERR_INVALID_PARAMETER); String name = state->images[i]->get_name(); if (name.is_empty()) { name = itos(i); @@ -2972,13 +2975,14 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path name = _gen_unique_name(state, name); name = name.pad_zeros(3) + ".png"; String texture_dir = "textures"; - String new_texture_dir = p_path.get_base_dir() + "/" + texture_dir; - DirAccessRef da = DirAccess::open(p_path.get_base_dir()); + String path = p_path.get_base_dir(); + String new_texture_dir = path + "/" + texture_dir; + DirAccessRef da = DirAccess::open(path); if (!da->dir_exists(new_texture_dir)) { da->make_dir(new_texture_dir); } image->save_png(new_texture_dir.plus_file(name)); - d["uri"] = texture_dir.plus_file(name); + d["uri"] = texture_dir.plus_file(name).uri_encode(); } images.push_back(d); } @@ -2994,6 +2998,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path } Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_path) { + ERR_FAIL_NULL_V(state, ERR_INVALID_PARAMETER); if (!state->json.has("images")) { return OK; } @@ -3053,6 +3058,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat } } } else { // Relative path to an external image file. + ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER); uri = uri.uri_decode(); uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows. // ResourceLoader will rely on the file extension to use the relevant loader. @@ -3386,29 +3392,32 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { tex.instantiate(); { Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL); - // Code for uncompressing RG normal maps - Ref<Image> img = normal_texture->get_image(); - Ref<ImageTexture> img_tex = img; - if (img_tex.is_valid()) { - img = img_tex->get_image(); - } - img->decompress(); - img->convert(Image::FORMAT_RGBA8); - img->convert_ra_rgba8_to_rg(); - for (int32_t y = 0; y < img->get_height(); y++) { - for (int32_t x = 0; x < img->get_width(); x++) { - Color c = img->get_pixel(x, y); - Vector2 red_green = Vector2(c.r, c.g); - red_green = red_green * Vector2(2.0f, 2.0f) - Vector2(1.0f, 1.0f); - float blue = 1.0f - red_green.dot(red_green); - blue = MAX(0.0f, blue); - c.b = Math::sqrt(blue); - img->set_pixel(x, y, c); + if (normal_texture.is_valid()) { + // Code for uncompressing RG normal maps + Ref<Image> img = normal_texture->get_image(); + if (img.is_valid()) { + Ref<ImageTexture> img_tex = img; + if (img_tex.is_valid()) { + img = img_tex->get_image(); + } + img->decompress(); + img->convert(Image::FORMAT_RGBA8); + img->convert_ra_rgba8_to_rg(); + for (int32_t y = 0; y < img->get_height(); y++) { + for (int32_t x = 0; x < img->get_width(); x++) { + Color c = img->get_pixel(x, y); + Vector2 red_green = Vector2(c.r, c.g); + red_green = red_green * Vector2(2.0f, 2.0f) - Vector2(1.0f, 1.0f); + float blue = 1.0f - red_green.dot(red_green); + blue = MAX(0.0f, blue); + c.b = Math::sqrt(blue); + img->set_pixel(x, y, c); + } + } + tex->create_from_image(img); } } - tex->create_from_image(img); } - Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL); GLTFTextureIndex gltf_texture_index = -1; if (tex.is_valid() && tex->get_image().is_valid()) { tex->set_name(material->get_name() + "_normal"); @@ -3455,6 +3464,9 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { } materials.push_back(d); } + if (!materials.size()) { + return OK; + } state->json["materials"] = materials; print_verbose("Total materials: " + itos(state->materials.size())); @@ -4319,6 +4331,9 @@ Error GLTFDocument::_create_skeletons(Ref<GLTFState> state) { skeleton->add_bone(node->get_name()); skeleton->set_bone_rest(bone_index, node->xform); + skeleton->set_bone_pose_position(bone_index, node->position); + skeleton->set_bone_pose_rotation(bone_index, node->rotation.normalized()); + skeleton->set_bone_pose_scale(bone_index, node->scale); if (node->parent >= 0 && state->nodes[node->parent]->skeleton == skel_i) { const int bone_parent = skeleton->find_bone(state->nodes[node->parent]->get_name()); @@ -4366,6 +4381,10 @@ Error GLTFDocument::_serialize_skins(Ref<GLTFState> state) { json_skin["name"] = gltf_skin->get_name(); json_skins.push_back(json_skin); } + if (!state->skins.size()) { + return OK; + } + state->json["skins"] = json_skins; return OK; } @@ -4580,7 +4599,7 @@ Error GLTFDocument::_parse_lights(Ref<GLTFState> state) { light->outer_cone_angle = spot["outerConeAngle"]; ERR_CONTINUE_MSG(light->inner_cone_angle >= light->outer_cone_angle, "The inner angle must be smaller than the outer angle."); } else if (type != "point" && type != "directional") { - ERR_CONTINUE_MSG(ERR_PARSE_ERROR, "Light type is unknown."); + ERR_CONTINUE_MSG(true, "Light type is unknown."); } state->lights.push_back(light); @@ -4778,7 +4797,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { bool last = false; Vector<real_t> weight_track; while (true) { - float weight = _interpolate_track<float>(track.weight_tracks[track_idx].times, + float weight = _interpolate_track<real_t>(track.weight_tracks[track_idx].times, track.weight_tracks[track_idx].values, time, track.weight_tracks[track_idx].interpolation); @@ -4802,7 +4821,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { int32_t weight_tracks_size = track.weight_tracks.size(); all_track_values.resize(weight_tracks_size * values_size); for (int k = 0; k < track.weight_tracks.size(); k++) { - Vector<float> wdata = track.weight_tracks[k].values; + Vector<real_t> wdata = track.weight_tracks[k].values; for (int l = 0; l < wdata.size(); l++) { int32_t index = l * weight_tracks_size + k; ERR_BREAK(index >= all_track_values.size()); @@ -4831,6 +4850,9 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { } } + if (!animations.size()) { + return OK; + } state->json["animations"] = animations; print_verbose("glTF: Total animations '" + itos(state->animations.size()) + "'."); @@ -4950,10 +4972,10 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) { const int wlen = weights.size() / wc; for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea - GLTFAnimation::Channel<float> cf; + GLTFAnimation::Channel<real_t> cf; cf.interpolation = interp; cf.times = Variant(times); - Vector<float> wdata; + Vector<real_t> wdata; wdata.resize(wlen); for (int l = 0; l < wlen; l++) { wdata.write[l] = weights[l * wc + k]; @@ -5051,6 +5073,18 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> state, MeshInst } Ref<GLTFMesh> gltf_mesh; gltf_mesh.instantiate(); + Array instance_materials; + for (int32_t surface_i = 0; surface_i < current_mesh->get_surface_count(); surface_i++) { + Ref<Material> mat = current_mesh->get_surface_material(surface_i); + if (p_mesh_instance->get_surface_override_material(surface_i).is_valid()) { + mat = p_mesh_instance->get_surface_override_material(surface_i); + } + if (p_mesh_instance->get_material_override().is_valid()) { + mat = p_mesh_instance->get_material_override(); + } + instance_materials.append(mat); + } + gltf_mesh->set_instance_materials(instance_materials); gltf_mesh->set_mesh(current_mesh); gltf_mesh->set_blend_weights(blend_weights); GLTFMeshIndex mesh_i = state->meshes.size(); @@ -5058,7 +5092,7 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> state, MeshInst return mesh_i; } -ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index) { +ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> state, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; ERR_FAIL_INDEX_V(gltf_node->mesh, state->meshes.size(), nullptr); @@ -5078,7 +5112,7 @@ ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> sta return mi; } -Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { +Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; ERR_FAIL_INDEX_V(gltf_node->light, state->lights.size(), nullptr); @@ -5130,7 +5164,7 @@ Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, return memnew(Node3D); } -Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { +Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> state, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; ERR_FAIL_INDEX_V(gltf_node->camera, state->cameras.size(), nullptr); @@ -5208,7 +5242,7 @@ void GLTFDocument::_convert_spatial(Ref<GLTFState> state, Node3D *p_spatial, Ref p_node->position = xform.origin; } -Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { +Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; Node3D *spatial = memnew(Node3D); @@ -5440,7 +5474,7 @@ void GLTFDocument::_convert_multi_mesh_instance_to_gltf( transform = p_multi_mesh_instance->get_transform() * transform; } else if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_3D) { transform = p_multi_mesh_instance->get_transform() * - multi_mesh->get_instance_transform(instance_i); + multi_mesh->get_instance_transform(instance_i); } Ref<GLTFNode> new_gltf_node; new_gltf_node.instantiate(); @@ -5470,7 +5504,7 @@ void GLTFDocument::_convert_skeleton_to_gltf(Skeleton3D *p_skeleton3d, Ref<GLTFS // Note that we cannot use _gen_unique_bone_name here, because glTF spec requires all node // names to be unique regardless of whether or not they are used as joints. joint_node->set_name(_gen_unique_name(state, skeleton->get_bone_name(bone_i))); - Transform3D xform = skeleton->get_bone_rest(bone_i) * skeleton->get_bone_pose(bone_i); + Transform3D xform = skeleton->get_bone_pose(bone_i); joint_node->scale = xform.basis.get_scale(); joint_node->rotation = xform.basis.get_rotation_quaternion(); joint_node->position = xform.origin; @@ -5564,7 +5598,7 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent // Bone Attachment - Parent Case BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index, gltf_node->parent); - scene_parent->add_child(bone_attachment); + scene_parent->add_child(bone_attachment, true); bone_attachment->set_owner(scene_root); // There is no gltf_node that represent this, so just directly create a unique name @@ -5575,18 +5609,17 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent scene_parent = bone_attachment; } if (gltf_node->mesh >= 0) { - current_node = _generate_mesh_instance(state, scene_parent, node_index); + current_node = _generate_mesh_instance(state, node_index); } else if (gltf_node->camera >= 0) { - current_node = _generate_camera(state, scene_parent, node_index); + current_node = _generate_camera(state, node_index); } else if (gltf_node->light >= 0) { - current_node = _generate_light(state, scene_parent, node_index); + current_node = _generate_light(state, node_index); } // We still have not managed to make a node. if (!current_node) { - current_node = _generate_spatial(state, scene_parent, node_index); + current_node = _generate_spatial(state, node_index); } - scene_parent->add_child(current_node); if (current_node != scene_root) { current_node->set_owner(scene_root); @@ -5617,7 +5650,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> state, Node *scen // Bone Attachment - Direct Parented Skeleton Case BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index, gltf_node->parent); - scene_parent->add_child(bone_attachment); + scene_parent->add_child(bone_attachment, true); bone_attachment->set_owner(scene_root); // There is no gltf_node that represent this, so just directly create a unique name @@ -5631,7 +5664,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> state, Node *scen // Add it to the scene if it has not already been added if (skeleton->get_parent() == nullptr) { - scene_parent->add_child(skeleton); + scene_parent->add_child(skeleton, true); skeleton->set_owner(scene_root); } } @@ -5645,7 +5678,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> state, Node *scen // Bone Attachment - Same Node Case BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index, node_index); - scene_parent->add_child(bone_attachment); + scene_parent->add_child(bone_attachment, true); bone_attachment->set_owner(scene_root); // There is no gltf_node that represent this, so just directly create a unique name @@ -5658,14 +5691,14 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> state, Node *scen // We still have not managed to make a node if (gltf_node->mesh >= 0) { - current_node = _generate_mesh_instance(state, scene_parent, node_index); + current_node = _generate_mesh_instance(state, node_index); } else if (gltf_node->camera >= 0) { - current_node = _generate_camera(state, scene_parent, node_index); + current_node = _generate_camera(state, node_index); } else if (gltf_node->light >= 0) { - current_node = _generate_light(state, scene_parent, node_index); + current_node = _generate_light(state, node_index); } - scene_parent->add_child(current_node); + scene_parent->add_child(current_node, true); if (current_node != scene_root) { current_node->set_owner(scene_root); } @@ -5681,7 +5714,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> state, Node *scen } template <class T> -struct EditorSceneImporterGLTFInterpolate { +struct EditorSceneFormatImporterGLTFInterpolate { T lerp(const T &a, const T &b, float c) const { return a + (b - a) * c; } @@ -5707,7 +5740,7 @@ struct EditorSceneImporterGLTFInterpolate { // thank you for existing, partial specialization template <> -struct EditorSceneImporterGLTFInterpolate<Quaternion> { +struct EditorSceneFormatImporterGLTFInterpolate<Quaternion> { Quaternion lerp(const Quaternion &a, const Quaternion &b, const float c) const { ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quaternion(), "The quaternion \"a\" must be normalized."); ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quaternion(), "The quaternion \"b\" must be normalized."); @@ -5731,9 +5764,9 @@ struct EditorSceneImporterGLTFInterpolate<Quaternion> { }; template <class T> -T GLTFDocument::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) { +T GLTFDocument::_interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) { ERR_FAIL_COND_V(!p_values.size(), T()); - if (p_times.size() != p_values.size()) { + if (p_times.size() != (p_values.size() / (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE ? 3 : 1))) { ERR_PRINT_ONCE("The interpolated values are not corresponding to its times."); return p_values[0]; } @@ -5746,7 +5779,7 @@ T GLTFDocument::_interpolate_track(const Vector<float> &p_times, const Vector<T> idx++; } - EditorSceneImporterGLTFInterpolate<T> interp; + EditorSceneFormatImporterGLTFInterpolate<T> interp; switch (p_interp) { case GLTFAnimation::INTERP_LINEAR: { @@ -5815,7 +5848,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, animation->set_name(name); if (anim->get_loop()) { - animation->set_loop(true); + animation->set_loop_mode(Animation::LOOP_LINEAR); } float length = 0.0; @@ -5868,9 +5901,67 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, const bool transform_affects_skinned_mesh_instance = gltf_node->skeleton < 0 && gltf_node->skin >= 0; if ((track.rotation_track.values.size() || track.position_track.values.size() || track.scale_track.values.size()) && !transform_affects_skinned_mesh_instance) { //make transform track - int track_idx = animation->get_track_count(); - animation->add_track(Animation::TYPE_TRANSFORM3D); - animation->track_set_path(track_idx, transform_node_path); + int base_idx = animation->get_track_count(); + int position_idx = -1; + int rotation_idx = -1; + int scale_idx = -1; + + if (track.position_track.values.size()) { + Vector3 base_pos = state->nodes[track_i.key]->position; + bool not_default = false; //discard the track if all it contains is default values + for (int i = 0; i < track.position_track.times.size(); i++) { + Vector3 value = track.position_track.values[track.position_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i]; + if (!value.is_equal_approx(base_pos)) { + not_default = true; + break; + } + } + if (not_default) { + position_idx = base_idx; + animation->add_track(Animation::TYPE_POSITION_3D); + animation->track_set_path(position_idx, transform_node_path); + animation->track_set_imported(position_idx, true); //helps merging later + + base_idx++; + } + } + if (track.rotation_track.values.size()) { + Quaternion base_rot = state->nodes[track_i.key]->rotation.normalized(); + bool not_default = false; //discard the track if all it contains is default values + for (int i = 0; i < track.rotation_track.times.size(); i++) { + Quaternion value = track.rotation_track.values[track.rotation_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i].normalized(); + if (!value.is_equal_approx(base_rot)) { + not_default = true; + break; + } + } + if (not_default) { + rotation_idx = base_idx; + animation->add_track(Animation::TYPE_ROTATION_3D); + animation->track_set_path(rotation_idx, transform_node_path); + animation->track_set_imported(rotation_idx, true); //helps merging later + base_idx++; + } + } + if (track.scale_track.values.size()) { + Vector3 base_scale = state->nodes[track_i.key]->scale; + bool not_default = false; //discard the track if all it contains is default values + for (int i = 0; i < track.scale_track.times.size(); i++) { + Vector3 value = track.scale_track.values[track.scale_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i]; + if (!value.is_equal_approx(base_scale)) { + not_default = true; + break; + } + } + if (not_default) { + scale_idx = base_idx; + animation->add_track(Animation::TYPE_SCALE_3D); + animation->track_set_path(scale_idx, transform_node_path); + animation->track_set_imported(scale_idx, true); //helps merging later + base_idx++; + } + } + //first determine animation length const double increment = 1.0 / bake_fps; @@ -5880,15 +5971,15 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, Quaternion base_rot; Vector3 base_scale = Vector3(1, 1, 1); - if (!track.rotation_track.values.size()) { + if (rotation_idx == -1) { base_rot = state->nodes[track_i.key]->rotation.normalized(); } - if (!track.position_track.values.size()) { + if (position_idx == -1) { base_pos = state->nodes[track_i.key]->position; } - if (!track.scale_track.values.size()) { + if (scale_idx == -1) { base_scale = state->nodes[track_i.key]->scale; } @@ -5898,35 +5989,21 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, Quaternion rot = base_rot; Vector3 scale = base_scale; - if (track.position_track.times.size()) { + if (position_idx >= 0) { pos = _interpolate_track<Vector3>(track.position_track.times, track.position_track.values, time, track.position_track.interpolation); + animation->position_track_insert_key(position_idx, time, pos); } - if (track.rotation_track.times.size()) { + if (rotation_idx >= 0) { rot = _interpolate_track<Quaternion>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation); + animation->rotation_track_insert_key(rotation_idx, time, rot); } - if (track.scale_track.times.size()) { + if (scale_idx >= 0) { scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation); + animation->scale_track_insert_key(scale_idx, time, scale); } - if (gltf_node->skeleton >= 0) { - Transform3D xform; - xform.basis.set_quaternion_scale(rot, scale); - xform.origin = pos; - - const Skeleton3D *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton; - const int bone_idx = skeleton->find_bone(gltf_node->get_name()); - xform = skeleton->get_bone_rest(bone_idx).affine_inverse() * xform; - - rot = xform.basis.get_rotation_quaternion(); - rot.normalize(); - scale = xform.basis.get_scale(); - pos = xform.origin; - } - - animation->transform_track_insert_key(track_idx, time, pos, rot, scale); - if (last) { break; } @@ -5944,12 +6021,11 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, ERR_CONTINUE(mesh.is_null()); ERR_CONTINUE(mesh->get_mesh().is_null()); ERR_CONTINUE(mesh->get_mesh()->get_mesh().is_null()); - const String prop = "blend_shapes/" + mesh->get_mesh()->get_blend_shape_name(i); - const String blend_path = String(node_path) + ":" + prop; + const String blend_path = String(node_path) + ":" + String(mesh->get_mesh()->get_blend_shape_name(i)); const int track_idx = animation->get_track_count(); - animation->add_track(Animation::TYPE_VALUE); + animation->add_track(Animation::TYPE_BLEND_SHAPE); animation->track_set_path(track_idx, blend_path); // Only LINEAR and STEP (NEAREST) can be supported out of the box by Godot's Animation, @@ -5960,7 +6036,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, for (int j = 0; j < track.weight_tracks[i].times.size(); j++) { const float t = track.weight_tracks[i].times[j]; const float attribs = track.weight_tracks[i].values[j]; - animation->track_insert_key(track_idx, t, attribs); + animation->blend_shape_track_insert_key(track_idx, t, attribs); } } else { // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. @@ -5968,7 +6044,8 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, double time = 0.0; bool last = false; while (true) { - _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp); + real_t blend = _interpolate_track<real_t>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp); + animation->blend_shape_track_insert_key(track_idx, time, blend); if (last) { break; } @@ -5999,7 +6076,9 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { continue; } MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->get()); - ERR_CONTINUE(!mi); + if (!mi) { + continue; + } Transform3D mi_xform = mi->get_transform(); node->scale = mi_xform.basis.get_scale(); node->rotation = mi_xform.basis.get_rotation_quaternion(); @@ -6030,7 +6109,10 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { int bone_cnt = skeleton->get_bone_count(); ERR_FAIL_COND(bone_cnt != gltf_skeleton->joints.size()); - ObjectID gltf_skin_key = skin->get_instance_id(); + ObjectID gltf_skin_key; + if (skin.is_valid()) { + gltf_skin_key = skin->get_instance_id(); + } ObjectID gltf_skel_key = godot_skeleton->get_instance_id(); GLTFSkinIndex skin_gltf_i = -1; GLTFNodeIndex root_gltf_i = -1; @@ -6042,7 +6124,7 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { } else { if (skin.is_null()) { // Note that gltf_skin_key should remain null, so these can share a reference. - skin = skeleton->register_skin(nullptr)->get_skin(); + skin = skeleton->create_skin_from_rest_transforms(); } gltf_skin.instantiate(); gltf_skin->godot_skin = skin; @@ -6135,7 +6217,7 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> state, Node *scene_roo ERR_CONTINUE_MSG(skeleton == nullptr, vformat("Unable to find Skeleton for node %d skin %d", node_i, skin_i)); mi->get_parent()->remove_child(mi); - skeleton->add_child(mi); + skeleton->add_child(mi, true); mi->set_owner(skeleton->get_owner()); mi->set_skin(state->skins.write[skin_i]->godot_skin); @@ -6145,7 +6227,7 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> state, Node *scene_roo } } -GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, Transform3D p_bone_rest, int32_t p_track_i, GLTFNodeIndex p_node_i) { +GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, int32_t p_track_i, GLTFNodeIndex p_node_i) { Animation::InterpolationType interpolation = p_animation->track_get_interpolation_type(p_track_i); GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR; @@ -6158,73 +6240,44 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state } Animation::TrackType track_type = p_animation->track_get_type(p_track_i); int32_t key_count = p_animation->track_get_key_count(p_track_i); - Vector<float> times; + Vector<real_t> times; times.resize(key_count); String path = p_animation->track_get_path(p_track_i); for (int32_t key_i = 0; key_i < key_count; key_i++) { times.write[key_i] = p_animation->track_get_key_time(p_track_i, key_i); } - if (track_type == Animation::TYPE_TRANSFORM3D) { - p_track.position_track.times = times; - p_track.position_track.interpolation = gltf_interpolation; - p_track.rotation_track.times = times; - p_track.rotation_track.interpolation = gltf_interpolation; + if (track_type == Animation::TYPE_SCALE_3D) { p_track.scale_track.times = times; p_track.scale_track.interpolation = gltf_interpolation; - p_track.scale_track.values.resize(key_count); - p_track.scale_track.interpolation = gltf_interpolation; - p_track.position_track.values.resize(key_count); - p_track.position_track.interpolation = gltf_interpolation; - p_track.rotation_track.values.resize(key_count); - p_track.rotation_track.interpolation = gltf_interpolation; for (int32_t key_i = 0; key_i < key_count; key_i++) { - Vector3 position; - Quaternion rotation; Vector3 scale; - Error err = p_animation->transform_track_get_key(p_track_i, key_i, &position, &rotation, &scale); + Error err = p_animation->scale_track_get_key(p_track_i, key_i, &scale); ERR_CONTINUE(err != OK); - Transform3D xform; - xform.basis.set_quaternion_scale(rotation, scale); - xform.origin = position; - xform = p_bone_rest * xform; - p_track.position_track.values.write[key_i] = xform.get_origin(); - p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quaternion(); - p_track.scale_track.values.write[key_i] = xform.basis.get_scale(); - } - } else if (path.find(":transform") != -1) { + p_track.scale_track.values.write[key_i] = scale; + } + } else if (track_type == Animation::TYPE_POSITION_3D) { p_track.position_track.times = times; + p_track.position_track.values.resize(key_count); p_track.position_track.interpolation = gltf_interpolation; + for (int32_t key_i = 0; key_i < key_count; key_i++) { + Vector3 position; + Error err = p_animation->position_track_get_key(p_track_i, key_i, &position); + ERR_CONTINUE(err != OK); + p_track.position_track.values.write[key_i] = position; + } + } else if (track_type == Animation::TYPE_ROTATION_3D) { p_track.rotation_track.times = times; p_track.rotation_track.interpolation = gltf_interpolation; - p_track.scale_track.times = times; - p_track.scale_track.interpolation = gltf_interpolation; - - p_track.scale_track.values.resize(key_count); - p_track.scale_track.interpolation = gltf_interpolation; - p_track.position_track.values.resize(key_count); - p_track.position_track.interpolation = gltf_interpolation; p_track.rotation_track.values.resize(key_count); - p_track.rotation_track.interpolation = gltf_interpolation; for (int32_t key_i = 0; key_i < key_count; key_i++) { - Transform3D xform = p_animation->track_get_key_value(p_track_i, key_i); - p_track.position_track.values.write[key_i] = xform.get_origin(); - p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quaternion(); - p_track.scale_track.values.write[key_i] = xform.basis.get_scale(); + Quaternion rotation; + Error err = p_animation->rotation_track_get_key(p_track_i, key_i, &rotation); + ERR_CONTINUE(err != OK); + p_track.rotation_track.values.write[key_i] = rotation; } } else if (track_type == Animation::TYPE_VALUE) { - if (path.find("/rotation_quat") != -1) { - p_track.rotation_track.times = times; - p_track.rotation_track.interpolation = gltf_interpolation; - - p_track.rotation_track.values.resize(key_count); - p_track.rotation_track.interpolation = gltf_interpolation; - - for (int32_t key_i = 0; key_i < key_count; key_i++) { - Quaternion rotation_track = p_animation->track_get_key_value(p_track_i, key_i); - p_track.rotation_track.values.write[key_i] = rotation_track; - } - } else if (path.find(":position") != -1) { + if (path.find(":position") != -1) { p_track.position_track.times = times; p_track.position_track.interpolation = gltf_interpolation; @@ -6262,7 +6315,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state if (path.find("/scale") != -1) { const int32_t keys = p_animation->track_get_key_time(p_track_i, key_count - 1) * BAKE_FPS; if (!p_track.scale_track.times.size()) { - Vector<float> new_times; + Vector<real_t> new_times; new_times.resize(keys); for (int32_t key_i = 0; key_i < keys; key_i++) { new_times.write[key_i] = key_i / BAKE_FPS; @@ -6282,20 +6335,17 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state Vector3 bezier_track = p_track.scale_track.values[key_i]; if (path.find("/scale:x") != -1) { bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS); - bezier_track.x = p_bone_rest.affine_inverse().basis.get_scale().x * bezier_track.x; } else if (path.find("/scale:y") != -1) { bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS); - bezier_track.y = p_bone_rest.affine_inverse().basis.get_scale().y * bezier_track.y; } else if (path.find("/scale:z") != -1) { bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS); - bezier_track.z = p_bone_rest.affine_inverse().basis.get_scale().z * bezier_track.z; } p_track.scale_track.values.write[key_i] = bezier_track; } } else if (path.find("/position") != -1) { const int32_t keys = p_animation->track_get_key_time(p_track_i, key_count - 1) * BAKE_FPS; if (!p_track.position_track.times.size()) { - Vector<float> new_times; + Vector<real_t> new_times; new_times.resize(keys); for (int32_t key_i = 0; key_i < keys; key_i++) { new_times.write[key_i] = key_i / BAKE_FPS; @@ -6311,19 +6361,15 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state Vector3 bezier_track = p_track.position_track.values[key_i]; if (path.find("/position:x") != -1) { bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS); - bezier_track.x = p_bone_rest.affine_inverse().origin.x * bezier_track.x; } else if (path.find("/position:y") != -1) { bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS); - bezier_track.y = p_bone_rest.affine_inverse().origin.y * bezier_track.y; } else if (path.find("/position:z") != -1) { bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS); - bezier_track.z = p_bone_rest.affine_inverse().origin.z * bezier_track.z; } p_track.position_track.values.write[key_i] = bezier_track; } } } - return p_track; } @@ -6350,7 +6396,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (position_track_i) { track = position_track_i->get(); } - track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index); + track = _convert_animation_track(state, track, animation, track_i, node_index); gltf_animation->get_tracks().insert(node_index, track); } } @@ -6366,7 +6412,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (rotation_degree_track_i) { track = rotation_degree_track_i->get(); } - track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index); + track = _convert_animation_track(state, track, animation, track_i, node_index); gltf_animation->get_tracks().insert(node_index, track); } } @@ -6382,7 +6428,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (scale_track_i) { track = scale_track_i->get(); } - track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index); + track = _convert_animation_track(state, track, animation, track_i, node_index); gltf_animation->get_tracks().insert(node_index, track); } } @@ -6393,7 +6439,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, for (const KeyValue<GLTFNodeIndex, Node *> &transform_track_i : state->scene_nodes) { if (transform_track_i.value == node) { GLTFAnimation::Track track; - track = _convert_animation_track(state, track, animation, Transform3D(), track_i, transform_track_i.key); + track = _convert_animation_track(state, track, animation, track_i, transform_track_i.key); gltf_animation->get_tracks().insert(transform_track_i.key, track); } } @@ -6417,10 +6463,10 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (!tracks.has(mesh_index)) { for (int32_t shape_i = 0; shape_i < mesh->get_blend_shape_count(); shape_i++) { String shape_name = mesh->get_blend_shape_name(shape_i); - NodePath shape_path = String(path) + ":blend_shapes/" + shape_name; - int32_t shape_track_i = animation->find_track(shape_path); + NodePath shape_path = String(path) + ":" + shape_name; + int32_t shape_track_i = animation->find_track(shape_path, Animation::TYPE_BLEND_SHAPE); if (shape_track_i == -1) { - GLTFAnimation::Channel<float> weight; + GLTFAnimation::Channel<real_t> weight; weight.interpolation = GLTFAnimation::INTERP_LINEAR; weight.times.push_back(0.0f); weight.times.push_back(0.0f); @@ -6439,7 +6485,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE; } int32_t key_count = animation->track_get_key_count(shape_track_i); - GLTFAnimation::Channel<float> weight; + GLTFAnimation::Channel<real_t> weight; weight.interpolation = gltf_interpolation; weight.times.resize(key_count); for (int32_t time_i = 0; time_i < key_count; time_i++) { @@ -6470,7 +6516,6 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, Ref<GLTFSkeleton> skeleton_gltf = state->skeletons[skeleton_gltf_i]; int32_t bone = skeleton->find_bone(suffix); ERR_CONTINUE(bone == -1); - Transform3D xform = skeleton->get_bone_rest(bone); if (!skeleton_gltf->godot_bone_node.has(bone)) { continue; } @@ -6480,27 +6525,24 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (property_track_i) { track = property_track_i->get(); } - track = _convert_animation_track(state, track, animation, xform, track_i, node_i); + track = _convert_animation_track(state, track, animation, track_i, node_i); gltf_animation->get_tracks()[node_i] = track; } } } else if (String(orig_track_path).find(":") == -1) { ERR_CONTINUE(!ap->get_parent()); - for (int32_t node_i = 0; node_i < ap->get_parent()->get_child_count(); node_i++) { - const Node *child = ap->get_parent()->get_child(node_i); - const Node *node = child->get_node_or_null(orig_track_path); - for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : state->scene_nodes) { - if (scene_node_i.value == node) { - GLTFNodeIndex node_index = scene_node_i.key; - Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_index); - GLTFAnimation::Track track; - if (node_track_i) { - track = node_track_i->get(); - } - track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index); - gltf_animation->get_tracks().insert(node_index, track); - break; + Node *godot_node = ap->get_parent()->get_node_or_null(orig_track_path); + for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : state->scene_nodes) { + if (scene_node_i.value == godot_node) { + GLTFNodeIndex node_i = scene_node_i.key; + Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_i); + GLTFAnimation::Track track; + if (node_track_i) { + track = node_track_i->get(); } + track = _convert_animation_track(state, track, animation, track_i, node_i); + gltf_animation->get_tracks()[node_i] = track; + break; } } } @@ -6510,142 +6552,57 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, } } -Error GLTFDocument::parse(Ref<GLTFState> state, String p_path, bool p_read_binary) { +Error GLTFDocument::_parse(Ref<GLTFState> state, String p_path, FileAccess *f, int p_bake_fps) { Error err; - FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err); if (!f) { - return err; + return FAILED; } + f->seek(0); uint32_t magic = f->get_32(); if (magic == 0x46546C67) { //binary file //text file - err = _parse_glb(p_path, state); - if (err) { - return FAILED; + f->seek(0); + err = _parse_glb(f, state); + if (err != OK) { + return err; } } else { - //text file - err = _parse_json(p_path, state); - if (err) { - return FAILED; + f->seek(0); + String text = f->get_as_utf8_string(); + JSON json; + err = json.parse(text); + if (err != OK) { + _err_print_error("", "", json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); } + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + state->json = json.get_data(); } f->close(); - // get file's name, use for scene name if none - state->filename = p_path.get_file().get_slice(".", 0); - - ERR_FAIL_COND_V(!state->json.has("asset"), Error::FAILED); + if (!state->json.has("asset")) { + return ERR_PARSE_ERROR; + } Dictionary asset = state->json["asset"]; - ERR_FAIL_COND_V(!asset.has("version"), Error::FAILED); + if (!asset.has("version")) { + return ERR_PARSE_ERROR; + } String version = asset["version"]; state->major_version = version.get_slice(".", 0).to_int(); state->minor_version = version.get_slice(".", 1).to_int(); - /* STEP 0 PARSE SCENE */ - err = _parse_scenes(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 1 PARSE NODES */ - err = _parse_nodes(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 2 PARSE BUFFERS */ - err = _parse_buffers(state, p_path.get_base_dir()); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 3 PARSE BUFFER VIEWS */ - err = _parse_buffer_views(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 4 PARSE ACCESSORS */ - err = _parse_accessors(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 5 PARSE IMAGES */ - err = _parse_images(state, p_path.get_base_dir()); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 6 PARSE TEXTURES */ - err = _parse_textures(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 7 PARSE TEXTURES */ - err = _parse_materials(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 9 PARSE SKINS */ - err = _parse_skins(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 10 DETERMINE SKELETONS */ - err = _determine_skeletons(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 11 CREATE SKELETONS */ - err = _create_skeletons(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 12 CREATE SKINS */ - err = _create_skins(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 13 PARSE MESHES (we have enough info now) */ - err = _parse_meshes(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 14 PARSE LIGHTS */ - err = _parse_lights(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 15 PARSE CAMERAS */ - err = _parse_cameras(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 16 PARSE ANIMATIONS */ - err = _parse_animations(state); - if (err != OK) { - return Error::FAILED; + for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { + Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; + ERR_CONTINUE(ext.is_null()); + err = ext->import_preflight(this); + ERR_FAIL_COND_V(err != OK, FAILED); } - - /* STEP 17 ASSIGN SCENE NAMES */ - _assign_scene_names(state); - + err = _parse_gltf_state(state, p_path, p_bake_fps); + ERR_FAIL_COND_V(err != OK, err); return OK; } @@ -6718,33 +6675,36 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> state, const String p_path) { const uint32_t magic = 0x46546C67; // GLTF const int32_t header_size = 12; const int32_t chunk_header_size = 8; - - for (int32_t pad_i = 0; pad_i < (chunk_header_size + json.utf8().length()) % 4; pad_i++) { - json += " "; - } CharString cs = json.utf8(); - const uint32_t text_chunk_length = cs.length(); - + const uint32_t text_data_length = cs.length(); + const uint32_t text_chunk_length = ((text_data_length + 3) & (~3)); const uint32_t text_chunk_type = 0x4E4F534A; //JSON - int32_t binary_data_length = 0; + + uint32_t binary_data_length = 0; if (state->buffers.size()) { binary_data_length = state->buffers[0].size(); } - const int32_t binary_chunk_length = binary_data_length; - const int32_t binary_chunk_type = 0x004E4942; //BIN + const uint32_t binary_chunk_length = ((binary_data_length + 3) & (~3)); + const uint32_t binary_chunk_type = 0x004E4942; //BIN f->create(FileAccess::ACCESS_RESOURCES); f->store_32(magic); f->store_32(state->major_version); // version - f->store_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_data_length); // length + f->store_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_chunk_length); // length f->store_32(text_chunk_length); f->store_32(text_chunk_type); f->store_buffer((uint8_t *)&cs[0], cs.length()); + for (uint32_t pad_i = text_data_length; pad_i < text_chunk_length; pad_i++) { + f->store_8(' '); + } if (binary_chunk_length) { f->store_32(binary_chunk_length); f->store_32(binary_chunk_type); f->store_buffer(state->buffers[0].ptr(), binary_data_length); } + for (uint32_t pad_i = binary_data_length; pad_i < binary_chunk_length; pad_i++) { + f->store_8(0); + } f->close(); } else { @@ -6761,89 +6721,20 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> state, const String p_path) { return err; } -Error GLTFDocument::save_scene(Node *p_node, const String &p_path, - const String &p_src_path, uint32_t p_flags, - float p_bake_fps, Ref<GLTFState> r_state) { - ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER); - - Ref<GLTFDocument> gltf_document; - gltf_document.instantiate(); - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; - ERR_CONTINUE(ext.is_null()); - Error err = ext->export_preflight(this, p_node); - ERR_FAIL_COND_V(err != OK, err); - } - - if (r_state == Ref<GLTFState>()) { - r_state.instantiate(); - } - Error err = gltf_document->serialize(r_state, p_node, p_path); - ERR_FAIL_COND_V(err != OK, err); - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; - ERR_CONTINUE(ext.is_null()); - err = ext->export_post(this); - ERR_FAIL_COND_V(err != OK, err); - } - return OK; -} - -Node *GLTFDocument::import_scene_gltf(const String &p_path, uint32_t p_flags, int32_t p_bake_fps, Ref<GLTFState> r_state, List<String> *r_missing_deps, Error *r_err) { - // TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire - if (r_state == Ref<GLTFState>()) { - r_state.instantiate(); - } - r_state->use_named_skin_binds = - p_flags & EditorSceneImporter::IMPORT_USE_NAMED_SKIN_BINDS; - - Ref<GLTFDocument> gltf_document; - gltf_document.instantiate(); - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; - ERR_CONTINUE(ext.is_null()); - Error err = ext->import_preflight(this); - if (r_err) { - *r_err = err; - } - ERR_FAIL_COND_V(err != OK, nullptr); - } - Error err = gltf_document->parse(r_state, p_path); - if (r_err) { - *r_err = err; - } - ERR_FAIL_COND_V(err != Error::OK, nullptr); - - Node3D *root = memnew(Node3D); - for (int32_t root_i = 0; root_i < r_state->root_nodes.size(); root_i++) { - gltf_document->_generate_scene_node(r_state, root, root, r_state->root_nodes[root_i]); - } - gltf_document->_process_mesh_instances(r_state, root); - if (r_state->animations.size()) { - AnimationPlayer *ap = memnew(AnimationPlayer); - root->add_child(ap); - ap->set_owner(root); - for (int i = 0; i < r_state->animations.size(); i++) { - gltf_document->_import_animation(r_state, ap, i, p_bake_fps); - } - } - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; - ERR_CONTINUE(ext.is_null()); - err = ext->import_post(this, root); - if (r_err) { - *r_err = err; - } - ERR_FAIL_COND_V(err != OK, nullptr); - } - return root; -} - void GLTFDocument::_bind_methods() { - ClassDB::bind_method(D_METHOD("save_scene", "node", "path", "src_path", "flags", "bake_fps", "state"), - &GLTFDocument::save_scene, DEFVAL(0), DEFVAL(30), DEFVAL(Ref<GLTFState>())); - ClassDB::bind_method(D_METHOD("import_scene", "path", "flags", "bake_fps", "state"), - &GLTFDocument::import_scene, DEFVAL(0), DEFVAL(30), DEFVAL(Ref<GLTFState>())); + ClassDB::bind_method(D_METHOD("append_from_file", "path", "state", "flags", "bake_fps"), + &GLTFDocument::append_from_file, DEFVAL(0), DEFVAL(30)); + ClassDB::bind_method(D_METHOD("append_from_buffer", "bytes", "base_path", "state", "flags", "bake_fps"), + &GLTFDocument::append_from_buffer, DEFVAL(0), DEFVAL(30)); + ClassDB::bind_method(D_METHOD("append_from_scene", "node", "state", "flags", "bake_fps"), + &GLTFDocument::append_from_scene, DEFVAL(0), DEFVAL(30)); + ClassDB::bind_method(D_METHOD("generate_scene", "state", "bake_fps"), + &GLTFDocument::generate_scene, DEFVAL(30)); + ClassDB::bind_method(D_METHOD("generate_buffer", "state"), + &GLTFDocument::generate_buffer); + ClassDB::bind_method(D_METHOD("write_to_filesystem", "state", "path"), + &GLTFDocument::write_to_filesystem); + ClassDB::bind_method(D_METHOD("set_extensions", "extensions"), &GLTFDocument::set_extensions); ClassDB::bind_method(D_METHOD("get_extensions"), @@ -6868,16 +6759,6 @@ void GLTFDocument::_build_parent_hierachy(Ref<GLTFState> state) { } } -Node *GLTFDocument::import_scene(const String &p_path, uint32_t p_flags, int32_t p_bake_fps, Ref<GLTFState> r_state) { - Error err = FAILED; - List<String> deps; - Node *node = import_scene_gltf(p_path, p_flags, p_bake_fps, r_state, &deps, &err); - if (err != OK) { - return nullptr; - } - return node; -} - void GLTFDocument::set_extensions(TypedArray<GLTFDocumentExtension> p_extensions) { document_extensions = p_extensions; } @@ -6895,3 +6776,226 @@ GLTFDocument::GLTFDocument() { extension_editor.instantiate(); document_extensions.push_back(extension_editor); } + +PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> state, Error *r_err) { + Error err = _encode_buffer_glb(state, ""); + if (r_err) { + *r_err = err; + } + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + String json = Variant(state->json).to_json_string(); + + const uint32_t magic = 0x46546C67; // GLTF + const int32_t header_size = 12; + const int32_t chunk_header_size = 8; + + for (int32_t pad_i = 0; pad_i < (chunk_header_size + json.utf8().length()) % 4; pad_i++) { + json += " "; + } + CharString cs = json.utf8(); + const uint32_t text_chunk_length = cs.length(); + + const uint32_t text_chunk_type = 0x4E4F534A; //JSON + int32_t binary_data_length = 0; + if (state->buffers.size()) { + binary_data_length = state->buffers[0].size(); + } + const int32_t binary_chunk_length = binary_data_length; + const int32_t binary_chunk_type = 0x004E4942; //BIN + + Ref<StreamPeerBuffer> buffer; + buffer.instantiate(); + buffer->put_32(magic); + buffer->put_32(state->major_version); // version + buffer->put_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_data_length); // length + buffer->put_32(text_chunk_length); + buffer->put_32(text_chunk_type); + buffer->put_data((uint8_t *)&cs[0], cs.length()); + if (binary_chunk_length) { + buffer->put_32(binary_chunk_length); + buffer->put_32(binary_chunk_type); + buffer->put_data(state->buffers[0].ptr(), binary_data_length); + } + return buffer->get_data_array(); +} + +PackedByteArray GLTFDocument::generate_buffer(Ref<GLTFState> state) { + ERR_FAIL_NULL_V(state, PackedByteArray()); + Error err = _serialize(state, ""); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + PackedByteArray bytes = _serialize_glb_buffer(state, &err); + return bytes; +} + +Error GLTFDocument::write_to_filesystem(Ref<GLTFState> state, const String &p_path) { + ERR_FAIL_NULL_V(state, ERR_INVALID_PARAMETER); + + Error err = _serialize(state, p_path); + if (err != OK) { + return err; + } + + err = _serialize_file(state, p_path); + if (err != OK) { + return Error::FAILED; + } + return OK; +} + +Node *GLTFDocument::generate_scene(Ref<GLTFState> state, int32_t p_bake_fps) { + ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr); + GLTFNodeIndex gltf_root = state->root_nodes.write[0]; + Node *gltf_root_node = state->get_scene_node(gltf_root); + Node *root = gltf_root_node->get_parent(); + ERR_FAIL_NULL_V(root, nullptr); + _process_mesh_instances(state, root); + if (state->animations.size()) { + AnimationPlayer *ap = memnew(AnimationPlayer); + root->add_child(ap); + ap->set_owner(root); + for (int i = 0; i < state->animations.size(); i++) { + _import_animation(state, ap, i, p_bake_fps); + } + } + + for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { + Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; + ERR_CONTINUE(ext.is_null()); + Error err = ext->import_post(this, root); + ERR_FAIL_COND_V(err != OK, nullptr); + } + ERR_FAIL_NULL_V(root, nullptr); + return root; +} + +Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> state, uint32_t p_flags, int32_t p_bake_fps) { + ERR_FAIL_COND_V(state.is_null(), FAILED); + state->use_named_skin_binds = + p_flags & EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; + + _convert_scene_node(state, p_node, -1, -1); + if (!state->buffers.size()) { + state->buffers.push_back(Vector<uint8_t>()); + } + + /* STEP 1 CONVERT MESH INSTANCES */ + _convert_mesh_instances(state); + + /* STEP 2 CREATE SKINS */ + Error err = _serialize_skins(state); + return err; +} + +Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> state, uint32_t p_flags, int32_t p_bake_fps) { + ERR_FAIL_COND_V(state.is_null(), FAILED); + // TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire + Error err = FAILED; + state->use_named_skin_binds = + p_flags & EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; + FileAccessMemory *file_access = memnew(FileAccessMemory); + file_access->open_custom(p_bytes.ptr(), p_bytes.size()); + err = _parse(state, p_base_path.get_base_dir(), file_access, p_bake_fps); + ERR_FAIL_COND_V(err != OK, FAILED); + return OK; +} + +Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> state, const String &p_search_path, float p_bake_fps) { + Error err; + /* STEP 0 PARSE SCENE */ + err = _parse_scenes(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 1 PARSE NODES */ + err = _parse_nodes(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 2 PARSE BUFFERS */ + err = _parse_buffers(state, p_search_path); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 3 PARSE BUFFER VIEWS */ + err = _parse_buffer_views(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 4 PARSE ACCESSORS */ + err = _parse_accessors(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 5 PARSE IMAGES */ + err = _parse_images(state, p_search_path); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 6 PARSE TEXTURES */ + err = _parse_textures(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 7 PARSE TEXTURES */ + err = _parse_materials(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 9 PARSE SKINS */ + err = _parse_skins(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 10 DETERMINE SKELETONS */ + err = _determine_skeletons(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 11 CREATE SKELETONS */ + err = _create_skeletons(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 12 CREATE SKINS */ + err = _create_skins(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 13 PARSE MESHES (we have enough info now) */ + err = _parse_meshes(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 14 PARSE LIGHTS */ + err = _parse_lights(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 15 PARSE CAMERAS */ + err = _parse_cameras(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 16 PARSE ANIMATIONS */ + err = _parse_animations(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* STEP 17 ASSIGN SCENE NAMES */ + _assign_scene_names(state); + + Node3D *root = memnew(Node3D); + for (int32_t root_i = 0; root_i < state->root_nodes.size(); root_i++) { + _generate_scene_node(state, root, root, state->root_nodes[root_i]); + } + return OK; +} + +Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint32_t p_flags, int32_t p_bake_fps) { + // TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire + if (r_state == Ref<GLTFState>()) { + r_state.instantiate(); + } + r_state->filename = p_path.get_file().get_basename(); + r_state->use_named_skin_binds = + p_flags & EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; + Error err; + FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); + ERR_FAIL_COND_V(err != OK, ERR_FILE_CANT_OPEN); + ERR_FAIL_NULL_V(f, ERR_FILE_CANT_OPEN); + + err = _parse(r_state, p_path.get_base_dir(), f, p_bake_fps); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + return err; +} diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 7317c6a9a3..8f8f5b410a 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,7 @@ #include "gltf_animation.h" +#include "core/error/error_list.h" #include "core/variant/dictionary.h" #include "core/variant/variant.h" #include "gltf_document_extension_convert_importer_mesh.h" @@ -46,7 +47,8 @@ #include "scene/resources/material.h" #include "scene/resources/texture.h" -#include "modules/modules_enabled.gen.h" +#include "modules/modules_enabled.gen.h" // For csg, gridmap. + #include <cstdint> class GLTFState; @@ -119,11 +121,6 @@ protected: static void _bind_methods(); public: - Node *import_scene(const String &p_path, uint32_t p_flags, int32_t p_bake_fps, Ref<GLTFState> r_state); - Node *import_scene_gltf(const String &p_path, uint32_t p_flags, int32_t p_bake_fps, Ref<GLTFState> r_state, List<String> *r_missing_deps, Error *r_err = nullptr); - Error save_scene(Node *p_node, const String &p_path, - const String &p_src_path, uint32_t p_flags, - float p_bake_fps, Ref<GLTFState> r_state); void set_extensions(TypedArray<GLTFDocumentExtension> p_extensions); TypedArray<GLTFDocumentExtension> get_extensions() const; @@ -199,7 +196,7 @@ private: Ref<Texture2D> _get_texture(Ref<GLTFState> state, const GLTFTextureIndex p_texture); Error _parse_json(const String &p_path, Ref<GLTFState> state); - Error _parse_glb(const String &p_path, Ref<GLTFState> state); + Error _parse_glb(FileAccess *f, Ref<GLTFState> state); void _compute_node_heights(Ref<GLTFState> state); Error _parse_buffers(Ref<GLTFState> state, const String &p_base_path); Error _parse_buffer_views(Ref<GLTFState> state); @@ -269,8 +266,6 @@ private: Error _reparent_non_joint_skeleton_subtrees( Ref<GLTFState> state, Ref<GLTFSkeleton> skeleton, const Vector<GLTFNodeIndex> &non_joints); - Error _reparent_to_fake_joint(Ref<GLTFState> state, Ref<GLTFSkeleton> skeleton, - const GLTFNodeIndex node_index); Error _determine_skeleton_roots(Ref<GLTFState> state, const GLTFSkeletonIndex skel_i); Error _create_skeletons(Ref<GLTFState> state); @@ -288,13 +283,13 @@ private: Skeleton3D *skeleton, const GLTFNodeIndex node_index, const GLTFNodeIndex bone_index); - ImporterMeshInstance3D *_generate_mesh_instance(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index); - Camera3D *_generate_camera(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index); - Node3D *_generate_light(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index); - Node3D *_generate_spatial(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index); + ImporterMeshInstance3D *_generate_mesh_instance(Ref<GLTFState> state, const GLTFNodeIndex node_index); + Camera3D *_generate_camera(Ref<GLTFState> state, const GLTFNodeIndex node_index); + Node3D *_generate_light(Ref<GLTFState> state, const GLTFNodeIndex node_index); + Node3D *_generate_spatial(Ref<GLTFState> state, const GLTFNodeIndex node_index); void _assign_scene_names(Ref<GLTFState> state); template <class T> - T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, + T _interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp); GLTFAccessorIndex _encode_accessor_as_quaternions(Ref<GLTFState> state, @@ -357,11 +352,12 @@ private: String interpolation_to_string(const GLTFAnimation::Interpolation p_interp); GLTFAnimation::Track _convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, - Ref<Animation> p_animation, Transform3D p_bone_rest, + Ref<Animation> p_animation, int32_t p_track_i, GLTFNodeIndex p_node_i); Error _encode_buffer_bins(Ref<GLTFState> state, const String &p_path); Error _encode_buffer_glb(Ref<GLTFState> state, const String &p_path); + PackedByteArray _serialize_glb_buffer(Ref<GLTFState> state, Error *r_err); Dictionary _serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material); Dictionary _serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material); Error _serialize_version(Ref<GLTFState> state); @@ -385,6 +381,17 @@ private: static float get_max_component(const Color &p_color); public: + Error append_from_file(String p_path, Ref<GLTFState> r_state, uint32_t p_flags = 0, int32_t p_bake_fps = 30); + Error append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> r_state, uint32_t p_flags = 0, int32_t p_bake_fps = 30); + Error append_from_scene(Node *p_node, Ref<GLTFState> r_state, uint32_t p_flags = 0, int32_t p_bake_fps = 30); + +public: + Node *generate_scene(Ref<GLTFState> state, int32_t p_bake_fps = 30.0f); + PackedByteArray generate_buffer(Ref<GLTFState> state); + Error write_to_filesystem(Ref<GLTFState> state, const String &p_path); + +public: + Error _parse_gltf_state(Ref<GLTFState> state, const String &p_search_path, float p_bake_fps); void _process_mesh_instances(Ref<GLTFState> state, Node *scene_root); void _generate_scene_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, @@ -448,8 +455,8 @@ public: MeshInstance3D *p_mesh_instance); void _convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, String p_animation_track_name); - Error serialize(Ref<GLTFState> state, Node *p_root, const String &p_path); - Error parse(Ref<GLTFState> state, String p_paths, bool p_read_binary = false); + Error _serialize(Ref<GLTFState> state, const String &p_path); + Error _parse(Ref<GLTFState> state, String p_path, FileAccess *f, int p_bake_fps); }; #endif // GLTF_DOCUMENT_H diff --git a/modules/gltf/gltf_document_extension.cpp b/modules/gltf/gltf_document_extension.cpp index a423059a9c..192a1d347c 100644 --- a/modules/gltf/gltf_document_extension.cpp +++ b/modules/gltf/gltf_document_extension.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/gltf_document_extension.h index 622a65708c..f7a3531282 100644 --- a/modules/gltf/gltf_document_extension.h +++ b/modules/gltf/gltf_document_extension.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp index 78a98dfa3e..47a3e5598f 100644 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp +++ b/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,6 +29,7 @@ /*************************************************************************/ #include "gltf_document_extension_convert_importer_mesh.h" +#include "core/error/error_macros.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/resources/importer_mesh.h" @@ -38,6 +39,8 @@ void GLTFDocumentExtensionConvertImporterMesh::_bind_methods() { } Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref<GLTFDocument> p_document, Node *p_node) { + ERR_FAIL_NULL_V(p_document, ERR_INVALID_PARAMETER); + ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER); List<Node *> queue; queue.push_back(p_node); List<Node *> delete_queue; diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.h b/modules/gltf/gltf_document_extension_convert_importer_mesh.h index 85ddb4d250..2d51143140 100644 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.h +++ b/modules/gltf/gltf_document_extension_convert_importer_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_light.cpp b/modules/gltf/gltf_light.cpp index c5aa8d5724..af21a4e804 100644 --- a/modules/gltf/gltf_light.cpp +++ b/modules/gltf/gltf_light.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_light.h b/modules/gltf/gltf_light.h index 62a20d2f16..25e0835a33 100644 --- a/modules/gltf/gltf_light.h +++ b/modules/gltf/gltf_light.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_mesh.cpp b/modules/gltf/gltf_mesh.cpp index 747820521a..1251622642 100644 --- a/modules/gltf/gltf_mesh.cpp +++ b/modules/gltf/gltf_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,9 +36,12 @@ void GLTFMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &GLTFMesh::set_mesh); ClassDB::bind_method(D_METHOD("get_blend_weights"), &GLTFMesh::get_blend_weights); ClassDB::bind_method(D_METHOD("set_blend_weights", "blend_weights"), &GLTFMesh::set_blend_weights); + ClassDB::bind_method(D_METHOD("get_instance_materials"), &GLTFMesh::get_instance_materials); + ClassDB::bind_method(D_METHOD("set_instance_materials", "instance_materials"), &GLTFMesh::set_instance_materials); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh"), "set_mesh", "get_mesh"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "blend_weights"), "set_blend_weights", "get_blend_weights"); // Vector<float> + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "instance_materials"), "set_instance_materials", "get_instance_materials"); } Ref<ImporterMesh> GLTFMesh::get_mesh() { @@ -49,6 +52,14 @@ void GLTFMesh::set_mesh(Ref<ImporterMesh> p_mesh) { mesh = p_mesh; } +Array GLTFMesh::get_instance_materials() { + return instance_materials; +} + +void GLTFMesh::set_instance_materials(Array p_instance_materials) { + instance_materials = p_instance_materials; +} + Vector<float> GLTFMesh::get_blend_weights() { return blend_weights; } diff --git a/modules/gltf/gltf_mesh.h b/modules/gltf/gltf_mesh.h index 3aba0ede32..aeab1ad68f 100644 --- a/modules/gltf/gltf_mesh.h +++ b/modules/gltf/gltf_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,6 +43,7 @@ class GLTFMesh : public Resource { private: Ref<ImporterMesh> mesh; Vector<float> blend_weights; + Array instance_materials; protected: static void _bind_methods(); @@ -52,5 +53,7 @@ public: void set_mesh(Ref<ImporterMesh> p_mesh); Vector<float> get_blend_weights(); void set_blend_weights(Vector<float> p_blend_weights); + Array get_instance_materials(); + void set_instance_materials(Array p_instance_materials); }; #endif // GLTF_MESH_H diff --git a/modules/gltf/gltf_node.cpp b/modules/gltf/gltf_node.cpp index 9f925c7bbc..86280603fa 100644 --- a/modules/gltf/gltf_node.cpp +++ b/modules/gltf/gltf_node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_node.h b/modules/gltf/gltf_node.h index 3b6e061449..929ad3eca0 100644 --- a/modules/gltf/gltf_node.h +++ b/modules/gltf/gltf_node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_skeleton.cpp b/modules/gltf/gltf_skeleton.cpp index d6c7a25eaf..e80376f130 100644 --- a/modules/gltf/gltf_skeleton.cpp +++ b/modules/gltf/gltf_skeleton.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_skeleton.h b/modules/gltf/gltf_skeleton.h index d6986eb35a..7d07d528cb 100644 --- a/modules/gltf/gltf_skeleton.h +++ b/modules/gltf/gltf_skeleton.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_skin.cpp b/modules/gltf/gltf_skin.cpp index 5cf17135ac..283fc34ff5 100644 --- a/modules/gltf/gltf_skin.cpp +++ b/modules/gltf/gltf_skin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_skin.h b/modules/gltf/gltf_skin.h index e32e2d397c..31cb892f19 100644 --- a/modules/gltf/gltf_skin.h +++ b/modules/gltf/gltf_skin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_spec_gloss.cpp b/modules/gltf/gltf_spec_gloss.cpp index 70b182da52..83af91bfcc 100644 --- a/modules/gltf/gltf_spec_gloss.cpp +++ b/modules/gltf/gltf_spec_gloss.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_spec_gloss.h b/modules/gltf/gltf_spec_gloss.h index 3cc6fb09ed..f8a431bdce 100644 --- a/modules/gltf/gltf_spec_gloss.h +++ b/modules/gltf/gltf_spec_gloss.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index ff9778e7d8..3f638bbca5 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 61faba0dc5..d03434d2f1 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_texture.cpp b/modules/gltf/gltf_texture.cpp index 0482c1064e..2a21cb3df8 100644 --- a/modules/gltf/gltf_texture.cpp +++ b/modules/gltf/gltf_texture.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/gltf_texture.h b/modules/gltf/gltf_texture.h index 4659725502..54dd61f9a5 100644 --- a/modules/gltf/gltf_texture.h +++ b/modules/gltf/gltf_texture.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index 0aceb838f7..6ab202096d 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,7 +52,7 @@ #ifndef _3D_DISABLED #ifdef TOOLS_ENABLED static void _editor_init() { - Ref<EditorSceneImporterGLTF> import_gltf; + Ref<EditorSceneFormatImporterGLTF> import_gltf; import_gltf.instantiate(); ResourceImporterScene::get_singleton()->add_importer(import_gltf); } @@ -64,7 +64,7 @@ void register_gltf_types() { #ifdef TOOLS_ENABLED ClassDB::APIType prev_api = ClassDB::get_current_api(); ClassDB::set_current_api(ClassDB::API_EDITOR); - GDREGISTER_CLASS(EditorSceneImporterGLTF); + GDREGISTER_CLASS(EditorSceneFormatImporterGLTF); GDREGISTER_CLASS(GLTFMesh); EditorPlugins::add_by_type<SceneExporterGLTFPlugin>(); ClassDB::set_current_api(prev_api); diff --git a/modules/gltf/register_types.h b/modules/gltf/register_types.h index fefacb1106..4a9c31241c 100644 --- a/modules/gltf/register_types.h +++ b/modules/gltf/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index c1dbe63628..73315350ff 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -11,7 +11,7 @@ [b]Note:[/b] GridMap doesn't extend [VisualInstance3D] and therefore can't be hidden or cull masked based on [member VisualInstance3D.layers]. If you make a light not affect the first layer, the whole GridMap won't be lit by the light in question. </description> <tutorials> - <link title="Using gridmaps">https://docs.godotengine.org/en/latest/tutorials/3d/using_gridmaps.html</link> + <link title="Using gridmaps">$DOCS_URL/tutorials/3d/using_gridmaps.html</link> <link title="3D Platformer Demo">https://godotengine.org/asset-library/asset/125</link> <link title="3D Kinematic Character Demo">https://godotengine.org/asset-library/asset/126</link> </tutorials> @@ -173,7 +173,7 @@ GridMaps act as static bodies, meaning they aren't affected by gravity or other forces. They only affect other physics bodies that collide with them. </member> <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1"> - The physics layers this GridMap detects collisions in. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. + The physics layers this GridMap detects collisions in. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> <member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library"> The assigned [MeshLibrary]. diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index c9d8f2b42b..3383daefea 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 879489fc70..db3395b6fe 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index c170bb107e..7abc8f7d7a 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -603,32 +603,32 @@ void GridMapEditor::_do_paste() { _clear_clipboard_data(); } -bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event) { +EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event) { if (!node) { - return false; + return EditorPlugin::AFTER_GUI_INPUT_PASS; } Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && (mb->is_command_pressed() || mb->is_shift_pressed())) { + if (mb->get_button_index() == MouseButton::WHEEL_UP && (mb->is_command_pressed() || mb->is_shift_pressed())) { if (mb->is_pressed()) { floor->set_value(floor->get_value() + mb->get_factor()); } - return true; // Eaten. - } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && (mb->is_command_pressed() || mb->is_shift_pressed())) { + return EditorPlugin::AFTER_GUI_INPUT_STOP; // Eaten. + } else if (mb->get_button_index() == MouseButton::WHEEL_DOWN && (mb->is_command_pressed() || mb->is_shift_pressed())) { if (mb->is_pressed()) { floor->set_value(floor->get_value() - mb->get_factor()); } - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } if (mb->is_pressed()) { Node3DEditorViewport::NavigationScheme nav_scheme = (Node3DEditorViewport::NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); if ((nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA || nav_scheme == Node3DEditorViewport::NAVIGATION_MODO) && mb->is_alt_pressed()) { input_action = INPUT_NONE; - } else if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { + } else if (mb->get_button_index() == MouseButton::LEFT) { bool can_edit = (node && node->get_mesh_library().is_valid()); if (input_action == INPUT_PASTE) { _do_paste(); @@ -643,26 +643,29 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In input_action = INPUT_PAINT; set_items.clear(); } - } else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) { + } else if (mb->get_button_index() == MouseButton::RIGHT) { if (input_action == INPUT_PASTE) { _clear_clipboard_data(); input_action = INPUT_NONE; _update_paste_indicator(); - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } else if (selection.active) { _set_selection(false); - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } else { input_action = INPUT_ERASE; set_items.clear(); } } else { - return false; + return EditorPlugin::AFTER_GUI_INPUT_PASS; } - return do_input_action(p_camera, Point2(mb->get_position().x, mb->get_position().y), true); + if (do_input_action(p_camera, Point2(mb->get_position().x, mb->get_position().y), true)) { + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + return EditorPlugin::AFTER_GUI_INPUT_PASS; } else { - if ((mb->get_button_index() == MOUSE_BUTTON_RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action == INPUT_PAINT)) { + if ((mb->get_button_index() == MouseButton::RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == MouseButton::LEFT && input_action == INPUT_PAINT)) { if (set_items.size()) { undo_redo->create_action(TTR("GridMap Paint")); for (const SetItem &si : set_items) { @@ -677,24 +680,28 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In } set_items.clear(); input_action = INPUT_NONE; - return set_items.size() > 0; + + if (set_items.size() > 0) { + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + return EditorPlugin::AFTER_GUI_INPUT_PASS; } - if (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action == INPUT_SELECT) { + if (mb->get_button_index() == MouseButton::LEFT && input_action == INPUT_SELECT) { undo_redo->create_action(TTR("GridMap Selection")); undo_redo->add_do_method(this, "_set_selection", selection.active, selection.begin, selection.end); undo_redo->add_undo_method(this, "_set_selection", last_selection.active, last_selection.begin, last_selection.end); undo_redo->commit_action(); } - if (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action != INPUT_NONE) { + if (mb->get_button_index() == MouseButton::LEFT && input_action != INPUT_NONE) { set_items.clear(); input_action = INPUT_NONE; - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } - if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_PASTE)) { + if (mb->get_button_index() == MouseButton::RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_PASTE)) { input_action = INPUT_NONE; - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } } } @@ -702,41 +709,44 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { - return do_input_action(p_camera, mm->get_position(), false); + if (do_input_action(p_camera, mm->get_position(), false)) { + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + return EditorPlugin::AFTER_GUI_INPUT_PASS; } Ref<InputEventKey> k = p_event; if (k.is_valid()) { if (k->is_pressed()) { - if (k->get_keycode() == KEY_ESCAPE) { + if (k->get_keycode() == Key::ESCAPE) { if (input_action == INPUT_PASTE) { _clear_clipboard_data(); input_action = INPUT_NONE; _update_paste_indicator(); - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } else if (selection.active) { _set_selection(false); - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } else { selected_palette = -1; mesh_library_palette->deselect_all(); update_palette(); _update_cursor_instance(); - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } } if (k->is_shift_pressed() && selection.active && input_action != INPUT_PASTE) { - if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) { + if (k->get_keycode() == (Key)options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) { selection.click[edit_axis]--; _validate_selection(); - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } - if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL))) { + if (k->get_keycode() == (Key)options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL))) { selection.click[edit_axis]++; _validate_selection(); - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } } } @@ -749,18 +759,18 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In accumulated_floor_delta += delta; int step = 0; if (ABS(accumulated_floor_delta) > 1.0) { - step = SGN(accumulated_floor_delta); + step = SIGN(accumulated_floor_delta); accumulated_floor_delta -= step; } if (step) { floor->set_value(floor->get_value() + step); } - return true; + return EditorPlugin::AFTER_GUI_INPUT_STOP; } } accumulated_floor_delta = 0.0; - return false; + return EditorPlugin::AFTER_GUI_INPUT_PASS; } struct _CGMEItemSort { @@ -794,7 +804,7 @@ void GridMapEditor::_text_changed(const String &p_text) { void GridMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) { const Ref<InputEventKey> k = p_ie; - if (k.is_valid() && (k->get_keycode() == KEY_UP || k->get_keycode() == KEY_DOWN || k->get_keycode() == KEY_PAGEUP || k->get_keycode() == KEY_PAGEDOWN)) { + if (k.is_valid() && (k->get_keycode() == Key::UP || k->get_keycode() == Key::DOWN || k->get_keycode() == Key::PAGEUP || k->get_keycode() == Key::PAGEDOWN)) { // Forward the key input to the ItemList so it can be scrolled mesh_library_palette->gui_input(k); search_box->accept_event(); @@ -806,11 +816,11 @@ void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) { // Zoom in/out using Ctrl + mouse wheel if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed()) { - if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { + if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { size_slider->set_value(size_slider->get_value() + 0.2); } - if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) { + if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) { size_slider->set_value(size_slider->get_value() - 0.2); } } @@ -875,11 +885,11 @@ void GridMapEditor::update_palette() { String name = mesh_library->get_item_name(id); Ref<Texture2D> preview = mesh_library->get_item_preview(id); - if (name == "") { + if (name.is_empty()) { name = "#" + itos(id); } - if (filter != "" && !filter.is_subsequence_ofi(name)) { + if (!filter.is_empty() && !filter.is_subsequence_ofi(name)) { continue; } @@ -1087,7 +1097,7 @@ void GridMapEditor::_notification(int p_what) { // Simulate mouse released event to stop drawing when editor focus exists. Ref<InputEventMouseButton> release; release.instantiate(); - release->set_button_index(MOUSE_BUTTON_LEFT); + release->set_button_index(MouseButton::LEFT); forward_spatial_input_event(nullptr, release); } } break; @@ -1153,7 +1163,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { spatial_editor_hb = memnew(HBoxContainer); spatial_editor_hb->set_h_size_flags(SIZE_EXPAND_FILL); - spatial_editor_hb->set_alignment(BoxContainer::ALIGN_END); + spatial_editor_hb->set_alignment(BoxContainer::ALIGNMENT_END); Node3DEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb); spin_box_label = memnew(Label); @@ -1178,33 +1188,33 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { spatial_editor_hb->hide(); options->set_text(TTR("Grid Map")); - options->get_popup()->add_item(TTR("Previous Floor"), MENU_OPTION_PREV_LEVEL, KEY_Q); - options->get_popup()->add_item(TTR("Next Floor"), MENU_OPTION_NEXT_LEVEL, KEY_E); + options->get_popup()->add_item(TTR("Previous Floor"), MENU_OPTION_PREV_LEVEL, Key::Q); + options->get_popup()->add_item(TTR("Next Floor"), MENU_OPTION_NEXT_LEVEL, Key::E); options->get_popup()->add_separator(); options->get_popup()->add_radio_check_item(TTR("Clip Disabled"), MENU_OPTION_CLIP_DISABLED); options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED), true); options->get_popup()->add_radio_check_item(TTR("Clip Above"), MENU_OPTION_CLIP_ABOVE); options->get_popup()->add_radio_check_item(TTR("Clip Below"), MENU_OPTION_CLIP_BELOW); options->get_popup()->add_separator(); - options->get_popup()->add_radio_check_item(TTR("Edit X Axis"), MENU_OPTION_X_AXIS, KEY_Z); - options->get_popup()->add_radio_check_item(TTR("Edit Y Axis"), MENU_OPTION_Y_AXIS, KEY_X); - options->get_popup()->add_radio_check_item(TTR("Edit Z Axis"), MENU_OPTION_Z_AXIS, KEY_C); + options->get_popup()->add_radio_check_item(TTR("Edit X Axis"), MENU_OPTION_X_AXIS, Key::Z); + options->get_popup()->add_radio_check_item(TTR("Edit Y Axis"), MENU_OPTION_Y_AXIS, Key::X); + options->get_popup()->add_radio_check_item(TTR("Edit Z Axis"), MENU_OPTION_Z_AXIS, Key::C); options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_Y_AXIS), true); options->get_popup()->add_separator(); - options->get_popup()->add_item(TTR("Cursor Rotate X"), MENU_OPTION_CURSOR_ROTATE_X, KEY_A); - options->get_popup()->add_item(TTR("Cursor Rotate Y"), MENU_OPTION_CURSOR_ROTATE_Y, KEY_S); - options->get_popup()->add_item(TTR("Cursor Rotate Z"), MENU_OPTION_CURSOR_ROTATE_Z, KEY_D); - options->get_popup()->add_item(TTR("Cursor Back Rotate X"), MENU_OPTION_CURSOR_BACK_ROTATE_X, KEY_MASK_SHIFT + KEY_A); - options->get_popup()->add_item(TTR("Cursor Back Rotate Y"), MENU_OPTION_CURSOR_BACK_ROTATE_Y, KEY_MASK_SHIFT + KEY_S); - options->get_popup()->add_item(TTR("Cursor Back Rotate Z"), MENU_OPTION_CURSOR_BACK_ROTATE_Z, KEY_MASK_SHIFT + KEY_D); - options->get_popup()->add_item(TTR("Cursor Clear Rotation"), MENU_OPTION_CURSOR_CLEAR_ROTATION, KEY_W); + options->get_popup()->add_item(TTR("Cursor Rotate X"), MENU_OPTION_CURSOR_ROTATE_X, Key::A); + options->get_popup()->add_item(TTR("Cursor Rotate Y"), MENU_OPTION_CURSOR_ROTATE_Y, Key::S); + options->get_popup()->add_item(TTR("Cursor Rotate Z"), MENU_OPTION_CURSOR_ROTATE_Z, Key::D); + options->get_popup()->add_item(TTR("Cursor Back Rotate X"), MENU_OPTION_CURSOR_BACK_ROTATE_X, KeyModifierMask::SHIFT + Key::A); + options->get_popup()->add_item(TTR("Cursor Back Rotate Y"), MENU_OPTION_CURSOR_BACK_ROTATE_Y, KeyModifierMask::SHIFT + Key::S); + options->get_popup()->add_item(TTR("Cursor Back Rotate Z"), MENU_OPTION_CURSOR_BACK_ROTATE_Z, KeyModifierMask::SHIFT + Key::D); + options->get_popup()->add_item(TTR("Cursor Clear Rotation"), MENU_OPTION_CURSOR_CLEAR_ROTATION, Key::W); options->get_popup()->add_separator(); options->get_popup()->add_check_item(TTR("Paste Selects"), MENU_OPTION_PASTE_SELECTS); options->get_popup()->add_separator(); - options->get_popup()->add_item(TTR("Duplicate Selection"), MENU_OPTION_SELECTION_DUPLICATE, KEY_MASK_CTRL + KEY_C); - options->get_popup()->add_item(TTR("Cut Selection"), MENU_OPTION_SELECTION_CUT, KEY_MASK_CTRL + KEY_X); - options->get_popup()->add_item(TTR("Clear Selection"), MENU_OPTION_SELECTION_CLEAR, KEY_DELETE); - options->get_popup()->add_item(TTR("Fill Selection"), MENU_OPTION_SELECTION_FILL, KEY_MASK_CTRL + KEY_F); + options->get_popup()->add_item(TTR("Duplicate Selection"), MENU_OPTION_SELECTION_DUPLICATE, KeyModifierMask::CTRL + Key::C); + options->get_popup()->add_item(TTR("Cut Selection"), MENU_OPTION_SELECTION_CUT, KeyModifierMask::CTRL + Key::X); + options->get_popup()->add_item(TTR("Clear Selection"), MENU_OPTION_SELECTION_CLEAR, Key::KEY_DELETE); + options->get_popup()->add_item(TTR("Fill Selection"), MENU_OPTION_SELECTION_FILL, KeyModifierMask::CTRL + Key::F); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Settings..."), MENU_OPTION_GRIDMAP_SETTINGS); @@ -1270,8 +1280,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { info_message = memnew(Label); info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes.")); - info_message->set_valign(Label::VALIGN_CENTER); - info_message->set_align(Label::ALIGN_CENTER); + info_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); + info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 4bc849e071..7e9510e227 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -232,7 +232,7 @@ protected: static void _bind_methods(); public: - bool forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event); + EditorPlugin::AfterGUIInput forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event); void edit(GridMap *p_gridmap); GridMapEditor() {} @@ -250,7 +250,7 @@ protected: void _notification(int p_what); public: - virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); } + virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); } virtual String get_name() const override { return "GridMap"; } bool has_main_screen() const override { return false; } virtual void edit(Object *p_object) override; diff --git a/modules/gridmap/register_types.cpp b/modules/gridmap/register_types.cpp index 85739d202e..f05c5de18b 100644 --- a/modules/gridmap/register_types.cpp +++ b/modules/gridmap/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/gridmap/register_types.h b/modules/gridmap/register_types.h index b977f4c5da..fa3511c5d1 100644 --- a/modules/gridmap/register_types.h +++ b/modules/gridmap/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index 9d6a399eff..996bbfadd1 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,7 +41,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force while (true) { String line = f->get_line(); ERR_FAIL_COND_V(f->eof_reached(), ERR_FILE_UNRECOGNIZED); - if (line == "") { // empty line indicates end of header + if (line.is_empty()) { // empty line indicates end of header break; } if (line.begins_with("FORMAT=")) { // leave option to implement other commands @@ -65,7 +65,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force Vector<uint8_t> imgdata; - imgdata.resize(height * width * sizeof(uint32_t)); + imgdata.resize(height * width * (int)sizeof(uint32_t)); { uint8_t *w = imgdata.ptrw(); @@ -75,7 +75,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force if (width < 8 || width >= 32768) { // Read flat data - f->get_buffer(ptr, width * height * 4); + f->get_buffer(ptr, (uint64_t)width * height * 4); } else { // Read RLE-encoded data diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h index 33fcdd1245..0213fdbcb2 100644 --- a/modules/hdr/image_loader_hdr.h +++ b/modules/hdr/image_loader_hdr.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/hdr/register_types.cpp b/modules/hdr/register_types.cpp index 5a4a1993e0..6bfeecc927 100644 --- a/modules/hdr/register_types.cpp +++ b/modules/hdr/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/hdr/register_types.h b/modules/hdr/register_types.h index c85bc84dce..4224aa2ce2 100644 --- a/modules/hdr/register_types.h +++ b/modules/hdr/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp index b5e4753e8d..e8c66ab9da 100644 --- a/modules/jpg/image_loader_jpegd.cpp +++ b/modules/jpg/image_loader_jpegd.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h index be265b280c..8e64f6fba7 100644 --- a/modules/jpg/image_loader_jpegd.h +++ b/modules/jpg/image_loader_jpegd.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/jpg/register_types.cpp b/modules/jpg/register_types.cpp index a6ae96635f..63203274f4 100644 --- a/modules/jpg/register_types.cpp +++ b/modules/jpg/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/jpg/register_types.h b/modules/jpg/register_types.h index 577e9b06f7..97223cefda 100644 --- a/modules/jpg/register_types.h +++ b/modules/jpg/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/jsonrpc/jsonrpc.cpp b/modules/jsonrpc/jsonrpc.cpp index 3d0759d83e..91774fe1f6 100644 --- a/modules/jsonrpc/jsonrpc.cpp +++ b/modules/jsonrpc/jsonrpc.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/jsonrpc/jsonrpc.h b/modules/jsonrpc/jsonrpc.h index 9fd016602d..3144746f6d 100644 --- a/modules/jsonrpc/jsonrpc.h +++ b/modules/jsonrpc/jsonrpc.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/jsonrpc/register_types.cpp b/modules/jsonrpc/register_types.cpp index 8fdf6fe1aa..d89b7e9353 100644 --- a/modules/jsonrpc/register_types.cpp +++ b/modules/jsonrpc/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/jsonrpc/register_types.h b/modules/jsonrpc/register_types.h index 6a21a12444..57744e6c07 100644 --- a/modules/jsonrpc/register_types.h +++ b/modules/jsonrpc/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index ba4ef3be8d..5d5b2ed6cb 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -611,6 +611,61 @@ void LightmapperRD::_raster_geometry(RenderingDevice *rd, Size2i atlas_size, int } } +LightmapperRD::BakeError LightmapperRD::_dilate(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices) { + Vector<RD::Uniform> uniforms; + { + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 0; + u.ids.push_back(dest_light_tex); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 1; + u.ids.push_back(source_light_tex); + uniforms.push_back(u); + } + } + + RID compute_shader_dilate = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("dilate")); + ERR_FAIL_COND_V(compute_shader_dilate.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen + RID compute_shader_dilate_pipeline = rd->compute_pipeline_create(compute_shader_dilate); + + RID dilate_uniform_set = rd->uniform_set_create(uniforms, compute_shader_dilate, 1); + + RD::ComputeListID compute_list = rd->compute_list_begin(); + rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_dilate_pipeline); + rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0); + rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1); + push_constant.region_ofs[0] = 0; + push_constant.region_ofs[1] = 0; + Vector3i group_size((atlas_size.x - 1) / 8 + 1, (atlas_size.y - 1) / 8 + 1, 1); //restore group size + + for (int i = 0; i < atlas_slices; i++) { + push_constant.atlas_slice = i; + rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant)); + rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z); + //no barrier, let them run all together + } + rd->compute_list_end(); + rd->free(compute_shader_dilate); + +#ifdef DEBUG_TEXTURES + for (int i = 0; i < atlas_slices; i++) { + Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i); + Ref<Image> img; + img.instantiate(); + img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s); + img->convert(Image::FORMAT_RGBA8); + img->save_png("res://5_dilated_" + itos(i) + ".png"); + } +#endif + return BAKE_OK; +} + LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function, void *p_bake_userdata) { if (p_step_function) { p_step_function(0.0, TTR("Begin Bake"), p_bake_userdata, true); @@ -943,11 +998,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d ERR_FAIL_COND_V(compute_shader_secondary.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen RID compute_shader_secondary_pipeline = rd->compute_pipeline_create(compute_shader_secondary); - // Dilate - RID compute_shader_dilate = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("dilate")); - ERR_FAIL_COND_V(compute_shader_dilate.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen - RID compute_shader_dilate_pipeline = rd->compute_pipeline_create(compute_shader_dilate); - // Light probes RID compute_shader_light_probes = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("light_probes")); ERR_FAIL_COND_V(compute_shader_light_probes.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen @@ -959,7 +1009,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d rd->free(compute_shader_unocclude); \ rd->free(compute_shader_primary); \ rd->free(compute_shader_secondary); \ - rd->free(compute_shader_dilate); \ rd->free(compute_shader_light_probes); PushConstant push_constant; @@ -1270,7 +1319,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d push_constant.environment_xform[3] = 0.0f; } - /* LIGHPROBES */ + /* LIGHTPROBES */ RID light_probe_buffer; @@ -1377,6 +1426,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d } #endif + { + SWAP(light_accum_tex, light_accum_tex2); + BakeError error = _dilate(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices * (p_bake_sh ? 4 : 1)); + if (unlikely(error != BAKE_OK)) { + return error; + } + } + /* DENOISE */ if (p_use_denoiser) { @@ -1409,58 +1466,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d } } } - } -#ifdef DEBUG_TEXTURES - - for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) { - Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i); - Ref<Image> img; - img.instantiate(); - img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s); - img->save_exr("res://4_light_secondary_" + itos(i) + ".exr", false); - } -#endif - - /* DILATE LIGHTMAP */ - { - SWAP(light_accum_tex, light_accum_tex2); - - Vector<RD::Uniform> uniforms; { - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 0; - u.ids.push_back(light_accum_tex); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 1; - u.ids.push_back(light_accum_tex2); - uniforms.push_back(u); + SWAP(light_accum_tex, light_accum_tex2); + BakeError error = _dilate(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices * (p_bake_sh ? 4 : 1)); + if (unlikely(error != BAKE_OK)) { + return error; } } - - RID dilate_uniform_set = rd->uniform_set_create(uniforms, compute_shader_dilate, 1); - - RD::ComputeListID compute_list = rd->compute_list_begin(); - rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_dilate_pipeline); - rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0); - rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1); - push_constant.region_ofs[0] = 0; - push_constant.region_ofs[1] = 0; - group_size = Vector3i((atlas_size.x - 1) / 8 + 1, (atlas_size.y - 1) / 8 + 1, 1); //restore group size - - for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) { - push_constant.atlas_slice = i; - rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant)); - rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z); - //no barrier, let them run all together - } - rd->compute_list_end(); } #ifdef DEBUG_TEXTURES @@ -1470,8 +1483,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d Ref<Image> img; img.instantiate(); img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s); - img->convert(Image::FORMAT_RGBA8); - img->save_png("res://5_dilated_" + itos(i) + ".png"); + img->save_exr("res://4_light_secondary_" + itos(i) + ".exr", false); } #endif diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index a6a3740051..503f5f7009 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,6 +36,7 @@ #include "scene/resources/mesh.h" #include "servers/rendering/rendering_device.h" +class RDShaderFile; class LightmapperRD : public Lightmapper { GDCLASS(LightmapperRD, Lightmapper) @@ -72,13 +73,13 @@ class LightmapperRD : public Lightmapper { bool operator==(const Vertex &p_vtx) const { return (position[0] == p_vtx.position[0]) && - (position[1] == p_vtx.position[1]) && - (position[2] == p_vtx.position[2]) && - (uv[0] == p_vtx.uv[0]) && - (uv[1] == p_vtx.uv[1]) && - (normal_xy[0] == p_vtx.normal_xy[0]) && - (normal_xy[1] == p_vtx.normal_xy[1]) && - (normal_z == p_vtx.normal_z); + (position[1] == p_vtx.position[1]) && + (position[2] == p_vtx.position[2]) && + (uv[0] == p_vtx.uv[0]) && + (uv[1] == p_vtx.uv[1]) && + (normal_xy[0] == p_vtx.normal_xy[0]) && + (normal_xy[1] == p_vtx.normal_xy[1]) && + (normal_z == p_vtx.normal_z); } }; @@ -231,6 +232,8 @@ class LightmapperRD : public Lightmapper { void _create_acceleration_structures(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, AABB &bounds, int grid_size, Vector<Probe> &probe_positions, GenerateProbes p_generate_probes, Vector<int> &slice_triangle_count, Vector<int> &slice_seam_count, RID &vertex_buffer, RID &triangle_buffer, RID &lights_buffer, RID &triangle_cell_indices_buffer, RID &probe_positions_buffer, RID &grid_texture, RID &seams_buffer, BakeStepFunc p_step_function, void *p_bake_userdata); void _raster_geometry(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, int grid_size, AABB bounds, float p_bias, Vector<int> slice_triangle_count, RID position_tex, RID unocclude_tex, RID normal_tex, RID raster_depth_buffer, RID rasterize_shader, RID raster_base_uniform); + BakeError _dilate(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices); + public: virtual void add_mesh(const MeshData &p_mesh) override; virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) override; diff --git a/modules/lightmapper_rd/lm_common_inc.glsl b/modules/lightmapper_rd/lm_common_inc.glsl index 22172d50e4..58523dc1f8 100644 --- a/modules/lightmapper_rd/lm_common_inc.glsl +++ b/modules/lightmapper_rd/lm_common_inc.glsl @@ -81,3 +81,7 @@ layout(set = 0, binding = 8) uniform texture2DArray albedo_tex; layout(set = 0, binding = 9) uniform texture2DArray emission_tex; layout(set = 0, binding = 10) uniform sampler linear_sampler; + +// Fragment action constants +const uint FA_NONE = 0; +const uint FA_SMOOTHEN_POSITION = 1; diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index 25b334c5eb..7bb8346c47 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -94,13 +94,14 @@ params; //check it, but also return distance and barycentric coords (for uv lookup) bool ray_hits_triangle(vec3 from, vec3 dir, float max_dist, vec3 p0, vec3 p1, vec3 p2, out float r_distance, out vec3 r_barycentric) { + const float EPSILON = 0.00001; const vec3 e0 = p1 - p0; const vec3 e1 = p0 - p2; vec3 triangle_normal = cross(e1, e0); float n_dot_dir = dot(triangle_normal, dir); - if (abs(n_dot_dir) < 0.01) { + if (abs(n_dot_dir) < EPSILON) { return false; } @@ -148,7 +149,7 @@ uint trace_ray(vec3 p_from, vec3 p_to ivec3 icell = ivec3(from_cell); ivec3 iendcell = ivec3(to_cell); vec3 dir_cell = normalize(rel_cell); - vec3 delta = abs(1.0 / dir_cell); //vec3(length(rel_cell)) / rel_cell); + vec3 delta = min(abs(1.0 / dir_cell), params.grid_size); // use params.grid_size as max to prevent infinity values ivec3 step = ivec3(sign(rel_cell)); vec3 side = (sign(rel_cell) * (vec3(icell) - from_cell) + (sign(rel_cell) * 0.5) + 0.5) * delta; @@ -234,19 +235,39 @@ uint trace_ray(vec3 p_from, vec3 p_to return RAY_MISS; } +// https://www.reedbeta.com/blog/hash-functions-for-gpu-rendering/ +uint hash(uint value) { + uint state = value * 747796405u + 2891336453u; + uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; + return (word >> 22u) ^ word; +} + +uint random_seed(ivec3 seed) { + return hash(seed.x ^ hash(seed.y ^ hash(seed.z))); +} + +// generates a random value in range [0.0, 1.0) +float randomize(inout uint value) { + value = hash(value); + return float(value / 4294967296.0); +} + const float PI = 3.14159265f; -const float GOLDEN_ANGLE = PI * (3.0 - sqrt(5.0)); - -vec3 vogel_hemisphere(uint p_index, uint p_count, float p_offset) { - float r = sqrt(float(p_index) + 0.5f) / sqrt(float(p_count)); - float theta = float(p_index) * GOLDEN_ANGLE + p_offset; - float y = cos(r * PI * 0.5); - float l = sin(r * PI * 0.5); - return vec3(l * cos(theta), l * sin(theta), y); + +// http://www.realtimerendering.com/raytracinggems/unofficial_RayTracingGems_v1.4.pdf (chapter 15) +vec3 generate_hemisphere_uniform_direction(inout uint noise) { + float noise1 = randomize(noise); + float noise2 = randomize(noise) * 2.0 * PI; + + float factor = sqrt(1 - (noise1 * noise1)); + return vec3(factor * cos(noise2), factor * sin(noise2), noise1); } -float quick_hash(vec2 pos) { - return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237); +vec3 generate_hemisphere_cosine_weighted_direction(inout uint noise) { + float noise1 = randomize(noise); + float noise2 = randomize(noise) * 2.0 * PI; + + return vec3(sqrt(noise1) * cos(noise2), sqrt(noise1) * sin(noise2), sqrt(1.0 - noise1)); } float get_omni_attenuation(float distance, float inv_range, float decay) { @@ -403,8 +424,9 @@ void main() { #endif vec3 light_average = vec3(0.0); float active_rays = 0.0; + uint noise = random_seed(ivec3(params.ray_from, atlas_pos)); for (uint i = params.ray_from; i < params.ray_to; i++) { - vec3 ray_dir = normal_mat * vogel_hemisphere(i, params.ray_count, quick_hash(vec2(atlas_pos))); + vec3 ray_dir = normal_mat * generate_hemisphere_cosine_weighted_direction(noise); uint tidx; vec3 barycentric; @@ -420,20 +442,22 @@ void main() { light = textureLod(sampler2DArray(source_light, linear_sampler), uvw, 0.0).rgb; active_rays += 1.0; - } else if (trace_result == RAY_MISS && params.env_transform[0][3] == 0.0) { // Use env_transform[0][3] to indicate when we are computing the first bounce - // Did not hit a triangle, reach out for the sky - vec3 sky_dir = normalize(mat3(params.env_transform) * ray_dir); + } else if (trace_result == RAY_MISS) { + if (params.env_transform[0][3] == 0.0) { // Use env_transform[0][3] to indicate when we are computing the first bounce + // Did not hit a triangle, reach out for the sky + vec3 sky_dir = normalize(mat3(params.env_transform) * ray_dir); - vec2 st = vec2( - atan(sky_dir.x, sky_dir.z), - acos(sky_dir.y)); + vec2 st = vec2( + atan(sky_dir.x, sky_dir.z), + acos(sky_dir.y)); - if (st.x < 0.0) - st.x += PI * 2.0; + if (st.x < 0.0) + st.x += PI * 2.0; - st /= vec2(PI * 2.0, PI); + st /= vec2(PI * 2.0, PI); - light = textureLod(sampler2D(environment, linear_sampler), st, 0.0).rgb; + light = textureLod(sampler2D(environment, linear_sampler), st, 0.0).rgb; + } active_rays += 1.0; } @@ -547,8 +571,9 @@ void main() { vec4(0.0), vec4(0.0)); + uint noise = random_seed(ivec3(params.ray_from, probe_index, 49502741 /* some prime */)); for (uint i = params.ray_from; i < params.ray_to; i++) { - vec3 ray_dir = vogel_hemisphere(i, params.ray_count, quick_hash(vec2(float(probe_index), 0.0))); + vec3 ray_dir = generate_hemisphere_uniform_direction(noise); if (bool(i & 1)) { //throw to both sides, so alternate them ray_dir.z *= -1.0; diff --git a/modules/lightmapper_rd/lm_raster.glsl b/modules/lightmapper_rd/lm_raster.glsl index 55ca193cc1..a86968a4f3 100644 --- a/modules/lightmapper_rd/lm_raster.glsl +++ b/modules/lightmapper_rd/lm_raster.glsl @@ -12,6 +12,7 @@ layout(location = 2) out vec2 uv_interp; layout(location = 3) out vec3 barycentric; layout(location = 4) flat out uvec3 vertex_indices; layout(location = 5) flat out vec3 face_normal; +layout(location = 6) flat out uint fragment_action; layout(push_constant, binding = 0, std430) uniform Params { vec2 atlas_size; @@ -49,6 +50,14 @@ void main() { face_normal = -normalize(cross((vertices.data[vertex_indices.x].position - vertices.data[vertex_indices.y].position), (vertices.data[vertex_indices.x].position - vertices.data[vertex_indices.z].position))); + { + const float FLAT_THRESHOLD = 0.99; + const vec3 norm_a = vec3(vertices.data[vertex_indices.x].normal_xy, vertices.data[vertex_indices.x].normal_z); + const vec3 norm_b = vec3(vertices.data[vertex_indices.y].normal_xy, vertices.data[vertex_indices.y].normal_z); + const vec3 norm_c = vec3(vertices.data[vertex_indices.z].normal_xy, vertices.data[vertex_indices.z].normal_z); + fragment_action = (dot(norm_a, norm_b) < FLAT_THRESHOLD || dot(norm_a, norm_c) < FLAT_THRESHOLD || dot(norm_b, norm_c) < FLAT_THRESHOLD) ? FA_SMOOTHEN_POSITION : FA_NONE; + } + gl_Position = vec4((uv_interp + params.uv_offset) * 2.0 - 1.0, 0.0001, 1.0); } @@ -78,6 +87,7 @@ layout(location = 2) in vec2 uv_interp; layout(location = 3) in vec3 barycentric; layout(location = 4) in flat uvec3 vertex_indices; layout(location = 5) in flat vec3 face_normal; +layout(location = 6) in flat uint fragment_action; layout(location = 0) out vec4 position; layout(location = 1) out vec4 normal; @@ -86,7 +96,7 @@ layout(location = 2) out vec4 unocclude; void main() { vec3 vertex_pos = vertex_interp; - { + if (fragment_action == FA_SMOOTHEN_POSITION) { // smooth out vertex position by interpolating its projection in the 3 normal planes (normal plane is created by vertex pos and normal) // because we don't want to interpolate inwards, normals found pointing inwards are pushed out. vec3 pos_a = vertices.data[vertex_indices.x].position; diff --git a/modules/lightmapper_rd/register_types.cpp b/modules/lightmapper_rd/register_types.cpp index ae9c5fc390..0a96a86076 100644 --- a/modules/lightmapper_rd/register_types.cpp +++ b/modules/lightmapper_rd/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/lightmapper_rd/register_types.h b/modules/lightmapper_rd/register_types.h index 622d6e37a7..35a701ce01 100644 --- a/modules/lightmapper_rd/register_types.h +++ b/modules/lightmapper_rd/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index 2522f1bb11..ea6b6d8233 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -310,7 +310,7 @@ void CryptoMbedTLS::load_default_certificates(String p_path) { default_certs = memnew(X509CertificateMbedTLS); ERR_FAIL_COND(default_certs == nullptr); - if (p_path != "") { + if (!p_path.is_empty()) { // Use certs defined in project settings. default_certs->load(p_path); } diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h index afa1ea7a64..5ba7e9cbf6 100644 --- a/modules/mbedtls/crypto_mbedtls.h +++ b/modules/mbedtls/crypto_mbedtls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/dtls_server_mbedtls.cpp b/modules/mbedtls/dtls_server_mbedtls.cpp index b1b6b3844b..dedf0651a0 100644 --- a/modules/mbedtls/dtls_server_mbedtls.cpp +++ b/modules/mbedtls/dtls_server_mbedtls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/dtls_server_mbedtls.h b/modules/mbedtls/dtls_server_mbedtls.h index 9f0c9670e7..29370062c4 100644 --- a/modules/mbedtls/dtls_server_mbedtls.h +++ b/modules/mbedtls/dtls_server_mbedtls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/packet_peer_mbed_dtls.cpp b/modules/mbedtls/packet_peer_mbed_dtls.cpp index 114bf49e9e..2a5eaa0109 100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.cpp +++ b/modules/mbedtls/packet_peer_mbed_dtls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/packet_peer_mbed_dtls.h b/modules/mbedtls/packet_peer_mbed_dtls.h index 6554c74a21..5f2f42cd30 100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.h +++ b/modules/mbedtls/packet_peer_mbed_dtls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -59,8 +59,6 @@ protected: Ref<SSLContextMbedTLS> ssl_ctx; mbedtls_timing_delay_context timer; - static void _bind_methods(); - Error _do_handshake(); int _set_cookie(); diff --git a/modules/mbedtls/register_types.cpp b/modules/mbedtls/register_types.cpp index e483030b94..1af978e70a 100644 --- a/modules/mbedtls/register_types.cpp +++ b/modules/mbedtls/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/register_types.h b/modules/mbedtls/register_types.h index 46ffb8522b..4bc2cca118 100644 --- a/modules/mbedtls/register_types.h +++ b/modules/mbedtls/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/ssl_context_mbedtls.cpp b/modules/mbedtls/ssl_context_mbedtls.cpp index cbb532587f..e2dad074cc 100644 --- a/modules/mbedtls/ssl_context_mbedtls.cpp +++ b/modules/mbedtls/ssl_context_mbedtls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h index 1b55a54a10..dd49792abd 100644 --- a/modules/mbedtls/ssl_context_mbedtls.h +++ b/modules/mbedtls/ssl_context_mbedtls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -67,8 +67,6 @@ class SSLContextMbedTLS : public RefCounted { protected: bool inited = false; - static PackedByteArray _read_file(String p_path); - public: static void print_mbedtls_error(int p_ret); diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp index 5727f5f82f..05a57607cd 100644 --- a/modules/mbedtls/stream_peer_mbedtls.cpp +++ b/modules/mbedtls/stream_peer_mbedtls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/stream_peer_mbedtls.h b/modules/mbedtls/stream_peer_mbedtls.h index b89d7fb238..98b91e65ab 100644 --- a/modules/mbedtls/stream_peer_mbedtls.h +++ b/modules/mbedtls/stream_peer_mbedtls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -50,8 +50,6 @@ private: protected: Ref<SSLContextMbedTLS> ssl_ctx; - static void _bind_methods(); - Error _do_handshake(); public: diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.cpp b/modules/mbedtls/tests/test_crypto_mbedtls.cpp index 8762838883..f88012c6cd 100644 --- a/modules/mbedtls/tests/test_crypto_mbedtls.cpp +++ b/modules/mbedtls/tests/test_crypto_mbedtls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.h b/modules/mbedtls/tests/test_crypto_mbedtls.h index b798717e52..6f920e5b34 100644 --- a/modules/mbedtls/tests/test_crypto_mbedtls.h +++ b/modules/mbedtls/tests/test_crypto_mbedtls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/meshoptimizer/register_types.cpp b/modules/meshoptimizer/register_types.cpp index 77cc82a4e2..57a1b697be 100644 --- a/modules/meshoptimizer/register_types.cpp +++ b/modules/meshoptimizer/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/meshoptimizer/register_types.h b/modules/meshoptimizer/register_types.h index 5b15503acd..fdd8bed657 100644 --- a/modules/meshoptimizer/register_types.h +++ b/modules/meshoptimizer/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp index 7b52ef178a..63fec6db8c 100644 --- a/modules/minimp3/audio_stream_mp3.cpp +++ b/modules/minimp3/audio_stream_mp3.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -112,7 +112,7 @@ void AudioStreamPlaybackMP3::seek(float p_time) { } frames_mixed = uint32_t(mp3_stream->sample_rate * p_time); - mp3dec_ex_seek(mp3d, frames_mixed * mp3_stream->channels); + mp3dec_ex_seek(mp3d, (uint64_t)frames_mixed * mp3_stream->channels); } AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() { @@ -125,7 +125,7 @@ AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() { Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() { Ref<AudioStreamPlaybackMP3> mp3s; - ERR_FAIL_COND_V_MSG(data == nullptr, mp3s, + ERR_FAIL_COND_V_MSG(data.is_empty(), mp3s, "This AudioStreamMP3 does not have an audio file assigned " "to it. AudioStreamMP3 should not be created from the " "inspector or with `.new()`. Instead, load an audio file."); @@ -134,7 +134,7 @@ Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() { mp3s->mp3_stream = Ref<AudioStreamMP3>(this); mp3s->mp3d = (mp3dec_ex_t *)memalloc(sizeof(mp3dec_ex_t)); - int errorcode = mp3dec_ex_open_buf(mp3s->mp3d, (const uint8_t *)data, data_len, MP3D_SEEK_TO_SAMPLE); + int errorcode = mp3dec_ex_open_buf(mp3s->mp3d, data.ptr(), data_len, MP3D_SEEK_TO_SAMPLE); mp3s->frames_mixed = 0; mp3s->active = false; @@ -152,11 +152,7 @@ String AudioStreamMP3::get_stream_name() const { } void AudioStreamMP3::clear_data() { - if (data) { - memfree(data); - data = nullptr; - data_len = 0; - } + data.clear(); } void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) { @@ -165,7 +161,7 @@ void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) { mp3dec_ex_t mp3d; int err = mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE); - ERR_FAIL_COND(err != 0); + ERR_FAIL_COND_MSG(err || mp3d.info.hz == 0, "Failed to decode mp3 file. Make sure it is a valid mp3 audio file."); channels = mp3d.info.channels; sample_rate = mp3d.info.hz; @@ -175,23 +171,13 @@ void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) { clear_data(); - data = memalloc(src_data_len); - memcpy(data, src_datar, src_data_len); + data.resize(src_data_len); + memcpy(data.ptrw(), src_datar, src_data_len); data_len = src_data_len; } Vector<uint8_t> AudioStreamMP3::get_data() const { - Vector<uint8_t> vdata; - - if (data_len && data) { - vdata.resize(data_len); - { - uint8_t *w = vdata.ptrw(); - memcpy(w, data, data_len); - } - } - - return vdata; + return data; } void AudioStreamMP3::set_loop(bool p_enable) { @@ -228,9 +214,9 @@ void AudioStreamMP3::_bind_methods() { ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamMP3::set_loop_offset); ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamMP3::get_loop_offset); - ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_loop", "has_loop"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_loop_offset", "get_loop_offset"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_data", "get_data"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset"); } AudioStreamMP3::AudioStreamMP3() { diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h index 3c8bdd8c53..c1a60ddccb 100644 --- a/modules/minimp3/audio_stream_mp3.h +++ b/modules/minimp3/audio_stream_mp3.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -75,7 +75,7 @@ class AudioStreamMP3 : public AudioStream { friend class AudioStreamPlaybackMP3; - void *data = nullptr; + PackedByteArray data; uint32_t data_len = 0; float sample_rate = 1.0; diff --git a/modules/minimp3/register_types.cpp b/modules/minimp3/register_types.cpp index 63f2589f42..4d32ebf8ea 100644 --- a/modules/minimp3/register_types.cpp +++ b/modules/minimp3/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/minimp3/register_types.h b/modules/minimp3/register_types.h index 96227c272e..fa7f67eefc 100644 --- a/modules/minimp3/register_types.h +++ b/modules/minimp3/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/minimp3/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp index dc360c12ba..0e0da806bf 100644 --- a/modules/minimp3/resource_importer_mp3.cpp +++ b/modules/minimp3/resource_importer_mp3.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,7 +54,7 @@ String ResourceImporterMP3::get_resource_type() const { return "AudioStreamMP3"; } -bool ResourceImporterMP3::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { +bool ResourceImporterMP3::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const { return true; } @@ -66,7 +66,7 @@ String ResourceImporterMP3::get_preset_name(int p_idx) const { return String(); } -void ResourceImporterMP3::get_import_options(List<ImportOption> *r_options, int p_preset) const { +void ResourceImporterMP3::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "loop_offset"), 0)); } diff --git a/modules/minimp3/resource_importer_mp3.h b/modules/minimp3/resource_importer_mp3.h index 71b51887a2..75890228b9 100644 --- a/modules/minimp3/resource_importer_mp3.h +++ b/modules/minimp3/resource_importer_mp3.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -47,8 +47,8 @@ public: virtual int get_preset_count() const override; virtual String get_preset_name(int p_idx) const override; - virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override; - virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override; + virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; + virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override; virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml index 04ba82ef51..df099f2c98 100644 --- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml +++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml @@ -37,5 +37,6 @@ <member name="oversample" type="float" setter="set_oversample" getter="get_oversample" default="1.5"> The oversample setting. Because of the lens distortion we have to render our buffers at a higher resolution then the screen can natively handle. A value between 1.5 and 2.0 often provides good results but at the cost of performance. </member> + <member name="xr_play_area_mode" type="int" setter="set_play_area_mode" getter="get_play_area_mode" overrides="XRInterface" enum="XRInterface.PlayAreaMode" default="1" /> </members> </class> diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index fc1a118e4f..59854ad527 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -126,6 +126,8 @@ void MobileVRInterface::set_position_from_sensors() { // 9dof is a misleading marketing term coming from 3 accelerometer axis + 3 gyro axis + 3 magnetometer axis = 9 axis // but in reality this only offers 3 dof (yaw, pitch, roll) orientation + Basis orientation; + uint64_t ticks = OS::get_singleton()->get_ticks_usec(); uint64_t ticks_elapsed = ticks - last_ticks; float delta_time = (double)ticks_elapsed / 1000000.0; @@ -207,8 +209,8 @@ void MobileVRInterface::set_position_from_sensors() { }; }; - // JIC - orientation.orthonormalize(); + // and copy to our head transform + head_transform.basis = orientation.orthonormalized(); last_ticks = ticks; }; @@ -318,7 +320,7 @@ bool MobileVRInterface::initialize() { ERR_FAIL_NULL_V(xr_server, false); if (!initialized) { - // reset our sensor data and orientation + // reset our sensor data mag_count = 0; has_gyro = false; sensor_first = true; @@ -326,9 +328,15 @@ bool MobileVRInterface::initialize() { mag_next_max = Vector3(-10000, -10000, -10000); mag_current_min = Vector3(0, 0, 0); mag_current_max = Vector3(0, 0, 0); + head_transform.basis = Basis(); + head_transform.origin = Vector3(0.0, eye_height, 0.0); - // reset our orientation - orientation = Basis(); + // we must create a tracker for our head + head.instantiate(); + head->set_tracker_type(XRServer::TRACKER_HEAD); + head->set_tracker_name("head"); + head->set_tracker_desc("Players head"); + xr_server->add_tracker(head); // make this our primary interface xr_server->set_primary_interface(this); @@ -343,16 +351,38 @@ bool MobileVRInterface::initialize() { void MobileVRInterface::uninitialize() { if (initialized) { + // do any cleanup here... XRServer *xr_server = XRServer::get_singleton(); - if (xr_server != nullptr && xr_server->get_primary_interface() == this) { - // no longer our primary interface - xr_server->set_primary_interface(nullptr); + if (xr_server != nullptr) { + if (head.is_valid()) { + xr_server->remove_tracker(head); + + head.unref(); + } + + if (xr_server->get_primary_interface() == this) { + // no longer our primary interface + xr_server->set_primary_interface(nullptr); + } } initialized = false; }; }; +bool MobileVRInterface::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) { + // This interface has no positional tracking so fix this to 3DOF + return p_mode == XR_PLAY_AREA_3DOF; +} + +XRInterface::PlayAreaMode MobileVRInterface::get_play_area_mode() const { + return XR_PLAY_AREA_3DOF; +} + +bool MobileVRInterface::set_play_area_mode(XRInterface::PlayAreaMode p_mode) { + return p_mode == XR_PLAY_AREA_3DOF; +} + Size2 MobileVRInterface::get_render_target_size() { _THREAD_SAFE_METHOD_ @@ -377,11 +407,10 @@ Transform3D MobileVRInterface::get_camera_transform() { float world_scale = xr_server->get_world_scale(); // just scale our origin point of our transform - Transform3D hmd_transform; - hmd_transform.basis = orientation; - hmd_transform.origin = Vector3(0.0, eye_height * world_scale, 0.0); + Transform3D _head_transform = head_transform; + _head_transform.origin *= world_scale; - transform_for_eye = (xr_server->get_reference_frame()) * hmd_transform; + transform_for_eye = (xr_server->get_reference_frame()) * _head_transform; } return transform_for_eye; @@ -409,11 +438,10 @@ Transform3D MobileVRInterface::get_transform_for_view(uint32_t p_view, const Tra }; // just scale our origin point of our transform - Transform3D hmd_transform; - hmd_transform.basis = orientation; - hmd_transform.origin = Vector3(0.0, eye_height * world_scale, 0.0); + Transform3D _head_transform = head_transform; + _head_transform.origin *= world_scale; - transform_for_eye = p_cam_transform * (xr_server->get_reference_frame()) * hmd_transform * transform_for_eye; + transform_for_eye = p_cam_transform * (xr_server->get_reference_frame()) * _head_transform * transform_for_eye; } else { // huh? well just return what we got.... transform_for_eye = p_cam_transform; @@ -476,7 +504,16 @@ void MobileVRInterface::process() { _THREAD_SAFE_METHOD_ if (initialized) { + // update our head transform orientation set_position_from_sensors(); + + // update our head transform position (should be constant) + head_transform.origin = Vector3(0.0, eye_height, 0.0); + + if (head.is_valid()) { + // Set our head position, note in real space, reference frame and world scale is applied later + head->set_pose("default", head_transform, Vector3(), Vector3()); + } }; }; diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index a843e1188b..9fcac3afe2 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -53,7 +53,6 @@ class MobileVRInterface : public XRInterface { private: bool initialized = false; XRInterface::TrackingStatus tracking_state; - Basis orientation; // Just set some defaults for these. At some point we need to look at adding a lookup table for common device + headset combos and/or support reading cardboard QR codes double eye_height = 1.85; @@ -68,6 +67,10 @@ private: double k2 = 0.215; double aspect = 1.0; + // at a minimum we need a tracker for our head + Ref<XRPositionalTracker> head; + Transform3D head_transform; + /* logic for processing our sensor data, this was originally in our positional tracker logic but I think that doesn't make sense in hindsight. It only makes marginally more sense to park it here for now, @@ -140,6 +143,10 @@ public: virtual bool initialize() override; virtual void uninitialize() override; + virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode) override; + virtual XRInterface::PlayAreaMode get_play_area_mode() const override; + virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode) override; + virtual Size2 get_render_target_size() override; virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; diff --git a/modules/mobile_vr/register_types.cpp b/modules/mobile_vr/register_types.cpp index 233c16531a..682d8bf59a 100644 --- a/modules/mobile_vr/register_types.cpp +++ b/modules/mobile_vr/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mobile_vr/register_types.h b/modules/mobile_vr/register_types.h index 9f20f252a4..8db96ac2fa 100644 --- a/modules/mobile_vr/register_types.h +++ b/modules/mobile_vr/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/SCsub b/modules/mono/SCsub index 3b94949470..db35e804aa 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -49,6 +49,7 @@ if env_mono["tools"] and env_mono["mono_glue"] and env_mono["build_cil"]: env_mono.add_source_files(env.modules_sources, "*.cpp") env_mono.add_source_files(env.modules_sources, "glue/*.cpp") +env_mono.add_source_files(env.modules_sources, "glue/mono_glue.gen.cpp") env_mono.add_source_files(env.modules_sources, "mono_gd/*.cpp") env_mono.add_source_files(env.modules_sources, "utils/*.cpp") @@ -57,6 +58,10 @@ env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.cpp") if env["platform"] in ["osx", "iphone"]: env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.mm") env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.m") +elif env["platform"] == "android": + env_mono.add_source_files(env.modules_sources, "mono_gd/android_mono_config.gen.cpp") if env["tools"]: env_mono.add_source_files(env.modules_sources, "editor/*.cpp") + +SConscript("editor_templates/SCsub") diff --git a/modules/mono/SdkPackageVersions.props b/modules/mono/SdkPackageVersions.props index df3ebe581c..bdec051625 100644 --- a/modules/mono/SdkPackageVersions.props +++ b/modules/mono/SdkPackageVersions.props @@ -1,6 +1,7 @@ <Project> <PropertyGroup> - <PackageVersion_Godot_NET_Sdk>4.0.0-dev5</PackageVersion_Godot_NET_Sdk> - <PackageVersion_Godot_SourceGenerators>4.0.0-dev2</PackageVersion_Godot_SourceGenerators> + <PackageFloatingVersion_Godot>4.0.*-*</PackageFloatingVersion_Godot> + <PackageVersion_Godot_NET_Sdk>4.0.0-dev6</PackageVersion_Godot_NET_Sdk> + <PackageVersion_Godot_SourceGenerators>4.0.0-dev3</PackageVersion_Godot_SourceGenerators> </PropertyGroup> </Project> diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py index 28494bff6e..1920ef1c1a 100644 --- a/modules/mono/build_scripts/make_android_mono_config.py +++ b/modules/mono/build_scripts/make_android_mono_config.py @@ -8,7 +8,9 @@ def generate_compressed_config(config_src, output_dir): decompr_size = len(buf) import zlib - buf = zlib.compress(buf) + # Use maximum zlib compression level to further reduce file size + # (at the cost of initial build times). + buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION) compr_size = len(buf) bytes_seq_str = "" diff --git a/modules/mono/build_scripts/mono_reg_utils.py b/modules/mono/build_scripts/mono_reg_utils.py index 0ec7e2f433..93a66ebf6f 100644 --- a/modules/mono/build_scripts/mono_reg_utils.py +++ b/modules/mono/build_scripts/mono_reg_utils.py @@ -2,7 +2,6 @@ import os import platform if os.name == "nt": - import sys import winreg diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp index 0da06131af..5884a24454 100644 --- a/modules/mono/class_db_api_json.cpp +++ b/modules/mono/class_db_api_json.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/class_db_api_json.h b/modules/mono/class_db_api_json.h index 6698a6260f..1d2000b033 100644 --- a/modules/mono/class_db_api_json.h +++ b/modules/mono/class_db_api_json.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/config.py b/modules/mono/config.py index 4c851a2989..df02d9a309 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -2,7 +2,7 @@ supported_platforms = ["windows", "osx", "linuxbsd", "server", "android", "haiku def can_build(env, platform): - return True + return not env["arch"].startswith("rv") def configure(env): diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 247eee4280..3d02f638ec 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -55,6 +55,7 @@ #endif #include "editor/editor_internal_calls.h" +#include "editor_templates/templates.gen.h" #include "godotsharp_dirs.h" #include "mono_gd/gd_mono_cache.h" #include "mono_gd/gd_mono_class.h" @@ -313,22 +314,22 @@ void CSharpLanguage::get_reserved_words(List<String> *p_words) const { bool CSharpLanguage::is_control_flow_keyword(String p_keyword) const { return p_keyword == "break" || - p_keyword == "case" || - p_keyword == "catch" || - p_keyword == "continue" || - p_keyword == "default" || - p_keyword == "do" || - p_keyword == "else" || - p_keyword == "finally" || - p_keyword == "for" || - p_keyword == "foreach" || - p_keyword == "goto" || - p_keyword == "if" || - p_keyword == "return" || - p_keyword == "switch" || - p_keyword == "throw" || - p_keyword == "try" || - p_keyword == "while"; + p_keyword == "case" || + p_keyword == "catch" || + p_keyword == "continue" || + p_keyword == "default" || + p_keyword == "do" || + p_keyword == "else" || + p_keyword == "finally" || + p_keyword == "for" || + p_keyword == "foreach" || + p_keyword == "goto" || + p_keyword == "if" || + p_keyword == "return" || + p_keyword == "switch" || + p_keyword == "throw" || + p_keyword == "try" || + p_keyword == "while"; } void CSharpLanguage::get_comment_delimiters(List<String> *p_delimiters) const { @@ -351,57 +352,33 @@ static String get_base_class_name(const String &p_base_class_name, const String return base_class; } -Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const { - String script_template = "using " BINDINGS_NAMESPACE ";\n" - "using System;\n" - "\n" - "public partial class %CLASS% : %BASE%\n" - "{\n" - " // Declare member variables here. Examples:\n" - " // private int a = 2;\n" - " // private string b = \"text\";\n" - "\n" - " // Called when the node enters the scene tree for the first time.\n" - " public override void _Ready()\n" - " {\n" - " \n" - " }\n" - "\n" - "// // Called every frame. 'delta' is the elapsed time since the previous frame.\n" - "// public override void _Process(float delta)\n" - "// {\n" - "// \n" - "// }\n" - "}\n"; - - // Replaces all spaces in p_class_name with underscores to prevent - // invalid C# Script templates from being generated when the object name - // has spaces in it. - String class_name_no_spaces = p_class_name.replace(" ", "_"); - String base_class_name = get_base_class_name(p_base_class_name, class_name_no_spaces); - script_template = script_template.replace("%BASE%", base_class_name) - .replace("%CLASS%", class_name_no_spaces); +bool CSharpLanguage::is_using_templates() { + return true; +} +Ref<Script> CSharpLanguage::make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const { Ref<CSharpScript> script; script.instantiate(); - script->set_source_code(script_template); - script->set_name(class_name_no_spaces); + String class_name_no_spaces = p_class_name.replace(" ", "_"); + String base_class_name = get_base_class_name(p_base_class_name, class_name_no_spaces); + String processed_template = p_template; + processed_template = processed_template.replace("_BINDINGS_NAMESPACE_", BINDINGS_NAMESPACE) + .replace("_BASE_", base_class_name) + .replace("_CLASS_", class_name_no_spaces) + .replace("_TS_", _get_indentation()); + script->set_source_code(processed_template); return script; } -bool CSharpLanguage::is_using_templates() { - return true; -} - -void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) { - String src = p_script->get_source_code(); - String class_name_no_spaces = p_class_name.replace(" ", "_"); - String base_class_name = get_base_class_name(p_base_class_name, class_name_no_spaces); - src = src.replace("%BASE%", base_class_name) - .replace("%CLASS%", class_name_no_spaces) - .replace("%TS%", _get_indentation()); - p_script->set_source_code(src); +Vector<ScriptLanguage::ScriptTemplate> CSharpLanguage::get_built_in_templates(StringName p_object) { + Vector<ScriptLanguage::ScriptTemplate> templates; + for (int i = 0; i < TEMPLATES_ARRAY_SIZE; i++) { + if (TEMPLATES[i].inherit == p_object) { + templates.append(TEMPLATES[i]); + } + } + return templates; } String CSharpLanguage::validate_path(const String &p_path) const { @@ -788,11 +765,7 @@ bool CSharpLanguage::is_assembly_reloading_needed() { GDMonoAssembly *proj_assembly = gdmono->get_project_assembly(); - String appname = ProjectSettings::get_singleton()->get("application/config/name"); - String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); - if (appname_safe.is_empty()) { - appname_safe = "UnnamedProject"; - } + String appname_safe = ProjectSettings::get_singleton()->get_safe_project_name(); appname_safe += ".dll"; @@ -1355,7 +1328,7 @@ void CSharpLanguage::_editor_init_callback() { // Enable it as a plugin EditorNode::add_editor_plugin(godotsharp_editor); - ED_SHORTCUT("mono/build_solution", TTR("Build Solution"), KEY_MASK_ALT | KEY_B); + ED_SHORTCUT("mono/build_solution", TTR("Build Solution"), KeyModifierMask::ALT | Key::B); godotsharp_editor->enable_plugin(); get_singleton()->godotsharp_editor = godotsharp_editor; @@ -1660,7 +1633,7 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) { GDMonoProperty *property = top->get_property(p_name); if (property) { - property->set_value(mono_object, GDMonoMarshal::variant_to_mono_object(p_value, property->get_type())); + property->set_value_from_variant(mono_object, p_value); return true; } @@ -1766,7 +1739,16 @@ void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Va ManagedType managedType; - GDMonoField *field = script->script_class->get_field(state_pair.first); + GDMonoField *field = nullptr; + GDMonoClass *top = script->script_class; + while (top && top != script->native) { + field = top->get_field(state_pair.first); + if (field) { + break; + } + + top = top->get_parent_class(); + } if (!field) { continue; // Properties ignored. We get the property baking fields instead. } @@ -1813,8 +1795,9 @@ void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName, } void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { - for (const KeyValue<StringName, PropertyInfo> &E : script->member_info) { - p_properties->push_back(E.value); + List<PropertyInfo> props; + for (OrderedHashMap<StringName, PropertyInfo>::ConstElement E = script->member_info.front(); E; E = E.next()) { + props.push_front(E.value()); } // Call _get_property_list @@ -1837,9 +1820,8 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { if (ret) { Array array = Array(GDMonoMarshal::mono_object_to_variant(ret)); for (int i = 0, size = array.size(); i < size; i++) { - p_properties->push_back(PropertyInfo::from_dict(array.get(i))); + props.push_back(PropertyInfo::from_dict(array.get(i))); } - return; } break; @@ -1847,6 +1829,10 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { top = top->get_parent_class(); } + + for (const PropertyInfo &prop : props) { + p_properties->push_back(prop); + } } Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { @@ -1865,8 +1851,9 @@ Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool * } void CSharpInstance::get_method_list(List<MethodInfo> *p_list) const { - if (!script->is_valid() || !script->script_class) + if (!script->is_valid() || !script->script_class) { return; + } GD_MONO_SCOPE_THREAD_ATTACH; @@ -2976,7 +2963,7 @@ bool CSharpScript::_set(const StringName &p_name, const Variant &p_value) { } void CSharpScript::_get_property_list(List<PropertyInfo> *p_properties) const { - p_properties->push_back(PropertyInfo(Variant::STRING, CSharpLanguage::singleton->string_names._script_source, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); + p_properties->push_back(PropertyInfo(Variant::STRING, CSharpLanguage::singleton->string_names._script_source, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); } void CSharpScript::_bind_methods() { @@ -3265,8 +3252,7 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) { "Script inherits from native type '" + String(native_name) + "', so it can't be instantiated in object of type: '" + p_this->get_class() + "'"); } - ERR_FAIL_V_MSG(nullptr, "Script inherits from native type '" + String(native_name) + - "', so it can't be instantiated in object of type: '" + p_this->get_class() + "'."); + ERR_FAIL_V_MSG(nullptr, "Script inherits from native type '" + String(native_name) + "', so it can't be instantiated in object of type: '" + p_this->get_class() + "'."); } } @@ -3499,9 +3485,15 @@ Ref<Script> CSharpScript::get_base_script() const { return Ref<Script>(); } -void CSharpScript::get_script_property_list(List<PropertyInfo> *p_list) const { - for (const KeyValue<StringName, PropertyInfo> &E : member_info) { - p_list->push_back(E.value); +void CSharpScript::get_script_property_list(List<PropertyInfo> *r_list) const { + List<PropertyInfo> props; + + for (OrderedHashMap<StringName, PropertyInfo>::ConstElement E = member_info.front(); E; E = E.next()) { + props.push_front(E.value()); + } + + for (const PropertyInfo &prop : props) { + r_list->push_back(prop); } } @@ -3529,10 +3521,10 @@ Error CSharpScript::load_source_code(const String &p_path) { Error ferr = read_all_file_utf8(p_path, source); ERR_FAIL_COND_V_MSG(ferr != OK, ferr, - ferr == ERR_INVALID_DATA ? - "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded." - " Please ensure that scripts are saved in valid UTF-8 unicode." : - "Failed to read file: '" + p_path + "'."); + ferr == ERR_INVALID_DATA + ? "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded." + " Please ensure that scripts are saved in valid UTF-8 unicode." + : "Failed to read file: '" + p_path + "'."); #ifdef TOOLS_ENABLED source_changed_cache = true; diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index afc17f694a..221bba3af9 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -154,7 +154,7 @@ private: Set<StringName> exported_members_names; #endif - Map<StringName, PropertyInfo> member_info; + OrderedHashMap<StringName, PropertyInfo> member_info; void _clear(); @@ -215,7 +215,7 @@ public: void get_script_signal_list(List<MethodInfo> *r_signals) const override; bool get_property_default_value(const StringName &p_property, Variant &r_value) const override; - void get_script_property_list(List<PropertyInfo> *p_list) const override; + void get_script_property_list(List<PropertyInfo> *r_list) const override; void update_exports() override; void get_members(Set<StringName> *p_members) override; @@ -463,9 +463,9 @@ public: bool is_control_flow_keyword(String p_keyword) const override; void get_comment_delimiters(List<String> *p_delimiters) const override; void get_string_delimiters(List<String> *p_delimiters) const override; - Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const override; bool is_using_templates() override; - void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) override; + virtual Ref<Script> make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const override; + virtual Vector<ScriptTemplate> get_built_in_templates(StringName p_object) override; /* TODO */ bool validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override { return true; diff --git a/modules/mono/doc_classes/CSharpScript.xml b/modules/mono/doc_classes/CSharpScript.xml index 45a6f991bf..14c62b4bb0 100644 --- a/modules/mono/doc_classes/CSharpScript.xml +++ b/modules/mono/doc_classes/CSharpScript.xml @@ -8,17 +8,14 @@ See also [GodotSharp]. </description> <tutorials> - <link title="C# tutorial index">https://docs.godotengine.org/en/latest/getting_started/scripting/c_sharp/index.html</link> + <link title="C# documentation index">$DOCS_URL/tutorials/scripting/c_sharp/index.html</link> </tutorials> <methods> <method name="new" qualifiers="vararg"> - <return type="Variant"> - </return> + <return type="Variant" /> <description> Returns a new instance of the script. </description> </method> </methods> - <constants> - </constants> </class> diff --git a/modules/mono/doc_classes/GodotSharp.xml b/modules/mono/doc_classes/GodotSharp.xml index 417f8ac704..a148072245 100644 --- a/modules/mono/doc_classes/GodotSharp.xml +++ b/modules/mono/doc_classes/GodotSharp.xml @@ -11,66 +11,55 @@ </tutorials> <methods> <method name="attach_thread"> - <return type="void"> - </return> + <return type="void" /> <description> Attaches the current thread to the Mono runtime. </description> </method> <method name="detach_thread"> - <return type="void"> - </return> + <return type="void" /> <description> Detaches the current thread from the Mono runtime. </description> </method> <method name="get_domain_id"> - <return type="int"> - </return> + <return type="int" /> <description> Returns the current MonoDomain ID. [b]Note:[/b] The Mono runtime must be initialized for this method to work (use [method is_runtime_initialized] to check). If the Mono runtime isn't initialized at the time this method is called, the engine will crash. </description> </method> <method name="get_scripts_domain_id"> - <return type="int"> - </return> + <return type="int" /> <description> Returns the scripts MonoDomain's ID. This will be the same MonoDomain ID as [method get_domain_id], unless the scripts domain isn't loaded. [b]Note:[/b] The Mono runtime must be initialized for this method to work (use [method is_runtime_initialized] to check). If the Mono runtime isn't initialized at the time this method is called, the engine will crash. </description> </method> <method name="is_domain_finalizing_for_unload"> - <return type="bool"> - </return> - <argument index="0" name="domain_id" type="int"> - </argument> + <return type="bool" /> + <argument index="0" name="domain_id" type="int" /> <description> Returns [code]true[/code] if the domain is being finalized, [code]false[/code] otherwise. </description> </method> <method name="is_runtime_initialized"> - <return type="bool"> - </return> + <return type="bool" /> <description> Returns [code]true[/code] if the Mono runtime is initialized, [code]false[/code] otherwise. </description> </method> <method name="is_runtime_shutting_down"> - <return type="bool"> - </return> + <return type="bool" /> <description> Returns [code]true[/code] if the Mono runtime is shutting down, [code]false[/code] otherwise. </description> </method> <method name="is_scripts_domain_loaded"> - <return type="bool"> - </return> + <return type="bool" /> <description> Returns [code]true[/code] if the scripts domain is loaded, [code]false[/code] otherwise. </description> </method> </methods> - <constants> - </constants> </class> diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets index 92e299d2f3..397ede9644 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets @@ -17,6 +17,6 @@ <!-- C# source generators --> <ItemGroup Condition=" '$(DisableImplicitGodotGeneratorReferences)' != 'true' "> - <PackageReference Include="Godot.SourceGenerators" Version="$(PackageVersion_Godot_SourceGenerators)" /> + <PackageReference Include="Godot.SourceGenerators" Version="$(PackageFloatingVersion_Godot)" /> </ItemGroup> </Project> diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs new file mode 100644 index 0000000000..2ddb8880c2 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs @@ -0,0 +1,16 @@ +namespace Godot.SourceGenerators.Sample +{ + partial class Generic<T> : Godot.Object + { + } + + // Generic again but different generic parameters + partial class Generic<T, R> : Godot.Object + { + } + + // Generic again but without generic parameters + partial class Generic : Godot.Object + { + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs index a51728e221..fa65595290 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs @@ -97,9 +97,13 @@ namespace Godot.SourceGenerators string.Empty; bool hasNamespace = classNs.Length != 0; - string uniqueName = hasNamespace ? - classNs + "." + className + "_ScriptPath_Generated" : - className + "_ScriptPath_Generated"; + var uniqueName = new StringBuilder(); + if (hasNamespace) + uniqueName.Append($"{classNs}."); + uniqueName.Append(className); + if (symbol.IsGenericType) + uniqueName.Append($"Of{string.Join(string.Empty, symbol.TypeParameters)}"); + uniqueName.Append("_ScriptPath_Generated"); var source = new StringBuilder(); @@ -121,6 +125,8 @@ namespace Godot.SourceGenerators source.Append(attributes); source.Append("\n partial class "); source.Append(className); + if (symbol.IsGenericType) + source.Append($"<{string.Join(", ", symbol.TypeParameters)}>"); source.Append("\n{\n}\n"); if (hasNamespace) @@ -128,7 +134,7 @@ namespace Godot.SourceGenerators source.Append("\n}\n"); } - context.AddSource(uniqueName, SourceText.From(source.ToString(), Encoding.UTF8)); + context.AddSource(uniqueName.ToString(), SourceText.From(source.ToString(), Encoding.UTF8)); } private static void AddScriptTypesAssemblyAttr(GeneratorExecutionContext context, @@ -145,12 +151,15 @@ namespace Godot.SourceGenerators foreach (var godotClass in godotClasses) { var qualifiedName = godotClass.Key.ToDisplayString( - NullableFlowState.NotNull, SymbolDisplayFormat.FullyQualifiedFormat); + NullableFlowState.NotNull, SymbolDisplayFormat.FullyQualifiedFormat + .WithGenericsOptions(SymbolDisplayGenericsOptions.None)); if (!first) sourceBuilder.Append(", "); first = false; sourceBuilder.Append("typeof("); sourceBuilder.Append(qualifiedName); + if (godotClass.Key.IsGenericType) + sourceBuilder.Append($"<{new string(',', godotClass.Key.TypeParameters.Count() - 1)}>"); sourceBuilder.Append(")"); } diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs index 0f50c90531..bc09e1ebf9 100644 --- a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs +++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs @@ -122,13 +122,19 @@ namespace GodotTools.IdeMessaging this.logger = logger; string projectMetadataDir = Path.Combine(godotProjectDir, ".godot", "mono", "metadata"); + // FileSystemWatcher requires an existing directory + if (!Directory.Exists(projectMetadataDir)) { + // Check if the non hidden version exists + string nonHiddenProjectMetadataDir = Path.Combine(godotProjectDir, "godot", "mono", "metadata"); + if (Directory.Exists(nonHiddenProjectMetadataDir)) { + projectMetadataDir = nonHiddenProjectMetadataDir; + } else { + Directory.CreateDirectory(projectMetadataDir); + } + } MetaFilePath = Path.Combine(projectMetadataDir, GodotIdeMetadata.DefaultFileName); - // FileSystemWatcher requires an existing directory - if (!Directory.Exists(projectMetadataDir)) - Directory.CreateDirectory(projectMetadataDir); - fsWatcher = new FileSystemWatcher(projectMetadataDir, GodotIdeMetadata.DefaultFileName); } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs index b53347fc4c..56fca6b5cb 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs @@ -119,7 +119,7 @@ namespace GodotTools.Build private void IssueActivated(int idx) { - if (idx < 0 || idx >= _issuesList.GetItemCount()) + if (idx < 0 || idx >= _issuesList.ItemCount) throw new IndexOutOfRangeException("Item list index out of range"); // Get correct issue idx from issue list @@ -193,7 +193,7 @@ namespace GodotTools.Build string itemText = lineBreakIdx == -1 ? text : text.Substring(0, lineBreakIdx); _issuesList.AddItem(itemText, issue.Warning ? warningIcon : errorIcon); - int index = _issuesList.GetItemCount() - 1; + int index = _issuesList.ItemCount - 1; _issuesList.SetItemTooltip(index, tooltip); _issuesList.SetItemMetadata(index, i); } @@ -207,7 +207,7 @@ namespace GodotTools.Build _issuesList.Clear(); - var issue = new BuildIssue {Message = cause, Warning = false}; + var issue = new BuildIssue { Message = cause, Warning = false }; ErrorCount += 1; _issues.Add(issue); @@ -348,7 +348,7 @@ namespace GodotTools.Build label: "Copy Error".TTR(), (int)IssuesContextMenuOption.Copy); } - if (_issuesListContextMenu.GetItemCount() > 0) + if (_issuesListContextMenu.ItemCount > 0) { _issuesListContextMenu.Position = (Vector2i)(_issuesList.RectGlobalPosition + atPosition); _issuesListContextMenu.Popup(); diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index e03c5fd248..1b4ab0ef4b 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -365,8 +365,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append(link_target); xml_output.append("</c>"); } else if (link_tag == "enum") { - StringName search_cname = !target_itype ? target_cname : - StringName(target_itype->name + "." + (String)target_cname); + StringName search_cname = !target_itype ? target_cname : StringName(target_itype->name + "." + (String)target_cname); const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(search_cname); @@ -1524,7 +1523,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte if (getter->return_type.cname != setter_first_arg.type.cname) { // Special case for Node::set_name bool whitelisted = getter->return_type.cname == name_cache.type_StringName && - setter_first_arg.type.cname == name_cache.type_String; + setter_first_arg.type.cname == name_cache.type_String; ERR_FAIL_COND_V_MSG(!whitelisted, ERR_BUG, "Return type from getter doesn't match first argument of setter for property: '" + @@ -2481,29 +2480,29 @@ bool BindingsGenerator::_arg_default_value_is_assignable_to_type(const Variant & switch (p_val.get_type()) { case Variant::NIL: return p_arg_type.is_object_type || - name_cache.is_nullable_type(p_arg_type.name); + name_cache.is_nullable_type(p_arg_type.name); case Variant::BOOL: return p_arg_type.name == name_cache.type_bool; case Variant::INT: return p_arg_type.name == name_cache.type_sbyte || - p_arg_type.name == name_cache.type_short || - p_arg_type.name == name_cache.type_int || - p_arg_type.name == name_cache.type_byte || - p_arg_type.name == name_cache.type_ushort || - p_arg_type.name == name_cache.type_uint || - p_arg_type.name == name_cache.type_long || - p_arg_type.name == name_cache.type_ulong || - p_arg_type.name == name_cache.type_float || - p_arg_type.name == name_cache.type_double || - p_arg_type.is_enum; + p_arg_type.name == name_cache.type_short || + p_arg_type.name == name_cache.type_int || + p_arg_type.name == name_cache.type_byte || + p_arg_type.name == name_cache.type_ushort || + p_arg_type.name == name_cache.type_uint || + p_arg_type.name == name_cache.type_long || + p_arg_type.name == name_cache.type_ulong || + p_arg_type.name == name_cache.type_float || + p_arg_type.name == name_cache.type_double || + p_arg_type.is_enum; case Variant::FLOAT: return p_arg_type.name == name_cache.type_float || - p_arg_type.name == name_cache.type_double; + p_arg_type.name == name_cache.type_double; case Variant::STRING: case Variant::STRING_NAME: return p_arg_type.name == name_cache.type_String || - p_arg_type.name == name_cache.type_StringName || - p_arg_type.name == name_cache.type_NodePath; + p_arg_type.name == name_cache.type_StringName || + p_arg_type.name == name_cache.type_NodePath; case Variant::NODE_PATH: return p_arg_type.name == name_cache.type_NodePath; case Variant::TRANSFORM2D: @@ -2535,13 +2534,13 @@ bool BindingsGenerator::_arg_default_value_is_assignable_to_type(const Variant & return p_arg_type.is_object_type; case Variant::VECTOR2I: return p_arg_type.name == name_cache.type_Vector2 || - p_arg_type.name == Variant::get_type_name(p_val.get_type()); + p_arg_type.name == Variant::get_type_name(p_val.get_type()); case Variant::RECT2I: return p_arg_type.name == name_cache.type_Rect2 || - p_arg_type.name == Variant::get_type_name(p_val.get_type()); + p_arg_type.name == Variant::get_type_name(p_val.get_type()); case Variant::VECTOR3I: return p_arg_type.name == name_cache.type_Vector3 || - p_arg_type.name == Variant::get_type_name(p_val.get_type()); + p_arg_type.name == Variant::get_type_name(p_val.get_type()); default: CRASH_NOW_MSG("Unexpected Variant type: " + itos(p_val.get_type())); break; @@ -2714,7 +2713,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { if (itype.cname != name_cache.type_Object || imethod.name != "free") { WARN_PRINT("Notification: New unexpected virtual non-overridable method found." " We only expected Object.free, but found '" + - itype.name + "." + imethod.name + "'."); + itype.name + "." + imethod.name + "'."); } } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { imethod.return_type.cname = return_info.class_name; @@ -2723,7 +2722,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { imethod.return_type.cname = return_info.class_name; bool bad_reference_hint = !imethod.is_virtual && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE && - ClassDB::is_parent_class(return_info.class_name, name_cache.type_RefCounted); + ClassDB::is_parent_class(return_info.class_name, name_cache.type_RefCounted); ERR_FAIL_COND_V_MSG(bad_reference_hint, false, String() + "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." + " Are you returning a reference type by pointer? Method: '" + itype.name + "." + imethod.name + "'."); diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 51a27ee934..2e6ce3a952 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -598,7 +598,7 @@ class BindingsGenerator { private: NameCache(const NameCache &); - NameCache &operator=(const NameCache &); + void operator=(const NameCache &); }; NameCache name_cache; diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index 7433c865f5..095fd831a3 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -155,7 +155,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr dir_access->list_dir_begin(); String filename = dir_access->get_next(); - while (filename != "") { + while (!filename.is_empty()) { if (filename == "." || filename == "..") { filename = dir_access->get_next(); continue; diff --git a/modules/mono/editor/code_completion.h b/modules/mono/editor/code_completion.h index 7f7521672b..82b592003b 100644 --- a/modules/mono/editor/code_completion.h +++ b/modules/mono/editor/code_completion.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 9a61b63c12..3c02ea0e8e 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/editor/editor_internal_calls.h b/modules/mono/editor/editor_internal_calls.h index 24080cd867..a899634d57 100644 --- a/modules/mono/editor/editor_internal_calls.h +++ b/modules/mono/editor/editor_internal_calls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp index 54dbaebf38..f9ea403334 100644 --- a/modules/mono/editor/godotsharp_export.cpp +++ b/modules/mono/editor/godotsharp_export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h index 0e9d689618..60620b5f4d 100644 --- a/modules/mono/editor/godotsharp_export.h +++ b/modules/mono/editor/godotsharp_export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs b/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs new file mode 100644 index 0000000000..6e9547ce9b --- /dev/null +++ b/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs @@ -0,0 +1,41 @@ +// meta-description: Classic movement for gravity games (platformer, ...) + +using _BINDINGS_NAMESPACE_; +using System; + +public partial class _CLASS_ : _BASE_ +{ + public const float Speed = 300.0f; + public const float JumpForce = -400.0f; + + // Get the gravity from the project settings to be synced with RigidDynamicBody nodes. + public float gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity"); + + public override void _PhysicsProcess(float delta) + { + Vector2 motionVelocity = MotionVelocity; + + // Add the gravity. + if (!IsOnFloor()) + motionVelocity.y += gravity * delta; + + // Handle Jump. + if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) + motionVelocity.y = JumpForce; + + // Get the input direction and handle the movement/deceleration. + // As good practice, you should replace UI actions with custom gameplay actions. + Vector2 direction = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down"); + if (direction != Vector2.Zero) + { + motionVelocity.x = direction.x * Speed; + } + else + { + motionVelocity.x = Mathf.MoveToward(MotionVelocity.x, 0, Speed); + } + + MotionVelocity = motionVelocity; + MoveAndSlide(); + } +} diff --git a/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs new file mode 100644 index 0000000000..13be4bbcb1 --- /dev/null +++ b/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs @@ -0,0 +1,44 @@ +// meta-description: Classic movement for gravity games (FPS, TPS, ...) + +using _BINDINGS_NAMESPACE_; +using System; + +public partial class _CLASS_ : _BASE_ +{ + public const float Speed = 5.0f; + public const float JumpForce = 4.5f; + + // Get the gravity from the project settings to be synced with RigidDynamicBody nodes. + public float gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity"); + + public override void _PhysicsProcess(float delta) + { + Vector3 motionVelocity = MotionVelocity; + + // Add the gravity. + if (!IsOnFloor()) + motionVelocity.y -= gravity * delta; + + // Handle Jump. + if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) + motionVelocity.y = JumpForce; + + // Get the input direction and handle the movement/deceleration. + // As good practice, you should replace UI actions with custom gameplay actions. + Vector2 inputDir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down"); + Vector3 direction = Transform.basis.Xform(new Vector3(inputDir.x, 0, inputDir.y)).Normalized(); + if (direction != Vector3.Zero) + { + motionVelocity.x = direction.x * Speed; + motionVelocity.z = direction.z * Speed; + } + else + { + motionVelocity.x = Mathf.MoveToward(MotionVelocity.x, 0, Speed); + motionVelocity.z = Mathf.MoveToward(MotionVelocity.z, 0, Speed); + } + + MotionVelocity = motionVelocity; + MoveAndSlide(); + } +} diff --git a/modules/mono/editor_templates/EditorPlugin/plugin.cs b/modules/mono/editor_templates/EditorPlugin/plugin.cs new file mode 100644 index 0000000000..6e6a799be6 --- /dev/null +++ b/modules/mono/editor_templates/EditorPlugin/plugin.cs @@ -0,0 +1,19 @@ +// meta-description: Basic plugin template +#if TOOLS +using _BINDINGS_NAMESPACE_; +using System; + +[Tool] +public partial class _CLASS_ : _BASE_ +{ + public override void _EnterTree() + { + // Initialization of the plugin goes here. + } + + public override void _ExitTree() + { + // Clean-up of the plugin goes here. + } +} +#endif diff --git a/modules/mono/editor_templates/EditorScript/basic_editor_script.cs b/modules/mono/editor_templates/EditorScript/basic_editor_script.cs new file mode 100644 index 0000000000..2088822890 --- /dev/null +++ b/modules/mono/editor_templates/EditorScript/basic_editor_script.cs @@ -0,0 +1,14 @@ +// meta-description: Basic editor script template +#if TOOLS +using _BINDINGS_NAMESPACE_; +using System; + +[Tool] +public partial class _CLASS_ : _BASE_ +{ + public override void _Run() + { + // Called when the script is executed (using File -> Run in Script Editor). + } +} +#endif diff --git a/modules/mono/editor_templates/Node/default.cs b/modules/mono/editor_templates/Node/default.cs new file mode 100644 index 0000000000..73d69dd993 --- /dev/null +++ b/modules/mono/editor_templates/Node/default.cs @@ -0,0 +1,19 @@ +// meta-description: Base template for Node with default Godot cycle methods + +using _BINDINGS_NAMESPACE_; +using System; + +public partial class _CLASS_ : _BASE_ +{ + // Called when the node enters the scene tree for the first time. + public override void _Ready() + { + + } + + // Called every frame. 'delta' is the elapsed time since the previous frame. + public override void _Process(float delta) + { + + } +} diff --git a/modules/mono/editor_templates/Object/empty.cs b/modules/mono/editor_templates/Object/empty.cs new file mode 100644 index 0000000000..e5bee64fe1 --- /dev/null +++ b/modules/mono/editor_templates/Object/empty.cs @@ -0,0 +1,9 @@ +// meta-description: Empty template suitable for all Objects + +using _BINDINGS_NAMESPACE_; +using System; + +public partial class _CLASS_ : _BASE_ +{ + +} diff --git a/modules/mono/editor_templates/SCsub b/modules/mono/editor_templates/SCsub new file mode 100644 index 0000000000..39f6cb5c01 --- /dev/null +++ b/modules/mono/editor_templates/SCsub @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +Import("env") + +import editor.template_builders as build_template_cs + +env["BUILDERS"]["MakeCSharpTemplateBuilder"] = Builder( + action=env.Run(build_template_cs.make_templates, "Generating C# templates header."), + suffix=".h", + src_suffix=".cs", +) + +# Template files +templates_sources = Glob("*/*.cs") + +env.Alias("editor_template_cs", [env.MakeCSharpTemplateBuilder("templates.gen.h", templates_sources)]) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs index 70a2cf5695..850ae7fc3b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs @@ -666,21 +666,40 @@ namespace Godot _size = new Vector3(width, height, depth); } + /// <summary> + /// Returns <see langword="true"/> if the AABBs are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left AABB.</param> + /// <param name="right">The right AABB.</param> + /// <returns>Whether or not the AABBs are exactly equal.</returns> public static bool operator ==(AABB left, AABB right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the AABBs are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left AABB.</param> + /// <param name="right">The right AABB.</param> + /// <returns>Whether or not the AABBs are not equal.</returns> public static bool operator !=(AABB left, AABB right) { return !left.Equals(right); } /// <summary> - /// Returns <see langword="true"/> if this AABB and <paramref name="obj"/> are equal. + /// Returns <see langword="true"/> if the AABB is exactly equal + /// to the given object (<see paramref="obj"/>). + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the AABB structure and the other object are equal.</returns> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the AABB and the object are equal.</returns> public override bool Equals(object obj) { if (obj is AABB) @@ -692,10 +711,12 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this AABB and <paramref name="other"/> are equal + /// Returns <see langword="true"/> if the AABBs are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="other">The other AABB to compare.</param> - /// <returns>Whether or not the AABBs are equal.</returns> + /// <param name="other">The other AABB.</param> + /// <returns>Whether or not the AABBs are exactly equal.</returns> public bool Equals(AABB other) { return _position == other._position && _size == other._size; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index 0fb1df6c2f..656796c5c7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -209,27 +209,6 @@ namespace Godot } } - /// <summary> - /// Returns the <see cref="Basis"/>'s rotation in the form of a - /// <see cref="Quaternion"/>. See <see cref="GetEuler"/> if you - /// need Euler angles, but keep in mind quaternions should generally - /// be preferred to Euler angles. - /// </summary> - /// <returns>The basis rotation.</returns> - public Quaternion GetRotationQuaternion() - { - Basis orthonormalizedBasis = Orthonormalized(); - real_t det = orthonormalizedBasis.Determinant(); - if (det < 0) - { - // Ensure that the determinant is 1, such that result is a proper - // rotation matrix which can be represented by Euler angles. - orthonormalizedBasis = orthonormalizedBasis.Scaled(-Vector3.One); - } - - return orthonormalizedBasis.Quaternion(); - } - internal void SetQuaternionScale(Quaternion quaternion, Vector3 scale) { SetDiagonal(scale); @@ -272,8 +251,8 @@ namespace Godot /// The returned vector contains the rotation angles in /// the format (X angle, Y angle, Z angle). /// - /// Consider using the <see cref="Quaternion()"/> method instead, which - /// returns a <see cref="Godot.Quaternion"/> quaternion instead of Euler angles. + /// Consider using the <see cref="GetRotationQuaternion"/> method instead, which + /// returns a <see cref="Quaternion"/> quaternion instead of Euler angles. /// </summary> /// <returns>A <see cref="Vector3"/> representing the basis rotation in Euler angles.</returns> public Vector3 GetEuler() @@ -309,6 +288,85 @@ namespace Godot } /// <summary> + /// Returns the basis's rotation in the form of a quaternion. + /// See <see cref="GetEuler()"/> if you need Euler angles, but keep in + /// mind that quaternions should generally be preferred to Euler angles. + /// </summary> + /// <returns>A <see cref="Quaternion"/> representing the basis's rotation.</returns> + internal Quaternion GetQuaternion() + { + real_t trace = Row0[0] + Row1[1] + Row2[2]; + + if (trace > 0.0f) + { + real_t s = Mathf.Sqrt(trace + 1.0f) * 2f; + real_t inv_s = 1f / s; + return new Quaternion( + (Row2[1] - Row1[2]) * inv_s, + (Row0[2] - Row2[0]) * inv_s, + (Row1[0] - Row0[1]) * inv_s, + s * 0.25f + ); + } + + if (Row0[0] > Row1[1] && Row0[0] > Row2[2]) + { + real_t s = Mathf.Sqrt(Row0[0] - Row1[1] - Row2[2] + 1.0f) * 2f; + real_t inv_s = 1f / s; + return new Quaternion( + s * 0.25f, + (Row0[1] + Row1[0]) * inv_s, + (Row0[2] + Row2[0]) * inv_s, + (Row2[1] - Row1[2]) * inv_s + ); + } + + if (Row1[1] > Row2[2]) + { + real_t s = Mathf.Sqrt(-Row0[0] + Row1[1] - Row2[2] + 1.0f) * 2f; + real_t inv_s = 1f / s; + return new Quaternion( + (Row0[1] + Row1[0]) * inv_s, + s * 0.25f, + (Row1[2] + Row2[1]) * inv_s, + (Row0[2] - Row2[0]) * inv_s + ); + } + else + { + real_t s = Mathf.Sqrt(-Row0[0] - Row1[1] + Row2[2] + 1.0f) * 2f; + real_t inv_s = 1f / s; + return new Quaternion( + (Row0[2] + Row2[0]) * inv_s, + (Row1[2] + Row2[1]) * inv_s, + s * 0.25f, + (Row1[0] - Row0[1]) * inv_s + ); + } + } + + /// <summary> + /// Returns the <see cref="Basis"/>'s rotation in the form of a + /// <see cref="Quaternion"/>. See <see cref="GetEuler"/> if you + /// need Euler angles, but keep in mind quaternions should generally + /// be preferred to Euler angles. + /// </summary> + /// <returns>The basis rotation.</returns> + public Quaternion GetRotationQuaternion() + { + Basis orthonormalizedBasis = Orthonormalized(); + real_t det = orthonormalizedBasis.Determinant(); + if (det < 0) + { + // Ensure that the determinant is 1, such that result is a proper + // rotation matrix which can be represented by Euler angles. + orthonormalizedBasis = orthonormalizedBasis.Scaled(-Vector3.One); + } + + return orthonormalizedBasis.GetQuaternion(); + } + + /// <summary> /// Get rows by index. Rows are not very useful for user code, /// but are more efficient for some internal calculations. /// </summary> @@ -600,64 +658,6 @@ namespace Godot ); } - /// <summary> - /// Returns the basis's rotation in the form of a quaternion. - /// See <see cref="GetEuler()"/> if you need Euler angles, but keep in - /// mind that quaternions should generally be preferred to Euler angles. - /// </summary> - /// <returns>A <see cref="Godot.Quaternion"/> representing the basis's rotation.</returns> - public Quaternion Quaternion() - { - real_t trace = Row0[0] + Row1[1] + Row2[2]; - - if (trace > 0.0f) - { - real_t s = Mathf.Sqrt(trace + 1.0f) * 2f; - real_t inv_s = 1f / s; - return new Quaternion( - (Row2[1] - Row1[2]) * inv_s, - (Row0[2] - Row2[0]) * inv_s, - (Row1[0] - Row0[1]) * inv_s, - s * 0.25f - ); - } - - if (Row0[0] > Row1[1] && Row0[0] > Row2[2]) - { - real_t s = Mathf.Sqrt(Row0[0] - Row1[1] - Row2[2] + 1.0f) * 2f; - real_t inv_s = 1f / s; - return new Quaternion( - s * 0.25f, - (Row0[1] + Row1[0]) * inv_s, - (Row0[2] + Row2[0]) * inv_s, - (Row2[1] - Row1[2]) * inv_s - ); - } - - if (Row1[1] > Row2[2]) - { - real_t s = Mathf.Sqrt(-Row0[0] + Row1[1] - Row2[2] + 1.0f) * 2f; - real_t inv_s = 1f / s; - return new Quaternion( - (Row0[1] + Row1[0]) * inv_s, - s * 0.25f, - (Row1[2] + Row2[1]) * inv_s, - (Row0[2] - Row2[0]) * inv_s - ); - } - else - { - real_t s = Mathf.Sqrt(-Row0[0] - Row1[1] + Row2[2] + 1.0f) * 2f; - real_t inv_s = 1f / s; - return new Quaternion( - (Row0[2] + Row2[0]) * inv_s, - (Row1[2] + Row2[1]) * inv_s, - s * 0.25f, - (Row1[0] - Row0[1]) * inv_s - ); - } - } - private static readonly Basis[] _orthoBases = { new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f), new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f), @@ -745,7 +745,7 @@ namespace Godot /// given in the vector format as (X angle, Y angle, Z angle). /// /// Consider using the <see cref="Basis(Quaternion)"/> constructor instead, which - /// uses a <see cref="Godot.Quaternion"/> quaternion instead of Euler angles. + /// uses a <see cref="Quaternion"/> quaternion instead of Euler angles. /// </summary> /// <param name="eulerYXZ">The Euler angles to create the basis from.</param> public Basis(Vector3 eulerYXZ) @@ -827,6 +827,14 @@ namespace Godot Row2 = new Vector3(xz, yz, zz); } + /// <summary> + /// Composes these two basis matrices by multiplying them + /// together. This has the effect of transforming the second basis + /// (the child) by the first basis (the parent). + /// </summary> + /// <param name="left">The parent basis.</param> + /// <param name="right">The child basis.</param> + /// <returns>The composed basis.</returns> public static Basis operator *(Basis left, Basis right) { return new Basis @@ -837,21 +845,40 @@ namespace Godot ); } + /// <summary> + /// Returns <see langword="true"/> if the basis matrices are exactly + /// equal. Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left basis.</param> + /// <param name="right">The right basis.</param> + /// <returns>Whether or not the basis matrices are exactly equal.</returns> public static bool operator ==(Basis left, Basis right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the basis matrices are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left basis.</param> + /// <param name="right">The right basis.</param> + /// <returns>Whether or not the basis matrices are not equal.</returns> public static bool operator !=(Basis left, Basis right) { return !left.Equals(right); } /// <summary> - /// Returns <see langword="true"/> if this basis and <paramref name="obj"/> are equal. + /// Returns <see langword="true"/> if the <see cref="Basis"/> is + /// exactly equal to the given object (<see paramref="obj"/>). + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the basis and the other object are equal.</returns> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the basis matrix and the object are exactly equal.</returns> public override bool Equals(object obj) { if (obj is Basis) @@ -863,10 +890,12 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this basis and <paramref name="other"/> are equal + /// Returns <see langword="true"/> if the basis matrices are exactly + /// equal. Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="other">The other basis to compare.</param> - /// <returns>Whether or not the bases are equal.</returns> + /// <param name="other">The other basis.</param> + /// <returns>Whether or not the basis matrices are exactly equal.</returns> public bool Equals(Basis other) { return Row0.Equals(other.Row0) && Row1.Equals(other.Row1) && Row2.Equals(other.Row2); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs index a28a46896b..2722b64e6d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; namespace Godot { @@ -71,5 +72,32 @@ namespace Godot _method = null; _delegate = @delegate; } + + /// <summary> + /// Calls the method represented by this <see cref="Callable"/>. + /// Arguments can be passed and should match the method's signature. + /// </summary> + /// <param name="args">Arguments that will be passed to the method call.</param> + /// <returns>The value returned by the method.</returns> + public object Call(params object[] args) + { + return godot_icall_Callable_Call(ref this, args); + } + + /// <summary> + /// Calls the method represented by this <see cref="Callable"/> in deferred mode, i.e. during the idle frame. + /// Arguments can be passed and should match the method's signature. + /// </summary> + /// <param name="args">Arguments that will be passed to the method call.</param> + public void CallDeferred(params object[] args) + { + godot_icall_Callable_CallDeferred(ref this, args); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern object godot_icall_Callable_Call(ref Callable callable, object[] args); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void godot_icall_Callable_CallDeferred(ref Callable callable, object[] args); } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 2a869bc335..fc9d40ca48 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -878,6 +878,13 @@ namespace Godot return true; } + /// <summary> + /// Adds each component of the <see cref="Color"/> + /// with the components of the given <see cref="Color"/>. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>The added color.</returns> public static Color operator +(Color left, Color right) { left.r += right.r; @@ -887,6 +894,13 @@ namespace Godot return left; } + /// <summary> + /// Subtracts each component of the <see cref="Color"/> + /// by the components of the given <see cref="Color"/>. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>The subtracted color.</returns> public static Color operator -(Color left, Color right) { left.r -= right.r; @@ -896,11 +910,25 @@ namespace Godot return left; } + /// <summary> + /// Inverts the given color. This is equivalent to + /// <c>Colors.White - c</c> or + /// <c>new Color(1 - c.r, 1 - c.g, 1 - c.b, 1 - c.a)</c>. + /// </summary> + /// <param name="color">The color to invert.</param> + /// <returns>The inverted color</returns> public static Color operator -(Color color) { return Colors.White - color; } + /// <summary> + /// Multiplies each component of the <see cref="Color"/> + /// by the given <see langword="float"/>. + /// </summary> + /// <param name="color">The color to multiply.</param> + /// <param name="scale">The value to multiply by.</param> + /// <returns>The multiplied color.</returns> public static Color operator *(Color color, float scale) { color.r *= scale; @@ -910,6 +938,13 @@ namespace Godot return color; } + /// <summary> + /// Multiplies each component of the <see cref="Color"/> + /// by the given <see langword="float"/>. + /// </summary> + /// <param name="scale">The value to multiply by.</param> + /// <param name="color">The color to multiply.</param> + /// <returns>The multiplied color.</returns> public static Color operator *(float scale, Color color) { color.r *= scale; @@ -919,6 +954,13 @@ namespace Godot return color; } + /// <summary> + /// Multiplies each component of the <see cref="Color"/> + /// by the components of the given <see cref="Color"/>. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>The multiplied color.</returns> public static Color operator *(Color left, Color right) { left.r *= right.r; @@ -928,6 +970,13 @@ namespace Godot return left; } + /// <summary> + /// Divides each component of the <see cref="Color"/> + /// by the given <see langword="float"/>. + /// </summary> + /// <param name="color">The dividend vector.</param> + /// <param name="scale">The divisor value.</param> + /// <returns>The divided color.</returns> public static Color operator /(Color color, float scale) { color.r /= scale; @@ -937,6 +986,13 @@ namespace Godot return color; } + /// <summary> + /// Divides each component of the <see cref="Color"/> + /// by the components of the given <see cref="Color"/>. + /// </summary> + /// <param name="left">The dividend color.</param> + /// <param name="right">The divisor color.</param> + /// <returns>The divided color.</returns> public static Color operator /(Color left, Color right) { left.r /= right.r; @@ -946,23 +1002,51 @@ namespace Godot return left; } + /// <summary> + /// Returns <see langword="true"/> if the colors are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>Whether or not the colors are equal.</returns> public static bool operator ==(Color left, Color right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the colors are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>Whether or not the colors are equal.</returns> public static bool operator !=(Color left, Color right) { return !left.Equals(right); } + /// <summary> + /// Compares two <see cref="Color"/>s by first checking if + /// the red value of the <paramref name="left"/> color is less than + /// the red value of the <paramref name="right"/> color. + /// If the red values are exactly equal, then it repeats this check + /// with the green values of the two colors, then with the blue values, + /// and then with the alpha value. + /// This operator is useful for sorting colors. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Color left, Color right) { - if (Mathf.IsEqualApprox(left.r, right.r)) + if (left.r == right.r) { - if (Mathf.IsEqualApprox(left.g, right.g)) + if (left.g == right.g) { - if (Mathf.IsEqualApprox(left.b, right.b)) + if (left.b == right.b) { return left.a < right.a; } @@ -973,13 +1057,25 @@ namespace Godot return left.r < right.r; } + /// <summary> + /// Compares two <see cref="Color"/>s by first checking if + /// the red value of the <paramref name="left"/> color is greater than + /// the red value of the <paramref name="right"/> color. + /// If the red values are exactly equal, then it repeats this check + /// with the green values of the two colors, then with the blue values, + /// and then with the alpha value. + /// This operator is useful for sorting colors. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Color left, Color right) { - if (Mathf.IsEqualApprox(left.r, right.r)) + if (left.r == right.r) { - if (Mathf.IsEqualApprox(left.g, right.g)) + if (left.g == right.g) { - if (Mathf.IsEqualApprox(left.b, right.b)) + if (left.b == right.b) { return left.a > right.a; } @@ -991,6 +1087,64 @@ namespace Godot } /// <summary> + /// Compares two <see cref="Color"/>s by first checking if + /// the red value of the <paramref name="left"/> color is less than + /// or equal to the red value of the <paramref name="right"/> color. + /// If the red values are exactly equal, then it repeats this check + /// with the green values of the two colors, then with the blue values, + /// and then with the alpha value. + /// This operator is useful for sorting colors. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>Whether or not the left is less than or equal to the right.</returns> + public static bool operator <=(Color left, Color right) + { + if (left.r == right.r) + { + if (left.g == right.g) + { + if (left.b == right.b) + { + return left.a <= right.a; + } + return left.b < right.b; + } + return left.g < right.g; + } + return left.r < right.r; + } + + /// <summary> + /// Compares two <see cref="Color"/>s by first checking if + /// the red value of the <paramref name="left"/> color is greater than + /// or equal to the red value of the <paramref name="right"/> color. + /// If the red values are exactly equal, then it repeats this check + /// with the green values of the two colors, then with the blue values, + /// and then with the alpha value. + /// This operator is useful for sorting colors. + /// </summary> + /// <param name="left">The left color.</param> + /// <param name="right">The right color.</param> + /// <returns>Whether or not the left is greater than or equal to the right.</returns> + public static bool operator >=(Color left, Color right) + { + if (left.r == right.r) + { + if (left.g == right.g) + { + if (left.b == right.b) + { + return left.a >= right.a; + } + return left.b > right.b; + } + return left.g > right.g; + } + return left.r > right.r; + } + + /// <summary> /// Returns <see langword="true"/> if this color and <paramref name="obj"/> are equal. /// </summary> /// <param name="obj">The other object to compare.</param> @@ -1006,9 +1160,11 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this color and <paramref name="other"/> are equal + /// Returns <see langword="true"/> if the colors are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="other">The other color to compare.</param> + /// <param name="other">The other color.</param> /// <returns>Whether or not the colors are equal.</returns> public bool Equals(Color other) { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs index d64c8b563e..68c821b447 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs @@ -158,6 +158,7 @@ namespace Godot {"YELLOWGREEN", new Color(0.60f, 0.80f, 0.20f)}, }; +#pragma warning disable CS1591 // Disable warning: "Missing XML comment for publicly visible type or member" public static Color AliceBlue { get { return namedColors["ALICEBLUE"]; } } public static Color AntiqueWhite { get { return namedColors["ANTIQUEWHITE"]; } } public static Color Aqua { get { return namedColors["AQUA"]; } } @@ -304,5 +305,6 @@ namespace Godot public static Color WhiteSmoke { get { return namedColors["WHITESMOKE"]; } } public static Color Yellow { get { return namedColors["YELLOW"]; } } public static Color YellowGreen { get { return namedColors["YELLOWGREEN"]; } } +#pragma warning restore CS1591 } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs index 2dfe304aaa..75240b0c09 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs @@ -314,13 +314,13 @@ namespace Godot.Collections internal static extern int godot_icall_Dictionary_Count(IntPtr ptr); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static int godot_icall_Dictionary_KeyValuePairs(IntPtr ptr, out IntPtr keys, out IntPtr values); + internal static extern int godot_icall_Dictionary_KeyValuePairs(IntPtr ptr, out IntPtr keys, out IntPtr values); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static void godot_icall_Dictionary_KeyValuePairAt(IntPtr ptr, int index, out object key, out object value); + internal static extern void godot_icall_Dictionary_KeyValuePairAt(IntPtr ptr, int index, out object key, out object value); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static void godot_icall_Dictionary_Add(IntPtr ptr, object key, object value); + internal static extern void godot_icall_Dictionary_Add(IntPtr ptr, object key, object value); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void godot_icall_Dictionary_Clear(IntPtr ptr); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs index ef42374041..74aa38386f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -127,7 +127,7 @@ namespace Godot /// </code> /// </example> /// <param name="linear">The linear energy to convert.</param> - /// <returns>Audio as decibels</returns> + /// <returns>Audio as decibels.</returns> public static real_t Linear2Db(real_t linear) { return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321); @@ -323,6 +323,16 @@ namespace Godot } /// <summary> + /// Returns a normally-distributed pseudo-random number, using Box-Muller transform with the specified <c>mean</c> and a standard <c>deviation</c>. + /// This is also called Gaussian distribution. + /// </summary> + /// <returns>A random normally-distributed <see langword="float"/> number.</returns> + public static double Randfn(double mean, double deviation) + { + return godot_icall_GD_randfn(mean, deviation); + } + + /// <summary> /// Returns a random unsigned 32-bit integer. /// Use remainder to obtain a random value in the interval <c>[0, N - 1]</c> (where N is smaller than 2^32). /// </summary> @@ -390,7 +400,7 @@ namespace Godot /// </summary> /// <param name="seed"> /// Seed to use to generate the random number. - /// If a different seed is used, its value will be modfied. + /// If a different seed is used, its value will be modified. /// </param> /// <returns>A random <see langword="uint"/> number.</returns> public static uint RandFromSeed(ref ulong seed) @@ -564,19 +574,22 @@ namespace Godot internal static extern void godot_icall_GD_printt(object[] what); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern float godot_icall_GD_randf(); + internal static extern void godot_icall_GD_randomize(); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern uint godot_icall_GD_randi(); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void godot_icall_GD_randomize(); + internal static extern float godot_icall_GD_randf(); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern int godot_icall_GD_randi_range(int from, int to); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern double godot_icall_GD_randf_range(double from, double to); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern int godot_icall_GD_randi_range(int from, int to); + internal static extern double godot_icall_GD_randfn(double mean, double deviation); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern uint godot_icall_GD_rand_seed(ulong seed, out ulong newSeed); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs index 3051bcedc7..ee4d0eed08 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs @@ -80,6 +80,18 @@ namespace Godot private static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>); /// <summary> + /// Returns the generic type definition of <paramref name="type"/>. + /// </summary> + /// <exception cref="InvalidOperationException"> + /// Thrown when the given <paramref name="type"/> is not a generic type. + /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>. + /// </exception> + private static void GetGenericTypeDefinition(Type type, out Type genericTypeDefinition) + { + genericTypeDefinition = type.GetGenericTypeDefinition(); + } + + /// <summary> /// Gets the element type for the given <paramref name="arrayType"/>. /// </summary> /// <param name="arrayType">Type for the generic array.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index 6f7fac7429..bfe9600084 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -624,7 +624,7 @@ namespace Godot /// </summary> /// <param name="s">The value to snap.</param> /// <param name="step">The step size to snap to.</param> - /// <returns></returns> + /// <returns>The snapped value.</returns> public static real_t Snapped(real_t s, real_t step) { if (step != 0f) @@ -693,5 +693,23 @@ namespace Godot } return min + ((((value - min) % range) + range) % range); } + + private static real_t Fract(real_t value) + { + return value - (real_t)Math.Floor(value); + } + + /// <summary> + /// Returns the [code]value[/code] wrapped between [code]0[/code] and the [code]length[/code]. + /// If the limit is reached, the next value the function returned is decreased to the [code]0[/code] side or increased to the [code]length[/code] side (like a triangle wave). + /// If [code]length[/code] is less than zero, it becomes positive. + /// </summary> + /// <param name="value">The value to pingpong.</param> + /// <param name="length">The maximum value of the function.</param> + /// <returns>The ping-ponged value.</returns> + public static real_t PingPong(real_t value, real_t length) + { + return (length != (real_t)0.0) ? Abs(Fract((value - length) / (length * (real_t)2.0)) * length * (real_t)2.0 - length) : (real_t)0.0; + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs index 9bb73ce7dd..f15d01b34b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs @@ -44,7 +44,7 @@ namespace Godot /// <summary> /// Returns the amount of digits after the decimal place. /// </summary> - /// <param name="s">The input <see cref="decimal"/> value.</param> + /// <param name="s">The input <see langword="decimal"/> value.</param> /// <returns>The amount of digits.</returns> public static int DecimalCount(decimal s) { @@ -54,7 +54,7 @@ namespace Godot /// <summary> /// Rounds <paramref name="s"/> upward (towards positive infinity). /// - /// This is the same as <see cref="Ceil(real_t)"/>, but returns an <c>int</c>. + /// This is the same as <see cref="Ceil(real_t)"/>, but returns an <see langword="int"/>. /// </summary> /// <param name="s">The number to ceil.</param> /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns> @@ -66,7 +66,7 @@ namespace Godot /// <summary> /// Rounds <paramref name="s"/> downward (towards negative infinity). /// - /// This is the same as <see cref="Floor(real_t)"/>, but returns an <c>int</c>. + /// This is the same as <see cref="Floor(real_t)"/>, but returns an <see langword="int"/>. /// </summary> /// <param name="s">The number to floor.</param> /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns> @@ -78,7 +78,7 @@ namespace Godot /// <summary> /// Rounds <paramref name="s"/> to the nearest whole number. /// - /// This is the same as <see cref="Round(real_t)"/>, but returns an <c>int</c>. + /// This is the same as <see cref="Round(real_t)"/>, but returns an <see langword="int"/>. /// </summary> /// <param name="s">The number to round.</param> /// <returns>The rounded number.</returns> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs index f53b5dc904..40fb5f8788 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs @@ -122,7 +122,7 @@ namespace Godot /// "/root/Level/Path2D" /// </code> /// </example> - /// <param name="path"></param> + /// <param name="path">A string that represents a path in a scene tree.</param> public NodePath(string path) { ptr = godot_icall_NodePath_Ctor(path); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs index 66f7b745f7..63af1c5892 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs @@ -309,16 +309,43 @@ namespace Godot D = _normal.Dot(v1); } + /// <summary> + /// Returns the negative value of the <see cref="Plane"/>. + /// This is the same as writing <c>new Plane(-p.Normal, -p.D)</c>. + /// This operation flips the direction of the normal vector and + /// also flips the distance value, resulting in a Plane that is + /// in the same place, but facing the opposite direction. + /// </summary> + /// <param name="plane">The plane to negate/flip.</param> + /// <returns>The negated/flipped plane.</returns> public static Plane operator -(Plane plane) { return new Plane(-plane._normal, -plane.D); } + /// <summary> + /// Returns <see langword="true"/> if the + /// <see cref="Plane"/>s are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left rect.</param> + /// <param name="right">The right rect.</param> + /// <returns>Whether or not the planes are exactly equal.</returns> public static bool operator ==(Plane left, Plane right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the + /// <see cref="Plane"/>s are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left rect.</param> + /// <param name="right">The right rect.</param> + /// <returns>Whether or not the planes are not equal.</returns> public static bool operator !=(Plane left, Plane right) { return !left.Equals(right); @@ -328,7 +355,7 @@ namespace Godot /// Returns <see langword="true"/> if this plane and <paramref name="obj"/> are equal. /// </summary> /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the plane and the other object are equal.</returns> + /// <returns>Whether or not the plane and the other object are exactly equal.</returns> public override bool Equals(object obj) { if (obj is Plane) @@ -343,7 +370,7 @@ namespace Godot /// Returns <see langword="true"/> if this plane and <paramref name="other"/> are equal. /// </summary> /// <param name="other">The other plane to compare.</param> - /// <returns>Whether or not the planes are equal.</returns> + /// <returns>Whether or not the planes are exactly equal.</returns> public bool Equals(Plane other) { return _normal == other._normal && D == other.D; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs index 1694ac0320..e38dca414f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -377,7 +377,7 @@ namespace Godot /// <param name="basis">The <see cref="Basis"/> to construct from.</param> public Quaternion(Basis basis) { - this = basis.Quaternion(); + this = basis.GetQuaternion(); } /// <summary> @@ -446,6 +446,14 @@ namespace Godot } } + /// <summary> + /// Composes these two quaternions by multiplying them together. + /// This has the effect of rotating the second quaternion + /// (the child) by the first quaternion (the parent). + /// </summary> + /// <param name="left">The parent quaternion.</param> + /// <param name="right">The child quaternion.</param> + /// <returns>The composed quaternion.</returns> public static Quaternion operator *(Quaternion left, Quaternion right) { return new Quaternion @@ -457,63 +465,143 @@ namespace Godot ); } + /// <summary> + /// Adds each component of the left <see cref="Quaternion"/> + /// to the right <see cref="Quaternion"/>. This operation is not + /// meaningful on its own, but it can be used as a part of a + /// larger expression, such as approximating an intermediate + /// rotation between two nearby rotations. + /// </summary> + /// <param name="left">The left quaternion to add.</param> + /// <param name="right">The right quaternion to add.</param> + /// <returns>The added quaternion.</returns> public static Quaternion operator +(Quaternion left, Quaternion right) { return new Quaternion(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); } + /// <summary> + /// Subtracts each component of the left <see cref="Quaternion"/> + /// by the right <see cref="Quaternion"/>. This operation is not + /// meaningful on its own, but it can be used as a part of a + /// larger expression. + /// </summary> + /// <param name="left">The left quaternion to subtract.</param> + /// <param name="right">The right quaternion to subtract.</param> + /// <returns>The subtracted quaternion.</returns> public static Quaternion operator -(Quaternion left, Quaternion right) { return new Quaternion(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); } - public static Quaternion operator -(Quaternion left) + /// <summary> + /// Returns the negative value of the <see cref="Quaternion"/>. + /// This is the same as writing + /// <c>new Quaternion(-q.x, -q.y, -q.z, -q.w)</c>. This operation + /// results in a quaternion that represents the same rotation. + /// </summary> + /// <param name="quat">The quaternion to negate.</param> + /// <returns>The negated quaternion.</returns> + public static Quaternion operator -(Quaternion quat) { - return new Quaternion(-left.x, -left.y, -left.z, -left.w); + return new Quaternion(-quat.x, -quat.y, -quat.z, -quat.w); } - public static Quaternion operator *(Quaternion left, Vector3 right) + /// <summary> + /// Rotates (multiplies) the <see cref="Vector3"/> + /// by the given <see cref="Quaternion"/>. + /// </summary> + /// <param name="quat">The quaternion to rotate by.</param> + /// <param name="vec">The vector to rotate.</param> + /// <returns>The rotated vector.</returns> + public static Vector3 operator *(Quaternion quat, Vector3 vec) { - return new Quaternion - ( - (left.w * right.x) + (left.y * right.z) - (left.z * right.y), - (left.w * right.y) + (left.z * right.x) - (left.x * right.z), - (left.w * right.z) + (left.x * right.y) - (left.y * right.x), - -(left.x * right.x) - (left.y * right.y) - (left.z * right.z) - ); +#if DEBUG + if (!quat.IsNormalized()) + { + throw new InvalidOperationException("Quaternion is not normalized."); + } +#endif + var u = new Vector3(quat.x, quat.y, quat.z); + Vector3 uv = u.Cross(vec); + return vec + (((uv * quat.w) + u.Cross(uv)) * 2); } - public static Quaternion operator *(Vector3 left, Quaternion right) + /// <summary> + /// Inversely rotates (multiplies) the <see cref="Vector3"/> + /// by the given <see cref="Quaternion"/>. + /// </summary> + /// <param name="vec">The vector to rotate.</param> + /// <param name="quat">The quaternion to rotate by.</param> + /// <returns>The inversely rotated vector.</returns> + public static Vector3 operator *(Vector3 vec, Quaternion quat) { - return new Quaternion - ( - (right.w * left.x) + (right.y * left.z) - (right.z * left.y), - (right.w * left.y) + (right.z * left.x) - (right.x * left.z), - (right.w * left.z) + (right.x * left.y) - (right.y * left.x), - -(right.x * left.x) - (right.y * left.y) - (right.z * left.z) - ); + return quat.Inverse() * vec; } + /// <summary> + /// Multiplies each component of the <see cref="Quaternion"/> + /// by the given <see cref="real_t"/>. This operation is not + /// meaningful on its own, but it can be used as a part of a + /// larger expression. + /// </summary> + /// <param name="left">The quaternion to multiply.</param> + /// <param name="right">The value to multiply by.</param> + /// <returns>The multiplied quaternion.</returns> public static Quaternion operator *(Quaternion left, real_t right) { return new Quaternion(left.x * right, left.y * right, left.z * right, left.w * right); } + /// <summary> + /// Multiplies each component of the <see cref="Quaternion"/> + /// by the given <see cref="real_t"/>. This operation is not + /// meaningful on its own, but it can be used as a part of a + /// larger expression. + /// </summary> + /// <param name="left">The value to multiply by.</param> + /// <param name="right">The quaternion to multiply.</param> + /// <returns>The multiplied quaternion.</returns> public static Quaternion operator *(real_t left, Quaternion right) { return new Quaternion(right.x * left, right.y * left, right.z * left, right.w * left); } + /// <summary> + /// Divides each component of the <see cref="Quaternion"/> + /// by the given <see cref="real_t"/>. This operation is not + /// meaningful on its own, but it can be used as a part of a + /// larger expression. + /// </summary> + /// <param name="left">The quaternion to divide.</param> + /// <param name="right">The value to divide by.</param> + /// <returns>The divided quaternion.</returns> public static Quaternion operator /(Quaternion left, real_t right) { return left * (1.0f / right); } + /// <summary> + /// Returns <see langword="true"/> if the quaternions are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left quaternion.</param> + /// <param name="right">The right quaternion.</param> + /// <returns>Whether or not the quaternions are exactly equal.</returns> public static bool operator ==(Quaternion left, Quaternion right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the quaternions are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left quaternion.</param> + /// <param name="right">The right quaternion.</param> + /// <returns>Whether or not the quaternions are not equal.</returns> public static bool operator !=(Quaternion left, Quaternion right) { return !left.Equals(right); @@ -523,7 +611,7 @@ namespace Godot /// Returns <see langword="true"/> if this quaternion and <paramref name="obj"/> are equal. /// </summary> /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the quaternion and the other object are equal.</returns> + /// <returns>Whether or not the quaternion and the other object are exactly equal.</returns> public override bool Equals(object obj) { if (obj is Quaternion) @@ -538,7 +626,7 @@ namespace Godot /// Returns <see langword="true"/> if this quaternion and <paramref name="other"/> are equal. /// </summary> /// <param name="other">The other quaternion to compare.</param> - /// <returns>Whether or not the quaternions are equal.</returns> + /// <returns>Whether or not the quaternions are exactly equal.</returns> public bool Equals(Quaternion other) { return x == other.x && y == other.y && z == other.z && w == other.w; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs index af94484577..ec16920fed 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs @@ -396,11 +396,29 @@ namespace Godot _size = new Vector2(width, height); } + /// <summary> + /// Returns <see langword="true"/> if the + /// <see cref="Rect2"/>s are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left rect.</param> + /// <param name="right">The right rect.</param> + /// <returns>Whether or not the rects are exactly equal.</returns> public static bool operator ==(Rect2 left, Rect2 right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the + /// <see cref="Rect2"/>s are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left rect.</param> + /// <param name="right">The right rect.</param> + /// <returns>Whether or not the rects are not equal.</returns> public static bool operator !=(Rect2 left, Rect2 right) { return !left.Equals(right); @@ -410,7 +428,7 @@ namespace Godot /// Returns <see langword="true"/> if this rect and <paramref name="obj"/> are equal. /// </summary> /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the rect and the other object are equal.</returns> + /// <returns>Whether or not the rect and the other object are exactly equal.</returns> public override bool Equals(object obj) { if (obj is Rect2) @@ -425,7 +443,7 @@ namespace Godot /// Returns <see langword="true"/> if this rect and <paramref name="other"/> are equal. /// </summary> /// <param name="other">The other rect to compare.</param> - /// <returns>Whether or not the rects are equal.</returns> + /// <returns>Whether or not the rects are exactly equal.</returns> public bool Equals(Rect2 other) { return _position.Equals(other._position) && _size.Equals(other._size); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs index 03f406a910..5d53b8330e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs @@ -377,11 +377,25 @@ namespace Godot _size = new Vector2i(width, height); } + /// <summary> + /// Returns <see langword="true"/> if the + /// <see cref="Rect2i"/>s are exactly equal. + /// </summary> + /// <param name="left">The left rect.</param> + /// <param name="right">The right rect.</param> + /// <returns>Whether or not the rects are equal.</returns> public static bool operator ==(Rect2i left, Rect2i right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the + /// <see cref="Rect2i"/>s are not equal. + /// </summary> + /// <param name="left">The left rect.</param> + /// <param name="right">The right rect.</param> + /// <returns>Whether or not the rects are not equal.</returns> public static bool operator !=(Rect2i left, Rect2i right) { return !left.Equals(right); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index 6b3eb09581..a89dca6c34 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -415,6 +415,10 @@ namespace Godot /// <summary> /// Find the first occurrence of a substring. Optionally, the search starting position can be passed. /// </summary> + /// <seealso cref="Find(string, char, int, bool)"/> + /// <seealso cref="FindLast(string, string, bool)"/> + /// <seealso cref="FindLast(string, string, int, bool)"/> + /// <seealso cref="FindN(string, string, int)"/> /// <param name="instance">The string that will be searched.</param> /// <param name="what">The substring to find.</param> /// <param name="from">The search starting position.</param> @@ -690,7 +694,7 @@ namespace Godot /// <summary> /// Returns <see langword="true"/> if the string is a path to a file or - /// directory and its startign point is explicitly defined. This includes + /// directory and its starting point is explicitly defined. This includes /// <c>res://</c>, <c>user://</c>, <c>C:\</c>, <c>/</c>, etc. /// </summary> /// <seealso cref="IsRelativePath(string)"/> @@ -1345,7 +1349,7 @@ namespace Godot } [MethodImpl(MethodImplOptions.InternalCall)] - internal extern static string godot_icall_String_simplify_path(string str); + internal static extern string godot_icall_String_simplify_path(string str); /// <summary> /// Split the string by a divisor string, return an array of the substrings. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index c82c5f4588..8e253388bf 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -23,7 +23,6 @@ namespace Godot /// <summary> /// The basis matrix's X vector (column 0). Equivalent to array index <c>[0]</c>. /// </summary> - /// <value></value> public Vector2 x; /// <summary> @@ -420,12 +419,12 @@ namespace Godot /// Constructs a transformation matrix from the given components. /// Arguments are named such that xy is equal to calling x.y /// </summary> - /// <param name="xx">The X component of the X column vector, accessed via <c>t.x.x</c> or <c>[0][0]</c></param> - /// <param name="xy">The Y component of the X column vector, accessed via <c>t.x.y</c> or <c>[0][1]</c></param> - /// <param name="yx">The X component of the Y column vector, accessed via <c>t.y.x</c> or <c>[1][0]</c></param> - /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.y.y</c> or <c>[1][1]</c></param> - /// <param name="ox">The X component of the origin vector, accessed via <c>t.origin.x</c> or <c>[2][0]</c></param> - /// <param name="oy">The Y component of the origin vector, accessed via <c>t.origin.y</c> or <c>[2][1]</c></param> + /// <param name="xx">The X component of the X column vector, accessed via <c>t.x.x</c> or <c>[0][0]</c>.</param> + /// <param name="xy">The Y component of the X column vector, accessed via <c>t.x.y</c> or <c>[0][1]</c>.</param> + /// <param name="yx">The X component of the Y column vector, accessed via <c>t.y.x</c> or <c>[1][0]</c>.</param> + /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.y.y</c> or <c>[1][1]</c>.</param> + /// <param name="ox">The X component of the origin vector, accessed via <c>t.origin.x</c> or <c>[2][0]</c>.</param> + /// <param name="oy">The Y component of the origin vector, accessed via <c>t.origin.y</c> or <c>[2][1]</c>.</param> public Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) { x = new Vector2(xx, xy); @@ -447,6 +446,14 @@ namespace Godot this.origin = origin; } + /// <summary> + /// Composes these two transformation matrices by multiplying them + /// together. This has the effect of transforming the second transform + /// (the child) by the first transform (the parent). + /// </summary> + /// <param name="left">The parent transform.</param> + /// <param name="right">The child transform.</param> + /// <returns>The composed transform.</returns> public static Transform2D operator *(Transform2D left, Transform2D right) { left.origin = left * right.origin; @@ -554,31 +561,52 @@ namespace Godot return newArray; } + /// <summary> + /// Returns <see langword="true"/> if the transforms are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left transform.</param> + /// <param name="right">The right transform.</param> + /// <returns>Whether or not the transforms are exactly equal.</returns> public static bool operator ==(Transform2D left, Transform2D right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the transforms are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left transform.</param> + /// <param name="right">The right transform.</param> + /// <returns>Whether or not the transforms are not equal.</returns> public static bool operator !=(Transform2D left, Transform2D right) { return !left.Equals(right); } /// <summary> - /// Returns <see langword="true"/> if this transform and <paramref name="obj"/> are equal. + /// Returns <see langword="true"/> if the transform is exactly equal + /// to the given object (<see paramref="obj"/>). + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the transform and the other object are equal.</returns> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the transform and the object are exactly equal.</returns> public override bool Equals(object obj) { return obj is Transform2D transform2D && Equals(transform2D); } /// <summary> - /// Returns <see langword="true"/> if this transform and <paramref name="other"/> are equal. + /// Returns <see langword="true"/> if the transforms are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> /// <param name="other">The other transform to compare.</param> - /// <returns>Whether or not the matrices are equal.</returns> + /// <returns>Whether or not the matrices are exactly equal.</returns> public bool Equals(Transform2D other) { return x.Equals(other.x) && y.Equals(other.y) && origin.Equals(other.origin); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index 7176cd60dc..5d9aabdd2f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -166,7 +166,7 @@ namespace Godot /// Operations take place in global space. /// </summary> /// <param name="target">The object to look at.</param> - /// <param name="up">The relative up direction</param> + /// <param name="up">The relative up direction.</param> /// <returns>The resulting transform.</returns> public Transform3D LookingAt(Vector3 target, Vector3 up) { @@ -352,6 +352,14 @@ namespace Godot this.origin = origin; } + /// <summary> + /// Composes these two transformation matrices by multiplying them + /// together. This has the effect of transforming the second transform + /// (the child) by the first transform (the parent). + /// </summary> + /// <param name="left">The parent transform.</param> + /// <param name="right">The child transform.</param> + /// <returns>The composed transform.</returns> public static Transform3D operator *(Transform3D left, Transform3D right) { left.origin = left.Xform(right.origin); @@ -359,21 +367,40 @@ namespace Godot return left; } + /// <summary> + /// Returns <see langword="true"/> if the transforms are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left transform.</param> + /// <param name="right">The right transform.</param> + /// <returns>Whether or not the transforms are exactly equal.</returns> public static bool operator ==(Transform3D left, Transform3D right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the transforms are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left transform.</param> + /// <param name="right">The right transform.</param> + /// <returns>Whether or not the transforms are not equal.</returns> public static bool operator !=(Transform3D left, Transform3D right) { return !left.Equals(right); } /// <summary> - /// Returns <see langword="true"/> if this transform and <paramref name="obj"/> are equal. + /// Returns <see langword="true"/> if the transform is exactly equal + /// to the given object (<see paramref="obj"/>). + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the transform and the other object are equal.</returns> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the transform and the object are exactly equal.</returns> public override bool Equals(object obj) { if (obj is Transform3D) @@ -385,10 +412,12 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this transform and <paramref name="other"/> are equal. + /// Returns <see langword="true"/> if the transforms are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> /// <param name="other">The other transform to compare.</param> - /// <returns>Whether or not the matrices are equal.</returns> + /// <returns>Whether or not the matrices are exactly equal.</returns> public bool Equals(Transform3D other) { return basis.Equals(other.basis) && origin.Equals(other.origin); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index fe70d71cce..1f5282e88f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -17,7 +17,7 @@ namespace Godot { /// <summary> /// Enumerated index values for the axes. - /// Returned by <see cref="MaxAxis"/> and <see cref="MinAxis"/>. + /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>. /// </summary> public enum Axis { @@ -184,13 +184,13 @@ namespace Godot } /// <summary> - /// Returns the cross product of this vector and <paramref name="b"/>. + /// Returns the cross product of this vector and <paramref name="with"/>. /// </summary> - /// <param name="b">The other vector.</param> + /// <param name="with">The other vector.</param> /// <returns>The cross product value.</returns> - public real_t Cross(Vector2 b) + public real_t Cross(Vector2 with) { - return (x * b.y) - (y * b.x); + return (x * with.y) - (y * with.x); } /// <summary> @@ -222,13 +222,13 @@ namespace Godot } /// <summary> - /// Returns the normalized vector pointing from this vector to <paramref name="b"/>. + /// Returns the normalized vector pointing from this vector to <paramref name="to"/>. /// </summary> - /// <param name="b">The other vector to point towards.</param> - /// <returns>The direction from this vector to <paramref name="b"/>.</returns> - public Vector2 DirectionTo(Vector2 b) + /// <param name="to">The other vector to point towards.</param> + /// <returns>The direction from this vector to <paramref name="to"/>.</returns> + public Vector2 DirectionTo(Vector2 to) { - return new Vector2(b.x - x, b.y - y).Normalized(); + return new Vector2(to.x - x, to.y - y).Normalized(); } /// <summary> @@ -365,21 +365,21 @@ namespace Godot } /// <summary> - /// Returns the axis of the vector's largest value. See <see cref="Axis"/>. + /// Returns the axis of the vector's highest value. See <see cref="Axis"/>. /// If both components are equal, this method returns <see cref="Axis.X"/>. /// </summary> - /// <returns>The index of the largest axis.</returns> - public Axis MaxAxis() + /// <returns>The index of the highest axis.</returns> + public Axis MaxAxisIndex() { return x < y ? Axis.Y : Axis.X; } /// <summary> - /// Returns the axis of the vector's smallest value. See <see cref="Axis"/>. + /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>. /// If both components are equal, this method returns <see cref="Axis.Y"/>. /// </summary> - /// <returns>The index of the smallest axis.</returns> - public Axis MinAxis() + /// <returns>The index of the lowest axis.</returns> + public Axis MinAxisIndex() { return x < y ? Axis.X : Axis.Y; } @@ -642,6 +642,13 @@ namespace Godot return new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)); } + /// <summary> + /// Adds each component of the <see cref="Vector2"/> + /// with the components of the given <see cref="Vector2"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The added vector.</returns> public static Vector2 operator +(Vector2 left, Vector2 right) { left.x += right.x; @@ -649,6 +656,13 @@ namespace Godot return left; } + /// <summary> + /// Subtracts each component of the <see cref="Vector2"/> + /// by the components of the given <see cref="Vector2"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The subtracted vector.</returns> public static Vector2 operator -(Vector2 left, Vector2 right) { left.x -= right.x; @@ -656,6 +670,15 @@ namespace Godot return left; } + /// <summary> + /// Returns the negative value of the <see cref="Vector2"/>. + /// This is the same as writing <c>new Vector2(-v.x, -v.y)</c>. + /// This operation flips the direction of the vector while + /// keeping the same magnitude. + /// With floats, the number zero can be either positive or negative. + /// </summary> + /// <param name="vec">The vector to negate/flip.</param> + /// <returns>The negated/flipped vector.</returns> public static Vector2 operator -(Vector2 vec) { vec.x = -vec.x; @@ -663,6 +686,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector2"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="vec">The vector to multiply.</param> + /// <param name="scale">The scale to multiply by.</param> + /// <returns>The multiplied vector.</returns> public static Vector2 operator *(Vector2 vec, real_t scale) { vec.x *= scale; @@ -670,6 +700,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector2"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="scale">The scale to multiply by.</param> + /// <param name="vec">The vector to multiply.</param> + /// <returns>The multiplied vector.</returns> public static Vector2 operator *(real_t scale, Vector2 vec) { vec.x *= scale; @@ -677,6 +714,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector2"/> + /// by the components of the given <see cref="Vector2"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The multiplied vector.</returns> public static Vector2 operator *(Vector2 left, Vector2 right) { left.x *= right.x; @@ -684,6 +728,13 @@ namespace Godot return left; } + /// <summary> + /// Multiplies each component of the <see cref="Vector2"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The divided vector.</returns> public static Vector2 operator /(Vector2 vec, real_t divisor) { vec.x /= divisor; @@ -691,6 +742,13 @@ namespace Godot return vec; } + /// <summary> + /// Divides each component of the <see cref="Vector2"/> + /// by the components of the given <see cref="Vector2"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The divided vector.</returns> public static Vector2 operator /(Vector2 vec, Vector2 divisorv) { vec.x /= divisorv.x; @@ -698,6 +756,22 @@ namespace Godot return vec; } + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector2"/> + /// with the components of the given <see cref="real_t"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(real_t)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector2(10, -20) % 7); // Prints "(3, -6)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The remainder vector.</returns> public static Vector2 operator %(Vector2 vec, real_t divisor) { vec.x %= divisor; @@ -705,6 +779,22 @@ namespace Godot return vec; } + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector2"/> + /// with the components of the given <see cref="Vector2"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(Vector2)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector2(10, -20) % new Vector2(7, 8)); // Prints "(3, -4)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The remainder vector.</returns> public static Vector2 operator %(Vector2 vec, Vector2 divisorv) { vec.x %= divisorv.x; @@ -712,16 +802,43 @@ namespace Godot return vec; } + /// <summary> + /// Returns <see langword="true"/> if the vectors are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are exactly equal.</returns> public static bool operator ==(Vector2 left, Vector2 right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the vectors are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are not equal.</returns> public static bool operator !=(Vector2 left, Vector2 right) { return !left.Equals(right); } + /// <summary> + /// Compares two <see cref="Vector2"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Vector2 left, Vector2 right) { if (left.x == right.x) @@ -731,6 +848,17 @@ namespace Godot return left.x < right.x; } + /// <summary> + /// Compares two <see cref="Vector2"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Vector2 left, Vector2 right) { if (left.x == right.x) @@ -740,29 +868,54 @@ namespace Godot return left.x > right.x; } + /// <summary> + /// Compares two <see cref="Vector2"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than or equal to the right.</returns> public static bool operator <=(Vector2 left, Vector2 right) { if (left.x == right.x) { return left.y <= right.y; } - return left.x <= right.x; + return left.x < right.x; } + /// <summary> + /// Compares two <see cref="Vector2"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than or equal to the right.</returns> public static bool operator >=(Vector2 left, Vector2 right) { if (left.x == right.x) { return left.y >= right.y; } - return left.x >= right.x; + return left.x > right.x; } /// <summary> - /// Returns <see langword="true"/> if this vector and <paramref name="obj"/> are equal. + /// Returns <see langword="true"/> if the vector is exactly equal + /// to the given object (<see paramref="obj"/>). + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the vector and the other object are equal.</returns> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the vector and the object are equal.</returns> public override bool Equals(object obj) { if (obj is Vector2) @@ -773,10 +926,12 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are equal. + /// Returns <see langword="true"/> if the vectors are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="other">The other vector to compare.</param> - /// <returns>Whether or not the vectors are equal.</returns> + /// <param name="other">The other vector.</param> + /// <returns>Whether or not the vectors are exactly equal.</returns> public bool Equals(Vector2 other) { return x == other.x && y == other.y; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs index ca4531d885..9b51de5c8c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs @@ -17,7 +17,7 @@ namespace Godot { /// <summary> /// Enumerated index values for the axes. - /// Returned by <see cref="MaxAxis"/> and <see cref="MinAxis"/>. + /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>. /// </summary> public enum Axis { @@ -149,45 +149,45 @@ namespace Godot } /// <summary> - /// Returns the cross product of this vector and <paramref name="b"/>. + /// Returns the cross product of this vector and <paramref name="with"/>. /// </summary> - /// <param name="b">The other vector.</param> + /// <param name="with">The other vector.</param> /// <returns>The cross product vector.</returns> - public int Cross(Vector2i b) + public int Cross(Vector2i with) { - return x * b.y - y * b.x; + return x * with.y - y * with.x; } /// <summary> - /// Returns the squared distance between this vector and <paramref name="b"/>. + /// Returns the squared distance between this vector and <paramref name="to"/>. /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if /// you need to compare vectors or need the squared distance for some formula. /// </summary> - /// <param name="b">The other vector to use.</param> + /// <param name="to">The other vector to use.</param> /// <returns>The squared distance between the two vectors.</returns> - public int DistanceSquaredTo(Vector2i b) + public int DistanceSquaredTo(Vector2i to) { - return (b - this).LengthSquared(); + return (to - this).LengthSquared(); } /// <summary> - /// Returns the distance between this vector and <paramref name="b"/>. + /// Returns the distance between this vector and <paramref name="to"/>. /// </summary> - /// <param name="b">The other vector to use.</param> + /// <param name="to">The other vector to use.</param> /// <returns>The distance between the two vectors.</returns> - public real_t DistanceTo(Vector2i b) + public real_t DistanceTo(Vector2i to) { - return (b - this).Length(); + return (to - this).Length(); } /// <summary> - /// Returns the dot product of this vector and <paramref name="b"/>. + /// Returns the dot product of this vector and <paramref name="with"/>. /// </summary> - /// <param name="b">The other vector to use.</param> + /// <param name="with">The other vector to use.</param> /// <returns>The dot product of the two vectors.</returns> - public int Dot(Vector2i b) + public int Dot(Vector2i with) { - return x * b.x + y * b.y; + return x * with.x + y * with.y; } /// <summary> @@ -218,21 +218,21 @@ namespace Godot } /// <summary> - /// Returns the axis of the vector's largest value. See <see cref="Axis"/>. + /// Returns the axis of the vector's highest value. See <see cref="Axis"/>. /// If both components are equal, this method returns <see cref="Axis.X"/>. /// </summary> - /// <returns>The index of the largest axis.</returns> - public Axis MaxAxis() + /// <returns>The index of the highest axis.</returns> + public Axis MaxAxisIndex() { return x < y ? Axis.Y : Axis.X; } /// <summary> - /// Returns the axis of the vector's smallest value. See <see cref="Axis"/>. + /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>. /// If both components are equal, this method returns <see cref="Axis.Y"/>. /// </summary> - /// <returns>The index of the smallest axis.</returns> - public Axis MinAxis() + /// <returns>The index of the lowest axis.</returns> + public Axis MinAxisIndex() { return x < y ? Axis.X : Axis.Y; } @@ -366,6 +366,13 @@ namespace Godot this.y = Mathf.RoundToInt(v.y); } + /// <summary> + /// Adds each component of the <see cref="Vector2i"/> + /// with the components of the given <see cref="Vector2i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The added vector.</returns> public static Vector2i operator +(Vector2i left, Vector2i right) { left.x += right.x; @@ -373,6 +380,13 @@ namespace Godot return left; } + /// <summary> + /// Subtracts each component of the <see cref="Vector2i"/> + /// by the components of the given <see cref="Vector2i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The subtracted vector.</returns> public static Vector2i operator -(Vector2i left, Vector2i right) { left.x -= right.x; @@ -380,6 +394,14 @@ namespace Godot return left; } + /// <summary> + /// Returns the negative value of the <see cref="Vector2i"/>. + /// This is the same as writing <c>new Vector2i(-v.x, -v.y)</c>. + /// This operation flips the direction of the vector while + /// keeping the same magnitude. + /// </summary> + /// <param name="vec">The vector to negate/flip.</param> + /// <returns>The negated/flipped vector.</returns> public static Vector2i operator -(Vector2i vec) { vec.x = -vec.x; @@ -387,6 +409,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector2i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The vector to multiply.</param> + /// <param name="scale">The scale to multiply by.</param> + /// <returns>The multiplied vector.</returns> public static Vector2i operator *(Vector2i vec, int scale) { vec.x *= scale; @@ -394,6 +423,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector2i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="scale">The scale to multiply by.</param> + /// <param name="vec">The vector to multiply.</param> + /// <returns>The multiplied vector.</returns> public static Vector2i operator *(int scale, Vector2i vec) { vec.x *= scale; @@ -401,6 +437,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector2i"/> + /// by the components of the given <see cref="Vector2i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The multiplied vector.</returns> public static Vector2i operator *(Vector2i left, Vector2i right) { left.x *= right.x; @@ -408,6 +451,13 @@ namespace Godot return left; } + /// <summary> + /// Multiplies each component of the <see cref="Vector2i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The divided vector.</returns> public static Vector2i operator /(Vector2i vec, int divisor) { vec.x /= divisor; @@ -415,6 +465,13 @@ namespace Godot return vec; } + /// <summary> + /// Divides each component of the <see cref="Vector2i"/> + /// by the components of the given <see cref="Vector2i"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The divided vector.</returns> public static Vector2i operator /(Vector2i vec, Vector2i divisorv) { vec.x /= divisorv.x; @@ -422,6 +479,22 @@ namespace Godot return vec; } + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector2i"/> + /// with the components of the given <see langword="int"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(int)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector2i(10, -20) % 7); // Prints "(3, -6)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The remainder vector.</returns> public static Vector2i operator %(Vector2i vec, int divisor) { vec.x %= divisor; @@ -429,6 +502,22 @@ namespace Godot return vec; } + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector2i"/> + /// with the components of the given <see cref="Vector2i"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(Vector2i)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector2i(10, -20) % new Vector2i(7, 8)); // Prints "(3, -4)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The remainder vector.</returns> public static Vector2i operator %(Vector2i vec, Vector2i divisorv) { vec.x %= divisorv.x; @@ -436,6 +525,13 @@ namespace Godot return vec; } + /// <summary> + /// Performs a bitwise AND operation with this <see cref="Vector2i"/> + /// and the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The vector to AND with.</param> + /// <param name="and">The integer to AND with.</param> + /// <returns>The result of the bitwise AND.</returns> public static Vector2i operator &(Vector2i vec, int and) { vec.x &= and; @@ -443,6 +539,13 @@ namespace Godot return vec; } + /// <summary> + /// Performs a bitwise AND operation with this <see cref="Vector2i"/> + /// and the given <see cref="Vector2i"/>. + /// </summary> + /// <param name="vec">The left vector to AND with.</param> + /// <param name="andv">The right vector to AND with.</param> + /// <returns>The result of the bitwise AND.</returns> public static Vector2i operator &(Vector2i vec, Vector2i andv) { vec.x &= andv.x; @@ -450,50 +553,106 @@ namespace Godot return vec; } + /// <summary> + /// Returns <see langword="true"/> if the vectors are equal. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are equal.</returns> public static bool operator ==(Vector2i left, Vector2i right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the vectors are not equal. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are not equal.</returns> public static bool operator !=(Vector2i left, Vector2i right) { return !left.Equals(right); } + /// <summary> + /// Compares two <see cref="Vector2i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Vector2i left, Vector2i right) { - if (left.x.Equals(right.x)) + if (left.x == right.x) { return left.y < right.y; } return left.x < right.x; } + /// <summary> + /// Compares two <see cref="Vector2i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Vector2i left, Vector2i right) { - if (left.x.Equals(right.x)) + if (left.x == right.x) { return left.y > right.y; } return left.x > right.x; } + /// <summary> + /// Compares two <see cref="Vector2i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than or equal to the right.</returns> public static bool operator <=(Vector2i left, Vector2i right) { - if (left.x.Equals(right.x)) + if (left.x == right.x) { return left.y <= right.y; } - return left.x <= right.x; + return left.x < right.x; } + /// <summary> + /// Compares two <see cref="Vector2i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than or equal to the right.</returns> public static bool operator >=(Vector2i left, Vector2i right) { - if (left.x.Equals(right.x)) + if (left.x == right.x) { return left.y >= right.y; } - return left.x >= right.x; + return left.x > right.x; } /// <summary> @@ -515,10 +674,11 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this vector and <paramref name="obj"/> are equal. + /// Returns <see langword="true"/> if the vector is equal + /// to the given object (<see paramref="obj"/>). /// </summary> - /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the vector and the other object are equal.</returns> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the vector and the object are equal.</returns> public override bool Equals(object obj) { if (obj is Vector2i) @@ -530,9 +690,9 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are equal. + /// Returns <see langword="true"/> if the vectors are equal. /// </summary> - /// <param name="other">The other vector to compare.</param> + /// <param name="other">The other vector.</param> /// <returns>Whether or not the vectors are equal.</returns> public bool Equals(Vector2i other) { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 01e3a71bcb..433a5d9dc9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -17,7 +17,7 @@ namespace Godot { /// <summary> /// Enumerated index values for the axes. - /// Returned by <see cref="MaxAxis"/> and <see cref="MinAxis"/>. + /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>. /// </summary> public enum Axis { @@ -170,17 +170,17 @@ namespace Godot } /// <summary> - /// Returns the cross product of this vector and <paramref name="b"/>. + /// Returns the cross product of this vector and <paramref name="with"/>. /// </summary> - /// <param name="b">The other vector.</param> + /// <param name="with">The other vector.</param> /// <returns>The cross product vector.</returns> - public Vector3 Cross(Vector3 b) + public Vector3 Cross(Vector3 with) { return new Vector3 ( - (y * b.z) - (z * b.y), - (z * b.x) - (x * b.z), - (x * b.y) - (y * b.x) + (y * with.z) - (z * with.y), + (z * with.x) - (x * with.z), + (x * with.y) - (y * with.x) ); } @@ -212,46 +212,46 @@ namespace Godot } /// <summary> - /// Returns the normalized vector pointing from this vector to <paramref name="b"/>. + /// Returns the normalized vector pointing from this vector to <paramref name="to"/>. /// </summary> - /// <param name="b">The other vector to point towards.</param> - /// <returns>The direction from this vector to <paramref name="b"/>.</returns> - public Vector3 DirectionTo(Vector3 b) + /// <param name="to">The other vector to point towards.</param> + /// <returns>The direction from this vector to <paramref name="to"/>.</returns> + public Vector3 DirectionTo(Vector3 to) { - return new Vector3(b.x - x, b.y - y, b.z - z).Normalized(); + return new Vector3(to.x - x, to.y - y, to.z - z).Normalized(); } /// <summary> - /// Returns the squared distance between this vector and <paramref name="b"/>. + /// Returns the squared distance between this vector and <paramref name="to"/>. /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if /// you need to compare vectors or need the squared distance for some formula. /// </summary> - /// <param name="b">The other vector to use.</param> + /// <param name="to">The other vector to use.</param> /// <returns>The squared distance between the two vectors.</returns> - public real_t DistanceSquaredTo(Vector3 b) + public real_t DistanceSquaredTo(Vector3 to) { - return (b - this).LengthSquared(); + return (to - this).LengthSquared(); } /// <summary> - /// Returns the distance between this vector and <paramref name="b"/>. + /// Returns the distance between this vector and <paramref name="to"/>. /// </summary> /// <seealso cref="DistanceSquaredTo(Vector3)"/> - /// <param name="b">The other vector to use.</param> + /// <param name="to">The other vector to use.</param> /// <returns>The distance between the two vectors.</returns> - public real_t DistanceTo(Vector3 b) + public real_t DistanceTo(Vector3 to) { - return (b - this).Length(); + return (to - this).Length(); } /// <summary> - /// Returns the dot product of this vector and <paramref name="b"/>. + /// Returns the dot product of this vector and <paramref name="with"/>. /// </summary> - /// <param name="b">The other vector to use.</param> + /// <param name="with">The other vector to use.</param> /// <returns>The dot product of the two vectors.</returns> - public real_t Dot(Vector3 b) + public real_t Dot(Vector3 with) { - return (x * b.x) + (y * b.y) + (z * b.z); + return (x * with.x) + (y * with.y) + (z * with.z); } /// <summary> @@ -364,21 +364,21 @@ namespace Godot } /// <summary> - /// Returns the axis of the vector's largest value. See <see cref="Axis"/>. + /// Returns the axis of the vector's highest value. See <see cref="Axis"/>. /// If all components are equal, this method returns <see cref="Axis.X"/>. /// </summary> - /// <returns>The index of the largest axis.</returns> - public Axis MaxAxis() + /// <returns>The index of the highest axis.</returns> + public Axis MaxAxisIndex() { return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X); } /// <summary> - /// Returns the axis of the vector's smallest value. See <see cref="Axis"/>. + /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>. /// If all components are equal, this method returns <see cref="Axis.Z"/>. /// </summary> - /// <returns>The index of the smallest axis.</returns> - public Axis MinAxis() + /// <returns>The index of the lowest axis.</returns> + public Axis MinAxisIndex() { return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z); } @@ -412,16 +412,16 @@ namespace Godot } /// <summary> - /// Returns the outer product with <paramref name="b"/>. + /// Returns the outer product with <paramref name="with"/>. /// </summary> - /// <param name="b">The other vector.</param> + /// <param name="with">The other vector.</param> /// <returns>A <see cref="Basis"/> representing the outer product matrix.</returns> - public Basis Outer(Vector3 b) + public Basis Outer(Vector3 with) { return new Basis( - x * b.x, x * b.y, x * b.z, - y * b.x, y * b.y, y * b.z, - z * b.x, z * b.y, z * b.z + x * with.x, x * with.y, x * with.z, + y * with.x, y * with.y, y * with.z, + z * with.x, z * with.y, z * with.z ); } @@ -699,6 +699,13 @@ namespace Godot z = v.z; } + /// <summary> + /// Adds each component of the <see cref="Vector3"/> + /// with the components of the given <see cref="Vector3"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The added vector.</returns> public static Vector3 operator +(Vector3 left, Vector3 right) { left.x += right.x; @@ -707,6 +714,13 @@ namespace Godot return left; } + /// <summary> + /// Subtracts each component of the <see cref="Vector3"/> + /// by the components of the given <see cref="Vector3"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The subtracted vector.</returns> public static Vector3 operator -(Vector3 left, Vector3 right) { left.x -= right.x; @@ -715,6 +729,15 @@ namespace Godot return left; } + /// <summary> + /// Returns the negative value of the <see cref="Vector3"/>. + /// This is the same as writing <c>new Vector3(-v.x, -v.y, -v.z)</c>. + /// This operation flips the direction of the vector while + /// keeping the same magnitude. + /// With floats, the number zero can be either positive or negative. + /// </summary> + /// <param name="vec">The vector to negate/flip.</param> + /// <returns>The negated/flipped vector.</returns> public static Vector3 operator -(Vector3 vec) { vec.x = -vec.x; @@ -723,6 +746,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector3"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="vec">The vector to multiply.</param> + /// <param name="scale">The scale to multiply by.</param> + /// <returns>The multiplied vector.</returns> public static Vector3 operator *(Vector3 vec, real_t scale) { vec.x *= scale; @@ -731,6 +761,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector3"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="scale">The scale to multiply by.</param> + /// <param name="vec">The vector to multiply.</param> + /// <returns>The multiplied vector.</returns> public static Vector3 operator *(real_t scale, Vector3 vec) { vec.x *= scale; @@ -739,6 +776,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector3"/> + /// by the components of the given <see cref="Vector3"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The multiplied vector.</returns> public static Vector3 operator *(Vector3 left, Vector3 right) { left.x *= right.x; @@ -747,6 +791,13 @@ namespace Godot return left; } + /// <summary> + /// Divides each component of the <see cref="Vector3"/> + /// by the given <see cref="real_t"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The divided vector.</returns> public static Vector3 operator /(Vector3 vec, real_t divisor) { vec.x /= divisor; @@ -755,6 +806,13 @@ namespace Godot return vec; } + /// <summary> + /// Divides each component of the <see cref="Vector3"/> + /// by the components of the given <see cref="Vector3"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The divided vector.</returns> public static Vector3 operator /(Vector3 vec, Vector3 divisorv) { vec.x /= divisorv.x; @@ -763,6 +821,22 @@ namespace Godot return vec; } + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector3"/> + /// with the components of the given <see cref="real_t"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(real_t)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector3(10, -20, 30) % 7); // Prints "(3, -6, 2)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The remainder vector.</returns> public static Vector3 operator %(Vector3 vec, real_t divisor) { vec.x %= divisor; @@ -771,6 +845,22 @@ namespace Godot return vec; } + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector3"/> + /// with the components of the given <see cref="Vector3"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(Vector3)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector3(10, -20, 30) % new Vector3(7, 8, 9)); // Prints "(3, -4, 3)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The remainder vector.</returns> public static Vector3 operator %(Vector3 vec, Vector3 divisorv) { vec.x %= divisorv.x; @@ -779,16 +869,43 @@ namespace Godot return vec; } + /// <summary> + /// Returns <see langword="true"/> if the vectors are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are exactly equal.</returns> public static bool operator ==(Vector3 left, Vector3 right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the vectors are not equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are not equal.</returns> public static bool operator !=(Vector3 left, Vector3 right) { return !left.Equals(right); } + /// <summary> + /// Compares two <see cref="Vector3"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors, and then with the Z values. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Vector3 left, Vector3 right) { if (left.x == right.x) @@ -802,6 +919,17 @@ namespace Godot return left.x < right.x; } + /// <summary> + /// Compares two <see cref="Vector3"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors, and then with the Z values. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Vector3 left, Vector3 right) { if (left.x == right.x) @@ -815,6 +943,17 @@ namespace Godot return left.x > right.x; } + /// <summary> + /// Compares two <see cref="Vector3"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors, and then with the Z values. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than or equal to the right.</returns> public static bool operator <=(Vector3 left, Vector3 right) { if (left.x == right.x) @@ -828,6 +967,17 @@ namespace Godot return left.x < right.x; } + /// <summary> + /// Compares two <see cref="Vector3"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors, and then with the Z values. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than or equal to the right.</returns> public static bool operator >=(Vector3 left, Vector3 right) { if (left.x == right.x) @@ -842,10 +992,13 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this vector and <paramref name="obj"/> are equal. + /// Returns <see langword="true"/> if the vector is exactly equal + /// to the given object (<see paramref="obj"/>). + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the vector and the other object are equal.</returns> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the vector and the object are equal.</returns> public override bool Equals(object obj) { if (obj is Vector3) @@ -857,10 +1010,12 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are equal + /// Returns <see langword="true"/> if the vectors are exactly equal. + /// Note: Due to floating-point precision errors, consider using + /// <see cref="IsEqualApprox"/> instead, which is more reliable. /// </summary> - /// <param name="other">The other vector to compare.</param> - /// <returns>Whether or not the vectors are equal.</returns> + /// <param name="other">The other vector.</param> + /// <returns>Whether or not the vectors are exactly equal.</returns> public bool Equals(Vector3 other) { return x == other.x && y == other.y && z == other.z; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs index 2a7771cdfc..eb06d2b87e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs @@ -17,7 +17,7 @@ namespace Godot { /// <summary> /// Enumerated index values for the axes. - /// Returned by <see cref="MaxAxis"/> and <see cref="MinAxis"/>. + /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>. /// </summary> public enum Axis { @@ -124,36 +124,36 @@ namespace Godot } /// <summary> - /// Returns the squared distance between this vector and <paramref name="b"/>. + /// Returns the squared distance between this vector and <paramref name="to"/>. /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if /// you need to compare vectors or need the squared distance for some formula. /// </summary> - /// <param name="b">The other vector to use.</param> + /// <param name="to">The other vector to use.</param> /// <returns>The squared distance between the two vectors.</returns> - public int DistanceSquaredTo(Vector3i b) + public int DistanceSquaredTo(Vector3i to) { - return (b - this).LengthSquared(); + return (to - this).LengthSquared(); } /// <summary> - /// Returns the distance between this vector and <paramref name="b"/>. + /// Returns the distance between this vector and <paramref name="to"/>. /// </summary> /// <seealso cref="DistanceSquaredTo(Vector3i)"/> - /// <param name="b">The other vector to use.</param> + /// <param name="to">The other vector to use.</param> /// <returns>The distance between the two vectors.</returns> - public real_t DistanceTo(Vector3i b) + public real_t DistanceTo(Vector3i to) { - return (b - this).Length(); + return (to - this).Length(); } /// <summary> - /// Returns the dot product of this vector and <paramref name="b"/>. + /// Returns the dot product of this vector and <paramref name="with"/>. /// </summary> - /// <param name="b">The other vector to use.</param> + /// <param name="with">The other vector to use.</param> /// <returns>The dot product of the two vectors.</returns> - public int Dot(Vector3i b) + public int Dot(Vector3i with) { - return x * b.x + y * b.y + z * b.z; + return x * with.x + y * with.y + z * with.z; } /// <summary> @@ -186,21 +186,21 @@ namespace Godot } /// <summary> - /// Returns the axis of the vector's largest value. See <see cref="Axis"/>. + /// Returns the axis of the vector's highest value. See <see cref="Axis"/>. /// If all components are equal, this method returns <see cref="Axis.X"/>. /// </summary> - /// <returns>The index of the largest axis.</returns> - public Axis MaxAxis() + /// <returns>The index of the highest axis.</returns> + public Axis MaxAxisIndex() { return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X); } /// <summary> - /// Returns the axis of the vector's smallest value. See <see cref="Axis"/>. + /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>. /// If all components are equal, this method returns <see cref="Axis.Z"/>. /// </summary> - /// <returns>The index of the smallest axis.</returns> - public Axis MinAxis() + /// <returns>The index of the lowest axis.</returns> + public Axis MinAxisIndex() { return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z); } @@ -347,6 +347,13 @@ namespace Godot this.z = Mathf.RoundToInt(v.z); } + /// <summary> + /// Adds each component of the <see cref="Vector3i"/> + /// with the components of the given <see cref="Vector3i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The added vector.</returns> public static Vector3i operator +(Vector3i left, Vector3i right) { left.x += right.x; @@ -355,6 +362,13 @@ namespace Godot return left; } + /// <summary> + /// Subtracts each component of the <see cref="Vector3i"/> + /// by the components of the given <see cref="Vector3i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The subtracted vector.</returns> public static Vector3i operator -(Vector3i left, Vector3i right) { left.x -= right.x; @@ -363,6 +377,14 @@ namespace Godot return left; } + /// <summary> + /// Returns the negative value of the <see cref="Vector3i"/>. + /// This is the same as writing <c>new Vector3i(-v.x, -v.y, -v.z)</c>. + /// This operation flips the direction of the vector while + /// keeping the same magnitude. + /// </summary> + /// <param name="vec">The vector to negate/flip.</param> + /// <returns>The negated/flipped vector.</returns> public static Vector3i operator -(Vector3i vec) { vec.x = -vec.x; @@ -371,6 +393,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector3i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The vector to multiply.</param> + /// <param name="scale">The scale to multiply by.</param> + /// <returns>The multiplied vector.</returns> public static Vector3i operator *(Vector3i vec, int scale) { vec.x *= scale; @@ -379,6 +408,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector3i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="scale">The scale to multiply by.</param> + /// <param name="vec">The vector to multiply.</param> + /// <returns>The multiplied vector.</returns> public static Vector3i operator *(int scale, Vector3i vec) { vec.x *= scale; @@ -387,6 +423,13 @@ namespace Godot return vec; } + /// <summary> + /// Multiplies each component of the <see cref="Vector3i"/> + /// by the components of the given <see cref="Vector3i"/>. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>The multiplied vector.</returns> public static Vector3i operator *(Vector3i left, Vector3i right) { left.x *= right.x; @@ -395,6 +438,13 @@ namespace Godot return left; } + /// <summary> + /// Multiplies each component of the <see cref="Vector3i"/> + /// by the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The divided vector.</returns> public static Vector3i operator /(Vector3i vec, int divisor) { vec.x /= divisor; @@ -403,6 +453,13 @@ namespace Godot return vec; } + /// <summary> + /// Divides each component of the <see cref="Vector3i"/> + /// by the components of the given <see cref="Vector3i"/>. + /// </summary> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The divided vector.</returns> public static Vector3i operator /(Vector3i vec, Vector3i divisorv) { vec.x /= divisorv.x; @@ -411,6 +468,22 @@ namespace Godot return vec; } + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector3i"/> + /// with the components of the given <see langword="int"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(int)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector3i(10, -20, 30) % 7); // Prints "(3, -6, 2)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The remainder vector.</returns> public static Vector3i operator %(Vector3i vec, int divisor) { vec.x %= divisor; @@ -419,6 +492,22 @@ namespace Godot return vec; } + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector3i"/> + /// with the components of the given <see cref="Vector3i"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(Vector3i)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector3i(10, -20, 30) % new Vector3i(7, 8, 9)); // Prints "(3, -4, 3)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The remainder vector.</returns> public static Vector3i operator %(Vector3i vec, Vector3i divisorv) { vec.x %= divisorv.x; @@ -427,6 +516,13 @@ namespace Godot return vec; } + /// <summary> + /// Performs a bitwise AND operation with this <see cref="Vector3i"/> + /// and the given <see langword="int"/>. + /// </summary> + /// <param name="vec">The vector to AND with.</param> + /// <param name="and">The integer to AND with.</param> + /// <returns>The result of the bitwise AND.</returns> public static Vector3i operator &(Vector3i vec, int and) { vec.x &= and; @@ -435,6 +531,13 @@ namespace Godot return vec; } + /// <summary> + /// Performs a bitwise AND operation with this <see cref="Vector3i"/> + /// and the given <see cref="Vector3i"/>. + /// </summary> + /// <param name="vec">The left vector to AND with.</param> + /// <param name="andv">The right vector to AND with.</param> + /// <returns>The result of the bitwise AND.</returns> public static Vector3i operator &(Vector3i vec, Vector3i andv) { vec.x &= andv.x; @@ -443,65 +546,121 @@ namespace Godot return vec; } + /// <summary> + /// Returns <see langword="true"/> if the vectors are equal. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are equal.</returns> public static bool operator ==(Vector3i left, Vector3i right) { return left.Equals(right); } + /// <summary> + /// Returns <see langword="true"/> if the vectors are not equal. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the vectors are not equal.</returns> public static bool operator !=(Vector3i left, Vector3i right) { return !left.Equals(right); } + /// <summary> + /// Compares two <see cref="Vector3i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors, and then with the Z values. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Vector3i left, Vector3i right) { if (left.x == right.x) { if (left.y == right.y) + { return left.z < right.z; - else - return left.y < right.y; + } + return left.y < right.y; } - return left.x < right.x; } + /// <summary> + /// Compares two <see cref="Vector3i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors, and then with the Z values. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Vector3i left, Vector3i right) { if (left.x == right.x) { if (left.y == right.y) + { return left.z > right.z; - else - return left.y > right.y; + } + return left.y > right.y; } - return left.x > right.x; } + /// <summary> + /// Compares two <see cref="Vector3i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is less than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors, and then with the Z values. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is less than or equal to the right.</returns> public static bool operator <=(Vector3i left, Vector3i right) { if (left.x == right.x) { if (left.y == right.y) + { return left.z <= right.z; - else - return left.y < right.y; + } + return left.y < right.y; } - return left.x < right.x; } + /// <summary> + /// Compares two <see cref="Vector3i"/> vectors by first checking if + /// the X value of the <paramref name="left"/> vector is greater than + /// or equal to the X value of the <paramref name="right"/> vector. + /// If the X values are exactly equal, then it repeats this check + /// with the Y values of the two vectors, and then with the Z values. + /// This operator is useful for sorting vectors. + /// </summary> + /// <param name="left">The left vector.</param> + /// <param name="right">The right vector.</param> + /// <returns>Whether or not the left is greater than or equal to the right.</returns> public static bool operator >=(Vector3i left, Vector3i right) { if (left.x == right.x) { if (left.y == right.y) + { return left.z >= right.z; - else - return left.y > right.y; + } + return left.y > right.y; } - return left.x > right.x; } @@ -524,10 +683,11 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this vector and <paramref name="obj"/> are equal. + /// Returns <see langword="true"/> if the vector is equal + /// to the given object (<see paramref="obj"/>). /// </summary> - /// <param name="obj">The other object to compare.</param> - /// <returns>Whether or not the vector and the other object are equal.</returns> + /// <param name="obj">The object to compare with.</param> + /// <returns>Whether or not the vector and the object are equal.</returns> public override bool Equals(object obj) { if (obj is Vector3i) @@ -539,9 +699,9 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this vector and <paramref name="other"/> are equal + /// Returns <see langword="true"/> if the vectors are equal. /// </summary> - /// <param name="other">The other vector to compare.</param> + /// <param name="other">The other vector.</param> /// <returns>Whether or not the vectors are equal.</returns> public bool Equals(Vector3i other) { diff --git a/modules/mono/glue/arguments_vector.h b/modules/mono/glue/arguments_vector.h index 9ba6a05ac6..7c991d87a4 100644 --- a/modules/mono/glue/arguments_vector.h +++ b/modules/mono/glue/arguments_vector.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 6c5503a3bd..8e7b125ed5 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webm/register_types.cpp b/modules/mono/glue/callable_glue.cpp index 8f690a6892..e59b34313c 100644 --- a/modules/webm/register_types.cpp +++ b/modules/mono/glue/callable_glue.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* register_types.cpp */ +/* callable_glue.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,20 +28,52 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "register_types.h" +#ifdef MONO_GLUE_ENABLED -#include "video_stream_webm.h" +#include "../mono_gd/gd_mono_marshal.h" +#include "arguments_vector.h" -static Ref<ResourceFormatLoaderWebm> resource_loader_webm; +MonoObject *godot_icall_Callable_Call(GDMonoMarshal::M_Callable *p_callable, MonoArray *p_args) { + Callable callable = GDMonoMarshal::managed_to_callable(*p_callable); -void register_webm_types() { - resource_loader_webm.instantiate(); - ResourceLoader::add_resource_format_loader(resource_loader_webm, true); + int argc = mono_array_length(p_args); - GDREGISTER_CLASS(VideoStreamWebm); + ArgumentsVector<Variant> arg_store(argc); + ArgumentsVector<const Variant *> args(argc); + + for (int i = 0; i < argc; i++) { + MonoObject *elem = mono_array_get(p_args, MonoObject *, i); + arg_store.set(i, GDMonoMarshal::mono_object_to_variant(elem)); + args.set(i, &arg_store.get(i)); + } + + Variant result; + Callable::CallError error; + callable.call(args.ptr(), argc, result, error); + + return GDMonoMarshal::variant_to_mono_object(result); +} + +void godot_icall_Callable_CallDeferred(GDMonoMarshal::M_Callable *p_callable, MonoArray *p_args) { + Callable callable = GDMonoMarshal::managed_to_callable(*p_callable); + + int argc = mono_array_length(p_args); + + ArgumentsVector<Variant> arg_store(argc); + ArgumentsVector<const Variant *> args(argc); + + for (int i = 0; i < argc; i++) { + MonoObject *elem = mono_array_get(p_args, MonoObject *, i); + arg_store.set(i, GDMonoMarshal::mono_object_to_variant(elem)); + args.set(i, &arg_store.get(i)); + } + + callable.call_deferred(args.ptr(), argc); } -void unregister_webm_types() { - ResourceLoader::remove_resource_format_loader(resource_loader_webm); - resource_loader_webm.unref(); +void godot_register_callable_icalls() { + GDMonoUtils::add_internal_call("Godot.Callable::godot_icall_Callable_Call", godot_icall_Callable_Call); + GDMonoUtils::add_internal_call("Godot.Callable::godot_icall_Callable_CallDeferred", godot_icall_Callable_CallDeferred); } + +#endif // MONO_GLUE_ENABLED diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp index 86976de244..56a08a0dd5 100644 --- a/modules/mono/glue/collections_glue.cpp +++ b/modules/mono/glue/collections_glue.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -144,7 +144,7 @@ void godot_icall_Array_Insert(Array *ptr, int32_t index, MonoObject *item) { MonoBoolean godot_icall_Array_Remove(Array *ptr, MonoObject *item) { int idx = ptr->find(GDMonoMarshal::mono_object_to_variant(item)); if (idx >= 0) { - ptr->remove(idx); + ptr->remove_at(idx); return true; } return false; @@ -155,7 +155,7 @@ void godot_icall_Array_RemoveAt(Array *ptr, int32_t index) { GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range()); return; } - ptr->remove(index); + ptr->remove_at(index); } int32_t godot_icall_Array_Resize(Array *ptr, int32_t new_size) { @@ -237,10 +237,8 @@ int32_t godot_icall_Dictionary_KeyValuePairs(Dictionary *ptr, Array **keys, Arra } void godot_icall_Dictionary_KeyValuePairAt(Dictionary *ptr, int index, MonoObject **key, MonoObject **value) { - Array *keys = godot_icall_Dictionary_Keys(ptr); - Array *values = godot_icall_Dictionary_Values(ptr); - *key = GDMonoMarshal::variant_to_mono_object(keys->get(index)); - *value = GDMonoMarshal::variant_to_mono_object(values->get(index)); + *key = GDMonoMarshal::variant_to_mono_object(ptr->get_key_at_index(index)); + *value = GDMonoMarshal::variant_to_mono_object(ptr->get_value_at_index(index)); } void godot_icall_Dictionary_Add(Dictionary *ptr, MonoObject *key, MonoObject *value) { diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp index a2ff868f65..8aead217cf 100644 --- a/modules/mono/glue/gd_glue.cpp +++ b/modules/mono/glue/gd_glue.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -182,26 +182,30 @@ void godot_icall_GD_printt(MonoArray *p_what) { print_line(str); } -float godot_icall_GD_randf() { - return Math::randf(); +void godot_icall_GD_randomize() { + Math::randomize(); } uint32_t godot_icall_GD_randi() { return Math::rand(); } -void godot_icall_GD_randomize() { - Math::randomize(); +float godot_icall_GD_randf() { + return Math::randf(); } -double godot_icall_GD_randf_range(double from, double to) { +int32_t godot_icall_GD_randi_range(int32_t from, int32_t to) { return Math::random(from, to); } -int32_t godot_icall_GD_randi_range(int32_t from, int32_t to) { +double godot_icall_GD_randf_range(double from, double to) { return Math::random(from, to); } +double godot_icall_GD_randfn(double mean, double deviation) { + return Math::randfn(mean, deviation); +} + uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed) { uint32_t ret = Math::rand_from_seed(&seed); *newSeed = seed; @@ -300,11 +304,12 @@ void godot_register_gd_icalls() { GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printraw", godot_icall_GD_printraw); GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_prints", godot_icall_GD_prints); GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printt", godot_icall_GD_printt); - GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf", godot_icall_GD_randf); - GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi", godot_icall_GD_randi); GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randomize", godot_icall_GD_randomize); - GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf_range", godot_icall_GD_randf_range); + GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi", godot_icall_GD_randi); + GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf", godot_icall_GD_randf); GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi_range", godot_icall_GD_randi_range); + GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf_range", godot_icall_GD_randf_range); + GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randfn", godot_icall_GD_randfn); GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_rand_seed", godot_icall_GD_rand_seed); GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_seed", godot_icall_GD_seed); GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_str", godot_icall_GD_str); diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h index eed3bd2167..9638b23410 100644 --- a/modules/mono/glue/glue_header.h +++ b/modules/mono/glue/glue_header.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,6 +36,7 @@ void godot_register_collections_icalls(); void godot_register_gd_icalls(); void godot_register_string_name_icalls(); void godot_register_nodepath_icalls(); +void godot_register_callable_icalls(); void godot_register_object_icalls(); void godot_register_rid_icalls(); void godot_register_string_icalls(); @@ -50,6 +51,7 @@ void godot_register_glue_header_icalls() { godot_register_gd_icalls(); godot_register_string_name_icalls(); godot_register_nodepath_icalls(); + godot_register_callable_icalls(); godot_register_object_icalls(); godot_register_rid_icalls(); godot_register_string_icalls(); diff --git a/modules/mono/glue/nodepath_glue.cpp b/modules/mono/glue/nodepath_glue.cpp index 4ddb94e1a8..0ea9814b1a 100644 --- a/modules/mono/glue/nodepath_glue.cpp +++ b/modules/mono/glue/nodepath_glue.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp index f464e63a81..3e09564539 100644 --- a/modules/mono/glue/rid_glue.cpp +++ b/modules/mono/glue/rid_glue.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/glue/scene_tree_glue.cpp b/modules/mono/glue/scene_tree_glue.cpp index 5a6fd69db8..c60e7c4869 100644 --- a/modules/mono/glue/scene_tree_glue.cpp +++ b/modules/mono/glue/scene_tree_glue.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp index bb80a836ad..fc6b13ceb3 100644 --- a/modules/mono/glue/string_glue.cpp +++ b/modules/mono/glue/string_glue.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/glue/string_name_glue.cpp b/modules/mono/glue/string_name_glue.cpp index f537896559..46d15316ba 100644 --- a/modules/mono/glue/string_name_glue.cpp +++ b/modules/mono/glue/string_name_glue.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/godotsharp_defs.h b/modules/mono/godotsharp_defs.h index 273dba52f9..e5f1abe8d7 100644 --- a/modules/mono/godotsharp_defs.h +++ b/modules/mono/godotsharp_defs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index 375ad413c4..02739f0480 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -122,7 +122,7 @@ public: private: _GodotSharpDirs() { - res_data_dir = "res://.godot/mono"; + res_data_dir = ProjectSettings::get_singleton()->get_project_data_path().plus_file("mono"); res_metadata_dir = res_data_dir.plus_file("metadata"); res_assemblies_base_dir = res_data_dir.plus_file("assemblies"); res_assemblies_dir = res_assemblies_base_dir.plus_file(GDMono::get_expected_api_build_config()); @@ -229,9 +229,6 @@ private: #endif } - _GodotSharpDirs(const _GodotSharpDirs &); - _GodotSharpDirs &operator=(const _GodotSharpDirs &); - public: static _GodotSharpDirs &get_singleton() { static _GodotSharpDirs singleton; diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h index 3a3c6f980e..da25e0778f 100644 --- a/modules/mono/godotsharp_dirs.h +++ b/modules/mono/godotsharp_dirs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp index 6d868b527c..8ed21c323f 100644 --- a/modules/mono/managed_callable.cpp +++ b/modules/mono/managed_callable.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/managed_callable.h b/modules/mono/managed_callable.h index c620eee60d..ea7231f43b 100644 --- a/modules/mono/managed_callable.h +++ b/modules/mono/managed_callable.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp index 8583065016..f3dafa6ecf 100644 --- a/modules/mono/mono_gc_handle.cpp +++ b/modules/mono/mono_gc_handle.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h index d0e51d159f..ab9e508c99 100644 --- a/modules/mono/mono_gc_handle.h +++ b/modules/mono/mono_gc_handle.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -56,13 +56,12 @@ struct MonoGCHandleData { void release(); - MonoGCHandleData &operator=(const MonoGCHandleData &p_other) { + void operator=(const MonoGCHandleData &p_other) { #ifdef DEBUG_ENABLED CRASH_COND(!is_released()); #endif handle = p_other.handle; type = p_other.type; - return *this; } MonoGCHandleData(const MonoGCHandleData &) = default; diff --git a/modules/mono/mono_gd/android_mono_config.h b/modules/mono/mono_gd/android_mono_config.h index 9d7cfe1b7c..9ee4bcf590 100644 --- a/modules/mono/mono_gd/android_mono_config.h +++ b/modules/mono/mono_gd/android_mono_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 1b1349a3a3..6f542a67e7 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -151,7 +151,7 @@ void gd_mono_debug_init() { if (da_args.length() == 0) { da_args = String("--debugger-agent=transport=dt_socket,address=127.0.0.1:" + itos(da_port) + - ",embedding=1,server=y,suspend=" + (da_suspend ? "y,timeout=" + itos(da_timeout) : "n")) + ",embedding=1,server=y,suspend=" + (da_suspend ? "y,timeout=" + itos(da_timeout) : "n")) .utf8(); } #else @@ -504,7 +504,7 @@ void GDMono::_init_godot_api_hashes() { } void GDMono::_init_exception_policy() { - PropertyInfo exc_policy_prop = PropertyInfo(Variant::INT, "mono/unhandled_exception_policy", PROPERTY_HINT_ENUM, + PropertyInfo exc_policy_prop = PropertyInfo(Variant::INT, "mono/runtime/unhandled_exception_policy", PROPERTY_HINT_ENUM, vformat("Terminate Application:%s,Log Error:%s", (int)POLICY_TERMINATE_APP, (int)POLICY_LOG_ERROR)); unhandled_exception_policy = (UnhandledExceptionPolicy)(int)GLOBAL_DEF(exc_policy_prop.name, (int)POLICY_TERMINATE_APP); ProjectSettings::get_singleton()->set_custom_property_info(exc_policy_prop.name, exc_policy_prop); @@ -592,9 +592,9 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMonoAssembly *p_api_assembly, ApiAssemblyInfo::Type p_api_type) { ApiAssemblyInfo::Version api_assembly_version; - const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE ? - BINDINGS_CLASS_NATIVECALLS : - BINDINGS_CLASS_NATIVECALLS_EDITOR; + const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE + ? BINDINGS_CLASS_NATIVECALLS + : BINDINGS_CLASS_NATIVECALLS_EDITOR; GDMonoClass *nativecalls_klass = p_api_assembly->get_class(BINDINGS_NAMESPACE, nativecalls_name); @@ -702,11 +702,11 @@ static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool } r_out_of_sync = GodotSharpBindings::get_bindings_version() != (uint32_t)cfg->get_value("core", "bindings_version") || - GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("core", "cs_glue_version") || - GodotSharpBindings::get_bindings_version() != (uint32_t)cfg->get_value("editor", "bindings_version") || - GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("editor", "cs_glue_version") || - GodotSharpBindings::get_core_api_hash() != (uint64_t)cfg->get_value("core", "api_hash") || - GodotSharpBindings::get_editor_api_hash() != (uint64_t)cfg->get_value("editor", "api_hash"); + GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("core", "cs_glue_version") || + GodotSharpBindings::get_bindings_version() != (uint32_t)cfg->get_value("editor", "bindings_version") || + GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("editor", "cs_glue_version") || + GodotSharpBindings::get_core_api_hash() != (uint64_t)cfg->get_value("core", "api_hash") || + GodotSharpBindings::get_editor_api_hash() != (uint64_t)cfg->get_value("editor", "api_hash"); return true; } @@ -754,14 +754,10 @@ bool GDMono::_temp_domain_load_are_assemblies_out_of_sync(const String &p_config } String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync, const bool *p_editor_api_out_of_sync) { -#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \ - ( \ - (m_out_of_sync ? \ - String("The assembly is invalidated ") : \ - String("The assembly was not found ")) + \ - (m_prebuilt_exists ? \ - String("and the prebuilt assemblies are missing.") : \ - String("and we failed to copy the prebuilt assemblies."))) +#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \ + ( \ + (m_out_of_sync ? String("The assembly is invalidated ") : String("The assembly was not found ")) + \ + (m_prebuilt_exists ? String("and the prebuilt assemblies are missing.") : String("and we failed to copy the prebuilt assemblies."))) String dst_assemblies_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config); @@ -819,14 +815,14 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date // If running the project manager, load it from the prebuilt API directory - String assembly_dir = !Main::is_project_manager() ? - GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : - GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); + String assembly_dir = !Main::is_project_manager() + ? GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) + : GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String assembly_path = assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); bool success = FileAccess::exists(assembly_path) && - load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); + load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); #else bool success = load_assembly(CORE_API_ASSEMBLY_NAME, &r_loaded_api_assembly.assembly, p_refonly); #endif @@ -834,8 +830,8 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c if (success) { ApiAssemblyInfo::Version api_assembly_ver = ApiAssemblyInfo::Version::get_from_loaded_assembly(r_loaded_api_assembly.assembly, ApiAssemblyInfo::API_CORE); r_loaded_api_assembly.out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash || - GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || - GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; + GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; } else { r_loaded_api_assembly.out_of_sync = false; } @@ -852,20 +848,20 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date // If running the project manager, load it from the prebuilt API directory - String assembly_dir = !Main::is_project_manager() ? - GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : - GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); + String assembly_dir = !Main::is_project_manager() + ? GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) + : GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); bool success = FileAccess::exists(assembly_path) && - load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); + load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); if (success) { ApiAssemblyInfo::Version api_assembly_ver = ApiAssemblyInfo::Version::get_from_loaded_assembly(r_loaded_api_assembly.assembly, ApiAssemblyInfo::API_EDITOR); r_loaded_api_assembly.out_of_sync = GodotSharpBindings::get_editor_api_hash() != api_assembly_ver.godot_api_hash || - GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || - GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; + GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; } else { r_loaded_api_assembly.out_of_sync = false; } @@ -985,7 +981,7 @@ bool GDMono::_load_tools_assemblies() { } bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) && - load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly); + load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly); return success; } @@ -1363,8 +1359,8 @@ int32_t GodotSharp::get_scripts_domain_id() { bool GodotSharp::is_scripts_domain_loaded() { return GDMono::get_singleton() != nullptr && - GDMono::get_singleton()->is_runtime_initialized() && - GDMono::get_singleton()->get_scripts_domain() != nullptr; + GDMono::get_singleton()->is_runtime_initialized() && + GDMono::get_singleton()->get_scripts_domain() != nullptr; } bool GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 4170e5053f..aab0b31c37 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,8 +54,8 @@ struct Version { bool operator==(const Version &p_other) const { return godot_api_hash == p_other.godot_api_hash && - bindings_version == p_other.bindings_version && - cs_glue_version == p_other.cs_glue_version; + bindings_version == p_other.bindings_version && + cs_glue_version == p_other.cs_glue_version; } Version() {} diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 67f38bf127..3991b14612 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h index 6191c491f4..b25d773be7 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.h +++ b/modules/mono/mono_gd/gd_mono_assembly.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index 2bf55493e0..d8fd244067 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -177,6 +177,8 @@ void CachedData::clear_godot_api_cache() { methodthunk_MarshalUtils_TypeIsGenericICollection.nullify(); methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify(); + methodthunk_MarshalUtils_GetGenericTypeDefinition.nullify(); + methodthunk_MarshalUtils_ArrayGetElementType.nullify(); methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify(); @@ -299,6 +301,8 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GetGenericTypeDefinition, GODOT_API_CLASS(MarshalUtils)->get_method("GetGenericTypeDefinition", 2)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 4b4688b4d9..49f47b0a15 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -148,6 +148,8 @@ struct CachedData { GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection; GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary; + GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GetGenericTypeDefinition; + GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType; GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes; diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 27b4ac7fa7..89c37e087b 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -187,7 +187,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base #ifdef DEBUG_ENABLED String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")"; WARN_PRINT("Method '" + fullname + "' is hidden by Godot API method. Should be '" + - method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'."); + method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'."); #endif continue; } @@ -205,7 +205,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base // found String fullname = m->get_ret_type_full_name() + " " + name + "(" + m->get_signature_desc(true) + ")"; WARN_PRINT("Method '" + fullname + "' should be '" + m->get_full_name_no_class() + - "'. In class '" + namespace_name + "." + class_name + "'."); + "'. In class '" + namespace_name + "." + class_name + "'."); break; } @@ -464,9 +464,18 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() { return delegates_list; } + // If the class is generic we must use the generic type definition. + MonoClass *klass = mono_class; + if (mono_type_get_type(get_mono_type()) == MONO_TYPE_GENERICINST) { + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), get_mono_type()); + GDMonoUtils::Marshal::get_generic_type_definition(reftype, &reftype); + MonoType *type = mono_reflection_type_get_type(reftype); + klass = mono_class_from_mono_type(type); + } + void *iter = nullptr; MonoClass *raw_class = nullptr; - while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != nullptr) { + while ((raw_class = mono_class_get_nested_types(klass, &iter)) != nullptr) { if (mono_class_is_delegate(raw_class)) { StringName name = String::utf8(mono_class_get_name(raw_class)); diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index daea75bae8..bfb5797d4b 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 111eaa0bbf..333a06c94a 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h index ed5078c673..abcdef378c 100644 --- a/modules/mono/mono_gd/gd_mono_field.h +++ b/modules/mono/mono_gd/gd_mono_field.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h index 483030610f..bf21283080 100644 --- a/modules/mono/mono_gd/gd_mono_header.h +++ b/modules/mono/mono_gd/gd_mono_header.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index cf76c23926..d206b0dfc3 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h index 26eb270eee..a8f9cfa3ca 100644 --- a/modules/mono/mono_gd/gd_mono_internals.h +++ b/modules/mono/mono_gd/gd_mono_internals.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index 179bbfb40c..01a6521876 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -121,12 +121,10 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) { ERR_FAIL_COND(da->list_dir_begin() != OK); - String current; - while ((current = da->get_next()).length()) { - if (da->current_is_dir()) { - continue; - } - if (!current.ends_with(".txt")) { + String current = da->get_next(); + while (!current.is_empty()) { + if (da->current_is_dir() || !current.ends_with(".txt")) { + current = da->get_next(); continue; } @@ -135,6 +133,7 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) { if (OS::get_singleton()->get_unix_time() - modified_time > MAX_SECS) { da->remove(current); } + current = da->get_next(); } da->list_dir_end(); diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h index 9ddbd251ac..9aa67a09e2 100644 --- a/modules/mono/mono_gd/gd_mono_log.h +++ b/modules/mono/mono_gd/gd_mono_log.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index c9789bf270..957abca37b 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -139,49 +139,65 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { - MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); + MonoClass *elem_class = mono_class_get_element_class(p_type.type_class->get_mono_ptr()); - if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { + if (elem_class == CACHED_CLASS_RAW(MonoObject)) { return Variant::ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { + if (elem_class == CACHED_CLASS_RAW(uint8_t)) { return Variant::PACKED_BYTE_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { + if (elem_class == CACHED_CLASS_RAW(int32_t)) { return Variant::PACKED_INT32_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { + if (elem_class == CACHED_CLASS_RAW(int64_t)) { return Variant::PACKED_INT64_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(float)) { + if (elem_class == CACHED_CLASS_RAW(float)) { return Variant::PACKED_FLOAT32_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(double)) { + if (elem_class == CACHED_CLASS_RAW(double)) { return Variant::PACKED_FLOAT64_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(String)) { + if (elem_class == CACHED_CLASS_RAW(String)) { return Variant::PACKED_STRING_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { + if (elem_class == CACHED_CLASS_RAW(Vector2)) { return Variant::PACKED_VECTOR2_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { + if (elem_class == CACHED_CLASS_RAW(Vector3)) { return Variant::PACKED_VECTOR3_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(Color)) { + if (elem_class == CACHED_CLASS_RAW(Color)) { return Variant::PACKED_COLOR_ARRAY; } - GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (elem_class == CACHED_CLASS_RAW(StringName)) { + return Variant::ARRAY; + } + + if (elem_class == CACHED_CLASS_RAW(NodePath)) { + return Variant::ARRAY; + } + + if (elem_class == CACHED_CLASS_RAW(RID)) { + return Variant::ARRAY; + } + + if (mono_class_is_enum(elem_class)) { + return Variant::ARRAY; + } + + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(elem_class); if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return Variant::ARRAY; } @@ -266,6 +282,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { return Variant::ARRAY; } + + // GodotObject + GDMonoClass *type_class = p_type.type_class; + if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { + return Variant::OBJECT; + } } break; default: { @@ -284,9 +306,8 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_ switch (p_array_type.type_encoding) { case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { - MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type()); - GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); - r_elem_type = ManagedType::from_class(array_type_class); + MonoClass *elem_class = mono_class_get_element_class(p_array_type.type_class->get_mono_ptr()); + r_elem_type = ManagedType::from_class(elem_class); return true; } break; case MONO_TYPE_GENERICINST: { @@ -361,12 +382,23 @@ MonoArray *variant_to_mono_array(const Variant &p_var, GDMonoClass *p_type_class return PackedColorArray_to_mono_array(p_var.operator PackedColorArray()); } + if (array_type->eklass == CACHED_CLASS_RAW(StringName)) { + return Array_to_mono_array(p_var.operator Array()); + } + + if (array_type->eklass == CACHED_CLASS_RAW(NodePath)) { + return Array_to_mono_array(p_var.operator Array()); + } + + if (array_type->eklass == CACHED_CLASS_RAW(RID)) { + return Array_to_mono_array(p_var.operator Array()); + } + if (mono_class_is_assignable_from(CACHED_CLASS(GodotObject)->get_mono_ptr(), array_type->eklass)) { return Array_to_mono_array(p_var.operator ::Array(), array_type->eklass); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to array of unsupported element type:" + - GDMonoClass::get_full_name(array_type->eklass) + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to array of unsupported element type:" + GDMonoClass::get_full_name(array_type->eklass) + "'."); } MonoObject *variant_to_mono_object_of_class(const Variant &p_var, GDMonoClass *p_type_class) { @@ -399,8 +431,7 @@ MonoObject *variant_to_mono_object_of_class(const Variant &p_var, GDMonoClass *p return GDMonoUtils::create_managed_from(p_var.operator Array(), CACHED_CLASS(Array)); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type: '" + - p_type_class->get_full_name() + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type: '" + p_type_class->get_full_name() + "'."); } MonoObject *variant_to_mono_object_of_genericinst(const Variant &p_var, GDMonoClass *p_type_class) { @@ -450,8 +481,12 @@ MonoObject *variant_to_mono_object_of_genericinst(const Variant &p_var, GDMonoCl return GDMonoUtils::create_managed_from(p_var.operator Array(), godot_array_class); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported generic type: '" + - p_type_class->get_full_name() + "'."); + // GodotObject + if (CACHED_CLASS(GodotObject)->is_assignable_from(p_type_class)) { + return GDMonoUtils::unmanaged_get_managed(p_var.operator Object *()); + } + + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported generic type: '" + p_type_class->get_full_name() + "'."); } MonoObject *variant_to_mono_object(const Variant &p_var) { @@ -786,14 +821,12 @@ void *variant_to_managed_unboxed(const Variant &p_var, const ManagedType &p_type RETURN_TYPE_VAL(uint64_t, val); } default: { - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" + - GDMonoClass::get_full_name(mono_class_from_mono_type(enum_basetype)) + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" + GDMonoClass::get_full_name(mono_class_from_mono_type(enum_basetype)) + "'."); } } } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" + - p_type.type_class->get_full_name() + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" + p_type.type_class->get_full_name() + "'."); } break; #undef RETURN_TYPE_VAL case MONO_TYPE_STRING: @@ -809,8 +842,7 @@ void *variant_to_managed_unboxed(const Variant &p_var, const ManagedType &p_type return variant_to_mono_object(p_var); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " + - itos(p_type.type_encoding) + "."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " + itos(p_type.type_encoding) + "."); } MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_type) { @@ -943,14 +975,12 @@ MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_ty return BOX_ENUM(enum_baseclass, val); } default: { - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" + - GDMonoClass::get_full_name(enum_baseclass) + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" + GDMonoClass::get_full_name(enum_baseclass) + "'."); } } } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" + - p_type.type_class->get_full_name() + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" + p_type.type_class->get_full_name() + "'."); } break; case MONO_TYPE_STRING: return (MonoObject *)variant_to_mono_string(p_var); @@ -965,8 +995,7 @@ MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_ty return variant_to_mono_object(p_var); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " + - itos(p_type.type_encoding) + "."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " + itos(p_type.type_encoding) + "."); } Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type, bool p_fail_with_err = true) { @@ -1118,6 +1147,18 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return mono_array_to_PackedColorArray((MonoArray *)p_obj); } + if (array_type->eklass == CACHED_CLASS_RAW(StringName)) { + return mono_array_to_Array((MonoArray *)p_obj); + } + + if (array_type->eklass == CACHED_CLASS_RAW(NodePath)) { + return mono_array_to_Array((MonoArray *)p_obj); + } + + if (array_type->eklass == CACHED_CLASS_RAW(RID)) { + return mono_array_to_Array((MonoArray *)p_obj); + } + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return mono_array_to_Array((MonoArray *)p_obj); @@ -1206,12 +1247,22 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); return system_generic_list_to_Array_variant(p_obj, p_type.type_class, elem_reftype); } + + // GodotObject + GDMonoClass *type_class = p_type.type_class; + if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { + Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj)); + if (ptr != nullptr) { + RefCounted *rc = Object::cast_to<RefCounted>(ptr); + return rc ? Variant(Ref<RefCounted>(rc)) : Variant(ptr); + } + return Variant(); + } } break; } if (p_fail_with_err) { - ERR_FAIL_V_MSG(Variant(), "Attempted to convert an unmarshallable managed type to Variant. Name: '" + - p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + "."); + ERR_FAIL_V_MSG(Variant(), "Attempted to convert an unmarshallable managed type to Variant. Name: '" + p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + "."); } else { return Variant(); } @@ -1271,7 +1322,7 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) + - ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; + ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true); CRASH_COND(ctor == nullptr); @@ -1293,7 +1344,7 @@ MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoCl Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype); String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) + - ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; + ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; GDMonoMethod *godot_dict_ctor = godot_dict_class->get_method_with_desc(ctor_desc, true); CRASH_COND(godot_dict_ctor == nullptr); @@ -1315,7 +1366,6 @@ Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype) { MonoType *elem_type = mono_reflection_type_get_type(p_elem_reftype); - MonoClass *elem_class = mono_class_from_mono_type(elem_type); String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + GDMonoUtils::get_type_desc(elem_type) + ">)"; GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true); @@ -1324,7 +1374,10 @@ MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_cl MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, nullptr); - void *ctor_args[1] = { Array_to_mono_array(p_array, elem_class) }; + GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(p_elem_reftype); + MonoObject *godot_array = GDMonoUtils::create_managed_from(p_array, godot_array_class); + + void *ctor_args[1] = { godot_array }; MonoException *exc = nullptr; ctor->invoke_raw(mono_object, ctor_args, &exc); @@ -1683,12 +1736,12 @@ Callable managed_to_callable(const M_Callable &p_managed_callable) { CallableCustom *managed_callable = memnew(ManagedCallable(p_managed_callable.delegate)); return Callable(managed_callable); } else { - Object *target = p_managed_callable.target ? - unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) : - nullptr; - StringName *method_ptr = p_managed_callable.method_string_name ? - unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name)) : - nullptr; + Object *target = p_managed_callable.target + ? unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) + : nullptr; + StringName *method_ptr = p_managed_callable.method_string_name + ? unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name)) + : nullptr; StringName method = method_ptr ? *method_ptr : StringName(); return Callable(target, method); } @@ -1731,12 +1784,12 @@ M_Callable callable_to_managed(const Callable &p_callable) { } Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal) { - Object *owner = p_managed_signal.owner ? - unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) : - nullptr; - StringName *name_ptr = p_managed_signal.name_string_name ? - unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name)) : - nullptr; + Object *owner = p_managed_signal.owner + ? unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) + : nullptr; + StringName *name_ptr = p_managed_signal.name_string_name + ? unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name)) + : nullptr; StringName name = name_ptr ? *name_ptr : StringName(); return Signal(owner, name); } diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 88afc7ebc5..20d4743e5c 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -234,58 +234,58 @@ enum { #endif MATCHES_Vector2 = (MATCHES_real_t && (sizeof(Vector2) == (sizeof(real_t) * 2)) && - offsetof(Vector2, x) == (sizeof(real_t) * 0) && - offsetof(Vector2, y) == (sizeof(real_t) * 1)), + offsetof(Vector2, x) == (sizeof(real_t) * 0) && + offsetof(Vector2, y) == (sizeof(real_t) * 1)), MATCHES_Vector2i = (MATCHES_int && (sizeof(Vector2i) == (sizeof(int32_t) * 2)) && - offsetof(Vector2i, x) == (sizeof(int32_t) * 0) && - offsetof(Vector2i, y) == (sizeof(int32_t) * 1)), + offsetof(Vector2i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector2i, y) == (sizeof(int32_t) * 1)), MATCHES_Rect2 = (MATCHES_Vector2 && (sizeof(Rect2) == (sizeof(Vector2) * 2)) && - offsetof(Rect2, position) == (sizeof(Vector2) * 0) && - offsetof(Rect2, size) == (sizeof(Vector2) * 1)), + offsetof(Rect2, position) == (sizeof(Vector2) * 0) && + offsetof(Rect2, size) == (sizeof(Vector2) * 1)), MATCHES_Rect2i = (MATCHES_Vector2i && (sizeof(Rect2i) == (sizeof(Vector2i) * 2)) && - offsetof(Rect2i, position) == (sizeof(Vector2i) * 0) && - offsetof(Rect2i, size) == (sizeof(Vector2i) * 1)), + offsetof(Rect2i, position) == (sizeof(Vector2i) * 0) && + offsetof(Rect2i, size) == (sizeof(Vector2i) * 1)), MATCHES_Transform2D = (MATCHES_Vector2 && (sizeof(Transform2D) == (sizeof(Vector2) * 3))), // No field offset required, it stores an array MATCHES_Vector3 = (MATCHES_real_t && (sizeof(Vector3) == (sizeof(real_t) * 3)) && - offsetof(Vector3, x) == (sizeof(real_t) * 0) && - offsetof(Vector3, y) == (sizeof(real_t) * 1) && - offsetof(Vector3, z) == (sizeof(real_t) * 2)), + offsetof(Vector3, x) == (sizeof(real_t) * 0) && + offsetof(Vector3, y) == (sizeof(real_t) * 1) && + offsetof(Vector3, z) == (sizeof(real_t) * 2)), MATCHES_Vector3i = (MATCHES_int && (sizeof(Vector3i) == (sizeof(int32_t) * 3)) && - offsetof(Vector3i, x) == (sizeof(int32_t) * 0) && - offsetof(Vector3i, y) == (sizeof(int32_t) * 1) && - offsetof(Vector3i, z) == (sizeof(int32_t) * 2)), + offsetof(Vector3i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector3i, y) == (sizeof(int32_t) * 1) && + offsetof(Vector3i, z) == (sizeof(int32_t) * 2)), MATCHES_Basis = (MATCHES_Vector3 && (sizeof(Basis) == (sizeof(Vector3) * 3))), // No field offset required, it stores an array MATCHES_Quaternion = (MATCHES_real_t && (sizeof(Quaternion) == (sizeof(real_t) * 4)) && - offsetof(Quaternion, x) == (sizeof(real_t) * 0) && - offsetof(Quaternion, y) == (sizeof(real_t) * 1) && - offsetof(Quaternion, z) == (sizeof(real_t) * 2) && - offsetof(Quaternion, w) == (sizeof(real_t) * 3)), + offsetof(Quaternion, x) == (sizeof(real_t) * 0) && + offsetof(Quaternion, y) == (sizeof(real_t) * 1) && + offsetof(Quaternion, z) == (sizeof(real_t) * 2) && + offsetof(Quaternion, w) == (sizeof(real_t) * 3)), MATCHES_Transform3D = (MATCHES_Basis && MATCHES_Vector3 && (sizeof(Transform3D) == (sizeof(Basis) + sizeof(Vector3))) && - offsetof(Transform3D, basis) == 0 && - offsetof(Transform3D, origin) == sizeof(Basis)), + offsetof(Transform3D, basis) == 0 && + offsetof(Transform3D, origin) == sizeof(Basis)), MATCHES_AABB = (MATCHES_Vector3 && (sizeof(AABB) == (sizeof(Vector3) * 2)) && - offsetof(AABB, position) == (sizeof(Vector3) * 0) && - offsetof(AABB, size) == (sizeof(Vector3) * 1)), + offsetof(AABB, position) == (sizeof(Vector3) * 0) && + offsetof(AABB, size) == (sizeof(Vector3) * 1)), MATCHES_Color = (MATCHES_float && (sizeof(Color) == (sizeof(float) * 4)) && - offsetof(Color, r) == (sizeof(float) * 0) && - offsetof(Color, g) == (sizeof(float) * 1) && - offsetof(Color, b) == (sizeof(float) * 2) && - offsetof(Color, a) == (sizeof(float) * 3)), + offsetof(Color, r) == (sizeof(float) * 0) && + offsetof(Color, g) == (sizeof(float) * 1) && + offsetof(Color, b) == (sizeof(float) * 2) && + offsetof(Color, a) == (sizeof(float) * 3)), MATCHES_Plane = (MATCHES_Vector3 && MATCHES_real_t && (sizeof(Plane) == (sizeof(Vector3) + sizeof(real_t))) && - offsetof(Plane, normal) == 0 && - offsetof(Plane, d) == sizeof(Vector3)) + offsetof(Plane, normal) == 0 && + offsetof(Plane, d) == sizeof(Vector3)) }; // In the future we may force this if we want to ref return these structs diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index 67aabcde10..6734b44783 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h index c08ffe904b..6e87a60ee2 100644 --- a/modules/mono/mono_gd/gd_mono_method.h +++ b/modules/mono/mono_gd/gd_mono_method.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_method_thunk.h b/modules/mono/mono_gd/gd_mono_method_thunk.h index 091d26df1d..bb163b89bc 100644 --- a/modules/mono/mono_gd/gd_mono_method_thunk.h +++ b/modules/mono/mono_gd/gd_mono_method_thunk.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp index 5391b7775e..c9775ae9cb 100644 --- a/modules/mono/mono_gd/gd_mono_property.cpp +++ b/modules/mono/mono_gd/gd_mono_property.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -65,6 +65,8 @@ GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_own type.type_class = GDMono::get_singleton()->get_class(param_type_class); } + param_buffer_size = GDMonoMarshal::variant_get_managed_unboxed_size(type); + attrs_fetched = false; attributes = nullptr; } @@ -147,24 +149,20 @@ bool GDMonoProperty::has_setter() { return mono_property_get_set_method(mono_property) != nullptr; } -void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc) { - MonoMethod *prop_method = mono_property_get_set_method(mono_property); - void *params[1] = { p_value }; - MonoException *exc = nullptr; - GDMonoUtils::runtime_invoke(prop_method, p_object, params, &exc); - if (exc) { - if (r_exc) { - *r_exc = exc; - } else { - GDMonoUtils::set_pending_exception(exc); - } - } -} +void GDMonoProperty::set_value_from_variant(MonoObject *p_object, const Variant &p_value, MonoException **r_exc) { + uint8_t *buffer = (uint8_t *)alloca(param_buffer_size); + unsigned int offset = 0; -void GDMonoProperty::set_value(MonoObject *p_object, void **p_params, MonoException **r_exc) { - MonoException *exc = nullptr; - GDMonoUtils::property_set_value(mono_property, p_object, p_params, &exc); + void *params[1] = { + GDMonoMarshal::variant_to_managed_unboxed(p_value, type, buffer, offset) + }; + +#ifdef DEBUG_ENABLED + CRASH_COND(offset != param_buffer_size); +#endif + MonoException *exc = nullptr; + GDMonoUtils::property_set_value(mono_property, p_object, params, &exc); if (exc) { if (r_exc) { *r_exc = exc; diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h index af7a2c02e5..003bcf05e1 100644 --- a/modules/mono/mono_gd/gd_mono_property.h +++ b/modules/mono/mono_gd/gd_mono_property.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -45,6 +45,8 @@ class GDMonoProperty : public IMonoClassMember { bool attrs_fetched; MonoCustomAttrInfo *attributes; + unsigned int param_buffer_size; + public: virtual GDMonoClass *get_enclosing_class() const final { return owner; } @@ -64,8 +66,7 @@ public: _FORCE_INLINE_ ManagedType get_type() const { return type; } - void set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc = nullptr); - void set_value(MonoObject *p_object, void **p_params, MonoException **r_exc = nullptr); + void set_value_from_variant(MonoObject *p_object, const Variant &p_value, MonoException **r_exc = nullptr); MonoObject *get_value(MonoObject *p_object, MonoException **r_exc = nullptr); bool get_bool_value(MonoObject *p_object); diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 13939bd014..a884bf4da0 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -450,7 +450,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { int line = si.size() ? si[0].line : __LINE__; String error_msg = "Unhandled exception"; - EngineDebugger::get_script_debugger()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si); + EngineDebugger::get_script_debugger()->send_error(func, file, line, error_msg, exc_msg, true, ERR_HANDLER_ERROR, si); #endif } @@ -614,6 +614,12 @@ bool type_is_generic_idictionary(MonoReflectionType *p_reftype) { return (bool)res; } +void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype) { + MonoException *exc = nullptr; + CACHED_METHOD_THUNK(MarshalUtils, GetGenericTypeDefinition).invoke(p_reftype, r_generic_reftype, &exc); + UNHANDLED_EXCEPTION(exc); +} + void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) { MonoException *exc = nullptr; CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc); diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 773501e93d..4c2c2c93c2 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -62,6 +62,8 @@ bool type_is_generic_ienumerable(MonoReflectionType *p_reftype); bool type_is_generic_icollection(MonoReflectionType *p_reftype); bool type_is_generic_idictionary(MonoReflectionType *p_reftype); +void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype); + void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype); void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); diff --git a/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp b/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp index a477c55456..dbfca2dc0c 100644 --- a/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp +++ b/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/gd_mono_wasm_m2n.h b/modules/mono/mono_gd/gd_mono_wasm_m2n.h index 366662ff81..68299aa984 100644 --- a/modules/mono/mono_gd/gd_mono_wasm_m2n.h +++ b/modules/mono/mono_gd/gd_mono_wasm_m2n.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -158,7 +158,7 @@ T m2n_arg_cast(Mono_InterpMethodArguments *p_margs, size_t p_idx) { return (T)(size_t)p_margs->iargs[p_idx]; } else if constexpr (cookie == 'L') { static_assert(std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t> || - (sizeof(void *) == 8 && std::is_pointer_v<T>), + (sizeof(void *) == 8 && std::is_pointer_v<T>), "Invalid type for cookie 'L'."); union { diff --git a/modules/mono/mono_gd/i_mono_class_member.h b/modules/mono/mono_gd/i_mono_class_member.h index 36e14ba27c..14e8ca82b9 100644 --- a/modules/mono/mono_gd/i_mono_class_member.h +++ b/modules/mono/mono_gd/i_mono_class_member.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/managed_type.cpp b/modules/mono/mono_gd/managed_type.cpp index 0acfafe841..5860d7db1e 100644 --- a/modules/mono/mono_gd/managed_type.cpp +++ b/modules/mono/mono_gd/managed_type.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/managed_type.h b/modules/mono/mono_gd/managed_type.h index 0456a9a864..603ff3aca1 100644 --- a/modules/mono/mono_gd/managed_type.h +++ b/modules/mono/mono_gd/managed_type.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/support/android_support.cpp b/modules/mono/mono_gd/support/android_support.cpp index c65353dfd1..eb8bbab948 100644 --- a/modules/mono/mono_gd/support/android_support.cpp +++ b/modules/mono/mono_gd/support/android_support.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/support/android_support.h b/modules/mono/mono_gd/support/android_support.h index 0c5dd2764c..073cd31c65 100644 --- a/modules/mono/mono_gd/support/android_support.h +++ b/modules/mono/mono_gd/support/android_support.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/support/ios_support.h b/modules/mono/mono_gd/support/ios_support.h index 28a8806d0e..2f444d5089 100644 --- a/modules/mono/mono_gd/support/ios_support.h +++ b/modules/mono/mono_gd/support/ios_support.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/mono_gd/support/ios_support.mm b/modules/mono/mono_gd/support/ios_support.mm index 23424fbaf9..e66b88db32 100644 --- a/modules/mono/mono_gd/support/ios_support.mm +++ b/modules/mono/mono_gd/support/ios_support.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp index 98e83335e9..531a4bb11f 100644 --- a/modules/mono/register_types.cpp +++ b/modules/mono/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/register_types.h b/modules/mono/register_types.h index 1a2ff004b5..12f7e36f02 100644 --- a/modules/mono/register_types.h +++ b/modules/mono/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp index 3aaf726fc8..315a9c29f6 100644 --- a/modules/mono/signal_awaiter_utils.cpp +++ b/modules/mono/signal_awaiter_utils.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h index e12ea45b3f..1a62f36625 100644 --- a/modules/mono/signal_awaiter_utils.h +++ b/modules/mono/signal_awaiter_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h index 4a220d89c8..2ca1a4cbf1 100644 --- a/modules/mono/utils/macros.h +++ b/modules/mono/utils/macros.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp index d0a27b27c1..f388661207 100644 --- a/modules/mono/utils/mono_reg_utils.cpp +++ b/modules/mono/utils/mono_reg_utils.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/utils/mono_reg_utils.h b/modules/mono/utils/mono_reg_utils.h index 0e617761ea..5be60d4930 100644 --- a/modules/mono/utils/mono_reg_utils.h +++ b/modules/mono/utils/mono_reg_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/osx_utils.cpp index f4216c8129..835c611709 100644 --- a/modules/mono/utils/osx_utils.cpp +++ b/modules/mono/utils/osx_utils.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/utils/osx_utils.h b/modules/mono/utils/osx_utils.h index 6704f19077..2f6c6dad51 100644 --- a/modules/mono/utils/osx_utils.h +++ b/modules/mono/utils/osx_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp index 64aec5d359..89851fc4d3 100644 --- a/modules/mono/utils/path_utils.cpp +++ b/modules/mono/utils/path_utils.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h index 82b8f95f49..a8cd8daf04 100644 --- a/modules/mono/utils/path_utils.h +++ b/modules/mono/utils/path_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp index 2fb5e446da..dd29299330 100644 --- a/modules/mono/utils/string_utils.cpp +++ b/modules/mono/utils/string_utils.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -139,24 +139,24 @@ bool is_csharp_keyword(const String &p_name) { // Reserved keywords return p_name == "abstract" || p_name == "as" || p_name == "base" || p_name == "bool" || - p_name == "break" || p_name == "byte" || p_name == "case" || p_name == "catch" || - p_name == "char" || p_name == "checked" || p_name == "class" || p_name == "const" || - p_name == "continue" || p_name == "decimal" || p_name == "default" || p_name == "delegate" || - p_name == "do" || p_name == "double" || p_name == "else" || p_name == "enum" || - p_name == "event" || p_name == "explicit" || p_name == "extern" || p_name == "false" || - p_name == "finally" || p_name == "fixed" || p_name == "float" || p_name == "for" || - p_name == "forech" || p_name == "goto" || p_name == "if" || p_name == "implicit" || - p_name == "in" || p_name == "int" || p_name == "interface" || p_name == "internal" || - p_name == "is" || p_name == "lock" || p_name == "long" || p_name == "namespace" || - p_name == "new" || p_name == "null" || p_name == "object" || p_name == "operator" || - p_name == "out" || p_name == "override" || p_name == "params" || p_name == "private" || - p_name == "protected" || p_name == "public" || p_name == "readonly" || p_name == "ref" || - p_name == "return" || p_name == "sbyte" || p_name == "sealed" || p_name == "short" || - p_name == "sizeof" || p_name == "stackalloc" || p_name == "static" || p_name == "string" || - p_name == "struct" || p_name == "switch" || p_name == "this" || p_name == "throw" || - p_name == "true" || p_name == "try" || p_name == "typeof" || p_name == "uint" || p_name == "ulong" || - p_name == "unchecked" || p_name == "unsafe" || p_name == "ushort" || p_name == "using" || - p_name == "virtual" || p_name == "volatile" || p_name == "void" || p_name == "while"; + p_name == "break" || p_name == "byte" || p_name == "case" || p_name == "catch" || + p_name == "char" || p_name == "checked" || p_name == "class" || p_name == "const" || + p_name == "continue" || p_name == "decimal" || p_name == "default" || p_name == "delegate" || + p_name == "do" || p_name == "double" || p_name == "else" || p_name == "enum" || + p_name == "event" || p_name == "explicit" || p_name == "extern" || p_name == "false" || + p_name == "finally" || p_name == "fixed" || p_name == "float" || p_name == "for" || + p_name == "forech" || p_name == "goto" || p_name == "if" || p_name == "implicit" || + p_name == "in" || p_name == "int" || p_name == "interface" || p_name == "internal" || + p_name == "is" || p_name == "lock" || p_name == "long" || p_name == "namespace" || + p_name == "new" || p_name == "null" || p_name == "object" || p_name == "operator" || + p_name == "out" || p_name == "override" || p_name == "params" || p_name == "private" || + p_name == "protected" || p_name == "public" || p_name == "readonly" || p_name == "ref" || + p_name == "return" || p_name == "sbyte" || p_name == "sealed" || p_name == "short" || + p_name == "sizeof" || p_name == "stackalloc" || p_name == "static" || p_name == "string" || + p_name == "struct" || p_name == "switch" || p_name == "this" || p_name == "throw" || + p_name == "true" || p_name == "try" || p_name == "typeof" || p_name == "uint" || p_name == "ulong" || + p_name == "unchecked" || p_name == "unsafe" || p_name == "ushort" || p_name == "using" || + p_name == "virtual" || p_name == "volatile" || p_name == "void" || p_name == "while"; } String escape_csharp_keyword(const String &p_name) { @@ -201,11 +201,11 @@ String str_format(const char *p_format, ...) { } #if defined(MINGW_ENABLED) -#define gd_vsnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf_s(m_buffer, m_count, _TRUNCATE, m_format, m_args_copy) -#define gd_vscprintf(m_format, m_args_copy) _vscprintf(m_format, m_args_copy) +#define RSnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf_s(m_buffer, m_count, _TRUNCATE, m_format, m_args_copy) +#define RScprintf(m_format, m_args_copy) _vscprintf(m_format, m_args_copy) #else -#define gd_vsnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf(m_buffer, m_count, m_format, m_args_copy) -#define gd_vscprintf(m_format, m_args_copy) vsnprintf(nullptr, 0, p_format, m_args_copy) +#define RSnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf(m_buffer, m_count, m_format, m_args_copy) +#define RScprintf(m_format, m_args_copy) vsnprintf(nullptr, 0, p_format, m_args_copy) #endif String str_format(const char *p_format, va_list p_list) { @@ -231,7 +231,7 @@ char *str_format_new(const char *p_format, va_list p_list) { va_list list; va_copy(list, p_list); - int len = gd_vscprintf(p_format, list); + int len = RScprintf(p_format, list); va_end(list); len += 1; // for the trailing '/0' @@ -239,7 +239,7 @@ char *str_format_new(const char *p_format, va_list p_list) { char *buffer(memnew_arr(char, len)); va_copy(list, p_list); - gd_vsnprintf(buffer, len, p_format, list); + RSnprintf(buffer, len, p_format, list); va_end(list); return buffer; diff --git a/modules/mono/utils/string_utils.h b/modules/mono/utils/string_utils.h index 3290cb38b9..d79888716a 100644 --- a/modules/mono/utils/string_utils.h +++ b/modules/mono/utils/string_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/msdfgen/register_types.cpp b/modules/msdfgen/register_types.cpp index ad60a66d2d..69855d93fe 100644 --- a/modules/msdfgen/register_types.cpp +++ b/modules/msdfgen/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/msdfgen/register_types.h b/modules/msdfgen/register_types.h index fb776c14ed..0e2fed2ce8 100644 --- a/modules/msdfgen/register_types.h +++ b/modules/msdfgen/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index f600f07c87..2b6ae5ef1e 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -150,8 +150,8 @@ COMMAND_2(map_set_active, RID, p_map, bool, p_active) { } else { int map_index = active_maps.find(map); ERR_FAIL_COND(map_index < 0); - active_maps.remove(map_index); - active_maps_update_id.remove(map_index); + active_maps.remove_at(map_index); + active_maps_update_id.remove_at(map_index); } } @@ -469,8 +469,8 @@ COMMAND_1(free, RID, p_object) { } int map_index = active_maps.find(map); - active_maps.remove(map_index); - active_maps_update_id.remove(map_index); + active_maps.remove_at(map_index); + active_maps_update_id.remove_at(map_index); map_owner.free(p_object); } else if (region_owner.owns(p_object)) { diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 65224493fd..6cc226b086 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 0c8f0ed8c9..b33b7933a8 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index 8e013a72eb..cd730fe3ef 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/nav_region.cpp b/modules/navigation/nav_region.cpp index 81b15a49f5..7d94e22014 100644 --- a/modules/navigation/nav_region.cpp +++ b/modules/navigation/nav_region.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/nav_region.h b/modules/navigation/nav_region.h index f8b067e638..c344414912 100644 --- a/modules/navigation/nav_region.h +++ b/modules/navigation/nav_region.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/nav_rid.h b/modules/navigation/nav_rid.h index a0a60a3643..2283973cac 100644 --- a/modules/navigation/nav_rid.h +++ b/modules/navigation/nav_rid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h index 35da391eea..2d725f214c 100644 --- a/modules/navigation/nav_utils.h +++ b/modules/navigation/nav_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/navigation_mesh_editor_plugin.cpp b/modules/navigation/navigation_mesh_editor_plugin.cpp index 587e56f593..6db3cbc1a3 100644 --- a/modules/navigation/navigation_mesh_editor_plugin.cpp +++ b/modules/navigation/navigation_mesh_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/navigation_mesh_editor_plugin.h b/modules/navigation/navigation_mesh_editor_plugin.h index c39269865b..6517a7be5b 100644 --- a/modules/navigation/navigation_mesh_editor_plugin.h +++ b/modules/navigation/navigation_mesh_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index bb6bc578a4..6cbdb645ca 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,6 +36,7 @@ #include "core/os/thread.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/mesh_instance_3d.h" +#include "scene/3d/multimesh_instance_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/box_shape_3d.h" #include "scene/resources/capsule_shape_3d.h" @@ -52,7 +53,8 @@ #include "editor/editor_settings.h" #endif -#include "modules/modules_enabled.gen.h" +#include "modules/modules_enabled.gen.h" // For csg, gridmap. + #ifdef MODULE_CSG_ENABLED #include "modules/csg/csg_shape.h" #endif @@ -62,17 +64,17 @@ NavigationMeshGenerator *NavigationMeshGenerator::singleton = nullptr; -void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) { - p_verticies.push_back(p_vec3.x); - p_verticies.push_back(p_vec3.y); - p_verticies.push_back(p_vec3.z); +void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices) { + p_vertices.push_back(p_vec3.x); + p_vertices.push_back(p_vec3.y); + p_vertices.push_back(p_vec3.z); } -void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { +void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices) { int current_vertex_count; for (int i = 0; i < p_mesh->get_surface_count(); i++) { - current_vertex_count = p_verticies.size() / 3; + current_vertex_count = p_vertices.size() / 3; if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { continue; @@ -99,7 +101,7 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform const int *ir = mesh_indices.ptr(); for (int j = 0; j < mesh_vertices.size(); j++) { - _add_vertex(p_xform.xform(vr[j]), p_verticies); + _add_vertex(p_xform.xform(vr[j]), p_vertices); } for (int j = 0; j < face_count; j++) { @@ -111,9 +113,9 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform } else { face_count = mesh_vertices.size() / 3; for (int j = 0; j < face_count; j++) { - _add_vertex(p_xform.xform(vr[j * 3 + 0]), p_verticies); - _add_vertex(p_xform.xform(vr[j * 3 + 2]), p_verticies); - _add_vertex(p_xform.xform(vr[j * 3 + 1]), p_verticies); + _add_vertex(p_xform.xform(vr[j * 3 + 0]), p_vertices); + _add_vertex(p_xform.xform(vr[j * 3 + 2]), p_vertices); + _add_vertex(p_xform.xform(vr[j * 3 + 1]), p_vertices); p_indices.push_back(current_vertex_count + (j * 3 + 0)); p_indices.push_back(current_vertex_count + (j * 3 + 1)); @@ -123,14 +125,14 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform } } -void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { +void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices) { int face_count = p_faces.size() / 3; - int current_vertex_count = p_verticies.size() / 3; + int current_vertex_count = p_vertices.size() / 3; for (int j = 0; j < face_count; j++) { - _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_verticies); - _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_verticies); - _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_verticies); + _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_vertices); + _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_vertices); + _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_vertices); p_indices.push_back(current_vertex_count + (j * 3 + 0)); p_indices.push_back(current_vertex_count + (j * 3 + 2)); @@ -138,12 +140,27 @@ void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, cons } } -void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) { +void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) { if (Object::cast_to<MeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) { MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_node); Ref<Mesh> mesh = mesh_instance->get_mesh(); if (mesh.is_valid()) { - _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_verticies, p_indices); + _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_vertices, p_indices); + } + } + + if (Object::cast_to<MultiMeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) { + MultiMeshInstance3D *multimesh_instance = Object::cast_to<MultiMeshInstance3D>(p_node); + Ref<MultiMesh> multimesh = multimesh_instance->get_multimesh(); + Ref<Mesh> mesh = multimesh->get_mesh(); + if (mesh.is_valid()) { + int n = multimesh->get_visible_instance_count(); + if (n == -1) { + n = multimesh->get_instance_count(); + } + for (int i = 0; i < n; i++) { + _add_mesh(mesh, p_accumulated_transform * multimesh->get_instance_transform(i), p_vertices, p_indices); + } } } @@ -154,7 +171,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor if (!meshes.is_empty()) { Ref<Mesh> mesh = meshes[1]; if (mesh.is_valid()) { - _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_verticies, p_indices); + _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_vertices, p_indices); } } } @@ -212,7 +229,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor ConcavePolygonShape3D *concave_polygon = Object::cast_to<ConcavePolygonShape3D>(*s); if (concave_polygon) { - _add_faces(concave_polygon->get_faces(), transform, p_verticies, p_indices); + _add_faces(concave_polygon->get_faces(), transform, p_vertices, p_indices); } ConvexPolygonShape3D *convex_polygon = Object::cast_to<ConvexPolygonShape3D>(*s); @@ -235,12 +252,12 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor } } - _add_faces(faces, transform, p_verticies, p_indices); + _add_faces(faces, transform, p_vertices, p_indices); } } if (mesh.is_valid()) { - _add_mesh(mesh, transform, p_verticies, p_indices); + _add_mesh(mesh, transform, p_vertices, p_indices); } } } @@ -255,7 +272,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor for (int i = 0; i < meshes.size(); i += 2) { Ref<Mesh> mesh = meshes[i + 1]; if (mesh.is_valid()) { - _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_verticies, p_indices); + _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices); } } } @@ -268,7 +285,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor if (p_recurse_children) { for (int i = 0; i < p_node->get_child_count(); i++) { - _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask, p_recurse_children); + _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_vertices, p_indices, p_generate_from, p_collision_mask, p_recurse_children); } } } @@ -489,7 +506,7 @@ NavigationMeshGenerator::~NavigationMeshGenerator() { } void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) { - ERR_FAIL_COND(!p_nav_mesh.is_valid()); + ERR_FAIL_COND_MSG(!p_nav_mesh.is_valid(), "Invalid navigation mesh."); #ifdef TOOLS_ENABLED EditorProgress *ep(nullptr); diff --git a/modules/navigation/navigation_mesh_generator.h b/modules/navigation/navigation_mesh_generator.h index 78f1329e3f..1ffdd39aee 100644 --- a/modules/navigation/navigation_mesh_generator.h +++ b/modules/navigation/navigation_mesh_generator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -49,10 +49,10 @@ class NavigationMeshGenerator : public Object { protected: static void _bind_methods(); - static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies); - static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices); - static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices); - static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children); + static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices); + static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices); + static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices); + static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children); static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh); static void _build_recast_navigation_mesh( diff --git a/modules/navigation/register_types.cpp b/modules/navigation/register_types.cpp index 97c01d42ab..e2264e843c 100644 --- a/modules/navigation/register_types.cpp +++ b/modules/navigation/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/register_types.h b/modules/navigation/register_types.h index 4737c818eb..11fa5769d7 100644 --- a/modules/navigation/register_types.h +++ b/modules/navigation/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/rvo_agent.cpp b/modules/navigation/rvo_agent.cpp index 21e43d08c1..6c38eaed0f 100644 --- a/modules/navigation/rvo_agent.cpp +++ b/modules/navigation/rvo_agent.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/navigation/rvo_agent.h b/modules/navigation/rvo_agent.h index 369cb1f9a3..2bf824186b 100644 --- a/modules/navigation/rvo_agent.h +++ b/modules/navigation/rvo_agent.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/ogg/SCsub b/modules/ogg/SCsub index e415d92498..f15525648f 100644 --- a/modules/ogg/SCsub +++ b/modules/ogg/SCsub @@ -3,9 +3,6 @@ Import("env") Import("env_modules") -# Only kept to build the thirdparty library used by the theora and webm -# modules. - env_ogg = env_modules.Clone() # Thirdparty source files diff --git a/modules/ogg/ogg_packet_sequence.cpp b/modules/ogg/ogg_packet_sequence.cpp index b7a3ad2876..65058f088e 100644 --- a/modules/ogg/ogg_packet_sequence.cpp +++ b/modules/ogg/ogg_packet_sequence.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -127,9 +127,9 @@ void OGGPacketSequence::_bind_methods() { ClassDB::bind_method(D_METHOD("get_length"), &OGGPacketSequence::get_length); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "packet_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_packet_data", "get_packet_data"); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "granule_positions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_packet_granule_positions", "get_packet_granule_positions"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sampling_rate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_sampling_rate", "get_sampling_rate"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "packet_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_data", "get_packet_data"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "granule_positions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_granule_positions", "get_packet_granule_positions"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sampling_rate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_sampling_rate", "get_sampling_rate"); } bool OGGPacketSequencePlayback::next_ogg_packet(ogg_packet **p_packet) const { diff --git a/modules/ogg/ogg_packet_sequence.h b/modules/ogg/ogg_packet_sequence.h index b00ada06c1..7e56b14a24 100644 --- a/modules/ogg/ogg_packet_sequence.h +++ b/modules/ogg/ogg_packet_sequence.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/ogg/register_types.cpp b/modules/ogg/register_types.cpp index 3448e7063a..3d04351032 100644 --- a/modules/ogg/register_types.cpp +++ b/modules/ogg/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/ogg/register_types.h b/modules/ogg/register_types.h index 49d5ed9c80..6ef7dc93ca 100644 --- a/modules/ogg/register_types.h +++ b/modules/ogg/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml index 8a10411cf6..16fea228b1 100644 --- a/modules/opensimplex/doc_classes/NoiseTexture.xml +++ b/modules/opensimplex/doc_classes/NoiseTexture.xml @@ -8,8 +8,9 @@ NoiseTexture can also generate normal map textures. The class uses [Thread]s to generate the texture data internally, so [method Texture2D.get_image] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the image and the generated byte data: [codeblock] - var texture = preload("res://noise.tres") - yield(texture, "changed") + var texture = NoiseTexture.new() + texture.noise = OpenSimplexNoise.new() + await texture.changed var image = texture.get_image() var data = image.get_data() [/codeblock] diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp index 9db3f3d5fd..f3342dfd84 100644 --- a/modules/opensimplex/noise_texture.cpp +++ b/modules/opensimplex/noise_texture.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -80,7 +80,7 @@ void NoiseTexture::_bind_methods() { void NoiseTexture::_validate_property(PropertyInfo &property) const { if (property.name == "bump_strength") { if (!as_normal_map) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; } } } diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h index 6237b6460d..ee8f88aaca 100644 --- a/modules/opensimplex/noise_texture.h +++ b/modules/opensimplex/noise_texture.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,9 +35,6 @@ #include "core/io/image.h" #include "core/object/ref_counted.h" -#include "editor/editor_node.h" -#include "editor/editor_plugin.h" -#include "editor/property_editor.h" class NoiseTexture : public Texture2D { GDCLASS(NoiseTexture, Texture2D); diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp index f0a8867284..b7c901fd06 100644 --- a/modules/opensimplex/open_simplex_noise.cpp +++ b/modules/opensimplex/open_simplex_noise.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/opensimplex/open_simplex_noise.h b/modules/opensimplex/open_simplex_noise.h index dcf922a8bf..c34f998b78 100644 --- a/modules/opensimplex/open_simplex_noise.h +++ b/modules/opensimplex/open_simplex_noise.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/opensimplex/register_types.cpp b/modules/opensimplex/register_types.cpp index d6f9f3436d..30dfdc3764 100644 --- a/modules/opensimplex/register_types.cpp +++ b/modules/opensimplex/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/opensimplex/register_types.h b/modules/opensimplex/register_types.h index d72e37e3a3..2262ab2f5e 100644 --- a/modules/opensimplex/register_types.h +++ b/modules/opensimplex/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/opus/SCsub b/modules/opus/SCsub deleted file mode 100644 index 1437cd86df..0000000000 --- a/modules/opus/SCsub +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -# Only kept to build the thirdparty library used by the webm module. -# AudioStreamOpus was dropped in 3.0 due to incompatibility with the new audio -# engine. If you want to port it, fetch it from the Git history. - -env_opus = env_modules.Clone() - -# Thirdparty source files - -thirdparty_obj = [] - -# Thirdparty source files -if env["builtin_opus"]: - thirdparty_dir = "#thirdparty/opus/" - - thirdparty_sources = [ - # Sync with opus_sources.mk - "opus.c", - "opus_decoder.c", - "opus_encoder.c", - "opus_multistream.c", - "opus_multistream_encoder.c", - "opus_multistream_decoder.c", - "repacketizer.c", - "analysis.c", - "mlp.c", - "mlp_data.c", - # Sync with libopusfile Makefile.am - "info.c", - "internal.c", - "opusfile.c", - "stream.c", - # Sync with celt_sources.mk - "celt/bands.c", - "celt/celt.c", - "celt/celt_encoder.c", - "celt/celt_decoder.c", - "celt/cwrs.c", - "celt/entcode.c", - "celt/entdec.c", - "celt/entenc.c", - "celt/kiss_fft.c", - "celt/laplace.c", - "celt/mathops.c", - "celt/mdct.c", - "celt/modes.c", - "celt/pitch.c", - "celt/celt_lpc.c", - "celt/quant_bands.c", - "celt/rate.c", - "celt/vq.c", - # "celt/arm/arm_celt_map.c", - # "celt/arm/armcpu.c", - # "celt/arm/celt_ne10_fft.c", - # "celt/arm/celt_ne10_mdct.c", - # "celt/arm/celt_neon_intr.c", - # Sync with silk_sources.mk - "silk/CNG.c", - "silk/code_signs.c", - "silk/init_decoder.c", - "silk/decode_core.c", - "silk/decode_frame.c", - "silk/decode_parameters.c", - "silk/decode_indices.c", - "silk/decode_pulses.c", - "silk/decoder_set_fs.c", - "silk/dec_API.c", - "silk/enc_API.c", - "silk/encode_indices.c", - "silk/encode_pulses.c", - "silk/gain_quant.c", - "silk/interpolate.c", - "silk/LP_variable_cutoff.c", - "silk/NLSF_decode.c", - "silk/NSQ.c", - "silk/NSQ_del_dec.c", - "silk/PLC.c", - "silk/shell_coder.c", - "silk/tables_gain.c", - "silk/tables_LTP.c", - "silk/tables_NLSF_CB_NB_MB.c", - "silk/tables_NLSF_CB_WB.c", - "silk/tables_other.c", - "silk/tables_pitch_lag.c", - "silk/tables_pulses_per_block.c", - "silk/VAD.c", - "silk/control_audio_bandwidth.c", - "silk/quant_LTP_gains.c", - "silk/VQ_WMat_EC.c", - "silk/HP_variable_cutoff.c", - "silk/NLSF_encode.c", - "silk/NLSF_VQ.c", - "silk/NLSF_unpack.c", - "silk/NLSF_del_dec_quant.c", - "silk/process_NLSFs.c", - "silk/stereo_LR_to_MS.c", - "silk/stereo_MS_to_LR.c", - "silk/check_control_input.c", - "silk/control_SNR.c", - "silk/init_encoder.c", - "silk/control_codec.c", - "silk/A2NLSF.c", - "silk/ana_filt_bank_1.c", - "silk/biquad_alt.c", - "silk/bwexpander_32.c", - "silk/bwexpander.c", - "silk/debug.c", - "silk/decode_pitch.c", - "silk/inner_prod_aligned.c", - "silk/lin2log.c", - "silk/log2lin.c", - "silk/LPC_analysis_filter.c", - "silk/LPC_inv_pred_gain.c", - "silk/table_LSF_cos.c", - "silk/NLSF2A.c", - "silk/NLSF_stabilize.c", - "silk/NLSF_VQ_weights_laroia.c", - "silk/pitch_est_tables.c", - "silk/resampler.c", - "silk/resampler_down2_3.c", - "silk/resampler_down2.c", - "silk/resampler_private_AR2.c", - "silk/resampler_private_down_FIR.c", - "silk/resampler_private_IIR_FIR.c", - "silk/resampler_private_up2_HQ.c", - "silk/resampler_rom.c", - "silk/sigm_Q15.c", - "silk/sort.c", - "silk/sum_sqr_shift.c", - "silk/stereo_decode_pred.c", - "silk/stereo_encode_pred.c", - "silk/stereo_find_predictor.c", - "silk/stereo_quant_pred.c", - ] - - opus_sources_silk = [] - - if env["platform"] in ["android", "iphone", "javascript"]: - env_opus.Append(CPPDEFINES=["FIXED_POINT"]) - opus_sources_silk = [ - "silk/fixed/LTP_analysis_filter_FIX.c", - "silk/fixed/LTP_scale_ctrl_FIX.c", - "silk/fixed/corrMatrix_FIX.c", - "silk/fixed/encode_frame_FIX.c", - "silk/fixed/find_LPC_FIX.c", - "silk/fixed/find_LTP_FIX.c", - "silk/fixed/find_pitch_lags_FIX.c", - "silk/fixed/find_pred_coefs_FIX.c", - "silk/fixed/noise_shape_analysis_FIX.c", - "silk/fixed/prefilter_FIX.c", - "silk/fixed/process_gains_FIX.c", - "silk/fixed/regularize_correlations_FIX.c", - "silk/fixed/residual_energy16_FIX.c", - "silk/fixed/residual_energy_FIX.c", - "silk/fixed/solve_LS_FIX.c", - "silk/fixed/warped_autocorrelation_FIX.c", - "silk/fixed/apply_sine_window_FIX.c", - "silk/fixed/autocorr_FIX.c", - "silk/fixed/burg_modified_FIX.c", - "silk/fixed/k2a_FIX.c", - "silk/fixed/k2a_Q16_FIX.c", - "silk/fixed/pitch_analysis_core_FIX.c", - "silk/fixed/vector_ops_FIX.c", - "silk/fixed/schur64_FIX.c", - "silk/fixed/schur_FIX.c", - ] - else: - opus_sources_silk = [ - "silk/float/apply_sine_window_FLP.c", - "silk/float/corrMatrix_FLP.c", - "silk/float/encode_frame_FLP.c", - "silk/float/find_LPC_FLP.c", - "silk/float/find_LTP_FLP.c", - "silk/float/find_pitch_lags_FLP.c", - "silk/float/find_pred_coefs_FLP.c", - "silk/float/LPC_analysis_filter_FLP.c", - "silk/float/LTP_analysis_filter_FLP.c", - "silk/float/LTP_scale_ctrl_FLP.c", - "silk/float/noise_shape_analysis_FLP.c", - "silk/float/prefilter_FLP.c", - "silk/float/process_gains_FLP.c", - "silk/float/regularize_correlations_FLP.c", - "silk/float/residual_energy_FLP.c", - "silk/float/solve_LS_FLP.c", - "silk/float/warped_autocorrelation_FLP.c", - "silk/float/wrappers_FLP.c", - "silk/float/autocorrelation_FLP.c", - "silk/float/burg_modified_FLP.c", - "silk/float/bwexpander_FLP.c", - "silk/float/energy_FLP.c", - "silk/float/inner_product_FLP.c", - "silk/float/k2a_FLP.c", - "silk/float/levinsondurbin_FLP.c", - "silk/float/LPC_inv_pred_gain_FLP.c", - "silk/float/pitch_analysis_core_FLP.c", - "silk/float/scale_copy_vector_FLP.c", - "silk/float/scale_vector_FLP.c", - "silk/float/schur_FLP.c", - "silk/float/sort_FLP.c", - ] - - thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources + opus_sources_silk] - - # also requires libogg - if env["builtin_libogg"]: - env_opus.Prepend(CPPPATH=["#thirdparty/libogg"]) - - env_opus.Append(CPPDEFINES=["HAVE_CONFIG_H"]) - - thirdparty_include_paths = [ - "", - "celt", - "opus", - "silk", - "silk/fixed", - "silk/float", - ] - env_opus.Prepend(CPPPATH=[thirdparty_dir + "/" + dir for dir in thirdparty_include_paths]) - - if env["platform"] == "android": - if "android_arch" in env and env["android_arch"] == "armv7": - env_opus.Append(CPPDEFINES=["OPUS_ARM_OPT"]) - elif "android_arch" in env and env["android_arch"] == "arm64v8": - env_opus.Append(CPPDEFINES=["OPUS_ARM64_OPT"]) - elif env["platform"] == "iphone": - if "arch" in env and env["arch"] == "arm": - env_opus.Append(CPPDEFINES=["OPUS_ARM_OPT"]) - elif "arch" in env and env["arch"] == "arm64": - env_opus.Append(CPPDEFINES=["OPUS_ARM64_OPT"]) - elif env["platform"] == "osx": - if "arch" in env and env["arch"] == "arm64": - env_opus.Append(CPPDEFINES=["OPUS_ARM64_OPT"]) - - env_thirdparty = env_opus.Clone() - env_thirdparty.disable_warnings() - env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) - env.modules_sources += thirdparty_obj - - -# Godot source files - -module_obj = [] - -env_opus.add_source_files(module_obj, "*.cpp") -env.modules_sources += module_obj - -# Needed to force rebuilding the module files when the thirdparty library is updated. -env.Depends(module_obj, thirdparty_obj) diff --git a/modules/opus/config.py b/modules/opus/config.py deleted file mode 100644 index 9ff7b2dece..0000000000 --- a/modules/opus/config.py +++ /dev/null @@ -1,6 +0,0 @@ -def can_build(env, platform): - return env.module_check_dependencies("opus", ["ogg"]) - - -def configure(env): - pass diff --git a/modules/opus/register_types.cpp b/modules/opus/register_types.cpp deleted file mode 100644 index 02874a9a4b..0000000000 --- a/modules/opus/register_types.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* register_types.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "register_types.h" - -// Dummy module as libvorbis is needed by other modules (theora ...) - -void register_opus_types() {} - -void unregister_opus_types() {} diff --git a/modules/opus/register_types.h b/modules/opus/register_types.h deleted file mode 100644 index af889cf809..0000000000 --- a/modules/opus/register_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* register_types.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef OPUS_REGISTER_TYPES_H -#define OPUS_REGISTER_TYPES_H - -void register_opus_types(); -void unregister_opus_types(); - -#endif // OPUS_REGISTER_TYPES_H diff --git a/modules/pvr/image_compress_pvrtc.cpp b/modules/pvr/image_compress_pvrtc.cpp index 980cac17d3..b996d910d5 100644 --- a/modules/pvr/image_compress_pvrtc.cpp +++ b/modules/pvr/image_compress_pvrtc.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/pvr/image_compress_pvrtc.h b/modules/pvr/image_compress_pvrtc.h index 985076ce4d..80edb81363 100644 --- a/modules/pvr/image_compress_pvrtc.h +++ b/modules/pvr/image_compress_pvrtc.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/pvr/register_types.cpp b/modules/pvr/register_types.cpp index ef72087d25..dcc7f505a1 100644 --- a/modules/pvr/register_types.cpp +++ b/modules/pvr/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/pvr/register_types.h b/modules/pvr/register_types.h index 74fcfe2ce4..faefb98678 100644 --- a/modules/pvr/register_types.h +++ b/modules/pvr/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index cb12976090..ff66a101ab 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -390,15 +390,15 @@ static void get_modulation_value(int x, int y, const int p_2bit, const int p_mod rep_vals0[p_modulation[y + 1][x]] + rep_vals0[p_modulation[y][x - 1]] + rep_vals0[p_modulation[y][x + 1]] + 2) / - 4; + 4; } else if (p_modulation_modes[y][x] == 2) { mod_val = (rep_vals0[p_modulation[y][x - 1]] + rep_vals0[p_modulation[y][x + 1]] + 1) / - 2; + 2; } else { mod_val = (rep_vals0[p_modulation[y - 1][x]] + rep_vals0[p_modulation[y + 1][x]] + 1) / - 2; + 2; } } else { mod_val = rep_vals1[p_modulation[y][x]]; diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h index 26071ce30f..06e8e91ba2 100644 --- a/modules/pvr/texture_loader_pvr.h +++ b/modules/pvr/texture_loader_pvr.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/raycast/config.py b/modules/raycast/config.py index 5de36c5322..7e8b3e9840 100644 --- a/modules/raycast/config.py +++ b/modules/raycast/config.py @@ -1,5 +1,7 @@ def can_build(env, platform): # Depends on Embree library, which only supports x86_64 and aarch64. + if env["arch"].startswith("rv") or env["arch"].startswith("ppc"): + return False if platform == "android": return env["android_arch"] in ["arm64v8", "x86_64"] diff --git a/modules/raycast/lightmap_raycaster.cpp b/modules/raycast/lightmap_raycaster.cpp index fdcf509da8..ecc256bff9 100644 --- a/modules/raycast/lightmap_raycaster.cpp +++ b/modules/raycast/lightmap_raycaster.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/raycast/lightmap_raycaster.h b/modules/raycast/lightmap_raycaster.h index 290b0a1cf3..c420e617e5 100644 --- a/modules/raycast/lightmap_raycaster.h +++ b/modules/raycast/lightmap_raycaster.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index 75491c98e5..dd5eef8b2b 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/raycast/raycast_occlusion_cull.h b/modules/raycast/raycast_occlusion_cull.h index ea96df5ff6..a22e52dd17 100644 --- a/modules/raycast/raycast_occlusion_cull.h +++ b/modules/raycast/raycast_occlusion_cull.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/raycast/register_types.cpp b/modules/raycast/register_types.cpp index ed99e635e1..053039a85b 100644 --- a/modules/raycast/register_types.cpp +++ b/modules/raycast/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/raycast/register_types.h b/modules/raycast/register_types.h index 789604a491..0abc5eb63a 100644 --- a/modules/raycast/register_types.h +++ b/modules/raycast/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/raycast/static_raycaster.cpp b/modules/raycast/static_raycaster.cpp index 2ba65eebf8..9df6d5ff43 100644 --- a/modules/raycast/static_raycaster.cpp +++ b/modules/raycast/static_raycaster.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/raycast/static_raycaster.h b/modules/raycast/static_raycaster.h index 6b13ecf690..cce19ba60d 100644 --- a/modules/raycast/static_raycaster.h +++ b/modules/raycast/static_raycaster.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/regex/config.py b/modules/regex/config.py index df9f44cb95..1248a8374d 100644 --- a/modules/regex/config.py +++ b/modules/regex/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return not env["arch"].startswith("rv") def configure(env): diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index 6bae12e7e6..ee1137b71f 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 68fe2bc6e0..a745c50a58 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/regex/register_types.cpp b/modules/regex/register_types.cpp index 03957f88cf..9289a724d8 100644 --- a/modules/regex/register_types.cpp +++ b/modules/regex/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/regex/register_types.h b/modules/regex/register_types.h index fe94cde954..b2d5009ef4 100644 --- a/modules/regex/register_types.h +++ b/modules/regex/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/regex/tests/test_regex.h b/modules/regex/tests/test_regex.h index c2d303b435..3f500e7b2f 100644 --- a/modules/regex/tests/test_regex.h +++ b/modules/regex/tests/test_regex.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/register_module_types.h b/modules/register_module_types.h index 2cff8c54c4..bc9aeb31ab 100644 --- a/modules/register_module_types.h +++ b/modules/register_module_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/squish/image_decompress_squish.cpp b/modules/squish/image_decompress_squish.cpp index 1450b0fe88..3a810e5259 100644 --- a/modules/squish/image_decompress_squish.cpp +++ b/modules/squish/image_decompress_squish.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/squish/image_decompress_squish.h b/modules/squish/image_decompress_squish.h index fff5839ac4..f1382b2610 100644 --- a/modules/squish/image_decompress_squish.h +++ b/modules/squish/image_decompress_squish.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/squish/register_types.cpp b/modules/squish/register_types.cpp index 51aab040e7..1dc2e11ab9 100644 --- a/modules/squish/register_types.cpp +++ b/modules/squish/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/squish/register_types.h b/modules/squish/register_types.h index 0f87d64333..ed1c6b0716 100644 --- a/modules/squish/register_types.h +++ b/modules/squish/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 4911346b96..bf43d7a4ad 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h index e64175b172..6052bf9831 100644 --- a/modules/svg/image_loader_svg.h +++ b/modules/svg/image_loader_svg.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/svg/register_types.cpp b/modules/svg/register_types.cpp index 1a611184d2..1560af95c3 100644 --- a/modules/svg/register_types.cpp +++ b/modules/svg/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/svg/register_types.h b/modules/svg/register_types.h index 106ac9056f..11fd9e7007 100644 --- a/modules/svg/register_types.h +++ b/modules/svg/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub index 7cd4db6f67..d6a96282f3 100644 --- a/modules/text_server_adv/SCsub +++ b/modules/text_server_adv/SCsub @@ -7,7 +7,6 @@ env_text_server_adv = env_modules.Clone() def make_icu_data(target, source, env): - import os dst = target[0].srcnode().abspath @@ -24,7 +23,6 @@ def make_icu_data(target, source, env): f = open(source[0].srcnode().abspath, "rb") buf = f.read() - import os.path g.write('extern "C" U_EXPORT const size_t U_ICUDATA_SIZE = ' + str(len(buf)) + ";\n") g.write('extern "C" U_EXPORT const unsigned char U_ICUDATA_ENTRY_POINT[] = {\n') @@ -272,6 +270,7 @@ if env["builtin_icu"]: "common/dictionarydata.cpp", "common/dtintrv.cpp", "common/edits.cpp", + "common/emojiprops.cpp", "common/errorcode.cpp", "common/filteredbrk.cpp", "common/filterednormalizer2.cpp", @@ -293,6 +292,7 @@ if env["builtin_icu"]: "common/locresdata.cpp", "common/locutil.cpp", "common/lsr.cpp", + "common/lstmbe.cpp", "common/messagepattern.cpp", "common/normalizer2.cpp", "common/normalizer2impl.cpp", @@ -450,7 +450,7 @@ if env["builtin_icu"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - icu_data_name = "icudt69l.dat" + icu_data_name = "icudt70l.dat" if env_icu["tools"]: env_icu.Depends("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name) diff --git a/modules/text_server_adv/icu_data/icudata_stub.cpp b/modules/text_server_adv/icu_data/icudata_stub.cpp index 187001f33a..47dfa5ce26 100644 --- a/modules/text_server_adv/icu_data/icudata_stub.cpp +++ b/modules/text_server_adv/icu_data/icudata_stub.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/text_server_adv/register_types.cpp b/modules/text_server_adv/register_types.cpp index b711d1561f..d2dbfa045b 100644 --- a/modules/text_server_adv/register_types.cpp +++ b/modules/text_server_adv/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/text_server_adv/register_types.h b/modules/text_server_adv/register_types.h index ddd1190f40..d2b49fce6e 100644 --- a/modules/text_server_adv/register_types.h +++ b/modules/text_server_adv/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/text_server_adv/script_iterator.cpp b/modules/text_server_adv/script_iterator.cpp index d1e849def8..9e3d9138d0 100644 --- a/modules/text_server_adv/script_iterator.cpp +++ b/modules/text_server_adv/script_iterator.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/text_server_adv/script_iterator.h b/modules/text_server_adv/script_iterator.h index 5efd40f7c4..1e11b51521 100644 --- a/modules/text_server_adv/script_iterator.h +++ b/modules/text_server_adv/script_iterator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index f5d159040f..f1945f62cb 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -38,6 +38,8 @@ #include "thirdparty/icu4c/icudata.gen.h" #endif +#include "modules/modules_enabled.gen.h" // For freetype, msdfgen. + #ifdef MODULE_MSDFGEN_ENABLED #include "core/ShapeDistanceFinder.h" #include "core/contour-combiners.h" @@ -46,13 +48,13 @@ #endif /*************************************************************************/ -/* hb_bmp_font_t HarfBuzz Bitmap font interface */ +/* bmp_font_t HarfBuzz Bitmap font interface */ /*************************************************************************/ hb_font_funcs_t *TextServerAdvanced::funcs = nullptr; -TextServerAdvanced::hb_bmp_font_t *TextServerAdvanced::_hb_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref) { - hb_bmp_font_t *bm_font = memnew(hb_bmp_font_t); +TextServerAdvanced::bmp_font_t *TextServerAdvanced::_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref) { + bmp_font_t *bm_font = memnew(bmp_font_t); if (!bm_font) { return nullptr; @@ -64,13 +66,13 @@ TextServerAdvanced::hb_bmp_font_t *TextServerAdvanced::_hb_bmp_font_create(TextS return bm_font; } -void TextServerAdvanced::_hb_bmp_font_destroy(void *p_data) { - hb_bmp_font_t *bm_font = reinterpret_cast<hb_bmp_font_t *>(p_data); +void TextServerAdvanced::_bmp_font_destroy(void *p_data) { + bmp_font_t *bm_font = reinterpret_cast<bmp_font_t *>(p_data); memdelete(bm_font); } -hb_bool_t TextServerAdvanced::hb_bmp_get_nominal_glyph(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_unicode, hb_codepoint_t *r_glyph, void *p_user_data) { - const hb_bmp_font_t *bm_font = reinterpret_cast<const hb_bmp_font_t *>(p_font_data); +hb_bool_t TextServerAdvanced::_bmp_get_nominal_glyph(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_unicode, hb_codepoint_t *r_glyph, void *p_user_data) { + const bmp_font_t *bm_font = reinterpret_cast<const bmp_font_t *>(p_font_data); if (!bm_font->face) { return false; @@ -89,8 +91,8 @@ hb_bool_t TextServerAdvanced::hb_bmp_get_nominal_glyph(hb_font_t *p_font, void * return true; } -hb_position_t TextServerAdvanced::hb_bmp_get_glyph_h_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data) { - const hb_bmp_font_t *bm_font = reinterpret_cast<const hb_bmp_font_t *>(p_font_data); +hb_position_t TextServerAdvanced::_bmp_get_glyph_h_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data) { + const bmp_font_t *bm_font = reinterpret_cast<const bmp_font_t *>(p_font_data); if (!bm_font->face) { return 0; @@ -103,8 +105,8 @@ hb_position_t TextServerAdvanced::hb_bmp_get_glyph_h_advance(hb_font_t *p_font, return bm_font->face->glyph_map[p_glyph].advance.x * 64; } -hb_position_t TextServerAdvanced::hb_bmp_get_glyph_v_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data) { - const hb_bmp_font_t *bm_font = reinterpret_cast<const hb_bmp_font_t *>(p_font_data); +hb_position_t TextServerAdvanced::_bmp_get_glyph_v_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data) { + const bmp_font_t *bm_font = reinterpret_cast<const bmp_font_t *>(p_font_data); if (!bm_font->face) { return 0; @@ -117,8 +119,8 @@ hb_position_t TextServerAdvanced::hb_bmp_get_glyph_v_advance(hb_font_t *p_font, return -bm_font->face->glyph_map[p_glyph].advance.y * 64; } -hb_position_t TextServerAdvanced::hb_bmp_get_glyph_h_kerning(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_left_glyph, hb_codepoint_t p_right_glyph, void *p_user_data) { - const hb_bmp_font_t *bm_font = reinterpret_cast<const hb_bmp_font_t *>(p_font_data); +hb_position_t TextServerAdvanced::_bmp_get_glyph_h_kerning(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_left_glyph, hb_codepoint_t p_right_glyph, void *p_user_data) { + const bmp_font_t *bm_font = reinterpret_cast<const bmp_font_t *>(p_font_data); if (!bm_font->face) { return 0; @@ -131,8 +133,8 @@ hb_position_t TextServerAdvanced::hb_bmp_get_glyph_h_kerning(hb_font_t *p_font, return bm_font->face->kerning_map[Vector2i(p_left_glyph, p_right_glyph)].x * 64; } -hb_bool_t TextServerAdvanced::hb_bmp_get_glyph_v_origin(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, hb_position_t *r_x, hb_position_t *r_y, void *p_user_data) { - const hb_bmp_font_t *bm_font = reinterpret_cast<const hb_bmp_font_t *>(p_font_data); +hb_bool_t TextServerAdvanced::_bmp_get_glyph_v_origin(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, hb_position_t *r_x, hb_position_t *r_y, void *p_user_data) { + const bmp_font_t *bm_font = reinterpret_cast<const bmp_font_t *>(p_font_data); if (!bm_font->face) { return false; @@ -148,8 +150,8 @@ hb_bool_t TextServerAdvanced::hb_bmp_get_glyph_v_origin(hb_font_t *p_font, void return true; } -hb_bool_t TextServerAdvanced::hb_bmp_get_glyph_extents(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, hb_glyph_extents_t *r_extents, void *p_user_data) { - const hb_bmp_font_t *bm_font = reinterpret_cast<const hb_bmp_font_t *>(p_font_data); +hb_bool_t TextServerAdvanced::_bmp_get_glyph_extents(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, hb_glyph_extents_t *r_extents, void *p_user_data) { + const bmp_font_t *bm_font = reinterpret_cast<const bmp_font_t *>(p_font_data); if (!bm_font->face) { return false; @@ -167,8 +169,8 @@ hb_bool_t TextServerAdvanced::hb_bmp_get_glyph_extents(hb_font_t *p_font, void * return true; } -hb_bool_t TextServerAdvanced::hb_bmp_get_font_h_extents(hb_font_t *p_font, void *p_font_data, hb_font_extents_t *r_metrics, void *p_user_data) { - const hb_bmp_font_t *bm_font = reinterpret_cast<const hb_bmp_font_t *>(p_font_data); +hb_bool_t TextServerAdvanced::_bmp_get_font_h_extents(hb_font_t *p_font, void *p_font_data, hb_font_extents_t *r_metrics, void *p_user_data) { + const bmp_font_t *bm_font = reinterpret_cast<const bmp_font_t *>(p_font_data); if (!bm_font->face) { return false; @@ -181,40 +183,40 @@ hb_bool_t TextServerAdvanced::hb_bmp_get_font_h_extents(hb_font_t *p_font, void return true; } -void TextServerAdvanced::hb_bmp_create_font_funcs() { +void TextServerAdvanced::_bmp_create_font_funcs() { if (funcs == nullptr) { funcs = hb_font_funcs_create(); - hb_font_funcs_set_font_h_extents_func(funcs, hb_bmp_get_font_h_extents, nullptr, nullptr); - hb_font_funcs_set_nominal_glyph_func(funcs, hb_bmp_get_nominal_glyph, nullptr, nullptr); - hb_font_funcs_set_glyph_h_advance_func(funcs, hb_bmp_get_glyph_h_advance, nullptr, nullptr); - hb_font_funcs_set_glyph_v_advance_func(funcs, hb_bmp_get_glyph_v_advance, nullptr, nullptr); - hb_font_funcs_set_glyph_v_origin_func(funcs, hb_bmp_get_glyph_v_origin, nullptr, nullptr); - hb_font_funcs_set_glyph_h_kerning_func(funcs, hb_bmp_get_glyph_h_kerning, nullptr, nullptr); - hb_font_funcs_set_glyph_extents_func(funcs, hb_bmp_get_glyph_extents, nullptr, nullptr); + hb_font_funcs_set_font_h_extents_func(funcs, _bmp_get_font_h_extents, nullptr, nullptr); + hb_font_funcs_set_nominal_glyph_func(funcs, _bmp_get_nominal_glyph, nullptr, nullptr); + hb_font_funcs_set_glyph_h_advance_func(funcs, _bmp_get_glyph_h_advance, nullptr, nullptr); + hb_font_funcs_set_glyph_v_advance_func(funcs, _bmp_get_glyph_v_advance, nullptr, nullptr); + hb_font_funcs_set_glyph_v_origin_func(funcs, _bmp_get_glyph_v_origin, nullptr, nullptr); + hb_font_funcs_set_glyph_h_kerning_func(funcs, _bmp_get_glyph_h_kerning, nullptr, nullptr); + hb_font_funcs_set_glyph_extents_func(funcs, _bmp_get_glyph_extents, nullptr, nullptr); hb_font_funcs_make_immutable(funcs); } } -void TextServerAdvanced::hb_bmp_free_font_funcs() { +void TextServerAdvanced::_bmp_free_font_funcs() { if (funcs != nullptr) { hb_font_funcs_destroy(funcs); funcs = nullptr; } } -void TextServerAdvanced::_hb_bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref) { - hb_font_set_funcs(p_font, funcs, _hb_bmp_font_create(p_face, p_unref), _hb_bmp_font_destroy); +void TextServerAdvanced::_bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref) { + hb_font_set_funcs(p_font, funcs, _bmp_font_create(p_face, p_unref), _bmp_font_destroy); } -hb_font_t *TextServerAdvanced::hb_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, hb_destroy_func_t p_destroy) { +hb_font_t *TextServerAdvanced::_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, hb_destroy_func_t p_destroy) { hb_font_t *font; hb_face_t *face = hb_face_create(nullptr, 0); font = hb_font_create(face); hb_face_destroy(face); - _hb_bmp_font_set_funcs(font, p_face, false); + _bmp_font_set_funcs(font, p_face, false); return font; } @@ -442,9 +444,7 @@ bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) const { } } -static Map<StringName, int32_t> feature_sets; - -static void _insert_feature_sets() { +void TextServerAdvanced::_insert_feature_sets() { // Registered OpenType feature tags. feature_sets.insert("access_all_alternates", HB_TAG('a', 'a', 'l', 't')); feature_sets.insert("above_base_forms", HB_TAG('a', 'b', 'v', 'f')); @@ -740,6 +740,10 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_ continue; } + if (ct.offsets.size() < ct.texture_w) { + continue; + } + ret.y = 0x7FFFFFFF; ret.x = 0; @@ -938,7 +942,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( FontGlyph chr; chr.found = true; - chr.advance = advance.round(); + chr.advance = advance; if (shape.validate() && shape.contours.size() > 0) { int w = (bounds.r - bounds.l); @@ -956,7 +960,6 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( edgeColoringSimple(shape, 3.0); // Max. angle. msdfgen::Bitmap<float, 4> image(w, h); // Texture size. - //msdfgen::generateMTSDF(image, shape, p_pixel_range, 1.0, msdfgen::Vector2(-bounds.l, -bounds.b)); // Range, scale, translation. DistancePixelConversion distancePixelConversion(p_pixel_range); msdfgen::Projection projection(msdfgen::Vector2(1.0, 1.0), msdfgen::Vector2(-bounds.l, -bounds.b)); @@ -986,10 +989,6 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( wr[ofs + 1] = (uint8_t)(CLAMP(image(j, i)[1] * 256.f, 0.f, 255.f)); wr[ofs + 2] = (uint8_t)(CLAMP(image(j, i)[2] * 256.f, 0.f, 255.f)); wr[ofs + 3] = (uint8_t)(CLAMP(image(j, i)[3] * 256.f, 0.f, 255.f)); - //wr[ofs + 0] = 100; - //wr[ofs + 1] = 100; - //wr[ofs + 2] = 100; - //wr[ofs + 3] = 100; } } } @@ -1054,13 +1053,12 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma case FT_PIXEL_MODE_MONO: { int byte = i * bitmap.pitch + (j >> 3); int bit = 1 << (7 - (j % 8)); - wr[ofs + 0] = 255; //grayscale as 1 + wr[ofs + 0] = 255; // grayscale as 1 wr[ofs + 1] = (bitmap.buffer[byte] & bit) ? 255 : 0; } break; case FT_PIXEL_MODE_GRAY: - wr[ofs + 0] = 255; //grayscale as 1 + wr[ofs + 0] = 255; // grayscale as 1 wr[ofs + 1] = bitmap.buffer[i * bitmap.pitch + j]; - //wr[ofs + 1] = 100; break; case FT_PIXEL_MODE_BGRA: { int ofs_color = i * bitmap.pitch + (j << 2); @@ -1097,12 +1095,12 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma } FontGlyph chr; - chr.advance = (advance * p_data->scale / p_data->oversampling).round(); + chr.advance = advance * p_data->scale / p_data->oversampling; chr.texture_idx = tex_pos.index; chr.found = true; chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w, h); - chr.rect.position = (Vector2(xofs, -yofs) * p_data->scale / p_data->oversampling).round(); + chr.rect.position = Vector2(xofs, -yofs) * p_data->scale / p_data->oversampling; chr.rect.size = chr.uv_rect.size * p_data->scale / p_data->oversampling; return chr; } @@ -1215,13 +1213,14 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontDataAdvanced *p_font_d } _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced *p_font_data, const Vector2i &p_size) const { + ERR_FAIL_COND_V(p_size.x <= 0, false); if (p_font_data->cache.has(p_size)) { return true; } FontDataForSizeAdvanced *fd = memnew(FontDataForSizeAdvanced); fd->size = p_size; - if (p_font_data->data_ptr) { + if (p_font_data->data_ptr && (p_font_data->data_size > 0)) { // Init dynamic font. #ifdef MODULE_FREETYPE_ENABLED int error = 0; @@ -1271,7 +1270,8 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced } FT_Select_Size(fd->face, best_match); } else { - FT_Set_Pixel_Sizes(fd->face, 0, fd->size.x * fd->oversampling); + FT_Set_Pixel_Sizes(fd->face, 0, float(fd->size.x * fd->oversampling)); + fd->scale = ((float)fd->size.x * fd->oversampling) / (float)fd->face->size->metrics.y_ppem; } fd->hb_handle = hb_ft_font_create(fd->face, nullptr); @@ -1282,6 +1282,23 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale; if (!p_font_data->face_init) { + // Get style flags and name. + if (fd->face->family_name != nullptr) { + p_font_data->font_name = String::utf8((const char *)fd->face->family_name); + } + if (fd->face->style_name != nullptr) { + p_font_data->style_name = String::utf8((const char *)fd->face->style_name); + } + p_font_data->style_flags = 0; + if (fd->face->style_flags & FT_STYLE_FLAG_BOLD) { + p_font_data->style_flags |= FONT_BOLD; + } + if (fd->face->style_flags & FT_STYLE_FLAG_ITALIC) { + p_font_data->style_flags |= FONT_ITALIC; + } + if (fd->face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) { + p_font_data->style_flags |= FONT_FIXED_WIDTH; + } // Get supported scripts from OpenType font data. p_font_data->supported_scripts.clear(); unsigned int count = hb_ot_layout_table_get_script_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GSUB, 0, nullptr, nullptr); @@ -1594,7 +1611,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced #endif } else { // Init bitmap font. - fd->hb_handle = hb_bmp_font_create(fd, nullptr); + fd->hb_handle = _bmp_font_create(fd, nullptr); } p_font_data->cache[p_size] = fd; return true; @@ -1651,6 +1668,66 @@ void TextServerAdvanced::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data fd->data_size = p_data_size; } +void TextServerAdvanced::font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + fd->style_flags = p_style; +} + +uint32_t /*FontStyle*/ TextServerAdvanced::font_get_style(RID p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, 0); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0); + return fd->style_flags; +} + +void TextServerAdvanced::font_set_style_name(RID p_font_rid, const String &p_name) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + fd->style_name = p_name; +} + +String TextServerAdvanced::font_get_style_name(RID p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, String()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), String()); + return fd->style_name; +} + +void TextServerAdvanced::font_set_name(RID p_font_rid, const String &p_name) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + fd->font_name = p_name; +} + +String TextServerAdvanced::font_get_name(RID p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, String()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), String()); + return fd->font_name; +} + void TextServerAdvanced::font_set_antialiased(RID p_font_rid, bool p_antialiased) { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -2072,7 +2149,7 @@ void TextServerAdvanced::font_remove_texture(RID p_font_rid, const Vector2i &p_s ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); ERR_FAIL_INDEX(p_texture_index, fd->cache[size]->textures.size()); - fd->cache[size]->textures.remove(p_texture_index); + fd->cache[size]->textures.remove_at(p_texture_index); } void TextServerAdvanced::font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) { @@ -2123,6 +2200,7 @@ void TextServerAdvanced::font_set_texture_offsets(RID p_font_rid, const Vector2i MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + ERR_FAIL_COND(p_texture_index < 0); if (p_texture_index >= fd->cache[size]->textures.size()) { fd->cache[size]->textures.resize(p_texture_index + 1); } @@ -2480,6 +2558,8 @@ Vector2 TextServerAdvanced::font_get_kerning(RID p_font_rid, int p_size, const V int32_t TextServerAdvanced::font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0); + ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), 0, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + "."); + ERR_FAIL_COND_V_MSG((p_variation_selector >= 0xd800 && p_variation_selector <= 0xdfff) || (p_variation_selector > 0x10ffff), 0, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_variation_selector, 16) + "."); MutexLock lock(fd->mutex); Vector2i size = _get_size(fd, p_size); @@ -2503,6 +2583,7 @@ int32_t TextServerAdvanced::font_get_glyph_index(RID p_font_rid, int p_size, cha bool TextServerAdvanced::font_has_char(RID p_font_rid, char32_t p_char) const { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); + ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), false, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + "."); MutexLock lock(fd->mutex); if (fd->cache.is_empty()) { @@ -2555,6 +2636,8 @@ String TextServerAdvanced::font_get_supported_chars(RID p_font_rid) const { void TextServerAdvanced::font_render_range(RID p_font_rid, const Vector2i &p_size, char32_t p_start, char32_t p_end) { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); + ERR_FAIL_COND_MSG((p_start >= 0xd800 && p_start <= 0xdfff) || (p_start > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_start, 16) + "."); + ERR_FAIL_COND_MSG((p_end >= 0xd800 && p_end <= 0xdfff) || (p_end > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_end, 16) + "."); MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); @@ -2588,7 +2671,7 @@ void TextServerAdvanced::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz Vector2i size = _get_size(fd, p_size); ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); if (!_ensure_glyph(fd, size, p_index)) { - return; // // Invalid or non graphicl glyph, do not display errors, nothing to draw. + return; // Invalid or non-graphical glyph, do not display errors, nothing to draw. } const FontGlyph &gl = fd->cache[size]->glyph_map[p_index]; @@ -2610,9 +2693,9 @@ void TextServerAdvanced::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range); } else { - Point2i cpos = p_pos; + Point2 cpos = p_pos.floor(); cpos += gl.rect.position; - Size2i csize = gl.rect.size; + Size2 csize = gl.rect.size; RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false); } } @@ -2628,7 +2711,7 @@ void TextServerAdvanced::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i Vector2i size = _get_size_outline(fd, Vector2i(p_size, p_outline_size)); ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); if (!_ensure_glyph(fd, size, p_index)) { - return; // // Invalid or non graphicl glyph, do not display errors, nothing to draw. + return; // Invalid or non-graphical glyph, do not display errors, nothing to draw. } const FontGlyph &gl = fd->cache[size]->glyph_map[p_index]; @@ -2650,9 +2733,9 @@ void TextServerAdvanced::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range); } else { - Point2i cpos = p_pos; + Point2 cpos = p_pos.floor(); cpos += gl.rect.position; - Size2i csize = gl.rect.size; + Size2 csize = gl.rect.size; RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false); } } @@ -2928,6 +3011,27 @@ TextServer::Direction TextServerAdvanced::shaped_text_get_direction(RID p_shaped return sd->direction; } +void TextServerAdvanced::shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) { + _THREAD_SAFE_METHOD_ + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND(!sd); + + if (sd->custom_punct != p_punct) { + if (sd->parent != RID()) { + full_copy(sd); + } + sd->custom_punct = p_punct; + invalidate(sd); + } +} + +String TextServerAdvanced::shaped_text_get_custom_punctuation(RID p_shaped) const { + _THREAD_SAFE_METHOD_ + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, String()); + return sd->custom_punct; +} + void TextServerAdvanced::shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) { ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); @@ -3041,7 +3145,7 @@ bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_te return true; } -bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) { +bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) { _THREAD_SAFE_METHOD_ ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); @@ -3053,7 +3157,7 @@ bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, con } ShapedTextDataAdvanced::Span span; - span.start = sd->text.length(); + span.start = sd->start + sd->text.length(); span.end = span.start + p_length; span.embedded_key = p_key; @@ -3071,7 +3175,7 @@ bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, con return true; } -bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) { +bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) { ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); @@ -3139,57 +3243,57 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.y = -sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.y = (-sd->ascent + sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.y = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.y = sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.y -= E.value.rect.size.y; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.y -= E.value.rect.size.y / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.y); full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.x = -sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.x = (-sd->ascent + sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.x = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.x = sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.x -= E.value.rect.size.x; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.x -= E.value.rect.size.x / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.x); @@ -3219,59 +3323,72 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng ERR_FAIL_COND_V(sd->end < p_start + p_length, RID()); ShapedTextDataAdvanced *new_sd = memnew(ShapedTextDataAdvanced); - - new_sd->hb_buffer = hb_buffer_create(); new_sd->parent = p_shaped; new_sd->start = p_start; new_sd->end = p_start + p_length; - new_sd->orientation = sd->orientation; new_sd->direction = sd->direction; + new_sd->custom_punct = sd->custom_punct; new_sd->para_direction = sd->para_direction; - new_sd->line_breaks_valid = sd->line_breaks_valid; - new_sd->justification_ops_valid = sd->justification_ops_valid; - new_sd->sort_valid = false; - new_sd->upos = sd->upos; - new_sd->uthk = sd->uthk; + + if (!_shape_substr(new_sd, sd, p_start, p_length)) { + memdelete(new_sd); + return RID(); + } + return shaped_owner.make_rid(new_sd); +} + +bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const ShapedTextDataAdvanced *p_sd, int p_start, int p_length) const { + if (p_new_sd->valid) { + return true; + } + + p_new_sd->hb_buffer = hb_buffer_create(); + + p_new_sd->line_breaks_valid = p_sd->line_breaks_valid; + p_new_sd->justification_ops_valid = p_sd->justification_ops_valid; + p_new_sd->sort_valid = false; + p_new_sd->upos = p_sd->upos; + p_new_sd->uthk = p_sd->uthk; if (p_length > 0) { - new_sd->text = sd->text.substr(p_start, p_length); - new_sd->utf16 = new_sd->text.utf16(); - new_sd->script_iter = memnew(ScriptIterator(new_sd->text, 0, new_sd->text.length())); + p_new_sd->text = p_sd->text.substr(p_start - p_sd->start, p_length); + p_new_sd->utf16 = p_new_sd->text.utf16(); + p_new_sd->script_iter = memnew(ScriptIterator(p_new_sd->text, 0, p_new_sd->text.length())); - int sd_size = sd->glyphs.size(); - const Glyph *sd_glyphs = sd->glyphs.ptr(); - for (int ov = 0; ov < sd->bidi_override.size(); ov++) { + int sd_size = p_sd->glyphs.size(); + const Glyph *sd_glyphs = p_sd->glyphs.ptr(); + for (int ov = 0; ov < p_sd->bidi_override.size(); ov++) { UErrorCode err = U_ZERO_ERROR; - if (sd->bidi_override[ov].x >= p_start + p_length || sd->bidi_override[ov].y <= p_start) { + if (p_sd->bidi_override[ov].x >= p_start + p_length || p_sd->bidi_override[ov].y <= p_start) { continue; } - int start = _convert_pos_inv(sd, MAX(0, p_start - sd->bidi_override[ov].x)); - int end = _convert_pos_inv(sd, MIN(p_start + p_length, sd->bidi_override[ov].y) - sd->bidi_override[ov].x); + int start = _convert_pos_inv(p_sd, MAX(0, p_start - p_sd->bidi_override[ov].x)); + int end = _convert_pos_inv(p_sd, MIN(p_start + p_length, p_sd->bidi_override[ov].y) - p_sd->bidi_override[ov].x); - ERR_FAIL_COND_V_MSG((start < 0 || end - start > new_sd->utf16.length()), RID(), "Invalid BiDi override range."); + ERR_FAIL_COND_V_MSG((start < 0 || end - start > p_new_sd->utf16.length()), false, "Invalid BiDi override range."); // Create temporary line bidi & shape. UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err); - ERR_FAIL_COND_V_MSG(U_FAILURE(err), RID(), u_errorName(err)); - ubidi_setLine(sd->bidi_iter[ov], start, end, bidi_iter, &err); + ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); + ubidi_setLine(p_sd->bidi_iter[ov], start, end, bidi_iter, &err); if (U_FAILURE(err)) { ubidi_close(bidi_iter); - ERR_FAIL_V_MSG(RID(), u_errorName(err)); + ERR_FAIL_V_MSG(false, u_errorName(err)); } - new_sd->bidi_iter.push_back(bidi_iter); + p_new_sd->bidi_iter.push_back(bidi_iter); err = U_ZERO_ERROR; int bidi_run_count = ubidi_countRuns(bidi_iter, &err); - ERR_FAIL_COND_V_MSG(U_FAILURE(err), RID(), u_errorName(err)); + ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); for (int i = 0; i < bidi_run_count; i++) { int32_t _bidi_run_start = 0; int32_t _bidi_run_length = 0; ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length); - int32_t bidi_run_start = _convert_pos(sd, sd->bidi_override[ov].x + start + _bidi_run_start); - int32_t bidi_run_end = _convert_pos(sd, sd->bidi_override[ov].x + start + _bidi_run_start + _bidi_run_length); + int32_t bidi_run_start = _convert_pos(p_sd, p_sd->bidi_override[ov].x + start + _bidi_run_start); + int32_t bidi_run_end = _convert_pos(p_sd, p_sd->bidi_override[ov].x + start + _bidi_run_start + _bidi_run_length); for (int j = 0; j < sd_size; j++) { if ((sd_glyphs[j].start >= bidi_run_start) && (sd_glyphs[j].end <= bidi_run_end)) { @@ -3280,106 +3397,106 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng Variant key; bool find_embedded = false; if (gl.count == 1) { - for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : p_sd->objects) { if (E.value.pos == gl.start) { find_embedded = true; key = E.key; - new_sd->objects[key] = E.value; + p_new_sd->objects[key] = E.value; break; } } } if (find_embedded) { - if (new_sd->orientation == ORIENTATION_HORIZONTAL) { - new_sd->objects[key].rect.position.x = new_sd->width; - new_sd->width += new_sd->objects[key].rect.size.x; + if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) { + p_new_sd->objects[key].rect.position.x = p_new_sd->width; + p_new_sd->width += p_new_sd->objects[key].rect.size.x; } else { - new_sd->objects[key].rect.position.y = new_sd->width; - new_sd->width += new_sd->objects[key].rect.size.y; + p_new_sd->objects[key].rect.position.y = p_new_sd->width; + p_new_sd->width += p_new_sd->objects[key].rect.size.y; } } else { if (gl.font_rid.is_valid()) { - if (new_sd->orientation == ORIENTATION_HORIZONTAL) { - new_sd->ascent = MAX(new_sd->ascent, MAX(font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off)); - new_sd->descent = MAX(new_sd->descent, MAX(font_get_descent(gl.font_rid, gl.font_size), gl.y_off)); + if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) { + p_new_sd->ascent = MAX(p_new_sd->ascent, MAX(font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off)); + p_new_sd->descent = MAX(p_new_sd->descent, MAX(font_get_descent(gl.font_rid, gl.font_size), gl.y_off)); } else { - new_sd->ascent = MAX(new_sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); - new_sd->descent = MAX(new_sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); + p_new_sd->ascent = MAX(p_new_sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); + p_new_sd->descent = MAX(p_new_sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); } - } else if (new_sd->preserve_invalid || (new_sd->preserve_control && is_control(gl.index))) { + } else if (p_new_sd->preserve_invalid || (p_new_sd->preserve_control && is_control(gl.index))) { // Glyph not found, replace with hex code box. - if (new_sd->orientation == ORIENTATION_HORIZONTAL) { - new_sd->ascent = MAX(new_sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y); + if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) { + p_new_sd->ascent = MAX(p_new_sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y); } else { - new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); - new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); + p_new_sd->ascent = MAX(p_new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); + p_new_sd->descent = MAX(p_new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); } } - new_sd->width += gl.advance * gl.repeat; + p_new_sd->width += gl.advance * gl.repeat; } - new_sd->glyphs.push_back(gl); + p_new_sd->glyphs.push_back(gl); } } } } // Align embedded objects to baseline. - float full_ascent = new_sd->ascent; - float full_descent = new_sd->descent; - for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) { - if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) { - if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { - E.value.rect.position.y = -new_sd->ascent; + float full_ascent = p_new_sd->ascent; + float full_descent = p_new_sd->descent; + for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : p_new_sd->objects) { + if ((E.value.pos >= p_new_sd->start) && (E.value.pos < p_new_sd->end)) { + if (p_sd->orientation == ORIENTATION_HORIZONTAL) { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { + E.value.rect.position.y = -p_new_sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { - E.value.rect.position.y = (-new_sd->ascent + new_sd->descent) / 2; + case INLINE_ALIGNMENT_TO_CENTER: { + E.value.rect.position.y = (-p_new_sd->ascent + p_new_sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.y = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { - E.value.rect.position.y = new_sd->descent; + case INLINE_ALIGNMENT_TO_BOTTOM: { + E.value.rect.position.y = p_new_sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.y -= E.value.rect.size.y; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.y -= E.value.rect.size.y / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.y); full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { - E.value.rect.position.x = -new_sd->ascent; + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { + E.value.rect.position.x = -p_new_sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { - E.value.rect.position.x = (-new_sd->ascent + new_sd->descent) / 2; + case INLINE_ALIGNMENT_TO_CENTER: { + E.value.rect.position.x = (-p_new_sd->ascent + p_new_sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.x = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { - E.value.rect.position.x = new_sd->descent; + case INLINE_ALIGNMENT_TO_BOTTOM: { + E.value.rect.position.x = p_new_sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.x -= E.value.rect.size.x; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.x -= E.value.rect.size.x / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.x); @@ -3387,12 +3504,12 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng } } } - new_sd->ascent = full_ascent; - new_sd->descent = full_descent; + p_new_sd->ascent = full_ascent; + p_new_sd->descent = full_descent; } - new_sd->valid = true; + p_new_sd->valid = true; - return shaped_owner.make_rid(new_sd); + return true; } RID TextServerAdvanced::shaped_text_get_parent(RID p_shaped) const { @@ -3651,10 +3768,10 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl width -= sd_glyphs[i].advance * sd_glyphs[i].repeat; } if (sd_glyphs[i].count > 0) { - bool above_min_char_treshold = ((is_rtl) ? sd_size - 1 - i : i) >= ell_min_characters; + bool above_min_char_threshold = ((is_rtl) ? sd_size - 1 - i : i) >= ell_min_characters; - if (width + (((above_min_char_treshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_width : 0) <= p_width) { - if (cut_per_word && above_min_char_treshold) { + if (width + (((above_min_char_threshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_width : 0) <= p_width) { + if (cut_per_word && above_min_char_threshold) { if ((sd_glyphs[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) { last_valid_cut = i; found = true; @@ -3666,7 +3783,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl if (found) { trim_pos = last_valid_cut; - if (add_ellipsis && (above_min_char_treshold || enforce_ellipsis) && width - ellipsis_width <= p_width) { + if (add_ellipsis && (above_min_char_threshold || enforce_ellipsis) && width - ellipsis_width <= p_width) { ellipsis_pos = trim_pos; } break; @@ -3807,6 +3924,9 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { const char32_t *ch = sd->text.ptr(); Glyph *sd_glyphs = sd->glyphs.ptrw(); + int c_punct_size = sd->custom_punct.length(); + const char32_t *c_punct = sd->custom_punct.ptr(); + for (i = 0; i < sd_size; i++) { if (sd_glyphs[i].count > 0) { char32_t c = ch[sd_glyphs[i].start - sd->start]; @@ -3819,12 +3939,21 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { if (is_whitespace(c)) { sd_glyphs[i].flags |= GRAPHEME_IS_SPACE; } + if (c_punct_size == 0) { + if (u_ispunct(c) && c != 0x005F) { + sd_glyphs[i].flags |= GRAPHEME_IS_PUNCTUATION; + } + } else { + for (int j = 0; j < c_punct_size; j++) { + if (c_punct[j] == c) { + sd_glyphs[i].flags |= GRAPHEME_IS_PUNCTUATION; + break; + } + } + } if (is_underscore(c)) { sd_glyphs[i].flags |= GRAPHEME_IS_UNDERSCORE; } - if (u_ispunct(c) && c != 0x005F) { - sd_glyphs[i].flags |= GRAPHEME_IS_PUNCTUATION; - } if (breaks.has(sd->glyphs[i].start)) { if (breaks[sd->glyphs[i].start]) { sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_HARD; @@ -4109,8 +4238,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star for (int i = p_start; i < p_end; i++) { if (p_sd->preserve_invalid || (p_sd->preserve_control && is_control(p_sd->text[i]))) { Glyph gl; - gl.start = i; - gl.end = i + 1; + gl.start = i + p_sd->start; + gl.end = i + 1 + p_sd->start; gl.count = 1; gl.index = p_sd->text[i]; gl.font_size = fs; @@ -4136,6 +4265,9 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star RID f = p_fonts[p_fb_index]; hb_font_t *hb_font = _font_get_hb_handle(f, fs); + float scale = font_get_scale(f, fs); + float sp_sp = font_get_spacing(f, fs, SPACING_SPACE); + float sp_gl = font_get_spacing(f, fs, SPACING_GLYPH); ERR_FAIL_COND(hb_font == nullptr); hb_buffer_clear_contents(p_sd->hb_buffer); @@ -4147,7 +4279,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star } hb_buffer_set_script(p_sd->hb_buffer, p_script); - if (p_sd->spans[p_span].language != String()) { + if (!p_sd->spans[p_span].language.is_empty()) { hb_language_t lang = hb_language_from_string(p_sd->spans[p_span].language.ascii().get_data(), -1); hb_buffer_set_language(p_sd->hb_buffer, lang); } @@ -4219,7 +4351,6 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star gl.index = glyph_info[i].codepoint; if (gl.index != 0) { - float scale = font_get_scale(f, fs); if (p_sd->orientation == ORIENTATION_HORIZONTAL) { gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale)); } else { @@ -4228,10 +4359,10 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star gl.x_off = Math::round(glyph_pos[i].x_offset / (64.0 / scale)); gl.y_off = -Math::round(glyph_pos[i].y_offset / (64.0 / scale)); } - if (font_get_spacing(f, fs, SPACING_SPACE) && is_whitespace(p_sd->text[glyph_info[i].cluster])) { - gl.advance += font_get_spacing(f, fs, SPACING_SPACE); + if (sp_sp && is_whitespace(p_sd->text[glyph_info[i].cluster])) { + gl.advance += sp_sp; } else { - gl.advance += font_get_spacing(f, fs, SPACING_GLYPH); + gl.advance += sp_gl; } if (p_sd->preserve_control) { @@ -4269,10 +4400,13 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star p_sd->ascent = MAX(p_sd->ascent, -w[i + j].y_off); p_sd->descent = MAX(p_sd->descent, w[i + j].y_off); } else { - p_sd->ascent = MAX(p_sd->ascent, Math::round(font_get_glyph_advance(f, fs, w[i + j].index).x * 0.5)); - p_sd->descent = MAX(p_sd->descent, Math::round(font_get_glyph_advance(f, fs, w[i + j].index).x * 0.5)); + float gla = Math::round(font_get_glyph_advance(f, fs, w[i + j].index).x * 0.5); + p_sd->ascent = MAX(p_sd->ascent, gla); + p_sd->descent = MAX(p_sd->descent, gla); } p_sd->width += w[i + j].advance; + w[i + j].start += p_sd->start; + w[i + j].end += p_sd->start; p_sd->glyphs.push_back(w[i + j]); } } else { @@ -4305,10 +4439,14 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { return true; } + invalidate(sd); if (sd->parent != RID()) { - full_copy(sd); + shaped_text_shape(sd->parent); + ShapedTextDataAdvanced *parent_sd = shaped_owner.get_or_null(sd->parent); + ERR_FAIL_COND_V(!parent_sd->valid, false); + ERR_FAIL_COND_V(!_shape_substr(sd, parent_sd, sd->start, sd->end - sd->start), false); + return true; } - invalidate(sd); if (sd->text.length() == 0) { sd->valid = true; @@ -4324,15 +4462,17 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { } if (sd->bidi_override.is_empty()) { - sd->bidi_override.push_back(Vector2i(0, sd->end)); + sd->bidi_override.push_back(Vector2i(sd->start, sd->end)); } for (int ov = 0; ov < sd->bidi_override.size(); ov++) { // Create BiDi iterator. - int start = _convert_pos_inv(sd, sd->bidi_override[ov].x); - int end = _convert_pos_inv(sd, sd->bidi_override[ov].y); + int start = _convert_pos_inv(sd, sd->bidi_override[ov].x - sd->start); + int end = _convert_pos_inv(sd, sd->bidi_override[ov].y - sd->start); - ERR_FAIL_COND_V_MSG((start < 0 || end - start > sd->utf16.length()), false, "Invalid BiDi override range."); + if (start < 0 || end - start > sd->utf16.length()) { + continue; + } UErrorCode err = U_ZERO_ERROR; UBiDi *bidi_iter = ubidi_openSized(end, 0, &err); @@ -4386,8 +4526,8 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { } } - int32_t bidi_run_start = _convert_pos(sd, sd->bidi_override[ov].x + _bidi_run_start); - int32_t bidi_run_end = _convert_pos(sd, sd->bidi_override[ov].x + _bidi_run_start + _bidi_run_length); + int32_t bidi_run_start = _convert_pos(sd, sd->bidi_override[ov].x - sd->start + _bidi_run_start); + int32_t bidi_run_end = _convert_pos(sd, sd->bidi_override[ov].x - sd->start + _bidi_run_start + _bidi_run_length); // Shape runs. @@ -4409,7 +4549,7 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { for (int k = spn_from; k != spn_to; k += spn_delta) { const ShapedTextDataAdvanced::Span &span = sd->spans[k]; - if (span.start >= script_run_end || span.end <= script_run_start) { + if (span.start - sd->start >= script_run_end || span.end - sd->start <= script_run_start) { continue; } if (span.embedded_key != Variant()) { @@ -4450,7 +4590,7 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { } fonts.append_array(fonts_scr_only); fonts.append_array(fonts_no_match); - _shape_run(sd, MAX(sd->spans[k].start, script_run_start), MIN(sd->spans[k].end, script_run_end), sd->script_iter->script_ranges[j].script, bidi_run_direction, fonts, k, 0); + _shape_run(sd, MAX(sd->spans[k].start - sd->start, script_run_start), MIN(sd->spans[k].end - sd->start, script_run_end), sd->script_iter->script_ranges[j].script, bidi_run_direction, fonts, k, 0); } } } @@ -4463,57 +4603,57 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { float full_descent = sd->descent; for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.y = -sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.y = (-sd->ascent + sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.y = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.y = sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.y -= E.value.rect.size.y; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.y -= E.value.rect.size.y / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.y); full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.x = -sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.x = (-sd->ascent + sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.x = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.x = sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.x -= E.value.rect.size.x; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.x -= E.value.rect.size.x / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.x); @@ -4679,78 +4819,188 @@ float TextServerAdvanced::shaped_text_get_underline_thickness(RID p_shaped) cons return sd->uthk; } -struct num_system_data { - Set<String> lang; - String digits; - String percent_sign; - String exp; -}; +void TextServerAdvanced::_insert_num_systems_lang() { + // Eastern Arabic numerals. + { + NumSystemData ar; + ar.lang.insert(StringName("ar")); // Arabic + ar.lang.insert(StringName("ar_AE")); + ar.lang.insert(StringName("ar_BH")); + ar.lang.insert(StringName("ar_DJ")); + ar.lang.insert(StringName("ar_EG")); + ar.lang.insert(StringName("ar_ER")); + ar.lang.insert(StringName("ar_IL")); + ar.lang.insert(StringName("ar_IQ")); + ar.lang.insert(StringName("ar_JO")); + ar.lang.insert(StringName("ar_KM")); + ar.lang.insert(StringName("ar_KW")); + ar.lang.insert(StringName("ar_LB")); + ar.lang.insert(StringName("ar_MR")); + ar.lang.insert(StringName("ar_OM")); + ar.lang.insert(StringName("ar_PS")); + ar.lang.insert(StringName("ar_QA")); + ar.lang.insert(StringName("ar_SA")); + ar.lang.insert(StringName("ar_SD")); + ar.lang.insert(StringName("ar_SO")); + ar.lang.insert(StringName("ar_SS")); + ar.lang.insert(StringName("ar_SY")); + ar.lang.insert(StringName("ar_TD")); + ar.lang.insert(StringName("ar_YE")); + ar.lang.insert(StringName("ckb")); // Central Kurdish + ar.lang.insert(StringName("ckb_IQ")); + ar.lang.insert(StringName("ckb_IR")); + ar.lang.insert(StringName("sd")); // Sindhi + ar.lang.insert(StringName("sd_PK")); + ar.lang.insert(StringName("sd_Arab")); + ar.lang.insert(StringName("sd_Arab_PK")); + ar.digits = U"٠١٢٣٤٥٦٧٨٩٫"; + ar.percent_sign = U"٪"; + ar.exp = U"اس"; + num_systems.push_back(ar); + } + + // Persian and Urdu numerals. + { + NumSystemData pr; + pr.lang.insert(StringName("fa")); // Persian + pr.lang.insert(StringName("fa_AF")); + pr.lang.insert(StringName("fa_IR")); + pr.lang.insert(StringName("ks")); // Kashmiri + pr.lang.insert(StringName("ks_IN")); + pr.lang.insert(StringName("ks_Arab")); + pr.lang.insert(StringName("ks_Arab_IN")); + pr.lang.insert(StringName("lrc")); // Northern Luri + pr.lang.insert(StringName("lrc_IQ")); + pr.lang.insert(StringName("lrc_IR")); + pr.lang.insert(StringName("mzn")); // Mazanderani + pr.lang.insert(StringName("mzn_IR")); + pr.lang.insert(StringName("pa_PK")); // Panjabi + pr.lang.insert(StringName("pa_Arab")); + pr.lang.insert(StringName("pa_Arab_PK")); + pr.lang.insert(StringName("ps")); // Pushto + pr.lang.insert(StringName("ps_AF")); + pr.lang.insert(StringName("ps_PK")); + pr.lang.insert(StringName("ur_IN")); // Urdu + pr.lang.insert(StringName("uz_AF")); // Uzbek + pr.lang.insert(StringName("uz_Arab")); + pr.lang.insert(StringName("uz_Arab_AF")); + pr.digits = U"۰۱۲۳۴۵۶۷۸۹٫"; + pr.percent_sign = U"٪"; + pr.exp = U"اس"; + num_systems.push_back(pr); + } + + // Bengali numerals. + { + NumSystemData bn; + bn.lang.insert(StringName("as")); // Assamese + bn.lang.insert(StringName("as_IN")); + bn.lang.insert(StringName("bn")); // Bengali + bn.lang.insert(StringName("bn_BD")); + bn.lang.insert(StringName("bn_IN")); + bn.lang.insert(StringName("mni")); // Manipuri + bn.lang.insert(StringName("mni_IN")); + bn.lang.insert(StringName("mni_Beng")); + bn.lang.insert(StringName("mni_Beng_IN")); + bn.digits = U"০১২৩৪৫৬৭৮৯."; + bn.percent_sign = U"%"; + bn.exp = U"e"; + num_systems.push_back(bn); + } + + // Devanagari numerals. + { + NumSystemData mr; + mr.lang.insert(StringName("mr")); // Marathi + mr.lang.insert(StringName("mr_IN")); + mr.lang.insert(StringName("ne")); // Nepali + mr.lang.insert(StringName("ne_IN")); + mr.lang.insert(StringName("ne_NP")); + mr.lang.insert(StringName("sa")); // Sanskrit + mr.lang.insert(StringName("sa_IN")); + mr.digits = U"०१२३४५६७८९."; + mr.percent_sign = U"%"; + mr.exp = U"e"; + num_systems.push_back(mr); + } + + // Dzongkha numerals. + { + NumSystemData dz; + dz.lang.insert(StringName("dz")); // Dzongkha + dz.lang.insert(StringName("dz_BT")); + dz.digits = U"༠༡༢༣༤༥༦༧༨༩."; + dz.percent_sign = U"%"; + dz.exp = U"e"; + num_systems.push_back(dz); + } -static num_system_data num_systems[]{ - { Set<String>(), U"٠١٢٣٤٥٦٧٨٩٫", U"٪", U"اس" }, - { Set<String>(), U"۰۱۲۳۴۵۶۷۸۹٫", U"٪", U"اس" }, - { Set<String>(), U"০১২৩৪৫৬৭৮৯.", U"%", U"e" }, - { Set<String>(), U"०१२३४५६७८९.", U"%", U"e" }, - { Set<String>(), U"༠༡༢༣༤༥༦༧༨༩.", U"%", U"e" }, - { Set<String>(), U"᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙.", U"%", U"e" }, - { Set<String>(), U"၀၁၂၃၄၅၆၇၈၉.", U"%", U"e" }, - { Set<String>(), String(), String(), String() }, -}; + // Santali numerals. + { + NumSystemData sat; + sat.lang.insert(StringName("sat")); // Santali + sat.lang.insert(StringName("sat_IN")); + sat.lang.insert(StringName("sat_Olck")); + sat.lang.insert(StringName("sat_Olck_IN")); + sat.digits = U"᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙."; + sat.percent_sign = U"%"; + sat.exp = U"e"; + num_systems.push_back(sat); + } + + // Burmese numerals. + { + NumSystemData my; + my.lang.insert(StringName("my")); // Burmese + my.lang.insert(StringName("my_MM")); + my.digits = U"၀၁၂၃၄၅၆၇၈၉."; + my.percent_sign = U"%"; + my.exp = U"e"; + num_systems.push_back(my); + } -static void _insert_num_systems_lang() { - num_systems[0].lang.insert(StringName("ar")); - num_systems[0].lang.insert(StringName("ar_AR")); - num_systems[0].lang.insert(StringName("ar_BH")); - num_systems[0].lang.insert(StringName("ar_DJ")); - num_systems[0].lang.insert(StringName("ar_EG")); - num_systems[0].lang.insert(StringName("ar_ER")); - num_systems[0].lang.insert(StringName("ar_IL")); - num_systems[0].lang.insert(StringName("ar_IQ")); - num_systems[0].lang.insert(StringName("ar_JO")); - num_systems[0].lang.insert(StringName("ar_KM")); - num_systems[0].lang.insert(StringName("ar_KW")); - num_systems[0].lang.insert(StringName("ar_LB")); - num_systems[0].lang.insert(StringName("ar_MR")); - num_systems[0].lang.insert(StringName("ar_OM")); - num_systems[0].lang.insert(StringName("ar_PS")); - num_systems[0].lang.insert(StringName("ar_QA")); - num_systems[0].lang.insert(StringName("ar_SA")); - num_systems[0].lang.insert(StringName("ar_SD")); - num_systems[0].lang.insert(StringName("ar_SO")); - num_systems[0].lang.insert(StringName("ar_SS")); - num_systems[0].lang.insert(StringName("ar_SY")); - num_systems[0].lang.insert(StringName("ar_TD")); - num_systems[0].lang.insert(StringName("ar_YE")); - - num_systems[1].lang.insert(StringName("fa")); - num_systems[1].lang.insert(StringName("ks")); - num_systems[1].lang.insert(StringName("pa_Arab")); - num_systems[1].lang.insert(StringName("ug")); - num_systems[1].lang.insert(StringName("ur_IN")); - num_systems[1].lang.insert(StringName("ur")); - num_systems[1].lang.insert(StringName("uz_Arab")); - - num_systems[2].lang.insert(StringName("as")); - num_systems[2].lang.insert(StringName("bn")); - num_systems[2].lang.insert(StringName("mni")); - - num_systems[3].lang.insert(StringName("mr")); - num_systems[3].lang.insert(StringName("ne")); - - num_systems[4].lang.insert(StringName("dz")); - - num_systems[5].lang.insert(StringName("sat")); - - num_systems[6].lang.insert(StringName("my")); + // Chakma numerals. + { + NumSystemData ccp; + ccp.lang.insert(StringName("ccp")); // Chakma + ccp.lang.insert(StringName("ccp_BD")); + ccp.lang.insert(StringName("ccp_IN")); + ccp.digits = U"𑄶𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑄿."; + ccp.percent_sign = U"%"; + ccp.exp = U"e"; + num_systems.push_back(ccp); + } + + // Adlam numerals. + { + NumSystemData ff; + ff.lang.insert(StringName("ff")); // Fulah + ff.lang.insert(StringName("ff_Adlm_BF")); + ff.lang.insert(StringName("ff_Adlm_CM")); + ff.lang.insert(StringName("ff_Adlm_GH")); + ff.lang.insert(StringName("ff_Adlm_GM")); + ff.lang.insert(StringName("ff_Adlm_GN")); + ff.lang.insert(StringName("ff_Adlm_GW")); + ff.lang.insert(StringName("ff_Adlm_LR")); + ff.lang.insert(StringName("ff_Adlm_MR")); + ff.lang.insert(StringName("ff_Adlm_NE")); + ff.lang.insert(StringName("ff_Adlm_NG")); + ff.lang.insert(StringName("ff_Adlm_SL")); + ff.lang.insert(StringName("ff_Adlm_SN")); + ff.digits = U"𞥐𞥑𞥒𞥓𞥔𞥕𞥖𞥗𞥘𞥙."; + ff.percent_sign = U"%"; + ff.exp = U"e"; + num_systems.push_back(ff); + } } String TextServerAdvanced::format_number(const String &p_string, const String &p_language) const { - const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language; + const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language; String res = p_string; - for (int i = 0; num_systems[i].lang.size() != 0; i++) { + for (int i = 0; i < num_systems.size(); i++) { if (num_systems[i].lang.has(lang)) { - if (num_systems[i].digits == String()) { + if (num_systems[i].digits.is_empty()) { return p_string; } res.replace("e", num_systems[i].exp); @@ -4770,12 +5020,12 @@ String TextServerAdvanced::format_number(const String &p_string, const String &p } String TextServerAdvanced::parse_number(const String &p_string, const String &p_language) const { - const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language; + const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language; String res = p_string; - for (int i = 0; num_systems[i].lang.size() != 0; i++) { + for (int i = 0; i < num_systems.size(); i++) { if (num_systems[i].lang.has(lang)) { - if (num_systems[i].digits == String()) { + if (num_systems[i].digits.is_empty()) { return p_string; } res.replace(num_systems[i].exp, "e"); @@ -4798,11 +5048,11 @@ String TextServerAdvanced::parse_number(const String &p_string, const String &p_ } String TextServerAdvanced::percent_sign(const String &p_language) const { - const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language; + const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language; - for (int i = 0; num_systems[i].lang.size() != 0; i++) { + for (int i = 0; i < num_systems.size(); i++) { if (num_systems[i].lang.has(lang)) { - if (num_systems[i].percent_sign == String()) { + if (num_systems[i].percent_sign.is_empty()) { return "%"; } return num_systems[i].percent_sign; @@ -4811,14 +5061,47 @@ String TextServerAdvanced::percent_sign(const String &p_language) const { return "%"; } +String TextServerAdvanced::strip_diacritics(const String &p_string) const { + UErrorCode err = U_ZERO_ERROR; + + // Get NFKD normalizer singleton. + const UNormalizer2 *unorm = unorm2_getNFKDInstance(&err); + ERR_FAIL_COND_V_MSG(U_FAILURE(err), TextServer::strip_diacritics(p_string), u_errorName(err)); + + // Convert to UTF-16. + Char16String utf16 = p_string.utf16(); + + // Normalize. + Char16String normalized; + err = U_ZERO_ERROR; + int32_t len = unorm2_normalize(unorm, utf16.ptr(), -1, nullptr, 0, &err); + ERR_FAIL_COND_V_MSG(err != U_BUFFER_OVERFLOW_ERROR, TextServer::strip_diacritics(p_string), u_errorName(err)); + normalized.resize(len); + err = U_ZERO_ERROR; + unorm2_normalize(unorm, utf16.ptr(), -1, normalized.ptrw(), len, &err); + ERR_FAIL_COND_V_MSG(U_FAILURE(err), TextServer::strip_diacritics(p_string), u_errorName(err)); + + // Convert back to UTF-32. + String normalized_string = String::utf16(normalized.ptr(), len); + + // Strip combining characters. + String result; + for (int i = 0; i < normalized_string.length(); i++) { + if (u_getCombiningClass(normalized_string[i]) == 0) { + result += normalized_string[i]; + } + } + return result; +} + TextServerAdvanced::TextServerAdvanced() { _insert_num_systems_lang(); _insert_feature_sets(); - hb_bmp_create_font_funcs(); + _bmp_create_font_funcs(); } TextServerAdvanced::~TextServerAdvanced() { - hb_bmp_free_font_funcs(); + _bmp_free_font_funcs(); if (library != nullptr) { FT_Done_FreeType(library); } diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 1feeada76d..fb9446da9f 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -50,11 +50,12 @@ #include <unicode/udata.h> #include <unicode/uiter.h> #include <unicode/uloc.h> +#include <unicode/unorm2.h> #include <unicode/uscript.h> #include <unicode/ustring.h> #include <unicode/utypes.h> -#include "modules/modules_enabled.gen.h" +#include "modules/modules_enabled.gen.h" // For freetype, msdfgen. #ifdef MODULE_FREETYPE_ENABLED #include <ft2build.h> @@ -79,6 +80,19 @@ class TextServerAdvanced : public TextServer { static String interface_name; static uint32_t interface_features; + struct NumSystemData { + Set<StringName> lang; + String digits; + String percent_sign; + String exp; + }; + + Vector<NumSystemData> num_systems; + Map<StringName, int32_t> feature_sets; + + void _insert_num_systems_lang(); + void _insert_feature_sets(); + // ICU support data. uint8_t *icu_data = nullptr; @@ -163,6 +177,10 @@ class TextServerAdvanced : public TextServer { Dictionary variation_coordinates; float oversampling = 0.f; + uint32_t style_flags = 0; + String font_name; + String style_name; + Map<Vector2i, FontDataForSizeAdvanced *> cache; bool face_init = false; @@ -251,6 +269,7 @@ class TextServerAdvanced : public TextServer { int _convert_pos(const ShapedTextDataAdvanced *p_sd, int p_pos) const; int _convert_pos_inv(const ShapedTextDataAdvanced *p_sd, int p_pos) const; + bool _shape_substr(ShapedTextDataAdvanced *p_new_sd, const ShapedTextDataAdvanced *p_sd, int p_start, int p_length) const; void _shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_start, int32_t p_end, hb_script_t p_script, hb_direction_t p_direction, Vector<RID> p_fonts, int p_span, int p_fb_index); Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size); @@ -258,24 +277,24 @@ class TextServerAdvanced : public TextServer { static hb_font_funcs_t *funcs; - struct hb_bmp_font_t { + struct bmp_font_t { TextServerAdvanced::FontDataForSizeAdvanced *face = nullptr; bool unref = false; /* Whether to destroy bm_face when done. */ }; - static hb_bmp_font_t *_hb_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref); - static void _hb_bmp_font_destroy(void *p_data); - static hb_bool_t hb_bmp_get_nominal_glyph(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_unicode, hb_codepoint_t *r_glyph, void *p_user_data); - static hb_position_t hb_bmp_get_glyph_h_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data); - static hb_position_t hb_bmp_get_glyph_v_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data); - static hb_position_t hb_bmp_get_glyph_h_kerning(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_left_glyph, hb_codepoint_t p_right_glyph, void *p_user_data); - static hb_bool_t hb_bmp_get_glyph_v_origin(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, hb_position_t *r_x, hb_position_t *r_y, void *p_user_data); - static hb_bool_t hb_bmp_get_glyph_extents(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, hb_glyph_extents_t *r_extents, void *p_user_data); - static hb_bool_t hb_bmp_get_font_h_extents(hb_font_t *p_font, void *p_font_data, hb_font_extents_t *r_metrics, void *p_user_data); - static void hb_bmp_create_font_funcs(); - static void hb_bmp_free_font_funcs(); - static void _hb_bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref); - static hb_font_t *hb_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, hb_destroy_func_t p_destroy); + static bmp_font_t *_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref); + static void _bmp_font_destroy(void *p_data); + static hb_bool_t _bmp_get_nominal_glyph(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_unicode, hb_codepoint_t *r_glyph, void *p_user_data); + static hb_position_t _bmp_get_glyph_h_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data); + static hb_position_t _bmp_get_glyph_v_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data); + static hb_position_t _bmp_get_glyph_h_kerning(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_left_glyph, hb_codepoint_t p_right_glyph, void *p_user_data); + static hb_bool_t _bmp_get_glyph_v_origin(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, hb_position_t *r_x, hb_position_t *r_y, void *p_user_data); + static hb_bool_t _bmp_get_glyph_extents(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, hb_glyph_extents_t *r_extents, void *p_user_data); + static hb_bool_t _bmp_get_font_h_extents(hb_font_t *p_font, void *p_font_data, hb_font_extents_t *r_metrics, void *p_user_data); + static void _bmp_create_font_funcs(); + static void _bmp_free_font_funcs(); + static void _bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref); + static hb_font_t *_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, hb_destroy_func_t p_destroy); protected: static void _bind_methods(){}; @@ -307,6 +326,15 @@ public: virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) override; virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) override; + virtual void font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) override; + virtual uint32_t /*FontStyle*/ font_get_style(RID p_font_rid) const override; + + virtual void font_set_style_name(RID p_font_rid, const String &p_name) override; + virtual String font_get_style_name(RID p_font_rid) const override; + + virtual void font_set_name(RID p_font_rid, const String &p_name) override; + virtual String font_get_name(RID p_font_rid) const override; + virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override; virtual bool font_is_antialiased(RID p_font_rid) const override; @@ -436,6 +464,9 @@ public: virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; + virtual void shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) override; + virtual String shaped_text_get_custom_punctuation(RID p_shaped) const override; + virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; virtual Orientation shaped_text_get_orientation(RID p_shaped) const override; @@ -446,8 +477,8 @@ public: virtual bool shaped_text_get_preserve_control(RID p_shaped) const override; virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override; - virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override; - virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override; + virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override; + virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override; virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override; virtual RID shaped_text_get_parent(RID p_shaped) const override; @@ -488,6 +519,8 @@ public: virtual String parse_number(const String &p_string, const String &p_language = "") const override; virtual String percent_sign(const String &p_language = "") const override; + virtual String strip_diacritics(const String &p_string) const override; + TextServerAdvanced(); ~TextServerAdvanced(); }; diff --git a/modules/text_server_fb/register_types.cpp b/modules/text_server_fb/register_types.cpp index 0b59040ce8..a545f84939 100644 --- a/modules/text_server_fb/register_types.cpp +++ b/modules/text_server_fb/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/text_server_fb/register_types.h b/modules/text_server_fb/register_types.h index c854db92e5..8652a8e9db 100644 --- a/modules/text_server_fb/register_types.h +++ b/modules/text_server_fb/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 3d868d7be3..1f7c5427be 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,8 @@ #include "core/error/error_macros.h" #include "core/string/print_string.h" +#include "modules/modules_enabled.gen.h" // For freetype, msdfgen. + #ifdef MODULE_MSDFGEN_ENABLED #include "core/ShapeDistanceFinder.h" #include "core/contour-combiners.h" @@ -111,22 +113,14 @@ bool TextServerFallback::is_locale_right_to_left(const String &p_locale) const { return false; // No RTL support. } -#define OT_TAG(c1, c2, c3, c4) ((int32_t)((((uint32_t)(c1)&0xFF) << 24) | (((uint32_t)(c2)&0xFF) << 16) | (((uint32_t)(c3)&0xFF) << 8) | ((uint32_t)(c4)&0xFF))) - -struct FeatureInfo { - int32_t tag; - String name; -}; - -static FeatureInfo feature_set[] = { - // Registered OpenType variation tags. - { OT_TAG('i', 't', 'a', 'l'), "italic" }, - { OT_TAG('o', 'p', 's', 'z'), "optical_size" }, - { OT_TAG('s', 'l', 'n', 't'), "slant" }, - { OT_TAG('w', 'd', 't', 'h'), "width" }, - { OT_TAG('w', 'g', 'h', 't'), "weight" }, - { 0, String() }, -}; +void TextServerFallback::_insert_feature_sets() { + // Registered OpenType variation tag. + feature_sets.insert("italic", OT_TAG('i', 't', 'a', 'l')); + feature_sets.insert("optical_size", OT_TAG('o', 'p', 's', 'z')); + feature_sets.insert("slant", OT_TAG('s', 'l', 'n', 't')); + feature_sets.insert("width", OT_TAG('w', 'd', 't', 'h')); + feature_sets.insert("weight", OT_TAG('w', 'g', 'h', 't')); +} _FORCE_INLINE_ int32_t ot_tag_from_string(const char *p_str, int p_len) { char tag[4]; @@ -150,10 +144,8 @@ _FORCE_INLINE_ int32_t ot_tag_from_string(const char *p_str, int p_len) { } int32_t TextServerFallback::name_to_tag(const String &p_name) const { - for (int i = 0; feature_set[i].tag != 0; i++) { - if (feature_set[i].name == p_name) { - return feature_set[i].tag; - } + if (feature_sets.has(p_name)) { + return feature_sets[p_name]; } // No readable name, use tag string. @@ -168,9 +160,9 @@ _FORCE_INLINE_ void ot_tag_to_string(int32_t p_tag, char *p_buf) { } String TextServerFallback::tag_to_name(int32_t p_tag) const { - for (int i = 0; feature_set[i].tag != 0; i++) { - if (feature_set[i].tag == p_tag) { - return feature_set[i].name; + for (const KeyValue<StringName, int32_t> &E : feature_sets) { + if (E.value == p_tag) { + return E.key; } } @@ -205,6 +197,10 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ continue; } + if (ct.offsets.size() < ct.texture_w) { + continue; + } + ret.y = 0x7FFFFFFF; ret.x = 0; @@ -403,7 +399,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( FontGlyph chr; chr.found = true; - chr.advance = advance.round(); + chr.advance = advance; if (shape.validate() && shape.contours.size() > 0) { int w = (bounds.r - bounds.l); @@ -421,7 +417,6 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( edgeColoringSimple(shape, 3.0); // Max. angle. msdfgen::Bitmap<float, 4> image(w, h); // Texture size. - //msdfgen::generateMTSDF(image, shape, p_pixel_range, 1.0, msdfgen::Vector2(-bounds.l, -bounds.b)); // Range, scale, translation. DistancePixelConversion distancePixelConversion(p_pixel_range); msdfgen::Projection projection(msdfgen::Vector2(1.0, 1.0), msdfgen::Vector2(-bounds.l, -bounds.b)); @@ -515,11 +510,11 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma case FT_PIXEL_MODE_MONO: { int byte = i * bitmap.pitch + (j >> 3); int bit = 1 << (7 - (j % 8)); - wr[ofs + 0] = 255; //grayscale as 1 + wr[ofs + 0] = 255; // grayscale as 1 wr[ofs + 1] = (bitmap.buffer[byte] & bit) ? 255 : 0; } break; case FT_PIXEL_MODE_GRAY: - wr[ofs + 0] = 255; //grayscale as 1 + wr[ofs + 0] = 255; // grayscale as 1 wr[ofs + 1] = bitmap.buffer[i * bitmap.pitch + j]; break; case FT_PIXEL_MODE_BGRA: { @@ -557,12 +552,12 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma } FontGlyph chr; - chr.advance = (advance * p_data->scale / p_data->oversampling).round(); + chr.advance = advance * p_data->scale / p_data->oversampling; chr.texture_idx = tex_pos.index; chr.found = true; chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w, h); - chr.rect.position = (Vector2(xofs, -yofs) * p_data->scale / p_data->oversampling).round(); + chr.rect.position = Vector2(xofs, -yofs) * p_data->scale / p_data->oversampling; chr.rect.size = chr.uv_rect.size * p_data->scale / p_data->oversampling; return chr; } @@ -677,13 +672,14 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontDataFallback *p_font_d } _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback *p_font_data, const Vector2i &p_size) const { + ERR_FAIL_COND_V(p_size.x <= 0, false); if (p_font_data->cache.has(p_size)) { return true; } FontDataForSizeFallback *fd = memnew(FontDataForSizeFallback); fd->size = p_size; - if (p_font_data->data_ptr) { + if (p_font_data->data_ptr && (p_font_data->data_size > 0)) { // Init dynamic font. #ifdef MODULE_FREETYPE_ENABLED int error = 0; @@ -733,7 +729,8 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback } FT_Select_Size(fd->face, best_match); } else { - FT_Set_Pixel_Sizes(fd->face, 0, fd->size.x * fd->oversampling); + FT_Set_Pixel_Sizes(fd->face, 0, Math::round(fd->size.x * fd->oversampling)); + fd->scale = ((float)fd->size.x * fd->oversampling) / (float)fd->face->size->metrics.y_ppem; } fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->oversampling * fd->scale; @@ -742,6 +739,23 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale; if (!p_font_data->face_init) { + // Get style flags and name. + if (fd->face->family_name != nullptr) { + p_font_data->font_name = String::utf8((const char *)fd->face->family_name); + } + if (fd->face->style_name != nullptr) { + p_font_data->style_name = String::utf8((const char *)fd->face->style_name); + } + p_font_data->style_flags = 0; + if (fd->face->style_flags & FT_STYLE_FLAG_BOLD) { + p_font_data->style_flags |= FONT_BOLD; + } + if (fd->face->style_flags & FT_STYLE_FLAG_ITALIC) { + p_font_data->style_flags |= FONT_ITALIC; + } + if (fd->face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) { + p_font_data->style_flags |= FONT_FIXED_WIDTH; + } // Read OpenType variations. p_font_data->supported_varaitions.clear(); if (fd->face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) { @@ -832,6 +846,66 @@ void TextServerFallback::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data fd->data_size = p_data_size; } +void TextServerFallback::font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + fd->style_flags = p_style; +} + +uint32_t /*FontStyle*/ TextServerFallback::font_get_style(RID p_font_rid) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, 0); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0); + return fd->style_flags; +} + +void TextServerFallback::font_set_style_name(RID p_font_rid, const String &p_name) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + fd->style_name = p_name; +} + +String TextServerFallback::font_get_style_name(RID p_font_rid) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, String()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), String()); + return fd->style_name; +} + +void TextServerFallback::font_set_name(RID p_font_rid, const String &p_name) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + fd->font_name = p_name; +} + +String TextServerFallback::font_get_name(RID p_font_rid) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, String()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), String()); + return fd->font_name; +} + void TextServerFallback::font_set_antialiased(RID p_font_rid, bool p_antialiased) { FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -1253,7 +1327,7 @@ void TextServerFallback::font_remove_texture(RID p_font_rid, const Vector2i &p_s ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); ERR_FAIL_INDEX(p_texture_index, fd->cache[size]->textures.size()); - fd->cache[size]->textures.remove(p_texture_index); + fd->cache[size]->textures.remove_at(p_texture_index); } void TextServerFallback::font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) { @@ -1304,6 +1378,7 @@ void TextServerFallback::font_set_texture_offsets(RID p_font_rid, const Vector2i MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + ERR_FAIL_COND(p_texture_index < 0); if (p_texture_index >= fd->cache[size]->textures.size()) { fd->cache[size]->textures.resize(p_texture_index + 1); } @@ -1661,12 +1736,14 @@ Vector2 TextServerFallback::font_get_kerning(RID p_font_rid, int p_size, const V } int32_t TextServerFallback::font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const { + ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), 0, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + "."); return (int32_t)p_char; } bool TextServerFallback::font_has_char(RID p_font_rid, char32_t p_char) const { FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); + ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), false, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + "."); MutexLock lock(fd->mutex); if (fd->cache.is_empty()) { @@ -1719,6 +1796,8 @@ String TextServerFallback::font_get_supported_chars(RID p_font_rid) const { void TextServerFallback::font_render_range(RID p_font_rid, const Vector2i &p_size, char32_t p_start, char32_t p_end) { FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); + ERR_FAIL_COND_MSG((p_start >= 0xd800 && p_start <= 0xdfff) || (p_start > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_start, 16) + "."); + ERR_FAIL_COND_MSG((p_end >= 0xd800 && p_end <= 0xdfff) || (p_end > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_end, 16) + "."); MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); @@ -1746,7 +1825,7 @@ void TextServerFallback::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz Vector2i size = _get_size(fd, p_size); ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); if (!_ensure_glyph(fd, size, p_index)) { - return; // // Invalid or non graphicl glyph, do not display errors, nothing to draw. + return; // Invalid or non-graphical glyph, do not display errors, nothing to draw. } const FontGlyph &gl = fd->cache[size]->glyph_map[p_index]; @@ -1768,9 +1847,9 @@ void TextServerFallback::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range); } else { - Point2i cpos = p_pos; + Point2 cpos = p_pos.floor(); cpos += gl.rect.position; - Size2i csize = gl.rect.size; + Size2 csize = gl.rect.size; RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false); } } @@ -1786,7 +1865,7 @@ void TextServerFallback::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i Vector2i size = _get_size_outline(fd, Vector2i(p_size, p_outline_size)); ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); if (!_ensure_glyph(fd, size, p_index)) { - return; // // Invalid or non graphicl glyph, do not display errors, nothing to draw. + return; // Invalid or non-graphical glyph, do not display errors, nothing to draw. } const FontGlyph &gl = fd->cache[size]->glyph_map[p_index]; @@ -1808,9 +1887,9 @@ void TextServerFallback::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range); } else { - Point2i cpos = p_pos; + Point2 cpos = p_pos.floor(); cpos += gl.rect.position; - Size2i csize = gl.rect.size; + Size2 csize = gl.rect.size; RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false); } } @@ -2031,6 +2110,27 @@ TextServer::Direction TextServerFallback::shaped_text_get_direction(RID p_shaped return TextServer::DIRECTION_LTR; } +void TextServerFallback::shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) { + _THREAD_SAFE_METHOD_ + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND(!sd); + + if (sd->custom_punct != p_punct) { + if (sd->parent != RID()) { + full_copy(sd); + } + sd->custom_punct = p_punct; + invalidate(sd); + } +} + +String TextServerFallback::shaped_text_get_custom_punctuation(RID p_shaped) const { + _THREAD_SAFE_METHOD_ + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, String()); + return sd->custom_punct; +} + void TextServerFallback::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) { ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); @@ -2148,7 +2248,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te return true; } -bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) { +bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) { ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); @@ -2161,7 +2261,7 @@ bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, con } ShapedTextData::Span span; - span.start = sd->text.length(); + span.start = sd->start + sd->text.length(); span.end = span.start + p_length; span.embedded_key = p_key; @@ -2179,7 +2279,7 @@ bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, con return true; } -bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) { +bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) { ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); @@ -2247,57 +2347,57 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.y = -sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.y = (-sd->ascent + sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.y = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.y = sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.y -= E.value.rect.size.y; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.y -= E.value.rect.size.y / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.y); full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.x = -sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.x = (-sd->ascent + sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.x = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.x = sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.x -= E.value.rect.size.x; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.x -= E.value.rect.size.x / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.x); @@ -2333,6 +2433,7 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng new_sd->orientation = sd->orientation; new_sd->direction = sd->direction; + new_sd->custom_punct = sd->custom_punct; new_sd->para_direction = sd->para_direction; new_sd->line_breaks_valid = sd->line_breaks_valid; new_sd->justification_ops_valid = sd->justification_ops_valid; @@ -2341,7 +2442,7 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng new_sd->uthk = sd->uthk; if (p_length > 0) { - new_sd->text = sd->text.substr(p_start, p_length); + new_sd->text = sd->text.substr(p_start - sd->start, p_length); int sd_size = sd->glyphs.size(); const Glyph *sd_glyphs = sd->glyphs.ptr(); @@ -2398,57 +2499,57 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) { if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.y = -new_sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.y = (-new_sd->ascent + new_sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.y = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.y = new_sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.y -= E.value.rect.size.y; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.y -= E.value.rect.size.y / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.y); full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.x = -new_sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.x = (-new_sd->ascent + new_sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.x = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.x = new_sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.x -= E.value.rect.size.x; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.x -= E.value.rect.size.x / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.x); @@ -2616,27 +2717,41 @@ bool TextServerFallback::shaped_text_update_breaks(RID p_shaped) { } int sd_size = sd->glyphs.size(); + Glyph *sd_glyphs = sd->glyphs.ptrw(); + + int c_punct_size = sd->custom_punct.length(); + const char32_t *c_punct = sd->custom_punct.ptr(); + for (int i = 0; i < sd_size; i++) { - if (sd->glyphs[i].count > 0) { - char32_t c = sd->text[sd->glyphs[i].start]; - if (is_punct(c)) { - sd->glyphs.write[i].flags |= GRAPHEME_IS_PUNCTUATION; + if (sd_glyphs[i].count > 0) { + char32_t c = sd->text[sd_glyphs[i].start - sd->start]; + if (c_punct_size == 0) { + if (is_punct(c)) { + sd_glyphs[i].flags |= GRAPHEME_IS_PUNCTUATION; + } + } else { + for (int j = 0; j < c_punct_size; j++) { + if (c_punct[j] == c) { + sd_glyphs[i].flags |= GRAPHEME_IS_PUNCTUATION; + break; + } + } } if (is_underscore(c)) { sd->glyphs.write[i].flags |= GRAPHEME_IS_UNDERSCORE; } if (is_whitespace(c) && !is_linebreak(c)) { - sd->glyphs.write[i].flags |= GRAPHEME_IS_SPACE; - sd->glyphs.write[i].flags |= GRAPHEME_IS_BREAK_SOFT; + sd_glyphs[i].flags |= GRAPHEME_IS_SPACE; + sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_SOFT; } if (is_linebreak(c)) { - sd->glyphs.write[i].flags |= GRAPHEME_IS_BREAK_HARD; + sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_HARD; } if (c == 0x0009 || c == 0x000b) { - sd->glyphs.write[i].flags |= GRAPHEME_IS_TAB; + sd_glyphs[i].flags |= GRAPHEME_IS_TAB; } - i += (sd->glyphs[i].count - 1); + i += (sd_glyphs[i].count - 1); } } sd->line_breaks_valid = true; @@ -2714,10 +2829,10 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl width -= sd_glyphs[i].advance * sd_glyphs[i].repeat; if (sd_glyphs[i].count > 0) { - bool above_min_char_treshold = (i >= ell_min_characters); + bool above_min_char_threshold = (i >= ell_min_characters); - if (width + (((above_min_char_treshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_width : 0) <= p_width) { - if (cut_per_word && above_min_char_treshold) { + if (width + (((above_min_char_threshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_width : 0) <= p_width) { + if (cut_per_word && above_min_char_threshold) { if ((sd_glyphs[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) { last_valid_cut = i; found = true; @@ -2729,7 +2844,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl if (found) { trim_pos = last_valid_cut; - if (add_ellipsis && (above_min_char_treshold || enforce_ellipsis) && width - ellipsis_width <= p_width) { + if (add_ellipsis && (above_min_char_threshold || enforce_ellipsis) && width - ellipsis_width <= p_width) { ellipsis_pos = trim_pos; } break; @@ -2866,7 +2981,7 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { gl.end = j + 1; gl.count = 1; gl.font_size = span.font_size; - gl.index = (int32_t)sd->text[j]; // Use codepoint. + gl.index = (int32_t)sd->text[j - sd->start]; // Use codepoint. if (gl.index == 0x0009 || gl.index == 0x000b) { gl.index = 0x0020; } @@ -2882,7 +2997,7 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { } if (gl.font_rid.is_valid()) { - if (sd->text[j] != 0 && !is_linebreak(sd->text[j])) { + if (sd->text[j - sd->start] != 0 && !is_linebreak(sd->text[j - sd->start])) { if (sd->orientation == ORIENTATION_HORIZONTAL) { gl.advance = font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x; gl.x_off = 0; @@ -2897,7 +3012,7 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { sd->descent = MAX(sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); } } - if (font_get_spacing(gl.font_rid, gl.font_size, TextServer::SPACING_SPACE) && is_whitespace(sd->text[j])) { + if (font_get_spacing(gl.font_rid, gl.font_size, TextServer::SPACING_SPACE) && is_whitespace(sd->text[j - sd->start])) { gl.advance += font_get_spacing(gl.font_rid, gl.font_size, TextServer::SPACING_SPACE); } else { gl.advance += font_get_spacing(gl.font_rid, gl.font_size, TextServer::SPACING_GLYPH); @@ -2938,57 +3053,57 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { float full_descent = sd->descent; for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.y = -sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.y = (-sd->ascent + sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.y = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.y = sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.y -= E.value.rect.size.y; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.y -= E.value.rect.size.y / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.y); full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { - case INLINE_ALIGN_TO_TOP: { + switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) { + case INLINE_ALIGNMENT_TO_TOP: { E.value.rect.position.x = -sd->ascent; } break; - case INLINE_ALIGN_TO_CENTER: { + case INLINE_ALIGNMENT_TO_CENTER: { E.value.rect.position.x = (-sd->ascent + sd->descent) / 2; } break; - case INLINE_ALIGN_TO_BASELINE: { + case INLINE_ALIGNMENT_TO_BASELINE: { E.value.rect.position.x = 0; } break; - case INLINE_ALIGN_TO_BOTTOM: { + case INLINE_ALIGNMENT_TO_BOTTOM: { E.value.rect.position.x = sd->descent; } break; } - switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { - case INLINE_ALIGN_BOTTOM_TO: { + switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) { + case INLINE_ALIGNMENT_BOTTOM_TO: { E.value.rect.position.x -= E.value.rect.size.x; } break; - case INLINE_ALIGN_CENTER_TO: { + case INLINE_ALIGNMENT_CENTER_TO: { E.value.rect.position.x -= E.value.rect.size.x / 2; } break; - case INLINE_ALIGN_TOP_TO: { - //NOP + case INLINE_ALIGNMENT_TOP_TO: { + // NOP } break; } full_ascent = MAX(full_ascent, -E.value.rect.position.x); @@ -3148,10 +3263,14 @@ float TextServerFallback::shaped_text_get_underline_thickness(RID p_shaped) cons return sd->uthk; } -TextServerFallback::TextServerFallback(){}; +TextServerFallback::TextServerFallback() { + _insert_feature_sets(); +}; TextServerFallback::~TextServerFallback() { +#ifdef MODULE_FREETYPE_ENABLED if (library != nullptr) { FT_Done_FreeType(library); } +#endif }; diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 992ce5018f..d47fa44f8f 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -42,7 +42,7 @@ #include "core/templates/thread_work_pool.h" #include "scene/resources/texture.h" -#include "modules/modules_enabled.gen.h" +#include "modules/modules_enabled.gen.h" // For freetype, msdfgen. #ifdef MODULE_FREETYPE_ENABLED #include <ft2build.h> @@ -54,6 +54,8 @@ #include FT_BBOX_H #endif +#define OT_TAG(c1, c2, c3, c4) ((int32_t)((((uint32_t)(c1)&0xFF) << 24) | (((uint32_t)(c2)&0xFF) << 16) | (((uint32_t)(c3)&0xFF) << 8) | ((uint32_t)(c4)&0xFF))) + class TextServerFallback : public TextServer { GDCLASS(TextServerFallback, TextServer); _THREAD_SAFE_CLASS_ @@ -61,6 +63,10 @@ class TextServerFallback : public TextServer { static String interface_name; static uint32_t interface_features; + Map<StringName, int32_t> feature_sets; + + void _insert_feature_sets(); + // Font cache data. #ifdef MODULE_FREETYPE_ENABLED @@ -136,6 +142,10 @@ class TextServerFallback : public TextServer { Dictionary variation_coordinates; float oversampling = 0.f; + uint32_t style_flags = 0; + String font_name; + String style_name; + Map<Vector2i, FontDataForSizeFallback *> cache; bool face_init = false; @@ -228,6 +238,15 @@ public: virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) override; virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) override; + virtual void font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) override; + virtual uint32_t /*FontStyle*/ font_get_style(RID p_font_rid) const override; + + virtual void font_set_style_name(RID p_font_rid, const String &p_name) override; + virtual String font_get_style_name(RID p_font_rid) const override; + + virtual void font_set_name(RID p_font_rid, const String &p_name) override; + virtual String font_get_name(RID p_font_rid) const override; + virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override; virtual bool font_is_antialiased(RID p_font_rid) const override; @@ -355,6 +374,9 @@ public: virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; + virtual void shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) override; + virtual String shaped_text_get_custom_punctuation(RID p_shaped) const override; + virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; virtual Orientation shaped_text_get_orientation(RID p_shaped) const override; @@ -365,8 +387,8 @@ public: virtual bool shaped_text_get_preserve_control(RID p_shaped) const override; virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override; - virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override; - virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override; + virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override; + virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override; virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override; virtual RID shaped_text_get_parent(RID p_shaped) const override; diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index f0d7c335bd..5060c1ab35 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index e4463a322f..feaff5925f 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/tga/register_types.cpp b/modules/tga/register_types.cpp index 9e5fe124ef..35f9d10956 100644 --- a/modules/tga/register_types.cpp +++ b/modules/tga/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/tga/register_types.h b/modules/tga/register_types.h index 0dcd750250..ae91aa560f 100644 --- a/modules/tga/register_types.h +++ b/modules/tga/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/theora/config.py b/modules/theora/config.py index b063ed51f9..7f354a8fda 100644 --- a/modules/theora/config.py +++ b/modules/theora/config.py @@ -1,4 +1,6 @@ def can_build(env, platform): + if env["arch"].startswith("rv"): + return False return env.module_check_dependencies("theora", ["ogg", "vorbis"]) diff --git a/modules/theora/doc_classes/VideoStreamTheora.xml b/modules/theora/doc_classes/VideoStreamTheora.xml index 2dfcd27dff..725f87b046 100644 --- a/modules/theora/doc_classes/VideoStreamTheora.xml +++ b/modules/theora/doc_classes/VideoStreamTheora.xml @@ -4,7 +4,7 @@ [VideoStream] resource for Ogg Theora videos. </brief_description> <description> - [VideoStream] resource handling the [url=https://www.theora.org/]Ogg Theora[/url] video format with [code].ogv[/code] extension. The Theora codec is less efficient than [VideoStreamWebm]'s VP8 and VP9, but it requires less CPU resources to decode. The Theora codec is decoded on the CPU. + [VideoStream] resource handling the [url=https://www.theora.org/]Ogg Theora[/url] video format with [code].ogv[/code] extension. The Theora codec is decoded on the CPU. [b]Note:[/b] While Ogg Theora videos can also have an [code].ogg[/code] extension, you will have to rename the extension to [code].ogv[/code] to use those videos within Godot. </description> <tutorials> diff --git a/modules/theora/register_types.cpp b/modules/theora/register_types.cpp index 55148a6b87..f658627574 100644 --- a/modules/theora/register_types.cpp +++ b/modules/theora/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/theora/register_types.h b/modules/theora/register_types.h index 654d70e417..d0c089ef49 100644 --- a/modules/theora/register_types.h +++ b/modules/theora/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 2f6faec8ec..9d297fcb93 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -108,7 +108,7 @@ void VideoStreamPlaybackTheora::video_write() { Ref<Image> img = memnew(Image(size.x, size.y, 0, Image::FORMAT_RGBA8, frame_data)); //zero copy image creation - texture->update(img); //zero copy send to visual server + texture->update(img); //zero copy send to rendering server frames_pending = 1; } @@ -603,7 +603,7 @@ float VideoStreamPlaybackTheora::get_playback_position() const { }; void VideoStreamPlaybackTheora::seek(float p_time) { - WARN_PRINT_ONCE("Seeking in Theora and WebM videos is not implemented yet (it's only supported for GDNative-provided video streams)."); + WARN_PRINT_ONCE("Seeking in Theora videos is not implemented yet (it's only supported for GDNative-provided video streams)."); } void VideoStreamPlaybackTheora::set_mix_callback(AudioMixCallback p_callback, void *p_userdata) { @@ -673,7 +673,7 @@ void VideoStreamTheora::_bind_methods() { ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamTheora::set_file); ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamTheora::get_file); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_file", "get_file"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_file", "get_file"); } //////////// diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index 760173d0df..3bc96908a2 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/tinyexr/SCsub b/modules/tinyexr/SCsub index 30bde96fb4..bf9242cc16 100644 --- a/modules/tinyexr/SCsub +++ b/modules/tinyexr/SCsub @@ -20,6 +20,9 @@ env_tinyexr.Prepend(CPPPATH=[thirdparty_dir]) # Enable threaded loading with C++11. env_tinyexr.Append(CPPDEFINES=["TINYEXR_USE_THREAD"]) +# miniz is an external dependency, we could add it but we can instead rely +# on our existing bundled zlib. +env_tinyexr.Append(CPPDEFINES=[("TINYEXR_USE_MINIZ", 0)]) env_thirdparty = env_tinyexr.Clone() env_thirdparty.disable_warnings() diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index eb7a8597e6..688707a42d 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,8 @@ #include "core/os/os.h" #include "core/string/print_string.h" +#include <zlib.h> // Should come before including tinyexr. + #include "thirdparty/tinyexr/tinyexr.h" Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h index 34390fccb0..aba5fdb959 100644 --- a/modules/tinyexr/image_loader_tinyexr.h +++ b/modules/tinyexr/image_loader_tinyexr.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/tinyexr/image_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp index 6a2fb0f666..3750994663 100644 --- a/modules/tinyexr/image_saver_tinyexr.cpp +++ b/modules/tinyexr/image_saver_tinyexr.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,8 @@ #include "image_saver_tinyexr.h" #include "core/math/math_funcs.h" +#include <zlib.h> // Should come before including tinyexr. + #include "thirdparty/tinyexr/tinyexr.h" static bool is_supported_format(Image::Format p_format) { diff --git a/modules/tinyexr/image_saver_tinyexr.h b/modules/tinyexr/image_saver_tinyexr.h index e5060ef11c..5bf95b265e 100644 --- a/modules/tinyexr/image_saver_tinyexr.h +++ b/modules/tinyexr/image_saver_tinyexr.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/tinyexr/register_types.cpp b/modules/tinyexr/register_types.cpp index ecbabc4951..0879a55b6e 100644 --- a/modules/tinyexr/register_types.cpp +++ b/modules/tinyexr/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/tinyexr/register_types.h b/modules/tinyexr/register_types.h index e401f37066..4c34757d8b 100644 --- a/modules/tinyexr/register_types.h +++ b/modules/tinyexr/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/upnp/SCsub b/modules/upnp/SCsub index b2fed0cb23..4b385b820d 100644 --- a/modules/upnp/SCsub +++ b/modules/upnp/SCsub @@ -26,9 +26,9 @@ if env["builtin_miniupnpc"]: "receivedata.c", "addr_is_reserved.c", ] - thirdparty_sources = [thirdparty_dir + "miniupnpc/" + file for file in thirdparty_sources] + thirdparty_sources = [thirdparty_dir + "src/" + file for file in thirdparty_sources] - env_upnp.Prepend(CPPPATH=[thirdparty_dir]) + env_upnp.Prepend(CPPPATH=[thirdparty_dir + "include"]) env_upnp.Append(CPPDEFINES=["MINIUPNP_STATICLIB"]) env_upnp.Append(CPPDEFINES=["MINIUPNPC_SET_SOCKET_TIMEOUT"]) diff --git a/modules/upnp/register_types.cpp b/modules/upnp/register_types.cpp index 1e5edd3602..7345901829 100644 --- a/modules/upnp/register_types.cpp +++ b/modules/upnp/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/upnp/register_types.h b/modules/upnp/register_types.h index 768031c4d9..e4482314f8 100644 --- a/modules/upnp/register_types.h +++ b/modules/upnp/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp index efe618012a..d762ca4f09 100644 --- a/modules/upnp/upnp.cpp +++ b/modules/upnp/upnp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,17 +30,17 @@ #include "upnp.h" -#include <miniupnpc/miniwget.h> -#include <miniupnpc/upnpcommands.h> +#include <miniwget.h> +#include <upnpcommands.h> #include <stdlib.h> bool UPNP::is_common_device(const String &dev) const { return dev.is_empty() || - dev.find("InternetGatewayDevice") >= 0 || - dev.find("WANIPConnection") >= 0 || - dev.find("WANPPPConnection") >= 0 || - dev.find("rootdevice") >= 0; + dev.find("InternetGatewayDevice") >= 0 || + dev.find("WANIPConnection") >= 0 || + dev.find("WANPPPConnection") >= 0 || + dev.find("rootdevice") >= 0; } int UPNP::discover(int timeout, int ttl, const String &device_filter) { @@ -257,7 +257,7 @@ void UPNP::set_device(int index, Ref<UPNPDevice> device) { void UPNP::remove_device(int index) { ERR_FAIL_INDEX(index, devices.size()); - devices.remove(index); + devices.remove_at(index); } void UPNP::clear_devices() { diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h index b961a9667f..6d87b42c56 100644 --- a/modules/upnp/upnp.h +++ b/modules/upnp/upnp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,7 +35,7 @@ #include "upnp_device.h" -#include <miniupnpc/miniupnpc.h> +#include <miniupnpc.h> class UPNP : public RefCounted { GDCLASS(UPNP, RefCounted); diff --git a/modules/upnp/upnp_device.cpp b/modules/upnp/upnp_device.cpp index ddc66d593c..4009a399f2 100644 --- a/modules/upnp/upnp_device.cpp +++ b/modules/upnp/upnp_device.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,7 @@ #include "upnp.h" -#include <miniupnpc/upnpcommands.h> +#include <upnpcommands.h> String UPNPDevice::query_external_address() const { ERR_FAIL_COND_V_MSG(!is_valid_gateway(), "", "The Internet Gateway Device must be valid."); diff --git a/modules/upnp/upnp_device.h b/modules/upnp/upnp_device.h index 0a66c36ab9..18491dce27 100644 --- a/modules/upnp/upnp_device.h +++ b/modules/upnp/upnp_device.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/vhacd/register_types.cpp b/modules/vhacd/register_types.cpp index 54240e66fc..6242c8faa3 100644 --- a/modules/vhacd/register_types.cpp +++ b/modules/vhacd/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/vhacd/register_types.h b/modules/vhacd/register_types.h index 24ad9378f4..e0e34d494d 100644 --- a/modules/vhacd/register_types.h +++ b/modules/vhacd/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/visual_script/SCsub b/modules/visual_script/SCsub index 16faea08d7..b91cceae09 100644 --- a/modules/visual_script/SCsub +++ b/modules/visual_script/SCsub @@ -6,3 +6,6 @@ Import("env_modules") env_vs = env_modules.Clone() env_vs.add_source_files(env.modules_sources, "*.cpp") + +if env["tools"]: + env_vs.add_source_files(env.modules_sources, "editor/*.cpp") diff --git a/modules/visual_script/config.py b/modules/visual_script/config.py index b15479797c..e8990c43c8 100644 --- a/modules/visual_script/config.py +++ b/modules/visual_script/config.py @@ -17,6 +17,7 @@ def get_doc_classes(): "VisualScriptConstant", "VisualScriptConstructor", "VisualScriptCustomNode", + "VisualScriptCustomNodes", "VisualScriptDeconstruct", "VisualScriptEditor", "VisualScriptEmitSignal", diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml index 372d46bc10..a452974014 100644 --- a/modules/visual_script/doc_classes/VisualScript.xml +++ b/modules/visual_script/doc_classes/VisualScript.xml @@ -9,7 +9,7 @@ You are most likely to use this class via the Visual Script editor or when writing plugins for it. </description> <tutorials> - <link title="VisualScript tutorial index">https://docs.godotengine.org/en/latest/getting_started/scripting/visual_script/index.html</link> + <link title="VisualScript documentation index">$DOCS_URL/tutorials/scripting/visual_script/index.html</link> </tutorials> <methods> <method name="add_custom_signal"> diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml index 942d92311b..1ac5768755 100644 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -16,85 +16,85 @@ </members> <constants> <constant name="MATH_SIN" value="0" enum="BuiltinFunc"> - Return the sine of the input. + Returns the sine of the input. </constant> <constant name="MATH_COS" value="1" enum="BuiltinFunc"> - Return the cosine of the input. + Returns the cosine of the input. </constant> <constant name="MATH_TAN" value="2" enum="BuiltinFunc"> - Return the tangent of the input. + Returns the tangent of the input. </constant> <constant name="MATH_SINH" value="3" enum="BuiltinFunc"> - Return the hyperbolic sine of the input. + Returns the hyperbolic sine of the input. </constant> <constant name="MATH_COSH" value="4" enum="BuiltinFunc"> - Return the hyperbolic cosine of the input. + Returns the hyperbolic cosine of the input. </constant> <constant name="MATH_TANH" value="5" enum="BuiltinFunc"> - Return the hyperbolic tangent of the input. + Returns the hyperbolic tangent of the input. </constant> <constant name="MATH_ASIN" value="6" enum="BuiltinFunc"> - Return the arc sine of the input. + Returns the arc sine of the input. </constant> <constant name="MATH_ACOS" value="7" enum="BuiltinFunc"> - Return the arc cosine of the input. + Returns the arc cosine of the input. </constant> <constant name="MATH_ATAN" value="8" enum="BuiltinFunc"> - Return the arc tangent of the input. + Returns the arc tangent of the input. </constant> <constant name="MATH_ATAN2" value="9" enum="BuiltinFunc"> - Return the arc tangent of the input, using the signs of both parameters to determine the exact angle. + Returns the arc tangent of the input, using the signs of both parameters to determine the exact angle. </constant> <constant name="MATH_SQRT" value="10" enum="BuiltinFunc"> - Return the square root of the input. + Returns the square root of the input. </constant> <constant name="MATH_FMOD" value="11" enum="BuiltinFunc"> - Return the remainder of one input divided by the other, using floating-point numbers. + Returns the remainder of one input divided by the other, using floating-point numbers. </constant> <constant name="MATH_FPOSMOD" value="12" enum="BuiltinFunc"> - Return the positive remainder of one input divided by the other, using floating-point numbers. + Returns the positive remainder of one input divided by the other, using floating-point numbers. </constant> <constant name="MATH_FLOOR" value="13" enum="BuiltinFunc"> - Return the input rounded down. + Returns the input rounded down. </constant> <constant name="MATH_CEIL" value="14" enum="BuiltinFunc"> - Return the input rounded up. + Returns the input rounded up. </constant> <constant name="MATH_ROUND" value="15" enum="BuiltinFunc"> - Return the input rounded to the nearest integer. + Returns the input rounded to the nearest integer. </constant> <constant name="MATH_ABS" value="16" enum="BuiltinFunc"> - Return the absolute value of the input. + Returns the absolute value of the input. </constant> <constant name="MATH_SIGN" value="17" enum="BuiltinFunc"> - Return the sign of the input, turning it into 1, -1, or 0. Useful to determine if the input is positive or negative. + Returns the sign of the input, turning it into 1, -1, or 0. Useful to determine if the input is positive or negative. </constant> <constant name="MATH_POW" value="18" enum="BuiltinFunc"> - Return the input raised to a given power. + Returns the input raised to a given power. </constant> <constant name="MATH_LOG" value="19" enum="BuiltinFunc"> - Return the natural logarithm of the input. Note that this is not the typical base-10 logarithm function calculators use. + Returns the natural logarithm of the input. Note that this is not the typical base-10 logarithm function calculators use. </constant> <constant name="MATH_EXP" value="20" enum="BuiltinFunc"> - Return the mathematical constant [b]e[/b] raised to the specified power of the input. [b]e[/b] has an approximate value of 2.71828. + Returns the mathematical constant [b]e[/b] raised to the specified power of the input. [b]e[/b] has an approximate value of 2.71828. </constant> <constant name="MATH_ISNAN" value="21" enum="BuiltinFunc"> - Return whether the input is NaN (Not a Number) or not. NaN is usually produced by dividing 0 by 0, though other ways exist. + Returns whether the input is NaN (Not a Number) or not. NaN is usually produced by dividing 0 by 0, though other ways exist. </constant> <constant name="MATH_ISINF" value="22" enum="BuiltinFunc"> - Return whether the input is an infinite floating-point number or not. Infinity is usually produced by dividing a number by 0, though other ways exist. + Returns whether the input is an infinite floating-point number or not. Infinity is usually produced by dividing a number by 0, though other ways exist. </constant> <constant name="MATH_EASE" value="23" enum="BuiltinFunc"> Easing function, based on exponent. 0 is constant, 1 is linear, 0 to 1 is ease-in, 1+ is ease out. Negative values are in-out/out in. </constant> <constant name="MATH_STEP_DECIMALS" value="24" enum="BuiltinFunc"> - Return the number of digit places after the decimal that the first non-zero digit occurs. + Returns the number of digit places after the decimal that the first non-zero digit occurs. </constant> <constant name="MATH_SNAPPED" value="25" enum="BuiltinFunc"> - Return the input snapped to a given step. + Returns the input snapped to a given step. </constant> <constant name="MATH_LERP" value="26" enum="BuiltinFunc"> - Return a number linearly interpolated between the first two inputs, based on the third input. Uses the formula [code]a + (a - b) * t[/code]. + Returns a number linearly interpolated between the first two inputs, based on the third input. Uses the formula [code]a + (a - b) * t[/code]. </constant> <constant name="MATH_INVERSE_LERP" value="27" enum="BuiltinFunc"> </constant> @@ -107,106 +107,112 @@ Randomize the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time. </constant> <constant name="MATH_RANDI" value="31" enum="BuiltinFunc"> - Return a random 32 bits integer value. To obtain a random value between 0 to N (where N is smaller than 2^32 - 1), you can use it with the remainder function. + Returns a random 32 bits integer value. To obtain a random value between 0 to N (where N is smaller than 2^32 - 1), you can use it with the remainder function. </constant> <constant name="MATH_RANDF" value="32" enum="BuiltinFunc"> - Return a random floating-point value between 0 and 1. To obtain a random value between 0 to N, you can use it with multiplication. + Returns a random floating-point value between 0 and 1. To obtain a random value between 0 to N, you can use it with multiplication. </constant> - <constant name="MATH_RANDF_RANGE" value="33" enum="BuiltinFunc"> - Return a random floating-point value between the two inputs. + <constant name="MATH_RANDI_RANGE" value="33" enum="BuiltinFunc"> + Returns a random 32-bit integer value between the two inputs. </constant> - <constant name="MATH_RANDI_RANGE" value="34" enum="BuiltinFunc"> - Return a random 32-bit integer value between the two inputs. + <constant name="MATH_RANDF_RANGE" value="34" enum="BuiltinFunc"> + Returns a random floating-point value between the two inputs. </constant> - <constant name="MATH_SEED" value="35" enum="BuiltinFunc"> + <constant name="MATH_RANDFN" value="35" enum="BuiltinFunc"> + Returns a normally-distributed pseudo-random number, using Box-Muller transform with the specified mean and a standard deviation. This is also called Gaussian distribution. + </constant> + <constant name="MATH_SEED" value="36" enum="BuiltinFunc"> Set the seed for the random number generator. </constant> - <constant name="MATH_RANDSEED" value="36" enum="BuiltinFunc"> - Return a random value from the given seed, along with the new seed. + <constant name="MATH_RANDSEED" value="37" enum="BuiltinFunc"> + Returns a random value from the given seed, along with the new seed. </constant> - <constant name="MATH_DEG2RAD" value="37" enum="BuiltinFunc"> + <constant name="MATH_DEG2RAD" value="38" enum="BuiltinFunc"> Convert the input from degrees to radians. </constant> - <constant name="MATH_RAD2DEG" value="38" enum="BuiltinFunc"> + <constant name="MATH_RAD2DEG" value="39" enum="BuiltinFunc"> Convert the input from radians to degrees. </constant> - <constant name="MATH_LINEAR2DB" value="39" enum="BuiltinFunc"> + <constant name="MATH_LINEAR2DB" value="40" enum="BuiltinFunc"> Convert the input from linear volume to decibel volume. </constant> - <constant name="MATH_DB2LINEAR" value="40" enum="BuiltinFunc"> + <constant name="MATH_DB2LINEAR" value="41" enum="BuiltinFunc"> Convert the input from decibel volume to linear volume. </constant> - <constant name="MATH_WRAP" value="41" enum="BuiltinFunc"> + <constant name="MATH_WRAP" value="42" enum="BuiltinFunc"> + </constant> + <constant name="MATH_WRAPF" value="43" enum="BuiltinFunc"> </constant> - <constant name="MATH_WRAPF" value="42" enum="BuiltinFunc"> + <constant name="MATH_PINGPONG" value="44" enum="BuiltinFunc"> + Returns the [code]value[/code] wrapped between [code]0[/code] and the [code]length[/code]. If the limit is reached, the next value the function returned is decreased to the [code]0[/code] side or increased to the [code]length[/code] side (like a triangle wave). If [code]length[/code] is less than zero, it becomes positive. </constant> - <constant name="LOGIC_MAX" value="43" enum="BuiltinFunc"> - Return the greater of the two numbers, also known as their maximum. + <constant name="LOGIC_MAX" value="45" enum="BuiltinFunc"> + Returns the greater of the two numbers, also known as their maximum. </constant> - <constant name="LOGIC_MIN" value="44" enum="BuiltinFunc"> - Return the lesser of the two numbers, also known as their minimum. + <constant name="LOGIC_MIN" value="46" enum="BuiltinFunc"> + Returns the lesser of the two numbers, also known as their minimum. </constant> - <constant name="LOGIC_CLAMP" value="45" enum="BuiltinFunc"> - Return the input clamped inside the given range, ensuring the result is never outside it. Equivalent to [code]min(max(input, range_low), range_high)[/code]. + <constant name="LOGIC_CLAMP" value="47" enum="BuiltinFunc"> + Returns the input clamped inside the given range, ensuring the result is never outside it. Equivalent to [code]min(max(input, range_low), range_high)[/code]. </constant> - <constant name="LOGIC_NEAREST_PO2" value="46" enum="BuiltinFunc"> - Return the nearest power of 2 to the input. + <constant name="LOGIC_NEAREST_PO2" value="48" enum="BuiltinFunc"> + Returns the nearest power of 2 to the input. </constant> - <constant name="OBJ_WEAKREF" value="47" enum="BuiltinFunc"> + <constant name="OBJ_WEAKREF" value="49" enum="BuiltinFunc"> Create a [WeakRef] from the input. </constant> - <constant name="TYPE_CONVERT" value="48" enum="BuiltinFunc"> + <constant name="TYPE_CONVERT" value="50" enum="BuiltinFunc"> Convert between types. </constant> - <constant name="TYPE_OF" value="49" enum="BuiltinFunc"> - Return the type of the input as an integer. Check [enum Variant.Type] for the integers that might be returned. + <constant name="TYPE_OF" value="51" enum="BuiltinFunc"> + Returns the type of the input as an integer. Check [enum Variant.Type] for the integers that might be returned. </constant> - <constant name="TYPE_EXISTS" value="50" enum="BuiltinFunc"> + <constant name="TYPE_EXISTS" value="52" enum="BuiltinFunc"> Checks if a type is registered in the [ClassDB]. </constant> - <constant name="TEXT_CHAR" value="51" enum="BuiltinFunc"> - Return a character with the given ascii value. + <constant name="TEXT_CHAR" value="53" enum="BuiltinFunc"> + Returns a character with the given ascii value. </constant> - <constant name="TEXT_STR" value="52" enum="BuiltinFunc"> + <constant name="TEXT_STR" value="54" enum="BuiltinFunc"> Convert the input to a string. </constant> - <constant name="TEXT_PRINT" value="53" enum="BuiltinFunc"> + <constant name="TEXT_PRINT" value="55" enum="BuiltinFunc"> Print the given string to the output window. </constant> - <constant name="TEXT_PRINTERR" value="54" enum="BuiltinFunc"> + <constant name="TEXT_PRINTERR" value="56" enum="BuiltinFunc"> Print the given string to the standard error output. </constant> - <constant name="TEXT_PRINTRAW" value="55" enum="BuiltinFunc"> + <constant name="TEXT_PRINTRAW" value="57" enum="BuiltinFunc"> Print the given string to the standard output, without adding a newline. </constant> - <constant name="TEXT_PRINT_VERBOSE" value="56" enum="BuiltinFunc"> + <constant name="TEXT_PRINT_VERBOSE" value="58" enum="BuiltinFunc"> </constant> - <constant name="VAR_TO_STR" value="57" enum="BuiltinFunc"> + <constant name="VAR_TO_STR" value="59" enum="BuiltinFunc"> Serialize a [Variant] to a string. </constant> - <constant name="STR_TO_VAR" value="58" enum="BuiltinFunc"> + <constant name="STR_TO_VAR" value="60" enum="BuiltinFunc"> Deserialize a [Variant] from a string serialized using [constant VAR_TO_STR]. </constant> - <constant name="VAR_TO_BYTES" value="59" enum="BuiltinFunc"> + <constant name="VAR_TO_BYTES" value="61" enum="BuiltinFunc"> Serialize a [Variant] to a [PackedByteArray]. </constant> - <constant name="BYTES_TO_VAR" value="60" enum="BuiltinFunc"> + <constant name="BYTES_TO_VAR" value="62" enum="BuiltinFunc"> Deserialize a [Variant] from a [PackedByteArray] serialized using [constant VAR_TO_BYTES]. </constant> - <constant name="MATH_SMOOTHSTEP" value="61" enum="BuiltinFunc"> - Return a number smoothly interpolated between the first two inputs, based on the third input. Similar to [constant MATH_LERP], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula: + <constant name="MATH_SMOOTHSTEP" value="63" enum="BuiltinFunc"> + Returns a number smoothly interpolated between the first two inputs, based on the third input. Similar to [constant MATH_LERP], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula: [codeblock] var t = clamp((weight - from) / (to - from), 0.0, 1.0) return t * t * (3.0 - 2.0 * t) [/codeblock] </constant> - <constant name="MATH_POSMOD" value="62" enum="BuiltinFunc"> + <constant name="MATH_POSMOD" value="64" enum="BuiltinFunc"> </constant> - <constant name="MATH_LERP_ANGLE" value="63" enum="BuiltinFunc"> + <constant name="MATH_LERP_ANGLE" value="65" enum="BuiltinFunc"> </constant> - <constant name="TEXT_ORD" value="64" enum="BuiltinFunc"> + <constant name="TEXT_ORD" value="66" enum="BuiltinFunc"> </constant> - <constant name="FUNC_MAX" value="65" enum="BuiltinFunc"> + <constant name="FUNC_MAX" value="67" enum="BuiltinFunc"> Represents the size of the [enum BuiltinFunc] enum. </constant> </constants> diff --git a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml index 2c6313c80a..486f60400a 100644 --- a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml +++ b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml @@ -12,112 +12,112 @@ <method name="_get_caption" qualifiers="virtual const"> <return type="String" /> <description> - Return the node's title. + Returns the node's title. </description> </method> <method name="_get_category" qualifiers="virtual const"> <return type="String" /> <description> - Return the node's category. + Returns the node's category. </description> </method> <method name="_get_input_value_port_count" qualifiers="virtual const"> <return type="int" /> <description> - Return the count of input value ports. + Returns the count of input value ports. </description> </method> <method name="_get_input_value_port_hint" qualifiers="virtual const"> <return type="int" /> <argument index="0" name="input_idx" type="int" /> <description> - Return the specified input port's hint. See the [enum @GlobalScope.PropertyHint] hints. + Returns the specified input port's hint. See the [enum @GlobalScope.PropertyHint] hints. </description> </method> <method name="_get_input_value_port_hint_string" qualifiers="virtual const"> <return type="String" /> <argument index="0" name="input_idx" type="int" /> <description> - Return the specified input port's hint string. + Returns the specified input port's hint string. </description> </method> <method name="_get_input_value_port_name" qualifiers="virtual const"> <return type="String" /> <argument index="0" name="input_idx" type="int" /> <description> - Return the specified input port's name. + Returns the specified input port's name. </description> </method> <method name="_get_input_value_port_type" qualifiers="virtual const"> <return type="int" /> <argument index="0" name="input_idx" type="int" /> <description> - Return the specified input port's type. See the [enum Variant.Type] values. + Returns the specified input port's type. See the [enum Variant.Type] values. </description> </method> <method name="_get_output_sequence_port_count" qualifiers="virtual const"> <return type="int" /> <description> - Return the amount of output [b]sequence[/b] ports. + Returns the amount of output [b]sequence[/b] ports. </description> </method> <method name="_get_output_sequence_port_text" qualifiers="virtual const"> <return type="String" /> <argument index="0" name="seq_idx" type="int" /> <description> - Return the specified [b]sequence[/b] output's name. + Returns the specified [b]sequence[/b] output's name. </description> </method> <method name="_get_output_value_port_count" qualifiers="virtual const"> <return type="int" /> <description> - Return the amount of output value ports. + Returns the amount of output value ports. </description> </method> <method name="_get_output_value_port_hint" qualifiers="virtual const"> <return type="int" /> <argument index="0" name="output_idx" type="int" /> <description> - Return the specified output port's hint. See the [enum @GlobalScope.PropertyHint] hints. + Returns the specified output port's hint. See the [enum @GlobalScope.PropertyHint] hints. </description> </method> <method name="_get_output_value_port_hint_string" qualifiers="virtual const"> <return type="String" /> <argument index="0" name="output_idx" type="int" /> <description> - Return the specified output port's hint string. + Returns the specified output port's hint string. </description> </method> <method name="_get_output_value_port_name" qualifiers="virtual const"> <return type="String" /> <argument index="0" name="output_idx" type="int" /> <description> - Return the specified output port's name. + Returns the specified output port's name. </description> </method> <method name="_get_output_value_port_type" qualifiers="virtual const"> <return type="int" /> <argument index="0" name="output_idx" type="int" /> <description> - Return the specified output port's type. See the [enum Variant.Type] values. + Returns the specified output port's type. See the [enum Variant.Type] values. </description> </method> <method name="_get_text" qualifiers="virtual const"> <return type="String" /> <description> - Return the custom node's text, which is shown right next to the input [b]sequence[/b] port (if there is none, on the place that is usually taken by it). + Returns the custom node's text, which is shown right next to the input [b]sequence[/b] port (if there is none, on the place that is usually taken by it). </description> </method> <method name="_get_working_memory_size" qualifiers="virtual const"> <return type="int" /> <description> - Return the size of the custom node's working memory. See [method _step] for more details. + Returns the size of the custom node's working memory. See [method _step] for more details. </description> </method> <method name="_has_input_sequence_port" qualifiers="virtual const"> <return type="bool" /> <description> - Return whether the custom node has an input [b]sequence[/b] port. + Returns whether the custom node has an input [b]sequence[/b] port. </description> </method> <method name="_step" qualifiers="virtual const"> diff --git a/modules/visual_script/doc_classes/VisualScriptCustomNodes.xml b/modules/visual_script/doc_classes/VisualScriptCustomNodes.xml new file mode 100644 index 0000000000..1681da7653 --- /dev/null +++ b/modules/visual_script/doc_classes/VisualScriptCustomNodes.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualScriptCustomNodes" inherits="Object" version="4.0"> + <brief_description> + Manages custom nodes for the Visual Script editor. + </brief_description> + <description> + This singleton can be used to manage (i.e., add or remove) custom nodes for the Visual Script editor. + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_custom_node"> + <return type="void" /> + <argument index="0" name="name" type="String" /> + <argument index="1" name="category" type="String" /> + <argument index="2" name="script" type="Script" /> + <description> + Add a custom Visual Script node to the editor. It'll be placed under "Custom Nodes" with the [code]category[/code] as the parameter. + </description> + </method> + <method name="remove_custom_node"> + <return type="void" /> + <argument index="0" name="name" type="String" /> + <argument index="1" name="category" type="String" /> + <description> + Remove a custom Visual Script node from the editor. Custom nodes already placed on scripts won't be removed. + </description> + </method> + </methods> + <signals> + <signal name="custom_nodes_updated"> + <description> + Emitted when a custom Visual Script node is added or removed. + </description> + </signal> + </signals> +</class> diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 8cb701ea20..bc40f4f9b4 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,10 @@ #include "visual_script_editor.h" +#include "../visual_script_expression.h" +#include "../visual_script_flow_control.h" +#include "../visual_script_func_nodes.h" +#include "../visual_script_nodes.h" #include "core/input/input.h" #include "core/object/class_db.h" #include "core/object/script_language.h" @@ -39,10 +43,6 @@ #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "scene/main/window.h" -#include "visual_script_expression.h" -#include "visual_script_flow_control.h" -#include "visual_script_func_nodes.h" -#include "visual_script_nodes.h" #ifdef TOOLS_ENABLED class VisualScriptEditorSignalEdit : public Object { @@ -779,7 +779,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { for (int i = 0; i < node->get_output_sequence_port_count(); i++) { Label *text2 = memnew(Label); text2->set_text(node->get_output_sequence_port_text(i)); - text2->set_align(Label::ALIGN_RIGHT); + text2->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); gnode->add_child(text2); gnode->set_slot(slot_idx, false, 0, Color(), true, TYPE_SEQUENCE, mono_color, seq_port, seq_port); slot_idx++; @@ -900,7 +900,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { if (i < mixed_seq_ports) { Label *text2 = memnew(Label); text2->set_text(node->get_output_sequence_port_text(i)); - text2->set_align(Label::ALIGN_RIGHT); + text2->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); hbc->add_child(text2); } @@ -998,7 +998,7 @@ void VisualScriptEditor::_change_port_type(int p_select, int p_id, int p_port, b void VisualScriptEditor::_update_node_size(int p_id) { Node *node = graph->get_node(itos(p_id)); if (Object::cast_to<Control>(node)) { - Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); // Shrink if text is smaller. + Object::cast_to<Control>(node)->reset_size(); // Shrink if text is smaller. } } @@ -1172,9 +1172,9 @@ void VisualScriptEditor::_member_selected() { if (ti->get_parent() == members->get_root()->get_first_child()) { #ifdef OSX_ENABLED - bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_META); + bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::META); #else - bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_CTRL); + bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL); #endif if (held_ctrl) { ERR_FAIL_COND(!script->has_function(selected)); @@ -1262,6 +1262,23 @@ void VisualScriptEditor::_member_edited() { undo_redo->create_action(TTR("Rename Variable")); undo_redo->add_do_method(script.ptr(), "rename_variable", name, new_name); undo_redo->add_undo_method(script.ptr(), "rename_variable", new_name, name); + + // Also fix all variable setter & getter calls + List<int> lst; + script->get_node_list(&lst); + for (int &P : lst) { + Ref<VisualScriptPropertySet> pset = script->get_node(P); + if (pset.is_valid() && pset->get_property() == name) { + undo_redo->add_do_method(pset.ptr(), "set_property", new_name); + undo_redo->add_undo_method(pset.ptr(), "set_property", name); + } + Ref<VisualScriptPropertyGet> pget = script->get_node(P); + if (pget.is_valid() && pget->get_property() == name) { + undo_redo->add_do_method(pget.ptr(), "set_property", new_name); + undo_redo->add_undo_method(pget.ptr(), "set_property", name); + } + } + undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); undo_redo->add_do_method(this, "_update_graph"); @@ -1278,6 +1295,18 @@ void VisualScriptEditor::_member_edited() { undo_redo->create_action(TTR("Rename Signal")); undo_redo->add_do_method(script.ptr(), "rename_custom_signal", name, new_name); undo_redo->add_undo_method(script.ptr(), "rename_custom_signal", new_name, name); + + // Also fix all signal emitting nodes + List<int> lst; + script->get_node_list(&lst); + for (int &P : lst) { + Ref<VisualScriptEmitSignal> psig = script->get_node(P); + if (psig.is_valid() && psig->get_signal() == name) { + undo_redo->add_do_method(psig.ptr(), "set_signal", new_name); + undo_redo->add_undo_method(psig.ptr(), "set_signal", name); + } + } + undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); @@ -1299,7 +1328,7 @@ void VisualScriptEditor::_create_function_dialog() { } void VisualScriptEditor::_create_function() { - String name = _validate_name((func_name_box->get_text() == "") ? "new_func" : func_name_box->get_text()); + String name = _validate_name((func_name_box->get_text().is_empty()) ? "new_func" : func_name_box->get_text()); selected = name; Vector2 pos = _get_available_pos(); @@ -1477,7 +1506,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt } } else if (ti->get_parent() == root->get_first_child()) { selected = ti->get_text(0); - function_name_edit->set_position(Input::get_singleton()->get_mouse_position() - Vector2(60, -10)); + function_name_edit->set_position(get_screen_position() + get_local_mouse_position() - Vector2(60, -10)); function_name_edit->popup(); function_name_box->set_text(selected); function_name_box->select_all(); @@ -1616,7 +1645,7 @@ void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id Node *node = graph->get_node(itos(p_id)); if (Object::cast_to<Control>(node)) { - Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); // Shrink if text is smaller. + Object::cast_to<Control>(node)->reset_size(); // Shrink if text is smaller. } updating_graph = false; @@ -1676,6 +1705,128 @@ String VisualScriptEditor::_validate_name(const String &p_name) const { return valid; } +void VisualScriptEditor::_on_nodes_copy() { + clipboard->nodes.clear(); + clipboard->data_connections.clear(); + clipboard->sequence_connections.clear(); + + for (int i = 0; i < graph->get_child_count(); i++) { + GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); + if (gn) { + if (gn->is_selected()) { + int id = gn->get_name().operator String().to_int(); + Ref<VisualScriptNode> node = script->get_node(id); + if (Object::cast_to<VisualScriptFunction>(*node)) { + EditorNode::get_singleton()->show_warning(TTR("Can't copy the function node.")); + return; + } + if (node.is_valid()) { + clipboard->nodes[id] = node->duplicate(true); + clipboard->nodes_positions[id] = script->get_node_position(id); + } + } + } + } + + if (clipboard->nodes.is_empty()) { + return; + } + + List<VisualScript::SequenceConnection> sequence_connections; + script->get_sequence_connection_list(&sequence_connections); + + for (const VisualScript::SequenceConnection &E : sequence_connections) { + if (clipboard->nodes.has(E.from_node) && clipboard->nodes.has(E.to_node)) { + clipboard->sequence_connections.insert(E); + } + } + + List<VisualScript::DataConnection> data_connections; + script->get_data_connection_list(&data_connections); + + for (const VisualScript::DataConnection &E : data_connections) { + if (clipboard->nodes.has(E.from_node) && clipboard->nodes.has(E.to_node)) { + clipboard->data_connections.insert(E); + } + } +} + +void VisualScriptEditor::_on_nodes_paste() { + if (clipboard->nodes.is_empty()) { + EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty!")); + return; + } + + Map<int, int> remap; + + undo_redo->create_action(TTR("Paste VisualScript Nodes")); + int idc = script->get_available_id() + 1; + + Set<int> to_select; + + Set<Vector2> existing_positions; + + { + List<int> nodes; + script->get_node_list(&nodes); + for (int &E : nodes) { + Vector2 pos = script->get_node_position(E).snapped(Vector2(2, 2)); + existing_positions.insert(pos); + } + } + + bool first_paste = true; + Vector2 position_offset = Vector2(0, 0); + + for (KeyValue<int, Ref<VisualScriptNode>> &E : clipboard->nodes) { + Ref<VisualScriptNode> node = E.value->duplicate(); + + int new_id = idc++; + to_select.insert(new_id); + + remap[E.key] = new_id; + + Vector2 paste_pos = clipboard->nodes_positions[E.key]; + + if (first_paste) { + position_offset = _get_pos_in_graph(mouse_up_position - graph->get_global_position()) - paste_pos; + first_paste = false; + } + + paste_pos += position_offset; + + while (existing_positions.has(paste_pos.snapped(Vector2(2, 2)))) { + paste_pos += Vector2(20, 20) * EDSCALE; + } + + undo_redo->add_do_method(script.ptr(), "add_node", new_id, node, paste_pos); + undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); + } + + for (Set<VisualScript::SequenceConnection>::Element *E = clipboard->sequence_connections.front(); E; E = E->next()) { + undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); + undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); + } + + for (Set<VisualScript::DataConnection>::Element *E = clipboard->data_connections.front(); E; E = E->next()) { + undo_redo->add_do_method(script.ptr(), "data_connect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); + undo_redo->add_undo_method(script.ptr(), "data_disconnect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); + } + + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + + undo_redo->commit_action(); + + for (int i = 0; i < graph->get_child_count(); i++) { + GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); + if (gn) { + int id = gn->get_name().operator String().to_int(); + gn->set_selected(to_select.has(id)); + } + } +} + void VisualScriptEditor::_on_nodes_delete() { // Delete all the selected nodes. @@ -1823,17 +1974,17 @@ void VisualScriptEditor::input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> key = p_event; if (key.is_valid() && !key->is_pressed()) { - mouse_up_position = Input::get_singleton()->get_mouse_position(); + mouse_up_position = get_screen_position() + get_local_mouse_position(); } } void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> key = p_event; - if (key.is_valid() && key->is_pressed() && key->get_button_mask() == MOUSE_BUTTON_RIGHT) { + if (key.is_valid() && key->is_pressed() && key->get_button_mask() == MouseButton::RIGHT) { saved_position = graph->get_local_mouse_position(); - Point2 gpos = Input::get_singleton()->get_mouse_position(); + Point2 gpos = get_screen_position() + get_local_mouse_position(); _generic_search(script->get_instance_base_type(), gpos); } } @@ -1927,7 +2078,7 @@ void VisualScriptEditor::_fn_name_box_input(const Ref<InputEvent> &p_event) { } Ref<InputEventKey> key = p_event; - if (key.is_valid() && key->is_pressed() && key->get_keycode() == KEY_ENTER) { + if (key.is_valid() && key->is_pressed() && key->get_keycode() == Key::ENTER) { function_name_edit->hide(); _rename_function(selected, function_name_box->get_text()); function_name_box->clear(); @@ -1943,7 +2094,7 @@ Variant VisualScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f String type = it->get_metadata(0); - if (type == String()) { + if (type.is_empty()) { return Variant(); } @@ -1986,7 +2137,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant & String(d["type"]) == "nodes")) { if (String(d["type"]) == "obj_property") { #ifdef OSX_ENABLED - const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Getter. Hold Shift to drop a generic signature."), find_keycode_name(KEY_META))); + const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Getter. Hold Shift to drop a generic signature."), find_keycode_name(Key::META))); #else const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature.")); #endif @@ -1994,7 +2145,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant & if (String(d["type"]) == "nodes") { #ifdef OSX_ENABLED - const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a simple reference to the node."), find_keycode_name(KEY_META))); + const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a simple reference to the node."), find_keycode_name(Key::META))); #else const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a simple reference to the node.")); #endif @@ -2002,7 +2153,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant & if (String(d["type"]) == "visual_script_variable_drag") { #ifdef OSX_ENABLED - const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Variable Setter."), find_keycode_name(KEY_META))); + const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Variable Setter."), find_keycode_name(Key::META))); #else const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a Variable Setter.")); #endif @@ -2065,28 +2216,28 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da if (String(d["type"]) == "visual_script_variable_drag") { #ifdef OSX_ENABLED - bool use_set = Input::get_singleton()->is_key_pressed(KEY_META); + bool use_set = Input::get_singleton()->is_key_pressed(Key::META); #else - bool use_set = Input::get_singleton()->is_key_pressed(KEY_CTRL); + bool use_set = Input::get_singleton()->is_key_pressed(Key::CTRL); #endif Vector2 pos = _get_pos_in_graph(p_point); Ref<VisualScriptNode> vnode; if (use_set) { - Ref<VisualScriptVariableSet> vnodes; - vnodes.instantiate(); - vnodes->set_variable(d["variable"]); - vnode = vnodes; + Ref<VisualScriptPropertySet> pset; + pset.instantiate(); + vnode = pset; } else { - Ref<VisualScriptVariableGet> vnodeg; - vnodeg.instantiate(); - vnodeg->set_variable(d["variable"]); - vnode = vnodeg; + Ref<VisualScriptPropertyGet> pget; + pget.instantiate(); + vnode = pget; } int new_id = script->get_available_id(); - undo_redo->create_action(TTR("Add Node")); + undo_redo->add_do_method(vnode.ptr(), "set_property", d["variable"]); + undo_redo->add_do_method(vnode.ptr(), "set_base_script", script->get_path()); + undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, pos); undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); undo_redo->add_do_method(this, "_update_graph"); @@ -2174,9 +2325,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da if (String(d["type"]) == "files") { #ifdef OSX_ENABLED - bool use_preload = Input::get_singleton()->is_key_pressed(KEY_META); + bool use_preload = Input::get_singleton()->is_key_pressed(Key::META); #else - bool use_preload = Input::get_singleton()->is_key_pressed(KEY_CTRL); + bool use_preload = Input::get_singleton()->is_key_pressed(Key::CTRL); #endif Vector2 pos = _get_pos_in_graph(p_point); @@ -2237,9 +2388,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } #ifdef OSX_ENABLED - bool use_node = Input::get_singleton()->is_key_pressed(KEY_META); + bool use_node = Input::get_singleton()->is_key_pressed(Key::META); #else - bool use_node = Input::get_singleton()->is_key_pressed(KEY_CTRL); + bool use_node = Input::get_singleton()->is_key_pressed(Key::CTRL); #endif Array nodes = d["nodes"]; @@ -2287,7 +2438,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da if (String(d["type"]) == "obj_property") { Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script); - if (!sn && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (!sn && !Input::get_singleton()->is_key_pressed(Key::SHIFT)) { EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop properties because script '%s' is not used in this scene.\nDrop holding 'Shift' to just copy the signature."), get_name())); return; } @@ -2302,12 +2453,12 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da Vector2 pos = _get_pos_in_graph(p_point); #ifdef OSX_ENABLED - bool use_get = Input::get_singleton()->is_key_pressed(KEY_META); + bool use_get = Input::get_singleton()->is_key_pressed(Key::META); #else - bool use_get = Input::get_singleton()->is_key_pressed(KEY_CTRL); + bool use_get = Input::get_singleton()->is_key_pressed(Key::CTRL); #endif - if (!node || Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (!node || Input::get_singleton()->is_key_pressed(Key::SHIFT)) { if (use_get) { undo_redo->create_action(TTR("Add Getter Property")); } else { @@ -2329,12 +2480,14 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da pget.instantiate(); pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE); pget->set_base_type(obj->get_class()); - vnode = pget; } undo_redo->add_do_method(script.ptr(), "add_node", base_id, vnode, pos); undo_redo->add_do_method(vnode.ptr(), "set_property", d["property"]); + if (!obj->get_script().is_null()) { + undo_redo->add_do_method(vnode.ptr(), "set_base_script", Ref<Script>(obj->get_script())->get_path()); + } if (!use_get) { undo_redo->add_do_method(vnode.ptr(), "set_default_input_value", 0, d["value"]); } @@ -2365,7 +2518,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH); pset->set_base_path(sn->get_path_to(node)); } - vnode = pset; } else { Ref<VisualScriptPropertyGet> pget; @@ -2380,9 +2532,13 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } undo_redo->add_do_method(script.ptr(), "add_node", base_id, vnode, pos); undo_redo->add_do_method(vnode.ptr(), "set_property", d["property"]); + if (!obj->get_script().is_null()) { + undo_redo->add_do_method(vnode.ptr(), "set_base_script", Ref<Script>(obj->get_script())->get_path()); + } if (!use_get) { undo_redo->add_do_method(vnode.ptr(), "set_default_input_value", 0, d["value"]); } + undo_redo->add_undo_method(script.ptr(), "remove_node", base_id); undo_redo->add_do_method(this, "_update_graph"); @@ -2460,18 +2616,21 @@ void VisualScriptEditor::reload_text() { String VisualScriptEditor::get_name() { String name; - if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) { - name = script->get_path().get_file(); - if (is_unsaved()) { - if (script->get_path().is_empty()) { - name = TTR("[unsaved]"); - } - name += "(*)"; + name = script->get_path().get_file(); + if (name.is_empty()) { + // This appears for newly created built-in scripts before saving the scene. + name = TTR("[unsaved]"); + } else if (script->is_built_in()) { + const String &script_name = script->get_name(); + if (!script_name.is_empty()) { + // If the built-in script has a custom resource name defined, + // display the built-in script name as follows: `ResourceName (scene_file.tscn)` + name = vformat("%s (%s)", script_name, name.get_slice("::", 0)); } - } else if (script->get_name() != "") { - name = script->get_name(); - } else { - name = script->get_class() + "(" + itos(script->get_instance_id()) + ")"; + } + + if (is_unsaved()) { + name += "(*)"; } return name; @@ -2683,7 +2842,7 @@ void VisualScriptEditor::clear_edit_menu() { void VisualScriptEditor::_change_base_type_callback() { String bt = select_base_type->get_selected_type(); - ERR_FAIL_COND(bt == String()); + ERR_FAIL_COND(bt.is_empty()); undo_redo->create_action(TTR("Change Base Type")); undo_redo->add_do_method(script.ptr(), "set_instance_base_type", bt); undo_redo->add_undo_method(script.ptr(), "set_instance_base_type", script->get_instance_base_type()); @@ -3054,7 +3213,7 @@ void VisualScriptEditor::_port_action_menu(int p_option) { if (tg.type == Variant::OBJECT) { if (tg.script.is_valid()) { new_connect_node_select->select_from_script(tg.script, ""); - } else if (type_string != String()) { + } else if (!type_string.is_empty()) { new_connect_node_select->select_from_base_type(type_string); } else { new_connect_node_select->select_from_base_type(n->get_base_type()); @@ -3078,7 +3237,7 @@ void VisualScriptEditor::_port_action_menu(int p_option) { property_info = script->get_node(port_action_node)->get_output_value_port_info(port_action_output); } if (tg.type == Variant::OBJECT) { - if (property_info.type == Variant::OBJECT && property_info.hint_string != String()) { + if (property_info.type == Variant::OBJECT && !property_info.hint_string.is_empty()) { new_connect_node_select->select_from_action(property_info.hint_string); } else { new_connect_node_select->select_from_action(""); @@ -3303,7 +3462,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; - if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) { + if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) { vsfc->set_base_type(base_type); } if (p_text == "call" || p_text == "call_deferred") { @@ -3338,7 +3497,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; - if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) { + if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) { vsp->set_base_type(base_type); } } @@ -3367,7 +3526,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri } else if (script->get_node(port_action_node).is_valid()) { PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; - if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) { + if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) { vsp->set_base_type(base_type); } } @@ -3417,7 +3576,7 @@ void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<Visual undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, pass_port, new_id); undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, pass_port, new_id); } else if (vnode_old->get_output_value_port_info(port_action_output).name == String("return") && - !script->get_output_sequence_ports_connected(port_action_node).has(return_port)) { + !script->get_output_sequence_ports_connected(port_action_node).has(return_port)) { undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, return_port, new_id); undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, return_port, new_id); } else { @@ -3545,8 +3704,8 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i Variant::construct(pinfo.type, existing, &existingp, 1, ce); } - default_value_edit->set_position(Object::cast_to<Control>(p_button)->get_global_position() + Vector2(0, Object::cast_to<Control>(p_button)->get_size().y)); - default_value_edit->set_size(Size2(1, 1)); + default_value_edit->set_position(Object::cast_to<Control>(p_button)->get_screen_position() + Vector2(0, Object::cast_to<Control>(p_button)->get_size().y) * graph->get_zoom()); + default_value_edit->reset_size(); if (pinfo.type == Variant::NODE_PATH) { Node *edited_scene = get_tree()->get_edited_scene_root(); @@ -3702,7 +3861,7 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_ undo_redo->commit_action(); gn->set_custom_minimum_size(new_size); - gn->set_size(Size2(1, 1)); + gn->reset_size(); graph->set_block_minimum_size_adjust(false); updating_graph = false; } @@ -3739,120 +3898,15 @@ void VisualScriptEditor::_menu_option(int p_what) { case EDIT_FIND_NODE_TYPE: { _generic_search(script->get_instance_base_type()); } break; - case EDIT_COPY_NODES: + case EDIT_COPY_NODES: { + _on_nodes_copy(); + } break; case EDIT_CUT_NODES: { - clipboard->nodes.clear(); - clipboard->data_connections.clear(); - clipboard->sequence_connections.clear(); - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected()) { - int id = gn->get_name().operator String().to_int(); - Ref<VisualScriptNode> node = script->get_node(id); - if (Object::cast_to<VisualScriptFunction>(*node)) { - EditorNode::get_singleton()->show_warning(TTR("Can't copy the function node.")); - return; - } - if (node.is_valid()) { - clipboard->nodes[id] = node->duplicate(true); - clipboard->nodes_positions[id] = script->get_node_position(id); - } - } - } - } - - if (clipboard->nodes.is_empty()) { - break; - } - - List<VisualScript::SequenceConnection> sequence_connections; - script->get_sequence_connection_list(&sequence_connections); - - for (const VisualScript::SequenceConnection &E : sequence_connections) { - if (clipboard->nodes.has(E.from_node) && clipboard->nodes.has(E.to_node)) { - clipboard->sequence_connections.insert(E); - } - } - - List<VisualScript::DataConnection> data_connections; - script->get_data_connection_list(&data_connections); - - for (const VisualScript::DataConnection &E : data_connections) { - if (clipboard->nodes.has(E.from_node) && clipboard->nodes.has(E.to_node)) { - clipboard->data_connections.insert(E); - } - } - if (p_what == EDIT_CUT_NODES) { - _on_nodes_delete(); // oh yeah, also delete on cut - } - + _on_nodes_copy(); + _on_nodes_delete(); } break; case EDIT_PASTE_NODES: { - if (clipboard->nodes.is_empty()) { - EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty!")); - break; - } - - Map<int, int> remap; - - undo_redo->create_action(TTR("Paste VisualScript Nodes")); - int idc = script->get_available_id() + 1; - - Set<int> to_select; - - Set<Vector2> existing_positions; - - { - List<int> nodes; - script->get_node_list(&nodes); - for (int &E : nodes) { - Vector2 pos = script->get_node_position(E).snapped(Vector2(2, 2)); - existing_positions.insert(pos); - } - } - - for (KeyValue<int, Ref<VisualScriptNode>> &E : clipboard->nodes) { - Ref<VisualScriptNode> node = E.value->duplicate(); - - int new_id = idc++; - to_select.insert(new_id); - - remap[E.key] = new_id; - - Vector2 paste_pos = clipboard->nodes_positions[E.key]; - - while (existing_positions.has(paste_pos.snapped(Vector2(2, 2)))) { - paste_pos += Vector2(20, 20) * EDSCALE; - } - - undo_redo->add_do_method(script.ptr(), "add_node", new_id, node, paste_pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - } - - for (Set<VisualScript::SequenceConnection>::Element *E = clipboard->sequence_connections.front(); E; E = E->next()) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]); - } - - for (Set<VisualScript::DataConnection>::Element *E = clipboard->data_connections.front(); E; E = E->next()) { - undo_redo->add_do_method(script.ptr(), "data_connect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port); - } - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - undo_redo->commit_action(); - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - int id = gn->get_name().operator String().to_int(); - gn->set_selected(to_select.has(id)); - } - } + _on_nodes_paste(); } break; case EDIT_CREATE_FUNCTION: { // Create Function. @@ -4106,11 +4160,11 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { ERR_FAIL_COND(!ti); member_popup->clear(); - member_popup->set_position(members->get_global_position() + p_pos); - member_popup->set_size(Vector2()); + member_popup->set_position(members->get_screen_position() + p_pos); + member_popup->reset_size(); - function_name_edit->set_position(members->get_global_position() + p_pos); - function_name_edit->set_size(Vector2()); + function_name_edit->set_position(members->get_screen_position() + p_pos); + function_name_edit->reset_size(); TreeItem *root = members->get_root(); @@ -4262,8 +4316,6 @@ void VisualScriptEditor::_bind_methods() { ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members); ClassDB::bind_method("_generic_search", &VisualScriptEditor::_generic_search); - - ClassDB::bind_method(D_METHOD("add_syntax_highlighter", "highlighter"), &VisualScriptEditor::add_syntax_highlighter); } VisualScriptEditor::VisualScriptEditor() { @@ -4336,6 +4388,8 @@ VisualScriptEditor::VisualScriptEditor() { graph->connect("node_selected", callable_mp(this, &VisualScriptEditor::_node_selected)); graph->connect("begin_node_move", callable_mp(this, &VisualScriptEditor::_begin_node_move)); graph->connect("end_node_move", callable_mp(this, &VisualScriptEditor::_end_node_move)); + graph->connect("copy_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_copy)); + graph->connect("paste_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_paste)); graph->connect("delete_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_delete)); graph->connect("duplicate_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_duplicate)); graph->connect("gui_input", callable_mp(this, &VisualScriptEditor::_graph_gui_input)); @@ -4422,8 +4476,8 @@ VisualScriptEditor::VisualScriptEditor() { select_func_text = memnew(Label); select_func_text->set_text(TTR("Select or create a function to edit its graph.")); - select_func_text->set_align(Label::ALIGN_CENTER); - select_func_text->set_valign(Label::VALIGN_CENTER); + select_func_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + select_func_text->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); select_func_text->set_h_size_flags(SIZE_EXPAND_FILL); add_child(select_func_text); @@ -4431,8 +4485,8 @@ VisualScriptEditor::VisualScriptEditor() { hint_text->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -100); hint_text->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0); hint_text->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0); - hint_text->set_align(Label::ALIGN_CENTER); - hint_text->set_valign(Label::VALIGN_CENTER); + hint_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + hint_text->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); graph->add_child(hint_text); hint_text_timer = memnew(Timer); @@ -4529,11 +4583,11 @@ void VisualScriptEditor::free_clipboard() { static void register_editor_callback() { ScriptEditor::register_create_script_editor_function(create_editor); - ED_SHORTCUT("visual_script_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9); - ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Type"), KEY_MASK_CMD + KEY_F); - ED_SHORTCUT("visual_script_editor/create_function", TTR("Make Function"), KEY_MASK_CMD + KEY_G); - ED_SHORTCUT("visual_script_editor/refresh_nodes", TTR("Refresh Graph"), KEY_MASK_CMD + KEY_R); - ED_SHORTCUT("visual_script_editor/edit_member", TTR("Edit Member"), KEY_MASK_CMD + KEY_E); + ED_SHORTCUT("visual_script_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), Key::F9); + ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Type"), KeyModifierMask::CMD + Key::F); + ED_SHORTCUT("visual_script_editor/create_function", TTR("Make Function"), KeyModifierMask::CMD + Key::G); + ED_SHORTCUT("visual_script_editor/refresh_nodes", TTR("Refresh Graph"), KeyModifierMask::CMD + Key::R); + ED_SHORTCUT("visual_script_editor/edit_member", TTR("Edit Member"), KeyModifierMask::CMD + Key::E); } void VisualScriptEditor::register_editor() { diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h index 19f5aabac9..b232b05391 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,11 +31,11 @@ #ifndef VISUALSCRIPT_EDITOR_H #define VISUALSCRIPT_EDITOR_H +#include "../visual_script.h" #include "editor/create_dialog.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/property_editor.h" #include "scene/gui/graph_edit.h" -#include "visual_script.h" #include "visual_script_property_selector.h" class VisualScriptEditorSignalEdit; @@ -253,6 +253,8 @@ class VisualScriptEditor : public ScriptEditorBase { void _node_item_selected(); void _node_item_unselected(); + void _on_nodes_copy(); + void _on_nodes_paste(); void _on_nodes_delete(); void _on_nodes_duplicate(); diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp index d8b88d6cd3..c88d10dabd 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/editor/visual_script_property_selector.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,15 +30,15 @@ #include "visual_script_property_selector.h" +#include "../visual_script.h" +#include "../visual_script_builtin_funcs.h" +#include "../visual_script_flow_control.h" +#include "../visual_script_func_nodes.h" +#include "../visual_script_nodes.h" #include "core/os/keyboard.h" #include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" -#include "modules/visual_script/visual_script.h" -#include "modules/visual_script/visual_script_builtin_funcs.h" -#include "modules/visual_script/visual_script_flow_control.h" -#include "modules/visual_script/visual_script_func_nodes.h" -#include "modules/visual_script/visual_script_nodes.h" #include "scene/main/node.h" #include "scene/main/window.h" @@ -51,10 +51,10 @@ void VisualScriptPropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) { if (k.is_valid()) { switch (k->get_keycode()) { - case KEY_UP: - case KEY_DOWN: - case KEY_PAGEUP: - case KEY_PAGEDOWN: { + case Key::UP: + case Key::DOWN: + case Key::PAGEUP: + case Key::PAGEDOWN: { search_options->gui_input(k); search_box->accept_event(); @@ -175,7 +175,7 @@ void VisualScriptPropertySelector::_update_search() { String set_text = set_text_raw.capitalize(); String input = search_box->get_text().capitalize(); - if (input == String() || get_text_raw.findn(input) != -1 || get_text.findn(input) != -1) { + if (input.is_empty() || get_text_raw.findn(input) != -1 || get_text.findn(input) != -1) { TreeItem *item = search_options->create_item(category ? category : root); item->set_text(0, get_text); item->set_metadata(0, F.name); @@ -188,7 +188,7 @@ void VisualScriptPropertySelector::_update_search() { item->set_metadata(2, connecting); } - if (input == String() || set_text_raw.findn(input) != -1 || set_text.findn(input) != -1) { + if (input.is_empty() || set_text_raw.findn(input) != -1 || set_text.findn(input) != -1) { TreeItem *item = search_options->create_item(category ? category : root); item->set_text(0, set_text); item->set_metadata(0, F.name); @@ -252,7 +252,7 @@ void VisualScriptPropertySelector::_update_search() { String desc_raw = mi.name + desc_arguments; String desc = desc_raw.capitalize().replace("( ", "("); - if (search_box->get_text() != String() && + if (!search_box->get_text().is_empty() && name.findn(search_box->get_text()) == -1 && desc.findn(search_box->get_text()) == -1 && desc_raw.findn(search_box->get_text()) == -1) { @@ -322,7 +322,7 @@ void VisualScriptPropertySelector::_update_search() { } void VisualScriptPropertySelector::create_visualscript_item(const String &name, TreeItem *const root, const String &search_input, const String &text) { - if (search_input == String() || text.findn(search_input) != -1) { + if (search_input.is_empty() || text.findn(search_input) != -1) { TreeItem *item = search_options->create_item(root); item->set_text(0, text); item->set_icon(0, vbc->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons"))); @@ -352,7 +352,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt bool in_filter = false; Vector<String> tx_filters = search_box->get_text().split(" "); for (int i = 0; i < tx_filters.size(); i++) { - if (tx_filters[i] == "") { + if (tx_filters[i].is_empty()) { in_filter = true; } else { in_filter = false; @@ -451,7 +451,7 @@ void VisualScriptPropertySelector::_item_selected() { String at_class = class_type; - while (at_class != String()) { + while (!at_class.is_empty()) { Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(at_class); if (E) { for (int i = 0; i < E->get().properties.size(); i++) { @@ -465,7 +465,7 @@ void VisualScriptPropertySelector::_item_selected() { } at_class = class_type; - while (at_class != String()) { + while (!at_class.is_empty()) { Map<String, DocData::ClassDoc>::Element *C = dd->class_list.find(at_class); if (C) { for (int i = 0; i < C->get().methods.size(); i++) { @@ -521,7 +521,7 @@ void VisualScriptPropertySelector::_item_selected() { memdelete(names); - if (text == String()) { + if (text.is_empty()) { return; } diff --git a/modules/visual_script/visual_script_property_selector.h b/modules/visual_script/editor/visual_script_property_selector.h index 7a87f3d3ee..9e065548a0 100644 --- a/modules/visual_script/visual_script_property_selector.h +++ b/modules/visual_script/editor/visual_script_property_selector.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp index 890861cf82..e7b5f58174 100644 --- a/modules/visual_script/register_types.cpp +++ b/modules/visual_script/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,7 +34,6 @@ #include "core/io/resource_loader.h" #include "visual_script.h" #include "visual_script_builtin_funcs.h" -#include "visual_script_editor.h" #include "visual_script_expression.h" #include "visual_script_flow_control.h" #include "visual_script_func_nodes.h" @@ -42,7 +41,9 @@ #include "visual_script_yield_nodes.h" VisualScriptLanguage *visual_script_language = nullptr; + #ifdef TOOLS_ENABLED +#include "editor/visual_script_editor.h" static VisualScriptCustomNodes *vs_custom_nodes_singleton = nullptr; #endif diff --git a/modules/visual_script/register_types.h b/modules/visual_script/register_types.h index b02a93ebc1..29768da67f 100644 --- a/modules/visual_script/register_types.h +++ b/modules/visual_script/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 54d310e636..fbdf3a654b 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -113,7 +113,7 @@ void VisualScriptNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_default_input_values", "values"), &VisualScriptNode::_set_default_input_values); ClassDB::bind_method(D_METHOD("_get_default_input_values"), &VisualScriptNode::_get_default_input_values); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_default_input_values", "_get_default_input_values"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_default_input_values", "_get_default_input_values"); ADD_SIGNAL(MethodInfo("ports_changed")); } @@ -661,7 +661,7 @@ void VisualScript::custom_signal_remove_argument(const StringName &p_func, int p ERR_FAIL_COND(instances.size()); ERR_FAIL_COND(!custom_signals.has(p_func)); ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size()); - custom_signals[p_func].remove(p_argidx); + custom_signals[p_func].remove_at(p_argidx); } int VisualScript::custom_signal_get_argument_count(const StringName &p_func) const { @@ -1172,7 +1172,7 @@ void VisualScript::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_data", "data"), &VisualScript::_set_data); ClassDB::bind_method(D_METHOD("_get_data"), &VisualScript::_get_data); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::INT, "id"))); } @@ -1665,8 +1665,8 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p String err_func = p_method; int err_line = current_node_id; // Not a line but it works as one. - if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str == String())) { - if (error_str != String()) { + if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str.is_empty())) { + if (!error_str.is_empty()) { error_str += " "; } @@ -1688,7 +1688,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p // debugger break did not happen if (!VisualScriptLanguage::singleton->debug_break(error_str, false)) { - _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, error_str.utf8().get_data(), ERR_HANDLER_SCRIPT); + _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, error_str.utf8().get_data(), false, ERR_HANDLER_SCRIPT); } //} @@ -2241,20 +2241,15 @@ void VisualScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) co void VisualScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const { } -Ref<Script> VisualScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const { - Ref<VisualScript> script; - script.instantiate(); - script->set_instance_base_type(p_base_class_name); - return script; -} - bool VisualScriptLanguage::is_using_templates() { - return true; + return false; } -void VisualScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) { - Ref<VisualScript> script = p_script; +Ref<Script> VisualScriptLanguage::make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const { + Ref<VisualScript> script; + script.instantiate(); script->set_instance_base_type(p_base_class_name); + return script; } bool VisualScriptLanguage::validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const { @@ -2370,7 +2365,6 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String const StringName *f = _call_stack[l].function; ERR_FAIL_COND(!_call_stack[l].instance->functions.has(*f)); - //VisualScriptInstance::Function *func = &_call_stack[l].instance->functions[*f]; VisualScriptNodeInstance *node = _call_stack[l].instance->instances[*_call_stack[l].current_id]; ERR_FAIL_COND(!node); @@ -2380,7 +2374,7 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String for (int i = 0; i < node->input_port_count; i++) { String name = node->get_base_node()->get_input_value_port_info(i).name; - if (name == String()) { + if (name.is_empty()) { name = "in_" + itos(i); } @@ -2400,7 +2394,7 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String for (int i = 0; i < node->output_port_count; i++) { String name = node->get_base_node()->get_output_value_port_info(i).name; - if (name == String()) { + if (name.is_empty()) { name = "out_" + itos(i); } @@ -2416,21 +2410,6 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String p_locals->push_back("working_mem/mem_" + itos(i)); p_values->push_back((*_call_stack[l].work_mem)[i]); } - - /* - ERR_FAIL_INDEX(p_level,_debug_call_stack_pos); - - - VisualFunction *f = _call_stack[l].function; - - List<Pair<StringName,int> > locals; - - f->debug_get_stack_member_state(*_call_stack[l].line,&locals); - for( List<Pair<StringName,int> >::Element *E = locals.front();E;E=E->next() ) { - p_locals->push_back(E->get().first); - p_values->push_back(_call_stack[l].stack[E->get().second]); - } -*/ } void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 39cef8f68b..e5c8ab48ee 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -554,57 +554,56 @@ public: ////////////////////////////////////// - virtual String get_name() const; + virtual String get_name() const override; /* LANGUAGE FUNCTIONS */ - virtual void init(); - virtual String get_type() const; - virtual String get_extension() const; - virtual Error execute_file(const String &p_path); - virtual void finish(); + virtual void init() override; + virtual String get_type() const override; + virtual String get_extension() const override; + virtual Error execute_file(const String &p_path) override; + virtual void finish() override; /* EDITOR FUNCTIONS */ - virtual void get_reserved_words(List<String> *p_words) const; - virtual bool is_control_flow_keyword(String p_keyword) const; - virtual void get_comment_delimiters(List<String> *p_delimiters) const; - virtual void get_string_delimiters(List<String> *p_delimiters) const; - virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const; - virtual bool is_using_templates(); - virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script); - virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const; - virtual Script *create_script() const; - virtual bool has_named_classes() const; - virtual bool supports_builtin_mode() const; - virtual int find_function(const String &p_function, const String &p_code) const; - virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const; - virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const; - virtual void add_global_constant(const StringName &p_variable, const Variant &p_value); + virtual void get_reserved_words(List<String> *p_words) const override; + virtual bool is_control_flow_keyword(String p_keyword) const override; + virtual void get_comment_delimiters(List<String> *p_delimiters) const override; + virtual void get_string_delimiters(List<String> *p_delimiters) const override; + virtual bool is_using_templates() override; + virtual Ref<Script> make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const override; + virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override; + virtual Script *create_script() const override; + virtual bool has_named_classes() const override; + virtual bool supports_builtin_mode() const override; + virtual int find_function(const String &p_function, const String &p_code) const override; + virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const override; + virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override; + virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) override; /* DEBUGGER FUNCTIONS */ - virtual String debug_get_error() const; - virtual int debug_get_stack_level_count() const; - virtual int debug_get_stack_level_line(int p_level) const; - virtual String debug_get_stack_level_function(int p_level) const; - virtual String debug_get_stack_level_source(int p_level) const; - virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1); - virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1); - virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1); - virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1); - - virtual void reload_all_scripts(); - virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload); + virtual String debug_get_error() const override; + virtual int debug_get_stack_level_count() const override; + virtual int debug_get_stack_level_line(int p_level) const override; + virtual String debug_get_stack_level_function(int p_level) const override; + virtual String debug_get_stack_level_source(int p_level) const override; + virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; + virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; + virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; + virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1) override; + + virtual void reload_all_scripts() override; + virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) override; /* LOADER FUNCTIONS */ - virtual void get_recognized_extensions(List<String> *p_extensions) const; - virtual void get_public_functions(List<MethodInfo> *p_functions) const; - virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; + virtual void get_public_functions(List<MethodInfo> *p_functions) const override; + virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override; - virtual void profiling_start(); - virtual void profiling_stop(); + virtual void profiling_start() override; + virtual void profiling_stop() override; - virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max); - virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max); + virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override; + virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override; void add_register_func(const String &p_name, VisualScriptNodeRegisterFunc p_func); void remove_register_func(const String &p_name); diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 7e01031128..99e75f9289 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,8 +71,9 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX "randomize", "randi", "randf", - "randf_range", "randi_range", + "randf_range", + "randfn", "seed", "rand_seed", "deg2rad", @@ -81,6 +82,7 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX "db2linear", "wrapi", "wrapf", + "pingpong", "max", "min", "clamp", @@ -190,11 +192,13 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) { case MATH_FMOD: case MATH_FPOSMOD: case MATH_POSMOD: + case MATH_PINGPONG: case MATH_POW: case MATH_EASE: case MATH_SNAPPED: - case MATH_RANDF_RANGE: case MATH_RANDI_RANGE: + case MATH_RANDF_RANGE: + case MATH_RANDFN: case LOGIC_MAX: case LOGIC_MIN: case TYPE_CONVERT: @@ -351,6 +355,13 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const case MATH_RANDI: case MATH_RANDF: { } break; + case MATH_RANDI_RANGE: { + if (p_idx == 0) { + return PropertyInfo(Variant::INT, "from"); + } else { + return PropertyInfo(Variant::INT, "to"); + } + } break; case MATH_RANDF_RANGE: { if (p_idx == 0) { return PropertyInfo(Variant::FLOAT, "from"); @@ -358,11 +369,11 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const return PropertyInfo(Variant::FLOAT, "to"); } } break; - case MATH_RANDI_RANGE: { + case MATH_RANDFN: { if (p_idx == 0) { - return PropertyInfo(Variant::INT, "from"); + return PropertyInfo(Variant::FLOAT, "mean"); } else { - return PropertyInfo(Variant::INT, "to"); + return PropertyInfo(Variant::FLOAT, "deviation"); } } break; case MATH_SEED: @@ -381,6 +392,13 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const case MATH_DB2LINEAR: { return PropertyInfo(Variant::FLOAT, "db"); } break; + case MATH_PINGPONG: { + if (p_idx == 0) { + return PropertyInfo(Variant::FLOAT, "value"); + } else { + return PropertyInfo(Variant::FLOAT, "length"); + } + } break; case MATH_WRAP: { if (p_idx == 0) { return PropertyInfo(Variant::INT, "value"); @@ -518,6 +536,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons t = Variant::INT; } break; case MATH_RANDF: + case MATH_RANDFN: case MATH_RANDF_RANGE: { t = Variant::FLOAT; } break; @@ -537,6 +556,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons case MATH_RAD2DEG: case MATH_LINEAR2DB: case MATH_WRAPF: + case MATH_PINGPONG: case MATH_DB2LINEAR: { t = Variant::FLOAT; } break; @@ -817,15 +837,20 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in case VisualScriptBuiltinFunc::MATH_RANDF: { *r_return = Math::randf(); } break; + case VisualScriptBuiltinFunc::MATH_RANDI_RANGE: { + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + *r_return = Math::random((int)*p_inputs[0], (int)*p_inputs[1]); + } break; case VisualScriptBuiltinFunc::MATH_RANDF_RANGE: { VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); *r_return = Math::random((double)*p_inputs[0], (double)*p_inputs[1]); } break; - case VisualScriptBuiltinFunc::MATH_RANDI_RANGE: { + case VisualScriptBuiltinFunc::MATH_RANDFN: { VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); - *r_return = Math::random((int)*p_inputs[0], (int)*p_inputs[1]); + *r_return = Math::randfn((double)*p_inputs[0], (double)*p_inputs[1]); } break; case VisualScriptBuiltinFunc::MATH_SEED: { VALIDATE_ARG_NUM(0); @@ -859,6 +884,11 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in VALIDATE_ARG_NUM(0); *r_return = Math::db2linear((double)*p_inputs[0]); } break; + case VisualScriptBuiltinFunc::MATH_PINGPONG: { + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + *r_return = Math::pingpong((double)*p_inputs[0], (double)*p_inputs[1]); + } break; case VisualScriptBuiltinFunc::MATH_WRAP: { VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); @@ -1196,8 +1226,9 @@ void VisualScriptBuiltinFunc::_bind_methods() { BIND_ENUM_CONSTANT(MATH_RANDOMIZE); BIND_ENUM_CONSTANT(MATH_RANDI); BIND_ENUM_CONSTANT(MATH_RANDF); - BIND_ENUM_CONSTANT(MATH_RANDF_RANGE); BIND_ENUM_CONSTANT(MATH_RANDI_RANGE); + BIND_ENUM_CONSTANT(MATH_RANDF_RANGE); + BIND_ENUM_CONSTANT(MATH_RANDFN); BIND_ENUM_CONSTANT(MATH_SEED); BIND_ENUM_CONSTANT(MATH_RANDSEED); BIND_ENUM_CONSTANT(MATH_DEG2RAD); @@ -1206,6 +1237,7 @@ void VisualScriptBuiltinFunc::_bind_methods() { BIND_ENUM_CONSTANT(MATH_DB2LINEAR); BIND_ENUM_CONSTANT(MATH_WRAP); BIND_ENUM_CONSTANT(MATH_WRAPF); + BIND_ENUM_CONSTANT(MATH_PINGPONG); BIND_ENUM_CONSTANT(LOGIC_MAX); BIND_ENUM_CONSTANT(LOGIC_MIN); BIND_ENUM_CONSTANT(LOGIC_CLAMP); @@ -1285,8 +1317,9 @@ void register_visual_script_builtin_func_node() { VisualScriptLanguage::singleton->add_register_func("functions/built_in/randomize", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDOMIZE>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/randi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDI>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF_RANGE>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/randi_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDI_RANGE>); + VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF_RANGE>); + VisualScriptLanguage::singleton->add_register_func("functions/built_in/randfn", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDFN>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/seed", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SEED>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/randseed", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDSEED>); @@ -1296,6 +1329,7 @@ void register_visual_script_builtin_func_node() { VisualScriptLanguage::singleton->add_register_func("functions/built_in/db2linear", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DB2LINEAR>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAP>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAPF>); + VisualScriptLanguage::singleton->add_register_func("functions/built_in/pingpong", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_PINGPONG>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/max", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_MAX>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/min", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_MIN>); diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h index f9eb7e983f..d689296233 100644 --- a/modules/visual_script/visual_script_builtin_funcs.h +++ b/modules/visual_script/visual_script_builtin_funcs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,8 +71,9 @@ public: MATH_RANDOMIZE, MATH_RANDI, MATH_RANDF, - MATH_RANDF_RANGE, MATH_RANDI_RANGE, + MATH_RANDF_RANGE, + MATH_RANDFN, MATH_SEED, MATH_RANDSEED, MATH_DEG2RAD, @@ -81,6 +82,7 @@ public: MATH_DB2LINEAR, MATH_WRAP, MATH_WRAPF, + MATH_PINGPONG, LOGIC_MAX, LOGIC_MIN, LOGIC_CLAMP, diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 99b7275008..b39f984a80 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -136,7 +136,7 @@ void VisualScriptExpression::_get_property_list(List<PropertyInfo> *p_list) cons argt += "," + Variant::get_type_name(Variant::Type(i)); } - p_list->push_back(PropertyInfo(Variant::STRING, "expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::STRING, "expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); p_list->push_back(PropertyInfo(Variant::INT, "out_type", PROPERTY_HINT_ENUM, argt)); p_list->push_back(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,64,1")); p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced")); @@ -1190,7 +1190,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() { op->nodes[1] = nullptr; expression.write[i].is_op = false; expression.write[i].node = op; - expression.remove(i + 1); + expression.remove_at(i + 1); } } else { @@ -1222,8 +1222,8 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() { //replace all 3 nodes by this operator and make it an expression expression.write[next_op - 1].node = op; - expression.remove(next_op); - expression.remove(next_op); + expression.remove_at(next_op); + expression.remove_at(next_op); } } diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h index ef16222b42..c93eb0686b 100644 --- a/modules/visual_script/visual_script_expression.h +++ b/modules/visual_script/visual_script_expression.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index 62a4f465cb..f8b03f2eea 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -724,7 +724,7 @@ String VisualScriptTypeCast::get_caption() const { } String VisualScriptTypeCast::get_text() const { - if (script != String()) { + if (!script.is_empty()) { return "Is " + script.get_file() + "?"; } else { return "Is " + base_type + "?"; @@ -762,7 +762,7 @@ String VisualScriptTypeCast::get_base_script() const { VisualScriptTypeCast::TypeGuess VisualScriptTypeCast::guess_output_type(TypeGuess *p_inputs, int p_output) const { TypeGuess tg; tg.type = Variant::OBJECT; - if (script != String()) { + if (!script.is_empty()) { tg.script = ResourceLoader::load(script); } //if (!tg.script.is_valid()) { @@ -793,7 +793,7 @@ public: return 0; } - if (script != String()) { + if (!script.is_empty()) { Ref<Script> obj_script = obj->get_script(); if (!obj_script.is_valid()) { return 1; //well, definitely not the script because object we got has no script. @@ -853,7 +853,7 @@ void VisualScriptTypeCast::_bind_methods() { String script_ext_hint; for (const String &E : script_extensions) { - if (script_ext_hint != String()) { + if (!script_ext_hint.is_empty()) { script_ext_hint += ","; } script_ext_hint += "*." + E; diff --git a/modules/visual_script/visual_script_flow_control.h b/modules/visual_script/visual_script_flow_control.h index 73822fcc37..7ffdf3df65 100644 --- a/modules/visual_script/visual_script_flow_control.h +++ b/modules/visual_script/visual_script_flow_control.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index 205918a5f0..056e1eb6a3 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -370,7 +370,7 @@ void VisualScriptFunctionCall::_update_method_cache() { } else if (call_mode == CALL_MODE_INSTANCE) { type = base_type; - if (base_script != String()) { + if (!base_script.is_empty()) { if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { ScriptServer::edit_request_func(base_script); //make sure it's loaded } @@ -514,7 +514,7 @@ Dictionary VisualScriptFunctionCall::_get_argument_cache() const { void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const { if (property.name == "base_type") { if (call_mode != CALL_MODE_INSTANCE) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; } } @@ -539,7 +539,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const property.hint = PROPERTY_HINT_ENUM; String sl; for (const Engine::Singleton &E : names) { - if (sl != String()) { + if (!sl.is_empty()) { sl += ","; } sl += E.name; @@ -580,7 +580,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE; property.hint_string = base_type; - if (base_script != String()) { + if (!base_script.is_empty()) { if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { ScriptServer::edit_request_func(base_script); //make sure it's loaded } @@ -684,7 +684,7 @@ void VisualScriptFunctionCall::_bind_methods() { String script_ext_hint; for (const String &E : script_extensions) { - if (script_ext_hint != String()) { + if (!script_ext_hint.is_empty()) { script_ext_hint += ","; } script_ext_hint += "*." + E; @@ -696,7 +696,7 @@ void VisualScriptFunctionCall::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "singleton"), "set_singleton", "get_singleton"); ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "argument_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_argument_cache", "_get_argument_cache"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "argument_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_argument_cache", "_get_argument_cache"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "function"), "set_function", "get_function"); //when set, if loaded properly, will override argument count. ADD_PROPERTY(PropertyInfo(Variant::INT, "use_default_args"), "set_use_default_args", "get_use_default_args"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "validate"), "set_validate", "get_validate"); @@ -1161,7 +1161,7 @@ void VisualScriptPropertySet::_update_cache() { } } else if (call_mode == CALL_MODE_INSTANCE) { type = base_type; - if (base_script != String()) { + if (!base_script.is_empty()) { if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { ScriptServer::edit_request_func(base_script); //make sure it's loaded } @@ -1282,7 +1282,7 @@ VisualScriptPropertySet::AssignOp VisualScriptPropertySet::get_assign_op() const void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const { if (property.name == "base_type") { if (call_mode != CALL_MODE_INSTANCE) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; } } @@ -1321,7 +1321,7 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const { property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; property.hint_string = base_type; - if (base_script != String()) { + if (!base_script.is_empty()) { if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { ScriptServer::edit_request_func(base_script); //make sure it's loaded } @@ -1361,7 +1361,7 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const { property.hint = PROPERTY_HINT_ENUM; property.hint_string = options; property.type = Variant::STRING; - if (options == "") { + if (options.is_empty()) { property.usage = PROPERTY_USAGE_NONE; //hide if type has no usable index } } @@ -1411,7 +1411,7 @@ void VisualScriptPropertySet::_bind_methods() { String script_ext_hint; for (const String &E : script_extensions) { - if (script_ext_hint != String()) { + if (!script_ext_hint.is_empty()) { script_ext_hint += ","; } script_ext_hint += "*." + E; @@ -1420,7 +1420,7 @@ void VisualScriptPropertySet::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_type_cache", "_get_type_cache"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_type_cache", "_get_type_cache"); ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "property"), "set_property", "get_property"); @@ -1847,7 +1847,7 @@ void VisualScriptPropertyGet::_update_cache() { } } else if (call_mode == CALL_MODE_INSTANCE) { type = base_type; - if (base_script != String()) { + if (!base_script.is_empty()) { if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { ScriptServer::edit_request_func(base_script); //make sure it's loaded } @@ -1988,7 +1988,7 @@ StringName VisualScriptPropertyGet::get_index() const { void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const { if (property.name == "base_type") { if (call_mode != CALL_MODE_INSTANCE) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; } } @@ -2027,7 +2027,7 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const { property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; property.hint_string = base_type; - if (base_script != String()) { + if (!base_script.is_empty()) { if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { ScriptServer::edit_request_func(base_script); //make sure it's loaded } @@ -2066,7 +2066,7 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const { property.hint = PROPERTY_HINT_ENUM; property.hint_string = options; property.type = Variant::STRING; - if (options == "") { + if (options.is_empty()) { property.usage = PROPERTY_USAGE_NONE; //hide if type has no usable index } } @@ -2113,7 +2113,7 @@ void VisualScriptPropertyGet::_bind_methods() { String script_ext_hint; for (const String &E : script_extensions) { - if (script_ext_hint != String()) { + if (!script_ext_hint.is_empty()) { script_ext_hint += ","; } script_ext_hint += "." + E; @@ -2122,7 +2122,7 @@ void VisualScriptPropertyGet::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_type_cache", "_get_type_cache"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_type_cache", "_get_type_cache"); ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "property"), "set_property", "get_property"); @@ -2316,19 +2316,27 @@ void VisualScriptEmitSignal::_validate_property(PropertyInfo &property) const { property.hint = PROPERTY_HINT_ENUM; List<StringName> sigs; + List<MethodInfo> base_sigs; Ref<VisualScript> vs = get_visual_script(); if (vs.is_valid()) { vs->get_custom_signal_list(&sigs); + ClassDB::get_signal_list(vs->get_instance_base_type(), &base_sigs); } String ml; for (const StringName &E : sigs) { - if (ml != String()) { + if (!ml.is_empty()) { ml += ","; } ml += E; } + for (const MethodInfo &E : base_sigs) { + if (!ml.is_empty()) { + ml += ","; + } + ml += E.name; + } property.hint_string = ml; } diff --git a/modules/visual_script/visual_script_func_nodes.h b/modules/visual_script/visual_script_func_nodes.h index cca08455f9..886ed7bc81 100644 --- a/modules/visual_script/visual_script_func_nodes.h +++ b/modules/visual_script/visual_script_func_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index ef77c0cef3..fccdab1a64 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -253,7 +253,7 @@ String VisualScriptFunction::get_argument_name(int p_argidx) const { void VisualScriptFunction::remove_argument(int p_argidx) { ERR_FAIL_INDEX(p_argidx, arguments.size()); - arguments.remove(p_argidx); + arguments.remove_at(p_argidx); ports_changed_notify(); } @@ -623,7 +623,7 @@ void VisualScriptLists::remove_input_data_port(int p_argidx) { ERR_FAIL_INDEX(p_argidx, inputports.size()); - inputports.remove(p_argidx); + inputports.remove_at(p_argidx); ports_changed_notify(); notify_property_list_changed(); @@ -679,7 +679,7 @@ void VisualScriptLists::remove_output_data_port(int p_argidx) { ERR_FAIL_INDEX(p_argidx, outputports.size()); - outputports.remove(p_argidx); + outputports.remove_at(p_argidx); ports_changed_notify(); notify_property_list_changed(); @@ -1307,7 +1307,7 @@ void VisualScriptVariableGet::_validate_property(PropertyInfo &property) const { String vhint; for (const StringName &E : vars) { - if (vhint != String()) { + if (!vhint.is_empty()) { vhint += ","; } @@ -1417,7 +1417,7 @@ void VisualScriptVariableSet::_validate_property(PropertyInfo &property) const { String vhint; for (const StringName &E : vars) { - if (vhint != String()) { + if (!vhint.is_empty()) { vhint += ","; } @@ -1615,7 +1615,7 @@ PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const { pinfo.hint_string = preload->get_class(); if (preload->get_path().is_resource_file()) { pinfo.name = preload->get_path(); - } else if (preload->get_name() != String()) { + } else if (!preload->get_name().is_empty()) { pinfo.name = preload->get_name(); } else { pinfo.name = preload->get_class(); @@ -1994,7 +1994,7 @@ void VisualScriptClassConstant::_validate_property(PropertyInfo &property) const property.hint_string = ""; for (const String &E : constants) { - if (property.hint_string != String()) { + if (!property.hint_string.is_empty()) { property.hint_string += ","; } property.hint_string += E; @@ -2132,7 +2132,7 @@ void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &property) c } property.hint_string = ""; for (const StringName &E : constants) { - if (property.hint_string != String()) { + if (!property.hint_string.is_empty()) { property.hint_string += ","; } property.hint_string += String(E); @@ -2363,7 +2363,7 @@ void VisualScriptEngineSingleton::_validate_property(PropertyInfo &property) con continue; //skip these, too simple named } - if (cc != String()) { + if (!cc.is_empty()) { cc += ","; } cc += E.name; @@ -3147,7 +3147,7 @@ String VisualScriptSubCall::get_caption() const { String VisualScriptSubCall::get_text() const { Ref<Script> script = get_script(); if (script.is_valid()) { - if (script->get_name() != String()) { + if (!script->get_name().is_empty()) { return script->get_name(); } if (script->get_path().is_resource_file()) { @@ -3415,8 +3415,8 @@ void VisualScriptConstructor::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constructor", "constructor"), &VisualScriptConstructor::set_constructor); ClassDB::bind_method(D_METHOD("get_constructor"), &VisualScriptConstructor::get_constructor); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor_type", "get_constructor_type"); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "constructor", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor", "get_constructor"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor_type", "get_constructor_type"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "constructor", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor", "get_constructor"); } VisualScriptConstructor::VisualScriptConstructor() { @@ -3786,7 +3786,7 @@ void VisualScriptInputAction::_validate_property(PropertyInfo &property) const { al.sort(); for (int i = 0; i < al.size(); i++) { - if (actions != String()) { + if (!actions.is_empty()) { actions += ","; } actions += al[i]; @@ -3958,7 +3958,7 @@ void VisualScriptDeconstruct::_bind_methods() { } ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_deconstruct_type", "get_deconstruct_type"); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "elem_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_elem_cache", "_get_elem_cache"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "elem_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_elem_cache", "_get_elem_cache"); } VisualScriptDeconstruct::VisualScriptDeconstruct() { diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index bf2d8e9683..18573f8682 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -90,12 +90,6 @@ public: void set_stack_size(int p_size); int get_stack_size() const; - void set_return_type_enabled(bool p_returns); - bool is_return_type_enabled() const; - - void set_return_type(Variant::Type p_type); - Variant::Type get_return_type() const; - void set_rpc_mode(Multiplayer::RPCMode p_mode); Multiplayer::RPCMode get_rpc_mode() const; diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index c62de64a85..d4f3fdd082 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -186,7 +186,7 @@ void VisualScriptYield::_bind_methods() { ClassDB::bind_method(D_METHOD("set_wait_time", "sec"), &VisualScriptYield::set_wait_time); ClassDB::bind_method(D_METHOD("get_wait_time"), &VisualScriptYield::get_wait_time); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Frame,Physics Frame,Time", PROPERTY_USAGE_NOEDITOR), "set_yield_mode", "get_yield_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Frame,Physics Frame,Time", PROPERTY_USAGE_NO_EDITOR), "set_yield_mode", "get_yield_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wait_time"), "set_wait_time", "get_wait_time"); BIND_ENUM_CONSTANT(YIELD_FRAME); @@ -415,7 +415,7 @@ VisualScriptYieldSignal::CallMode VisualScriptYieldSignal::get_call_mode() const void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const { if (property.name == "base_type") { if (call_mode != CALL_MODE_INSTANCE) { - property.usage = PROPERTY_USAGE_NOEDITOR; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } @@ -449,7 +449,7 @@ void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const { String ml; for (const String &E : mstring) { - if (ml != String()) { + if (!ml.is_empty()) { ml += ","; } ml += E; diff --git a/modules/visual_script/visual_script_yield_nodes.h b/modules/visual_script/visual_script_yield_nodes.h index 6005ff30b0..a7bf4e8a78 100644 --- a/modules/visual_script/visual_script_yield_nodes.h +++ b/modules/visual_script/visual_script_yield_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp index e4a80c339f..049d816a5a 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -56,7 +56,7 @@ int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram todo -= mixed; frames_mixed += mixed; start_buffer += mixed; - if (!have_packets_left) { + if (!have_packets_left && !have_samples_left) { //end of file! bool is_not_empty = mixed > 0 || vorbis_stream->get_length() > 0; if (vorbis_stream->loop && is_not_empty) { @@ -110,7 +110,7 @@ int AudioStreamPlaybackOGGVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p if (info.channels > 1) { for (int frame = 0; frame < frames; frame++) { p_buffer[frame].l = pcm[0][frame]; - p_buffer[frame].r = pcm[0][frame]; + p_buffer[frame].r = pcm[1][frame]; } } else { for (int frame = 0; frame < frames; frame++) { @@ -425,7 +425,7 @@ void AudioStreamOGGVorbis::_bind_methods() { ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamOGGVorbis::set_loop_offset); ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamOGGVorbis::get_loop_offset); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "packet_sequence", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_packet_sequence", "get_packet_sequence"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "packet_sequence", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_sequence", "get_packet_sequence"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset"); } diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h index 59a1318a6b..b09ef9ff5d 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.h +++ b/modules/vorbis/audio_stream_ogg_vorbis.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/vorbis/register_types.cpp b/modules/vorbis/register_types.cpp index de3f41afdd..1baf7b2edc 100644 --- a/modules/vorbis/register_types.cpp +++ b/modules/vorbis/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/vorbis/register_types.h b/modules/vorbis/register_types.h index 1497e6f5e4..666c7e5b9f 100644 --- a/modules/vorbis/register_types.h +++ b/modules/vorbis/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/vorbis/resource_importer_ogg_vorbis.cpp b/modules/vorbis/resource_importer_ogg_vorbis.cpp index 33ee6cf359..ccd463fd52 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/vorbis/resource_importer_ogg_vorbis.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -57,7 +57,7 @@ String ResourceImporterOGGVorbis::get_resource_type() const { return "AudioStreamOGGVorbis"; } -bool ResourceImporterOGGVorbis::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { +bool ResourceImporterOGGVorbis::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const { return true; } @@ -69,7 +69,7 @@ String ResourceImporterOGGVorbis::get_preset_name(int p_idx) const { return String(); } -void ResourceImporterOGGVorbis::get_import_options(List<ImportOption> *r_options, int p_preset) const { +void ResourceImporterOGGVorbis::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "loop_offset"), 0)); } diff --git a/modules/vorbis/resource_importer_ogg_vorbis.h b/modules/vorbis/resource_importer_ogg_vorbis.h index acdc1a3d38..07291803a1 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.h +++ b/modules/vorbis/resource_importer_ogg_vorbis.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -51,8 +51,8 @@ public: virtual String get_visible_name() const override; virtual int get_preset_count() const override; virtual String get_preset_name(int p_idx) const override; - virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override; - virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override; + virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; + virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override; virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; diff --git a/modules/webm/SCsub b/modules/webm/SCsub deleted file mode 100644 index 44e80e2870..0000000000 --- a/modules/webm/SCsub +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_webm = env_modules.Clone() - -# Thirdparty source files - -thirdparty_obj = [] - -thirdparty_dir = "#thirdparty/libsimplewebm/" -thirdparty_sources = [ - "libwebm/mkvparser/mkvparser.cc", - "OpusVorbisDecoder.cpp", - "VPXDecoder.cpp", - "WebMDemuxer.cpp", -] -thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - -env_webm.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "libwebm/"]) - -# also requires libogg, libvorbis and libopus -if env["builtin_libogg"]: - env_webm.Prepend(CPPPATH=["#thirdparty/libogg"]) -if env["builtin_libvorbis"]: - env_webm.Prepend(CPPPATH=["#thirdparty/libvorbis"]) -if env["builtin_opus"]: - env_webm.Prepend(CPPPATH=["#thirdparty/opus"]) - -if env["builtin_libvpx"]: - env_webm.Prepend(CPPPATH=["#thirdparty/libvpx"]) - SConscript("libvpx/SCsub") - -env_thirdparty = env_webm.Clone() -env_thirdparty.disable_warnings() -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) -env.modules_sources += thirdparty_obj - -# Godot source files - -module_obj = [] - -env_webm.add_source_files(module_obj, "*.cpp") -env.modules_sources += module_obj - -# Needed to force rebuilding the module files when the thirdparty library is updated. -env.Depends(module_obj, thirdparty_obj) diff --git a/modules/webm/config.py b/modules/webm/config.py deleted file mode 100644 index 99f8ace114..0000000000 --- a/modules/webm/config.py +++ /dev/null @@ -1,19 +0,0 @@ -def can_build(env, platform): - if platform in ["iphone"]: - return False - - return env.module_check_dependencies("webm", ["ogg", "opus", "vorbis"]) - - -def configure(env): - pass - - -def get_doc_classes(): - return [ - "VideoStreamWebm", - ] - - -def get_doc_path(): - return "doc_classes" diff --git a/modules/webm/doc_classes/VideoStreamWebm.xml b/modules/webm/doc_classes/VideoStreamWebm.xml deleted file mode 100644 index e04d02d6ab..0000000000 --- a/modules/webm/doc_classes/VideoStreamWebm.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VideoStreamWebm" inherits="VideoStream" version="4.0"> - <brief_description> - [VideoStream] resource for WebM videos. - </brief_description> - <description> - [VideoStream] resource handling the [url=https://www.webmproject.org/]WebM[/url] video format with [code].webm[/code] extension. Both the VP8 and VP9 codecs are supported. The VP8 and VP9 codecs are more efficient than [VideoStreamTheora], but they require more CPU resources to decode (especially VP9). Both the VP8 and VP9 codecs are decoded on the CPU. - [b]Note:[/b] Alpha channel (also known as transparency) is not supported. The video will always appear to have a black background, even if it originally contains an alpha channel. - [b]Note:[/b] There are known bugs and performance issues with WebM video playback in Godot. If you run into problems, try using the Ogg Theora format instead: [VideoStreamTheora] - </description> - <tutorials> - </tutorials> - <methods> - <method name="get_file"> - <return type="String" /> - <description> - Returns the WebM video file handled by this [VideoStreamWebm]. - </description> - </method> - <method name="set_file"> - <return type="void" /> - <argument index="0" name="file" type="String" /> - <description> - Sets the WebM video file that this [VideoStreamWebm] resource handles. The [code]file[/code] name should have the [code].webm[/code] extension. - </description> - </method> - </methods> -</class> diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub deleted file mode 100644 index 4334cf732b..0000000000 --- a/modules/webm/libvpx/SCsub +++ /dev/null @@ -1,382 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -# Thirdparty sources - -libvpx_dir = "#thirdparty/libvpx/" - -libvpx_sources = [ - "vp8/vp8_dx_iface.c", - "vp8/common/generic/systemdependent.c", - "vp8/common/alloccommon.c", - "vp8/common/blockd.c", - "vp8/common/copy_c.c", - "vp8/common/debugmodes.c", - "vp8/common/dequantize.c", - "vp8/common/entropy.c", - "vp8/common/entropymode.c", - "vp8/common/entropymv.c", - "vp8/common/extend.c", - "vp8/common/filter.c", - "vp8/common/findnearmv.c", - "vp8/common/idct_blk.c", - "vp8/common/idctllm.c", - "vp8/common/loopfilter_filters.c", - "vp8/common/mbpitch.c", - "vp8/common/modecont.c", - "vp8/common/quant_common.c", - "vp8/common/reconinter.c", - "vp8/common/reconintra.c", - "vp8/common/reconintra4x4.c", - "vp8/common/rtcd.c", - "vp8/common/setupintrarecon.c", - "vp8/common/swapyv12buffer.c", - "vp8/common/treecoder.c", - "vp8/common/vp8_loopfilter.c", - "vp8/decoder/dboolhuff.c", - "vp8/decoder/decodeframe.c", - "vp8/decoder/decodemv.c", - "vp8/decoder/detokenize.c", - "vp8/decoder/onyxd_if.c", - "vp9/vp9_dx_iface.c", - "vp9/common/vp9_alloccommon.c", - "vp9/common/vp9_blockd.c", - "vp9/common/vp9_common_data.c", - "vp9/common/vp9_debugmodes.c", - "vp9/common/vp9_entropy.c", - "vp9/common/vp9_entropymode.c", - "vp9/common/vp9_entropymv.c", - "vp9/common/vp9_filter.c", - "vp9/common/vp9_frame_buffers.c", - "vp9/common/vp9_idct.c", - "vp9/common/vp9_loopfilter.c", - "vp9/common/vp9_mvref_common.c", - "vp9/common/vp9_pred_common.c", - "vp9/common/vp9_quant_common.c", - "vp9/common/vp9_reconinter.c", - "vp9/common/vp9_reconintra.c", - "vp9/common/vp9_rtcd.c", - "vp9/common/vp9_scale.c", - "vp9/common/vp9_scan.c", - "vp9/common/vp9_seg_common.c", - "vp9/common/vp9_thread_common.c", - "vp9/common/vp9_tile_common.c", - "vp9/decoder/vp9_decodeframe.c", - "vp9/decoder/vp9_decodemv.c", - "vp9/decoder/vp9_decoder.c", - "vp9/decoder/vp9_detokenize.c", - "vp9/decoder/vp9_dsubexp.c", - "vp9/decoder/vp9_dthread.c", - "vpx/src/vpx_codec.c", - "vpx/src/vpx_decoder.c", - "vpx/src/vpx_image.c", - "vpx/src/vpx_psnr.c", - "vpx_dsp/bitreader.c", - "vpx_dsp/bitreader_buffer.c", - "vpx_dsp/intrapred.c", - "vpx_dsp/inv_txfm.c", - "vpx_dsp/loopfilter.c", - "vpx_dsp/prob.c", - "vpx_dsp/vpx_convolve.c", - "vpx_dsp/vpx_dsp_rtcd.c", - "vpx_mem/vpx_mem.c", - "vpx_scale/vpx_scale_rtcd.c", - "vpx_scale/generic/yv12config.c", - "vpx_scale/generic/yv12extend.c", - "vpx_util/vpx_thread.c", -] - -libvpx_sources_mt = [ - "vp8/decoder/threading.c", -] - -libvpx_sources_intrin_x86 = [ - "vp8/common/x86/filter_x86.c", - "vp8/common/x86/loopfilter_x86.c", - "vp8/common/x86/vp8_asm_stubs.c", - "vpx_dsp/x86/vpx_asm_stubs.c", -] -libvpx_sources_intrin_x86_mmx = [ - "vp8/common/x86/idct_blk_mmx.c", -] -libvpx_sources_intrin_x86_sse2 = [ - "vp8/common/x86/idct_blk_sse2.c", - "vp9/common/x86/vp9_idct_intrin_sse2.c", - "vpx_dsp/x86/inv_txfm_sse2.c", - "vpx_dsp/x86/loopfilter_sse2.c", -] -libvpx_sources_intrin_x86_ssse3 = [ - "vpx_dsp/x86/vpx_subpixel_8t_intrin_ssse3.c", -] -libvpx_sources_intrin_x86_avx2 = [ - "vpx_dsp/x86/loopfilter_avx2.c", - "vpx_dsp/x86/vpx_subpixel_8t_intrin_avx2.c", -] -libvpx_sources_x86asm = [ - "vp8/common/x86/copy_sse2.asm", - "vp8/common/x86/copy_sse3.asm", - "vp8/common/x86/dequantize_mmx.asm", - "vp8/common/x86/idctllm_mmx.asm", - "vp8/common/x86/idctllm_sse2.asm", - "vp8/common/x86/iwalsh_mmx.asm", - "vp8/common/x86/iwalsh_sse2.asm", - "vp8/common/x86/loopfilter_sse2.asm", - "vp8/common/x86/recon_mmx.asm", - "vp8/common/x86/recon_sse2.asm", - "vp8/common/x86/subpixel_mmx.asm", - "vp8/common/x86/subpixel_sse2.asm", - "vp8/common/x86/subpixel_ssse3.asm", - "vp8/common/x86/vp8_loopfilter_mmx.asm", - "vpx_dsp/x86/intrapred_sse2.asm", - "vpx_dsp/x86/intrapred_ssse3.asm", - "vpx_dsp/x86/inv_wht_sse2.asm", - "vpx_dsp/x86/vpx_convolve_copy_sse2.asm", - "vpx_dsp/x86/vpx_subpixel_8t_sse2.asm", - "vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm", - "vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm", - "vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm", - "vpx_ports/emms.asm", -] -libvpx_sources_x86_64asm = [ - "vp8/common/x86/loopfilter_block_sse2_x86_64.asm", - "vpx_dsp/x86/inv_txfm_ssse3_x86_64.asm", -] - -libvpx_sources_arm = [ - "vpx_ports/arm_cpudetect.c", - "vp8/common/arm/loopfilter_arm.c", -] -libvpx_sources_arm_neon = [ - "vp8/common/arm/neon/bilinearpredict_neon.c", - "vp8/common/arm/neon/copymem_neon.c", - "vp8/common/arm/neon/dc_only_idct_add_neon.c", - "vp8/common/arm/neon/dequant_idct_neon.c", - "vp8/common/arm/neon/dequantizeb_neon.c", - "vp8/common/arm/neon/idct_blk_neon.c", - "vp8/common/arm/neon/idct_dequant_0_2x_neon.c", - "vp8/common/arm/neon/idct_dequant_full_2x_neon.c", - "vp8/common/arm/neon/iwalsh_neon.c", - "vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c", - "vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c", - "vp8/common/arm/neon/mbloopfilter_neon.c", - "vp8/common/arm/neon/shortidct4x4llm_neon.c", - "vp8/common/arm/neon/sixtappredict_neon.c", - "vp8/common/arm/neon/vp8_loopfilter_neon.c", - "vp9/common/arm/neon/vp9_iht4x4_add_neon.c", - "vp9/common/arm/neon/vp9_iht8x8_add_neon.c", - "vpx_dsp/arm/idct16x16_1_add_neon.c", - "vpx_dsp/arm/idct16x16_add_neon.c", - "vpx_dsp/arm/idct16x16_neon.c", - "vpx_dsp/arm/idct32x32_1_add_neon.c", - "vpx_dsp/arm/idct32x32_add_neon.c", - "vpx_dsp/arm/idct4x4_1_add_neon.c", - "vpx_dsp/arm/idct4x4_add_neon.c", - "vpx_dsp/arm/idct8x8_1_add_neon.c", - "vpx_dsp/arm/idct8x8_add_neon.c", - "vpx_dsp/arm/intrapred_neon.c", - "vpx_dsp/arm/loopfilter_16_neon.c", - "vpx_dsp/arm/loopfilter_4_neon.c", - "vpx_dsp/arm/loopfilter_8_neon.c", - "vpx_dsp/arm/loopfilter_neon.c", - "vpx_dsp/arm/vpx_convolve8_avg_neon.c", - "vpx_dsp/arm/vpx_convolve8_neon.c", - "vpx_dsp/arm/vpx_convolve_avg_neon.c", - "vpx_dsp/arm/vpx_convolve_copy_neon.c", - "vpx_dsp/arm/vpx_convolve_neon.c", -] -libvpx_sources_arm_neon_gas = [ - "vpx_dsp/arm/gas/intrapred_neon_asm.s", - "vpx_dsp/arm/gas/loopfilter_mb_neon.s", - "vpx_dsp/arm/gas/save_reg_neon.s", -] -libvpx_sources_arm_neon_armasm_ms = [ - "vpx_dsp/arm/armasm_ms/intrapred_neon_asm.asm", - "vpx_dsp/arm/armasm_ms/loopfilter_mb_neon.asm", - "vpx_dsp/arm/armasm_ms/save_reg_neon.asm", -] -libvpx_sources_arm_neon_gas_apple = [ - "vpx_dsp/arm/gas_apple/intrapred_neon_asm.s", - "vpx_dsp/arm/gas_apple/loopfilter_mb_neon.s", - "vpx_dsp/arm/gas_apple/save_reg_neon.s", -] - -libvpx_sources = [libvpx_dir + file for file in libvpx_sources] -libvpx_sources_mt = [libvpx_dir + file for file in libvpx_sources_mt] -libvpx_sources_intrin_x86 = [libvpx_dir + file for file in libvpx_sources_intrin_x86] -libvpx_sources_intrin_x86_mmx = [libvpx_dir + file for file in libvpx_sources_intrin_x86_mmx] -libvpx_sources_intrin_x86_sse2 = [libvpx_dir + file for file in libvpx_sources_intrin_x86_sse2] -libvpx_sources_intrin_x86_ssse3 = [libvpx_dir + file for file in libvpx_sources_intrin_x86_ssse3] -libvpx_sources_intrin_x86_avx2 = [libvpx_dir + file for file in libvpx_sources_intrin_x86_avx2] -libvpx_sources_x86asm = [libvpx_dir + file for file in libvpx_sources_x86asm] -libvpx_sources_x86_64asm = [libvpx_dir + file for file in libvpx_sources_x86_64asm] -libvpx_sources_arm = [libvpx_dir + file for file in libvpx_sources_arm] -libvpx_sources_arm_neon = [libvpx_dir + file for file in libvpx_sources_arm_neon] -libvpx_sources_arm_neon_gas = [libvpx_dir + file for file in libvpx_sources_arm_neon_gas] -libvpx_sources_arm_neon_armasm_ms = [libvpx_dir + file for file in libvpx_sources_arm_neon_armasm_ms] -libvpx_sources_arm_neon_gas_apple = [libvpx_dir + file for file in libvpx_sources_arm_neon_gas_apple] - - -env_libvpx = env_modules.Clone() -env_libvpx.disable_warnings() -env_libvpx.Prepend(CPPPATH=[libvpx_dir]) - -webm_multithread = env["platform"] != "javascript" - -cpu_bits = env["bits"] -webm_cpu_x86 = False -webm_cpu_arm = False -if env["platform"] == "uwp": - if "arm" in env["PROGSUFFIX"]: - webm_cpu_arm = True - else: - webm_cpu_x86 = True -else: - import platform - - is_x11_or_server_arm = env["platform"] == "linuxbsd" and ( - platform.machine().startswith("arm") or platform.machine().startswith("aarch") - ) - is_macos_x86 = env["platform"] == "osx" and ("arch" in env and (env["arch"] != "arm64")) - is_ios_x86 = env["platform"] == "iphone" and ("arch" in env and env["arch"].startswith("x86")) - is_android_x86 = env["platform"] == "android" and env["android_arch"].startswith("x86") - if is_android_x86: - cpu_bits = "32" if env["android_arch"] == "x86" else "64" - webm_cpu_x86 = ( - not is_x11_or_server_arm - and (cpu_bits == "32" or cpu_bits == "64") - and ( - env["platform"] == "windows" - or env["platform"] == "linuxbsd" - or env["platform"] == "haiku" - or is_macos_x86 - or is_android_x86 - or is_ios_x86 - ) - ) - webm_cpu_arm = ( - is_x11_or_server_arm - or (not is_macos_x86 and env["platform"] == "osx") - or (not is_ios_x86 and env["platform"] == "iphone") - or (not is_android_x86 and env["platform"] == "android") - ) - -if webm_cpu_x86: - import subprocess - import os - - yasm_paths = [ - "yasm", - "../../../yasm", - ] - - yasm_found = False - - devnull = open(os.devnull) - for yasm_path in yasm_paths: - try: - yasm_found = True - subprocess.Popen([yasm_path, "--version"], stdout=devnull, stderr=devnull).communicate() - except Exception: - yasm_found = False - if yasm_found: - break - - if not yasm_found: - webm_cpu_x86 = False - print("YASM is necessary for WebM SIMD optimizations.") - -webm_simd_optimizations = False - -if webm_cpu_x86: - if env["platform"] == "windows" or env["platform"] == "uwp": - env_libvpx["ASFORMAT"] = "win" - elif env["platform"] == "osx" or env["platform"] == "iphone": - env_libvpx["ASFORMAT"] = "macho" - else: - env_libvpx["ASFORMAT"] = "elf" - env_libvpx["ASFORMAT"] += cpu_bits - - env_libvpx["AS"] = "yasm" - env_libvpx["ASFLAGS"] = "-I" + libvpx_dir[1:] + " -f $ASFORMAT -D $ASCPU" - env_libvpx["ASCOM"] = "$AS $ASFLAGS -o $TARGET $SOURCES" - - if cpu_bits == "32": - env_libvpx["ASCPU"] = "X86_32" - elif cpu_bits == "64": - env_libvpx["ASCPU"] = "X86_64" - - env_libvpx.Append(CPPDEFINES=["WEBM_X86ASM"]) - - webm_simd_optimizations = True - -if webm_cpu_arm: - if env["platform"] == "iphone": - env_libvpx["ASFLAGS"] = "-arch armv7" - elif env["platform"] == "android" and env["android_arch"] == "armv7" or env["platform"] == "linuxbsd": - env_libvpx["ASFLAGS"] = "-mfpu=neon" - elif env["platform"] == "uwp": - env_libvpx["AS"] = "armasm" - env_libvpx["ASFLAGS"] = "" - env_libvpx["ASCOM"] = "$AS $ASFLAGS -o $TARGET $SOURCES" - - env_libvpx.Append(CPPDEFINES=["WEBM_ARMASM"]) - - webm_simd_optimizations = True - -if webm_simd_optimizations == False: - print("WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!") - -env_libvpx.add_source_files(env.modules_sources, libvpx_sources) - -if webm_multithread: - env_libvpx.add_source_files(env.modules_sources, libvpx_sources_mt) - -if webm_cpu_x86: - is_clang_or_gcc = ( - ("gcc" in os.path.basename(env["CC"])) or ("clang" in os.path.basename(env["CC"])) or ("osxcross" in env) - ) - - env_libvpx_mmx = env_libvpx.Clone() - if cpu_bits == "32" and is_clang_or_gcc: - env_libvpx_mmx.Append(CCFLAGS=["-mmmx"]) - env_libvpx_mmx.add_source_files(env.modules_sources, libvpx_sources_intrin_x86_mmx) - - env_libvpx_sse2 = env_libvpx.Clone() - if cpu_bits == "32" and is_clang_or_gcc: - env_libvpx_sse2.Append(CCFLAGS=["-msse2"]) - env_libvpx_sse2.add_source_files(env.modules_sources, libvpx_sources_intrin_x86_sse2) - - env_libvpx_ssse3 = env_libvpx.Clone() - if is_clang_or_gcc: - env_libvpx_ssse3.Append(CCFLAGS=["-mssse3"]) - env_libvpx_ssse3.add_source_files(env.modules_sources, libvpx_sources_intrin_x86_ssse3) - - env_libvpx_avx2 = env_libvpx.Clone() - if is_clang_or_gcc: - env_libvpx_avx2.Append(CCFLAGS=["-mavx2"]) - env_libvpx_avx2.add_source_files(env.modules_sources, libvpx_sources_intrin_x86_avx2) - - env_libvpx.add_source_files(env.modules_sources, libvpx_sources_intrin_x86) - - env_libvpx.add_source_files(env.modules_sources, libvpx_sources_x86asm) - if cpu_bits == "64": - env_libvpx.add_source_files(env.modules_sources, libvpx_sources_x86_64asm) -elif webm_cpu_arm: - env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm) - if env["platform"] == "android": - env_libvpx.Prepend(CPPPATH=[libvpx_dir + "third_party/android"]) - env_libvpx.add_source_files(env.modules_sources, [libvpx_dir + "third_party/android/cpu-features.c"]) - - env_libvpx_neon = env_libvpx.Clone() - env_libvpx_neon.add_source_files(env.modules_sources, libvpx_sources_arm_neon) - - if env["platform"] == "uwp": - env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm_neon_armasm_ms) - elif env["platform"] == "iphone": - env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm_neon_gas_apple) - elif (is_x11_or_server_arm and cpu_bits == "32") or ( - env["platform"] == "android" and not env["android_arch"] == "arm64v8" - ): - env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm_neon_gas) diff --git a/modules/webm/register_types.h b/modules/webm/register_types.h deleted file mode 100644 index d090fe745b..0000000000 --- a/modules/webm/register_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* register_types.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef WEBM_REGISTER_TYPES_H -#define WEBM_REGISTER_TYPES_H - -void register_webm_types(); -void unregister_webm_types(); - -#endif // WEBM_REGISTER_TYPES_H diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp deleted file mode 100644 index 12e0f5bd25..0000000000 --- a/modules/webm/video_stream_webm.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/*************************************************************************/ -/* video_stream_webm.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "video_stream_webm.h" - -#include "core/config/project_settings.h" -#include "core/io/file_access.h" -#include "core/os/os.h" -#include "servers/audio_server.h" - -#include "thirdparty/misc/yuv2rgb.h" - -// libsimplewebm -#include <OpusVorbisDecoder.hpp> -#include <VPXDecoder.hpp> - -// libvpx -#include <vpx/vpx_image.h> - -// libwebm -#include <mkvparser/mkvparser.h> - -class MkvReader : public mkvparser::IMkvReader { -public: - MkvReader(const String &p_file) { - file = FileAccess::open(p_file, FileAccess::READ); - - ERR_FAIL_COND_MSG(!file, "Failed loading resource: '" + p_file + "'."); - } - ~MkvReader() { - if (file) { - memdelete(file); - } - } - - virtual int Read(long long pos, long len, unsigned char *buf) { - if (file) { - if (file->get_position() != (uint64_t)pos) { - file->seek(pos); - } - if (file->get_buffer(buf, len) == (uint64_t)len) { - return 0; - } - } - return -1; - } - - virtual int Length(long long *total, long long *available) { - if (file) { - const uint64_t len = file->get_length(); - if (total) { - *total = len; - } - if (available) { - *available = len; - } - return 0; - } - return -1; - } - -private: - FileAccess *file; -}; - -/**/ - -VideoStreamPlaybackWebm::VideoStreamPlaybackWebm() : - - texture(memnew(ImageTexture)) {} -VideoStreamPlaybackWebm::~VideoStreamPlaybackWebm() { - delete_pointers(); -} - -bool VideoStreamPlaybackWebm::open_file(const String &p_file) { - file_name = p_file; - webm = memnew(WebMDemuxer(new MkvReader(file_name), 0, audio_track)); - if (webm->isOpen()) { - video = memnew(VPXDecoder(*webm, OS::get_singleton()->get_processor_count())); - if (video->isOpen()) { - audio = memnew(OpusVorbisDecoder(*webm)); - if (audio->isOpen()) { - audio_frame = memnew(WebMFrame); - pcm = (float *)memalloc(sizeof(float) * audio->getBufferSamples() * webm->getChannels()); - } else { - memdelete(audio); - audio = nullptr; - } - - frame_data.resize((webm->getWidth() * webm->getHeight()) << 2); - Ref<Image> img; - img.instantiate(); - img->create(webm->getWidth(), webm->getHeight(), false, Image::FORMAT_RGBA8); - texture->create_from_image(img); - - return true; - } - memdelete(video); - video = nullptr; - } - memdelete(webm); - webm = nullptr; - return false; -} - -void VideoStreamPlaybackWebm::stop() { - if (playing) { - delete_pointers(); - - pcm = nullptr; - - audio_frame = nullptr; - video_frames = nullptr; - - video = nullptr; - audio = nullptr; - - open_file(file_name); //Should not fail here... - - video_frames_capacity = video_frames_pos = 0; - num_decoded_samples = 0; - samples_offset = -1; - video_frame_delay = video_pos = 0.0; - } - time = 0.0; - playing = false; -} - -void VideoStreamPlaybackWebm::play() { - stop(); - - delay_compensation = ProjectSettings::get_singleton()->get("audio/video/video_delay_compensation_ms"); - delay_compensation /= 1000.0; - - playing = true; -} - -bool VideoStreamPlaybackWebm::is_playing() const { - return playing; -} - -void VideoStreamPlaybackWebm::set_paused(bool p_paused) { - paused = p_paused; -} - -bool VideoStreamPlaybackWebm::is_paused() const { - return paused; -} - -void VideoStreamPlaybackWebm::set_loop(bool p_enable) { - //Empty -} - -bool VideoStreamPlaybackWebm::has_loop() const { - return false; -} - -float VideoStreamPlaybackWebm::get_length() const { - if (webm) { - return webm->getLength(); - } - return 0.0f; -} - -float VideoStreamPlaybackWebm::get_playback_position() const { - return video_pos; -} - -void VideoStreamPlaybackWebm::seek(float p_time) { - WARN_PRINT_ONCE("Seeking in Theora and WebM videos is not implemented yet (it's only supported for GDNative-provided video streams)."); -} - -void VideoStreamPlaybackWebm::set_audio_track(int p_idx) { - audio_track = p_idx; -} - -Ref<Texture2D> VideoStreamPlaybackWebm::get_texture() const { - return texture; -} - -void VideoStreamPlaybackWebm::update(float p_delta) { - if ((!playing || paused) || !video) { - return; - } - - time += p_delta; - - if (time < video_pos) { - return; - } - - bool audio_buffer_full = false; - - if (samples_offset > -1) { - //Mix remaining samples - const int to_read = num_decoded_samples - samples_offset; - const int mixed = mix_callback(mix_udata, pcm + samples_offset * webm->getChannels(), to_read); - if (mixed != to_read) { - samples_offset += mixed; - audio_buffer_full = true; - } else { - samples_offset = -1; - } - } - - const bool hasAudio = (audio && mix_callback); - while ((hasAudio && !audio_buffer_full && !has_enough_video_frames()) || - (!hasAudio && video_frames_pos == 0)) { - if (hasAudio && !audio_buffer_full && audio_frame->isValid() && - audio->getPCMF(*audio_frame, pcm, num_decoded_samples) && num_decoded_samples > 0) { - const int mixed = mix_callback(mix_udata, pcm, num_decoded_samples); - - if (mixed != num_decoded_samples) { - samples_offset = mixed; - audio_buffer_full = true; - } - } - - WebMFrame *video_frame; - if (video_frames_pos >= video_frames_capacity) { - WebMFrame **video_frames_new = (WebMFrame **)memrealloc(video_frames, ++video_frames_capacity * sizeof(void *)); - ERR_FAIL_COND(!video_frames_new); //Out of memory - (video_frames = video_frames_new)[video_frames_capacity - 1] = memnew(WebMFrame); - } - video_frame = video_frames[video_frames_pos]; - - if (!webm->readFrame(video_frame, audio_frame)) { //This will invalidate frames - break; //Can't demux, EOS? - } - - if (video_frame->isValid()) { - ++video_frames_pos; - } - }; - - bool video_frame_done = false; - while (video_frames_pos > 0 && !video_frame_done) { - WebMFrame *video_frame = video_frames[0]; - - // It seems VPXDecoder::decode has to be executed even though we might skip this frame - if (video->decode(*video_frame)) { - VPXDecoder::IMAGE_ERROR err; - VPXDecoder::Image image; - - if (should_process(*video_frame)) { - if ((err = video->getImage(image)) != VPXDecoder::NO_FRAME) { - if (err == VPXDecoder::NO_ERROR && image.w == webm->getWidth() && image.h == webm->getHeight()) { - uint8_t *w = frame_data.ptrw(); - bool converted = false; - - if (image.chromaShiftW == 0 && image.chromaShiftH == 0 && image.cs == VPX_CS_SRGB) { - uint8_t *wp = w; - unsigned char *rRow = image.planes[2]; - unsigned char *gRow = image.planes[0]; - unsigned char *bRow = image.planes[1]; - for (int i = 0; i < image.h; i++) { - for (int j = 0; j < image.w; j++) { - *wp++ = rRow[j]; - *wp++ = gRow[j]; - *wp++ = bRow[j]; - *wp++ = 255; - } - rRow += image.linesize[2]; - gRow += image.linesize[0]; - bRow += image.linesize[1]; - } - converted = true; - } else if (image.chromaShiftW == 1 && image.chromaShiftH == 1) { - yuv420_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2); - //libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); - converted = true; - } else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) { - yuv422_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2); - //libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); - converted = true; - } else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) { - yuv444_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2); - //libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); - converted = true; - } else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) { - //libyuv::I411ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2] image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); - //converted = true; - } - - if (converted) { - Ref<Image> img = memnew(Image(image.w, image.h, 0, Image::FORMAT_RGBA8, frame_data)); - texture->update(img); //Zero copy send to visual server - video_frame_done = true; - } - } - } - } - } - - video_pos = video_frame->time; - memmove(video_frames, video_frames + 1, (--video_frames_pos) * sizeof(void *)); - video_frames[video_frames_pos] = video_frame; - } - - if (video_frames_pos == 0 && webm->isEOS()) { - stop(); - } -} - -void VideoStreamPlaybackWebm::set_mix_callback(VideoStreamPlayback::AudioMixCallback p_callback, void *p_userdata) { - mix_callback = p_callback; - mix_udata = p_userdata; -} - -int VideoStreamPlaybackWebm::get_channels() const { - if (audio) { - return webm->getChannels(); - } - return 0; -} - -int VideoStreamPlaybackWebm::get_mix_rate() const { - if (audio) { - return webm->getSampleRate(); - } - return 0; -} - -inline bool VideoStreamPlaybackWebm::has_enough_video_frames() const { - if (video_frames_pos > 0) { - // FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to - // systematically return 0. Now that it gives a proper latency, it broke this - // code where the delay compensation likely never really worked. - //const double audio_delay = AudioServer::get_singleton()->get_output_latency(); - const double video_time = video_frames[video_frames_pos - 1]->time; - return video_time >= time + /* audio_delay + */ delay_compensation; - } - return false; -} - -bool VideoStreamPlaybackWebm::should_process(WebMFrame &video_frame) { - // FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to - // systematically return 0. Now that it gives a proper latency, it broke this - // code where the delay compensation likely never really worked. - //const double audio_delay = AudioServer::get_singleton()->get_output_latency(); - return video_frame.time >= time + /* audio_delay + */ delay_compensation; -} - -void VideoStreamPlaybackWebm::delete_pointers() { - if (pcm) { - memfree(pcm); - } - - if (audio_frame) { - memdelete(audio_frame); - } - if (video_frames) { - for (int i = 0; i < video_frames_capacity; ++i) { - memdelete(video_frames[i]); - } - memfree(video_frames); - } - - if (video) { - memdelete(video); - } - if (audio) { - memdelete(audio); - } - - if (webm) { - memdelete(webm); - } -} - -/**/ - -VideoStreamWebm::VideoStreamWebm() {} - -Ref<VideoStreamPlayback> VideoStreamWebm::instance_playback() { - Ref<VideoStreamPlaybackWebm> pb = memnew(VideoStreamPlaybackWebm); - pb->set_audio_track(audio_track); - if (pb->open_file(file)) { - return pb; - } - return nullptr; -} - -void VideoStreamWebm::set_file(const String &p_file) { - file = p_file; -} - -String VideoStreamWebm::get_file() { - return file; -} - -void VideoStreamWebm::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamWebm::set_file); - ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamWebm::get_file); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_file", "get_file"); -} - -void VideoStreamWebm::set_audio_track(int p_track) { - audio_track = p_track; -} - -//////////// - -RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { - FileAccess *f = FileAccess::open(p_path, FileAccess::READ); - if (!f) { - if (r_error) { - *r_error = ERR_CANT_OPEN; - } - return RES(); - } - - VideoStreamWebm *stream = memnew(VideoStreamWebm); - stream->set_file(p_path); - - Ref<VideoStreamWebm> webm_stream = Ref<VideoStreamWebm>(stream); - - if (r_error) { - *r_error = OK; - } - - f->close(); - memdelete(f); - return webm_stream; -} - -void ResourceFormatLoaderWebm::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("webm"); -} - -bool ResourceFormatLoaderWebm::handles_type(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "VideoStream"); -} - -String ResourceFormatLoaderWebm::get_resource_type(const String &p_path) const { - String el = p_path.get_extension().to_lower(); - if (el == "webm") { - return "VideoStreamWebm"; - } - return ""; -} diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h deleted file mode 100644 index 60e02ab38b..0000000000 --- a/modules/webm/video_stream_webm.h +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************/ -/* video_stream_webm.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VIDEO_STREAM_WEBM_H -#define VIDEO_STREAM_WEBM_H - -#include "core/io/resource_loader.h" -#include "scene/resources/video_stream.h" - -class WebMFrame; -class WebMDemuxer; -class VPXDecoder; -class OpusVorbisDecoder; - -class VideoStreamPlaybackWebm : public VideoStreamPlayback { - GDCLASS(VideoStreamPlaybackWebm, VideoStreamPlayback); - - String file_name; - int audio_track = 0; - - WebMDemuxer *webm = nullptr; - VPXDecoder *video = nullptr; - OpusVorbisDecoder *audio = nullptr; - - WebMFrame **video_frames = nullptr, *audio_frame = nullptr; - int video_frames_pos = 0, video_frames_capacity = 0; - - int num_decoded_samples = 0, samples_offset = -1; - AudioMixCallback mix_callback = nullptr; - void *mix_udata = nullptr; - - bool playing = false, paused = false; - double delay_compensation = 0.0; - double time = 0.0, video_frame_delay = 0.0, video_pos = 0.0; - - Vector<uint8_t> frame_data; - Ref<ImageTexture> texture; - - float *pcm = nullptr; - -public: - VideoStreamPlaybackWebm(); - ~VideoStreamPlaybackWebm(); - - bool open_file(const String &p_file); - - virtual void stop() override; - virtual void play() override; - - virtual bool is_playing() const override; - - virtual void set_paused(bool p_paused) override; - virtual bool is_paused() const override; - - virtual void set_loop(bool p_enable) override; - virtual bool has_loop() const override; - - virtual float get_length() const override; - - virtual float get_playback_position() const override; - virtual void seek(float p_time) override; - - virtual void set_audio_track(int p_idx) override; - - virtual Ref<Texture2D> get_texture() const override; - virtual void update(float p_delta) override; - - virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata) override; - virtual int get_channels() const override; - virtual int get_mix_rate() const override; - -private: - inline bool has_enough_video_frames() const; - bool should_process(WebMFrame &video_frame); - - void delete_pointers(); -}; - -/**/ - -class VideoStreamWebm : public VideoStream { - GDCLASS(VideoStreamWebm, VideoStream); - - String file; - int audio_track = 0; - -protected: - static void _bind_methods(); - -public: - VideoStreamWebm(); - - virtual Ref<VideoStreamPlayback> instance_playback() override; - - virtual void set_file(const String &p_file); - String get_file(); - virtual void set_audio_track(int p_track) override; -}; - -class ResourceFormatLoaderWebm : public ResourceFormatLoader { -public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - virtual bool handles_type(const String &p_type) const; - virtual String get_resource_type(const String &p_path) const; -}; - -#endif // VIDEO_STREAM_WEBM_H diff --git a/modules/webp/SCsub b/modules/webp/SCsub index 4c0c2f7893..80d62400c8 100644 --- a/modules/webp/SCsub +++ b/modules/webp/SCsub @@ -67,6 +67,7 @@ if env["builtin_libwebp"]: "dsp/lossless_msa.c", "dsp/lossless_neon.c", "dsp/lossless_sse2.c", + "dsp/lossless_sse41.c", "dsp/rescaler.c", "dsp/rescaler_mips32.c", "dsp/rescaler_mips_dsp_r2.c", diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp index 5bebad2b53..902e182d83 100644 --- a/modules/webp/image_loader_webp.cpp +++ b/modules/webp/image_loader_webp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h index 9ea3056a19..327582ca55 100644 --- a/modules/webp/image_loader_webp.h +++ b/modules/webp/image_loader_webp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webp/register_types.cpp b/modules/webp/register_types.cpp index ea9af72418..462c0a0b3d 100644 --- a/modules/webp/register_types.cpp +++ b/modules/webp/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webp/register_types.h b/modules/webp/register_types.h index 59d6894bf6..828ef07f9a 100644 --- a/modules/webp/register_types.h +++ b/modules/webp/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml b/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml index a8360a4d45..780791c0d9 100644 --- a/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml +++ b/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml @@ -32,7 +32,7 @@ <return type="Dictionary" /> <argument index="0" name="peer_id" type="int" /> <description> - Return a dictionary representation of the peer with given [code]peer_id[/code] with three keys. [code]connection[/code] containing the [WebRTCPeerConnection] to this peer, [code]channels[/code] an array of three [WebRTCDataChannel], and [code]connected[/code] a boolean representing if the peer connection is currently connected (all three channels are open). + Returns a dictionary representation of the peer with given [code]peer_id[/code] with three keys. [code]connection[/code] containing the [WebRTCPeerConnection] to this peer, [code]channels[/code] an array of three [WebRTCDataChannel], and [code]connected[/code] a boolean representing if the peer connection is currently connected (all three channels are open). </description> </method> <method name="get_peers"> diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml index f6f360503f..618fe14137 100644 --- a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml +++ b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml @@ -26,7 +26,8 @@ <method name="close"> <return type="void" /> <description> - Close the peer connection and all data channels associated with it. Note, you cannot reuse this object for a new connection unless you call [method initialize]. + Close the peer connection and all data channels associated with it. + [b]Note:[/b] You cannot reuse this object for a new connection unless you call [method initialize]. </description> </method> <method name="create_data_channel"> diff --git a/modules/webrtc/library_godot_webrtc.js b/modules/webrtc/library_godot_webrtc.js index a0a6c21be3..e57e4299e0 100644 --- a/modules/webrtc/library_godot_webrtc.js +++ b/modules/webrtc/library_godot_webrtc.js @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/register_types.cpp b/modules/webrtc/register_types.cpp index 8110e4a048..54d4f57eef 100644 --- a/modules/webrtc/register_types.cpp +++ b/modules/webrtc/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/register_types.h b/modules/webrtc/register_types.h index 710ee88a28..2e4457beaf 100644 --- a/modules/webrtc/register_types.h +++ b/modules/webrtc/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_data_channel.cpp b/modules/webrtc/webrtc_data_channel.cpp index ca520a733d..b4af4b8415 100644 --- a/modules/webrtc/webrtc_data_channel.cpp +++ b/modules/webrtc/webrtc_data_channel.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_data_channel.h b/modules/webrtc/webrtc_data_channel.h index 809d35c6e3..eac8f85a84 100644 --- a/modules/webrtc/webrtc_data_channel.h +++ b/modules/webrtc/webrtc_data_channel.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_data_channel_extension.cpp b/modules/webrtc/webrtc_data_channel_extension.cpp index ae346f6d8e..b7ea8d22bb 100644 --- a/modules/webrtc/webrtc_data_channel_extension.cpp +++ b/modules/webrtc/webrtc_data_channel_extension.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_data_channel_extension.h b/modules/webrtc/webrtc_data_channel_extension.h index eec96b4c62..83bb627815 100644 --- a/modules/webrtc/webrtc_data_channel_extension.h +++ b/modules/webrtc/webrtc_data_channel_extension.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp index 31d6a0568c..4c41a4c7ee 100644 --- a/modules/webrtc/webrtc_data_channel_js.cpp +++ b/modules/webrtc/webrtc_data_channel_js.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_data_channel_js.h b/modules/webrtc/webrtc_data_channel_js.h index 5cd6a32ed9..d059ec31ed 100644 --- a/modules/webrtc/webrtc_data_channel_js.h +++ b/modules/webrtc/webrtc_data_channel_js.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_multiplayer_peer.cpp b/modules/webrtc/webrtc_multiplayer_peer.cpp index 133bd71ddb..bc3c0d9265 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.cpp +++ b/modules/webrtc/webrtc_multiplayer_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -146,6 +146,10 @@ void WebRTCMultiplayerPeer::_find_next_peer() { } // After last. while (E) { + if (!E->get()->connected) { + E = E->next(); + continue; + } for (const Ref<WebRTCDataChannel> &F : E->get()->channels) { if (F->get_available_packet_count()) { next_packet_peer = E->key(); @@ -157,6 +161,10 @@ void WebRTCMultiplayerPeer::_find_next_peer() { E = peer_map.front(); // Before last while (E) { + if (!E->get()->connected) { + E = E->next(); + continue; + } for (const Ref<WebRTCDataChannel> &F : E->get()->channels) { if (F->get_available_packet_count()) { next_packet_peer = E->key(); @@ -378,6 +386,9 @@ int WebRTCMultiplayerPeer::get_available_packet_count() const { } int size = 0; for (const KeyValue<int, Ref<ConnectedPeer>> &E : peer_map) { + if (!E.value->connected) { + continue; + } for (const Ref<WebRTCDataChannel> &F : E.value->channels) { size += F->get_available_packet_count(); } diff --git a/modules/webrtc/webrtc_multiplayer_peer.h b/modules/webrtc/webrtc_multiplayer_peer.h index 4a7e9ad7c8..6675c67867 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.h +++ b/modules/webrtc/webrtc_multiplayer_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_peer_connection.cpp b/modules/webrtc/webrtc_peer_connection.cpp index ad28aa76c7..96cf518c06 100644 --- a/modules/webrtc/webrtc_peer_connection.cpp +++ b/modules/webrtc/webrtc_peer_connection.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_peer_connection.h b/modules/webrtc/webrtc_peer_connection.h index e2ef3e55ad..8c324d0942 100644 --- a/modules/webrtc/webrtc_peer_connection.h +++ b/modules/webrtc/webrtc_peer_connection.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_peer_connection_extension.cpp b/modules/webrtc/webrtc_peer_connection_extension.cpp index 33288e66d6..3bc7de217e 100644 --- a/modules/webrtc/webrtc_peer_connection_extension.cpp +++ b/modules/webrtc/webrtc_peer_connection_extension.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_peer_connection_extension.h b/modules/webrtc/webrtc_peer_connection_extension.h index b3c2039fc1..82e32b5602 100644 --- a/modules/webrtc/webrtc_peer_connection_extension.h +++ b/modules/webrtc/webrtc_peer_connection_extension.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_peer_connection_js.cpp b/modules/webrtc/webrtc_peer_connection_js.cpp index ed3459d5f8..90e19fe4f1 100644 --- a/modules/webrtc/webrtc_peer_connection_js.cpp +++ b/modules/webrtc/webrtc_peer_connection_js.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webrtc/webrtc_peer_connection_js.h b/modules/webrtc/webrtc_peer_connection_js.h index d2beccaf03..3d0b365355 100644 --- a/modules/webrtc/webrtc_peer_connection_js.h +++ b/modules/webrtc/webrtc_peer_connection_js.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub index 4c022c43cf..63c941c4a8 100644 --- a/modules/websocket/SCsub +++ b/modules/websocket/SCsub @@ -18,12 +18,11 @@ elif env["builtin_wslay"]: "wslay_net.c", "wslay_event.c", "wslay_queue.c", - "wslay_stack.c", "wslay_frame.c", ] thirdparty_sources = [thirdparty_dir + s for s in thirdparty_sources] - env_ws.Prepend(CPPPATH=[thirdparty_dir + "includes/"]) + env_ws.Prepend(CPPPATH=[thirdparty_dir]) env_ws.Append(CPPDEFINES=["HAVE_CONFIG_H"]) if env["platform"] == "windows" or env["platform"] == "uwp": diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml index 4b515c12a1..5fcf51293d 100644 --- a/modules/websocket/doc_classes/WebSocketClient.xml +++ b/modules/websocket/doc_classes/WebSocketClient.xml @@ -39,13 +39,13 @@ <method name="get_connected_host" qualifiers="const"> <return type="String" /> <description> - Return the IP address of the currently connected host. + Returns the IP address of the currently connected host. </description> </method> <method name="get_connected_port" qualifiers="const"> <return type="int" /> <description> - Return the IP port of the currently connected host. + Returns the IP port of the currently connected host. </description> </method> </methods> diff --git a/modules/websocket/doc_classes/WebSocketPeer.xml b/modules/websocket/doc_classes/WebSocketPeer.xml index ab7ef6c4d0..2f455c32fd 100644 --- a/modules/websocket/doc_classes/WebSocketPeer.xml +++ b/modules/websocket/doc_classes/WebSocketPeer.xml @@ -4,7 +4,7 @@ A class representing a specific WebSocket connection. </brief_description> <description> - This class represent a specific WebSocket connection, you can do lower level operations with it. + This class represents a specific WebSocket connection, allowing you to do lower level operations with it. You can choose to write to the socket in binary or text mode, and you can recognize the mode used for writing by the other peer. </description> <tutorials> diff --git a/modules/websocket/editor_debugger_server_websocket.cpp b/modules/websocket/editor_debugger_server_websocket.cpp index d248433d82..4f1a56f00b 100644 --- a/modules/websocket/editor_debugger_server_websocket.cpp +++ b/modules/websocket/editor_debugger_server_websocket.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,8 @@ #include "editor_debugger_server_websocket.h" #include "core/config/project_settings.h" +#include "editor/editor_log.h" +#include "editor/editor_node.h" #include "editor/editor_settings.h" #include "modules/websocket/remote_debugger_peer_websocket.h" @@ -48,19 +50,47 @@ void EditorDebuggerServerWebSocket::poll() { server->poll(); } +String EditorDebuggerServerWebSocket::get_uri() const { + return endpoint; +} + Error EditorDebuggerServerWebSocket::start(const String &p_uri) { + // Default host and port + String bind_host = (String)EditorSettings::get_singleton()->get("network/debug/remote_host"); int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); - String bind_host = EditorSettings::get_singleton()->get("network/debug/remote_host"); + + // Optionally override if (!p_uri.is_empty() && p_uri != "ws://") { String scheme, path; Error err = p_uri.parse_url(scheme, bind_host, bind_port, path); ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER); } + + // Set up the server server->set_bind_ip(bind_host); Vector<String> compatible_protocols; compatible_protocols.push_back("binary"); // compatibility with EMSCRIPTEN TCP-to-WebSocket layer. - return server->listen(bind_port, compatible_protocols); + + // Try listening on ports + const int max_attempts = 5; + for (int attempt = 1;; ++attempt) { + const Error err = server->listen(bind_port, compatible_protocols); + if (err == OK) { + break; + } + if (attempt >= max_attempts) { + EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, remote debugging unavailable.", bind_port), EditorLog::MSG_TYPE_ERROR); + return err; + } + int last_port = bind_port++; + EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, trying %d instead.", last_port, bind_port), EditorLog::MSG_TYPE_WARNING); + } + + // Endpoint that the client should connect to + endpoint = vformat("ws://%s:%d", bind_host, bind_port); + + return OK; } void EditorDebuggerServerWebSocket::stop() { diff --git a/modules/websocket/editor_debugger_server_websocket.h b/modules/websocket/editor_debugger_server_websocket.h index 14ab0109b2..cc14bf62ba 100644 --- a/modules/websocket/editor_debugger_server_websocket.h +++ b/modules/websocket/editor_debugger_server_websocket.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -40,6 +40,7 @@ class EditorDebuggerServerWebSocket : public EditorDebuggerServer { private: Ref<WebSocketServer> server; List<int> pending_peers; + String endpoint; public: static EditorDebuggerServer *create(const String &p_protocol); @@ -47,12 +48,13 @@ public: void _peer_connected(int p_peer, String p_protocol); void _peer_disconnected(int p_peer, bool p_was_clean); - void poll() override; - Error start(const String &p_uri) override; - void stop() override; - bool is_active() const override; - bool is_connection_available() const override; - Ref<RemoteDebuggerPeer> take_connection() override; + virtual void poll() override; + virtual String get_uri() const override; + virtual Error start(const String &p_uri = "") override; + virtual void stop() override; + virtual bool is_active() const override; + virtual bool is_connection_available() const override; + virtual Ref<RemoteDebuggerPeer> take_connection() override; EditorDebuggerServerWebSocket(); ~EditorDebuggerServerWebSocket(); diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 5cd94e978f..2d029dfbbc 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index 3b0b8395b9..61ea0002ea 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index d7263dcf43..77a96c8e4f 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,11 +54,14 @@ Error EMWSPeer::read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_strin } Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { - ERR_FAIL_COND_V(_out_buf_size && ((uint64_t)godot_js_websocket_buffered_amount(peer_sock) >= (1ULL << _out_buf_size)), ERR_OUT_OF_MEMORY); + ERR_FAIL_COND_V(_out_buf_size && ((uint64_t)godot_js_websocket_buffered_amount(peer_sock) + p_buffer_size >= (1ULL << _out_buf_size)), ERR_OUT_OF_MEMORY); int is_bin = write_mode == WebSocketPeer::WRITE_MODE_BINARY ? 1 : 0; - godot_js_websocket_send(peer_sock, p_buffer, p_buffer_size, is_bin); + if (godot_js_websocket_send(peer_sock, p_buffer, p_buffer_size, is_bin) != 0) { + return FAILED; + } + return OK; } diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index 6e93ea31a2..df63d2d801 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp index 4a4f09a943..53b4a0207d 100644 --- a/modules/websocket/emws_server.cpp +++ b/modules/websocket/emws_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h index d36e3a3557..f310c17c9d 100644 --- a/modules/websocket/emws_server.h +++ b/modules/websocket/emws_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/library_godot_websocket.js b/modules/websocket/library_godot_websocket.js index dd2fd1e94f..c88986fbe3 100644 --- a/modules/websocket/library_godot_websocket.js +++ b/modules/websocket/library_godot_websocket.js @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/packet_buffer.h b/modules/websocket/packet_buffer.h index e99a379767..7b4a164576 100644 --- a/modules/websocket/packet_buffer.h +++ b/modules/websocket/packet_buffer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp index 7c742b1b89..1e9a4c0392 100644 --- a/modules/websocket/register_types.cpp +++ b/modules/websocket/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/register_types.h b/modules/websocket/register_types.h index 3884db67b7..4ab6c0cfd3 100644 --- a/modules/websocket/register_types.h +++ b/modules/websocket/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/remote_debugger_peer_websocket.cpp b/modules/websocket/remote_debugger_peer_websocket.cpp index c9591cc564..6319c3c664 100644 --- a/modules/websocket/remote_debugger_peer_websocket.cpp +++ b/modules/websocket/remote_debugger_peer_websocket.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/remote_debugger_peer_websocket.h b/modules/websocket/remote_debugger_peer_websocket.h index 590d925dcc..ddf5425d81 100644 --- a/modules/websocket/remote_debugger_peer_websocket.h +++ b/modules/websocket/remote_debugger_peer_websocket.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp index f7a8944745..2734b4b88f 100644 --- a/modules/websocket/websocket_client.cpp +++ b/modules/websocket/websocket_client.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -129,7 +129,7 @@ void WebSocketClient::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "verify_ssl", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_verify_ssl_enabled", "is_verify_ssl_enabled"); ClassDB::bind_method(D_METHOD("get_trusted_ssl_certificate"), &WebSocketClient::get_trusted_ssl_certificate); - ClassDB::bind_method(D_METHOD("set_trusted_ssl_certificate"), &WebSocketClient::set_trusted_ssl_certificate); + ClassDB::bind_method(D_METHOD("set_trusted_ssl_certificate", "cert"), &WebSocketClient::set_trusted_ssl_certificate); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trusted_ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", PROPERTY_USAGE_NONE), "set_trusted_ssl_certificate", "get_trusted_ssl_certificate"); diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h index c7f17f1ffb..d6c072ae16 100644 --- a/modules/websocket/websocket_client.h +++ b/modules/websocket/websocket_client.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_macros.h b/modules/websocket/websocket_macros.h index d04909c97d..a01ae65c56 100644 --- a/modules/websocket/websocket_macros.h +++ b/modules/websocket/websocket_macros.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef WEBSOCKETMACTOS_H -#define WEBSOCKETMACTOS_H +#ifndef WEBSOCKET_MACROS_H +#define WEBSOCKET_MACROS_H // Defaults per peer buffers, 1024 packets with a shared 65536 bytes payload. #define DEF_PKT_SHIFT 10 @@ -65,4 +65,4 @@ public:\ protected:\ /* clang-format on */ -#endif // WEBSOCKETMACTOS_H +#endif // WEBSOCKET_MACROS_H diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index e54bfbca12..7a3bbf1c47 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index 380edf67ed..43d9d59f38 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_peer.cpp b/modules/websocket/websocket_peer.cpp index ee13040821..a0af9303b8 100644 --- a/modules/websocket/websocket_peer.cpp +++ b/modules/websocket/websocket_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h index 517b8600d6..13fef2424f 100644 --- a/modules/websocket/websocket_peer.h +++ b/modules/websocket/websocket_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index fb838109f3..b7249e4243 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -50,19 +50,19 @@ void WebSocketServer::_bind_methods() { ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "code", "reason"), &WebSocketServer::disconnect_peer, DEFVAL(1000), DEFVAL("")); ClassDB::bind_method(D_METHOD("get_bind_ip"), &WebSocketServer::get_bind_ip); - ClassDB::bind_method(D_METHOD("set_bind_ip"), &WebSocketServer::set_bind_ip); + ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &WebSocketServer::set_bind_ip); ADD_PROPERTY(PropertyInfo(Variant::STRING, "bind_ip"), "set_bind_ip", "get_bind_ip"); ClassDB::bind_method(D_METHOD("get_private_key"), &WebSocketServer::get_private_key); - ClassDB::bind_method(D_METHOD("set_private_key"), &WebSocketServer::set_private_key); + ClassDB::bind_method(D_METHOD("set_private_key", "key"), &WebSocketServer::set_private_key); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "private_key", PROPERTY_HINT_RESOURCE_TYPE, "CryptoKey", PROPERTY_USAGE_NONE), "set_private_key", "get_private_key"); ClassDB::bind_method(D_METHOD("get_ssl_certificate"), &WebSocketServer::get_ssl_certificate); - ClassDB::bind_method(D_METHOD("set_ssl_certificate"), &WebSocketServer::set_ssl_certificate); + ClassDB::bind_method(D_METHOD("set_ssl_certificate", "cert"), &WebSocketServer::set_ssl_certificate); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", PROPERTY_USAGE_NONE), "set_ssl_certificate", "get_ssl_certificate"); ClassDB::bind_method(D_METHOD("get_ca_chain"), &WebSocketServer::get_ca_chain); - ClassDB::bind_method(D_METHOD("set_ca_chain"), &WebSocketServer::set_ca_chain); + ClassDB::bind_method(D_METHOD("set_ca_chain", "ca_chain"), &WebSocketServer::set_ca_chain); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ca_chain", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", PROPERTY_USAGE_NONE), "set_ca_chain", "get_ca_chain"); ClassDB::bind_method(D_METHOD("get_handshake_timeout"), &WebSocketServer::get_handshake_timeout); diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index c4d651471f..f6f3b80045 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index 26c0176ea4..bccbf88417 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index 3972977910..4839d7ab9b 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index 7f027e1c0d..d277eedace 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -242,15 +242,15 @@ void WSLPeer::poll() { Error WSLPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { ERR_FAIL_COND_V(!is_connected_to_host(), FAILED); ERR_FAIL_COND_V(_out_pkt_size && (wslay_event_get_queued_msg_count(_data->ctx) >= (1ULL << _out_pkt_size)), ERR_OUT_OF_MEMORY); - ERR_FAIL_COND_V(_out_buf_size && (wslay_event_get_queued_msg_length(_data->ctx) >= (1ULL << _out_buf_size)), ERR_OUT_OF_MEMORY); + ERR_FAIL_COND_V(_out_buf_size && (wslay_event_get_queued_msg_length(_data->ctx) + p_buffer_size >= (1ULL << _out_buf_size)), ERR_OUT_OF_MEMORY); - struct wslay_event_msg msg; // Should I use fragmented? + struct wslay_event_msg msg; msg.opcode = write_mode == WRITE_MODE_TEXT ? WSLAY_TEXT_FRAME : WSLAY_BINARY_FRAME; msg.msg = p_buffer; msg.msg_length = p_buffer_size; - wslay_event_queue_msg(_data->ctx, &msg); - if (wslay_event_send(_data->ctx) < 0) { + // Queue & send message. + if (wslay_event_queue_msg(_data->ctx, &msg) != 0 || wslay_event_send(_data->ctx) != 0) { close_now(); return FAILED; } diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index 260d4b183d..555559c6e1 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 514b2d055f..31175c5779 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -83,11 +83,11 @@ bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols, St break; } // Found a protocol - if (protocol != "") { + if (!protocol.is_empty()) { break; } } - if (protocol == "") { // Invalid protocol(s) requested + if (protocol.is_empty()) { // Invalid protocol(s) requested return false; } } else if (p_protocols.size() > 0) { // No protocol requested, but we need one @@ -138,7 +138,7 @@ Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols, uin s += "Upgrade: websocket\r\n"; s += "Connection: Upgrade\r\n"; s += "Sec-WebSocket-Accept: " + WSLPeer::compute_key_response(key) + "\r\n"; - if (protocol != "") { + if (!protocol.is_empty()) { s += "Sec-WebSocket-Protocol: " + protocol + "\r\n"; } s += "\r\n"; diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index 93c8bd9604..221cae4793 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -53,7 +53,7 @@ private: Ref<StreamPeer> connection; bool use_ssl = false; - int time = 0; + uint64_t time = 0; uint8_t req_buf[WSL_MAX_HEADER_SIZE] = {}; int req_pos = 0; String key; diff --git a/modules/webxr/doc_classes/WebXRInterface.xml b/modules/webxr/doc_classes/WebXRInterface.xml index 16d671c9e9..6e224a8242 100644 --- a/modules/webxr/doc_classes/WebXRInterface.xml +++ b/modules/webxr/doc_classes/WebXRInterface.xml @@ -87,7 +87,7 @@ There are several ways to handle "controller" input: - Using [XRController3D] nodes and their [signal XRController3D.button_pressed] and [signal XRController3D.button_released] signals. This is how controllers are typically handled in AR/VR apps in Godot, however, this will only work with advanced VR controllers like the Oculus Touch or Index controllers, for example. The buttons codes are defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url]. - Using [method Node._unhandled_input] and [InputEventJoypadButton] or [InputEventJoypadMotion]. This works the same as normal joypads, except the [member InputEvent.device] starts at 100, so the left controller is 100 and the right controller is 101, and the button codes are also defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url]. - - Using the [signal select], [signal squeeze] and related signals. This method will work for both advanced VR controllers, and non-traditional "controllers" like a tap on the screen, a spoken voice command or a button press on the device itself. The [code]controller_id[/code] passed to these signals is the same id as used in [member XRController3D.controller_id]. + - Using the [signal select], [signal squeeze] and related signals. This method will work for both advanced VR controllers, and non-traditional "controllers" like a tap on the screen, a spoken voice command or a button press on the device itself. You can use one or all of these methods to allow your game or app to support a wider or narrower set of devices and input methods, or to allow more advanced interactions with more advanced devices. </description> <tutorials> diff --git a/modules/webxr/godot_webxr.h b/modules/webxr/godot_webxr.h index 7aac0a6508..34225df001 100644 --- a/modules/webxr/godot_webxr.h +++ b/modules/webxr/godot_webxr.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webxr/register_types.cpp b/modules/webxr/register_types.cpp index 16b483c39e..78fed3fbd6 100644 --- a/modules/webxr/register_types.cpp +++ b/modules/webxr/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webxr/register_types.h b/modules/webxr/register_types.h index f0c5a4bd79..5dda728099 100644 --- a/modules/webxr/register_types.h +++ b/modules/webxr/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webxr/webxr_interface.cpp b/modules/webxr/webxr_interface.cpp index 3e8e75bf0e..b0ad53523a 100644 --- a/modules/webxr/webxr_interface.cpp +++ b/modules/webxr/webxr_interface.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webxr/webxr_interface.h b/modules/webxr/webxr_interface.h index 366235fcd5..291d53044f 100644 --- a/modules/webxr/webxr_interface.h +++ b/modules/webxr/webxr_interface.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp index 10c17aa672..8eb0d8ff90 100644 --- a/modules/webxr/webxr_interface_js.cpp +++ b/modules/webxr/webxr_interface_js.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -163,9 +163,14 @@ String WebXRInterfaceJS::get_reference_space_type() const { Ref<XRPositionalTracker> WebXRInterfaceJS::get_controller(int p_controller_id) const { XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, nullptr); + ERR_FAIL_NULL_V(xr_server, Ref<XRPositionalTracker>()); - return xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); + // TODO support more then two controllers + if (p_controller_id >= 0 && p_controller_id < 2) { + return controllers[p_controller_id]; + }; + + return Ref<XRPositionalTracker>(); } String WebXRInterfaceJS::get_visibility_state() const { @@ -224,6 +229,13 @@ bool WebXRInterfaceJS::initialize() { return false; } + // we must create a tracker for our head + head_tracker.instantiate(); + head_tracker->set_tracker_type(XRServer::TRACKER_HEAD); + head_tracker->set_tracker_name("head"); + head_tracker->set_tracker_desc("Players head"); + xr_server->add_tracker(head_tracker); + // make this our primary interface xr_server->set_primary_interface(this); @@ -254,9 +266,17 @@ bool WebXRInterfaceJS::initialize() { void WebXRInterfaceJS::uninitialize() { if (initialized) { XRServer *xr_server = XRServer::get_singleton(); - if (xr_server != nullptr && xr_server->get_primary_interface() == this) { - // no longer our primary interface - xr_server->set_primary_interface(nullptr); + if (xr_server != nullptr) { + if (head_tracker.is_valid()) { + xr_server->remove_tracker(head_tracker); + + head_tracker.unref(); + } + + if (xr_server->get_primary_interface() == this) { + // no longer our primary interface + xr_server->set_primary_interface(nullptr); + } } godot_webxr_uninitialize(); @@ -373,9 +393,9 @@ Vector<BlitToScreen> WebXRInterfaceJS::commit_views(RID p_render_target, const R } // @todo Refactor this to be based on "views" rather than "eyes". - godot_webxr_commit_for_eye(XRInterface::EYE_LEFT); + godot_webxr_commit_for_eye(1); if (godot_webxr_get_view_count() > 1) { - godot_webxr_commit_for_eye(XRInterface::EYE_RIGHT); + godot_webxr_commit_for_eye(2); } return blit_to_screen; @@ -385,6 +405,11 @@ void WebXRInterfaceJS::process() { if (initialized) { godot_webxr_sample_controller_data(); + if (head_tracker.is_valid()) { + // TODO set default pose to our head location (i.e. get_camera_transform without world scale and reference frame applied) + // head_tracker->set_pose("default", head_transform, Vector3(), Vector3()); + } + int controller_count = godot_webxr_get_controller_count(); if (controller_count == 0) { return; @@ -400,51 +425,70 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); - Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id + 1); + // need to support more then two controllers... + if (p_controller_id < 0 || p_controller_id > 1) { + return; + } + + Ref<XRPositionalTracker> tracker = controllers[p_controller_id]; if (godot_webxr_is_controller_connected(p_controller_id)) { if (tracker.is_null()) { tracker.instantiate(); tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); // Controller id's 0 and 1 are always the left and right hands. if (p_controller_id < 2) { - tracker->set_tracker_name(p_controller_id == 0 ? "Left" : "Right"); + tracker->set_tracker_name(p_controller_id == 0 ? "left_hand" : "right_hand"); + tracker->set_tracker_desc(p_controller_id == 0 ? "Left hand controller" : "Right hand controller"); tracker->set_tracker_hand(p_controller_id == 0 ? XRPositionalTracker::TRACKER_HAND_LEFT : XRPositionalTracker::TRACKER_HAND_RIGHT); + } else { + char name[1024]; + sprintf(name, "tracker_%i", p_controller_id); + tracker->set_tracker_name(name); + tracker->set_tracker_desc(name); } - // Use the ids we're giving to our "virtual" gamepads. - tracker->set_joy_id(p_controller_id + 100); xr_server->add_tracker(tracker); } - Input *input = Input::get_singleton(); - float *tracker_matrix = godot_webxr_get_controller_transform(p_controller_id); if (tracker_matrix) { + // Note, poses should NOT have world scale and our reference frame applied! Transform3D transform = _js_matrix_to_transform(tracker_matrix); - tracker->set_position(transform.origin); - tracker->set_orientation(transform.basis); + tracker->set_pose("default", transform, Vector3(), Vector3()); free(tracker_matrix); } + // TODO implement additional poses such as "aim" and "grip" + int *buttons = godot_webxr_get_controller_buttons(p_controller_id); if (buttons) { + // TODO buttons should be named properly, this is just a temporary fix for (int i = 0; i < buttons[0]; i++) { - input->joy_button(p_controller_id + 100, (JoyButton)i, *((float *)buttons + (i + 1))); + char name[1024]; + sprintf(name, "button_%i", i); + + float value = *((float *)buttons + (i + 1)); + bool state = value > 0.0; + tracker->set_input(name, state); } free(buttons); } int *axes = godot_webxr_get_controller_axes(p_controller_id); if (axes) { + // TODO again just a temporary fix, split these between proper float and vector2 inputs for (int i = 0; i < axes[0]; i++) { - Input::JoyAxisValue joy_axis; - joy_axis.min = -1; - joy_axis.value = *((float *)axes + (i + 1)); - input->joy_axis(p_controller_id + 100, (JoyAxis)i, joy_axis); + char name[1024]; + sprintf(name, "axis_%i", i); + + float value = *((float *)axes + (i + 1)); + ; + tracker->set_input(name, value); } free(axes); } } else if (tracker.is_valid()) { xr_server->remove_tracker(tracker); + controllers[p_controller_id].unref(); } } @@ -454,7 +498,7 @@ void WebXRInterfaceJS::_on_controller_changed() { for (int i = 0; i < 2; i++) { bool controller_connected = godot_webxr_is_controller_connected(i); if (controllers_state[i] != controller_connected) { - Input::get_singleton()->joy_connection_changed(i + 100, controller_connected, i == 0 ? "Left" : "Right", ""); + // Input::get_singleton()->joy_connection_changed(i + 100, controller_connected, i == 0 ? "Left" : "Right", ""); controllers_state[i] = controller_connected; } } diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h index eb77f35f39..3eec451d50 100644 --- a/modules/webxr/webxr_interface_js.h +++ b/modules/webxr/webxr_interface_js.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -46,6 +46,7 @@ class WebXRInterfaceJS : public WebXRInterface { private: bool initialized; + Ref<XRPositionalTracker> head_tracker; String session_mode; String required_features; @@ -53,7 +54,9 @@ private: String requested_reference_space_types; String reference_space_type; + // TODO maybe turn into a vector to support more then 2 controllers... bool controllers_state[2]; + Ref<XRPositionalTracker> controllers[2]; Size2 render_targetsize; Transform3D _js_matrix_to_transform(float *p_js_matrix); diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index 8913ef1b65..6f397fe285 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -114,7 +114,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver input_mesh.vertexPositionStride = sizeof(float) * 3; input_mesh.vertexNormalData = p_normals; input_mesh.vertexNormalStride = sizeof(uint32_t) * 3; - input_mesh.vertexUvData = NULL; + input_mesh.vertexUvData = nullptr; input_mesh.vertexUvStride = 0; xatlas::ChartOptions chart_options; diff --git a/modules/xatlas_unwrap/register_types.h b/modules/xatlas_unwrap/register_types.h index 2ad729f172..63a985f8c5 100644 --- a/modules/xatlas_unwrap/register_types.h +++ b/modules/xatlas_unwrap/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ |