summaryrefslogtreecommitdiff
path: root/scene/3d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/area_3d.cpp2
-rw-r--r--scene/3d/audio_stream_player_3d.cpp4
-rw-r--r--scene/3d/camera_3d.cpp6
-rw-r--r--scene/3d/collision_object_3d.cpp146
-rw-r--r--scene/3d/collision_object_3d.h23
-rw-r--r--scene/3d/cpu_particles_3d.cpp8
-rw-r--r--scene/3d/gpu_particles_3d.cpp6
-rw-r--r--scene/3d/immediate_geometry_3d.cpp157
-rw-r--r--scene/3d/immediate_geometry_3d.h72
-rw-r--r--scene/3d/light_3d.cpp10
-rw-r--r--scene/3d/node_3d.cpp15
-rw-r--r--scene/3d/node_3d.h2
-rw-r--r--scene/3d/physics_body_3d.cpp208
-rw-r--r--scene/3d/physics_body_3d.h8
-rw-r--r--scene/3d/reflection_probe.cpp2
-rw-r--r--scene/3d/soft_body_3d.cpp68
-rw-r--r--scene/3d/soft_body_3d.h12
-rw-r--r--scene/3d/sprite_3d.cpp306
-rw-r--r--scene/3d/sprite_3d.h49
-rw-r--r--scene/3d/vehicle_body_3d.cpp43
20 files changed, 641 insertions, 506 deletions
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 44708cddff..cd64a813dd 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -601,7 +601,7 @@ void Area3D::_bind_methods() {
ADD_GROUP("Physics Overrides", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine"), "set_space_override_mode", "get_space_override_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point"), "set_gravity_is_point", "is_gravity_a_point");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_distance_scale", "get_gravity_distance_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_vec"), "set_gravity_vector", "get_gravity_vector");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-32,32,0.001,or_lesser,or_greater"), "set_gravity", "get_gravity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index e05f37c73c..ba559b4ecb 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -967,13 +967,13 @@ void AudioStreamPlayer3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,4096,1,or_greater"), "set_max_distance", "get_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,4096,1,or_greater,exp"), "set_max_distance", "get_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask");
ADD_GROUP("Emission Angle", "emission_angle");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emission_angle_enabled"), "set_emission_angle_enabled", "is_emission_angle_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1"), "set_emission_angle", "get_emission_angle");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1,degrees"), "set_emission_angle", "get_emission_angle");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db");
ADD_GROUP("Attenuation Filter", "attenuation_filter_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz");
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 32006d5e7f..1ed8c0b4eb 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -513,11 +513,11 @@ void Camera3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking");
ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov", "get_fov");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset"), "set_frustum_offset", "get_frustum_offset");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_EXP_RANGE, "0.001,10,0.001,or_greater"), "set_near", "get_near");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_EXP_RANGE, "0.01,4000,0.01,or_greater"), "set_far", "get_far");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater,exp"), "set_near", "get_near");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_RANGE, "0.01,4000,0.01,or_greater,exp"), "set_far", "get_far");
BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE);
BIND_ENUM_CONSTANT(PROJECTION_ORTHOGONAL);
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index a04667e53b..40e3f7c764 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -32,7 +32,6 @@
#include "core/config/engine.h"
#include "scene/scene_string_names.h"
-#include "servers/physics_server_3d.h"
void CollisionObject3D::_notification(int p_what) {
switch (p_what) {
@@ -59,15 +58,22 @@ void CollisionObject3D::_notification(int p_what) {
PhysicsServer3D::get_singleton()->body_set_state(rid, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
}
- RID space = get_world_3d()->get_space();
- if (area) {
- PhysicsServer3D::get_singleton()->area_set_space(rid, space);
- } else {
- PhysicsServer3D::get_singleton()->body_set_space(rid, space);
+ bool disabled = !is_enabled();
+
+ if (disabled && (disable_mode != DISABLE_MODE_REMOVE)) {
+ _apply_disabled();
+ }
+
+ if (!disabled || (disable_mode != DISABLE_MODE_REMOVE)) {
+ RID space = get_world_3d()->get_space();
+ if (area) {
+ PhysicsServer3D::get_singleton()->area_set_space(rid, space);
+ } else {
+ PhysicsServer3D::get_singleton()->body_set_space(rid, space);
+ }
}
_update_pickable();
- //get space
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -78,19 +84,34 @@ void CollisionObject3D::_notification(int p_what) {
}
_on_transform_changed();
-
} break;
+
case NOTIFICATION_VISIBILITY_CHANGED: {
_update_pickable();
-
} break;
+
case NOTIFICATION_EXIT_WORLD: {
- if (area) {
- PhysicsServer3D::get_singleton()->area_set_space(rid, RID());
- } else {
- PhysicsServer3D::get_singleton()->body_set_space(rid, RID());
+ bool disabled = !is_enabled();
+
+ if (!disabled || (disable_mode != DISABLE_MODE_REMOVE)) {
+ if (area) {
+ PhysicsServer3D::get_singleton()->area_set_space(rid, RID());
+ } else {
+ PhysicsServer3D::get_singleton()->body_set_space(rid, RID());
+ }
+ }
+
+ if (disabled && (disable_mode != DISABLE_MODE_REMOVE)) {
+ _apply_enabled();
}
+ } break;
+ case NOTIFICATION_DISABLED: {
+ _apply_disabled();
+ } break;
+
+ case NOTIFICATION_ENABLED: {
+ _apply_enabled();
} break;
}
}
@@ -153,6 +174,79 @@ bool CollisionObject3D::get_collision_mask_bit(int p_bit) const {
return get_collision_mask() & (1 << p_bit);
}
+void CollisionObject3D::set_disable_mode(DisableMode p_mode) {
+ if (disable_mode == p_mode) {
+ return;
+ }
+
+ bool disabled = is_inside_tree() && !is_enabled();
+
+ if (disabled) {
+ // Cancel previous disable mode.
+ _apply_enabled();
+ }
+
+ disable_mode = p_mode;
+
+ if (disabled) {
+ // Apply new disable mode.
+ _apply_disabled();
+ }
+}
+
+CollisionObject3D::DisableMode CollisionObject3D::get_disable_mode() const {
+ return disable_mode;
+}
+
+void CollisionObject3D::_apply_disabled() {
+ switch (disable_mode) {
+ case DISABLE_MODE_REMOVE: {
+ if (is_inside_tree()) {
+ if (area) {
+ PhysicsServer3D::get_singleton()->area_set_space(rid, RID());
+ } else {
+ PhysicsServer3D::get_singleton()->body_set_space(rid, RID());
+ }
+ }
+ } break;
+
+ case DISABLE_MODE_MAKE_STATIC: {
+ if (!area && (body_mode != PhysicsServer3D::BODY_MODE_STATIC)) {
+ PhysicsServer3D::get_singleton()->body_set_mode(rid, PhysicsServer3D::BODY_MODE_STATIC);
+ }
+ } break;
+
+ case DISABLE_MODE_KEEP_ACTIVE: {
+ // Nothing to do.
+ } break;
+ }
+}
+
+void CollisionObject3D::_apply_enabled() {
+ switch (disable_mode) {
+ case DISABLE_MODE_REMOVE: {
+ if (is_inside_tree()) {
+ RID space = get_world_3d()->get_space();
+ if (area) {
+ PhysicsServer3D::get_singleton()->area_set_space(rid, space);
+ } else {
+ PhysicsServer3D::get_singleton()->body_set_space(rid, space);
+ }
+ }
+ } break;
+
+ case DISABLE_MODE_MAKE_STATIC: {
+ if (!area && (body_mode != PhysicsServer3D::BODY_MODE_STATIC)) {
+ PhysicsServer3D::get_singleton()->body_set_mode(rid, body_mode);
+ }
+ } break;
+
+ case DISABLE_MODE_KEEP_ACTIVE: {
+ // Nothing to do.
+ } break;
+ }
+}
+
void CollisionObject3D::_input_event(Node *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
@@ -174,6 +268,22 @@ void CollisionObject3D::_mouse_exit() {
emit_signal(SceneStringNames::get_singleton()->mouse_exited);
}
+void CollisionObject3D::set_body_mode(PhysicsServer3D::BodyMode p_mode) {
+ ERR_FAIL_COND(area);
+
+ if (body_mode == p_mode) {
+ return;
+ }
+
+ body_mode = p_mode;
+
+ if (is_inside_tree() && !is_enabled() && (disable_mode == DISABLE_MODE_MAKE_STATIC)) {
+ return;
+ }
+
+ PhysicsServer3D::get_singleton()->body_set_mode(rid, p_mode);
+}
+
void CollisionObject3D::_update_pickable() {
if (!is_inside_tree()) {
return;
@@ -305,6 +415,8 @@ void CollisionObject3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &CollisionObject3D::get_collision_layer_bit);
ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &CollisionObject3D::set_collision_mask_bit);
ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &CollisionObject3D::get_collision_mask_bit);
+ 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);
ClassDB::bind_method(D_METHOD("is_ray_pickable"), &CollisionObject3D::is_ray_pickable);
ClassDB::bind_method(D_METHOD("set_capture_input_on_drag", "enable"), &CollisionObject3D::set_capture_input_on_drag);
@@ -332,6 +444,8 @@ void CollisionObject3D::_bind_methods() {
ADD_SIGNAL(MethodInfo("mouse_entered"));
ADD_SIGNAL(MethodInfo("mouse_exited"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "disable_mode", PROPERTY_HINT_ENUM, "Remove,MakeStatic,KeepActive"), "set_disable_mode", "get_disable_mode");
+
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");
@@ -339,6 +453,10 @@ void CollisionObject3D::_bind_methods() {
ADD_GROUP("Input", "input_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input_ray_pickable"), "set_ray_pickable", "is_ray_pickable");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input_capture_on_drag"), "set_capture_input_on_drag", "get_capture_input_on_drag");
+
+ BIND_ENUM_CONSTANT(DISABLE_MODE_REMOVE);
+ BIND_ENUM_CONSTANT(DISABLE_MODE_MAKE_STATIC);
+ BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE);
}
uint32_t CollisionObject3D::create_shape_owner(Object *p_owner) {
@@ -540,8 +658,8 @@ CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) {
PhysicsServer3D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id());
} else {
PhysicsServer3D::get_singleton()->body_attach_object_instance_id(rid, get_instance_id());
+ PhysicsServer3D::get_singleton()->body_set_mode(rid, body_mode);
}
- //set_transform_notify(true);
}
void CollisionObject3D::set_capture_input_on_drag(bool p_capture) {
diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h
index 50a9b4fcd0..a3a890db75 100644
--- a/scene/3d/collision_object_3d.h
+++ b/scene/3d/collision_object_3d.h
@@ -33,10 +33,19 @@
#include "scene/3d/node_3d.h"
#include "scene/resources/shape_3d.h"
+#include "servers/physics_server_3d.h"
class CollisionObject3D : public Node3D {
GDCLASS(CollisionObject3D, Node3D);
+public:
+ enum DisableMode {
+ DISABLE_MODE_REMOVE,
+ DISABLE_MODE_MAKE_STATIC,
+ DISABLE_MODE_KEEP_ACTIVE,
+ };
+
+private:
uint32_t collision_layer = 1;
uint32_t collision_mask = 1;
@@ -44,6 +53,10 @@ class CollisionObject3D : public Node3D {
RID rid;
+ DisableMode disable_mode = DISABLE_MODE_REMOVE;
+
+ PhysicsServer3D::BodyMode body_mode = PhysicsServer3D::BODY_MODE_STATIC;
+
struct ShapeData {
Object *owner = nullptr;
Transform3D xform;
@@ -76,6 +89,9 @@ class CollisionObject3D : public Node3D {
void _update_debug_shapes();
void _clear_debug_shapes();
+ void _apply_disabled();
+ void _apply_enabled();
+
protected:
CollisionObject3D(RID p_rid, bool p_area);
@@ -89,6 +105,8 @@ protected:
virtual void _mouse_enter();
virtual void _mouse_exit();
+ void set_body_mode(PhysicsServer3D::BodyMode p_mode);
+
public:
void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
@@ -102,6 +120,9 @@ public:
void set_collision_mask_bit(int p_bit, bool p_value);
bool get_collision_mask_bit(int p_bit) const;
+ void set_disable_mode(DisableMode p_mode);
+ DisableMode get_disable_mode() const;
+
uint32_t create_shape_owner(Object *p_owner);
void remove_shape_owner(uint32_t owner);
void get_shape_owners(List<uint32_t> *r_owners);
@@ -138,4 +159,6 @@ public:
~CollisionObject3D();
};
+VARIANT_ENUM_CAST(CollisionObject3D::DisableMode);
+
#endif // COLLISION_OBJECT__H
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 2301fef651..54d94638d5 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -1273,11 +1273,11 @@ void CPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("restart"), &CPUParticles3D::restart);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount");
ADD_GROUP("Time", "");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater,exp"), "set_lifetime", "get_lifetime");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01,exp"), "set_pre_process_time", "get_pre_process_time");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio");
@@ -1390,7 +1390,7 @@ void CPUParticles3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING);
ADD_GROUP("Angle", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param", "get_param", PARAM_ANGLE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE);
ADD_GROUP("Scale", "");
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index d7f4bfeb4e..1d3d5f13cd 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -562,12 +562,12 @@ void GPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_transform_align"), &GPUParticles3D::get_transform_align);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "sub_emitter", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GPUParticles3D"), "set_sub_emitter", "get_sub_emitter");
ADD_GROUP("Time", "");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater,exp"), "set_lifetime", "get_lifetime");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01,exp"), "set_pre_process_time", "get_pre_process_time");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio");
diff --git a/scene/3d/immediate_geometry_3d.cpp b/scene/3d/immediate_geometry_3d.cpp
deleted file mode 100644
index d64babaa9d..0000000000
--- a/scene/3d/immediate_geometry_3d.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*************************************************************************/
-/* immediate_geometry_3d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "immediate_geometry_3d.h"
-
-void ImmediateGeometry3D::begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture) {
- RS::get_singleton()->immediate_begin(im, (RS::PrimitiveType)p_primitive, p_texture.is_valid() ? p_texture->get_rid() : RID());
- if (p_texture.is_valid()) {
- cached_textures.push_back(p_texture);
- }
-}
-
-void ImmediateGeometry3D::set_normal(const Vector3 &p_normal) {
- RS::get_singleton()->immediate_normal(im, p_normal);
-}
-
-void ImmediateGeometry3D::set_tangent(const Plane &p_tangent) {
- RS::get_singleton()->immediate_tangent(im, p_tangent);
-}
-
-void ImmediateGeometry3D::set_color(const Color &p_color) {
- RS::get_singleton()->immediate_color(im, p_color);
-}
-
-void ImmediateGeometry3D::set_uv(const Vector2 &p_uv) {
- RS::get_singleton()->immediate_uv(im, p_uv);
-}
-
-void ImmediateGeometry3D::set_uv2(const Vector2 &p_uv2) {
- RS::get_singleton()->immediate_uv2(im, p_uv2);
-}
-
-void ImmediateGeometry3D::add_vertex(const Vector3 &p_vertex) {
- RS::get_singleton()->immediate_vertex(im, p_vertex);
- if (empty) {
- aabb.position = p_vertex;
- aabb.size = Vector3();
- empty = false;
- } else {
- aabb.expand_to(p_vertex);
- }
-}
-
-void ImmediateGeometry3D::end() {
- RS::get_singleton()->immediate_end(im);
-}
-
-void ImmediateGeometry3D::clear() {
- RS::get_singleton()->immediate_clear(im);
- empty = true;
- cached_textures.clear();
-}
-
-AABB ImmediateGeometry3D::get_aabb() const {
- return aabb;
-}
-
-Vector<Face3> ImmediateGeometry3D::get_faces(uint32_t p_usage_flags) const {
- return Vector<Face3>();
-}
-
-void ImmediateGeometry3D::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) {
- const double lat_step = Math_TAU / p_lats;
- const double lon_step = Math_TAU / p_lons;
-
- for (int i = 1; i <= p_lats; i++) {
- double lat0 = lat_step * (i - 1) - Math_TAU / 4;
- double z0 = Math::sin(lat0);
- double zr0 = Math::cos(lat0);
-
- double lat1 = lat_step * i - Math_TAU / 4;
- double z1 = Math::sin(lat1);
- double zr1 = Math::cos(lat1);
-
- for (int j = p_lons; j >= 1; j--) {
- double lng0 = lon_step * (j - 1);
- double x0 = Math::cos(lng0);
- double y0 = Math::sin(lng0);
-
- double lng1 = lon_step * j;
- double x1 = Math::cos(lng1);
- double y1 = Math::sin(lng1);
-
- Vector3 v[4] = {
- Vector3(x1 * zr0, z0, y1 * zr0),
- Vector3(x1 * zr1, z1, y1 * zr1),
- Vector3(x0 * zr1, z1, y0 * zr1),
- Vector3(x0 * zr0, z0, y0 * zr0)
- };
-
-#define ADD_POINT(m_idx) \
- if (p_add_uv) { \
- set_uv(Vector2(Math::atan2(v[m_idx].x, v[m_idx].z) / Math_PI * 0.5 + 0.5, v[m_idx].y * 0.5 + 0.5)); \
- set_tangent(Plane(Vector3(-v[m_idx].z, v[m_idx].y, v[m_idx].x), 1)); \
- } \
- set_normal(v[m_idx]); \
- add_vertex(v[m_idx] * p_radius);
-
- ADD_POINT(0);
- ADD_POINT(1);
- ADD_POINT(2);
-
- ADD_POINT(2);
- ADD_POINT(3);
- ADD_POINT(0);
- }
- }
-}
-
-void ImmediateGeometry3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("begin", "primitive", "texture"), &ImmediateGeometry3D::begin, DEFVAL(Ref<Texture2D>()));
- ClassDB::bind_method(D_METHOD("set_normal", "normal"), &ImmediateGeometry3D::set_normal);
- ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &ImmediateGeometry3D::set_tangent);
- ClassDB::bind_method(D_METHOD("set_color", "color"), &ImmediateGeometry3D::set_color);
- ClassDB::bind_method(D_METHOD("set_uv", "uv"), &ImmediateGeometry3D::set_uv);
- ClassDB::bind_method(D_METHOD("set_uv2", "uv"), &ImmediateGeometry3D::set_uv2);
- ClassDB::bind_method(D_METHOD("add_vertex", "position"), &ImmediateGeometry3D::add_vertex);
- ClassDB::bind_method(D_METHOD("add_sphere", "lats", "lons", "radius", "add_uv"), &ImmediateGeometry3D::add_sphere, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("end"), &ImmediateGeometry3D::end);
- ClassDB::bind_method(D_METHOD("clear"), &ImmediateGeometry3D::clear);
-}
-
-ImmediateGeometry3D::ImmediateGeometry3D() {
- im = RenderingServer::get_singleton()->immediate_create();
- set_base(im);
-}
-
-ImmediateGeometry3D::~ImmediateGeometry3D() {
- RenderingServer::get_singleton()->free(im);
-}
diff --git a/scene/3d/immediate_geometry_3d.h b/scene/3d/immediate_geometry_3d.h
deleted file mode 100644
index ee4938d9f7..0000000000
--- a/scene/3d/immediate_geometry_3d.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*************************************************************************/
-/* immediate_geometry_3d.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef IMMEDIATE_GEOMETRY_3D_H
-#define IMMEDIATE_GEOMETRY_3D_H
-
-#include "scene/3d/visual_instance_3d.h"
-#include "scene/resources/mesh.h"
-
-class ImmediateGeometry3D : public GeometryInstance3D {
- GDCLASS(ImmediateGeometry3D, GeometryInstance3D);
-
- RID im;
- //a list of textures drawn need to be kept, to avoid references
- // in RenderingServer from becoming invalid if the texture is no longer used
- List<Ref<Texture2D>> cached_textures;
- bool empty = true;
- AABB aabb;
-
-protected:
- static void _bind_methods();
-
-public:
- void begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture = Ref<Texture2D>());
- void set_normal(const Vector3 &p_normal);
- void set_tangent(const Plane &p_tangent);
- void set_color(const Color &p_color);
- void set_uv(const Vector2 &p_uv);
- void set_uv2(const Vector2 &p_uv2);
-
- void add_vertex(const Vector3 &p_vertex);
-
- void end();
- void clear();
-
- void add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv = true);
-
- virtual AABB get_aabb() const override;
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
-
- ImmediateGeometry3D();
- ~ImmediateGeometry3D();
-};
-
-#endif // IMMEDIATE_GEOMETRY_H
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 37881c3332..de4862326a 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -423,8 +423,8 @@ void DirectionalLight3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_fade_start", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_FADE_START);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_EXP_RANGE, "0,8192,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_pancake_size", PROPERTY_HINT_EXP_RANGE, "0,1024,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_PANCAKE_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_RANGE, "0,8192,0.1,or_greater,exp"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_pancake_size", PROPERTY_HINT_RANGE, "0,1024,0.1,or_greater,exp"), "set_param", "get_param", PARAM_SHADOW_PANCAKE_SIZE);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_in_sky_only"), "set_sky_only", "is_sky_only");
@@ -472,7 +472,7 @@ void OmniLight3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &OmniLight3D::get_shadow_mode);
ADD_GROUP("Omni", "omni_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "omni_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "omni_range", PROPERTY_HINT_RANGE, "0,4096,0.1,or_greater,exp"), "set_param", "get_param", PARAM_RANGE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "omni_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION);
ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_mode", PROPERTY_HINT_ENUM, "Dual Paraboloid,Cube"), "set_shadow_mode", "get_shadow_mode");
@@ -504,8 +504,8 @@ TypedArray<String> SpotLight3D::get_configuration_warnings() const {
void SpotLight3D::_bind_methods() {
ADD_GROUP("Spot", "spot_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_range", PROPERTY_HINT_RANGE, "0,4096,0.1,or_greater,exp"), "set_param", "get_param", PARAM_RANGE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_angle", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_param", "get_param", PARAM_SPOT_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_angle", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), "set_param", "get_param", PARAM_SPOT_ANGLE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_angle_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_SPOT_ATTENUATION);
}
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index f78a2ff14e..d6c6ec75b4 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -328,10 +328,6 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) {
}
}
-void Node3D::set_rotation_degrees(const Vector3 &p_euler_deg) {
- set_rotation(p_euler_deg * (Math_PI / 180.0));
-}
-
void Node3D::set_scale(const Vector3 &p_scale) {
if (data.dirty & DIRTY_VECTORS) {
data.rotation = data.local_transform.basis.get_rotation();
@@ -361,10 +357,6 @@ Vector3 Node3D::get_rotation() const {
return data.rotation;
}
-Vector3 Node3D::get_rotation_degrees() const {
- return get_rotation() * (180.0 / Math_PI);
-}
-
Vector3 Node3D::get_scale() const {
if (data.dirty & DIRTY_VECTORS) {
data.scale = data.local_transform.basis.get_scale();
@@ -749,8 +741,6 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_position"), &Node3D::get_position);
ClassDB::bind_method(D_METHOD("set_rotation", "euler"), &Node3D::set_rotation);
ClassDB::bind_method(D_METHOD("get_rotation"), &Node3D::get_rotation);
- ClassDB::bind_method(D_METHOD("set_rotation_degrees", "euler_degrees"), &Node3D::set_rotation_degrees);
- ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &Node3D::get_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_scale", "scale"), &Node3D::set_scale);
ClassDB::bind_method(D_METHOD("get_scale"), &Node3D::get_scale);
ClassDB::bind_method(D_METHOD("set_global_transform", "global"), &Node3D::set_global_transform);
@@ -814,9 +804,8 @@ void Node3D::_bind_methods() {
//ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM3D,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ;
ADD_GROUP("Transform", "");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_position", "get_position");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_rotation", "get_rotation");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0,or_greater,or_lesser,noslider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level");
ADD_GROUP("Matrix", "");
diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h
index c7e36cf2ec..fe6324c796 100644
--- a/scene/3d/node_3d.h
+++ b/scene/3d/node_3d.h
@@ -131,12 +131,10 @@ public:
void set_position(const Vector3 &p_position);
void set_rotation(const Vector3 &p_euler_rad);
- void set_rotation_degrees(const Vector3 &p_euler_deg);
void set_scale(const Vector3 &p_scale);
Vector3 get_position() const;
Vector3 get_rotation() const;
- Vector3 get_rotation_degrees() const;
Vector3 get_scale() const;
void set_transform(const Transform3D &p_transform);
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 8e10a37afb..e7482d35e7 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -65,7 +65,7 @@ void PhysicsBody3D::_bind_methods() {
PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) :
CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode);
+ set_body_mode(p_mode);
}
PhysicsBody3D::~PhysicsBody3D() {
@@ -118,10 +118,43 @@ Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_i
return Ref<KinematicCollision3D>();
}
-bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only) {
+bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding) {
Transform3D gt = get_global_transform();
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes);
+ // Restore direction of motion to be along original motion,
+ // in order to avoid sliding due to recovery,
+ // but only if collision depth is low enough to avoid tunneling.
+ real_t motion_length = p_motion.length();
+ if (motion_length > CMP_EPSILON) {
+ real_t precision = CMP_EPSILON;
+
+ if (colliding && p_cancel_sliding) {
+ // Can't just use margin as a threshold because collision depth is calculated on unsafe motion,
+ // so even in normal resting cases the depth can be a bit more than the margin.
+ precision += motion_length * (r_result.collision_unsafe_fraction - r_result.collision_safe_fraction);
+
+ if (r_result.collision_depth > (real_t)p_margin + precision) {
+ p_cancel_sliding = false;
+ }
+ }
+
+ if (p_cancel_sliding) {
+ // Check depth of recovery.
+ Vector3 motion_normal = p_motion / motion_length;
+ real_t dot = r_result.motion.dot(motion_normal);
+ Vector3 recovery = r_result.motion - motion_normal * dot;
+ real_t recovery_length = recovery.length();
+ // Fixes cases where canceling slide causes the motion to go too deep into the ground,
+ // Becauses we're only taking rest information into account and not general recovery.
+ if (recovery_length < (real_t)p_margin + precision) {
+ // Apply adjustment to motion.
+ r_result.motion = motion_normal * dot;
+ r_result.remainder = p_motion - r_result.motion;
+ }
+ }
+ }
+
for (int i = 0; i < 3; i++) {
if (locked_axis & (1 << i)) {
r_result.motion[i] = 0;
@@ -200,9 +233,9 @@ void StaticBody3D::set_kinematic_motion_enabled(bool p_enabled) {
kinematic_motion = p_enabled;
if (kinematic_motion) {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_KINEMATIC);
+ set_body_mode(PhysicsServer3D::BODY_MODE_KINEMATIC);
} else {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC);
+ set_body_mode(PhysicsServer3D::BODY_MODE_STATIC);
}
_update_kinematic_motion();
@@ -249,35 +282,37 @@ Vector3 StaticBody3D::get_angular_velocity() const {
}
void StaticBody3D::_notification(int p_what) {
- if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
+ switch (p_what) {
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
#ifdef TOOLS_ENABLED
- if (Engine::get_singleton()->is_editor_hint()) {
- return;
- }
+ if (Engine::get_singleton()->is_editor_hint()) {
+ return;
+ }
#endif
- ERR_FAIL_COND(!kinematic_motion);
+ ERR_FAIL_COND(!kinematic_motion);
- real_t delta_time = get_physics_process_delta_time();
+ real_t delta_time = get_physics_process_delta_time();
- Transform3D new_transform = get_global_transform();
- new_transform.origin += constant_linear_velocity * delta_time;
+ Transform3D new_transform = get_global_transform();
+ new_transform.origin += constant_linear_velocity * delta_time;
- real_t ang_vel = constant_angular_velocity.length();
- if (!Math::is_zero_approx(ang_vel)) {
- Vector3 ang_vel_axis = constant_angular_velocity / ang_vel;
- Basis rot(ang_vel_axis, ang_vel * delta_time);
- new_transform.basis = rot * new_transform.basis;
- new_transform.orthonormalize();
- }
+ real_t ang_vel = constant_angular_velocity.length();
+ if (!Math::is_zero_approx(ang_vel)) {
+ Vector3 ang_vel_axis = constant_angular_velocity / ang_vel;
+ Basis rot(ang_vel_axis, ang_vel * delta_time);
+ new_transform.basis = rot * new_transform.basis;
+ new_transform.orthonormalize();
+ }
- PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_TRANSFORM, new_transform);
+ PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_TRANSFORM, new_transform);
- // Propagate transform change to node.
- set_ignore_transform_notification(true);
- set_global_transform(new_transform);
- set_ignore_transform_notification(false);
- _on_transform_changed();
+ // Propagate transform change to node.
+ set_ignore_transform_notification(true);
+ set_global_transform(new_transform);
+ set_ignore_transform_notification(false);
+ _on_transform_changed();
+ } break;
}
}
@@ -565,18 +600,19 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
void RigidBody3D::_notification(int p_what) {
#ifdef TOOLS_ENABLED
- if (p_what == NOTIFICATION_ENTER_TREE) {
- if (Engine::get_singleton()->is_editor_hint()) {
- set_notify_local_transform(true); //used for warnings and only in editor
- }
- }
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ set_notify_local_transform(true); //used for warnings and only in editor
+ }
+ } break;
- if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
- if (Engine::get_singleton()->is_editor_hint()) {
- update_configuration_warnings();
- }
+ case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ update_configuration_warnings();
+ }
+ } break;
}
-
#endif
}
@@ -584,18 +620,16 @@ void RigidBody3D::set_mode(Mode p_mode) {
mode = p_mode;
switch (p_mode) {
case MODE_DYNAMIC: {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC);
+ set_body_mode(PhysicsServer3D::BODY_MODE_DYNAMIC);
} break;
case MODE_STATIC: {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC);
-
+ set_body_mode(PhysicsServer3D::BODY_MODE_STATIC);
} break;
case MODE_DYNAMIC_LOCKED: {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC_LOCKED);
-
+ set_body_mode(PhysicsServer3D::BODY_MODE_DYNAMIC_LOCKED);
} break;
case MODE_KINEMATIC: {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_KINEMATIC);
+ set_body_mode(PhysicsServer3D::BODY_MODE_KINEMATIC);
} break;
}
update_configuration_warnings();
@@ -902,7 +936,7 @@ void RigidBody3D::_bind_methods() {
BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState3D")));
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Dynamic,Static,DynamicLocked,Kinematic"), "set_mode", "get_mode");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_RANGE, "0.01,65535,0.01,exp"), "set_mass", "get_mass");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator");
@@ -978,15 +1012,16 @@ void CharacterBody3D::move_and_slide() {
floor_normal = Vector3();
floor_velocity = Vector3();
- int slide_count = max_slides;
- while (slide_count) {
+ // No sliding on first attempt to keep motion stable when possible.
+ bool sliding_enabled = false;
+ for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer3D::MotionResult result;
bool found_collision = false;
for (int i = 0; i < 2; ++i) {
bool collided;
if (i == 0) { //collide
- collided = move_and_collide(motion, infinite_inertia, result, margin);
+ collided = move_and_collide(motion, infinite_inertia, result, margin, true, false, !sliding_enabled);
if (!collided) {
motion = Vector3(); //clear because no collision happened and motion completed
}
@@ -1002,7 +1037,6 @@ void CharacterBody3D::move_and_slide() {
found_collision = true;
motion_results.push_back(result);
- motion = result.remainder;
if (up_direction == Vector3()) {
//all is a wall
@@ -1016,7 +1050,7 @@ void CharacterBody3D::move_and_slide() {
floor_velocity = result.collider_velocity;
if (stop_on_slope) {
- if ((body_velocity_normal + up_direction).length() < 0.01 && result.motion.length() < 1) {
+ if ((body_velocity_normal + up_direction).length() < 0.01) {
Transform3D gt = get_global_transform();
gt.origin -= result.motion.slide(up_direction);
set_global_transform(gt);
@@ -1031,22 +1065,26 @@ void CharacterBody3D::move_and_slide() {
}
}
- motion = motion.slide(result.collision_normal);
- linear_velocity = linear_velocity.slide(result.collision_normal);
+ if (sliding_enabled || !on_floor) {
+ motion = result.remainder.slide(result.collision_normal);
+ linear_velocity = linear_velocity.slide(result.collision_normal);
- for (int j = 0; j < 3; j++) {
- if (locked_axis & (1 << j)) {
- linear_velocity[j] = 0.0;
+ for (int j = 0; j < 3; j++) {
+ if (locked_axis & (1 << j)) {
+ linear_velocity[j] = 0.0;
+ }
}
+ } else {
+ motion = result.remainder;
}
}
+
+ sliding_enabled = true;
}
if (!found_collision || motion == Vector3()) {
break;
}
-
- --slide_count;
}
if (!was_on_floor || snap == Vector3()) {
@@ -1208,14 +1246,6 @@ void CharacterBody3D::set_floor_max_angle(real_t p_radians) {
floor_max_angle = p_radians;
}
-real_t CharacterBody3D::get_floor_max_angle_degrees() const {
- return Math::rad2deg(floor_max_angle);
-}
-
-void CharacterBody3D::set_floor_max_angle_degrees(real_t p_degrees) {
- floor_max_angle = Math::deg2rad(p_degrees);
-}
-
const Vector3 &CharacterBody3D::get_snap() const {
return snap;
}
@@ -1233,14 +1263,16 @@ void CharacterBody3D::set_up_direction(const Vector3 &p_up_direction) {
}
void CharacterBody3D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- // Reset move_and_slide() data.
- on_floor = false;
- on_floor_body = RID();
- on_ceiling = false;
- on_wall = false;
- motion_results.clear();
- floor_velocity = Vector3();
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ // Reset move_and_slide() data.
+ on_floor = false;
+ on_floor_body = RID();
+ on_ceiling = false;
+ on_wall = false;
+ motion_results.clear();
+ floor_velocity = Vector3();
+ } break;
}
}
@@ -1260,8 +1292,6 @@ void CharacterBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody3D::set_max_slides);
ClassDB::bind_method(D_METHOD("get_floor_max_angle"), &CharacterBody3D::get_floor_max_angle);
ClassDB::bind_method(D_METHOD("set_floor_max_angle", "radians"), &CharacterBody3D::set_floor_max_angle);
- ClassDB::bind_method(D_METHOD("get_floor_max_angle_degrees"), &CharacterBody3D::get_floor_max_angle_degrees);
- ClassDB::bind_method(D_METHOD("set_floor_max_angle_degrees", "degrees"), &CharacterBody3D::set_floor_max_angle_degrees);
ClassDB::bind_method(D_METHOD("get_snap"), &CharacterBody3D::get_snap);
ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CharacterBody3D::set_snap);
ClassDB::bind_method(D_METHOD("get_up_direction"), &CharacterBody3D::get_up_direction);
@@ -1280,8 +1310,7 @@ void CharacterBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stop_on_slope"), "set_stop_on_slope_enabled", "is_stop_on_slope_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "infinite_inertia"), "set_infinite_inertia_enabled", "is_infinite_inertia_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides"), "set_max_slides", "get_max_slides");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_floor_max_angle", "get_floor_max_angle");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle_degrees", PROPERTY_HINT_RANGE, "0,180,0.1", PROPERTY_USAGE_EDITOR), "set_floor_max_angle_degrees", "get_floor_max_angle_degrees");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap"), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
@@ -2095,7 +2124,8 @@ void PhysicalBone3D::_notification(int p_what) {
_reload_joint();
}
break;
- case NOTIFICATION_EXIT_TREE:
+
+ case NOTIFICATION_EXIT_TREE: {
if (parent_skeleton) {
if (-1 != bone_id) {
parent_skeleton->unbind_physical_bone_from_bone(bone_id);
@@ -2105,12 +2135,13 @@ void PhysicalBone3D::_notification(int p_what) {
}
parent_skeleton = nullptr;
PhysicsServer3D::get_singleton()->joint_clear(joint);
- break;
- case NOTIFICATION_TRANSFORM_CHANGED:
+ } break;
+
+ case NOTIFICATION_TRANSFORM_CHANGED: {
if (Engine::get_singleton()->is_editor_hint()) {
update_offset();
}
- break;
+ } break;
}
}
@@ -2156,8 +2187,6 @@ void PhysicalBone3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone3D::get_joint_offset);
ClassDB::bind_method(D_METHOD("set_joint_rotation", "euler"), &PhysicalBone3D::set_joint_rotation);
ClassDB::bind_method(D_METHOD("get_joint_rotation"), &PhysicalBone3D::get_joint_rotation);
- ClassDB::bind_method(D_METHOD("set_joint_rotation_degrees", "euler_degrees"), &PhysicalBone3D::set_joint_rotation_degrees);
- ClassDB::bind_method(D_METHOD("get_joint_rotation_degrees"), &PhysicalBone3D::get_joint_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone3D::set_body_offset);
ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone3D::get_body_offset);
@@ -2192,12 +2221,11 @@ void PhysicalBone3D::_bind_methods() {
ADD_GROUP("Joint", "joint_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "joint_offset"), "set_joint_offset", "get_joint_offset");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_joint_rotation", "get_joint_rotation");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_RANGE, "-360,360,0.01,or_lesser,or_greater,radians"), "set_joint_rotation", "get_joint_rotation");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "body_offset"), "set_body_offset", "get_body_offset");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_RANGE, "0.01,65535,0.01,exp"), "set_mass", "get_mass");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale");
@@ -2428,14 +2456,6 @@ Vector3 PhysicalBone3D::get_joint_rotation() const {
return joint_offset.basis.get_rotation();
}
-void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) {
- set_joint_rotation(p_euler_deg * (Math_PI / 180.0));
-}
-
-Vector3 PhysicalBone3D::get_joint_rotation_degrees() const {
- return get_joint_rotation() * (180.0 / Math_PI);
-}
-
const Transform3D &PhysicalBone3D::get_body_offset() const {
return body_offset;
}
@@ -2605,7 +2625,7 @@ void PhysicalBone3D::_start_physics_simulation() {
return;
}
reset_to_rest_position();
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC);
+ 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_force_integration_callback(get_rid(), callable_mp(this, &PhysicalBone3D::_direct_state_changed));
@@ -2618,11 +2638,11 @@ void PhysicalBone3D::_stop_physics_simulation() {
return;
}
if (parent_skeleton->get_animate_physical_bones()) {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_KINEMATIC);
+ 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());
} else {
- PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC);
+ 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);
}
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index 7d7adf1624..9d45ce3799 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -53,7 +53,7 @@ protected:
Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.001);
public:
- bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
+ bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true);
bool test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001);
void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
@@ -307,9 +307,6 @@ private:
real_t get_floor_max_angle() const;
void set_floor_max_angle(real_t p_radians);
- real_t get_floor_max_angle_degrees() const;
- void set_floor_max_angle_degrees(real_t p_degrees);
-
const Vector3 &get_snap() const;
void set_snap(const Vector3 &p_snap);
@@ -551,9 +548,6 @@ public:
void set_joint_rotation(const Vector3 &p_euler_rad);
Vector3 get_joint_rotation() const;
- void set_joint_rotation_degrees(const Vector3 &p_euler_deg);
- Vector3 get_joint_rotation_degrees() const;
-
void set_body_offset(const Transform3D &p_offset);
const Transform3D &get_body_offset() const;
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index 7762156b4a..c289fc4fd7 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -232,7 +232,7 @@ void ReflectionProbe::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once (Fast),Always (Slow)"), "set_update_mode", "get_update_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "intensity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_intensity", "get_intensity");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,16384,0.1,or_greater"), "set_max_distance", "get_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384,0.1,or_greater,exp"), "set_max_distance", "get_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "origin_offset"), "set_origin_offset", "get_origin_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "box_projection"), "set_enable_box_projection", "is_box_projection_enabled");
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index 9592fe5849..efd8a2b50c 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -81,7 +81,7 @@ void SoftBodyRenderingServerHandler::close() {
}
void SoftBodyRenderingServerHandler::commit_changes() {
- RS::get_singleton()->mesh_surface_update_region(mesh, surface, 0, buffer);
+ RS::get_singleton()->mesh_surface_update_vertex_region(mesh, surface, 0, buffer);
}
void SoftBodyRenderingServerHandler::set_vertex(int p_vertex_id, const void *p_vector3) {
@@ -266,12 +266,13 @@ void SoftBody3D::_notification(int p_what) {
PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, space);
prepare_physics_server();
} break;
+
case NOTIFICATION_READY: {
if (!parent_collision_ignore.is_empty()) {
add_collision_exception_with(get_node(parent_collision_ignore));
}
-
} break;
+
case NOTIFICATION_TRANSFORM_CHANGED: {
if (Engine::get_singleton()->is_editor_hint()) {
_reset_points_offsets();
@@ -285,27 +286,36 @@ void SoftBody3D::_notification(int p_what) {
set_as_top_level(true);
set_transform(Transform3D());
set_notify_transform(true);
-
} break;
+
case NOTIFICATION_VISIBILITY_CHANGED: {
_update_pickable();
-
} break;
+
case NOTIFICATION_EXIT_WORLD: {
PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, RID());
-
} break;
- }
-#ifdef TOOLS_ENABLED
+ case NOTIFICATION_DISABLED: {
+ if (is_inside_tree() && (disable_mode == DISABLE_MODE_REMOVE)) {
+ prepare_physics_server();
+ }
+ } break;
- if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
- if (Engine::get_singleton()->is_editor_hint()) {
- update_configuration_warnings();
- }
- }
+ case NOTIFICATION_ENABLED: {
+ if (is_inside_tree() && (disable_mode == DISABLE_MODE_REMOVE)) {
+ prepare_physics_server();
+ }
+ } break;
+#ifdef TOOLS_ENABLED
+ case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ update_configuration_warnings();
+ }
+ } break;
#endif
+ }
}
void SoftBody3D::_bind_methods() {
@@ -326,6 +336,9 @@ void SoftBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_parent_collision_ignore", "parent_collision_ignore"), &SoftBody3D::set_parent_collision_ignore);
ClassDB::bind_method(D_METHOD("get_parent_collision_ignore"), &SoftBody3D::get_parent_collision_ignore);
+ ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &SoftBody3D::set_disable_mode);
+ ClassDB::bind_method(D_METHOD("get_disable_mode"), &SoftBody3D::get_disable_mode);
+
ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &SoftBody3D::get_collision_exceptions);
ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &SoftBody3D::add_collision_exception_with);
ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &SoftBody3D::remove_collision_exception_with);
@@ -364,6 +377,11 @@ void SoftBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ray_pickable"), "set_ray_pickable", "is_ray_pickable");
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "disable_mode", PROPERTY_HINT_ENUM, "Remove,KeepActive"), "set_disable_mode", "get_disable_mode");
+
+ BIND_ENUM_CONSTANT(DISABLE_MODE_REMOVE);
+ BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE);
}
TypedArray<String> SoftBody3D::get_configuration_warnings() const {
@@ -421,6 +439,7 @@ void SoftBody3D::_draw_soft_mesh() {
}
void SoftBody3D::prepare_physics_server() {
+#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
if (get_mesh().is_valid()) {
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
@@ -430,8 +449,9 @@ void SoftBody3D::prepare_physics_server() {
return;
}
+#endif
- if (get_mesh().is_valid()) {
+ if (get_mesh().is_valid() && (is_enabled() || (disable_mode != DISABLE_MODE_REMOVE))) {
become_mesh_owner();
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh));
@@ -527,6 +547,28 @@ bool SoftBody3D::get_collision_layer_bit(int p_bit) const {
return get_collision_layer() & (1 << p_bit);
}
+void SoftBody3D::set_disable_mode(DisableMode p_mode) {
+ if (disable_mode == p_mode) {
+ return;
+ }
+
+ bool inside_tree = is_inside_tree();
+
+ if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) {
+ prepare_physics_server();
+ }
+
+ disable_mode = p_mode;
+
+ if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) {
+ prepare_physics_server();
+ }
+}
+
+SoftBody3D::DisableMode SoftBody3D::get_disable_mode() const {
+ return disable_mode;
+}
+
void SoftBody3D::set_parent_collision_ignore(const NodePath &p_parent_collision_ignore) {
parent_collision_ignore = p_parent_collision_ignore;
}
diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h
index 0d0d39d48f..81aa0c10c6 100644
--- a/scene/3d/soft_body_3d.h
+++ b/scene/3d/soft_body_3d.h
@@ -67,6 +67,11 @@ class SoftBody3D : public MeshInstance3D {
GDCLASS(SoftBody3D, MeshInstance3D);
public:
+ enum DisableMode {
+ DISABLE_MODE_REMOVE,
+ DISABLE_MODE_KEEP_ACTIVE,
+ };
+
struct PinnedPoint {
int point_index = -1;
NodePath spatial_attachment_path;
@@ -83,6 +88,8 @@ private:
RID physics_rid;
+ DisableMode disable_mode = DISABLE_MODE_REMOVE;
+
bool mesh_owner = false;
uint32_t collision_mask = 1;
uint32_t collision_layer = 1;
@@ -137,6 +144,9 @@ public:
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;
+ void set_disable_mode(DisableMode p_mode);
+ DisableMode get_disable_mode() const;
+
void set_parent_collision_ignore(const NodePath &p_parent_collision_ignore);
const NodePath &get_parent_collision_ignore() const;
@@ -192,4 +202,6 @@ private:
int _has_pinned_point(int p_point_index) const;
};
+VARIANT_ENUM_CAST(SoftBody3D::DisableMode);
+
#endif // SOFT_PHYSICS_BODY_H
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 9ec461d973..13f8002721 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -164,6 +164,8 @@ void SpriteBase3D::_im_update() {
_draw();
pending_update = false;
+
+ //texture->draw_rect_region(ci,dst_rect,src_rect,modulate);
}
void SpriteBase3D::_queue_update() {
@@ -204,6 +206,7 @@ Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const {
float pixel_size = get_pixel_size();
Vector2 vertices[4] = {
+
(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
(final_rect.position + final_rect.size) * pixel_size,
(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
@@ -313,6 +316,9 @@ void SpriteBase3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_rect"), &SpriteBase3D::get_item_rect);
ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &SpriteBase3D::generate_triangle_mesh);
+ ClassDB::bind_method(D_METHOD("_queue_update"), &SpriteBase3D::_queue_update);
+ ClassDB::bind_method(D_METHOD("_im_update"), &SpriteBase3D::_im_update);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h");
@@ -343,21 +349,89 @@ SpriteBase3D::SpriteBase3D() {
flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED;
}
- immediate = RenderingServer::get_singleton()->immediate_create();
- set_base(immediate);
+ material = RenderingServer::get_singleton()->material_create();
+ // Set defaults for material, names need to match up those in StandardMaterial3D
+ RS::get_singleton()->material_set_param(material, "albedo", Color(1, 1, 1, 1));
+ RS::get_singleton()->material_set_param(material, "specular", 0.5);
+ RS::get_singleton()->material_set_param(material, "metallic", 0.0);
+ RS::get_singleton()->material_set_param(material, "roughness", 1.0);
+ RS::get_singleton()->material_set_param(material, "uv1_offset", Vector3(0, 0, 0));
+ RS::get_singleton()->material_set_param(material, "uv1_scale", Vector3(1, 1, 1));
+ RS::get_singleton()->material_set_param(material, "uv2_offset", Vector3(0, 0, 0));
+ RS::get_singleton()->material_set_param(material, "uv2_scale", Vector3(1, 1, 1));
+ RS::get_singleton()->material_set_param(material, "alpha_scissor_threshold", 0.98);
+
+ mesh = RenderingServer::get_singleton()->mesh_create();
+
+ PackedVector3Array mesh_vertices;
+ PackedVector3Array mesh_normals;
+ PackedFloat32Array mesh_tangents;
+ PackedColorArray mesh_colors;
+ PackedVector2Array mesh_uvs;
+ PackedInt32Array indices;
+
+ mesh_vertices.resize(4);
+ mesh_normals.resize(4);
+ mesh_tangents.resize(16);
+ mesh_colors.resize(4);
+ mesh_uvs.resize(4);
+
+ // create basic mesh and store format information
+ for (int i = 0; i < 4; i++) {
+ mesh_normals.write[i] = Vector3(0.0, 0.0, 0.0);
+ mesh_tangents.write[i * 4 + 0] = 0.0;
+ mesh_tangents.write[i * 4 + 1] = 0.0;
+ mesh_tangents.write[i * 4 + 2] = 0.0;
+ mesh_tangents.write[i * 4 + 3] = 0.0;
+ mesh_colors.write[i] = Color(1.0, 1.0, 1.0, 1.0);
+ mesh_uvs.write[i] = Vector2(0.0, 0.0);
+ mesh_vertices.write[i] = Vector3(0.0, 0.0, 0.0);
+ }
+
+ indices.resize(6);
+ indices.write[0] = 0;
+ indices.write[1] = 1;
+ indices.write[2] = 2;
+ indices.write[3] = 0;
+ indices.write[4] = 2;
+ indices.write[5] = 3;
+
+ Array mesh_array;
+ mesh_array.resize(RS::ARRAY_MAX);
+ mesh_array[RS::ARRAY_VERTEX] = mesh_vertices;
+ mesh_array[RS::ARRAY_NORMAL] = mesh_normals;
+ mesh_array[RS::ARRAY_TANGENT] = mesh_tangents;
+ mesh_array[RS::ARRAY_COLOR] = mesh_colors;
+ mesh_array[RS::ARRAY_TEX_UV] = mesh_uvs;
+ mesh_array[RS::ARRAY_INDEX] = indices;
+
+ RS::SurfaceData sd;
+ RS::get_singleton()->mesh_create_surface_data_from_arrays(&sd, RS::PRIMITIVE_TRIANGLES, mesh_array);
+
+ mesh_surface_format = sd.format;
+ vertex_buffer = sd.vertex_data;
+ attribute_buffer = sd.attribute_data;
+
+ sd.material = material;
+
+ RS::get_singleton()->mesh_surface_make_offsets_from_format(sd.format, sd.vertex_count, sd.index_count, mesh_surface_offsets, vertex_stride, attrib_stride, skin_stride);
+ RS::get_singleton()->mesh_add_surface(mesh, sd);
+ set_base(mesh);
}
SpriteBase3D::~SpriteBase3D() {
- RenderingServer::get_singleton()->free(immediate);
+ RenderingServer::get_singleton()->free(mesh);
+ RenderingServer::get_singleton()->free(material);
}
///////////////////////////////////////////
void Sprite3D::_draw() {
- RID immediate = get_immediate();
-
- RS::get_singleton()->immediate_clear(immediate);
+ if (get_base() != get_mesh()) {
+ set_base(get_mesh());
+ }
if (!texture.is_valid()) {
+ set_base(RID());
return;
}
Vector2 tsize = texture->get_size();
@@ -366,7 +440,7 @@ void Sprite3D::_draw() {
}
Rect2 base_rect;
- if (region_enabled) {
+ if (region) {
base_rect = region_rect;
} else {
base_rect = Rect2(0, 0, texture->get_width(), texture->get_height());
@@ -399,6 +473,7 @@ void Sprite3D::_draw() {
float pixel_size = get_pixel_size();
Vector2 vertices[4] = {
+
(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
(final_rect.position + final_rect.size) * pixel_size,
(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
@@ -426,6 +501,7 @@ void Sprite3D::_draw() {
SWAP(uvs[0], uvs[1]);
SWAP(uvs[2], uvs[3]);
}
+
if (is_flipped_v()) {
SWAP(uvs[0], uvs[3]);
SWAP(uvs[1], uvs[2]);
@@ -442,11 +518,6 @@ void Sprite3D::_draw() {
tangent = Plane(1, 0, 0, 1);
}
- RID mat = StandardMaterial3D::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y);
- RS::get_singleton()->immediate_set_material(immediate, mat);
-
- RS::get_singleton()->immediate_begin(immediate, RS::PRIMITIVE_TRIANGLES, texture->get_rid());
-
int x_axis = ((axis + 1) % 3);
int y_axis = ((axis + 2) % 3);
@@ -466,31 +537,80 @@ void Sprite3D::_draw() {
AABB aabb;
- for (int i = 0; i < 6; i++) {
- static const int index[6] = { 0, 1, 2, 0, 2, 3 };
+ // Everything except position and UV is compressed
+ uint8_t *vertex_write_buffer = vertex_buffer.ptrw();
+ uint8_t *attribute_write_buffer = attribute_buffer.ptrw();
+
+ uint32_t v_normal;
+ {
+ Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
+
+ 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;
+
+ v_normal = value;
+ }
+ uint32_t v_tangent;
+ {
+ Plane t = tangent;
+ 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 |= 3 << 30;
+ }
+ v_tangent = value;
+ }
- RS::get_singleton()->immediate_normal(immediate, normal);
- RS::get_singleton()->immediate_tangent(immediate, tangent);
- RS::get_singleton()->immediate_color(immediate, color);
- RS::get_singleton()->immediate_uv(immediate, uvs[index[i]]);
+ uint8_t v_color[4] = {
+ uint8_t(CLAMP(color.r * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.g * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.b * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.a * 255.0, 0.0, 255.0))
+ };
+ for (int i = 0; i < 4; i++) {
Vector3 vtx;
- vtx[x_axis] = vertices[index[i]][0];
- vtx[y_axis] = vertices[index[i]][1];
- RS::get_singleton()->immediate_vertex(immediate, vtx);
+ vtx[x_axis] = vertices[i][0];
+ vtx[y_axis] = vertices[i][1];
if (i == 0) {
aabb.position = vtx;
aabb.size = Vector3();
} else {
aabb.expand_to(vtx);
}
+
+ float v_uv[2] = { uvs[i].x, uvs[i].y };
+ memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_TEX_UV]], v_uv, 8);
+
+ float v_vertex[3] = { vtx.x, vtx.y, vtx.z };
+
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3);
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_NORMAL]], &v_normal, 4);
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_TANGENT]], &v_tangent, 4);
+ memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_COLOR]], v_color, 4);
}
+
+ RID mesh = get_mesh();
+ RS::get_singleton()->mesh_surface_update_vertex_region(mesh, 0, 0, vertex_buffer);
+ RS::get_singleton()->mesh_surface_update_attribute_region(mesh, 0, 0, attribute_buffer);
+
+ RS::get_singleton()->mesh_set_custom_aabb(mesh, aabb);
set_aabb(aabb);
- RS::get_singleton()->immediate_end(immediate);
-}
-void Sprite3D::_texture_changed() {
- _queue_update();
+ RID shader_rid;
+ StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, &shader_rid);
+ if (last_shader != shader_rid) {
+ RS::get_singleton()->material_set_shader(get_material(), shader_rid);
+ last_shader = shader_rid;
+ }
+ if (last_texture != texture->get_rid()) {
+ RS::get_singleton()->material_set_param(get_material(), "texture_albedo", texture->get_rid());
+ last_texture = texture->get_rid();
+ }
}
void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
@@ -498,38 +618,36 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
return;
}
if (texture.is_valid()) {
- texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite3D::_texture_changed));
+ texture->disconnect(CoreStringNames::get_singleton()->changed, Callable(this, "_queue_update"));
}
texture = p_texture;
if (texture.is_valid()) {
- texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite3D::_texture_changed));
+ texture->connect(CoreStringNames::get_singleton()->changed, Callable(this, "_queue_update"));
}
_queue_update();
- emit_signal(SceneStringNames::get_singleton()->texture_changed);
}
Ref<Texture2D> Sprite3D::get_texture() const {
return texture;
}
-void Sprite3D::set_region_enabled(bool p_region_enabled) {
- if (p_region_enabled == region_enabled) {
+void Sprite3D::set_region_enabled(bool p_region) {
+ if (p_region == region) {
return;
}
- region_enabled = p_region_enabled;
+ region = p_region;
_queue_update();
- notify_property_list_changed();
}
bool Sprite3D::is_region_enabled() const {
- return region_enabled;
+ return region;
}
void Sprite3D::set_region_rect(const Rect2 &p_region_rect) {
bool changed = region_rect != p_region_rect;
region_rect = p_region_rect;
- if (region_enabled && changed) {
+ if (region && changed) {
_queue_update();
}
}
@@ -596,7 +714,7 @@ Rect2 Sprite3D::get_item_rect() const {
Size2i s;
- if (region_enabled) {
+ if (region) {
s = region_rect.size;
} else {
s = texture->get_size();
@@ -625,10 +743,6 @@ void Sprite3D::_validate_property(PropertyInfo &property) const {
if (property.name == "frame_coords") {
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
-
- if (!region_enabled && property.name == "region_rect") {
- property.usage = PROPERTY_USAGE_NOEDITOR;
- }
}
void Sprite3D::_bind_methods() {
@@ -653,32 +767,28 @@ void Sprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hframes", "hframes"), &Sprite3D::set_hframes);
ClassDB::bind_method(D_METHOD("get_hframes"), &Sprite3D::get_hframes);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
ADD_GROUP("Animation", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_SIGNAL(MethodInfo("frame_changed"));
- ADD_SIGNAL(MethodInfo("texture_changed"));
}
Sprite3D::Sprite3D() {
- region_enabled = false;
- frame = 0;
- vframes = 1;
- hframes = 1;
}
////////////////////////////////////////
void AnimatedSprite3D::_draw() {
- RID immediate = get_immediate();
- RS::get_singleton()->immediate_clear(immediate);
+ if (get_base() != get_mesh()) {
+ set_base(get_mesh());
+ }
if (frames.is_null()) {
return;
@@ -694,7 +804,8 @@ void AnimatedSprite3D::_draw() {
Ref<Texture2D> texture = frames->get_frame(animation, frame);
if (!texture.is_valid()) {
- return; //no texture no life
+ set_base(RID());
+ return; //no texuture no life
}
Vector2 tsize = texture->get_size();
if (tsize.x == 0 || tsize.y == 0) {
@@ -729,6 +840,7 @@ void AnimatedSprite3D::_draw() {
float pixel_size = get_pixel_size();
Vector2 vertices[4] = {
+
(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
(final_rect.position + final_rect.size) * pixel_size,
(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
@@ -772,12 +884,6 @@ void AnimatedSprite3D::_draw() {
tangent = Plane(1, 0, 0, -1);
}
- RID mat = StandardMaterial3D::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y);
-
- RS::get_singleton()->immediate_set_material(immediate, mat);
-
- RS::get_singleton()->immediate_begin(immediate, RS::PRIMITIVE_TRIANGLES, texture->get_rid());
-
int x_axis = ((axis + 1) % 3);
int y_axis = ((axis + 2) % 3);
@@ -797,30 +903,79 @@ void AnimatedSprite3D::_draw() {
AABB aabb;
- for (int i = 0; i < 6; i++) {
- static const int indices[6] = {
- 0, 1, 2,
- 0, 2, 3
- };
+ // Everything except position and UV is compressed
+ uint8_t *vertex_write_buffer = vertex_buffer.ptrw();
+ uint8_t *attribute_write_buffer = attribute_buffer.ptrw();
+
+ uint32_t v_normal;
+ {
+ Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
+
+ 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;
+
+ v_normal = value;
+ }
+ uint32_t v_tangent;
+ {
+ Plane t = tangent;
+ 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 |= 3 << 30;
+ }
+ v_tangent = value;
+ }
- RS::get_singleton()->immediate_normal(immediate, normal);
- RS::get_singleton()->immediate_tangent(immediate, tangent);
- RS::get_singleton()->immediate_color(immediate, color);
- RS::get_singleton()->immediate_uv(immediate, uvs[indices[i]]);
+ uint8_t v_color[4] = {
+ uint8_t(CLAMP(color.r * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.g * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.b * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.a * 255.0, 0.0, 255.0))
+ };
+ for (int i = 0; i < 4; i++) {
Vector3 vtx;
- vtx[x_axis] = vertices[indices[i]][0];
- vtx[y_axis] = vertices[indices[i]][1];
- RS::get_singleton()->immediate_vertex(immediate, vtx);
+ vtx[x_axis] = vertices[i][0];
+ vtx[y_axis] = vertices[i][1];
if (i == 0) {
aabb.position = vtx;
aabb.size = Vector3();
} else {
aabb.expand_to(vtx);
}
+
+ float v_uv[2] = { uvs[i].x, uvs[i].y };
+ memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_TEX_UV]], v_uv, 8);
+
+ float v_vertex[3] = { vtx.x, vtx.y, vtx.z };
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3);
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_NORMAL]], &v_normal, 4);
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_TANGENT]], &v_tangent, 4);
+ memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_COLOR]], v_color, 4);
}
+
+ RID mesh = get_mesh();
+ RS::get_singleton()->mesh_surface_update_vertex_region(mesh, 0, 0, vertex_buffer);
+ RS::get_singleton()->mesh_surface_update_attribute_region(mesh, 0, 0, attribute_buffer);
+
+ RS::get_singleton()->mesh_set_custom_aabb(mesh, aabb);
set_aabb(aabb);
- RS::get_singleton()->immediate_end(immediate);
+
+ RID shader_rid;
+ StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, &shader_rid);
+ if (last_shader != shader_rid) {
+ RS::get_singleton()->material_set_shader(get_material(), shader_rid);
+ last_shader = shader_rid;
+ }
+ if (last_texture != texture->get_rid()) {
+ RS::get_singleton()->material_set_param(get_material(), "texture_albedo", texture->get_rid());
+ last_texture = texture->get_rid();
+ }
}
void AnimatedSprite3D::_validate_property(PropertyInfo &property) const {
@@ -914,11 +1069,11 @@ void AnimatedSprite3D::_notification(int p_what) {
void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
if (frames.is_valid()) {
- frames->disconnect("changed", callable_mp(this, &AnimatedSprite3D::_res_changed));
+ frames->disconnect("changed", Callable(this, "_res_changed"));
}
frames = p_frames;
if (frames.is_valid()) {
- frames->connect("changed", callable_mp(this, &AnimatedSprite3D::_res_changed));
+ frames->connect("changed", Callable(this, "_res_changed"));
}
if (!frames.is_valid()) {
@@ -944,9 +1099,8 @@ void AnimatedSprite3D::set_frame(int p_frame) {
if (frames->has_animation(animation)) {
int limit = frames->get_frame_count(animation);
- if (p_frame >= limit) {
+ if (p_frame >= limit)
p_frame = limit - 1;
- }
}
if (p_frame < 0) {
@@ -960,7 +1114,6 @@ void AnimatedSprite3D::set_frame(int p_frame) {
frame = p_frame;
_reset_timeout();
_queue_update();
-
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -1061,8 +1214,7 @@ StringName AnimatedSprite3D::get_animation() const {
}
TypedArray<String> AnimatedSprite3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
-
+ TypedArray<String> warnings = SpriteBase3D::get_configuration_warnings();
if (frames.is_null()) {
warnings.push_back(TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames."));
}
@@ -1087,11 +1239,13 @@ void AnimatedSprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &AnimatedSprite3D::set_frame);
ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame);
+ ClassDB::bind_method(D_METHOD("_res_changed"), &AnimatedSprite3D::_res_changed);
+
ADD_SIGNAL(MethodInfo("frame_changed"));
ADD_SIGNAL(MethodInfo("animation_finished"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames");
- ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing");
}
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index e3dd117804..404ef57e6a 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -31,8 +31,8 @@
#ifndef SPRITE_3D_H
#define SPRITE_3D_H
+#include "scene/2d/animated_sprite_2d.h"
#include "scene/3d/visual_instance_3d.h"
-#include "scene/resources/sprite_frames.h"
class SpriteBase3D : public GeometryInstance3D {
GDCLASS(SpriteBase3D, GeometryInstance3D);
@@ -75,9 +75,10 @@ private:
float pixel_size = 0.01;
AABB aabb;
- RID immediate;
+ RID mesh;
+ RID material;
- bool flags[FLAG_MAX];
+ bool flags[FLAG_MAX] = {};
AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
bool pending_update = false;
@@ -91,7 +92,17 @@ protected:
static void _bind_methods();
virtual void _draw() = 0;
_FORCE_INLINE_ void set_aabb(const AABB &p_aabb) { aabb = p_aabb; }
- _FORCE_INLINE_ RID &get_immediate() { return immediate; }
+ _FORCE_INLINE_ RID &get_mesh() { return mesh; }
+ _FORCE_INLINE_ RID &get_material() { return material; }
+
+ uint32_t mesh_surface_offsets[RS::ARRAY_MAX];
+ PackedByteArray vertex_buffer;
+ PackedByteArray attribute_buffer;
+ uint32_t vertex_stride;
+ uint32_t attrib_stride;
+ uint32_t skin_stride;
+ uint32_t mesh_surface_format;
+
void _queue_update();
public:
@@ -107,7 +118,7 @@ public:
void set_flip_v(bool p_flip);
bool is_flipped_v() const;
- void set_region_enabled(bool p_region_enabled);
+ void set_region_enabled(bool p_region);
bool is_region_enabled() const;
void set_region_rect(const Rect2 &p_region_rect);
@@ -147,15 +158,16 @@ class Sprite3D : public SpriteBase3D {
GDCLASS(Sprite3D, SpriteBase3D);
Ref<Texture2D> texture;
- bool region_enabled;
+ bool region = false;
Rect2 region_rect;
- int frame;
+ int frame = 0;
- int vframes;
- int hframes;
+ int vframes = 1;
+ int hframes = 1;
- void _texture_changed();
+ RID last_shader;
+ RID last_texture;
protected:
virtual void _draw() override;
@@ -167,7 +179,7 @@ public:
void set_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture() const;
- void set_region_enabled(bool p_region_enabled);
+ void set_region_enabled(bool p_region);
bool is_region_enabled() const;
void set_region_rect(const Rect2 &p_region_rect);
@@ -199,14 +211,9 @@ class AnimatedSprite3D : public SpriteBase3D {
StringName animation = "default";
int frame = 0;
- bool centered = true;
-
- float timeout = 0.0;
-
- bool hflip = true;
- bool vflip = true;
+ bool centered = false;
- Color modulate;
+ float timeout = 0;
void _res_changed();
@@ -214,6 +221,9 @@ class AnimatedSprite3D : public SpriteBase3D {
void _set_playing(bool p_playing);
bool _is_playing() const;
+ RID last_shader;
+ RID last_texture;
+
protected:
virtual void _draw() override;
static void _bind_methods();
@@ -236,10 +246,11 @@ public:
virtual Rect2 get_item_rect() const override;
- TypedArray<String> get_configuration_warnings() const override;
+ virtual TypedArray<String> get_configuration_warnings() const override;
AnimatedSprite3D();
};
VARIANT_ENUM_CAST(SpriteBase3D::DrawFlags);
VARIANT_ENUM_CAST(SpriteBase3D::AlphaCutMode);
+
#endif // SPRITE_3D_H
diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp
index 0d88769b70..b0e37b81a5 100644
--- a/scene/3d/vehicle_body_3d.cpp
+++ b/scene/3d/vehicle_body_3d.cpp
@@ -79,26 +79,29 @@ public:
};
void VehicleWheel3D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- VehicleBody3D *cb = Object::cast_to<VehicleBody3D>(get_parent());
- if (!cb) {
- return;
- }
- body = cb;
- local_xform = get_transform();
- cb->wheels.push_back(this);
-
- m_chassisConnectionPointCS = get_transform().origin;
- m_wheelDirectionCS = -get_transform().basis.get_axis(Vector3::AXIS_Y).normalized();
- m_wheelAxleCS = get_transform().basis.get_axis(Vector3::AXIS_X).normalized();
- }
- if (p_what == NOTIFICATION_EXIT_TREE) {
- VehicleBody3D *cb = Object::cast_to<VehicleBody3D>(get_parent());
- if (!cb) {
- return;
- }
- cb->wheels.erase(this);
- body = nullptr;
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ VehicleBody3D *cb = Object::cast_to<VehicleBody3D>(get_parent());
+ if (!cb) {
+ return;
+ }
+ body = cb;
+ local_xform = get_transform();
+ cb->wheels.push_back(this);
+
+ m_chassisConnectionPointCS = get_transform().origin;
+ m_wheelDirectionCS = -get_transform().basis.get_axis(Vector3::AXIS_Y).normalized();
+ m_wheelAxleCS = get_transform().basis.get_axis(Vector3::AXIS_X).normalized();
+ } break;
+
+ case NOTIFICATION_EXIT_TREE: {
+ VehicleBody3D *cb = Object::cast_to<VehicleBody3D>(get_parent());
+ if (!cb) {
+ return;
+ }
+ cb->wheels.erase(this);
+ body = nullptr;
+ } break;
}
}