diff options
Diffstat (limited to 'modules')
91 files changed, 1814 insertions, 646 deletions
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index b5a7da0c38..10a71d65df 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -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,30 +70,42 @@ 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())]; +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 (!event.event_callback.is_valid()) { event.event_callback = Callable(); @@ -101,58 +113,97 @@ void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3 } 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; 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 { @@ -276,6 +312,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, const Callable &p 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(); } } diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index d96c550082..3bff364cc1 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -43,8 +43,6 @@ class btGhostObject; class AreaBullet : public RigidCollisionObjectBullet { - friend void SpaceBullet::check_ghost_overlaps(); - public: struct InOutEventCallback { Callable event_callback; @@ -59,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: @@ -82,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; @@ -104,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; } @@ -143,20 +140,18 @@ public: virtual void set_space(SpaceBullet *p_space); virtual void dispatch_callbacks(); - void call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status); - 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; } - - void add_overlap(CollisionObjectBullet *p_otherObject); - void put_overlap_as_exit(int p_index); - void put_overlap_as_inside(int p_index); + virtual void on_collision_checker_end() { updated = false; } + + 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; diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index c45bd5bbc0..cbb746800d 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -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..6d2c564e44 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -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/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index 1f962772e7..edb2bcb4c7 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -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..3dfa21aec8 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -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/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 7b20fad28c..4faab19539 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -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/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index 3a2370ff31..c0ffffa364 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -442,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/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 66d7370bd7..7aa3815c94 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -662,101 +662,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 +741,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 +789,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/csg/csg.cpp b/modules/csg/csg.cpp index a7742ef415..a70e153abd 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -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/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/enet/doc_classes/ENetMultiplayerPeer.xml b/modules/enet/doc_classes/ENetMultiplayerPeer.xml index 22136c3944..d2456d3360 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> diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml index 6b3bd714b9..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/scripting/gdnative/gdnative_c_example.html</link> - <link title="GDNative C++ example">https://docs.godotengine.org/en/latest/tutorials/scripting/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/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 5b476cda01..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"> diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml index 0a448ed88c..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 documentation index">https://docs.godotengine.org/en/latest/tutorials/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/gdscript.cpp b/modules/gdscript/gdscript.cpp index 68da588c3d..b76c2c0437 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -427,7 +427,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; } } @@ -2131,7 +2131,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_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index cd8fd361c5..1ecde53dd0 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3001,7 +3001,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); } } } diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 9d076a8e4c..e1ed71a268 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -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_parser.cpp b/modules/gdscript/gdscript_parser.cpp index bde6783322..41b2d2191c 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -741,20 +741,22 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)() if (member->identifier != nullptr) { 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_error(vformat(R"(%s "%s" has the same name as a built-in function.)", p_member_kind.capitalize(), member->identifier->name), member->identifier); - return; + 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 if (Variant::has_utility_function(member->identifier->name)) { - push_error(vformat(R"(%s "%s" has the same name as a built-in function.)", p_member_kind.capitalize(), member->identifier->name), member->identifier); - } else if (ClassDB::class_exists(member->identifier->name)) { - push_error(vformat(R"(%s "%s" has the same name as a global class.)", p_member_kind.capitalize(), member->identifier->name), member->identifier); } else { current_class->add_member(member); } @@ -827,21 +829,18 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_allow_proper GDScriptParser::IdentifierNode *identifier = parse_identifier(); +#ifdef DEBUG_ENABLED List<MethodInfo> gdscript_funcs; GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs); for (MethodInfo &info : gdscript_funcs) { if (info.name == identifier->name) { - push_error(vformat(R"(Local var "%s" has the same name as a built-in function.)", identifier->name), identifier); - return nullptr; + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "local variable", identifier->name, "built-in function"); } } if (Variant::has_utility_function(identifier->name)) { - push_error(vformat(R"(Local var "%s" has the same name as a built-in function.)", identifier->name), identifier); - return nullptr; - } else if (ClassDB::class_exists(identifier->name)) { - push_error(vformat(R"(Local var "%s" has the same name as a global class.)", identifier->name), identifier); - return nullptr; + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "local variable", identifier->name, "built-in function"); } +#endif VariableNode *variable = alloc_node<VariableNode>(); variable->identifier = identifier; @@ -1099,22 +1098,20 @@ GDScriptParser::ParameterNode *GDScriptParser::parse_parameter() { } GDScriptParser::IdentifierNode *identifier = parse_identifier(); - +#ifdef DEBUG_ENABLED List<MethodInfo> gdscript_funcs; GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs); for (MethodInfo &info : gdscript_funcs) { if (info.name == identifier->name) { - push_error(vformat(R"(Parameter "%s" has the same name as a built-in function.)", identifier->name), identifier); - return nullptr; + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "parameter", identifier->name, "built-in function"); } } if (Variant::has_utility_function(identifier->name)) { - push_error(vformat(R"(Parameter "%s" has the same name as a built-in function.)", identifier->name), identifier); - return nullptr; + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "parameter", identifier->name, "built-in function"); } else if (ClassDB::class_exists(identifier->name)) { - push_error(vformat(R"(Parameter "%s" has the same name as a global class.)", identifier->name), identifier); - return nullptr; + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "parameter", identifier->name, "global class"); } +#endif ParameterNode *parameter = alloc_node<ParameterNode>(); parameter->identifier = identifier; @@ -1195,8 +1192,10 @@ 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)) { @@ -1205,20 +1204,18 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() { if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier for enum key.)")) { EnumNode::Value item; GDScriptParser::IdentifierNode *identifier = parse_identifier(); - +#ifdef DEBUG_ENABLED for (MethodInfo &info : gdscript_funcs) { if (info.name == identifier->name) { - push_error(vformat(R"(Enum member "%s" has the same name as a built-in function.)", identifier->name), identifier); - return nullptr; + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "enum member", identifier->name, "built-in function"); } } if (Variant::has_utility_function(identifier->name)) { - push_error(vformat(R"(Enum member "%s" has the same name as a built-in function.)", identifier->name), identifier); - return nullptr; + push_warning(identifier, GDScriptWarning::SHADOWED_GLOBAL_IDENTIFIER, "enum member", identifier->name, "built-in function"); } else if (ClassDB::class_exists(identifier->name)) { - push_error(vformat(R"(Enum member "%s" has the same name as a global class.)", identifier->name), identifier); - return nullptr; + 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; @@ -3417,7 +3414,7 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) 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); + p_annotation->resolved_arguments.remove_at(p_annotation->resolved_arguments.size() - 1); return false; } break; @@ -3441,7 +3438,7 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) 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); + p_annotation->resolved_arguments.remove_at(p_annotation->resolved_arguments.size() - 1); return false; } break; diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index af9b973ada..2f05b4b948 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -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; diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp index 7a483a16ba..a351bd6dad 100644 --- a/modules/gdscript/gdscript_warning.cpp +++ b/modules/gdscript/gdscript_warning.cpp @@ -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."); diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h index 8de46b08c1..d05f47efe7 100644 --- a/modules/gdscript/gdscript_warning.h +++ b/modules/gdscript/gdscript_warning.h @@ -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_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 5cf1e0fc5f..578943696e 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -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..a4a63a23a8 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.h +++ b/modules/gdscript/language_server/gdscript_language_protocol.h @@ -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/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..f2b29e5bad --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.out @@ -0,0 +1,9 @@ +GDTEST_OK +>> WARNING +>> Line: 2 +>> SHADOWED_GLOBAL_IDENTIFIER +>> The local variable 'abs' has the same name as a built-in function. +>> 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' diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 0b2854e731..f3317aeada 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -68,7 +68,7 @@ #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" @@ -6115,7 +6115,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; diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index f2f0b439a5..27a1f64bca 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -46,7 +46,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; 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_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 08d55de976..d827ce2fb0 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -611,13 +611,13 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D 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 EditorPlugin::AFTER_GUI_INPUT_STOP; // Eaten. - } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && (mb->is_command_pressed() || mb->is_shift_pressed())) { + } 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()); } @@ -628,7 +628,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D 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,7 +643,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D 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; @@ -665,7 +665,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } 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) { @@ -687,19 +687,19 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D 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 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 EditorPlugin::AFTER_GUI_INPUT_STOP; } @@ -719,7 +719,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D 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; @@ -738,12 +738,12 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } 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 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 EditorPlugin::AFTER_GUI_INPUT_STOP; @@ -759,7 +759,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D 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) { @@ -804,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(); @@ -816,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); } } @@ -1097,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; @@ -1188,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); diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index 158cd960c4..7bb8346c47 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -235,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) { @@ -404,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; @@ -550,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/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp index 49e9f5f97e..a9c1f0bb9a 100644 --- a/modules/minimp3/audio_stream_mp3.cpp +++ b/modules/minimp3/audio_stream_mp3.cpp @@ -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) { diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h index 3c8bdd8c53..e3adfe683b 100644 --- a/modules/minimp3/audio_stream_mp3.h +++ b/modules/minimp3/audio_stream_mp3.h @@ -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/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp index dc360c12ba..b2a755e23b 100644 --- a/modules/minimp3/resource_importer_mp3.cpp +++ b/modules/minimp3/resource_importer_mp3.cpp @@ -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..356ec77d22 100644 --- a/modules/minimp3/resource_importer_mp3.h +++ b/modules/minimp3/resource_importer_mp3.h @@ -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/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index d9b291489b..0ceb45d425 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -788,11 +788,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 +1351,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; diff --git a/modules/mono/doc_classes/CSharpScript.xml b/modules/mono/doc_classes/CSharpScript.xml index 2bca8bc24e..14c62b4bb0 100644 --- a/modules/mono/doc_classes/CSharpScript.xml +++ b/modules/mono/doc_classes/CSharpScript.xml @@ -8,7 +8,7 @@ See also [GodotSharp]. </description> <tutorials> - <link title="C# documentation index">https://docs.godotengine.org/en/latest/tutorials/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"> diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 51a27ee934..a7879e96c8 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -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/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..bfbf1a097e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -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/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..a3afc83222 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -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> @@ -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/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 c18f818ed2..dfb8e87bce 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -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,21 +465,55 @@ 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); } + /// <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) { #if DEBUG @@ -485,31 +527,81 @@ namespace Godot return vec + (((uv * quat.w) + u.Cross(uv)) * 2); } + /// <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 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); @@ -519,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) @@ -534,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..d9ee684c5b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -1345,7 +1345,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..6f1d9574a8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -447,6 +447,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 +562,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..4bb8308c12 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -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..30ecd22db7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -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> @@ -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..3bbc2ae2ba 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs @@ -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> @@ -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..15acf88f62 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -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> @@ -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..562f653fa8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs @@ -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> @@ -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/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp index 86976de244..e367ecb7d6 100644 --- a/modules/mono/glue/collections_glue.cpp +++ b/modules/mono/glue/collections_glue.cpp @@ -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) { diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp index a2ff868f65..07ddf5d945 100644 --- a/modules/mono/glue/gd_glue.cpp +++ b/modules/mono/glue/gd_glue.cpp @@ -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/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index 24bd1ed492..2b4cc7fcc3 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -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/mono_gc_handle.h b/modules/mono/mono_gc_handle.h index d0e51d159f..a18a4ce646 100644 --- a/modules/mono/mono_gc_handle.h +++ b/modules/mono/mono_gc_handle.h @@ -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/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index 179bbfb40c..bcdcd6623b 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -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/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index f600f07c87..ac3422187f 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -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/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index 8fd3a13e1f..05e040b518 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -52,7 +52,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 diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h index 6237b6460d..a0b2a86c41 100644 --- a/modules/opensimplex/noise_texture.h +++ b/modules/opensimplex/noise_texture.h @@ -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/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 1a0b0e357d..f480c86088 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -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" @@ -2146,7 +2148,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) { diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index eb8316b200..5eaff67a6e 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -55,7 +55,7 @@ #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> diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 43a636e484..5c06051211 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -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" @@ -1324,7 +1326,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) { @@ -3265,7 +3267,9 @@ TextServerFallback::TextServerFallback() { }; 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 2f495115e0..67b08d1eac 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -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> 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..6c4c06aab0 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -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_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp index 6a2fb0f666..f64acf8395 100644 --- a/modules/tinyexr/image_saver_tinyexr.cpp +++ b/modules/tinyexr/image_saver_tinyexr.cpp @@ -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/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/upnp.cpp b/modules/upnp/upnp.cpp index 0e51822b01..64823deaba 100644 --- a/modules/upnp/upnp.cpp +++ b/modules/upnp/upnp.cpp @@ -30,8 +30,8 @@ #include "upnp.h" -#include <miniupnpc/miniwget.h> -#include <miniupnpc/upnpcommands.h> +#include <miniwget.h> +#include <upnpcommands.h> #include <stdlib.h> @@ -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..67df187f8c 100644 --- a/modules/upnp/upnp.h +++ b/modules/upnp/upnp.h @@ -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..692a0f3509 100644 --- a/modules/upnp/upnp_device.cpp +++ b/modules/upnp/upnp_device.cpp @@ -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/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/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml index be6bf00e50..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 documentation index">https://docs.godotengine.org/en/latest/tutorials/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 f4abb3c122..b3fd678379 100644 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -112,104 +112,107 @@ <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. </constant> - <constant name="MATH_RANDF_RANGE" value="33" enum="BuiltinFunc"> + <constant name="MATH_RANDI_RANGE" value="33" enum="BuiltinFunc"> + Return a random 32-bit integer value between the two inputs. + </constant> + <constant name="MATH_RANDF_RANGE" value="34" enum="BuiltinFunc"> Return a random floating-point 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_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="35" enum="BuiltinFunc"> + <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"> + <constant name="MATH_RANDSEED" value="37" enum="BuiltinFunc"> Return 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="42" enum="BuiltinFunc"> + <constant name="MATH_WRAPF" value="43" enum="BuiltinFunc"> </constant> - <constant name="MATH_PINGPONG" value="43" enum="BuiltinFunc"> + <constant name="MATH_PINGPONG" value="44" enum="BuiltinFunc"> Return 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="44" enum="BuiltinFunc"> + <constant name="LOGIC_MAX" value="45" enum="BuiltinFunc"> Return the greater of the two numbers, also known as their maximum. </constant> - <constant name="LOGIC_MIN" value="45" enum="BuiltinFunc"> + <constant name="LOGIC_MIN" value="46" enum="BuiltinFunc"> Return the lesser of the two numbers, also known as their minimum. </constant> - <constant name="LOGIC_CLAMP" value="46" enum="BuiltinFunc"> + <constant name="LOGIC_CLAMP" value="47" 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> - <constant name="LOGIC_NEAREST_PO2" value="47" enum="BuiltinFunc"> + <constant name="LOGIC_NEAREST_PO2" value="48" enum="BuiltinFunc"> Return the nearest power of 2 to the input. </constant> - <constant name="OBJ_WEAKREF" value="48" enum="BuiltinFunc"> + <constant name="OBJ_WEAKREF" value="49" enum="BuiltinFunc"> Create a [WeakRef] from the input. </constant> - <constant name="TYPE_CONVERT" value="49" enum="BuiltinFunc"> + <constant name="TYPE_CONVERT" value="50" enum="BuiltinFunc"> Convert between types. </constant> - <constant name="TYPE_OF" value="50" enum="BuiltinFunc"> + <constant name="TYPE_OF" value="51" enum="BuiltinFunc"> Return 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="51" 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="52" enum="BuiltinFunc"> + <constant name="TEXT_CHAR" value="53" enum="BuiltinFunc"> Return a character with the given ascii value. </constant> - <constant name="TEXT_STR" value="53" enum="BuiltinFunc"> + <constant name="TEXT_STR" value="54" enum="BuiltinFunc"> Convert the input to a string. </constant> - <constant name="TEXT_PRINT" value="54" enum="BuiltinFunc"> + <constant name="TEXT_PRINT" value="55" enum="BuiltinFunc"> Print the given string to the output window. </constant> - <constant name="TEXT_PRINTERR" value="55" 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="56" 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="57" enum="BuiltinFunc"> + <constant name="TEXT_PRINT_VERBOSE" value="58" enum="BuiltinFunc"> </constant> - <constant name="VAR_TO_STR" value="58" enum="BuiltinFunc"> + <constant name="VAR_TO_STR" value="59" enum="BuiltinFunc"> Serialize a [Variant] to a string. </constant> - <constant name="STR_TO_VAR" value="59" 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="60" enum="BuiltinFunc"> + <constant name="VAR_TO_BYTES" value="61" enum="BuiltinFunc"> Serialize a [Variant] to a [PackedByteArray]. </constant> - <constant name="BYTES_TO_VAR" value="61" 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="62" enum="BuiltinFunc"> + <constant name="MATH_SMOOTHSTEP" value="63" 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: [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="63" enum="BuiltinFunc"> + <constant name="MATH_POSMOD" value="64" enum="BuiltinFunc"> </constant> - <constant name="MATH_LERP_ANGLE" value="64" enum="BuiltinFunc"> + <constant name="MATH_LERP_ANGLE" value="65" enum="BuiltinFunc"> </constant> - <constant name="TEXT_ORD" value="65" enum="BuiltinFunc"> + <constant name="TEXT_ORD" value="66" enum="BuiltinFunc"> </constant> - <constant name="FUNC_MAX" value="66" 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/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index c74d6f9a4a..13dd1f7bc7 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -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 { @@ -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"); @@ -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; @@ -1952,7 +1981,7 @@ void VisualScriptEditor::input(const Ref<InputEvent> &p_event) { 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(); @@ -2049,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(); @@ -2108,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 @@ -2116,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 @@ -2124,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 @@ -2187,9 +2216,9 @@ 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); @@ -2296,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); @@ -2359,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"]; @@ -2409,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; } @@ -2424,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 { @@ -3676,7 +3705,7 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i } 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->reset_size(); if (pinfo.type == Variant::NODE_PATH) { Node *edited_scene = get_tree()->get_edited_scene_root(); @@ -3832,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; } @@ -4132,10 +4161,10 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { member_popup->clear(); member_popup->set_position(members->get_global_position() + p_pos); - member_popup->set_size(Vector2()); + member_popup->reset_size(); function_name_edit->set_position(members->get_global_position() + p_pos); - function_name_edit->set_size(Vector2()); + function_name_edit->reset_size(); TreeItem *root = members->get_root(); @@ -4554,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 9467c2dea4..fd1db2bc43 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -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; diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp index d8b88d6cd3..02307b712c 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/editor/visual_script_property_selector.cpp @@ -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(); diff --git a/modules/visual_script/visual_script_property_selector.h b/modules/visual_script/editor/visual_script_property_selector.h index 7a87f3d3ee..7a87f3d3ee 100644 --- a/modules/visual_script/visual_script_property_selector.h +++ b/modules/visual_script/editor/visual_script_property_selector.h diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp index 890861cf82..6f56fbbc70 100644 --- a/modules/visual_script/register_types.cpp +++ b/modules/visual_script/register_types.cpp @@ -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/visual_script.cpp b/modules/visual_script/visual_script.cpp index 700cc85672..34d8c0b1e6 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -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 { diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 54a5e1449f..7ae85ea415 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -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", @@ -195,8 +196,9 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) { 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: @@ -353,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"); @@ -360,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: @@ -527,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; @@ -827,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); @@ -1211,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); @@ -1301,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>); diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h index 30f1f0d417..f71a053f7d 100644 --- a/modules/visual_script/visual_script_builtin_funcs.h +++ b/modules/visual_script/visual_script_builtin_funcs.h @@ -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, diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 55c707890f..699042ffa6 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -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_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 471d8ef0ae..b0af030981 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -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(); diff --git a/modules/vorbis/resource_importer_ogg_vorbis.cpp b/modules/vorbis/resource_importer_ogg_vorbis.cpp index 33ee6cf359..be9f880103 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/vorbis/resource_importer_ogg_vorbis.cpp @@ -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..8565e0deb8 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.h +++ b/modules/vorbis/resource_importer_ogg_vorbis.h @@ -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/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/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": |