diff options
Diffstat (limited to 'scene')
43 files changed, 473 insertions, 282 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 7890348314..af722b2461 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -512,25 +512,25 @@ void Area2D::_validate_property(PropertyInfo &property) const { property.hint_string = options; } else if (property.name.begins_with("gravity") && property.name != "gravity_space_override") { if (gravity_space_override == SPACE_OVERRIDE_DISABLED) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } else { if (gravity_is_point) { if (property.name == "gravity_direction") { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } else { if (property.name.begins_with("gravity_point_")) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } } } else if (property.name.begins_with("linear_damp") && property.name != "linear_damp_space_override") { if (linear_damp_space_override == SPACE_OVERRIDE_DISABLED) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } else if (property.name.begins_with("angular_damp") && property.name != "angular_damp_space_override") { if (angular_damp_space_override == SPACE_OVERRIDE_DISABLED) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } } diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index a8c12f4893..7f991df36c 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -186,6 +186,17 @@ bool CollisionObject2D::get_collision_mask_value(int p_layer_number) const { return get_collision_mask() & (1 << (p_layer_number - 1)); } +void CollisionObject2D::set_collision_priority(real_t p_priority) { + collision_priority = p_priority; + if (!area) { + PhysicsServer2D::get_singleton()->body_set_collision_priority(get_rid(), p_priority); + } +} + +real_t CollisionObject2D::get_collision_priority() const { + return collision_priority; +} + void CollisionObject2D::set_disable_mode(DisableMode p_mode) { if (disable_mode == p_mode) { return; @@ -574,6 +585,8 @@ void CollisionObject2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &CollisionObject2D::get_collision_layer_value); ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &CollisionObject2D::set_collision_mask_value); ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &CollisionObject2D::get_collision_mask_value); + ClassDB::bind_method(D_METHOD("set_collision_priority", "priority"), &CollisionObject2D::set_collision_priority); + ClassDB::bind_method(D_METHOD("get_collision_priority"), &CollisionObject2D::get_collision_priority); ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &CollisionObject2D::set_disable_mode); ClassDB::bind_method(D_METHOD("get_disable_mode"), &CollisionObject2D::get_disable_mode); ClassDB::bind_method(D_METHOD("set_pickable", "enabled"), &CollisionObject2D::set_pickable); @@ -611,6 +624,7 @@ void CollisionObject2D::_bind_methods() { ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_priority"), "set_collision_priority", "get_collision_priority"); ADD_GROUP("Input", "input_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input_pickable"), "set_pickable", "is_pickable"); diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index 997afee6c4..f03c6fc72e 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -49,6 +49,7 @@ public: private: uint32_t collision_layer = 1; uint32_t collision_mask = 1; + real_t collision_priority = 1.0; bool area = false; RID rid; @@ -115,6 +116,9 @@ public: void set_collision_mask_value(int p_layer_number, bool p_value); bool get_collision_mask_value(int p_layer_number) const; + void set_collision_priority(real_t p_priority); + real_t get_collision_priority() const; + void set_disable_mode(DisableMode p_mode); DisableMode get_disable_mode() const; diff --git a/scene/2d/physical_bone_2d.cpp b/scene/2d/physical_bone_2d.cpp index 2999736d64..62f4d855ef 100644 --- a/scene/2d/physical_bone_2d.cpp +++ b/scene/2d/physical_bone_2d.cpp @@ -158,6 +158,7 @@ void PhysicalBone2D::_start_physics_simulation() { // Apply the layers and masks. PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); + PhysicsServer2D::get_singleton()->body_set_collision_priority(get_rid(), get_collision_priority()); // Apply the correct mode. _apply_body_mode(); @@ -176,6 +177,7 @@ void PhysicalBone2D::_stop_physics_simulation() { set_physics_process_internal(false); PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), 0); PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), 0); + PhysicsServer2D::get_singleton()->body_set_collision_priority(get_rid(), 1.0); PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_STATIC); } } diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 2ead48c889..e170caf80e 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1065,7 +1065,7 @@ void RigidDynamicBody2D::_bind_methods() { void RigidDynamicBody2D::_validate_property(PropertyInfo &property) const { if (center_of_mass_mode != CENTER_OF_MASS_MODE_CUSTOM) { if (property.name == "center_of_mass") { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } } @@ -1779,11 +1779,11 @@ void CharacterBody2D::_bind_methods() { void CharacterBody2D::_validate_property(PropertyInfo &property) const { if (motion_mode == MOTION_MODE_FLOATING) { if (property.name.begins_with("floor_") || property.name == "up_direction" || property.name == "slide_on_ceiling") { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } else { if (property.name == "wall_min_slide_angle") { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } } diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 68e5ffdcf9..c4036faa79 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -82,6 +82,10 @@ Object *RayCast2D::get_collider() const { return ObjectDB::get_instance(against); } +RID RayCast2D::get_collider_rid() const { + return against_rid; +} + int RayCast2D::get_collider_shape() const { return against_shape; } @@ -203,12 +207,14 @@ void RayCast2D::_update_raycast_state() { if (dss->intersect_ray(ray_params, rr)) { collided = true; against = rr.collider_id; + against_rid = rr.rid; collision_point = rr.position; collision_normal = rr.normal; against_shape = rr.shape; } else { collided = false; against = ObjectID(); + against_rid = RID(); against_shape = 0; } @@ -321,6 +327,7 @@ void RayCast2D::_bind_methods() { ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast2D::force_raycast_update); ClassDB::bind_method(D_METHOD("get_collider"), &RayCast2D::get_collider); + ClassDB::bind_method(D_METHOD("get_collider_rid"), &RayCast2D::get_collider_rid); ClassDB::bind_method(D_METHOD("get_collider_shape"), &RayCast2D::get_collider_shape); ClassDB::bind_method(D_METHOD("get_collision_point"), &RayCast2D::get_collision_point); ClassDB::bind_method(D_METHOD("get_collision_normal"), &RayCast2D::get_collision_normal); diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index 1fb97d89fe..57f993fe8d 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -41,6 +41,7 @@ class RayCast2D : public Node2D { bool enabled = true; bool collided = false; ObjectID against; + RID against_rid; int against_shape = 0; Vector2 collision_point; Vector2 collision_normal; @@ -91,6 +92,7 @@ public: bool is_colliding() const; Object *get_collider() const; + RID get_collider_rid() const; int get_collider_shape() const; Vector2 get_collision_point() const; Vector2 get_collision_normal() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 5ba8c95a06..13bdd2bd5f 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -2063,6 +2063,18 @@ int TileMap::get_cell_alternative_tile(int p_layer, const Vector2i &p_coords, bo return E->value.alternative_tile; } +TileData *TileMap::get_cell_tile_data(int p_layer, const Vector2i &p_coords, bool p_use_proxies) const { + int source_id = get_cell_source_id(p_layer, p_coords, p_use_proxies); + ERR_FAIL_COND_V_MSG(source_id == TileSet::INVALID_SOURCE, nullptr, vformat("Invalid TileSetSource at cell %s. Make sure a tile exists at this cell.", p_coords)); + + Ref<TileSetAtlasSource> source = tile_set->get_source(source_id); + if (source.is_valid()) { + return source->get_tile_data(get_cell_atlas_coords(p_layer, p_coords, p_use_proxies), get_cell_alternative_tile(p_layer, p_coords, p_use_proxies)); + } + + return nullptr; +} + Ref<TileMapPattern> TileMap::get_pattern(int p_layer, TypedArray<Vector2i> p_coords_array) { ERR_FAIL_INDEX_V(p_layer, (int)layers.size(), nullptr); ERR_FAIL_COND_V(!tile_set.is_valid(), nullptr); @@ -3846,9 +3858,10 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_cell", "layer", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMap::set_cell, DEFVAL(TileSet::INVALID_SOURCE), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(0)); ClassDB::bind_method(D_METHOD("erase_cell", "layer", "coords"), &TileMap::erase_cell); - ClassDB::bind_method(D_METHOD("get_cell_source_id", "layer", "coords", "use_proxies"), &TileMap::get_cell_source_id); - ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "layer", "coords", "use_proxies"), &TileMap::get_cell_atlas_coords); - ClassDB::bind_method(D_METHOD("get_cell_alternative_tile", "layer", "coords", "use_proxies"), &TileMap::get_cell_alternative_tile); + ClassDB::bind_method(D_METHOD("get_cell_source_id", "layer", "coords", "use_proxies"), &TileMap::get_cell_source_id, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "layer", "coords", "use_proxies"), &TileMap::get_cell_atlas_coords, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_cell_alternative_tile", "layer", "coords", "use_proxies"), &TileMap::get_cell_alternative_tile, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_cell_tile_data", "layer", "coords", "use_proxies"), &TileMap::get_cell_tile_data, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_coords_for_body_rid", "body"), &TileMap::get_coords_for_body_rid); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 012bf01df9..ecc6ee1d59 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -343,6 +343,8 @@ public: int get_cell_source_id(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const; Vector2i get_cell_atlas_coords(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const; int get_cell_alternative_tile(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const; + // Helper method to make accessing the data easier. + TileData *get_cell_tile_data(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const; // Patterns. Ref<TileMapPattern> get_pattern(int p_layer, TypedArray<Vector2i> p_coords_array); diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index e9e19488e9..1f0fd37d0b 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -612,25 +612,25 @@ void Area3D::_validate_property(PropertyInfo &property) const { property.hint_string = options; } else if (property.name.begins_with("gravity") && property.name != "gravity_space_override") { if (gravity_space_override == SPACE_OVERRIDE_DISABLED) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } else { if (gravity_is_point) { if (property.name == "gravity_direction") { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } else { if (property.name.begins_with("gravity_point_")) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } } } else if (property.name.begins_with("linear_damp") && property.name != "linear_damp_space_override") { if (linear_damp_space_override == SPACE_OVERRIDE_DISABLED) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } else if (property.name.begins_with("angular_damp") && property.name != "angular_damp_space_override") { if (angular_damp_space_override == SPACE_OVERRIDE_DISABLED) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 9a5d4f5480..22de9a47a2 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -183,6 +183,17 @@ bool CollisionObject3D::get_collision_mask_value(int p_layer_number) const { return get_collision_mask() & (1 << (p_layer_number - 1)); } +void CollisionObject3D::set_collision_priority(real_t p_priority) { + collision_priority = p_priority; + if (!area) { + PhysicsServer3D::get_singleton()->body_set_collision_priority(get_rid(), p_priority); + } +} + +real_t CollisionObject3D::get_collision_priority() const { + return collision_priority; +} + void CollisionObject3D::set_disable_mode(DisableMode p_mode) { if (disable_mode == p_mode) { return; @@ -432,6 +443,8 @@ void CollisionObject3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &CollisionObject3D::get_collision_layer_value); ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &CollisionObject3D::set_collision_mask_value); ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &CollisionObject3D::get_collision_mask_value); + ClassDB::bind_method(D_METHOD("set_collision_priority", "priority"), &CollisionObject3D::set_collision_priority); + ClassDB::bind_method(D_METHOD("get_collision_priority"), &CollisionObject3D::get_collision_priority); ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &CollisionObject3D::set_disable_mode); ClassDB::bind_method(D_METHOD("get_disable_mode"), &CollisionObject3D::get_disable_mode); ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &CollisionObject3D::set_ray_pickable); @@ -466,6 +479,7 @@ void CollisionObject3D::_bind_methods() { ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_priority"), "set_collision_priority", "get_collision_priority"); ADD_GROUP("Input", "input_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input_ray_pickable"), "set_ray_pickable", "is_ray_pickable"); diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index 3ec3aa0fc1..3f0d070db4 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -47,6 +47,7 @@ public: private: uint32_t collision_layer = 1; uint32_t collision_mask = 1; + real_t collision_priority = 1.0; bool area = false; @@ -125,6 +126,9 @@ public: void set_collision_mask_value(int p_layer_number, bool p_value); bool get_collision_mask_value(int p_layer_number) const; + void set_collision_priority(real_t p_priority); + real_t get_collision_priority() const; + void set_disable_mode(DisableMode p_mode); DisableMode get_disable_mode() const; diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 1de85d57a3..4ae834cf7a 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -897,7 +897,7 @@ void Node3D::_validate_property(PropertyInfo &property) const { } } -bool Node3D::property_can_revert(const String &p_name) { +bool Node3D::_property_can_revert(const StringName &p_name) const { if (p_name == "basis") { return true; } else if (p_name == "scale") { @@ -912,47 +912,48 @@ bool Node3D::property_can_revert(const String &p_name) { return false; } -Variant Node3D::property_get_revert(const String &p_name) { - Variant r_ret; +bool Node3D::_property_get_revert(const StringName &p_name, Variant &r_property) const { bool valid = false; if (p_name == "basis") { Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { - r_ret = Transform3D(variant).get_basis(); + r_property = Transform3D(variant).get_basis(); } else { - r_ret = Basis(); + r_property = Basis(); } } else if (p_name == "scale") { Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { - r_ret = Transform3D(variant).get_basis().get_scale(); + r_property = Transform3D(variant).get_basis().get_scale(); } else { - return Vector3(1.0, 1.0, 1.0); + r_property = Vector3(1.0, 1.0, 1.0); } } else if (p_name == "quaternion") { Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { - r_ret = Quaternion(Transform3D(variant).get_basis().get_rotation_quaternion()); + r_property = Quaternion(Transform3D(variant).get_basis().get_rotation_quaternion()); } else { - return Quaternion(); + r_property = Quaternion(); } } else if (p_name == "rotation") { Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { - r_ret = Transform3D(variant).get_basis().get_euler_normalized(data.euler_rotation_order); + r_property = Transform3D(variant).get_basis().get_euler_normalized(data.euler_rotation_order); } else { - return Vector3(); + r_property = Vector3(); } } else if (p_name == "position") { Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); if (valid) { - r_ret = Transform3D(variant).get_origin(); + r_property = Transform3D(variant).get_origin(); } else { - return Vector3(); + r_property = Vector3(); } + } else { + return false; } - return r_ret; + return true; } void Node3D::_bind_methods() { @@ -1032,9 +1033,6 @@ void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("to_local", "global_point"), &Node3D::to_local); ClassDB::bind_method(D_METHOD("to_global", "local_point"), &Node3D::to_global); - ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &Node3D::property_can_revert); - ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &Node3D::property_get_revert); - BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED); BIND_CONSTANT(NOTIFICATION_ENTER_WORLD); BIND_CONSTANT(NOTIFICATION_EXIT_WORLD); diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index b1e129798d..3d1c59445b 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -157,8 +157,8 @@ protected: virtual void _validate_property(PropertyInfo &property) const override; - bool property_can_revert(const String &p_name); - Variant property_get_revert(const String &p_name); + bool _property_can_revert(const StringName &p_name) const; + bool _property_get_revert(const StringName &p_name, Variant &r_property) const; public: enum { diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index cbdef02826..7ecc073422 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -1127,7 +1127,7 @@ void RigidDynamicBody3D::_bind_methods() { void RigidDynamicBody3D::_validate_property(PropertyInfo &property) const { if (center_of_mass_mode != CENTER_OF_MASS_MODE_CUSTOM) { if (property.name == "center_of_mass") { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } PhysicsBody3D::_validate_property(property); @@ -2025,7 +2025,7 @@ void CharacterBody3D::_bind_methods() { void CharacterBody3D::_validate_property(PropertyInfo &property) const { if (motion_mode == MOTION_MODE_FLOATING) { if (property.name.begins_with("floor_") || property.name == "up_direction" || property.name == "slide_on_ceiling") { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } PhysicsBody3D::_validate_property(property); @@ -3417,6 +3417,7 @@ void PhysicalBone3D::_start_physics_simulation() { set_body_mode(PhysicsServer3D::BODY_MODE_DYNAMIC); PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); + PhysicsServer3D::get_singleton()->body_set_collision_priority(get_rid(), get_collision_priority()); PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback); set_as_top_level(true); _internal_simulate_physics = true; @@ -3430,10 +3431,12 @@ void PhysicalBone3D::_stop_physics_simulation() { set_body_mode(PhysicsServer3D::BODY_MODE_KINEMATIC); PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); + PhysicsServer3D::get_singleton()->body_set_collision_priority(get_rid(), get_collision_priority()); } else { set_body_mode(PhysicsServer3D::BODY_MODE_STATIC); PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), 0); PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), 0); + PhysicsServer3D::get_singleton()->body_set_collision_priority(get_rid(), 1.0); } if (_internal_simulate_physics) { PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), nullptr, nullptr); diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index 2db5ab2d4e..a45ef52452 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -88,6 +88,10 @@ Object *RayCast3D::get_collider() const { return ObjectDB::get_instance(against); } +RID RayCast3D::get_collider_rid() const { + return against_rid; +} + int RayCast3D::get_collider_shape() const { return against_shape; } @@ -224,12 +228,14 @@ void RayCast3D::_update_raycast_state() { if (dss->intersect_ray(ray_params, rr)) { collided = true; against = rr.collider_id; + against_rid = rr.rid; collision_point = rr.position; collision_normal = rr.normal; against_shape = rr.shape; } else { collided = false; against = ObjectID(); + against_rid = RID(); against_shape = 0; } } @@ -302,6 +308,7 @@ void RayCast3D::_bind_methods() { ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast3D::force_raycast_update); ClassDB::bind_method(D_METHOD("get_collider"), &RayCast3D::get_collider); + ClassDB::bind_method(D_METHOD("get_collider_rid"), &RayCast3D::get_collider_rid); ClassDB::bind_method(D_METHOD("get_collider_shape"), &RayCast3D::get_collider_shape); ClassDB::bind_method(D_METHOD("get_collision_point"), &RayCast3D::get_collision_point); ClassDB::bind_method(D_METHOD("get_collision_normal"), &RayCast3D::get_collision_normal); diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h index aa62f6927e..eb5c3ee90a 100644 --- a/scene/3d/ray_cast_3d.h +++ b/scene/3d/ray_cast_3d.h @@ -41,6 +41,7 @@ class RayCast3D : public Node3D { bool enabled = true; bool collided = false; ObjectID against; + RID against_rid; int against_shape = 0; Vector3 collision_point; Vector3 collision_normal; @@ -113,6 +114,7 @@ public: void force_raycast_update(); bool is_colliding() const; Object *get_collider() const; + RID get_collider_rid() const; int get_collider_shape() const; Vector3 get_collision_point() const; Vector3 get_collision_normal() const; diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index 0a9d6cbbeb..92fc91ee4e 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -179,9 +179,9 @@ AABB ReflectionProbe::get_aabb() const { } void ReflectionProbe::_validate_property(PropertyInfo &property) const { - if (property.name == "interior/ambient_color" || property.name == "interior/ambient_color_energy") { + if (property.name == "ambient_color" || property.name == "ambient_color_energy") { if (ambient_mode != AMBIENT_COLOR) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } VisualInstance3D::_validate_property(property); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 4c38fccc8b..e16435d5fb 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -762,6 +762,20 @@ Vector3 Skeleton3D::get_bone_pose_scale(int p_bone) const { return bones[p_bone].pose_scale; } +void Skeleton3D::reset_bone_pose(int p_bone) { + const int bone_size = bones.size(); + ERR_FAIL_INDEX(p_bone, bone_size); + set_bone_pose_position(p_bone, bones[p_bone].rest.origin); + set_bone_pose_rotation(p_bone, bones[p_bone].rest.basis.get_rotation_quaternion()); + set_bone_pose_scale(p_bone, bones[p_bone].rest.basis.get_scale()); +} + +void Skeleton3D::reset_bone_poses() { + for (int i = 0; i < bones.size(); i++) { + reset_bone_pose(i); + } +} + Transform3D Skeleton3D::get_bone_pose(int p_bone) const { const int bone_size = bones.size(); ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D()); @@ -1252,6 +1266,9 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bone_pose_rotation", "bone_idx"), &Skeleton3D::get_bone_pose_rotation); ClassDB::bind_method(D_METHOD("get_bone_pose_scale", "bone_idx"), &Skeleton3D::get_bone_pose_scale); + ClassDB::bind_method(D_METHOD("reset_bone_pose", "bone_idx"), &Skeleton3D::reset_bone_pose); + ClassDB::bind_method(D_METHOD("reset_bone_poses"), &Skeleton3D::reset_bone_poses); + ClassDB::bind_method(D_METHOD("is_bone_enabled", "bone_idx"), &Skeleton3D::is_bone_enabled); ClassDB::bind_method(D_METHOD("set_bone_enabled", "bone_idx", "enabled"), &Skeleton3D::set_bone_enabled, DEFVAL(true)); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 8b69410a39..6b3a952ee6 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -227,6 +227,9 @@ public: Quaternion get_bone_pose_rotation(int p_bone) const; Vector3 get_bone_pose_scale(int p_bone) const; + void reset_bone_pose(int p_bone); + void reset_bone_poses(); + void clear_bones_global_pose_override(); Transform3D get_bone_global_pose_override(int p_bone) const; void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent = false); diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index 15f050defb..c9eafc77e0 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -88,10 +88,10 @@ void SoftDynamicBodyRenderingServerHandler::set_normal(int p_vertex_id, const vo memcpy(&n, p_vector3, sizeof(Vector3)); n *= Vector3(0.5, 0.5, 0.5); n += Vector3(0.5, 0.5, 0.5); + Vector2 res = n.octahedron_encode(); uint32_t value = 0; - value |= CLAMP(int(n.x * 1023.0), 0, 1023); - value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10; - value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20; + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; memcpy(&write_buffer[p_vertex_id * stride + offset_normal], &value, sizeof(uint32_t)); } diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index ef2b9e1ce5..42ed502e18 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -562,23 +562,21 @@ void Sprite3D::_draw() { { Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); + Vector2 res = n.octahedron_encode(); uint32_t value = 0; - value |= CLAMP(int(n.x * 1023.0), 0, 1023); - value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10; - value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20; + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; v_normal = value; } uint32_t v_tangent; { Plane t = tangent; + Vector2 res = t.normal.octahedron_tangent_encode(t.d); uint32_t value = 0; - value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023); - value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10; - value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20; - if (t.d > 0) { - value |= 3UL << 30; - } + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; + v_tangent = value; } @@ -929,23 +927,20 @@ void AnimatedSprite3D::_draw() { { Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); + Vector2 res = n.octahedron_encode(); uint32_t value = 0; - value |= CLAMP(int(n.x * 1023.0), 0, 1023); - value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10; - value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20; + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; v_normal = value; } uint32_t v_tangent; { Plane t = tangent; + Vector2 res = t.normal.octahedron_tangent_encode(t.d); uint32_t value = 0; - value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023); - value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10; - value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20; - if (t.d > 0) { - value |= 3UL << 30; - } + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; v_tangent = value; } diff --git a/scene/3d/velocity_tracker_3d.h b/scene/3d/velocity_tracker_3d.h index 6b27cdffc2..d3b92ab766 100644 --- a/scene/3d/velocity_tracker_3d.h +++ b/scene/3d/velocity_tracker_3d.h @@ -34,8 +34,6 @@ #include "scene/3d/node_3d.h" class VelocityTracker3D : public RefCounted { - GDCLASS(VelocityTracker3D, RefCounted); - struct PositionHistory { uint64_t frame = 0; Vector3 position; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 09ec086564..1a7bf4c302 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -323,10 +323,8 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov #endif // _3D_DISABLED - { - if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed))) { - child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed).bind(child), CONNECT_ONESHOT); - } + if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed))) { + child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed).bind(child), CONNECT_ONESHOT); } TrackNodeCacheKey key; @@ -375,7 +373,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov node_cache->init_rot = rest.basis.get_rotation_quaternion(); node_cache->init_scale = rest.basis.get_scale(); } else { - // no property, just use spatialnode + // Not a skeleton, the node can be accessed with the node_3d member. node_cache->skeleton = nullptr; } } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 6d0380c898..fbdaee4b22 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -565,6 +565,26 @@ void Control::_validate_property(PropertyInfo &property) const { } } +bool Control::_property_can_revert(const StringName &p_name) const { + if (p_name == "layout_mode" || p_name == "anchors_preset") { + return true; + } + + return false; +} + +bool Control::_property_get_revert(const StringName &p_name, Variant &r_property) const { + if (p_name == "layout_mode") { + r_property = _get_default_layout_mode(); + return true; + } else if (p_name == "anchors_preset") { + r_property = LayoutPreset::PRESET_TOP_LEFT; + return true; + } + + return false; +} + // Global relations. bool Control::is_top_level_control() const { @@ -794,24 +814,15 @@ void Control::_compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t ( void Control::_set_layout_mode(LayoutMode p_mode) { bool list_changed = false; - if (p_mode == LayoutMode::LAYOUT_MODE_POSITION || p_mode == LayoutMode::LAYOUT_MODE_ANCHORS) { - if ((int)get_meta("_edit_layout_mode", p_mode) != (int)p_mode) { - list_changed = true; - } - - set_meta("_edit_layout_mode", (int)p_mode); + if (data.stored_layout_mode != p_mode) { + list_changed = true; + data.stored_layout_mode = p_mode; + } - if (p_mode == LayoutMode::LAYOUT_MODE_POSITION) { - remove_meta("_edit_layout_mode"); - remove_meta("_edit_use_custom_anchors"); - set_anchors_and_offsets_preset(LayoutPreset::PRESET_TOP_LEFT, LayoutPresetMode::PRESET_MODE_KEEP_SIZE); - set_grow_direction_preset(LayoutPreset::PRESET_TOP_LEFT); - } - } else { - if (has_meta("_edit_layout_mode")) { - remove_meta("_edit_layout_mode"); - list_changed = true; - } + if (data.stored_layout_mode == LayoutMode::LAYOUT_MODE_POSITION) { + data.stored_use_custom_anchors = false; + set_anchors_and_offsets_preset(LayoutPreset::PRESET_TOP_LEFT, LayoutPresetMode::PRESET_MODE_KEEP_SIZE); + set_grow_direction_preset(LayoutPreset::PRESET_TOP_LEFT); } if (list_changed) { @@ -832,33 +843,43 @@ Control::LayoutMode Control::_get_layout_mode() const { if (_get_anchors_layout_preset() != (int)LayoutPreset::PRESET_TOP_LEFT) { return LayoutMode::LAYOUT_MODE_ANCHORS; } - // Otherwise check what was saved. - if (has_meta("_edit_layout_mode")) { - return (LayoutMode)(int)get_meta("_edit_layout_mode"); + + // Otherwise fallback on what's stored. + return data.stored_layout_mode; +} + +Control::LayoutMode Control::_get_default_layout_mode() const { + Node *parent_node = get_parent_control(); + // In these modes the property is read-only. + if (!parent_node) { + return LayoutMode::LAYOUT_MODE_UNCONTROLLED; + } else if (Object::cast_to<Container>(parent_node)) { + return LayoutMode::LAYOUT_MODE_CONTAINER; } - // Or fallback on default. + + // Otherwise fallback on the position mode. return LayoutMode::LAYOUT_MODE_POSITION; } void Control::_set_anchors_layout_preset(int p_preset) { bool list_changed = false; - if (get_meta("_edit_layout_mode", LayoutMode::LAYOUT_MODE_ANCHORS).operator int() != LayoutMode::LAYOUT_MODE_ANCHORS) { + if (data.stored_layout_mode != LayoutMode::LAYOUT_MODE_ANCHORS) { list_changed = true; - set_meta("_edit_layout_mode", LayoutMode::LAYOUT_MODE_ANCHORS); + data.stored_layout_mode = LayoutMode::LAYOUT_MODE_ANCHORS; } if (p_preset == -1) { - if (!get_meta("_edit_use_custom_anchors", false)) { - set_meta("_edit_use_custom_anchors", true); + if (!data.stored_use_custom_anchors) { + data.stored_use_custom_anchors = true; notify_property_list_changed(); } return; // Keep settings as is. } - if (get_meta("_edit_use_custom_anchors", true)) { + if (data.stored_use_custom_anchors) { list_changed = true; - remove_meta("_edit_use_custom_anchors"); + data.stored_use_custom_anchors = false; } LayoutPreset preset = (LayoutPreset)p_preset; @@ -899,7 +920,7 @@ void Control::_set_anchors_layout_preset(int p_preset) { int Control::_get_anchors_layout_preset() const { // If the custom preset was selected by user, use it. - if ((bool)get_meta("_edit_use_custom_anchors", false)) { + if (data.stored_use_custom_anchors) { return -1; } @@ -3391,7 +3412,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_contents"), "set_clip_contents", "is_clipping_contents"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "custom_minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode"); ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION); const String anchors_presets_options = "Custom:-1,PresetFullRect:15," @@ -3399,7 +3420,7 @@ void Control::_bind_methods() { "PresetCenterLeft:4,PresetCenterTop:5,PresetCenterRight:6,PresetCenterBottom:7,PresetCenter:8," "PresetLeftWide:9,PresetTopWide:10,PresetRightWide:11,PresetBottomWide:12,PresetVCenterWide:13,PresetHCenterWide:14"; - ADD_PROPERTY(PropertyInfo(Variant::INT, "anchors_preset", PROPERTY_HINT_ENUM, anchors_presets_options, PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_anchors_layout_preset", "_get_anchors_layout_preset"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "anchors_preset", PROPERTY_HINT_ENUM, anchors_presets_options, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_anchors_layout_preset", "_get_anchors_layout_preset"); ADD_PROPERTY_DEFAULT("anchors_preset", -1); ADD_SUBGROUP_INDENT("Anchor Points", "anchor_", 1); diff --git a/scene/gui/control.h b/scene/gui/control.h index db19d09b11..aa06189a9e 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -170,6 +170,9 @@ private: // Positioning and sizing. + LayoutMode stored_layout_mode = LayoutMode::LAYOUT_MODE_POSITION; + bool stored_use_custom_anchors = false; + real_t offset[4] = { 0.0, 0.0, 0.0, 0.0 }; real_t anchor[4] = { ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN }; FocusMode focus_mode = FOCUS_NONE; @@ -275,6 +278,7 @@ private: void _set_layout_mode(LayoutMode p_mode); LayoutMode _get_layout_mode() const; + LayoutMode _get_default_layout_mode() const; void _set_anchors_layout_preset(int p_preset); int _get_anchors_layout_preset() const; @@ -319,6 +323,9 @@ protected: void _get_property_list(List<PropertyInfo> *p_list) const; virtual void _validate_property(PropertyInfo &property) const override; + bool _property_can_revert(const StringName &p_name) const; + bool _property_get_revert(const StringName &p_name, Variant &r_property) const; + // Internationalization. virtual Array structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index d0a25972f8..e3e9499705 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -932,11 +932,7 @@ void ItemList::_notification(int p_what) { scroll_bar->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -bg->get_margin(SIDE_BOTTOM)); Size2 size = get_size(); - int width = size.width - bg->get_minimum_size().width; - if (scroll_bar->is_visible()) { - width -= mw; - } draw_style_box(bg, Rect2(Point2(), size)); @@ -1095,6 +1091,10 @@ void ItemList::_notification(int p_what) { shape_changed = false; } + if (scroll_bar->is_visible()) { + width -= mw; + } + //ensure_selected_visible needs to be checked before we draw the list. if (ensure_selected_visible && current >= 0 && current < items.size()) { Rect2 r = items[current].rect_cache; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index e7f48beb00..4ef1e48a32 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -764,13 +764,17 @@ int Label::get_visible_characters() const { void Label::set_percent_visible(float p_percent) { if (percent_visible != p_percent) { - if (p_percent < 0 || p_percent >= 1) { + if (percent_visible >= 1.0) { visible_chars = -1; - percent_visible = 1; + percent_visible = 1.0; + } else if (percent_visible < 0.0) { + visible_chars = 0; + percent_visible = 0.0; } else { visible_chars = get_total_character_count() * p_percent; percent_visible = p_percent; } + if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { dirty = true; } diff --git a/scene/gui/menu_bar.cpp b/scene/gui/menu_bar.cpp index 8f03ddeeab..f450222130 100644 --- a/scene/gui/menu_bar.cpp +++ b/scene/gui/menu_bar.cpp @@ -749,7 +749,6 @@ Size2 MenuBar::get_minimum_size() const { } Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - int hsep = get_theme_constant(SNAME("h_separation")); Vector2 size; for (int i = 0; i < menu_cache.size(); i++) { @@ -758,7 +757,10 @@ Size2 MenuBar::get_minimum_size() const { } Size2 sz = menu_cache[i].text_buf->get_size() + style->get_minimum_size(); size.y = MAX(size.y, sz.y); - size.x += sz.x + hsep; + size.x += sz.x; + } + if (menu_cache.size() > 1) { + size.x += get_theme_constant(SNAME("h_separation")) * (menu_cache.size() - 1); } return size; } @@ -859,6 +861,7 @@ void MenuBar::get_translatable_strings(List<String> *p_strings) const { } MenuBar::MenuBar() { + set_process_shortcut_input(true); } MenuBar::~MenuBar() { diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 984f20ee58..ab466089a7 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -4912,15 +4912,19 @@ void RichTextLabel::set_percent_visible(float p_percent) { if (percent_visible != p_percent) { _stop_thread(); - if (p_percent < 0 || p_percent >= 1) { + if (percent_visible >= 1.0) { visible_characters = -1; - percent_visible = 1; + percent_visible = 1.0; + } else if (percent_visible < 0.0) { + visible_characters = 0; + percent_visible = 0.0; } else { visible_characters = get_total_character_count() * p_percent; percent_visible = p_percent; } + if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { - main->first_invalid_line.store(0); //invalidate ALL + main->first_invalid_line.store(0); // Invalidate ALL. _validate_line_caches(); } update(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index f2c3e565b7..762d9f2a28 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -158,8 +158,8 @@ #include "scene/resources/immediate_mesh.h" #include "scene/resources/label_settings.h" #include "scene/resources/material.h" -#include "scene/resources/mesh.h" #include "scene/resources/mesh_data_tool.h" +#include "scene/resources/multimesh.h" #include "scene/resources/navigation_mesh.h" #include "scene/resources/packed_scene.h" #include "scene/resources/particles_material.h" @@ -260,7 +260,7 @@ #include "scene/resources/fog_material.h" #include "scene/resources/importer_mesh.h" #include "scene/resources/mesh_library.h" -#endif +#endif // _3D_DISABLED static Ref<ResourceFormatSaverText> resource_saver_text; static Ref<ResourceFormatLoaderText> resource_loader_text; @@ -575,7 +575,7 @@ void register_scene_types() { GDREGISTER_CLASS(NavigationObstacle3D); OS::get_singleton()->yield(); // may take time to init -#endif +#endif // _3D_DISABLED /* REGISTER SHADER */ @@ -765,10 +765,6 @@ void register_scene_types() { SceneTree::add_idle_callback(ParticlesMaterial::flush_changes); ParticlesMaterial::init_shaders(); - GDREGISTER_CLASS(ProceduralSkyMaterial); - GDREGISTER_CLASS(PanoramaSkyMaterial); - GDREGISTER_CLASS(PhysicalSkyMaterial); - GDREGISTER_VIRTUAL_CLASS(Mesh); GDREGISTER_CLASS(ArrayMesh); GDREGISTER_CLASS(PlaceholderMesh); @@ -796,6 +792,9 @@ void register_scene_types() { GDREGISTER_CLASS(StandardMaterial3D); GDREGISTER_CLASS(ORMMaterial3D); GDREGISTER_CLASS(PlaceholderMaterial); + GDREGISTER_CLASS(ProceduralSkyMaterial); + GDREGISTER_CLASS(PanoramaSkyMaterial); + GDREGISTER_CLASS(PhysicalSkyMaterial); SceneTree::add_idle_callback(BaseMaterial3D::flush_changes); BaseMaterial3D::init_shaders(); @@ -824,9 +823,7 @@ void register_scene_types() { ClassDB::register_class<SkeletonModification3DStackHolder>(); OS::get_singleton()->yield(); // may take time to init - - GDREGISTER_CLASS(VelocityTracker3D); -#endif +#endif // _3D_DISABLED GDREGISTER_CLASS(PhysicsMaterial); GDREGISTER_CLASS(World3D); @@ -845,7 +842,6 @@ void register_scene_types() { GDREGISTER_CLASS(CurveXYZTexture); GDREGISTER_CLASS(GradientTexture1D); GDREGISTER_CLASS(GradientTexture2D); - GDREGISTER_CLASS(ProxyTexture); GDREGISTER_CLASS(AnimatedTexture); GDREGISTER_CLASS(CameraTexture); GDREGISTER_VIRTUAL_CLASS(TextureLayered); @@ -1054,7 +1050,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("Spatial", "Node3D"); ClassDB::add_compatibility_class("SpatialGizmo", "Node3DGizmo"); ClassDB::add_compatibility_class("SpatialMaterial", "StandardMaterial3D"); - ClassDB::add_compatibility_class("SpatialVelocityTracker", "VelocityTracker3D"); ClassDB::add_compatibility_class("SphereShape", "SphereShape3D"); ClassDB::add_compatibility_class("SpotLight", "SpotLight3D"); ClassDB::add_compatibility_class("SpringArm", "SpringArm3D"); @@ -1207,11 +1202,10 @@ void unregister_scene_types() { // StandardMaterial3D is not initialised when 3D is disabled, so it shouldn't be cleaned up either #ifndef _3D_DISABLED BaseMaterial3D::finish_shaders(); -#endif // _3D_DISABLED - PhysicalSkyMaterial::cleanup_shader(); PanoramaSkyMaterial::cleanup_shader(); ProceduralSkyMaterial::cleanup_shader(); +#endif // _3D_DISABLED ParticlesMaterial::finish_shaders(); CanvasItemMaterial::finish_shaders(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 69b30b72b0..289d026ddb 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -967,7 +967,6 @@ int Animation::find_track(const NodePath &p_path, const TrackType p_type) const void Animation::track_set_interpolation_type(int p_track, InterpolationType p_interp) { ERR_FAIL_INDEX(p_track, tracks.size()); - ERR_FAIL_INDEX(p_interp, 3); tracks[p_track]->interpolation = p_interp; emit_changed(); } @@ -2283,6 +2282,8 @@ int Animation::_find(const Vector<K> &p_keys, double p_time, bool p_backward) co return middle; } +// Linear interpolation for anytype. + Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, real_t p_c) const { return p_a.lerp(p_b, p_c); } @@ -2301,6 +2302,8 @@ real_t Animation::_interpolate(const real_t &p_a, const real_t &p_b, real_t p_c) return p_a * (1.0 - p_c) + p_b * p_c; } +// Cubic interpolation for anytype. + Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c) const { return p_a.cubic_interpolate(p_b, p_pre_a, p_post_b, p_c); } @@ -2389,6 +2392,96 @@ real_t Animation::_cubic_interpolate(const real_t &p_pre_a, const real_t &p_a, c return _interpolate(p_a, p_b, p_c); } +// Cubic interpolation in time for anytype. + +Vector3 Animation::_cubic_interpolate_in_time(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const { + return p_a.cubic_interpolate_in_time(p_b, p_pre_a, p_post_b, p_c, p_b_t, p_pre_a_t, p_post_b_t); +} + +Quaternion Animation::_cubic_interpolate_in_time(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const { + return p_a.spherical_cubic_interpolate_in_time(p_b, p_pre_a, p_post_b, p_c, p_b_t, p_pre_a_t, p_post_b_t); +} + +Variant Animation::_cubic_interpolate_in_time(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const { + Variant::Type type_a = p_a.get_type(); + Variant::Type type_b = p_b.get_type(); + Variant::Type type_pa = p_pre_a.get_type(); + Variant::Type type_pb = p_post_b.get_type(); + + //make int and real play along + + uint32_t vformat = 1 << type_a; + vformat |= 1 << type_b; + vformat |= 1 << type_pa; + vformat |= 1 << type_pb; + + if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) { + //mix of real and int + real_t a = p_a; + real_t b = p_b; + real_t pa = p_pre_a; + real_t pb = p_post_b; + + return Math::cubic_interpolate_in_time(a, b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t); + } else if ((vformat & (vformat - 1))) { + return p_a; //can't interpolate, mix of types + } + + switch (type_a) { + case Variant::VECTOR2: { + Vector2 a = p_a; + Vector2 b = p_b; + Vector2 pa = p_pre_a; + Vector2 pb = p_post_b; + + return a.cubic_interpolate_in_time(b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t); + } + case Variant::RECT2: { + Rect2 a = p_a; + Rect2 b = p_b; + Rect2 pa = p_pre_a; + Rect2 pb = p_post_b; + + return Rect2( + a.position.cubic_interpolate_in_time(b.position, pa.position, pb.position, p_c, p_b_t, p_pre_a_t, p_post_b_t), + a.size.cubic_interpolate_in_time(b.size, pa.size, pb.size, p_c, p_b_t, p_pre_a_t, p_post_b_t)); + } + case Variant::VECTOR3: { + Vector3 a = p_a; + Vector3 b = p_b; + Vector3 pa = p_pre_a; + Vector3 pb = p_post_b; + + return a.cubic_interpolate_in_time(b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t); + } + case Variant::QUATERNION: { + Quaternion a = p_a; + Quaternion b = p_b; + Quaternion pa = p_pre_a; + Quaternion pb = p_post_b; + + return a.spherical_cubic_interpolate_in_time(b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t); + } + case Variant::AABB: { + AABB a = p_a; + AABB b = p_b; + AABB pa = p_pre_a; + AABB pb = p_post_b; + + return AABB( + a.position.cubic_interpolate_in_time(b.position, pa.position, pb.position, p_c, p_b_t, p_pre_a_t, p_post_b_t), + a.size.cubic_interpolate_in_time(b.size, pa.size, pb.size, p_c, p_b_t, p_pre_a_t, p_post_b_t)); + } + default: { + return _interpolate(p_a, p_b, p_c); + } + } +} + +real_t Animation::_cubic_interpolate_in_time(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const { + return _interpolate(p_a, p_b, p_c); +} + template <class T> T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok, bool p_backward) const { int len = _find(p_keys, length) + 1; // try to find last key (there may be more past the end) @@ -2568,26 +2661,65 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol case INTERPOLATION_LINEAR: { return _interpolate(p_keys[idx].value, p_keys[next].value, c); } break; - case INTERPOLATION_CUBIC: { - int pre = idx - 1; - if (pre < 0) { - if (loop_mode == LOOP_LINEAR && p_loop_wrap) { - pre = len - 1; - } else { - pre = 0; + case INTERPOLATION_CUBIC: + case INTERPOLATION_CUBIC_IN_TIME: { + int pre = 0; + int post = 0; + if (!p_backward) { + pre = idx - 1; + if (pre < 0) { + if (loop_mode == LOOP_LINEAR && p_loop_wrap) { + pre = len - 1; + } else { + pre = 0; + } } - } - int post = next + 1; - if (post >= len) { - if (loop_mode == LOOP_LINEAR && p_loop_wrap) { - post = 0; - } else { - post = next; + post = next + 1; + if (post >= len) { + if (loop_mode == LOOP_LINEAR && p_loop_wrap) { + post = 0; + } else { + post = next; + } + } + } else { + pre = idx + 1; + if (pre >= len) { + if (loop_mode == LOOP_LINEAR && p_loop_wrap) { + pre = 0; + } else { + pre = idx; + } + } + post = next - 1; + if (post < 0) { + if (loop_mode == LOOP_LINEAR && p_loop_wrap) { + post = len - 1; + } else { + post = 0; + } } } - return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c); + if (loop_mode == LOOP_LINEAR && p_loop_wrap) { + if (p_interp == INTERPOLATION_CUBIC) { + return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c); + } + return _cubic_interpolate_in_time( + p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c, + pre > idx ? -length + p_keys[pre].time - p_keys[idx].time : p_keys[pre].time - p_keys[idx].time, + next < idx ? length + p_keys[next].time - p_keys[idx].time : p_keys[next].time - p_keys[idx].time, + next < idx || post <= idx ? length + p_keys[post].time - p_keys[idx].time : p_keys[post].time - p_keys[idx].time); + } + if (p_interp == INTERPOLATION_CUBIC) { + return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c); + } + return _cubic_interpolate_in_time( + p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c, + p_keys[pre].time - p_keys[idx].time, + p_keys[next].time - p_keys[idx].time, + p_keys[post].time - p_keys[idx].time); } break; default: return p_keys[idx].value; @@ -3839,6 +3971,7 @@ void Animation::_bind_methods() { BIND_ENUM_CONSTANT(INTERPOLATION_NEAREST); BIND_ENUM_CONSTANT(INTERPOLATION_LINEAR); BIND_ENUM_CONSTANT(INTERPOLATION_CUBIC); + BIND_ENUM_CONSTANT(INTERPOLATION_CUBIC_IN_TIME); BIND_ENUM_CONSTANT(UPDATE_CONTINUOUS); BIND_ENUM_CONSTANT(UPDATE_DISCRETE); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index bf9f786a0d..b141b4e15f 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -56,7 +56,8 @@ public: enum InterpolationType { INTERPOLATION_NEAREST, INTERPOLATION_LINEAR, - INTERPOLATION_CUBIC + INTERPOLATION_CUBIC, + INTERPOLATION_CUBIC_IN_TIME, }; enum UpdateMode { @@ -231,6 +232,11 @@ private: _FORCE_INLINE_ Variant _cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c) const; _FORCE_INLINE_ real_t _cubic_interpolate(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c) const; + _FORCE_INLINE_ Vector3 _cubic_interpolate_in_time(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; + _FORCE_INLINE_ Quaternion _cubic_interpolate_in_time(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; + _FORCE_INLINE_ Variant _cubic_interpolate_in_time(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; + _FORCE_INLINE_ real_t _cubic_interpolate_in_time(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; + template <class T> _FORCE_INLINE_ T _interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok, bool p_backward = false) const; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index d361b34da8..4af287a915 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1038,39 +1038,39 @@ void Environment::_update_adjustment() { // Private methods, constructor and destructor void Environment::_validate_property(PropertyInfo &property) const { - if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") { + if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light_sky_contribution") { if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } if (property.name == "fog_aerial_perspective") { if (bg_mode != BG_SKY) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } if (property.name == "tonemap_white" && tone_mapper == TONE_MAPPER_LINEAR) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } if (property.name == "glow_intensity" && glow_blend_mode == GLOW_BLEND_MODE_MIX) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } if (property.name == "glow_mix" && glow_blend_mode != GLOW_BLEND_MODE_MIX) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } if (property.name == "background_color") { if (bg_mode != BG_COLOR && ambient_source != AMBIENT_SOURCE_COLOR) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } if (property.name == "background_canvas_max_layer") { if (bg_mode != BG_CANVAS) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; } } @@ -1108,7 +1108,7 @@ void Environment::_validate_property(PropertyInfo &property) const { String enabled = prefix + "enabled"; if (property.name.begins_with(prefix) && property.name != enabled && !bool(get(enabled))) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; return; } @@ -1121,7 +1121,7 @@ void Environment::_validate_property(PropertyInfo &property) const { String prefix = String(*prefixes); if (property.name.begins_with(prefix)) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR; return; } diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 88bc01fb25..5d887dae17 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -297,7 +297,7 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { } } -bool ShaderMaterial::property_can_revert(const String &p_name) { +bool ShaderMaterial::_property_can_revert(const StringName &p_name) const { if (shader.is_valid()) { StringName pr = shader->remap_uniform(p_name); if (pr) { @@ -310,15 +310,15 @@ bool ShaderMaterial::property_can_revert(const String &p_name) { return false; } -Variant ShaderMaterial::property_get_revert(const String &p_name) { - Variant r_ret; +bool ShaderMaterial::_property_get_revert(const StringName &p_name, Variant &r_property) const { if (shader.is_valid()) { StringName pr = shader->remap_uniform(p_name); if (pr) { - r_ret = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); + r_property = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); + return true; } } - return r_ret; + return false; } void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { @@ -386,8 +386,6 @@ void ShaderMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader); ClassDB::bind_method(D_METHOD("set_shader_uniform", "param", "value"), &ShaderMaterial::set_shader_uniform); ClassDB::bind_method(D_METHOD("get_shader_uniform", "param"), &ShaderMaterial::get_shader_uniform); - ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ShaderMaterial::property_can_revert); - ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ShaderMaterial::property_get_revert); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader"), "set_shader", "get_shader"); } diff --git a/scene/resources/material.h b/scene/resources/material.h index ca5b17dd07..6049671582 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -99,8 +99,8 @@ protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; - bool property_can_revert(const String &p_name); - Variant property_get_revert(const String &p_name); + bool _property_can_revert(const StringName &p_name) const; + bool _property_get_revert(const StringName &p_name, Variant &r_property) const; static void _bind_methods(); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index ec9db89794..1f75d4a323 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -32,11 +32,10 @@ #include "core/math/convex_hull.h" #include "core/templates/pair.h" +#include "scene/resources/surface_tool.h" + #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" -#include "surface_tool.h" - -#include <stdlib.h> Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr; @@ -201,7 +200,9 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { continue; } int len = (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? surface_get_array_index_len(i) : surface_get_array_len(i); - if ((primitive == PRIMITIVE_TRIANGLES && (len == 0 || (len % 3) != 0)) || (primitive == PRIMITIVE_TRIANGLE_STRIP && len < 3)) { + if ((primitive == PRIMITIVE_TRIANGLES && (len == 0 || (len % 3) != 0)) || + (primitive == PRIMITIVE_TRIANGLE_STRIP && len < 3) || + (surface_get_format(i) & ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY)) { // Error was already shown, just skip (including zero). continue; } @@ -211,6 +212,7 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { int vc = surface_get_array_len(i); Vector<Vector3> vertices = a[ARRAY_VERTEX]; + ERR_FAIL_COND_V(vertices.is_empty(), Ref<TriangleMesh>()); const Vector3 *vr = vertices.ptr(); int32_t from_index = widx / 3; @@ -863,27 +865,6 @@ static Mesh::PrimitiveType _old_primitives[7] = { }; #endif // DISABLE_DEPRECATED -// Convert Octahedron-mapped normalized vector back to Cartesian -// Assumes normalized format (elements of v within range [-1, 1]) -Vector3 _oct_to_norm(const Vector2 v) { - Vector3 res(v.x, v.y, 1 - (Math::absf(v.x) + Math::absf(v.y))); - float t = MAX(-res.z, 0.0f); - res.x += t * -SIGN(res.x); - res.y += t * -SIGN(res.y); - return res.normalized(); -} - -// Convert Octahedron-mapped normalized tangent vector back to Cartesian -// out_sign provides the direction for the original cartesian tangent -// Assumes normalized format (elements of v within range [-1, 1]) -Vector3 _oct_to_tangent(const Vector2 v, float *out_sign) { - Vector2 v_decompressed = v; - v_decompressed.y = Math::absf(v_decompressed.y) * 2 - 1; - Vector3 res = _oct_to_norm(v_decompressed); - *out_sign = SIGN(v[1]); - return res; -} - void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_format, uint32_t p_new_format, uint32_t p_elements, Vector<uint8_t> &vertex_data, Vector<uint8_t> &attribute_data, Vector<uint8_t> &skin_data) { uint32_t dst_vertex_stride; uint32_t dst_attribute_stride; @@ -954,127 +935,93 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma if ((p_old_format & OLD_ARRAY_COMPRESS_NORMAL) && (p_old_format & OLD_ARRAY_FORMAT_TANGENT) && (p_old_format & OLD_ARRAY_COMPRESS_TANGENT)) { for (uint32_t i = 0; i < p_elements; i++) { const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; - const Vector2 src_vec(src[0] / 127.0f, src[1] / 127.0f); - - const Vector3 res = _oct_to_norm(src_vec) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - *dst = 0; - *dst |= CLAMP(int(res.x * 1023.0f), 0, 1023); - *dst |= CLAMP(int(res.y * 1023.0f), 0, 1023) << 10; - *dst |= CLAMP(int(res.z * 1023.0f), 0, 1023) << 20; + int16_t *dst = (int16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + + dst[0] = (int16_t)CLAMP(src[0] / 127.0f * 32767, -32768, 32767); + dst[1] = (int16_t)CLAMP(src[1] / 127.0f * 32767, -32768, 32767); } - src_offset += sizeof(int8_t) * 2; + src_offset += sizeof(int16_t) * 2; } else { for (uint32_t i = 0; i < p_elements; i++) { const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; - const Vector2 src_vec(src[0] / 32767.0f, src[1] / 32767.0f); - - const Vector3 res = _oct_to_norm(src_vec) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - *dst = 0; - *dst |= CLAMP(int(res.x * 1023.0f), 0, 1023); - *dst |= CLAMP(int(res.y * 1023.0f), 0, 1023) << 10; - *dst |= CLAMP(int(res.z * 1023.0f), 0, 1023) << 20; + int16_t *dst = (int16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + + dst[0] = src[0]; + dst[1] = src[1]; } src_offset += sizeof(int16_t) * 2; } } else { // No Octahedral compression if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) { - const float multiplier = 1.f / 127.f * 1023.0f; - for (uint32_t i = 0; i < p_elements; i++) { const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + const Vector3 original_normal(src[0], src[1], src[2]); + Vector2 res = original_normal.octahedron_encode(); - *dst = 0; - *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); - *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(uint32_t); + src_offset += sizeof(uint16_t) * 2; } else { for (uint32_t i = 0; i < p_elements; i++) { const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + const Vector3 original_normal(src[0], src[1], src[2]); + Vector2 res = original_normal.octahedron_encode(); - *dst = 0; - *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); - *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(float) * 3; + src_offset += sizeof(uint16_t) * 2; } } } break; case OLD_ARRAY_TANGENT: { if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { - if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { // int8 + if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { // int8 SNORM -> uint16 UNORM for (uint32_t i = 0; i < p_elements; i++) { const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - const Vector2 src_vec(src[0] / 127.0f, src[1] / 127.0f); - float out_sign; - const Vector3 res = _oct_to_tangent(src_vec, &out_sign) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - - *dst = 0; - *dst |= CLAMP(int(res.x * 1023.0), 0, 1023); - *dst |= CLAMP(int(res.y * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(res.z * 1023.0), 0, 1023) << 20; - if (out_sign > 0) { - *dst |= 3 << 30; - } + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + + dst[0] = (uint16_t)CLAMP((src[0] / 127.0f * .5f + .5f) * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP((src[1] / 127.0f * .5f + .5f) * 65535, 0, 65535); } - src_offset += sizeof(int8_t) * 2; - } else { // int16 + src_offset += sizeof(uint16_t) * 2; + } else { // int16 SNORM -> uint16 UNORM for (uint32_t i = 0; i < p_elements; i++) { const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - const Vector2 src_vec(src[0] / 32767.0f, src[1] / 32767.0f); - float out_sign; - Vector3 res = _oct_to_tangent(src_vec, &out_sign) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - - *dst = 0; - *dst |= CLAMP(int(res.x * 1023.0), 0, 1023); - *dst |= CLAMP(int(res.y * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(res.z * 1023.0), 0, 1023) << 20; - if (out_sign > 0) { - *dst |= 3 << 30; - } + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + + dst[0] = (uint16_t)CLAMP((src[0] / 32767.0f * .5f + .5f) * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP((src[1] / 32767.0f * .5f + .5f) * 65535, 0, 65535); } - src_offset += sizeof(int16_t) * 2; + src_offset += sizeof(uint16_t) * 2; } } else { // No Octahedral compression if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { - const float multiplier = 1.f / 127.f * 1023.0f; - for (uint32_t i = 0; i < p_elements; i++) { const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - - *dst = 0; - *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); - *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; - if (src[3] > 0) { - *dst |= 3 << 30; - } + const Vector3 original_tangent(src[0], src[1], src[2]); + Vector2 res = original_tangent.octahedron_tangent_encode(src[3]); + + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(uint32_t); + src_offset += sizeof(uint16_t) * 2; } else { for (uint32_t i = 0; i < p_elements; i++) { const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - - *dst = 0; - *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); - *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; - if (src[3] > 0) { - *dst |= 3 << 30; - } + const Vector3 original_tangent(src[0], src[1], src[2]); + Vector2 res = original_tangent.octahedron_tangent_encode(src[3]); + + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(float) * 4; + src_offset += sizeof(uint16_t) * 2; } } } break; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 142373ce7f..491a383416 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -144,6 +144,7 @@ public: ARRAY_FLAG_USE_DYNAMIC_UPDATE = RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE, ARRAY_FLAG_USE_8_BONE_WEIGHTS = RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS, + ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY = RS::ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY, }; virtual int get_surface_count() const; @@ -168,9 +169,6 @@ public: void generate_debug_mesh_lines(Vector<Vector3> &r_lines); void generate_debug_mesh_indices(Vector<Vector3> &r_points); - Ref<Shape3D> create_trimesh_shape() const; - Ref<Shape3D> create_convex_shape(bool p_clean = true, bool p_simplify = false) const; - Ref<Mesh> create_outline(float p_margin) const; void set_lightmap_size_hint(const Size2i &p_size); @@ -213,6 +211,8 @@ public: static ConvexDecompositionFunc convex_decomposition_function; Vector<Ref<Shape3D>> convex_decompose(const ConvexDecompositionSettings &p_settings) const; + Ref<Shape3D> create_convex_shape(bool p_clean = true, bool p_simplify = false) const; + Ref<Shape3D> create_trimesh_shape() const; virtual int get_builtin_bind_pose_count() const; virtual Transform3D get_builtin_bind_pose(int p_index) const; diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 4105bd6960..79acb41c4e 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -33,8 +33,8 @@ #include "core/io/resource.h" #include "core/templates/rb_map.h" -#include "mesh.h" #include "scene/3d/navigation_region_3d.h" +#include "scene/resources/mesh.h" #include "shape_3d.h" class MeshLibrary : public Resource { diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index ac5493efdc..e8b78a06f1 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -614,8 +614,10 @@ void NavigationMesh::_bind_methods() { ADD_GROUP("Geometry", "geometry_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_parsed_geometry_type", PROPERTY_HINT_ENUM, "Mesh Instances,Static Colliders,Both"), "set_parsed_geometry_type", "get_parsed_geometry_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_PROPERTY_DEFAULT("geometry_collision_mask", 0xFFFFFFFF); ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_source_geometry_mode", PROPERTY_HINT_ENUM, "NavMesh Children, Group With Children, Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry_source_group_name"), "set_source_group_name", "get_source_group_name"); + ADD_PROPERTY_DEFAULT("geometry_source_group_name", StringName("navmesh")); ADD_GROUP("Cells", "cell_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater,suffix:m"), "set_cell_size", "get_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_height", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater,suffix:m"), "set_cell_height", "get_cell_height"); @@ -659,14 +661,14 @@ void NavigationMesh::_bind_methods() { } void NavigationMesh::_validate_property(PropertyInfo &property) const { - if (property.name == "geometry/collision_mask") { + if (property.name == "geometry_collision_mask") { if (parsed_geometry_type == PARSED_GEOMETRY_MESH_INSTANCES) { property.usage = PROPERTY_USAGE_NONE; return; } } - if (property.name == "geometry/source_group_name") { + if (property.name == "geometry_source_group_name") { if (source_geometry_mode == SOURCE_GEOMETRY_NAVMESH_CHILDREN) { property.usage = PROPERTY_USAGE_NONE; return; diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 79d8962d24..d5d6b9eb08 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -33,8 +33,6 @@ #include "scene/resources/mesh.h" -class Mesh; - class NavigationMesh : public Resource { GDCLASS(NavigationMesh, Resource); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 05ed9238b8..6fe86447f6 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -35,8 +35,8 @@ #include "core/io/marshalls.h" #include "core/math/geometry_2d.h" #include "core/os/os.h" -#include "mesh.h" #include "scene/resources/bit_map.h" +#include "scene/resources/mesh.h" #include "servers/camera/camera_feed.h" int Texture2D::get_width() const { int ret; @@ -2537,13 +2537,6 @@ void GradientTexture2D::_bind_methods() { ////////////////////////////////////// -void ProxyTexture::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_base", "base"), &ProxyTexture::set_base); - ClassDB::bind_method(D_METHOD("get_base"), &ProxyTexture::get_base); - - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base", "get_base"); -} - void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(p_texture == this); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 36b193c5d4..7c5624bd09 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -883,8 +883,6 @@ VARIANT_ENUM_CAST(GradientTexture2D::Fill); VARIANT_ENUM_CAST(GradientTexture2D::Repeat); class ProxyTexture : public Texture2D { - GDCLASS(ProxyTexture, Texture2D); - private: mutable RID proxy_ph; mutable RID proxy; |