summaryrefslogtreecommitdiff
path: root/scene/3d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/area_3d.cpp85
-rw-r--r--scene/3d/area_3d.h62
-rw-r--r--scene/3d/audio_stream_player_3d.cpp110
-rw-r--r--scene/3d/audio_stream_player_3d.h74
-rw-r--r--scene/3d/baked_lightmap.cpp33
-rw-r--r--scene/3d/baked_lightmap.h65
-rw-r--r--scene/3d/bone_attachment_3d.cpp5
-rw-r--r--scene/3d/bone_attachment_3d.h8
-rw-r--r--scene/3d/camera_3d.cpp89
-rw-r--r--scene/3d/camera_3d.h64
-rw-r--r--scene/3d/collision_object_3d.cpp66
-rw-r--r--scene/3d/collision_object_3d.h32
-rw-r--r--scene/3d/collision_polygon_3d.cpp48
-rw-r--r--scene/3d/collision_polygon_3d.h24
-rw-r--r--scene/3d/collision_shape_3d.cpp90
-rw-r--r--scene/3d/collision_shape_3d.h18
-rw-r--r--scene/3d/cpu_particles_3d.cpp187
-rw-r--r--scene/3d/cpu_particles_3d.h113
-rw-r--r--scene/3d/decal.cpp17
-rw-r--r--scene/3d/decal.h30
-rw-r--r--scene/3d/gi_probe.cpp38
-rw-r--r--scene/3d/gi_probe.h38
-rw-r--r--scene/3d/gpu_particles_3d.cpp77
-rw-r--r--scene/3d/gpu_particles_3d.h34
-rw-r--r--scene/3d/gpu_particles_collision_3d.cpp901
-rw-r--r--scene/3d/gpu_particles_collision_3d.h342
-rw-r--r--scene/3d/immediate_geometry_3d.cpp16
-rw-r--r--scene/3d/immediate_geometry_3d.h10
-rw-r--r--scene/3d/light_3d.cpp66
-rw-r--r--scene/3d/light_3d.h47
-rw-r--r--scene/3d/lightmap_probe.cpp4
-rw-r--r--scene/3d/lightmap_probe.h4
-rw-r--r--scene/3d/lightmapper.cpp4
-rw-r--r--scene/3d/lightmapper.h4
-rw-r--r--scene/3d/listener_3d.cpp6
-rw-r--r--scene/3d/listener_3d.h8
-rw-r--r--scene/3d/mesh_instance_3d.cpp13
-rw-r--r--scene/3d/mesh_instance_3d.h18
-rw-r--r--scene/3d/multimesh_instance_3d.cpp4
-rw-r--r--scene/3d/multimesh_instance_3d.h8
-rw-r--r--scene/3d/navigation_3d.cpp8
-rw-r--r--scene/3d/navigation_3d.h6
-rw-r--r--scene/3d/navigation_agent_3d.cpp17
-rw-r--r--scene/3d/navigation_agent_3d.h8
-rw-r--r--scene/3d/navigation_obstacle_3d.cpp13
-rw-r--r--scene/3d/navigation_obstacle_3d.h6
-rw-r--r--scene/3d/navigation_region_3d.cpp37
-rw-r--r--scene/3d/navigation_region_3d.h11
-rw-r--r--scene/3d/node_3d.cpp91
-rw-r--r--scene/3d/node_3d.h46
-rw-r--r--scene/3d/path_3d.cpp119
-rw-r--r--scene/3d/path_3d.h31
-rw-r--r--scene/3d/physics_body_3d.cpp198
-rw-r--r--scene/3d/physics_body_3d.h188
-rw-r--r--scene/3d/physics_joint_3d.cpp301
-rw-r--r--scene/3d/physics_joint_3d.h128
-rw-r--r--scene/3d/position_3d.cpp4
-rw-r--r--scene/3d/position_3d.h4
-rw-r--r--scene/3d/proximity_group_3d.cpp98
-rw-r--r--scene/3d/proximity_group_3d.h31
-rw-r--r--scene/3d/ray_cast_3d.cpp71
-rw-r--r--scene/3d/ray_cast_3d.h26
-rw-r--r--scene/3d/reflection_probe.cpp96
-rw-r--r--scene/3d/reflection_probe.h58
-rw-r--r--scene/3d/remote_transform_3d.cpp18
-rw-r--r--scene/3d/remote_transform_3d.h14
-rw-r--r--scene/3d/skeleton_3d.cpp76
-rw-r--r--scene/3d/skeleton_3d.h61
-rw-r--r--scene/3d/skeleton_ik_3d.cpp15
-rw-r--r--scene/3d/skeleton_ik_3d.h18
-rw-r--r--scene/3d/soft_body_3d.cpp47
-rw-r--r--scene/3d/soft_body_3d.h30
-rw-r--r--scene/3d/spring_arm_3d.cpp18
-rw-r--r--scene/3d/spring_arm_3d.h20
-rw-r--r--scene/3d/sprite_3d.cpp58
-rw-r--r--scene/3d/sprite_3d.h62
-rw-r--r--scene/3d/vehicle_body_3d.cpp129
-rw-r--r--scene/3d/vehicle_body_3d.h142
-rw-r--r--scene/3d/velocity_tracker_3d.cpp14
-rw-r--r--scene/3d/velocity_tracker_3d.h10
-rw-r--r--scene/3d/visibility_notifier_3d.cpp19
-rw-r--r--scene/3d/visibility_notifier_3d.h14
-rw-r--r--scene/3d/visual_instance_3d.cpp30
-rw-r--r--scene/3d/visual_instance_3d.h29
-rw-r--r--scene/3d/voxelizer.cpp20
-rw-r--r--scene/3d/voxelizer.h52
-rw-r--r--scene/3d/world_environment.cpp105
-rw-r--r--scene/3d/world_environment.h11
-rw-r--r--scene/3d/xr_nodes.cpp74
-rw-r--r--scene/3d/xr_nodes.h22
90 files changed, 3424 insertions, 2142 deletions
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index a024757927..23eda379be 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -180,26 +180,20 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
E->get().shapes.erase(ShapePair(p_body_shape, p_area_shape));
}
- bool eraseit = false;
-
+ bool in_tree = E->get().in_tree;
if (E->get().rc == 0) {
+ body_map.erase(E);
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree));
- if (E->get().in_tree) {
+ if (in_tree) {
emit_signal(SceneStringNames::get_singleton()->body_exited, obj);
}
}
-
- eraseit = true;
}
- if (node && E->get().in_tree) {
+ if (node && in_tree) {
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_area_shape);
}
-
- if (eraseit) {
- body_map.erase(E);
- }
}
locked = false;
@@ -222,6 +216,9 @@ void Area3D::_clear_monitoring() {
}
//ERR_CONTINUE(!node);
+ node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree));
+ node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree));
+
if (!E->get().in_tree) {
continue;
}
@@ -231,9 +228,6 @@ void Area3D::_clear_monitoring() {
}
emit_signal(SceneStringNames::get_singleton()->body_exited, node);
-
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree));
}
}
@@ -251,6 +245,9 @@ void Area3D::_clear_monitoring() {
}
//ERR_CONTINUE(!node);
+ node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree));
+ node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree));
+
if (!E->get().in_tree) {
continue;
}
@@ -260,9 +257,6 @@ void Area3D::_clear_monitoring() {
}
emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
-
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree));
}
}
}
@@ -366,26 +360,20 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
E->get().shapes.erase(AreaShapePair(p_area_shape, p_self_shape));
}
- bool eraseit = false;
-
+ bool in_tree = E->get().in_tree;
if (E->get().rc == 0) {
+ area_map.erase(E);
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree));
- if (E->get().in_tree) {
+ if (in_tree) {
emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
}
}
-
- eraseit = true;
}
- if (!node || E->get().in_tree) {
+ if (!node || in_tree) {
emit_signal(SceneStringNames::get_singleton()->area_shape_exited, objid, obj, p_area_shape, p_self_shape);
}
-
- if (eraseit) {
- area_map.erase(E);
- }
}
locked = false;
@@ -517,11 +505,11 @@ bool Area3D::is_overriding_audio_bus() const {
return audio_bus_override;
}
-void Area3D::set_audio_bus(const StringName &p_audio_bus) {
+void Area3D::set_audio_bus_name(const StringName &p_audio_bus) {
audio_bus = p_audio_bus;
}
-StringName Area3D::get_audio_bus() const {
+StringName Area3D::get_audio_bus_name() const {
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == audio_bus) {
return audio_bus;
@@ -637,8 +625,8 @@ void Area3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area3D::set_audio_bus_override);
ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area3D::is_overriding_audio_bus);
- ClassDB::bind_method(D_METHOD("set_audio_bus", "name"), &Area3D::set_audio_bus);
- ClassDB::bind_method(D_METHOD("get_audio_bus"), &Area3D::get_audio_bus);
+ ClassDB::bind_method(D_METHOD("set_audio_bus_name", "name"), &Area3D::set_audio_bus_name);
+ ClassDB::bind_method(D_METHOD("get_audio_bus_name"), &Area3D::get_audio_bus_name);
ClassDB::bind_method(D_METHOD("set_use_reverb_bus", "enable"), &Area3D::set_use_reverb_bus);
ClassDB::bind_method(D_METHOD("is_using_reverb_bus"), &Area3D::is_using_reverb_bus);
@@ -652,13 +640,13 @@ void Area3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_reverb_uniformity", "amount"), &Area3D::set_reverb_uniformity);
ClassDB::bind_method(D_METHOD("get_reverb_uniformity"), &Area3D::get_reverb_uniformity);
- ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
- ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
- ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
- ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
+ ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D")));
+ ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D")));
- ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
- ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
+ ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D")));
ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D")));
@@ -677,7 +665,7 @@ void Area3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_GROUP("Audio Bus", "audio_bus_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus");
- ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus", "get_audio_bus");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus_name", "get_audio_bus_name");
ADD_GROUP("Reverb Bus", "reverb_bus_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "reverb_bus_enable"), "set_use_reverb_bus", "is_using_reverb_bus");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "reverb_bus_name", PROPERTY_HINT_ENUM, ""), "set_reverb_bus", "get_reverb_bus");
@@ -693,29 +681,10 @@ void Area3D::_bind_methods() {
Area3D::Area3D() :
CollisionObject3D(PhysicsServer3D::get_singleton()->area_create(), true) {
- space_override = SPACE_OVERRIDE_DISABLED;
set_gravity(9.8);
- locked = false;
set_gravity_vector(Vector3(0, -1, 0));
- gravity_is_point = false;
- gravity_distance_scale = 0;
- linear_damp = 0.1;
- angular_damp = 0.1;
- priority = 0;
- monitoring = false;
- monitorable = false;
- collision_mask = 1;
- collision_layer = 1;
set_monitoring(true);
set_monitorable(true);
-
- audio_bus_override = false;
- audio_bus = "Master";
-
- use_reverb_bus = false;
- reverb_bus = "Master";
- reverb_amount = 0.0;
- reverb_uniformity = 0.0;
}
Area3D::~Area3D() {
diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h
index 98f337d3e4..6d976115f7 100644
--- a/scene/3d/area_3d.h
+++ b/scene/3d/area_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,7 +31,7 @@
#ifndef AREA_3D_H
#define AREA_3D_H
-#include "core/vset.h"
+#include "core/templates/vset.h"
#include "scene/3d/collision_object_3d.h"
class Area3D : public CollisionObject3D {
@@ -47,19 +47,19 @@ public:
};
private:
- SpaceOverride space_override;
+ SpaceOverride space_override = SPACE_OVERRIDE_DISABLED;
Vector3 gravity_vec;
real_t gravity;
- bool gravity_is_point;
- real_t gravity_distance_scale;
- real_t angular_damp;
- real_t linear_damp;
- uint32_t collision_mask;
- uint32_t collision_layer;
- int priority;
- bool monitoring;
- bool monitorable;
- bool locked;
+ bool gravity_is_point = false;
+ real_t gravity_distance_scale = 0.0;
+ real_t angular_damp = 0.1;
+ real_t linear_damp = 0.1;
+ uint32_t collision_mask = 1;
+ uint32_t collision_layer = 1;
+ int priority = 0;
+ bool monitoring = false;
+ bool monitorable = false;
+ bool locked = false;
void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape);
@@ -67,8 +67,8 @@ private:
void _body_exit_tree(ObjectID p_id);
struct ShapePair {
- int body_shape;
- int area_shape;
+ int body_shape = 0;
+ int area_shape = 0;
bool operator<(const ShapePair &p_sp) const {
if (body_shape == p_sp.body_shape) {
return area_shape < p_sp.area_shape;
@@ -85,8 +85,8 @@ private:
};
struct BodyState {
- int rc;
- bool in_tree;
+ int rc = 0;
+ bool in_tree = false;
VSet<ShapePair> shapes;
};
@@ -98,8 +98,8 @@ private:
void _area_exit_tree(ObjectID p_id);
struct AreaShapePair {
- int area_shape;
- int self_shape;
+ int area_shape = 0;
+ int self_shape = 0;
bool operator<(const AreaShapePair &p_sp) const {
if (area_shape == p_sp.area_shape) {
return self_shape < p_sp.self_shape;
@@ -116,23 +116,23 @@ private:
};
struct AreaState {
- int rc;
- bool in_tree;
+ int rc = 0;
+ bool in_tree = false;
VSet<AreaShapePair> shapes;
};
Map<ObjectID, AreaState> area_map;
void _clear_monitoring();
- bool audio_bus_override;
- StringName audio_bus;
+ bool audio_bus_override = false;
+ StringName audio_bus = "Master";
- bool use_reverb_bus;
- StringName reverb_bus;
- float reverb_amount;
- float reverb_uniformity;
+ bool use_reverb_bus = false;
+ StringName reverb_bus = "Master";
+ float reverb_amount = 0.0;
+ float reverb_uniformity = 0.0;
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
protected:
void _notification(int p_what);
@@ -190,8 +190,8 @@ public:
void set_audio_bus_override(bool p_override);
bool is_overriding_audio_bus() const;
- void set_audio_bus(const StringName &p_audio_bus);
- StringName get_audio_bus() const;
+ void set_audio_bus_name(const StringName &p_audio_bus);
+ StringName get_audio_bus_name() const;
void set_use_reverb_bus(bool p_enable);
bool is_using_reverb_bus() const;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 6e4db8f382..72392be5bd 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,7 +30,7 @@
#include "audio_stream_player_3d.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
#include "scene/3d/area_3d.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/listener_3d.h"
@@ -42,8 +42,8 @@ class Spcap {
private:
struct Speaker {
Vector3 direction;
- real_t effective_number_of_speakers; // precalculated
- mutable real_t squared_gain; // temporary
+ real_t effective_number_of_speakers = 0; // precalculated
+ mutable real_t squared_gain = 0; // temporary
};
Vector<Speaker> speakers;
@@ -138,15 +138,15 @@ void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tig
}
void AudioStreamPlayer3D::_mix_audio() {
- if (!stream_playback.is_valid() || !active ||
+ if (!stream_playback.is_valid() || !active.is_set() ||
(stream_paused && !stream_paused_fade_out)) {
return;
}
bool started = false;
- if (setseek >= 0.0) {
- stream_playback->start(setseek);
- setseek = -1.0; //reset seek
+ if (setseek.get() >= 0.0) {
+ stream_playback->start(setseek.get());
+ setseek.set(-1.0); //reset seek
started = true;
}
@@ -160,14 +160,14 @@ void AudioStreamPlayer3D::_mix_audio() {
}
// Mix if we're not paused or we're fading out
- if ((output_count > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) {
+ if ((output_count.get() > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) {
float output_pitch_scale = 0.0;
- if (output_count) {
+ if (output_count.get()) {
//used for doppler, not realistic but good enough
- for (int i = 0; i < output_count; i++) {
+ for (int i = 0; i < output_count.get(); i++) {
output_pitch_scale += outputs[i].pitch_scale;
}
- output_pitch_scale /= float(output_count);
+ output_pitch_scale /= float(output_count.get());
} else {
output_pitch_scale = 1.0;
}
@@ -176,7 +176,7 @@ void AudioStreamPlayer3D::_mix_audio() {
}
//write all outputs
- for (int i = 0; i < output_count; i++) {
+ for (int i = 0; i < output_count.get(); i++) {
Output current = outputs[i];
//see if current output exists, to keep volume ramp
@@ -285,14 +285,14 @@ void AudioStreamPlayer3D::_mix_audio() {
prev_outputs[i] = current;
}
- prev_output_count = output_count;
+ prev_output_count = output_count.get();
//stream is no longer active, disable this.
if (!stream_playback->is_playing()) {
- active = false;
+ active.clear();
}
- output_ready = false;
+ output_ready.clear();
stream_paused_fade_in = false;
stream_paused_fade_out = false;
}
@@ -327,9 +327,6 @@ float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
return att;
}
-void _update_sound() {
-}
-
void AudioStreamPlayer3D::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
velocity_tracker->reset(get_global_transform().origin);
@@ -363,7 +360,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
//update anything related to position first, if possible of course
- if (!output_ready) {
+ if (!output_ready.is_set()) {
Vector3 linear_velocity;
//compute linear velocity for doppler
@@ -487,7 +484,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
if (area) {
if (area->is_overriding_audio_bus()) {
//override audio bus
- StringName bus_name = area->get_audio_bus();
+ StringName bus_name = area->get_audio_bus_name();
output.bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
}
@@ -599,24 +596,20 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
}
- output_count = new_output_count;
- output_ready = true;
+ output_count.set(new_output_count);
+ output_ready.set();
}
//start playing if requested
- if (setplay >= 0.0) {
- setseek = setplay;
- active = true;
- setplay = -1;
- //do not update, this makes it easier to animate (will shut off otherwise)
- ///_change_notify("playing"); //update property in editor
+ if (setplay.get() >= 0.0) {
+ setseek.set(setplay.get());
+ active.set();
+ setplay.set(-1);
}
//stop playing if no longer active
- if (!active) {
+ if (!active.is_set()) {
set_physics_process_internal(false);
- //do not update, this makes it easier to animate (will shut off otherwise)
- //_change_notify("playing"); //update property in editor
emit_signal("finished");
}
}
@@ -630,8 +623,8 @@ void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) {
if (stream_playback.is_valid()) {
stream_playback.unref();
stream.unref();
- active = false;
- setseek = -1;
+ active.clear();
+ setseek.set(-1);
}
if (p_stream.is_valid()) {
@@ -690,30 +683,29 @@ void AudioStreamPlayer3D::play(float p_from_pos) {
}
if (stream_playback.is_valid()) {
- active = true;
- setplay = p_from_pos;
- output_ready = false;
+ setplay.set(p_from_pos);
+ output_ready.clear();
set_physics_process_internal(true);
}
}
void AudioStreamPlayer3D::seek(float p_seconds) {
if (stream_playback.is_valid()) {
- setseek = p_seconds;
+ setseek.set(p_seconds);
}
}
void AudioStreamPlayer3D::stop() {
if (stream_playback.is_valid()) {
- active = false;
+ active.clear();
set_physics_process_internal(false);
- setplay = -1;
+ setplay.set(-1);
}
}
bool AudioStreamPlayer3D::is_playing() const {
if (stream_playback.is_valid()) {
- return active; // && stream_playback->is_playing();
+ return active.is_set() || setplay.get() >= 0;
}
return false;
@@ -721,6 +713,10 @@ bool AudioStreamPlayer3D::is_playing() const {
float AudioStreamPlayer3D::get_playback_position() {
if (stream_playback.is_valid()) {
+ float ss = setseek.get();
+ if (ss >= 0.0) {
+ return ss;
+ }
return stream_playback->get_playback_position();
}
@@ -760,7 +756,7 @@ void AudioStreamPlayer3D::_set_playing(bool p_enable) {
}
bool AudioStreamPlayer3D::_is_active() const {
- return active;
+ return active.is_set();
}
void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
@@ -779,7 +775,7 @@ void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
}
void AudioStreamPlayer3D::_bus_layout_changed() {
- _change_notify();
+ notify_property_list_changed();
}
void AudioStreamPlayer3D::set_max_distance(float p_metres) {
@@ -812,7 +808,6 @@ void AudioStreamPlayer3D::set_emission_angle(float p_angle) {
ERR_FAIL_COND(p_angle < 0 || p_angle > 90);
emission_angle = p_angle;
update_gizmo();
- _change_notify("emission_angle");
}
float AudioStreamPlayer3D::get_emission_angle() const {
@@ -1005,31 +1000,6 @@ void AudioStreamPlayer3D::_bind_methods() {
}
AudioStreamPlayer3D::AudioStreamPlayer3D() {
- unit_db = 0;
- unit_size = 1;
- attenuation_model = ATTENUATION_INVERSE_DISTANCE;
- max_db = 3;
- pitch_scale = 1.0;
- autoplay = false;
- setseek = -1;
- active = false;
- output_count = 0;
- prev_output_count = 0;
- max_distance = 0;
- setplay = -1;
- output_ready = false;
- area_mask = 1;
- emission_angle = 45;
- emission_angle_enabled = false;
- emission_angle_filter_attenuation_db = -12;
- attenuation_filter_cutoff_hz = 5000;
- attenuation_filter_db = -24;
- out_of_range_mode = OUT_OF_RANGE_MIX;
- doppler_tracking = DOPPLER_TRACKING_DISABLED;
- stream_paused = false;
- stream_paused_fade_in = false;
- stream_paused_fade_out = false;
-
velocity_tracker.instance();
AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer3D::_bus_layout_changed));
set_disable_scale(true);
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 9f261c54b4..70c535bd89 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,6 +31,7 @@
#ifndef AUDIO_STREAM_PLAYER_3D_H
#define AUDIO_STREAM_PLAYER_3D_H
+#include "core/templates/safe_refcount.h"
#include "scene/3d/node_3d.h"
#include "scene/3d/velocity_tracker_3d.h"
#include "servers/audio/audio_filter_sw.h"
@@ -71,46 +72,39 @@ private:
AudioFilterSW filter;
AudioFilterSW::Processor filter_process[8];
AudioFrame vol[4];
- float filter_gain;
- float pitch_scale;
- int bus_index;
- int reverb_bus_index;
+ float filter_gain = 0.0;
+ float pitch_scale = 0.0;
+ int bus_index = -1;
+ int reverb_bus_index = -1;
AudioFrame reverb_vol[4];
- Viewport *viewport; //pointer only used for reference to previous mix
-
- Output() {
- filter_gain = 0;
- viewport = nullptr;
- reverb_bus_index = -1;
- bus_index = -1;
- }
+ Viewport *viewport = nullptr; //pointer only used for reference to previous mix
};
Output outputs[MAX_OUTPUTS];
- volatile int output_count;
- volatile bool output_ready;
+ SafeNumeric<int> output_count;
+ SafeFlag output_ready;
//these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks)
Output prev_outputs[MAX_OUTPUTS];
- int prev_output_count;
+ int prev_output_count = 0;
Ref<AudioStreamPlayback> stream_playback;
Ref<AudioStream> stream;
Vector<AudioFrame> mix_buffer;
- volatile float setseek;
- volatile bool active;
- volatile float setplay;
-
- AttenuationModel attenuation_model;
- float unit_db;
- float unit_size;
- float max_db;
- float pitch_scale;
- bool autoplay;
- bool stream_paused;
- bool stream_paused_fade_in;
- bool stream_paused_fade_out;
+ SafeNumeric<float> setseek{ -1.0 };
+ SafeFlag active;
+ SafeNumeric<float> setplay{ -1.0 };
+
+ AttenuationModel attenuation_model = ATTENUATION_INVERSE_DISTANCE;
+ float unit_db = 0.0;
+ float unit_size = 1.0;
+ float max_db = 3.0;
+ float pitch_scale = 1.0;
+ bool autoplay = false;
+ bool stream_paused = false;
+ bool stream_paused_fade_in = false;
+ bool stream_paused_fade_out = false;
StringName bus;
static void _calc_output_vol(const Vector3 &source_dir, real_t tightness, Output &output);
@@ -122,26 +116,26 @@ private:
void _bus_layout_changed();
- uint32_t area_mask;
+ uint32_t area_mask = 1;
- bool emission_angle_enabled;
- float emission_angle;
- float emission_angle_filter_attenuation_db;
- float attenuation_filter_cutoff_hz;
- float attenuation_filter_db;
+ bool emission_angle_enabled = false;
+ float emission_angle = 45.0;
+ float emission_angle_filter_attenuation_db = -12.0;
+ float attenuation_filter_cutoff_hz = 5000.0;
+ float attenuation_filter_db = -24.0;
- float max_distance;
+ float max_distance = 0.0;
Ref<VelocityTracker3D> velocity_tracker;
- DopplerTracking doppler_tracking;
+ DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED;
- OutOfRangeMode out_of_range_mode;
+ OutOfRangeMode out_of_range_mode = OUT_OF_RANGE_MIX;
float _get_attenuation_db(float p_distance) const;
protected:
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp
index e2f1b3807d..578ea823f0 100644
--- a/scene/3d/baked_lightmap.cpp
+++ b/scene/3d/baked_lightmap.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -37,7 +37,7 @@
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
-#include "core/sort_array.h"
+#include "core/templates/sort_array.h"
#include "lightmap_probe.h"
void BakedLightmapData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance) {
@@ -195,7 +195,7 @@ void BakedLightmapData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uses_spherical_harmonics", "uses_spherical_harmonics"), &BakedLightmapData::set_uses_spherical_harmonics);
ClassDB::bind_method(D_METHOD("is_using_spherical_harmonics"), &BakedLightmapData::is_using_spherical_harmonics);
- ClassDB::bind_method(D_METHOD("add_user", "path", "lightmap", "offset"), &BakedLightmapData::add_user);
+ ClassDB::bind_method(D_METHOD("add_user", "path", "uv_scale", "slice_index", "sub_instance"), &BakedLightmapData::add_user);
ClassDB::bind_method(D_METHOD("get_user_count"), &BakedLightmapData::get_user_count);
ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &BakedLightmapData::get_user_path);
ClassDB::bind_method(D_METHOD("clear_users"), &BakedLightmapData::clear_users);
@@ -559,7 +559,7 @@ void BakedLightmap::_plot_triangle_into_octree(GenProbesOctree *p_cell, float p_
subcell.position = Vector3(pos) * p_cell_size;
subcell.size = Vector3(half_size, half_size, half_size) * p_cell_size;
- if (!Geometry::triangle_box_overlap(subcell.position + subcell.size * 0.5, subcell.size * 0.5, p_triangle)) {
+ if (!Geometry3D::triangle_box_overlap(subcell.position + subcell.size * 0.5, subcell.size * 0.5, p_triangle)) {
continue;
}
@@ -678,7 +678,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d
}
TypedArray<Image> images = RS::get_singleton()->bake_render_uv2(mf.mesh->get_rid(), overrides, lightmap_size);
- ERR_FAIL_COND_V(images.empty(), BAKE_ERROR_CANT_CREATE_IMAGE);
+ ERR_FAIL_COND_V(images.is_empty(), BAKE_ERROR_CANT_CREATE_IMAGE);
Ref<Image> albedo = images[RS::BAKE_CHANNEL_ALBEDO_ALPHA];
Ref<Image> orm = images[RS::BAKE_CHANNEL_ORM];
@@ -894,13 +894,13 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d
if (Object::cast_to<DirectionalLight3D>(light)) {
DirectionalLight3D *l = Object::cast_to<DirectionalLight3D>(light);
- lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_ALL, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_SIZE));
+ lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_STATIC, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_SIZE));
} else if (Object::cast_to<OmniLight3D>(light)) {
OmniLight3D *l = Object::cast_to<OmniLight3D>(light);
- lightmapper->add_omni_light(light->get_bake_mode() == Light3D::BAKE_ALL, xf.origin, l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
+ lightmapper->add_omni_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
} else if (Object::cast_to<SpotLight3D>(light)) {
SpotLight3D *l = Object::cast_to<SpotLight3D>(light);
- lightmapper->add_spot_light(light->get_bake_mode() == Light3D::BAKE_ALL, xf.origin, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SPOT_ANGLE), l->get_param(Light3D::PARAM_SPOT_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
+ lightmapper->add_spot_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SPOT_ANGLE), l->get_param(Light3D::PARAM_SPOT_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
}
}
for (int i = 0; i < probes_found.size(); i++) {
@@ -1302,7 +1302,7 @@ bool BakedLightmap::is_interior() const {
void BakedLightmap::set_environment_mode(EnvironmentMode p_mode) {
environment_mode = p_mode;
- _change_notify();
+ notify_property_list_changed();
}
BakedLightmap::EnvironmentMode BakedLightmap::get_environment_mode() const {
@@ -1466,17 +1466,4 @@ void BakedLightmap::_bind_methods() {
}
BakedLightmap::BakedLightmap() {
- environment_mode = ENVIRONMENT_MODE_DISABLED;
- environment_custom_color = Color(0.2, 0.7, 1.0);
- environment_custom_energy = 1.0;
-
- bake_quality = BAKE_QUALITY_MEDIUM;
- interior = false;
- directional = false;
-
- gen_probes = GENERATE_PROBES_DISABLED;
- use_denoiser = true;
- bounces = 1;
- bias = 0.0005;
- max_texture_size = 16384;
}
diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h
index 08098c3d5d..e2d89ab2d0 100644
--- a/scene/3d/baked_lightmap.h
+++ b/scene/3d/baked_lightmap.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,7 +31,7 @@
#ifndef BAKED_LIGHTMAP_H
#define BAKED_LIGHTMAP_H
-#include "core/local_vector.h"
+#include "core/templates/local_vector.h"
#include "scene/3d/light_3d.h"
#include "scene/3d/lightmapper.h"
#include "scene/3d/mesh_instance_3d.h"
@@ -53,9 +53,9 @@ class BakedLightmapData : public Resource {
struct User {
NodePath path;
- int32_t sub_instance;
+ int32_t sub_instance = 0;
Rect2 uv_scale;
- int slice_index;
+ int slice_index = 0;
};
Vector<User> users;
@@ -94,7 +94,7 @@ public:
void clear();
- virtual RID get_rid() const;
+ virtual RID get_rid() const override;
BakedLightmapData();
~BakedLightmapData();
};
@@ -136,32 +136,32 @@ public:
};
private:
- BakeQuality bake_quality;
- bool use_denoiser;
- int bounces;
- float bias;
- int max_texture_size;
- bool interior;
- EnvironmentMode environment_mode;
+ BakeQuality bake_quality = BAKE_QUALITY_MEDIUM;
+ bool use_denoiser = true;
+ int bounces = 1;
+ float bias = 0.0005;
+ int max_texture_size = 16384;
+ bool interior = false;
+ EnvironmentMode environment_mode = ENVIRONMENT_MODE_DISABLED;
Ref<Sky> environment_custom_sky;
- Color environment_custom_color;
- float environment_custom_energy;
- bool directional;
- GenerateProbes gen_probes;
+ Color environment_custom_color = Color(0.2, 0.7, 1.0);
+ float environment_custom_energy = 1.0;
+ bool directional = false;
+ GenerateProbes gen_probes = GENERATE_PROBES_DISABLED;
Ref<BakedLightmapData> light_data;
struct LightsFound {
Transform xform;
- Light3D *light;
+ Light3D *light = nullptr;
};
struct MeshesFound {
Transform xform;
NodePath node_path;
- int32_t subindex;
+ int32_t subindex = 0;
Ref<Mesh> mesh;
- int32_t lightmap_scale;
+ int32_t lightmap_scale = 0;
Vector<Ref<Material>> overrides;
};
@@ -172,19 +172,20 @@ private:
struct BakeTimeData {
String text;
- int pass;
- uint64_t last_step;
+ int pass = 0;
+ uint64_t last_step = 0;
};
struct BSPSimplex {
- int vertices[4];
- int planes[4];
+ int vertices[4] = {};
+ int planes[4] = {};
};
struct BSPNode {
static const int32_t EMPTY_LEAF = INT32_MIN;
Plane plane;
- int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
+ int32_t over = EMPTY_LEAF;
+ int32_t under = EMPTY_LEAF;
};
int _bsp_get_simplex_side(const Vector<Vector3> &p_points, const LocalVector<BSPSimplex> &p_simplices, const Plane &p_plane, uint32_t p_simplex) const;
@@ -192,16 +193,16 @@ private:
struct BakeStepUD {
Lightmapper::BakeStepFunc func;
- void *ud;
- float from_percent;
- float to_percent;
+ void *ud = nullptr;
+ float from_percent = 0.0;
+ float to_percent = 0.0;
};
static bool _lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh);
struct GenProbesOctree {
Vector3i offset;
- uint32_t size;
+ uint32_t size = 0;
GenProbesOctree *children[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
~GenProbesOctree() {
for (int i = 0; i < 8; i++) {
@@ -224,7 +225,7 @@ private:
void _gen_new_positions_from_octree(const GenProbesOctree *p_cell, float p_cell_size, const Vector<Vector3> &probe_positions, LocalVector<Vector3> &new_probe_positions, HashMap<Vector3i, bool, Vector3iHash> &positions_used, const AABB &p_bounds);
protected:
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
static void _bind_methods();
void _notification(int p_what);
@@ -268,8 +269,8 @@ public:
void set_generate_probes(GenerateProbes p_generate_probes);
GenerateProbes get_generate_probes() const;
- AABB get_aabb() const;
- Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ AABB get_aabb() const override;
+ Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
BakeError bake(Node *p_from_node, String p_image_data_path = "", Lightmapper::BakeStepFunc p_bake_step = nullptr, void *p_bake_userdata = nullptr);
BakedLightmap();
diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp
index 68303bbfe5..5315e685a0 100644
--- a/scene/3d/bone_attachment_3d.cpp
+++ b/scene/3d/bone_attachment_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -105,7 +105,6 @@ void BoneAttachment3D::_notification(int p_what) {
}
BoneAttachment3D::BoneAttachment3D() {
- bound = false;
}
void BoneAttachment3D::_bind_methods() {
diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h
index fec59217d2..0c6d5f12b1 100644
--- a/scene/3d/bone_attachment_3d.h
+++ b/scene/3d/bone_attachment_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -36,14 +36,14 @@
class BoneAttachment3D : public Node3D {
GDCLASS(BoneAttachment3D, Node3D);
- bool bound;
+ bool bound = false;
String bone_name;
void _check_bind();
void _check_unbind();
protected:
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 8dc5cd4aba..f0623c625e 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,10 +31,11 @@
#include "camera_3d.h"
#include "collision_object_3d.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
#include "core/math/camera_matrix.h"
#include "scene/resources/material.h"
#include "scene/resources/surface_tool.h"
+
void Camera3D::_update_audio_listener_state() {
}
@@ -208,7 +209,7 @@ void Camera3D::set_projection(Camera3D::Projection p_mode) {
if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL || p_mode == PROJECTION_FRUSTUM) {
mode = p_mode;
_update_camera_mode();
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -318,8 +319,8 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const {
bool Camera3D::is_position_behind(const Vector3 &p_pos) const {
Transform t = get_global_transform();
- Vector3 eyedir = -get_global_transform().basis.get_axis(2).normalized();
- return eyedir.dot(p_pos) < (eyedir.dot(t.origin) + near);
+ Vector3 eyedir = -t.basis.get_axis(2).normalized();
+ return eyedir.dot(p_pos - t.origin) < near;
}
Vector<Vector3> Camera3D::get_near_plane_points() const {
@@ -431,7 +432,7 @@ void Camera3D::set_keep_aspect_mode(KeepAspect p_aspect) {
keep_aspect = p_aspect;
RenderingServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH);
_update_camera_mode();
- _change_notify();
+ notify_property_list_changed();
}
Camera3D::KeepAspect Camera3D::get_keep_aspect_mode() const {
@@ -475,13 +476,13 @@ void Camera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_fov"), &Camera3D::get_fov);
ClassDB::bind_method(D_METHOD("get_frustum_offset"), &Camera3D::get_frustum_offset);
ClassDB::bind_method(D_METHOD("get_size"), &Camera3D::get_size);
- ClassDB::bind_method(D_METHOD("get_zfar"), &Camera3D::get_zfar);
- ClassDB::bind_method(D_METHOD("get_znear"), &Camera3D::get_znear);
+ ClassDB::bind_method(D_METHOD("get_far"), &Camera3D::get_far);
+ ClassDB::bind_method(D_METHOD("get_near"), &Camera3D::get_near);
ClassDB::bind_method(D_METHOD("set_fov"), &Camera3D::set_fov);
ClassDB::bind_method(D_METHOD("set_frustum_offset"), &Camera3D::set_frustum_offset);
ClassDB::bind_method(D_METHOD("set_size"), &Camera3D::set_size);
- ClassDB::bind_method(D_METHOD("set_zfar"), &Camera3D::set_zfar);
- ClassDB::bind_method(D_METHOD("set_znear"), &Camera3D::set_znear);
+ ClassDB::bind_method(D_METHOD("set_far"), &Camera3D::set_far);
+ ClassDB::bind_method(D_METHOD("set_near"), &Camera3D::set_near);
ClassDB::bind_method(D_METHOD("get_projection"), &Camera3D::get_projection);
ClassDB::bind_method(D_METHOD("set_projection"), &Camera3D::set_projection);
ClassDB::bind_method(D_METHOD("set_h_offset", "ofs"), &Camera3D::set_h_offset);
@@ -518,8 +519,8 @@ void Camera3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "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.01,8192,0.01,or_greater"), "set_znear", "get_znear");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_EXP_RANGE, "0.1,8192,0.1,or_greater"), "set_zfar", "get_zfar");
+ 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");
BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE);
BIND_ENUM_CONSTANT(PROJECTION_ORTHOGONAL);
@@ -541,7 +542,7 @@ float Camera3D::get_size() const {
return size;
}
-float Camera3D::get_znear() const {
+float Camera3D::get_near() const {
return near;
}
@@ -549,7 +550,7 @@ Vector2 Camera3D::get_frustum_offset() const {
return frustum_offset;
}
-float Camera3D::get_zfar() const {
+float Camera3D::get_far() const {
return far;
}
@@ -561,18 +562,16 @@ void Camera3D::set_fov(float p_fov) {
ERR_FAIL_COND(p_fov < 1 || p_fov > 179);
fov = p_fov;
_update_camera_mode();
- _change_notify("fov");
}
void Camera3D::set_size(float p_size) {
ERR_FAIL_COND(p_size < 0.1 || p_size > 16384);
size = p_size;
_update_camera_mode();
- _change_notify("size");
}
-void Camera3D::set_znear(float p_znear) {
- near = p_znear;
+void Camera3D::set_near(float p_near) {
+ near = p_near;
_update_camera_mode();
}
@@ -581,8 +580,8 @@ void Camera3D::set_frustum_offset(Vector2 p_offset) {
_update_camera_mode();
}
-void Camera3D::set_zfar(float p_zfar) {
- far = p_zfar;
+void Camera3D::set_far(float p_far) {
+ far = p_far;
_update_camera_mode();
}
@@ -652,24 +651,10 @@ Vector3 Camera3D::get_doppler_tracked_velocity() const {
Camera3D::Camera3D() {
camera = RenderingServer::get_singleton()->camera_create();
- size = 1;
- fov = 0;
- frustum_offset = Vector2();
- near = 0;
- far = 0;
- current = false;
- viewport = nullptr;
- force_change = false;
- mode = PROJECTION_PERSPECTIVE;
- set_perspective(75.0, 0.05, 100.0);
- keep_aspect = KEEP_HEIGHT;
- layers = 0xfffff;
- v_offset = 0;
- h_offset = 0;
+ set_perspective(75.0, 0.05, 4000.0);
RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers);
//active=false;
velocity_tracker.instance();
- doppler_tracking = DOPPLER_TRACKING_DISABLED;
set_notify_transform(true);
set_disable_scale(true);
}
@@ -688,17 +673,17 @@ float ClippedCamera3D::get_margin() const {
return margin;
}
-void ClippedCamera3D::set_process_mode(ProcessMode p_mode) {
- if (process_mode == p_mode) {
+void ClippedCamera3D::set_process_callback(ClipProcessCallback p_mode) {
+ if (process_callback == p_mode) {
return;
}
- process_mode = p_mode;
- set_process_internal(process_mode == CLIP_PROCESS_IDLE);
- set_physics_process_internal(process_mode == CLIP_PROCESS_PHYSICS);
+ process_callback = p_mode;
+ set_process_internal(process_callback == CLIP_PROCESS_IDLE);
+ set_physics_process_internal(process_callback == CLIP_PROCESS_PHYSICS);
}
-ClippedCamera3D::ProcessMode ClippedCamera3D::get_process_mode() const {
- return process_mode;
+ClippedCamera3D::ClipProcessCallback ClippedCamera3D::get_process_callback() const {
+ return process_callback;
}
Transform ClippedCamera3D::get_camera_transform() const {
@@ -754,9 +739,9 @@ void ClippedCamera3D::_notification(int p_what) {
xf.origin = ray_from;
xf.orthonormalize();
- float csafe, cunsafe;
- if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, csafe, cunsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) {
- clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from) * csafe);
+ float closest_safe = 1.0f, closest_unsafe = 1.0f;
+ if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, closest_safe, closest_unsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) {
+ clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from) * closest_safe);
}
_update_camera();
@@ -843,8 +828,8 @@ void ClippedCamera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ClippedCamera3D::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &ClippedCamera3D::get_margin);
- ClassDB::bind_method(D_METHOD("set_process_mode", "process_mode"), &ClippedCamera3D::set_process_mode);
- ClassDB::bind_method(D_METHOD("get_process_mode"), &ClippedCamera3D::get_process_mode);
+ ClassDB::bind_method(D_METHOD("set_process_callback", "process_callback"), &ClippedCamera3D::set_process_callback);
+ ClassDB::bind_method(D_METHOD("get_process_callback"), &ClippedCamera3D::get_process_callback);
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &ClippedCamera3D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &ClippedCamera3D::get_collision_mask);
@@ -869,7 +854,7 @@ void ClippedCamera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_exceptions"), &ClippedCamera3D::clear_exceptions);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_GROUP("Clip To", "clip_to");
@@ -881,16 +866,10 @@ void ClippedCamera3D::_bind_methods() {
}
ClippedCamera3D::ClippedCamera3D() {
- margin = 0;
- clip_offset = 0;
- process_mode = CLIP_PROCESS_PHYSICS;
set_physics_process_internal(true);
- collision_mask = 1;
set_notify_local_transform(Engine::get_singleton()->is_editor_hint());
points.resize(5);
pyramid_shape = PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONVEX_POLYGON);
- clip_to_areas = false;
- clip_to_bodies = true;
}
ClippedCamera3D::~ClippedCamera3D() {
diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h
index 138b1b8a7a..cea61e4db8 100644
--- a/scene/3d/camera_3d.h
+++ b/scene/3d/camera_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -34,6 +34,7 @@
#include "scene/3d/node_3d.h"
#include "scene/3d/velocity_tracker_3d.h"
#include "scene/main/window.h"
+#include "scene/resources/camera_effects.h"
#include "scene/resources/environment.h"
class Camera3D : public Node3D {
@@ -41,7 +42,6 @@ class Camera3D : public Node3D {
public:
enum Projection {
-
PROJECTION_PERSPECTIVE,
PROJECTION_ORTHOGONAL,
PROJECTION_FRUSTUM
@@ -57,26 +57,27 @@ public:
};
private:
- bool force_change;
- bool current;
- Viewport *viewport;
+ bool force_change = false;
+ bool current = false;
+ Viewport *viewport = nullptr;
- Projection mode;
+ Projection mode = PROJECTION_PERSPECTIVE;
- float fov;
- float size;
+ float fov = 0.0;
+ float size = 1.0;
Vector2 frustum_offset;
- float near, far;
- float v_offset;
- float h_offset;
- KeepAspect keep_aspect;
+ float near = 0.0;
+ float far = 0.0;
+ float v_offset = 0.0;
+ float h_offset = 0.0;
+ KeepAspect keep_aspect = KEEP_HEIGHT;
RID camera;
RID scenario_id;
// String camera_group;
- uint32_t layers;
+ uint32_t layers = 0xfffff;
Ref<Environment> environment;
Ref<CameraEffects> effects;
@@ -87,7 +88,7 @@ private:
friend class Viewport;
void _update_audio_listener_state();
- DopplerTracking doppler_tracking;
+ DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED;
Ref<VelocityTracker3D> velocity_tracker;
protected:
@@ -96,13 +97,12 @@ protected:
void _update_camera_mode();
void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &p_property) const;
+ virtual void _validate_property(PropertyInfo &p_property) const override;
static void _bind_methods();
public:
enum {
-
NOTIFICATION_BECAME_CURRENT = 50,
NOTIFICATION_LOST_CURRENT = 51
};
@@ -122,16 +122,16 @@ public:
float get_fov() const;
float get_size() const;
- float get_zfar() const;
- float get_znear() const;
+ float get_far() const;
+ float get_near() const;
Vector2 get_frustum_offset() const;
Projection get_projection() const;
void set_fov(float p_fov);
void set_size(float p_size);
- void set_zfar(float p_zfar);
- void set_znear(float p_znear);
+ void set_far(float p_far);
+ void set_near(float p_near);
void set_frustum_offset(Vector2 p_offset);
virtual Transform get_camera_transform() const;
@@ -186,19 +186,19 @@ class ClippedCamera3D : public Camera3D {
GDCLASS(ClippedCamera3D, Camera3D);
public:
- enum ProcessMode {
+ enum ClipProcessCallback {
CLIP_PROCESS_PHYSICS,
CLIP_PROCESS_IDLE,
};
private:
- ProcessMode process_mode;
+ ClipProcessCallback process_callback = CLIP_PROCESS_PHYSICS;
RID pyramid_shape;
- float margin;
- float clip_offset;
- uint32_t collision_mask;
- bool clip_to_areas;
- bool clip_to_bodies;
+ float margin = 0.0;
+ float clip_offset = 0.0;
+ uint32_t collision_mask = 1;
+ bool clip_to_areas = false;
+ bool clip_to_bodies = true;
Set<RID> exclude;
@@ -207,7 +207,7 @@ private:
protected:
void _notification(int p_what);
static void _bind_methods();
- virtual Transform get_camera_transform() const;
+ virtual Transform get_camera_transform() const override;
public:
void set_clip_to_areas(bool p_clip);
@@ -219,8 +219,8 @@ public:
void set_margin(float p_margin);
float get_margin() const;
- void set_process_mode(ProcessMode p_mode);
- ProcessMode get_process_mode() const;
+ void set_process_callback(ClipProcessCallback p_mode);
+ ClipProcessCallback get_process_callback() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
@@ -240,5 +240,5 @@ public:
~ClippedCamera3D();
};
-VARIANT_ENUM_CAST(ClippedCamera3D::ProcessMode);
+VARIANT_ENUM_CAST(ClippedCamera3D::ClipProcessCallback);
#endif
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index 356992e922..849ef7a2bf 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,6 +30,7 @@
#include "collision_object_3d.h"
+#include "mesh_instance_3d.h"
#include "scene/scene_string_names.h"
#include "servers/physics_server_3d.h"
@@ -110,6 +111,42 @@ void CollisionObject3D::_update_pickable() {
}
}
+void CollisionObject3D::_update_debug_shapes() {
+ for (Set<uint32_t>::Element *shapedata_idx = debug_shapes_to_update.front(); shapedata_idx; shapedata_idx = shapedata_idx->next()) {
+ if (shapes.has(shapedata_idx->get())) {
+ ShapeData &shapedata = shapes[shapedata_idx->get()];
+ for (int i = 0; i < shapedata.shapes.size(); i++) {
+ ShapeData::ShapeBase &s = shapedata.shapes.write[i];
+ if (s.debug_shape) {
+ s.debug_shape->queue_delete();
+ s.debug_shape = nullptr;
+ }
+ if (s.shape.is_null() || shapedata.disabled) {
+ continue;
+ }
+
+ Ref<Mesh> mesh = s.shape->get_debug_mesh();
+ MeshInstance3D *mi = memnew(MeshInstance3D);
+ mi->set_transform(shapedata.xform);
+ mi->set_mesh(mesh);
+ add_child(mi);
+ mi->force_update_transform();
+ s.debug_shape = mi;
+ }
+ }
+ }
+ debug_shapes_to_update.clear();
+}
+
+void CollisionObject3D::_update_shape_data(uint32_t p_owner) {
+ if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
+ if (debug_shapes_to_update.is_empty()) {
+ call_deferred("_update_debug_shapes");
+ }
+ debug_shapes_to_update.insert(p_owner);
+ }
+}
+
void CollisionObject3D::set_ray_pickable(bool p_ray_pickable) {
ray_pickable = p_ray_pickable;
_update_pickable();
@@ -141,6 +178,8 @@ void CollisionObject3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject3D::shape_owner_clear_shapes);
ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject3D::shape_find_owner);
+ ClassDB::bind_method(D_METHOD("_update_debug_shapes"), &CollisionObject3D::_update_debug_shapes);
+
BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
@@ -188,6 +227,7 @@ void CollisionObject3D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabl
PhysicsServer3D::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);
}
}
+ _update_shape_data(p_owner);
}
bool CollisionObject3D::is_shape_owner_disabled(uint32_t p_owner) const {
@@ -223,6 +263,8 @@ void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transf
PhysicsServer3D::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform);
}
}
+
+ _update_shape_data(p_owner);
}
Transform CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const {
@@ -245,6 +287,7 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3
ShapeData::ShapeBase s;
s.index = total_subshapes;
s.shape = p_shape;
+
if (area) {
PhysicsServer3D::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled);
} else {
@@ -253,6 +296,8 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3
sd.shapes.push_back(s);
total_subshapes++;
+
+ _update_shape_data(p_owner);
}
int CollisionObject3D::shape_owner_get_shape_count(uint32_t p_owner) const {
@@ -279,13 +324,19 @@ void CollisionObject3D::shape_owner_remove_shape(uint32_t p_owner, int p_shape)
ERR_FAIL_COND(!shapes.has(p_owner));
ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());
- int index_to_remove = shapes[p_owner].shapes[p_shape].index;
+ const ShapeData::ShapeBase &s = shapes[p_owner].shapes[p_shape];
+ int index_to_remove = s.index;
+
if (area) {
PhysicsServer3D::get_singleton()->area_remove_shape(rid, index_to_remove);
} else {
PhysicsServer3D::get_singleton()->body_remove_shape(rid, index_to_remove);
}
+ if (s.debug_shape) {
+ s.debug_shape->queue_delete();
+ }
+
shapes[p_owner].shapes.remove(p_shape);
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
@@ -325,10 +376,7 @@ uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const {
CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) {
rid = p_rid;
area = p_area;
- capture_input_on_drag = false;
- ray_pickable = true;
set_notify_transform(true);
- total_subshapes = 0;
if (p_area) {
PhysicsServer3D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id());
@@ -349,8 +397,8 @@ bool CollisionObject3D::get_capture_input_on_drag() const {
String CollisionObject3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
- if (shapes.empty()) {
- if (!warning.empty()) {
+ if (shapes.is_empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape3D or CollisionPolygon3D as a child to define its shape.");
@@ -360,8 +408,6 @@ String CollisionObject3D::get_configuration_warning() const {
}
CollisionObject3D::CollisionObject3D() {
- capture_input_on_drag = false;
- ray_pickable = true;
set_notify_transform(true);
//owner=
diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h
index 8bcbef0e98..fe20176984 100644
--- a/scene/3d/collision_object_3d.h
+++ b/scene/3d/collision_object_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -37,36 +37,36 @@
class CollisionObject3D : public Node3D {
GDCLASS(CollisionObject3D, Node3D);
- bool area;
+ bool area = false;
RID rid;
struct ShapeData {
- Object *owner;
+ Object *owner = nullptr;
Transform xform;
struct ShapeBase {
+ Node *debug_shape = nullptr;
Ref<Shape3D> shape;
- int index;
+ int index = 0;
};
Vector<ShapeBase> shapes;
- bool disabled;
-
- ShapeData() {
- disabled = false;
- owner = nullptr;
- }
+ bool disabled = false;
};
- int total_subshapes;
+ int total_subshapes = 0;
Map<uint32_t, ShapeData> shapes;
- bool capture_input_on_drag;
- bool ray_pickable;
+ bool capture_input_on_drag = false;
+ bool ray_pickable = true;
+
+ Set<uint32_t> debug_shapes_to_update;
void _update_pickable();
+ void _update_shape_data(uint32_t p_owner);
+
protected:
CollisionObject3D(RID p_rid, bool p_area);
@@ -77,6 +77,8 @@ protected:
virtual void _mouse_enter();
virtual void _mouse_exit();
+ void _update_debug_shapes();
+
public:
uint32_t create_shape_owner(Object *p_owner);
void remove_shape_owner(uint32_t owner);
@@ -108,7 +110,7 @@ public:
_FORCE_INLINE_ RID get_rid() const { return rid; }
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
CollisionObject3D();
~CollisionObject3D();
diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp
index bad4a1fddd..e3e2eb4669 100644
--- a/scene/3d/collision_polygon_3d.cpp
+++ b/scene/3d/collision_polygon_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,6 +31,7 @@
#include "collision_polygon_3d.h"
#include "collision_object_3d.h"
+#include "core/math/geometry_2d.h"
#include "scene/resources/concave_polygon_shape_3d.h"
#include "scene/resources/convex_polygon_shape_3d.h"
@@ -45,7 +46,7 @@ void CollisionPolygon3D::_build_polygon() {
return;
}
- Vector<Vector<Vector2>> decomp = Geometry::decompose_polygon_in_convex(polygon);
+ Vector<Vector<Vector2>> decomp = Geometry2D::decompose_polygon_in_convex(polygon);
if (decomp.size() == 0) {
return;
}
@@ -69,6 +70,7 @@ void CollisionPolygon3D::_build_polygon() {
}
convex->set_points(cp);
+ convex->set_margin(margin);
parent->shape_owner_add_shape(owner_id, convex);
parent->shape_owner_set_disabled(owner_id, disabled);
}
@@ -131,13 +133,13 @@ AABB CollisionPolygon3D::get_item_rect() const {
return aabb;
}
-void CollisionPolygon3D::set_depth(float p_depth) {
+void CollisionPolygon3D::set_depth(real_t p_depth) {
depth = p_depth;
_build_polygon();
update_gizmo();
}
-float CollisionPolygon3D::get_depth() const {
+real_t CollisionPolygon3D::get_depth() const {
return depth;
}
@@ -154,16 +156,35 @@ bool CollisionPolygon3D::is_disabled() const {
return disabled;
}
+real_t CollisionPolygon3D::get_margin() const {
+ return margin;
+}
+
+void CollisionPolygon3D::set_margin(real_t p_margin) {
+ margin = p_margin;
+ if (parent) {
+ _build_polygon();
+ }
+}
+
String CollisionPolygon3D::get_configuration_warning() const {
+ String warning = Node3D::get_configuration_warning();
+
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
- return TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
}
- if (polygon.empty()) {
- return TTR("An empty CollisionPolygon3D has no effect on collision.");
+ if (polygon.is_empty()) {
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("An empty CollisionPolygon3D has no effect on collision.");
}
- return String();
+ return warning;
}
bool CollisionPolygon3D::_is_editable_3d_polygon() const {
@@ -180,18 +201,17 @@ void CollisionPolygon3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &CollisionPolygon3D::set_disabled);
ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionPolygon3D::is_disabled);
+ ClassDB::bind_method(D_METHOD("set_margin", "margin"), &CollisionPolygon3D::set_margin);
+ ClassDB::bind_method(D_METHOD("get_margin"), &CollisionPolygon3D::get_margin);
+
ClassDB::bind_method(D_METHOD("_is_editable_3d_polygon"), &CollisionPolygon3D::_is_editable_3d_polygon);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth"), "set_depth", "get_depth");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin");
}
CollisionPolygon3D::CollisionPolygon3D() {
- aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
- depth = 1.0;
set_notify_local_transform(true);
- parent = nullptr;
- owner_id = 0;
- disabled = false;
}
diff --git a/scene/3d/collision_polygon_3d.h b/scene/3d/collision_polygon_3d.h
index 0cd9aee111..750751b509 100644
--- a/scene/3d/collision_polygon_3d.h
+++ b/scene/3d/collision_polygon_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -37,16 +37,17 @@
class CollisionObject3D;
class CollisionPolygon3D : public Node3D {
GDCLASS(CollisionPolygon3D, Node3D);
+ real_t margin = 0.04;
protected:
- float depth;
- AABB aabb;
+ real_t depth = 1.0;
+ AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
Vector<Point2> polygon;
- uint32_t owner_id;
- CollisionObject3D *parent;
+ uint32_t owner_id = 0;
+ CollisionObject3D *parent = nullptr;
- bool disabled;
+ bool disabled = false;
void _build_polygon();
@@ -59,8 +60,8 @@ protected:
static void _bind_methods();
public:
- void set_depth(float p_depth);
- float get_depth() const;
+ void set_depth(real_t p_depth);
+ real_t get_depth() const;
void set_polygon(const Vector<Point2> &p_polygon);
Vector<Point2> get_polygon() const;
@@ -70,7 +71,10 @@ public:
virtual AABB get_item_rect() const;
- String get_configuration_warning() const;
+ real_t get_margin() const;
+ void set_margin(real_t p_margin);
+
+ String get_configuration_warning() const override;
CollisionPolygon3D();
};
diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp
index 56367e9bdd..242d82ab4c 100644
--- a/scene/3d/collision_shape_3d.cpp
+++ b/scene/3d/collision_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -44,23 +44,36 @@
//TODO: Implement CylinderShape and HeightMapShape?
-void CollisionShape3D::make_convex_from_brothers() {
+void CollisionShape3D::make_convex_from_siblings() {
Node *p = get_parent();
if (!p) {
return;
}
+ Vector<Vector3> vertices;
+
for (int i = 0; i < p->get_child_count(); i++) {
Node *n = p->get_child(i);
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(n);
if (mi) {
Ref<Mesh> m = mi->get_mesh();
if (m.is_valid()) {
- Ref<Shape3D> s = m->create_convex_shape();
- set_shape(s);
+ for (int j = 0; j < m->get_surface_count(); j++) {
+ Array a = m->surface_get_arrays(j);
+ if (!a.is_empty()) {
+ Vector<Vector3> v = a[RenderingServer::ARRAY_VERTEX];
+ for (int k = 0; k < v.size(); k++) {
+ vertices.append(mi->get_transform().xform(v[k]));
+ }
+ }
+ }
}
}
}
+
+ Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D);
+ shape->set_points(vertices);
+ set_shape(shape);
}
void CollisionShape3D::_update_in_shape_owner(bool p_xform_only) {
@@ -87,9 +100,6 @@ void CollisionShape3D::_notification(int p_what) {
if (parent) {
_update_in_shape_owner();
}
- if (get_tree()->is_debugging_collisions_hint()) {
- _update_debug_shape();
- }
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
if (parent) {
@@ -111,23 +121,33 @@ void CollisionShape3D::resource_changed(RES res) {
}
String CollisionShape3D::get_configuration_warning() const {
+ String warning = Node3D::get_configuration_warning();
+
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
- return TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
}
if (!shape.is_valid()) {
- return TTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it.");
}
- if (Object::cast_to<RigidBody3D>(get_parent())) {
- if (Object::cast_to<ConcavePolygonShape3D>(*shape)) {
- if (Object::cast_to<RigidBody3D>(get_parent())->get_mode() != RigidBody3D::MODE_STATIC) {
- return TTR("ConcavePolygonShape3D doesn't support RigidBody3D in another mode than static.");
- }
+ if (shape.is_valid() &&
+ Object::cast_to<RigidBody3D>(get_parent()) &&
+ Object::cast_to<ConcavePolygonShape3D>(*shape) &&
+ Object::cast_to<RigidBody3D>(get_parent())->get_mode() != RigidBody3D::MODE_STATIC) {
+ if (!warning.is_empty()) {
+ warning += "\n\n";
}
+ warning += TTR("ConcavePolygonShape3D doesn't support RigidBody3D in another mode than static.");
}
- return String();
+ return warning;
}
void CollisionShape3D::_bind_methods() {
@@ -137,16 +157,17 @@ void CollisionShape3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_shape"), &CollisionShape3D::get_shape);
ClassDB::bind_method(D_METHOD("set_disabled", "enable"), &CollisionShape3D::set_disabled);
ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionShape3D::is_disabled);
- ClassDB::bind_method(D_METHOD("make_convex_from_brothers"), &CollisionShape3D::make_convex_from_brothers);
- ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_brothers", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
- ClassDB::bind_method(D_METHOD("_update_debug_shape"), &CollisionShape3D::_update_debug_shape);
+ ClassDB::bind_method(D_METHOD("make_convex_from_siblings"), &CollisionShape3D::make_convex_from_siblings);
+ ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_siblings", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
}
void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) {
+ if (p_shape == shape) {
+ return;
+ }
if (!shape.is_null()) {
shape->unregister_owner(this);
shape->disconnect("changed", callable_mp(this, &CollisionShape3D::_shape_changed));
@@ -188,10 +209,6 @@ bool CollisionShape3D::is_disabled() const {
CollisionShape3D::CollisionShape3D() {
//indicator = RenderingServer::get_singleton()->mesh_create();
- disabled = false;
- debug_shape = nullptr;
- parent = nullptr;
- owner_id = 0;
set_notify_local_transform(true);
}
@@ -202,34 +219,9 @@ CollisionShape3D::~CollisionShape3D() {
//RenderingServer::get_singleton()->free(indicator);
}
-void CollisionShape3D::_update_debug_shape() {
- debug_shape_dirty = false;
-
- if (debug_shape) {
- debug_shape->queue_delete();
- debug_shape = nullptr;
- }
-
- Ref<Shape3D> s = get_shape();
- if (s.is_null()) {
- return;
- }
-
- Ref<Mesh> mesh = s->get_debug_mesh();
- MeshInstance3D *mi = memnew(MeshInstance3D);
- mi->set_mesh(mesh);
- add_child(mi);
- debug_shape = mi;
-}
-
void CollisionShape3D::_shape_changed() {
// If this is a heightfield shape our center may have changed
if (parent) {
_update_in_shape_owner(true);
}
-
- if (is_inside_tree() && get_tree()->is_debugging_collisions_hint() && !debug_shape_dirty) {
- debug_shape_dirty = true;
- call_deferred("_update_debug_shape");
- }
}
diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h
index 4ed2f4007b..5512417f75 100644
--- a/scene/3d/collision_shape_3d.h
+++ b/scene/3d/collision_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -40,17 +40,13 @@ class CollisionShape3D : public Node3D {
Ref<Shape3D> shape;
- uint32_t owner_id;
- CollisionObject3D *parent;
-
- Node *debug_shape;
- bool debug_shape_dirty;
+ uint32_t owner_id = 0;
+ CollisionObject3D *parent = nullptr;
void resource_changed(RES res);
- bool disabled;
+ bool disabled = false;
protected:
- void _update_debug_shape();
void _shape_changed();
void _update_in_shape_owner(bool p_xform_only = false);
@@ -60,7 +56,7 @@ protected:
static void _bind_methods();
public:
- void make_convex_from_brothers();
+ void make_convex_from_siblings();
void set_shape(const Ref<Shape3D> &p_shape);
Ref<Shape3D> get_shape() const;
@@ -68,7 +64,7 @@ public:
void set_disabled(bool p_disabled);
bool is_disabled() const;
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
CollisionShape3D();
~CollisionShape3D();
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 4244a11592..d22d7ff3ab 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -39,7 +39,7 @@ AABB CPUParticles3D::get_aabb() const {
return AABB();
}
-Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_flags) const {
+Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_particle_flags) const {
return Vector<Face3>();
}
@@ -73,7 +73,7 @@ void CPUParticles3D::set_amount(int p_amount) {
}
particle_data.resize((12 + 4 + 4) * p_amount);
- RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, true, true);
+ RS::get_singleton()->multimesh_allocate_data(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, true, true);
particle_order.resize(p_amount);
}
@@ -152,6 +152,7 @@ float CPUParticles3D::get_speed_scale() const {
}
void CPUParticles3D::set_draw_order(DrawOrder p_order) {
+ ERR_FAIL_INDEX(p_order, DRAW_ORDER_MAX);
draw_order = p_order;
}
@@ -189,7 +190,7 @@ bool CPUParticles3D::get_fractional_delta() const {
}
String CPUParticles3D::get_configuration_warning() const {
- String warnings;
+ String warnings = GeometryInstance3D::get_configuration_warning();
bool mesh_found = false;
bool anim_material_found = false;
@@ -368,17 +369,17 @@ Ref<Gradient> CPUParticles3D::get_color_ramp() const {
return color_ramp;
}
-void CPUParticles3D::set_particle_flag(Flags p_flag, bool p_enable) {
- ERR_FAIL_INDEX(p_flag, FLAG_MAX);
- flags[p_flag] = p_enable;
- if (p_flag == FLAG_DISABLE_Z) {
- _change_notify();
+void CPUParticles3D::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) {
+ ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX);
+ particle_flags[p_particle_flag] = p_enable;
+ if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) {
+ notify_property_list_changed();
}
}
-bool CPUParticles3D::get_particle_flag(Flags p_flag) const {
- ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
- return flags[p_flag];
+bool CPUParticles3D::get_particle_flag(ParticleFlags p_particle_flag) const {
+ ERR_FAIL_INDEX_V(p_particle_flag, PARTICLE_FLAG_MAX, false);
+ return particle_flags[p_particle_flag];
}
void CPUParticles3D::set_emission_shape(EmissionShape p_shape) {
@@ -459,7 +460,7 @@ void CPUParticles3D::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) {
+ if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
property.usage = 0;
}
}
@@ -575,7 +576,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
cycle++;
if (one_shot && cycle > 0) {
set_emitting(false);
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -646,6 +647,8 @@ void CPUParticles3D::_particles_process(float p_delta) {
restart = true;
}
+ float tv = 0.0;
+
if (restart) {
if (!emitting) {
p.active = false;
@@ -660,12 +663,12 @@ void CPUParticles3D::_particles_process(float p_delta) {
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
p.seed = Math::rand();
@@ -675,14 +678,14 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.hue_rot_rand = Math::randf();
p.anim_offset_rand = Math::randf();
- if (flags[FLAG_DISABLE_Z]) {
- float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0;
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
+ float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0);
p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
} else {
//initiate velocity spread in 3D
- float angle1_rad = Math::atan2(direction.x, direction.z) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0;
- float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0;
+ float angle1_rad = Math::atan2(direction.x, direction.z) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
+ float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * spread);
Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad));
Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad));
@@ -706,8 +709,9 @@ void CPUParticles3D::_particles_process(float p_delta) {
//do none
} break;
case EMISSION_SHAPE_SPHERE: {
- float s = 2.0 * Math::randf() - 1.0, t = 2.0 * Math_PI * Math::randf();
- float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
+ real_t s = 2.0 * Math::randf() - 1.0;
+ real_t t = Math_TAU * Math::randf();
+ real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s);
} break;
case EMISSION_SHAPE_BOX: {
@@ -725,14 +729,16 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.transform.origin = emission_points.get(random_idx);
if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS && emission_normals.size() == pc) {
- if (flags[FLAG_DISABLE_Z]) {
- /*
- mat2 rotm;
- ";
- rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;
- rotm[1] = rotm[0].yx * vec2(1.0, -1.0);
- VELOCITY.xy = rotm * VELOCITY.xy;
- */
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
+ Vector3 normal = emission_normals.get(random_idx);
+ Vector2 normal_2d(normal.x, normal.y);
+ Transform2D m2;
+ m2.set_axis(0, normal_2d);
+ m2.set_axis(1, normal_2d.orthogonal());
+ Vector2 velocity_2d(p.velocity.x, p.velocity.y);
+ velocity_2d = m2.basis_xform(velocity_2d);
+ p.velocity.x = velocity_2d.x;
+ p.velocity.y = velocity_2d.y;
} else {
Vector3 normal = emission_normals.get(random_idx);
Vector3 v0 = Math::abs(normal.z) < 0.999 ? Vector3(0.0, 0.0, 1.0) : Vector3(0, 1.0, 0.0);
@@ -760,7 +766,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.transform = emission_xform * p.transform;
}
- if (flags[FLAG_DISABLE_Z]) {
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
p.velocity.z = 0.0;
p.transform.origin.z = 0.0;
}
@@ -769,66 +775,68 @@ void CPUParticles3D::_particles_process(float p_delta) {
continue;
} else if (p.time > p.lifetime) {
p.active = false;
+ tv = 1.0;
} else {
uint32_t alt_seed = p.seed;
p.time += local_delta;
p.custom[1] = p.time / lifetime;
+ tv = p.time / p.lifetime;
float tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
float tex_orbit_velocity = 0.0;
- if (flags[FLAG_DISABLE_Z]) {
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
- tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]);
+ tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
}
float tex_angular_velocity = 0.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
- tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
float tex_linear_accel = 0.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
- tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]);
+ tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
float tex_tangential_accel = 0.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
- tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
float tex_radial_accel = 0.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
- tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
float tex_damping = 0.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
- tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]);
+ tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_speed = 0.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
- tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]);
+ tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]);
+ tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
Vector3 force = gravity;
Vector3 position = p.transform.origin;
- if (flags[FLAG_DISABLE_Z]) {
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
position.z = 0.0;
}
//apply linear acceleration
@@ -838,7 +846,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
Vector3 diff = position - org;
force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3();
//apply tangential acceleration;
- if (flags[FLAG_DISABLE_Z]) {
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
Vector2 yx = Vector2(diff.y, diff.x);
Vector2 yx2 = (yx * Vector2(-1.0, 1.0)).normalized();
force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3();
@@ -850,10 +858,10 @@ void CPUParticles3D::_particles_process(float p_delta) {
//apply attractor forces
p.velocity += force * local_delta;
//orbit velocity
- if (flags[FLAG_DISABLE_Z]) {
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]);
if (orbit_amount != 0.0) {
- float ang = orbit_amount * local_delta * Math_PI * 2.0;
+ float ang = orbit_amount * local_delta * Math_TAU;
// Not sure why the ParticlesMaterial code uses a clockwise rotation matrix,
// but we use -ang here to reproduce its behavior.
Transform2D rot = Transform2D(-ang, Vector2());
@@ -885,15 +893,15 @@ void CPUParticles3D::_particles_process(float p_delta) {
float tex_scale = 1.0;
if (curve_parameters[PARAM_SCALE].is_valid()) {
- tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]);
+ tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
}
float tex_hue_variation = 0.0;
if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
- tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]);
+ tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}
- float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
+ float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
float hue_rot_c = Math::cos(hue_rot_angle);
float hue_rot_s = Math::sin(hue_rot_angle);
@@ -909,7 +917,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
}
if (color_ramp.is_valid()) {
- p.color = color_ramp->get_color_at_offset(p.custom[1]) * color;
+ p.color = color_ramp->get_color_at_offset(tv) * color;
} else {
p.color = color;
}
@@ -921,8 +929,8 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.color *= p.base_color;
- if (flags[FLAG_DISABLE_Z]) {
- if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
+ if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) {
if (p.velocity.length() > 0.0) {
p.transform.basis.set_axis(1, p.velocity.normalized());
} else {
@@ -939,7 +947,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
} else {
//orient particle Y towards velocity
- if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
+ if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) {
if (p.velocity.length() > 0.0) {
p.transform.basis.set_axis(1, p.velocity.normalized());
} else {
@@ -957,7 +965,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
}
//turn particle by rotation in Y
- if (flags[FLAG_ROTATE_Y]) {
+ if (particle_flags[PARTICLE_FLAG_ROTATE_Y]) {
Basis rot_y(Vector3(0, 1, 0), p.custom[0]);
p.transform.basis = p.transform.basis * rot_y;
}
@@ -971,7 +979,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.transform.basis.scale(Vector3(1, 1, 1) * base_scale);
- if (flags[FLAG_DISABLE_Z]) {
+ if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
p.velocity.z = 0.0;
p.transform.origin.z = 0.0;
}
@@ -1004,6 +1012,7 @@ void CPUParticles3D::_update_particle_data_buffer() {
sorter.compare.particles = r;
sorter.sort(order, pc);
} else if (draw_order == DRAW_ORDER_VIEW_DEPTH) {
+ ERR_FAIL_NULL(get_viewport());
Camera3D *c = get_viewport()->get_camera();
if (c) {
Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close
@@ -1065,7 +1074,7 @@ void CPUParticles3D::_update_particle_data_buffer() {
ptr += 20;
}
- can_update = true;
+ can_update.set();
}
void CPUParticles3D::_set_redraw(bool p_redraw) {
@@ -1094,9 +1103,9 @@ void CPUParticles3D::_set_redraw(bool p_redraw) {
void CPUParticles3D::_update_render_thread() {
MutexLock lock(update_mutex);
- if (can_update) {
+ if (can_update.is_set()) {
RS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
- can_update = false; //wait for next time
+ can_update.clear(); //wait for next time
}
}
@@ -1158,7 +1167,7 @@ void CPUParticles3D::_notification(int p_what) {
ptr += 20;
}
- can_update = true;
+ can_update.set();
}
}
}
@@ -1197,9 +1206,9 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) {
set_color_ramp(gt->get_gradient());
}
- set_particle_flag(FLAG_ALIGN_Y_TO_VELOCITY, material->get_flag(ParticlesMaterial::FLAG_ALIGN_Y_TO_VELOCITY));
- set_particle_flag(FLAG_ROTATE_Y, material->get_flag(ParticlesMaterial::FLAG_ROTATE_Y));
- set_particle_flag(FLAG_DISABLE_Z, material->get_flag(ParticlesMaterial::FLAG_DISABLE_Z));
+ set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY));
+ set_particle_flag(PARTICLE_FLAG_ROTATE_Y, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ROTATE_Y));
+ set_particle_flag(PARTICLE_FLAG_DISABLE_Z, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z));
set_emission_shape(EmissionShape(material->get_emission_shape()));
set_emission_sphere_radius(material->get_emission_sphere_radius());
@@ -1316,8 +1325,8 @@ void CPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &CPUParticles3D::set_color_ramp);
ClassDB::bind_method(D_METHOD("get_color_ramp"), &CPUParticles3D::get_color_ramp);
- ClassDB::bind_method(D_METHOD("set_particle_flag", "flag", "enable"), &CPUParticles3D::set_particle_flag);
- ClassDB::bind_method(D_METHOD("get_particle_flag", "flag"), &CPUParticles3D::get_particle_flag);
+ ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &CPUParticles3D::set_particle_flag);
+ ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &CPUParticles3D::get_particle_flag);
ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &CPUParticles3D::set_emission_shape);
ClassDB::bind_method(D_METHOD("get_emission_shape"), &CPUParticles3D::get_emission_shape);
@@ -1343,16 +1352,16 @@ void CPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles3D::convert_from_particles);
ADD_GROUP("Emission Shape", "emission_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors");
- ADD_GROUP("Flags", "flag_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_particle_flag", "get_particle_flag", FLAG_ROTATE_Y);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_particle_flag", "get_particle_flag", FLAG_DISABLE_Z);
+ ADD_GROUP("Particle Flags", "particle_flag_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_disable_z"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_DISABLE_Z);
ADD_GROUP("Direction", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread");
@@ -1424,10 +1433,10 @@ void CPUParticles3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_ANIM_OFFSET);
BIND_ENUM_CONSTANT(PARAM_MAX);
- BIND_ENUM_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY);
- BIND_ENUM_CONSTANT(FLAG_ROTATE_Y);
- BIND_ENUM_CONSTANT(FLAG_DISABLE_Z);
- BIND_ENUM_CONSTANT(FLAG_MAX);
+ BIND_ENUM_CONSTANT(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY);
+ BIND_ENUM_CONSTANT(PARTICLE_FLAG_ROTATE_Y);
+ BIND_ENUM_CONSTANT(PARTICLE_FLAG_DISABLE_Z);
+ BIND_ENUM_CONSTANT(PARTICLE_FLAG_MAX);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE);
@@ -1438,13 +1447,6 @@ void CPUParticles3D::_bind_methods() {
}
CPUParticles3D::CPUParticles3D() {
- time = 0;
- inactive_time = 0;
- frame_remainder = 0;
- cycle = 0;
- redraw = false;
- emitting = false;
-
set_notify_transform(true);
multimesh = RenderingServer::get_singleton()->multimesh_create();
@@ -1452,23 +1454,8 @@ CPUParticles3D::CPUParticles3D() {
set_base(multimesh);
set_emitting(true);
- set_one_shot(false);
set_amount(8);
- set_lifetime(1);
- set_fixed_fps(0);
- set_fractional_delta(true);
- set_pre_process_time(0);
- set_explosiveness_ratio(0);
- set_randomness_ratio(0);
- set_lifetime_randomness(0);
- set_use_local_coordinates(true);
-
- set_draw_order(DRAW_ORDER_INDEX);
- set_speed_scale(1);
-
- set_direction(Vector3(1, 0, 0));
- set_spread(45);
- set_flatness(0);
+
set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0);
set_param(PARAM_ANGULAR_VELOCITY, 0);
set_param(PARAM_ORBIT_VELOCITY, 0);
@@ -1491,12 +1478,10 @@ CPUParticles3D::CPUParticles3D() {
set_param_randomness(Parameter(i), 0);
}
- for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = false;
+ for (int i = 0; i < PARTICLE_FLAG_MAX; i++) {
+ particle_flags[i] = false;
}
- can_update = false;
-
set_color(Color(1, 1, 1, 1));
}
diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h
index 2afb6846c0..10ac32622d 100644
--- a/scene/3d/cpu_particles_3d.h
+++ b/scene/3d/cpu_particles_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,7 +31,8 @@
#ifndef CPU_PARTICLES_H
#define CPU_PARTICLES_H
-#include "core/rid.h"
+#include "core/templates/rid.h"
+#include "core/templates/safe_refcount.h"
#include "scene/3d/visual_instance_3d.h"
class CPUParticles3D : public GeometryInstance3D {
@@ -43,10 +44,10 @@ public:
DRAW_ORDER_INDEX,
DRAW_ORDER_LIFETIME,
DRAW_ORDER_VIEW_DEPTH,
+ DRAW_ORDER_MAX
};
enum Parameter {
-
PARAM_INITIAL_LINEAR_VELOCITY,
PARAM_ANGULAR_VELOCITY,
PARAM_ORBIT_VELOCITY,
@@ -62,11 +63,11 @@ public:
PARAM_MAX
};
- enum Flags {
- FLAG_ALIGN_Y_TO_VELOCITY,
- FLAG_ROTATE_Y,
- FLAG_DISABLE_Z,
- FLAG_MAX
+ enum ParticleFlags {
+ PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY,
+ PARTICLE_FLAG_ROTATE_Y,
+ PARTICLE_FLAG_DISABLE_Z,
+ PARTICLE_FLAG_MAX
};
enum EmissionShape {
@@ -79,30 +80,30 @@ public:
};
private:
- bool emitting;
+ bool emitting = false;
struct Particle {
Transform transform;
Color color;
- float custom[4];
+ float custom[4] = {};
Vector3 velocity;
- bool active;
- float angle_rand;
- float scale_rand;
- float hue_rot_rand;
- float anim_offset_rand;
- float time;
- float lifetime;
+ bool active = false;
+ float angle_rand = 0.0;
+ float scale_rand = 0.0;
+ float hue_rot_rand = 0.0;
+ float anim_offset_rand = 0.0;
+ float time = 0.0;
+ float lifetime = 0.0;
Color base_color;
- uint32_t seed;
+ uint32_t seed = 0;
};
- float time;
- float inactive_time;
- float frame_remainder;
- int cycle;
- bool redraw;
+ float time = 0.0;
+ float inactive_time = 0.0;
+ float frame_remainder = 0.0;
+ int cycle = 0;
+ bool redraw = false;
RID multimesh;
@@ -111,7 +112,7 @@ private:
Vector<int> particle_order;
struct SortLifetime {
- const Particle *particles;
+ const Particle *particles = nullptr;
bool operator()(int p_a, int p_b) const {
return particles[p_a].time > particles[p_b].time;
@@ -119,7 +120,7 @@ private:
};
struct SortAxis {
- const Particle *particles;
+ const Particle *particles = nullptr;
Vector3 axis;
bool operator()(int p_a, int p_b) const {
return axis.dot(particles[p_a].transform.origin) < axis.dot(particles[p_b].transform.origin);
@@ -128,50 +129,50 @@ private:
//
- bool one_shot;
+ bool one_shot = false;
- float lifetime;
- float pre_process_time;
- float explosiveness_ratio;
- float randomness_ratio;
- float lifetime_randomness;
- float speed_scale;
- bool local_coords;
- int fixed_fps;
- bool fractional_delta;
+ float lifetime = 1.0;
+ float pre_process_time = 0.0;
+ float explosiveness_ratio = 0.0;
+ float randomness_ratio = 0.0;
+ float lifetime_randomness = 0.0;
+ float speed_scale = 1.0;
+ bool local_coords = true;
+ int fixed_fps = 0;
+ bool fractional_delta = true;
Transform inv_emission_transform;
- volatile bool can_update;
+ SafeFlag can_update;
- DrawOrder draw_order;
+ DrawOrder draw_order = DRAW_ORDER_INDEX;
Ref<Mesh> mesh;
////////
- Vector3 direction;
- float spread;
- float flatness;
+ Vector3 direction = Vector3(1, 0, 0);
+ float spread = 45.0;
+ float flatness = 0.0;
float parameters[PARAM_MAX];
- float randomness[PARAM_MAX];
+ float randomness[PARAM_MAX] = {};
Ref<Curve> curve_parameters[PARAM_MAX];
- Color color;
+ Color color = Color(1, 1, 1, 1);
Ref<Gradient> color_ramp;
- bool flags[FLAG_MAX];
+ bool particle_flags[PARTICLE_FLAG_MAX] = {};
- EmissionShape emission_shape;
- float emission_sphere_radius;
- Vector3 emission_box_extents;
+ EmissionShape emission_shape = EMISSION_SHAPE_POINT;
+ float emission_sphere_radius = 1.0;
+ Vector3 emission_box_extents = Vector3(1, 1, 1);
Vector<Vector3> emission_points;
Vector<Vector3> emission_normals;
Vector<Color> emission_colors;
- int emission_point_count;
+ int emission_point_count = 0;
- Vector3 gravity;
+ Vector3 gravity = Vector3(0, -9.8, 0);
void _update_internal();
void _particles_process(float p_delta);
@@ -186,11 +187,11 @@ private:
protected:
static void _bind_methods();
void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
public:
- AABB get_aabb() const;
- Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ AABB get_aabb() const override;
+ Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
void set_emitting(bool p_emitting);
void set_amount(int p_amount);
@@ -257,8 +258,8 @@ public:
void set_color_ramp(const Ref<Gradient> &p_ramp);
Ref<Gradient> get_color_ramp() const;
- void set_particle_flag(Flags p_flag, bool p_enable);
- bool get_particle_flag(Flags p_flag) const;
+ void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable);
+ bool get_particle_flag(ParticleFlags p_particle_flag) const;
void set_emission_shape(EmissionShape p_shape);
void set_emission_sphere_radius(float p_radius);
@@ -279,7 +280,7 @@ public:
void set_gravity(const Vector3 &p_gravity);
Vector3 get_gravity() const;
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
void restart();
@@ -291,7 +292,7 @@ public:
VARIANT_ENUM_CAST(CPUParticles3D::DrawOrder)
VARIANT_ENUM_CAST(CPUParticles3D::Parameter)
-VARIANT_ENUM_CAST(CPUParticles3D::Flags)
+VARIANT_ENUM_CAST(CPUParticles3D::ParticleFlags)
VARIANT_ENUM_CAST(CPUParticles3D::EmissionShape)
#endif // CPU_PARTICLES_H
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index fb72e10171..0f10f2b85f 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -34,7 +34,6 @@ void Decal::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->decal_set_extents(decal, p_extents);
update_gizmo();
- _change_notify("extents");
}
Vector3 Decal::get_extents() const {
@@ -220,18 +219,6 @@ void Decal::_bind_methods() {
}
Decal::Decal() {
- extents = Vector3(1, 1, 1);
- emission_energy = 1.0;
- modulate = Color(1, 1, 1, 1);
- albedo_mix = 1.0;
- cull_mask = (1 << 20) - 1;
- upper_fade = 0.3;
- lower_fade = 0.3;
- normal_fade = 0;
- distance_fade_enabled = false;
- distance_fade_begin = 10;
- distance_fade_length = 1;
-
decal = RenderingServer::get_singleton()->decal_create();
RS::get_singleton()->instance_set_base(get_instance(), decal);
}
diff --git a/scene/3d/decal.h b/scene/3d/decal.h
index 665444829d..095579d775 100644
--- a/scene/3d/decal.h
+++ b/scene/3d/decal.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -49,18 +49,18 @@ public:
private:
RID decal;
- Vector3 extents;
+ Vector3 extents = Vector3(1, 1, 1);
Ref<Texture2D> textures[TEXTURE_MAX];
- float emission_energy;
- float albedo_mix;
- Color modulate;
- uint32_t cull_mask;
- float normal_fade;
- float upper_fade;
- float lower_fade;
- bool distance_fade_enabled;
- float distance_fade_begin;
- float distance_fade_length;
+ float emission_energy = 1.0;
+ float albedo_mix = 1.0;
+ Color modulate = Color(1, 1, 1, 1);
+ uint32_t cull_mask = (1 << 20) - 1;
+ float normal_fade = 0.0;
+ float upper_fade = 0.3;
+ float lower_fade = 0.3;
+ bool distance_fade_enabled = false;
+ float distance_fade_begin = 10.0;
+ float distance_fade_length = 1.0;
protected:
static void _bind_methods();
@@ -102,8 +102,8 @@ public:
void set_cull_mask(uint32_t p_layers);
uint32_t get_cull_mask() const;
- virtual AABB get_aabb() const;
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual AABB get_aabb() const override;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
Decal();
~Decal();
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 1b6f9b45b9..8a8bfe50b9 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -32,7 +32,6 @@
#include "core/os/os.h"
-#include "core/method_bind_ext.gen.inc"
#include "mesh_instance_3d.h"
#include "voxelizer.h"
@@ -92,7 +91,7 @@ Dictionary GIProbeData::_get_data() const {
}
void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
- RS::get_singleton()->gi_probe_allocate(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts);
+ RS::get_singleton()->gi_probe_allocate_data(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts);
bounds = p_aabb;
to_cell_xform = p_to_cell_xform;
octree_size = p_octree_size;
@@ -222,7 +221,7 @@ RID GIProbeData::get_rid() const {
void GIProbeData::_validate_property(PropertyInfo &property) const {
if (property.name == "anisotropy_strength") {
- bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/quality/gi_probes/anisotropic");
+ bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/global_illumination/gi_probes/anisotropic");
if (!anisotropy_enabled) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
@@ -287,17 +286,6 @@ void GIProbeData::_bind_methods() {
}
GIProbeData::GIProbeData() {
- ao = 0.0;
- ao_size = 0.5;
- dynamic_range = 4;
- energy = 1.0;
- bias = 1.5;
- normal_bias = 0.0;
- propagation = 0.7;
- anisotropy_strength = 0.5;
- interior = false;
- use_two_bounces = false;
-
probe = RS::get_singleton()->gi_probe_create();
}
@@ -335,7 +323,6 @@ GIProbe::Subdiv GIProbe::get_subdiv() const {
void GIProbe::set_extents(const Vector3 &p_extents) {
extents = p_extents;
update_gizmo();
- _change_notify("extents");
}
Vector3 GIProbe::get_extents() const {
@@ -498,7 +485,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
bake_end_function();
}
- _change_notify(); //bake property may have changed
+ notify_property_list_changed(); //bake property may have changed
}
void GIProbe::_debug_bake() {
@@ -514,10 +501,18 @@ Vector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const {
}
String GIProbe::get_configuration_warning() const {
+ String warning = VisualInstance3D::get_configuration_warning();
+
if (RenderingServer::get_singleton()->is_low_end()) {
- return TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.");
+ } else if (probe_data.is_null()) {
+ warning += TTR("No GIProbe data set, so this node is disabled. Bake static objects to enable GI.");
}
- return String();
+
+ return warning;
}
void GIProbe::_bind_methods() {
@@ -546,9 +541,6 @@ void GIProbe::_bind_methods() {
}
GIProbe::GIProbe() {
- subdiv = SUBDIV_128;
- extents = Vector3(10, 10, 10);
-
gi_probe = RS::get_singleton()->gi_probe_create();
set_disable_scale(true);
}
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index b7abfbd01b..534b425557 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -46,20 +46,20 @@ class GIProbeData : public Resource {
AABB bounds;
Vector3 octree_size;
- float dynamic_range;
- float energy;
- float bias;
- float normal_bias;
- float propagation;
- float anisotropy_strength;
- float ao;
- float ao_size;
- bool interior;
- bool use_two_bounces;
+ float dynamic_range = 4.0;
+ float energy = 1.0;
+ float bias = 1.5;
+ float normal_bias = 0.0;
+ float propagation = 0.7;
+ float anisotropy_strength = 0.5;
+ float ao = 0.0;
+ float ao_size = 0.5;
+ bool interior = false;
+ bool use_two_bounces = false;
protected:
static void _bind_methods();
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
void allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts);
@@ -101,7 +101,7 @@ public:
void set_use_two_bounces(bool p_enable);
bool is_using_two_bounces() const;
- virtual RID get_rid() const;
+ virtual RID get_rid() const override;
GIProbeData();
~GIProbeData();
@@ -129,8 +129,8 @@ private:
RID gi_probe;
- Subdiv subdiv;
- Vector3 extents;
+ Subdiv subdiv = SUBDIV_128;
+ Vector3 extents = Vector3(10, 10, 10);
struct PlotMesh {
Ref<Material> override_material;
@@ -162,10 +162,10 @@ public:
void bake(Node *p_from_node = nullptr, bool p_create_visual_debug = false);
- virtual AABB get_aabb() const;
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual AABB get_aabb() const override;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
GIProbe();
~GIProbe();
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index c4480e3ed2..17a61b3e4d 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -100,7 +100,6 @@ void GPUParticles3D::set_visibility_aabb(const AABB &p_aabb) {
visibility_aabb = p_aabb;
RS::get_singleton()->particles_set_custom_aabb(particles, visibility_aabb);
update_gizmo();
- _change_notify("visibility_aabb");
}
void GPUParticles3D::set_use_local_coordinates(bool p_enable) {
@@ -124,6 +123,11 @@ void GPUParticles3D::set_speed_scale(float p_scale) {
RS::get_singleton()->particles_set_speed_scale(particles, p_scale);
}
+void GPUParticles3D::set_collision_base_size(float p_size) {
+ collision_base_size = p_size;
+ RS::get_singleton()->particles_set_collision_base_size(particles, p_size);
+}
+
bool GPUParticles3D::is_emitting() const {
return RS::get_singleton()->particles_get_emitting(particles);
}
@@ -168,6 +172,10 @@ float GPUParticles3D::get_speed_scale() const {
return speed_scale;
}
+float GPUParticles3D::get_collision_base_size() const {
+ return collision_base_size;
+}
+
void GPUParticles3D::set_draw_order(DrawOrder p_order) {
draw_order = p_order;
RS::get_singleton()->particles_set_draw_order(particles, RS::ParticlesDrawOrder(p_order));
@@ -181,7 +189,7 @@ void GPUParticles3D::set_draw_passes(int p_count) {
ERR_FAIL_COND(p_count < 1);
draw_passes.resize(p_count);
RS::get_singleton()->particles_set_draw_passes(particles, p_count);
- _change_notify();
+ notify_property_list_changed();
}
int GPUParticles3D::get_draw_passes() const {
@@ -232,7 +240,7 @@ String GPUParticles3D::get_configuration_warning() const {
return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles3D node instead. You can use the \"Convert to CPUParticles3D\" option for this purpose.");
}
- String warnings;
+ String warnings = GeometryInstance3D::get_configuration_warning();
bool meshes_found = false;
bool anim_material_found = false;
@@ -301,6 +309,36 @@ void GPUParticles3D::_validate_property(PropertyInfo &property) const {
}
}
+void GPUParticles3D::emit_particle(const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
+ RS::get_singleton()->particles_emit(particles, p_transform, p_velocity, p_color, p_custom, p_emit_flags);
+}
+
+void GPUParticles3D::_attach_sub_emitter() {
+ Node *n = get_node_or_null(sub_emitter);
+ if (n) {
+ GPUParticles3D *sen = Object::cast_to<GPUParticles3D>(n);
+ if (sen && sen != this) {
+ RS::get_singleton()->particles_set_subemitter(particles, sen->particles);
+ }
+ }
+}
+
+void GPUParticles3D::set_sub_emitter(const NodePath &p_path) {
+ if (is_inside_tree()) {
+ RS::get_singleton()->particles_set_subemitter(particles, RID());
+ }
+
+ sub_emitter = p_path;
+
+ if (is_inside_tree() && sub_emitter != NodePath()) {
+ _attach_sub_emitter();
+ }
+}
+
+NodePath GPUParticles3D::get_sub_emitter() const {
+ return sub_emitter;
+}
+
void GPUParticles3D::_notification(int p_what) {
if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) {
if (can_process()) {
@@ -314,11 +352,21 @@ void GPUParticles3D::_notification(int p_what) {
// the shot ends the editor can properly update
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
if (one_shot && !is_emitting()) {
- _change_notify();
+ notify_property_list_changed();
set_process_internal(false);
}
}
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ if (sub_emitter != NodePath()) {
+ _attach_sub_emitter();
+ }
+ }
+
+ if (p_what == NOTIFICATION_EXIT_TREE) {
+ RS::get_singleton()->particles_set_subemitter(particles, RID());
+ }
+
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
// make sure particles are updated before rendering occurs if they were active before
if (is_visible_in_tree() && !RS::get_singleton()->particles_is_inactive(particles)) {
@@ -341,6 +389,7 @@ void GPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &GPUParticles3D::set_fractional_delta);
ClassDB::bind_method(D_METHOD("set_process_material", "material"), &GPUParticles3D::set_process_material);
ClassDB::bind_method(D_METHOD("set_speed_scale", "scale"), &GPUParticles3D::set_speed_scale);
+ ClassDB::bind_method(D_METHOD("set_collision_base_size", "size"), &GPUParticles3D::set_collision_base_size);
ClassDB::bind_method(D_METHOD("is_emitting"), &GPUParticles3D::is_emitting);
ClassDB::bind_method(D_METHOD("get_amount"), &GPUParticles3D::get_amount);
@@ -355,6 +404,7 @@ void GPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_fractional_delta"), &GPUParticles3D::get_fractional_delta);
ClassDB::bind_method(D_METHOD("get_process_material"), &GPUParticles3D::get_process_material);
ClassDB::bind_method(D_METHOD("get_speed_scale"), &GPUParticles3D::get_speed_scale);
+ ClassDB::bind_method(D_METHOD("get_collision_base_size"), &GPUParticles3D::get_collision_base_size);
ClassDB::bind_method(D_METHOD("set_draw_order", "order"), &GPUParticles3D::set_draw_order);
@@ -369,8 +419,14 @@ void GPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("restart"), &GPUParticles3D::restart);
ClassDB::bind_method(D_METHOD("capture_aabb"), &GPUParticles3D::capture_aabb);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter", "path"), &GPUParticles3D::set_sub_emitter);
+ ClassDB::bind_method(D_METHOD("get_sub_emitter"), &GPUParticles3D::get_sub_emitter);
+
+ ClassDB::bind_method(D_METHOD("emit_particle", "xform", "velocity", "color", "custom", "flags"), &GPUParticles3D::emit_particle);
+
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::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::BOOL, "one_shot"), "set_one_shot", "get_one_shot");
@@ -380,6 +436,8 @@ void GPUParticles3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta");
+ ADD_GROUP("Collision", "collision_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_base_size", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_collision_base_size", "get_collision_base_size");
ADD_GROUP("Drawing", "");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "visibility_aabb"), "set_visibility_aabb", "get_visibility_aabb");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates");
@@ -396,6 +454,12 @@ void GPUParticles3D::_bind_methods() {
BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
BIND_ENUM_CONSTANT(DRAW_ORDER_VIEW_DEPTH);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_POSITION);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_ROTATION_SCALE);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_VELOCITY);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_COLOR);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_CUSTOM);
+
BIND_CONSTANT(MAX_DRAW_PASSES);
}
@@ -417,6 +481,7 @@ GPUParticles3D::GPUParticles3D() {
set_draw_passes(1);
set_draw_order(DRAW_ORDER_INDEX);
set_speed_scale(1);
+ set_collision_base_size(0.01);
}
GPUParticles3D::~GPUParticles3D() {
diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h
index 0c6653294b..0c1a1a510c 100644
--- a/scene/3d/gpu_particles_3d.h
+++ b/scene/3d/gpu_particles_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,7 +31,7 @@
#ifndef PARTICLES_H
#define PARTICLES_H
-#include "core/rid.h"
+#include "core/templates/rid.h"
#include "scene/3d/visual_instance_3d.h"
#include "scene/resources/material.h"
@@ -64,6 +64,8 @@ private:
bool local_coords;
int fixed_fps;
bool fractional_delta;
+ NodePath sub_emitter;
+ float collision_base_size;
Ref<Material> process_material;
@@ -71,14 +73,16 @@ private:
Vector<Ref<Mesh>> draw_passes;
+ void _attach_sub_emitter();
+
protected:
static void _bind_methods();
void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
public:
- AABB get_aabb() const;
- Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ AABB get_aabb() const override;
+ Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
void set_emitting(bool p_emitting);
void set_amount(int p_amount);
@@ -91,6 +95,7 @@ public:
void set_use_local_coordinates(bool p_enable);
void set_process_material(const Ref<Material> &p_material);
void set_speed_scale(float p_scale);
+ void set_collision_base_size(float p_ratio);
bool is_emitting() const;
int get_amount() const;
@@ -103,6 +108,7 @@ public:
bool get_use_local_coordinates() const;
Ref<Material> get_process_material() const;
float get_speed_scale() const;
+ float get_collision_base_size() const;
void set_fixed_fps(int p_count);
int get_fixed_fps() const;
@@ -119,15 +125,29 @@ public:
void set_draw_pass_mesh(int p_pass, const Ref<Mesh> &p_mesh);
Ref<Mesh> get_draw_pass_mesh(int p_pass) const;
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
+
+ void set_sub_emitter(const NodePath &p_path);
+ NodePath get_sub_emitter() const;
void restart();
+ enum EmitFlags {
+ EMIT_FLAG_POSITION = RS::PARTICLES_EMIT_FLAG_POSITION,
+ EMIT_FLAG_ROTATION_SCALE = RS::PARTICLES_EMIT_FLAG_ROTATION_SCALE,
+ EMIT_FLAG_VELOCITY = RS::PARTICLES_EMIT_FLAG_VELOCITY,
+ EMIT_FLAG_COLOR = RS::PARTICLES_EMIT_FLAG_COLOR,
+ EMIT_FLAG_CUSTOM = RS::PARTICLES_EMIT_FLAG_CUSTOM
+ };
+
+ void emit_particle(const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags);
+
AABB capture_aabb() const;
GPUParticles3D();
~GPUParticles3D();
};
VARIANT_ENUM_CAST(GPUParticles3D::DrawOrder)
+VARIANT_ENUM_CAST(GPUParticles3D::EmitFlags)
#endif // PARTICLES_H
diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp
new file mode 100644
index 0000000000..97241be60f
--- /dev/null
+++ b/scene/3d/gpu_particles_collision_3d.cpp
@@ -0,0 +1,901 @@
+/*************************************************************************/
+/* gpu_particles_collision_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 "gpu_particles_collision_3d.h"
+
+#include "core/templates/thread_work_pool.h"
+#include "mesh_instance_3d.h"
+#include "scene/3d/camera_3d.h"
+#include "scene/main/viewport.h"
+
+void GPUParticlesCollision3D::set_cull_mask(uint32_t p_cull_mask) {
+ cull_mask = p_cull_mask;
+ RS::get_singleton()->particles_collision_set_cull_mask(collision, p_cull_mask);
+}
+
+uint32_t GPUParticlesCollision3D::get_cull_mask() const {
+ return cull_mask;
+}
+
+void GPUParticlesCollision3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_cull_mask", "mask"), &GPUParticlesCollision3D::set_cull_mask);
+ ClassDB::bind_method(D_METHOD("get_cull_mask"), &GPUParticlesCollision3D::get_cull_mask);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
+}
+
+GPUParticlesCollision3D::GPUParticlesCollision3D(RS::ParticlesCollisionType p_type) {
+ collision = RS::get_singleton()->particles_collision_create();
+ RS::get_singleton()->particles_collision_set_collision_type(collision, p_type);
+ set_base(collision);
+}
+
+GPUParticlesCollision3D::~GPUParticlesCollision3D() {
+ RS::get_singleton()->free(collision);
+}
+
+/////////////////////////////////
+
+void GPUParticlesCollisionSphere::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesCollisionSphere::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesCollisionSphere::get_radius);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_radius", "get_radius");
+}
+
+void GPUParticlesCollisionSphere::set_radius(float p_radius) {
+ radius = p_radius;
+ RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius);
+ update_gizmo();
+}
+
+float GPUParticlesCollisionSphere::get_radius() const {
+ return radius;
+}
+
+AABB GPUParticlesCollisionSphere::get_aabb() const {
+ return AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2, radius * 2, radius * 2));
+}
+
+GPUParticlesCollisionSphere::GPUParticlesCollisionSphere() :
+ GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE) {
+}
+
+GPUParticlesCollisionSphere::~GPUParticlesCollisionSphere() {
+}
+
+///////////////////////////
+
+void GPUParticlesCollisionBox::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionBox::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionBox::get_extents);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
+}
+
+void GPUParticlesCollisionBox::set_extents(const Vector3 &p_extents) {
+ extents = p_extents;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+ update_gizmo();
+}
+
+Vector3 GPUParticlesCollisionBox::get_extents() const {
+ return extents;
+}
+
+AABB GPUParticlesCollisionBox::get_aabb() const {
+ return AABB(-extents, extents * 2);
+}
+
+GPUParticlesCollisionBox::GPUParticlesCollisionBox() :
+ GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_BOX_COLLIDE) {
+}
+
+GPUParticlesCollisionBox::~GPUParticlesCollisionBox() {
+}
+
+///////////////////////////////
+///////////////////////////
+
+void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes) {
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node);
+ if (mi && mi->is_visible_in_tree()) {
+ Ref<Mesh> mesh = mi->get_mesh();
+ if (mesh.is_valid()) {
+ AABB aabb = mesh->get_aabb();
+
+ Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform();
+
+ if (p_aabb.intersects(xf.xform(aabb))) {
+ PlotMesh pm;
+ pm.local_xform = xf;
+ pm.mesh = mesh;
+ plot_meshes.push_back(pm);
+ }
+ }
+ }
+
+ Node3D *s = Object::cast_to<Node3D>(p_at_node);
+ if (s) {
+ if (s->is_visible_in_tree()) {
+ Array meshes = p_at_node->call("get_meshes");
+ for (int i = 0; i < meshes.size(); i += 2) {
+ Transform mxf = meshes[i];
+ Ref<Mesh> mesh = meshes[i + 1];
+ if (!mesh.is_valid()) {
+ continue;
+ }
+
+ AABB aabb = mesh->get_aabb();
+
+ Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf);
+
+ if (p_aabb.intersects(xf.xform(aabb))) {
+ PlotMesh pm;
+ pm.local_xform = xf;
+ pm.mesh = mesh;
+ plot_meshes.push_back(pm);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < p_at_node->get_child_count(); i++) {
+ Node *child = p_at_node->get_child(i);
+ _find_meshes(p_aabb, child, plot_meshes);
+ }
+}
+
+uint32_t GPUParticlesCollisionSDF::_create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness) {
+ if (p_face_count == 1) {
+ return BVH::LEAF_BIT | p_faces[0].index;
+ }
+
+ uint32_t index = bvh_tree.size();
+ {
+ BVH bvh;
+
+ for (uint32_t i = 0; i < p_face_count; i++) {
+ const Face3 &f = p_triangles[p_faces[i].index];
+ AABB aabb(f.vertex[0], Vector3());
+ aabb.expand_to(f.vertex[1]);
+ aabb.expand_to(f.vertex[2]);
+ if (p_thickness > 0.0) {
+ Vector3 normal = p_triangles[p_faces[i].index].get_plane().normal;
+ aabb.expand_to(f.vertex[0] - normal * p_thickness);
+ aabb.expand_to(f.vertex[1] - normal * p_thickness);
+ aabb.expand_to(f.vertex[2] - normal * p_thickness);
+ }
+ if (i == 0) {
+ bvh.bounds = aabb;
+ } else {
+ bvh.bounds.merge_with(aabb);
+ }
+ }
+ bvh_tree.push_back(bvh);
+ }
+
+ uint32_t middle = p_face_count / 2;
+
+ SortArray<FacePos, FaceSort> s;
+ s.compare.axis = bvh_tree[index].bounds.get_longest_axis_index();
+ s.sort(p_faces, p_face_count);
+
+ uint32_t left = _create_bvh(bvh_tree, p_faces, middle, p_triangles, p_thickness);
+ uint32_t right = _create_bvh(bvh_tree, p_faces + middle, p_face_count - middle, p_triangles, p_thickness);
+
+ bvh_tree[index].children[0] = left;
+ bvh_tree[index].children[1] = right;
+
+ return index;
+}
+
+static _FORCE_INLINE_ float Vector3_dot2(const Vector3 &p_vec3) {
+ return p_vec3.dot(p_vec3);
+}
+
+void GPUParticlesCollisionSDF::_find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance) {
+ if (p_bvh_cell & BVH::LEAF_BIT) {
+ p_bvh_cell &= BVH::LEAF_MASK; //remove bit
+
+ Vector3 point = p_pos;
+ Plane p = triangles[p_bvh_cell].get_plane();
+ float d = p.distance_to(point);
+ float inside_d = 1e20;
+ if (d < 0 && d > -thickness) {
+ //inside planes, do this in 2D
+
+ Vector3 x_axis = (triangles[p_bvh_cell].vertex[0] - triangles[p_bvh_cell].vertex[1]).normalized();
+ Vector3 y_axis = p.normal.cross(x_axis).normalized();
+
+ Vector2 points[3];
+ for (int i = 0; i < 3; i++) {
+ points[i] = Vector2(x_axis.dot(triangles[p_bvh_cell].vertex[i]), y_axis.dot(triangles[p_bvh_cell].vertex[i]));
+ }
+
+ Vector2 p2d = Vector2(x_axis.dot(point), y_axis.dot(point));
+
+ {
+ // https://www.shadertoy.com/view/XsXSz4
+
+ Vector2 e0 = points[1] - points[0];
+ Vector2 e1 = points[2] - points[1];
+ Vector2 e2 = points[0] - points[2];
+
+ Vector2 v0 = p2d - points[0];
+ Vector2 v1 = p2d - points[1];
+ Vector2 v2 = p2d - points[2];
+
+ Vector2 pq0 = v0 - e0 * CLAMP(v0.dot(e0) / e0.dot(e0), 0.0, 1.0);
+ Vector2 pq1 = v1 - e1 * CLAMP(v1.dot(e1) / e1.dot(e1), 0.0, 1.0);
+ Vector2 pq2 = v2 - e2 * CLAMP(v2.dot(e2) / e2.dot(e2), 0.0, 1.0);
+
+ float s = SGN(e0.x * e2.y - e0.y * e2.x);
+ Vector2 d2 = Vector2(pq0.dot(pq0), s * (v0.x * e0.y - v0.y * e0.x)).min(Vector2(pq1.dot(pq1), s * (v1.x * e1.y - v1.y * e1.x))).min(Vector2(pq2.dot(pq2), s * (v2.x * e2.y - v2.y * e2.x)));
+
+ inside_d = -Math::sqrt(d2.x) * SGN(d2.y);
+ }
+
+ //make sure distance to planes is not shorter if inside
+ if (inside_d < 0) {
+ inside_d = MAX(inside_d, d);
+ inside_d = MAX(inside_d, -(thickness + d));
+ }
+
+ closest_distance = MIN(closest_distance, inside_d);
+ } else {
+ if (d < 0) {
+ point -= p.normal * thickness; //flatten
+ }
+
+ // https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
+ Vector3 a = triangles[p_bvh_cell].vertex[0];
+ Vector3 b = triangles[p_bvh_cell].vertex[1];
+ Vector3 c = triangles[p_bvh_cell].vertex[2];
+
+ Vector3 ba = b - a;
+ Vector3 pa = point - a;
+ Vector3 cb = c - b;
+ Vector3 pb = point - b;
+ Vector3 ac = a - c;
+ Vector3 pc = point - c;
+ Vector3 nor = ba.cross(ac);
+
+ inside_d = Math::sqrt(
+ (SGN(ba.cross(nor).dot(pa)) +
+ SGN(cb.cross(nor).dot(pb)) +
+ SGN(ac.cross(nor).dot(pc)) <
+ 2.0) ?
+ MIN(MIN(
+ Vector3_dot2(ba * CLAMP(ba.dot(pa) / Vector3_dot2(ba), 0.0, 1.0) - pa),
+ Vector3_dot2(cb * CLAMP(cb.dot(pb) / Vector3_dot2(cb), 0.0, 1.0) - pb)),
+ Vector3_dot2(ac * CLAMP(ac.dot(pc) / Vector3_dot2(ac), 0.0, 1.0) - pc)) :
+ nor.dot(pa) * nor.dot(pa) / Vector3_dot2(nor));
+
+ closest_distance = MIN(closest_distance, inside_d);
+ }
+
+ } else {
+ bool pass = true;
+ if (!bvh[p_bvh_cell].bounds.has_point(p_pos)) {
+ //outside, find closest point
+ Vector3 he = bvh[p_bvh_cell].bounds.size * 0.5;
+ Vector3 center = bvh[p_bvh_cell].bounds.position + he;
+
+ Vector3 rel = (p_pos - center).abs();
+ Vector3 closest(MIN(rel.x, he.x), MIN(rel.y, he.y), MIN(rel.z, he.z));
+ float d = rel.distance_to(closest);
+
+ if (d >= closest_distance) {
+ pass = false; //already closer than this aabb, discard
+ }
+ }
+
+ if (pass) {
+ _find_closest_distance(p_pos, bvh, bvh[p_bvh_cell].children[0], triangles, thickness, closest_distance);
+ _find_closest_distance(p_pos, bvh, bvh[p_bvh_cell].children[1], triangles, thickness, closest_distance);
+ }
+ }
+}
+
+void GPUParticlesCollisionSDF::_compute_sdf_z(uint32_t p_z, ComputeSDFParams *params) {
+ int32_t z_ofs = p_z * params->size.y * params->size.x;
+ for (int32_t y = 0; y < params->size.y; y++) {
+ int32_t y_ofs = z_ofs + y * params->size.x;
+ for (int32_t x = 0; x < params->size.x; x++) {
+ int32_t x_ofs = y_ofs + x;
+ float &cell = params->cells[x_ofs];
+
+ Vector3 pos = params->cell_offset + Vector3(x, y, p_z) * params->cell_size;
+
+ cell = 1e20;
+
+ _find_closest_distance(pos, params->bvh, 0, params->triangles, params->thickness, cell);
+ }
+ }
+}
+
+void GPUParticlesCollisionSDF::_compute_sdf(ComputeSDFParams *params) {
+ ThreadWorkPool work_pool;
+ work_pool.init();
+ work_pool.begin_work(params->size.z, this, &GPUParticlesCollisionSDF::_compute_sdf_z, params);
+ while (work_pool.get_work_index() < (uint32_t)params->size.z) {
+ OS::get_singleton()->delay_usec(10000);
+ bake_step_function(work_pool.get_work_index() * 100 / params->size.z, "Baking SDF");
+ }
+ work_pool.end_work();
+ work_pool.finish();
+}
+
+Vector3i GPUParticlesCollisionSDF::get_estimated_cell_size() const {
+ static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 };
+ int subdiv = subdivs[get_resolution()];
+
+ AABB aabb(-extents, extents * 2);
+
+ float cell_size = aabb.get_longest_axis_size() / float(subdiv);
+
+ Vector3i sdf_size = Vector3i(aabb.size / cell_size);
+ sdf_size.x = MAX(1, sdf_size.x);
+ sdf_size.y = MAX(1, sdf_size.y);
+ sdf_size.z = MAX(1, sdf_size.z);
+ return sdf_size;
+}
+
+Ref<Image> GPUParticlesCollisionSDF::bake() {
+ static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 };
+ int subdiv = subdivs[get_resolution()];
+
+ AABB aabb(-extents, extents * 2);
+
+ float cell_size = aabb.get_longest_axis_size() / float(subdiv);
+
+ Vector3i sdf_size = Vector3i(aabb.size / cell_size);
+ sdf_size.x = MAX(1, sdf_size.x);
+ sdf_size.y = MAX(1, sdf_size.y);
+ sdf_size.z = MAX(1, sdf_size.z);
+
+ if (bake_begin_function) {
+ bake_begin_function(100);
+ }
+
+ aabb.size = Vector3(sdf_size) * cell_size;
+
+ List<PlotMesh> plot_meshes;
+ _find_meshes(aabb, get_parent(), plot_meshes);
+
+ LocalVector<Face3> faces;
+
+ if (bake_step_function) {
+ bake_step_function(0, "Finding Meshes");
+ }
+
+ for (List<PlotMesh>::Element *E = plot_meshes.front(); E; E = E->next()) {
+ const PlotMesh &pm = E->get();
+
+ for (int i = 0; i < pm.mesh->get_surface_count(); i++) {
+ if (pm.mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
+ continue; //only triangles
+ }
+
+ Array a = pm.mesh->surface_get_arrays(i);
+
+ Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
+ const Vector3 *vr = vertices.ptr();
+ Vector<int> index = a[Mesh::ARRAY_INDEX];
+
+ if (index.size()) {
+ int facecount = index.size() / 3;
+ const int *ir = index.ptr();
+
+ for (int j = 0; j < facecount; j++) {
+ Face3 face;
+
+ for (int k = 0; k < 3; k++) {
+ face.vertex[k] = pm.local_xform.xform(vr[ir[j * 3 + k]]);
+ }
+
+ //test against original bounds
+ if (!Geometry3D::triangle_box_overlap(aabb.position + aabb.size * 0.5, aabb.size * 0.5, face.vertex)) {
+ continue;
+ }
+
+ faces.push_back(face);
+ }
+
+ } else {
+ int facecount = vertices.size() / 3;
+
+ for (int j = 0; j < facecount; j++) {
+ Face3 face;
+
+ for (int k = 0; k < 3; k++) {
+ face.vertex[k] = pm.local_xform.xform(vr[j * 3 + k]);
+ }
+
+ //test against original bounds
+ if (!Geometry3D::triangle_box_overlap(aabb.position + aabb.size * 0.5, aabb.size * 0.5, face.vertex)) {
+ continue;
+ }
+
+ faces.push_back(face);
+ }
+ }
+ }
+ }
+
+ //compute bvh
+
+ ERR_FAIL_COND_V(faces.size() <= 1, Ref<Image>());
+
+ LocalVector<FacePos> face_pos;
+
+ face_pos.resize(faces.size());
+
+ float th = cell_size * thickness;
+
+ for (uint32_t i = 0; i < faces.size(); i++) {
+ face_pos[i].index = i;
+ face_pos[i].center = (faces[i].vertex[0] + faces[i].vertex[1] + faces[i].vertex[2]) / 2;
+ if (th > 0.0) {
+ face_pos[i].center -= faces[i].get_plane().normal * th * 0.5;
+ }
+ }
+
+ if (bake_step_function) {
+ bake_step_function(0, "Creating BVH");
+ }
+
+ LocalVector<BVH> bvh;
+
+ _create_bvh(bvh, face_pos.ptr(), face_pos.size(), faces.ptr(), th);
+
+ Vector<uint8_t> data;
+ data.resize(sdf_size.z * sdf_size.y * sdf_size.x * sizeof(float));
+
+ if (bake_step_function) {
+ bake_step_function(0, "Baking SDF");
+ }
+
+ ComputeSDFParams params;
+ params.cells = (float *)data.ptrw();
+ params.size = sdf_size;
+ params.cell_size = cell_size;
+ params.cell_offset = aabb.position + Vector3(cell_size * 0.5, cell_size * 0.5, cell_size * 0.5);
+ params.bvh = bvh.ptr();
+ params.triangles = faces.ptr();
+ params.thickness = th;
+ _compute_sdf(&params);
+
+ Ref<Image> ret;
+ ret.instance();
+ ret->create(sdf_size.x, sdf_size.y * sdf_size.z, false, Image::FORMAT_RF, data);
+ ret->convert(Image::FORMAT_RH); //convert to half, save space
+ ret->set_meta("depth", sdf_size.z); //hack, make sure to add to the docs of this function
+
+ if (bake_end_function) {
+ bake_end_function();
+ }
+
+ return ret;
+}
+
+void GPUParticlesCollisionSDF::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF::get_extents);
+
+ ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionSDF::set_resolution);
+ ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionSDF::get_resolution);
+
+ ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesCollisionSDF::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesCollisionSDF::get_texture);
+
+ ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &GPUParticlesCollisionSDF::set_thickness);
+ ClassDB::bind_method(D_METHOD("get_thickness"), &GPUParticlesCollisionSDF::get_thickness);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "16,32,64,128,256,512"), "set_resolution", "get_resolution");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "thickness", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_thickness", "get_thickness");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture");
+
+ BIND_ENUM_CONSTANT(RESOLUTION_16);
+ BIND_ENUM_CONSTANT(RESOLUTION_32);
+ BIND_ENUM_CONSTANT(RESOLUTION_64);
+ BIND_ENUM_CONSTANT(RESOLUTION_128);
+ BIND_ENUM_CONSTANT(RESOLUTION_256);
+ BIND_ENUM_CONSTANT(RESOLUTION_512);
+ BIND_ENUM_CONSTANT(RESOLUTION_MAX);
+}
+
+void GPUParticlesCollisionSDF::set_thickness(float p_thickness) {
+ thickness = p_thickness;
+}
+
+float GPUParticlesCollisionSDF::get_thickness() const {
+ return thickness;
+}
+
+void GPUParticlesCollisionSDF::set_extents(const Vector3 &p_extents) {
+ extents = p_extents;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+ update_gizmo();
+}
+
+Vector3 GPUParticlesCollisionSDF::get_extents() const {
+ return extents;
+}
+
+void GPUParticlesCollisionSDF::set_resolution(Resolution p_resolution) {
+ resolution = p_resolution;
+ update_gizmo();
+}
+
+GPUParticlesCollisionSDF::Resolution GPUParticlesCollisionSDF::get_resolution() const {
+ return resolution;
+}
+
+void GPUParticlesCollisionSDF::set_texture(const Ref<Texture3D> &p_texture) {
+ texture = p_texture;
+ RID tex = texture.is_valid() ? texture->get_rid() : RID();
+ RS::get_singleton()->particles_collision_set_field_texture(_get_collision(), tex);
+}
+
+Ref<Texture3D> GPUParticlesCollisionSDF::get_texture() const {
+ return texture;
+}
+
+AABB GPUParticlesCollisionSDF::get_aabb() const {
+ return AABB(-extents, extents * 2);
+}
+
+GPUParticlesCollisionSDF::BakeBeginFunc GPUParticlesCollisionSDF::bake_begin_function = nullptr;
+GPUParticlesCollisionSDF::BakeStepFunc GPUParticlesCollisionSDF::bake_step_function = nullptr;
+GPUParticlesCollisionSDF::BakeEndFunc GPUParticlesCollisionSDF::bake_end_function = nullptr;
+
+GPUParticlesCollisionSDF::GPUParticlesCollisionSDF() :
+ GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_SDF_COLLIDE) {
+}
+
+GPUParticlesCollisionSDF::~GPUParticlesCollisionSDF() {
+}
+
+////////////////////////////
+////////////////////////////
+
+void GPUParticlesCollisionHeightField::_notification(int p_what) {
+ if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
+ if (update_mode == UPDATE_MODE_ALWAYS) {
+ RS::get_singleton()->particles_collision_height_field_update(_get_collision());
+ }
+
+ if (follow_camera_mode && get_viewport()) {
+ Camera3D *cam = get_viewport()->get_camera();
+ if (cam) {
+ Transform xform = get_global_transform();
+ Vector3 x_axis = xform.basis.get_axis(Vector3::AXIS_X).normalized();
+ Vector3 z_axis = xform.basis.get_axis(Vector3::AXIS_Z).normalized();
+ float x_len = xform.basis.get_scale().x;
+ float z_len = xform.basis.get_scale().z;
+
+ Vector3 cam_pos = cam->get_global_transform().origin;
+ Transform new_xform = xform;
+
+ while (x_axis.dot(cam_pos - new_xform.origin) > x_len) {
+ new_xform.origin += x_axis * x_len;
+ }
+ while (x_axis.dot(cam_pos - new_xform.origin) < -x_len) {
+ new_xform.origin -= x_axis * x_len;
+ }
+
+ while (z_axis.dot(cam_pos - new_xform.origin) > z_len) {
+ new_xform.origin += z_axis * z_len;
+ }
+ while (z_axis.dot(cam_pos - new_xform.origin) < -z_len) {
+ new_xform.origin -= z_axis * z_len;
+ }
+
+ if (new_xform != xform) {
+ set_global_transform(new_xform);
+ RS::get_singleton()->particles_collision_height_field_update(_get_collision());
+ }
+ }
+ }
+ }
+
+ if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
+ RS::get_singleton()->particles_collision_height_field_update(_get_collision());
+ }
+}
+
+void GPUParticlesCollisionHeightField::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionHeightField::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionHeightField::get_extents);
+
+ ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionHeightField::set_resolution);
+ ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionHeightField::get_resolution);
+
+ ClassDB::bind_method(D_METHOD("set_update_mode", "update_mode"), &GPUParticlesCollisionHeightField::set_update_mode);
+ ClassDB::bind_method(D_METHOD("get_update_mode"), &GPUParticlesCollisionHeightField::get_update_mode);
+
+ ClassDB::bind_method(D_METHOD("set_follow_camera_mode", "enabled"), &GPUParticlesCollisionHeightField::set_follow_camera_mode);
+ ClassDB::bind_method(D_METHOD("is_follow_camera_mode_enabled"), &GPUParticlesCollisionHeightField::is_follow_camera_mode_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_follow_camera_push_ratio", "ratio"), &GPUParticlesCollisionHeightField::set_follow_camera_push_ratio);
+ ClassDB::bind_method(D_METHOD("get_follow_camera_push_ratio"), &GPUParticlesCollisionHeightField::get_follow_camera_push_ratio);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096,8192"), "set_resolution", "get_resolution");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "WhenMoved,Always"), "set_update_mode", "get_update_mode");
+ ADD_GROUP("Folow Camera", "follow_camera_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_camera_enabled"), "set_follow_camera_mode", "is_follow_camera_mode_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "follow_camera_push_ratio", PROPERTY_HINT_RANGE, "0.01,1,0.01"), "set_follow_camera_push_ratio", "get_follow_camera_push_ratio");
+
+ BIND_ENUM_CONSTANT(RESOLUTION_256);
+ BIND_ENUM_CONSTANT(RESOLUTION_512);
+ BIND_ENUM_CONSTANT(RESOLUTION_1024);
+ BIND_ENUM_CONSTANT(RESOLUTION_2048);
+ BIND_ENUM_CONSTANT(RESOLUTION_4096);
+ BIND_ENUM_CONSTANT(RESOLUTION_8192);
+ BIND_ENUM_CONSTANT(RESOLUTION_MAX);
+
+ BIND_ENUM_CONSTANT(UPDATE_MODE_WHEN_MOVED);
+ BIND_ENUM_CONSTANT(UPDATE_MODE_ALWAYS);
+}
+
+void GPUParticlesCollisionHeightField::set_follow_camera_push_ratio(float p_follow_camera_push_ratio) {
+ follow_camera_push_ratio = p_follow_camera_push_ratio;
+}
+
+float GPUParticlesCollisionHeightField::get_follow_camera_push_ratio() const {
+ return follow_camera_push_ratio;
+}
+
+void GPUParticlesCollisionHeightField::set_extents(const Vector3 &p_extents) {
+ extents = p_extents;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+ update_gizmo();
+ RS::get_singleton()->particles_collision_height_field_update(_get_collision());
+}
+
+Vector3 GPUParticlesCollisionHeightField::get_extents() const {
+ return extents;
+}
+
+void GPUParticlesCollisionHeightField::set_resolution(Resolution p_resolution) {
+ resolution = p_resolution;
+ RS::get_singleton()->particles_collision_set_height_field_resolution(_get_collision(), RS::ParticlesCollisionHeightfieldResolution(resolution));
+ update_gizmo();
+ RS::get_singleton()->particles_collision_height_field_update(_get_collision());
+}
+
+GPUParticlesCollisionHeightField::Resolution GPUParticlesCollisionHeightField::get_resolution() const {
+ return resolution;
+}
+
+void GPUParticlesCollisionHeightField::set_update_mode(UpdateMode p_update_mode) {
+ update_mode = p_update_mode;
+ set_process_internal(follow_camera_mode || update_mode == UPDATE_MODE_ALWAYS);
+}
+
+GPUParticlesCollisionHeightField::UpdateMode GPUParticlesCollisionHeightField::get_update_mode() const {
+ return update_mode;
+}
+
+void GPUParticlesCollisionHeightField::set_follow_camera_mode(bool p_enabled) {
+ follow_camera_mode = p_enabled;
+ set_process_internal(follow_camera_mode || update_mode == UPDATE_MODE_ALWAYS);
+}
+
+bool GPUParticlesCollisionHeightField::is_follow_camera_mode_enabled() const {
+ return follow_camera_mode;
+}
+
+AABB GPUParticlesCollisionHeightField::get_aabb() const {
+ return AABB(-extents, extents * 2);
+}
+
+GPUParticlesCollisionHeightField::GPUParticlesCollisionHeightField() :
+ GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE) {
+}
+
+GPUParticlesCollisionHeightField::~GPUParticlesCollisionHeightField() {
+}
+
+////////////////////////////
+////////////////////////////
+
+void GPUParticlesAttractor3D::set_cull_mask(uint32_t p_cull_mask) {
+ cull_mask = p_cull_mask;
+ RS::get_singleton()->particles_collision_set_cull_mask(collision, p_cull_mask);
+}
+
+uint32_t GPUParticlesAttractor3D::get_cull_mask() const {
+ return cull_mask;
+}
+
+void GPUParticlesAttractor3D::set_strength(float p_strength) {
+ strength = p_strength;
+ RS::get_singleton()->particles_collision_set_attractor_strength(collision, p_strength);
+}
+
+float GPUParticlesAttractor3D::get_strength() const {
+ return strength;
+}
+
+void GPUParticlesAttractor3D::set_attenuation(float p_attenuation) {
+ attenuation = p_attenuation;
+ RS::get_singleton()->particles_collision_set_attractor_attenuation(collision, p_attenuation);
+}
+
+float GPUParticlesAttractor3D::get_attenuation() const {
+ return attenuation;
+}
+
+void GPUParticlesAttractor3D::set_directionality(float p_directionality) {
+ directionality = p_directionality;
+ RS::get_singleton()->particles_collision_set_attractor_directionality(collision, p_directionality);
+ update_gizmo();
+}
+
+float GPUParticlesAttractor3D::get_directionality() const {
+ return directionality;
+}
+
+void GPUParticlesAttractor3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_cull_mask", "mask"), &GPUParticlesAttractor3D::set_cull_mask);
+ ClassDB::bind_method(D_METHOD("get_cull_mask"), &GPUParticlesAttractor3D::get_cull_mask);
+
+ ClassDB::bind_method(D_METHOD("set_strength", "strength"), &GPUParticlesAttractor3D::set_strength);
+ ClassDB::bind_method(D_METHOD("get_strength"), &GPUParticlesAttractor3D::get_strength);
+
+ ClassDB::bind_method(D_METHOD("set_attenuation", "attenuation"), &GPUParticlesAttractor3D::set_attenuation);
+ ClassDB::bind_method(D_METHOD("get_attenuation"), &GPUParticlesAttractor3D::get_attenuation);
+
+ ClassDB::bind_method(D_METHOD("set_directionality", "amount"), &GPUParticlesAttractor3D::set_directionality);
+ ClassDB::bind_method(D_METHOD("get_directionality"), &GPUParticlesAttractor3D::get_directionality);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "-128,128,0.01,or_greater,or_lesser"), "set_strength", "get_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation", PROPERTY_HINT_EXP_EASING, "0,8,0.01"), "set_attenuation", "get_attenuation");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "directionality", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_directionality", "get_directionality");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
+}
+
+GPUParticlesAttractor3D::GPUParticlesAttractor3D(RS::ParticlesCollisionType p_type) {
+ collision = RS::get_singleton()->particles_collision_create();
+ RS::get_singleton()->particles_collision_set_collision_type(collision, p_type);
+ set_base(collision);
+}
+GPUParticlesAttractor3D::~GPUParticlesAttractor3D() {
+ RS::get_singleton()->free(collision);
+}
+
+/////////////////////////////////
+
+void GPUParticlesAttractorSphere::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesAttractorSphere::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesAttractorSphere::get_radius);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_radius", "get_radius");
+}
+
+void GPUParticlesAttractorSphere::set_radius(float p_radius) {
+ radius = p_radius;
+ RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius);
+ update_gizmo();
+}
+
+float GPUParticlesAttractorSphere::get_radius() const {
+ return radius;
+}
+
+AABB GPUParticlesAttractorSphere::get_aabb() const {
+ return AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2, radius * 2, radius * 2));
+}
+
+GPUParticlesAttractorSphere::GPUParticlesAttractorSphere() :
+ GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT) {
+}
+
+GPUParticlesAttractorSphere::~GPUParticlesAttractorSphere() {
+}
+
+///////////////////////////
+
+void GPUParticlesAttractorBox::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorBox::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorBox::get_extents);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
+}
+
+void GPUParticlesAttractorBox::set_extents(const Vector3 &p_extents) {
+ extents = p_extents;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+ update_gizmo();
+}
+
+Vector3 GPUParticlesAttractorBox::get_extents() const {
+ return extents;
+}
+
+AABB GPUParticlesAttractorBox::get_aabb() const {
+ return AABB(-extents, extents * 2);
+}
+
+GPUParticlesAttractorBox::GPUParticlesAttractorBox() :
+ GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_BOX_ATTRACT) {
+}
+
+GPUParticlesAttractorBox::~GPUParticlesAttractorBox() {
+}
+
+///////////////////////////
+
+void GPUParticlesAttractorVectorField::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorVectorField::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorVectorField::get_extents);
+
+ ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesAttractorVectorField::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesAttractorVectorField::get_texture);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture");
+}
+
+void GPUParticlesAttractorVectorField::set_extents(const Vector3 &p_extents) {
+ extents = p_extents;
+ RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
+ update_gizmo();
+}
+
+Vector3 GPUParticlesAttractorVectorField::get_extents() const {
+ return extents;
+}
+
+void GPUParticlesAttractorVectorField::set_texture(const Ref<Texture3D> &p_texture) {
+ texture = p_texture;
+ RID tex = texture.is_valid() ? texture->get_rid() : RID();
+ RS::get_singleton()->particles_collision_set_field_texture(_get_collision(), tex);
+}
+
+Ref<Texture3D> GPUParticlesAttractorVectorField::get_texture() const {
+ return texture;
+}
+
+AABB GPUParticlesAttractorVectorField::get_aabb() const {
+ return AABB(-extents, extents * 2);
+}
+
+GPUParticlesAttractorVectorField::GPUParticlesAttractorVectorField() :
+ GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT) {
+}
+
+GPUParticlesAttractorVectorField::~GPUParticlesAttractorVectorField() {
+}
diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h
new file mode 100644
index 0000000000..81c33663f3
--- /dev/null
+++ b/scene/3d/gpu_particles_collision_3d.h
@@ -0,0 +1,342 @@
+/*************************************************************************/
+/* gpu_particles_collision_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 GPU_PARTICLES_COLLISION_3D_H
+#define GPU_PARTICLES_COLLISION_3D_H
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid.h"
+#include "scene/3d/visual_instance_3d.h"
+#include "scene/resources/material.h"
+
+class GPUParticlesCollision3D : public VisualInstance3D {
+ GDCLASS(GPUParticlesCollision3D, VisualInstance3D);
+
+ uint32_t cull_mask = 0xFFFFFFFF;
+ RID collision;
+
+protected:
+ _FORCE_INLINE_ RID _get_collision() { return collision; }
+ static void _bind_methods();
+
+ GPUParticlesCollision3D(RS::ParticlesCollisionType p_type);
+
+public:
+ void set_cull_mask(uint32_t p_cull_mask);
+ uint32_t get_cull_mask() const;
+
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override { return Vector<Face3>(); }
+
+ ~GPUParticlesCollision3D();
+};
+
+class GPUParticlesCollisionSphere : public GPUParticlesCollision3D {
+ GDCLASS(GPUParticlesCollisionSphere, GPUParticlesCollision3D);
+
+ float radius = 1.0;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_radius(float p_radius);
+ float get_radius() const;
+
+ virtual AABB get_aabb() const override;
+
+ GPUParticlesCollisionSphere();
+ ~GPUParticlesCollisionSphere();
+};
+
+class GPUParticlesCollisionBox : public GPUParticlesCollision3D {
+ GDCLASS(GPUParticlesCollisionBox, GPUParticlesCollision3D);
+
+ Vector3 extents = Vector3(1, 1, 1);
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_extents(const Vector3 &p_extents);
+ Vector3 get_extents() const;
+
+ virtual AABB get_aabb() const override;
+
+ GPUParticlesCollisionBox();
+ ~GPUParticlesCollisionBox();
+};
+
+class GPUParticlesCollisionSDF : public GPUParticlesCollision3D {
+ GDCLASS(GPUParticlesCollisionSDF, GPUParticlesCollision3D);
+
+public:
+ enum Resolution {
+ RESOLUTION_16,
+ RESOLUTION_32,
+ RESOLUTION_64,
+ RESOLUTION_128,
+ RESOLUTION_256,
+ RESOLUTION_512,
+ RESOLUTION_MAX,
+ };
+
+ typedef void (*BakeBeginFunc)(int);
+ typedef void (*BakeStepFunc)(int, const String &);
+ typedef void (*BakeEndFunc)();
+
+private:
+ Vector3 extents = Vector3(1, 1, 1);
+ Resolution resolution = RESOLUTION_64;
+ Ref<Texture3D> texture;
+ float thickness = 1.0;
+
+ struct PlotMesh {
+ Ref<Mesh> mesh;
+ Transform local_xform;
+ };
+
+ void _find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes);
+
+ struct BVH {
+ enum {
+ LEAF_BIT = 1 << 30,
+ LEAF_MASK = LEAF_BIT - 1
+ };
+ AABB bounds;
+ uint32_t children[2] = {};
+ };
+
+ struct FacePos {
+ Vector3 center;
+ uint32_t index = 0;
+ };
+
+ struct FaceSort {
+ uint32_t axis = 0;
+ bool operator()(const FacePos &p_left, const FacePos &p_right) const {
+ return p_left.center[axis] < p_right.center[axis];
+ }
+ };
+
+ uint32_t _create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness);
+
+ struct ComputeSDFParams {
+ float *cells = nullptr;
+ Vector3i size;
+ float cell_size = 0.0;
+ Vector3 cell_offset;
+ const BVH *bvh = nullptr;
+ const Face3 *triangles = nullptr;
+ float thickness = 0.0;
+ };
+
+ void _find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance);
+ void _compute_sdf_z(uint32_t p_z, ComputeSDFParams *params);
+ void _compute_sdf(ComputeSDFParams *params);
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_thickness(float p_thickness);
+ float get_thickness() const;
+
+ void set_extents(const Vector3 &p_extents);
+ Vector3 get_extents() const;
+
+ void set_resolution(Resolution p_resolution);
+ Resolution get_resolution() const;
+
+ void set_texture(const Ref<Texture3D> &p_texture);
+ Ref<Texture3D> get_texture() const;
+
+ Vector3i get_estimated_cell_size() const;
+ Ref<Image> bake();
+
+ virtual AABB get_aabb() const override;
+
+ static BakeBeginFunc bake_begin_function;
+ static BakeStepFunc bake_step_function;
+ static BakeEndFunc bake_end_function;
+
+ GPUParticlesCollisionSDF();
+ ~GPUParticlesCollisionSDF();
+};
+
+VARIANT_ENUM_CAST(GPUParticlesCollisionSDF::Resolution)
+
+class GPUParticlesCollisionHeightField : public GPUParticlesCollision3D {
+ GDCLASS(GPUParticlesCollisionHeightField, GPUParticlesCollision3D);
+
+public:
+ enum Resolution {
+ RESOLUTION_256,
+ RESOLUTION_512,
+ RESOLUTION_1024,
+ RESOLUTION_2048,
+ RESOLUTION_4096,
+ RESOLUTION_8192,
+ RESOLUTION_MAX,
+ };
+
+ enum UpdateMode {
+ UPDATE_MODE_WHEN_MOVED,
+ UPDATE_MODE_ALWAYS,
+ };
+
+private:
+ Vector3 extents = Vector3(1, 1, 1);
+ Resolution resolution = RESOLUTION_1024;
+ bool follow_camera_mode = false;
+ float follow_camera_push_ratio = 0.1;
+
+ UpdateMode update_mode = UPDATE_MODE_WHEN_MOVED;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_extents(const Vector3 &p_extents);
+ Vector3 get_extents() const;
+
+ void set_resolution(Resolution p_resolution);
+ Resolution get_resolution() const;
+
+ void set_update_mode(UpdateMode p_update_mode);
+ UpdateMode get_update_mode() const;
+
+ void set_follow_camera_mode(bool p_enabled);
+ bool is_follow_camera_mode_enabled() const;
+
+ void set_follow_camera_push_ratio(float p_ratio);
+ float get_follow_camera_push_ratio() const;
+
+ virtual AABB get_aabb() const override;
+
+ GPUParticlesCollisionHeightField();
+ ~GPUParticlesCollisionHeightField();
+};
+
+VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField::Resolution)
+VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField::UpdateMode)
+
+class GPUParticlesAttractor3D : public VisualInstance3D {
+ GDCLASS(GPUParticlesAttractor3D, VisualInstance3D);
+
+ uint32_t cull_mask = 0xFFFFFFFF;
+ RID collision;
+ float strength = 1.0;
+ float attenuation = 1.0;
+ float directionality = 0.0;
+
+protected:
+ _FORCE_INLINE_ RID _get_collision() { return collision; }
+ static void _bind_methods();
+
+ GPUParticlesAttractor3D(RS::ParticlesCollisionType p_type);
+
+public:
+ void set_cull_mask(uint32_t p_cull_mask);
+ uint32_t get_cull_mask() const;
+
+ void set_strength(float p_strength);
+ float get_strength() const;
+
+ void set_attenuation(float p_attenuation);
+ float get_attenuation() const;
+
+ void set_directionality(float p_directionality);
+ float get_directionality() const;
+
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override { return Vector<Face3>(); }
+
+ ~GPUParticlesAttractor3D();
+};
+
+class GPUParticlesAttractorSphere : public GPUParticlesAttractor3D {
+ GDCLASS(GPUParticlesAttractorSphere, GPUParticlesAttractor3D);
+
+ float radius = 1.0;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_radius(float p_radius);
+ float get_radius() const;
+
+ virtual AABB get_aabb() const override;
+
+ GPUParticlesAttractorSphere();
+ ~GPUParticlesAttractorSphere();
+};
+
+class GPUParticlesAttractorBox : public GPUParticlesAttractor3D {
+ GDCLASS(GPUParticlesAttractorBox, GPUParticlesAttractor3D);
+
+ Vector3 extents = Vector3(1, 1, 1);
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_extents(const Vector3 &p_extents);
+ Vector3 get_extents() const;
+
+ virtual AABB get_aabb() const override;
+
+ GPUParticlesAttractorBox();
+ ~GPUParticlesAttractorBox();
+};
+
+class GPUParticlesAttractorVectorField : public GPUParticlesAttractor3D {
+ GDCLASS(GPUParticlesAttractorVectorField, GPUParticlesAttractor3D);
+
+ Vector3 extents = Vector3(1, 1, 1);
+ Ref<Texture3D> texture;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_extents(const Vector3 &p_extents);
+ Vector3 get_extents() const;
+
+ void set_texture(const Ref<Texture3D> &p_texture);
+ Ref<Texture3D> get_texture() const;
+
+ virtual AABB get_aabb() const override;
+
+ GPUParticlesAttractorVectorField();
+ ~GPUParticlesAttractorVectorField();
+};
+
+#endif // GPU_PARTICLES_COLLISION_3D_H
diff --git a/scene/3d/immediate_geometry_3d.cpp b/scene/3d/immediate_geometry_3d.cpp
index 7ccfd527a1..d64babaa9d 100644
--- a/scene/3d/immediate_geometry_3d.cpp
+++ b/scene/3d/immediate_geometry_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -87,21 +87,24 @@ Vector<Face3> ImmediateGeometry3D::get_faces(uint32_t p_usage_flags) const {
}
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 = Math_PI * (-0.5 + (double)(i - 1) / p_lats);
+ double lat0 = lat_step * (i - 1) - Math_TAU / 4;
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
- double lat1 = Math_PI * (-0.5 + (double)i / p_lats);
+ 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 = 2 * Math_PI * (double)(j - 1) / p_lons;
+ double lng0 = lon_step * (j - 1);
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
- double lng1 = 2 * Math_PI * (double)(j) / p_lons;
+ double lng1 = lon_step * j;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
@@ -147,7 +150,6 @@ void ImmediateGeometry3D::_bind_methods() {
ImmediateGeometry3D::ImmediateGeometry3D() {
im = RenderingServer::get_singleton()->immediate_create();
set_base(im);
- empty = true;
}
ImmediateGeometry3D::~ImmediateGeometry3D() {
diff --git a/scene/3d/immediate_geometry_3d.h b/scene/3d/immediate_geometry_3d.h
index 7c9e8851a2..ee4938d9f7 100644
--- a/scene/3d/immediate_geometry_3d.h
+++ b/scene/3d/immediate_geometry_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -41,7 +41,7 @@ class ImmediateGeometry3D : public GeometryInstance3D {
//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;
+ bool empty = true;
AABB aabb;
protected:
@@ -62,8 +62,8 @@ public:
void add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv = true);
- virtual AABB get_aabb() const;
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual AABB get_aabb() const override;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
ImmediateGeometry3D();
~ImmediateGeometry3D();
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 814e911372..b0a10b5547 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,8 +30,8 @@
#include "light_3d.h"
-#include "core/engine.h"
-#include "core/project_settings.h"
+#include "core/config/engine.h"
+#include "core/config/project_settings.h"
#include "scene/resources/surface_tool.h"
bool Light3D::_can_gizmo_scale() const {
@@ -48,11 +48,7 @@ void Light3D::set_param(Param p_param, float p_value) {
update_gizmo();
if (p_param == PARAM_SPOT_ANGLE) {
- _change_notify("spot_angle");
update_configuration_warning();
- } else if (p_param == PARAM_RANGE) {
- _change_notify("omni_range");
- _change_notify("spot_range");
}
}
}
@@ -144,7 +140,7 @@ Vector<Face3> Light3D::get_faces(uint32_t p_usage_flags) const {
void Light3D::set_bake_mode(BakeMode p_mode) {
bake_mode = p_mode;
- RS::get_singleton()->light_set_use_gi(light, p_mode != BAKE_DISABLED);
+ RS::get_singleton()->light_set_bake_mode(light, RS::LightBakeMode(p_mode));
}
Light3D::BakeMode Light3D::get_bake_mode() const {
@@ -184,8 +180,6 @@ void Light3D::_update_visibility() {
#endif
RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree() && editor_ok);
-
- _change_notify("geometry/visible");
}
void Light3D::_notification(int p_what) {
@@ -212,6 +206,10 @@ void Light3D::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
+ if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_specular") {
+ property.usage = 0;
+ }
+
if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") {
property.usage = 0;
}
@@ -257,11 +255,11 @@ void Light3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,64,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01"), "set_param", "get_param", PARAM_SIZE);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disable,Indirect,All"), "set_bake_mode", "get_bake_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disabled,Dynamic,Static"), "set_bake_mode", "get_bake_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "light_cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
ADD_GROUP("Shadow", "shadow_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow");
@@ -270,6 +268,7 @@ void Light3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_fog_fade", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_param", "get_param", PARAM_SHADOW_VOLUMETRIC_FOG_FADE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0.1,8,0.01"), "set_param", "get_param", PARAM_SHADOW_BLUR);
ADD_GROUP("Editor", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only");
@@ -292,12 +291,13 @@ void Light3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS);
BIND_ENUM_CONSTANT(PARAM_SHADOW_PANCAKE_SIZE);
BIND_ENUM_CONSTANT(PARAM_SHADOW_BLUR);
+ BIND_ENUM_CONSTANT(PARAM_SHADOW_VOLUMETRIC_FOG_FADE);
BIND_ENUM_CONSTANT(PARAM_TRANSMITTANCE_BIAS);
BIND_ENUM_CONSTANT(PARAM_MAX);
BIND_ENUM_CONSTANT(BAKE_DISABLED);
- BIND_ENUM_CONSTANT(BAKE_INDIRECT);
- BIND_ENUM_CONSTANT(BAKE_ALL);
+ BIND_ENUM_CONSTANT(BAKE_DYNAMIC);
+ BIND_ENUM_CONSTANT(BAKE_STATIC);
}
Light3D::Light3D(RenderingServer::LightType p_type) {
@@ -318,10 +318,6 @@ Light3D::Light3D(RenderingServer::LightType p_type) {
RS::get_singleton()->instance_set_base(get_instance(), light);
- reverse_cull = false;
- bake_mode = BAKE_INDIRECT;
-
- editor_only = false;
set_color(Color(1, 1, 1, 1));
set_shadow(false);
set_negative(false);
@@ -345,12 +341,12 @@ Light3D::Light3D(RenderingServer::LightType p_type) {
set_param(PARAM_SHADOW_BIAS, 0.02);
set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0);
set_param(PARAM_TRANSMITTANCE_BIAS, 0.05);
+ set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 0.1);
set_param(PARAM_SHADOW_FADE_START, 1);
set_disable_scale(true);
}
Light3D::Light3D() {
- type = RenderingServer::LIGHT_DIRECTIONAL;
ERR_PRINT("Light3D should not be instanced directly; use the DirectionalLight3D, OmniLight3D or SpotLight3D subtypes instead.");
}
@@ -391,6 +387,15 @@ bool DirectionalLight3D::is_blend_splits_enabled() const {
return blend_splits;
}
+void DirectionalLight3D::set_sky_only(bool p_sky_only) {
+ sky_only = p_sky_only;
+ RS::get_singleton()->light_directional_set_sky_only(light, p_sky_only);
+}
+
+bool DirectionalLight3D::is_sky_only() const {
+ return sky_only;
+}
+
void DirectionalLight3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &DirectionalLight3D::set_shadow_mode);
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &DirectionalLight3D::get_shadow_mode);
@@ -401,8 +406,11 @@ void DirectionalLight3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blend_splits", "enabled"), &DirectionalLight3D::set_blend_splits);
ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight3D::is_blend_splits_enabled);
+ ClassDB::bind_method(D_METHOD("set_sky_only", "priority"), &DirectionalLight3D::set_sky_only);
+ ClassDB::bind_method(D_METHOD("is_sky_only"), &DirectionalLight3D::is_sky_only);
+
ADD_GROUP("Directional Shadow", "directional_shadow_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal,PSSM 2 Splits,PSSM 4 Splits"), "set_shadow_mode", "get_shadow_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal (Fast),PSSM 2 Splits (Average),PSSM 4 Splits (Slow)"), "set_shadow_mode", "get_shadow_mode");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_1", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_1_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_2", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_2_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET);
@@ -412,6 +420,8 @@ void DirectionalLight3D::_bind_methods() {
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_PROPERTY(PropertyInfo(Variant::BOOL, "use_in_sky_only"), "set_sky_only", "is_sky_only");
+
BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL);
BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS);
BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS);
@@ -424,9 +434,11 @@ DirectionalLight3D::DirectionalLight3D() :
Light3D(RenderingServer::LIGHT_DIRECTIONAL) {
set_param(PARAM_SHADOW_MAX_DISTANCE, 100);
set_param(PARAM_SHADOW_FADE_START, 0.8);
+ // Increase the default shadow bias to better suit most scenes.
+ // Leave normal bias untouched as it doesn't benefit DirectionalLight3D as much as OmniLight3D.
+ set_param(PARAM_SHADOW_BIAS, 0.05);
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE);
-
blend_splits = false;
}
@@ -443,7 +455,7 @@ String OmniLight3D::get_configuration_warning() const {
String warning = Light3D::get_configuration_warning();
if (!has_shadow() && get_projector().is_valid()) {
- if (warning != String()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Projector texture only works with shadows active.");
@@ -468,21 +480,23 @@ void OmniLight3D::_bind_methods() {
OmniLight3D::OmniLight3D() :
Light3D(RenderingServer::LIGHT_OMNI) {
set_shadow_mode(SHADOW_CUBE);
+ // Increase the default shadow biases to better suit most scenes.
+ set_param(PARAM_SHADOW_BIAS, 0.1);
+ set_param(PARAM_SHADOW_NORMAL_BIAS, 2.0);
}
String SpotLight3D::get_configuration_warning() const {
String warning = Light3D::get_configuration_warning();
if (has_shadow() && get_param(PARAM_SPOT_ANGLE) >= 90.0) {
- if (warning != String()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
-
warning += TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows.");
}
if (!has_shadow() && get_projector().is_valid()) {
- if (warning != String()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Projector texture only works with shadows active.");
diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h
index f16773f6ae..311db54bce 100644
--- a/scene/3d/light_3d.h
+++ b/scene/3d/light_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef LIGHT_H
-#define LIGHT_H
+#ifndef LIGHT_3D_H
+#define LIGHT_3D_H
#include "scene/3d/visual_instance_3d.h"
#include "scene/resources/texture.h"
@@ -58,28 +58,29 @@ public:
PARAM_SHADOW_BIAS = RS::LIGHT_PARAM_SHADOW_BIAS,
PARAM_SHADOW_PANCAKE_SIZE = RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE,
PARAM_SHADOW_BLUR = RS::LIGHT_PARAM_SHADOW_BLUR,
+ PARAM_SHADOW_VOLUMETRIC_FOG_FADE = RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE,
PARAM_TRANSMITTANCE_BIAS = RS::LIGHT_PARAM_TRANSMITTANCE_BIAS,
PARAM_MAX = RS::LIGHT_PARAM_MAX
};
enum BakeMode {
BAKE_DISABLED,
- BAKE_INDIRECT,
- BAKE_ALL
+ BAKE_DYNAMIC,
+ BAKE_STATIC
};
private:
Color color;
- float param[PARAM_MAX];
+ float param[PARAM_MAX] = {};
Color shadow_color;
- bool shadow;
- bool negative;
- bool reverse_cull;
- uint32_t cull_mask;
- RS::LightType type;
- bool editor_only;
+ bool shadow = false;
+ bool negative = false;
+ bool reverse_cull = false;
+ uint32_t cull_mask = 0;
+ RS::LightType type = RenderingServer::LIGHT_DIRECTIONAL;
+ bool editor_only = false;
void _update_visibility();
- BakeMode bake_mode;
+ BakeMode bake_mode = BAKE_DYNAMIC;
Ref<Texture2D> projector;
// bind helpers
@@ -91,7 +92,7 @@ protected:
static void _bind_methods();
void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
Light3D(RenderingServer::LightType p_type);
@@ -128,8 +129,8 @@ public:
void set_projector(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_projector() const;
- virtual AABB get_aabb() const;
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual AABB get_aabb() const override;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
Light3D();
~Light3D();
@@ -145,7 +146,7 @@ public:
enum ShadowMode {
SHADOW_ORTHOGONAL,
SHADOW_PARALLEL_2_SPLITS,
- SHADOW_PARALLEL_4_SPLITS
+ SHADOW_PARALLEL_4_SPLITS,
};
enum ShadowDepthRange {
@@ -157,6 +158,7 @@ private:
bool blend_splits;
ShadowMode shadow_mode;
ShadowDepthRange shadow_depth_range;
+ bool sky_only = false;
protected:
static void _bind_methods();
@@ -171,6 +173,9 @@ public:
void set_blend_splits(bool p_enable);
bool is_blend_splits_enabled() const;
+ void set_sky_only(bool p_sky_only);
+ bool is_sky_only() const;
+
DirectionalLight3D();
};
@@ -197,7 +202,7 @@ public:
void set_shadow_mode(ShadowMode p_mode);
ShadowMode get_shadow_mode() const;
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
OmniLight3D();
};
@@ -211,10 +216,10 @@ protected:
static void _bind_methods();
public:
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
SpotLight3D() :
Light3D(RenderingServer::LIGHT_SPOT) {}
};
-#endif
+#endif // LIGHT_3D_H
diff --git a/scene/3d/lightmap_probe.cpp b/scene/3d/lightmap_probe.cpp
index ee21934b80..830b97ffab 100644
--- a/scene/3d/lightmap_probe.cpp
+++ b/scene/3d/lightmap_probe.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
diff --git a/scene/3d/lightmap_probe.h b/scene/3d/lightmap_probe.h
index c4bd33556f..df87ed49dd 100644
--- a/scene/3d/lightmap_probe.h
+++ b/scene/3d/lightmap_probe.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
diff --git a/scene/3d/lightmapper.cpp b/scene/3d/lightmapper.cpp
index 26faf5154c..c17ac52aa2 100644
--- a/scene/3d/lightmapper.cpp
+++ b/scene/3d/lightmapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h
index ccf9bde279..a07a964c01 100644
--- a/scene/3d/lightmapper.h
+++ b/scene/3d/lightmapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp
index 0a5b9ad09f..9842f152d7 100644
--- a/scene/3d/listener_3d.cpp
+++ b/scene/3d/listener_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -159,8 +159,6 @@ void Listener3D::_bind_methods() {
}
Listener3D::Listener3D() {
- current = false;
- force_change = false;
set_notify_transform(true);
//active=false;
}
diff --git a/scene/3d/listener_3d.h b/scene/3d/listener_3d.h
index 4b6923d6e8..85657a8e53 100644
--- a/scene/3d/listener_3d.h
+++ b/scene/3d/listener_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -38,8 +38,8 @@ class Listener3D : public Node3D {
GDCLASS(Listener3D, Node3D);
private:
- bool force_change;
- bool current;
+ bool force_change = false;
+ bool current = false;
RID scenario_id;
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index 13f40aed4f..b997c64b29 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -95,7 +95,7 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
ls.sort();
for (List<String>::Element *E = ls.front(); E; E = E->next()) {
- p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "0,1,0.00001"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "-1,1,0.00001"));
}
if (mesh.is_valid()) {
@@ -112,7 +112,6 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
if (mesh.is_valid()) {
mesh->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &MeshInstance3D::_mesh_changed));
- materials.clear();
}
mesh = p_mesh;
@@ -136,7 +135,7 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
update_gizmo();
- _change_notify();
+ notify_property_list_changed();
}
Ref<Mesh> MeshInstance3D::get_mesh() const {
@@ -153,7 +152,7 @@ void MeshInstance3D::_resolve_skeleton_path() {
if (skin_internal.is_null()) {
//a skin was created for us
skin_internal = new_skin_reference->get_skin();
- _change_notify();
+ notify_property_list_changed();
}
}
}
@@ -320,6 +319,7 @@ Ref<Material> MeshInstance3D::get_active_material(int p_surface) const {
}
void MeshInstance3D::_mesh_changed() {
+ ERR_FAIL_COND(mesh.is_null());
materials.resize(mesh->get_surface_count());
}
@@ -429,7 +429,6 @@ void MeshInstance3D::_bind_methods() {
}
MeshInstance3D::MeshInstance3D() {
- skeleton_path = NodePath("..");
}
MeshInstance3D::~MeshInstance3D() {
diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h
index e29204f702..eb300784b1 100644
--- a/scene/3d/mesh_instance_3d.h
+++ b/scene/3d/mesh_instance_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -44,15 +44,11 @@ protected:
Ref<Skin> skin;
Ref<Skin> skin_internal;
Ref<SkinReference> skin_ref;
- NodePath skeleton_path;
+ NodePath skeleton_path = NodePath("..");
struct BlendShapeTrack {
- int idx;
- float value;
- BlendShapeTrack() {
- idx = 0;
- value = 0;
- }
+ int idx = 0;
+ float value = 0.0;
};
Map<StringName, BlendShapeTrack> blend_shape_tracks;
@@ -92,8 +88,8 @@ public:
void create_debug_tangents();
- virtual AABB get_aabb() const;
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual AABB get_aabb() const override;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
MeshInstance3D();
~MeshInstance3D();
diff --git a/scene/3d/multimesh_instance_3d.cpp b/scene/3d/multimesh_instance_3d.cpp
index 88dff111f7..2adef115cf 100644
--- a/scene/3d/multimesh_instance_3d.cpp
+++ b/scene/3d/multimesh_instance_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
diff --git a/scene/3d/multimesh_instance_3d.h b/scene/3d/multimesh_instance_3d.h
index 87ec9e120e..63735fd3a6 100644
--- a/scene/3d/multimesh_instance_3d.h
+++ b/scene/3d/multimesh_instance_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -44,12 +44,12 @@ protected:
// bind helpers
public:
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
void set_multimesh(const Ref<MultiMesh> &p_multimesh);
Ref<MultiMesh> get_multimesh() const;
- virtual AABB get_aabb() const;
+ virtual AABB get_aabb() const override;
MultiMeshInstance3D();
~MultiMeshInstance3D();
diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp
index 07a4824c28..eaddec7601 100644
--- a/scene/3d/navigation_3d.cpp
+++ b/scene/3d/navigation_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -109,9 +109,7 @@ Navigation3D::Navigation3D() {
map = NavigationServer3D::get_singleton()->map_create();
set_cell_size(0.3);
- set_edge_connection_margin(5.0); // Five meters, depends alot on the agents radius
-
- up = Vector3(0, 1, 0);
+ set_edge_connection_margin(5.0); // Five meters, depends a lot on the agent's radius
}
Navigation3D::~Navigation3D() {
diff --git a/scene/3d/navigation_3d.h b/scene/3d/navigation_3d.h
index 890caed171..b89725a3f5 100644
--- a/scene/3d/navigation_3d.h
+++ b/scene/3d/navigation_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -39,7 +39,7 @@ class Navigation3D : public Node3D {
RID map;
- Vector3 up;
+ Vector3 up = Vector3(0, 1, 0);
real_t cell_size;
real_t edge_connection_margin;
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index f8d44506b6..8917cc4664 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,7 +30,7 @@
#include "navigation_agent_3d.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
#include "scene/3d/navigation_3d.h"
#include "servers/navigation_server_3d.h"
@@ -287,11 +287,16 @@ void NavigationAgent3D::_avoidance_done(Vector3 p_new_velocity) {
}
String NavigationAgent3D::get_configuration_warning() const {
+ String warning = Node::get_configuration_warning();
+
if (!Object::cast_to<Node3D>(get_parent())) {
- return TTR("The NavigationAgent3D can be used only under a spatial node.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("The NavigationAgent3D can be used only under a spatial node.");
}
- return String();
+ return warning;
}
void NavigationAgent3D::update_navigation() {
@@ -323,7 +328,7 @@ void NavigationAgent3D::update_navigation() {
segment[1] = navigation_path[nav_path_index];
segment[0].y -= navigation_height_offset;
segment[1].y -= navigation_height_offset;
- Vector3 p = Geometry::get_closest_point_to_segment(o, segment);
+ Vector3 p = Geometry3D::get_closest_point_to_segment(o, segment);
if (o.distance_to(p) >= path_max_distance) {
// To faraway, reload path
reload_path = true;
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index 6dc375ef24..bd890a051b 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,7 +31,7 @@
#ifndef NAVIGATION_AGENT_H
#define NAVIGATION_AGENT_H
-#include "core/vector.h"
+#include "core/templates/vector.h"
#include "scene/main/node.h"
class Node3D;
@@ -153,7 +153,7 @@ public:
void set_velocity(Vector3 p_velocity);
void _avoidance_done(Vector3 p_new_velocity);
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
private:
void update_navigation();
diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp
index 69fd5b02fc..01bf7de913 100644
--- a/scene/3d/navigation_obstacle_3d.cpp
+++ b/scene/3d/navigation_obstacle_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -113,11 +113,16 @@ Node *NavigationObstacle3D::get_navigation_node() const {
}
String NavigationObstacle3D::get_configuration_warning() const {
+ String warning = Node::get_configuration_warning();
+
if (!Object::cast_to<Node3D>(get_parent())) {
- return TTR("The NavigationObstacle3D only serves to provide collision avoidance to a spatial object.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("The NavigationObstacle3D only serves to provide collision avoidance to a spatial object.");
}
- return String();
+ return warning;
}
void NavigationObstacle3D::update_agent_shape() {
diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h
index c7d2b556af..b8d05b8a87 100644
--- a/scene/3d/navigation_obstacle_3d.h
+++ b/scene/3d/navigation_obstacle_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -62,7 +62,7 @@ public:
return agent;
}
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
private:
void update_agent_shape();
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index 15ed448a65..19bde94222 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -124,13 +124,13 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmes
}
if (navmesh.is_valid()) {
- navmesh->remove_change_receptor(this);
+ navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed));
}
navmesh = p_navmesh;
if (navmesh.is_valid()) {
- navmesh->add_change_receptor(this);
+ navmesh->connect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed));
}
NavigationServer3D::get_singleton()->region_set_navmesh(region, p_navmesh);
@@ -150,7 +150,7 @@ Ref<NavigationMesh> NavigationRegion3D::get_navigation_mesh() const {
}
struct BakeThreadsArgs {
- NavigationRegion3D *nav_region;
+ NavigationRegion3D *nav_region = nullptr;
};
void _bake_navigation_mesh(void *p_user_data) {
@@ -170,18 +170,18 @@ void _bake_navigation_mesh(void *p_user_data) {
}
void NavigationRegion3D::bake_navigation_mesh() {
- ERR_FAIL_COND(bake_thread != nullptr);
+ ERR_FAIL_COND(bake_thread.is_started());
BakeThreadsArgs *args = memnew(BakeThreadsArgs);
args->nav_region = this;
- bake_thread = Thread::create(_bake_navigation_mesh, args);
- ERR_FAIL_COND(bake_thread == nullptr);
+ bake_thread.start(_bake_navigation_mesh, args);
}
void NavigationRegion3D::_bake_finished(Ref<NavigationMesh> p_nav_mesh) {
set_navigation_mesh(p_nav_mesh);
- bake_thread = nullptr;
+ bake_thread.wait_to_finish();
+ emit_signal("bake_finished");
}
String NavigationRegion3D::get_configuration_warning() const {
@@ -189,19 +189,28 @@ String NavigationRegion3D::get_configuration_warning() const {
return String();
}
+ String warning = Node3D::get_configuration_warning();
+
if (!navmesh.is_valid()) {
- return TTR("A NavigationMesh resource must be set or created for this node to work.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("A NavigationMesh resource must be set or created for this node to work.");
}
+
const Node3D *c = this;
while (c) {
if (Object::cast_to<Navigation3D>(c)) {
- return String();
+ return warning;
}
c = Object::cast_to<Node3D>(c->get_parent());
}
- return TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ return warning + TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data.");
}
void NavigationRegion3D::_bind_methods() {
@@ -221,7 +230,7 @@ void NavigationRegion3D::_bind_methods() {
ADD_SIGNAL(MethodInfo("bake_finished"));
}
-void NavigationRegion3D::_changed_callback(Object *p_changed, const char *p_prop) {
+void NavigationRegion3D::_navigation_changed() {
update_gizmo();
update_configuration_warning();
}
@@ -233,7 +242,7 @@ NavigationRegion3D::NavigationRegion3D() {
NavigationRegion3D::~NavigationRegion3D() {
if (navmesh.is_valid()) {
- navmesh->remove_change_receptor(this);
+ navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed));
}
NavigationServer3D::get_singleton()->free(region);
}
diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h
index fcd2efd4ef..6ae15c9360 100644
--- a/scene/3d/navigation_region_3d.h
+++ b/scene/3d/navigation_region_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -46,12 +46,13 @@ class NavigationRegion3D : public Node3D {
Navigation3D *navigation = nullptr;
Node *debug_view = nullptr;
- Thread *bake_thread = nullptr;
+ Thread bake_thread;
+
+ void _navigation_changed();
protected:
void _notification(int p_what);
static void _bind_methods();
- void _changed_callback(Object *p_changed, const char *p_prop);
public:
void set_enabled(bool p_enabled);
@@ -65,7 +66,7 @@ public:
void bake_navigation_mesh();
void _bake_finished(Ref<NavigationMesh> p_nav_mesh);
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
NavigationRegion3D();
~NavigationRegion3D();
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 73f17060df..4575716f7a 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,8 +30,8 @@
#include "node_3d.h"
-#include "core/engine.h"
-#include "core/message_queue.h"
+#include "core/config/engine.h"
+#include "core/object/message_queue.h"
#include "scene/main/scene_tree.h"
#include "scene/main/window.h"
#include "scene/scene_string_names.h"
@@ -103,8 +103,8 @@ void Node3D::_propagate_transform_changed(Node3D *p_origin) {
data.children_lock++;
for (List<Node3D *>::Element *E = data.children.front(); E; E = E->next()) {
- if (E->get()->data.toplevel_active) {
- continue; //don't propagate to a toplevel
+ if (E->get()->data.top_level_active) {
+ continue; //don't propagate to a top_level
}
E->get()->_propagate_transform_changed(p_origin);
}
@@ -136,12 +136,12 @@ void Node3D::_notification(int p_what) {
data.C = nullptr;
}
- if (data.toplevel && !Engine::get_singleton()->is_editor_hint()) {
+ if (data.top_level && !Engine::get_singleton()->is_editor_hint()) {
if (data.parent) {
data.local_transform = data.parent->get_global_transform() * get_transform();
data.dirty = DIRTY_VECTORS; //global is always dirty upon entering a scene
}
- data.toplevel_active = true;
+ data.top_level_active = true;
}
data.dirty |= DIRTY_GLOBAL; //global is always dirty upon entering a scene
@@ -160,7 +160,7 @@ void Node3D::_notification(int p_what) {
}
data.parent = nullptr;
data.C = nullptr;
- data.toplevel_active = false;
+ data.top_level_active = false;
} break;
case NOTIFICATION_ENTER_WORLD: {
data.inside_world = true;
@@ -174,7 +174,7 @@ void Node3D::_notification(int p_what) {
ERR_FAIL_COND(!data.viewport);
if (get_script_instance()) {
- get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, nullptr, 0);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_enter_world);
}
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {
@@ -202,7 +202,7 @@ void Node3D::_notification(int p_what) {
#endif
if (get_script_instance()) {
- get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, nullptr, 0);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_exit_world);
}
data.viewport = nullptr;
@@ -226,10 +226,6 @@ void Node3D::_notification(int p_what) {
void Node3D::set_transform(const Transform &p_transform) {
data.local_transform = p_transform;
data.dirty |= DIRTY_VECTORS;
- _change_notify("translation");
- _change_notify("rotation");
- _change_notify("rotation_degrees");
- _change_notify("scale");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -238,9 +234,9 @@ void Node3D::set_transform(const Transform &p_transform) {
void Node3D::set_global_transform(const Transform &p_transform) {
Transform xform =
- (data.parent && !data.toplevel_active) ?
- data.parent->get_global_transform().affine_inverse() * p_transform :
- p_transform;
+ (data.parent && !data.top_level_active) ?
+ data.parent->get_global_transform().affine_inverse() * p_transform :
+ p_transform;
set_transform(xform);
}
@@ -261,7 +257,7 @@ Transform Node3D::get_global_transform() const {
_update_local_transform();
}
- if (data.parent && !data.toplevel_active) {
+ if (data.parent && !data.top_level_active) {
data.global_transform = data.parent->get_global_transform() * data.local_transform;
} else {
data.global_transform = data.local_transform;
@@ -307,7 +303,6 @@ Transform Node3D::get_relative_transform(const Node *p_parent) const {
void Node3D::set_translation(const Vector3 &p_translation) {
data.local_transform.origin = p_translation;
- _change_notify("transform");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -322,7 +317,6 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) {
data.rotation = p_euler_rad;
data.dirty |= DIRTY_LOCAL;
- _change_notify("transform");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -330,7 +324,7 @@ 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);
+ set_rotation(p_euler_deg * (Math_PI / 180.0));
}
void Node3D::set_scale(const Vector3 &p_scale) {
@@ -341,7 +335,6 @@ void Node3D::set_scale(const Vector3 &p_scale) {
data.scale = p_scale;
data.dirty |= DIRTY_LOCAL;
- _change_notify("transform");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -364,7 +357,7 @@ Vector3 Node3D::get_rotation() const {
}
Vector3 Node3D::get_rotation_degrees() const {
- return get_rotation() * 180.0 / Math_PI;
+ return get_rotation() * (180.0 / Math_PI);
}
Vector3 Node3D::get_scale() const {
@@ -462,8 +455,8 @@ bool Node3D::is_scale_disabled() const {
return data.disable_scale;
}
-void Node3D::set_as_toplevel(bool p_enabled) {
- if (data.toplevel == p_enabled) {
+void Node3D::set_as_top_level(bool p_enabled) {
+ if (data.top_level == p_enabled) {
return;
}
if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
@@ -473,16 +466,16 @@ void Node3D::set_as_toplevel(bool p_enabled) {
set_transform(data.parent->get_global_transform().affine_inverse() * get_global_transform());
}
- data.toplevel = p_enabled;
- data.toplevel_active = p_enabled;
+ data.top_level = p_enabled;
+ data.top_level_active = p_enabled;
} else {
- data.toplevel = p_enabled;
+ data.top_level = p_enabled;
}
}
-bool Node3D::is_set_as_toplevel() const {
- return data.toplevel;
+bool Node3D::is_set_as_top_level() const {
+ return data.top_level;
}
Ref<World3D> Node3D::get_world_3d() const {
@@ -495,7 +488,6 @@ Ref<World3D> Node3D::get_world_3d() const {
void Node3D::_propagate_visibility_changed() {
notification(NOTIFICATION_VISIBILITY_CHANGED);
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
- _change_notify("visible");
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
_update_gizmo();
@@ -715,8 +707,8 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_global_transform"), &Node3D::get_global_transform);
ClassDB::bind_method(D_METHOD("get_parent_spatial"), &Node3D::get_parent_spatial);
ClassDB::bind_method(D_METHOD("set_ignore_transform_notification", "enabled"), &Node3D::set_ignore_transform_notification);
- ClassDB::bind_method(D_METHOD("set_as_toplevel", "enable"), &Node3D::set_as_toplevel);
- ClassDB::bind_method(D_METHOD("is_set_as_toplevel"), &Node3D::is_set_as_toplevel);
+ ClassDB::bind_method(D_METHOD("set_as_top_level", "enable"), &Node3D::set_as_top_level);
+ ClassDB::bind_method(D_METHOD("is_set_as_top_level"), &Node3D::is_set_as_top_level);
ClassDB::bind_method(D_METHOD("set_disable_scale", "disable"), &Node3D::set_disable_scale);
ClassDB::bind_method(D_METHOD("is_scale_disabled"), &Node3D::is_scale_disabled);
ClassDB::bind_method(D_METHOD("get_world_3d"), &Node3D::get_world_3d);
@@ -755,8 +747,8 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("orthonormalize"), &Node3D::orthonormalize);
ClassDB::bind_method(D_METHOD("set_identity"), &Node3D::set_identity);
- ClassDB::bind_method(D_METHOD("look_at", "target", "up"), &Node3D::look_at);
- ClassDB::bind_method(D_METHOD("look_at_from_position", "position", "target", "up"), &Node3D::look_at_from_position);
+ ClassDB::bind_method(D_METHOD("look_at", "target", "up"), &Node3D::look_at, DEFVAL(Vector3(0, 1, 0)));
+ ClassDB::bind_method(D_METHOD("look_at_from_position", "position", "target", "up"), &Node3D::look_at_from_position, DEFVAL(Vector3(0, 1, 0)));
ClassDB::bind_method(D_METHOD("to_local", "global_point"), &Node3D::to_local);
ClassDB::bind_method(D_METHOD("to_global", "local_point"), &Node3D::to_global);
@@ -773,6 +765,7 @@ void Node3D::_bind_methods() {
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, "", 0), "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", "");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform");
ADD_GROUP("Visibility", "");
@@ -783,28 +776,4 @@ void Node3D::_bind_methods() {
}
Node3D::Node3D() :
- xform_change(this) {
- data.dirty = DIRTY_NONE;
- data.children_lock = 0;
-
- data.ignore_notification = false;
- data.toplevel = false;
- data.toplevel_active = false;
- data.scale = Vector3(1, 1, 1);
- data.viewport = nullptr;
- data.inside_world = false;
- data.visible = true;
- data.disable_scale = false;
-
-#ifdef TOOLS_ENABLED
- data.gizmo_disabled = false;
- data.gizmo_dirty = false;
-#endif
- data.notify_local_transform = false;
- data.notify_transform = false;
- data.parent = nullptr;
- data.C = nullptr;
-}
-
-Node3D::~Node3D() {
-}
+ xform_change(this) {}
diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h
index 327d4671e9..a62c7b31a8 100644
--- a/scene/3d/node_3d.h
+++ b/scene/3d/node_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -65,32 +65,32 @@ class Node3D : public Node {
mutable Transform global_transform;
mutable Transform local_transform;
mutable Vector3 rotation;
- mutable Vector3 scale;
+ mutable Vector3 scale = Vector3(1, 1, 1);
- mutable int dirty;
+ mutable int dirty = DIRTY_NONE;
- Viewport *viewport;
+ Viewport *viewport = nullptr;
- bool toplevel_active;
- bool toplevel;
- bool inside_world;
+ bool top_level_active = false;
+ bool top_level = false;
+ bool inside_world = false;
- int children_lock;
- Node3D *parent;
+ int children_lock = 0;
+ Node3D *parent = nullptr;
List<Node3D *> children;
- List<Node3D *>::Element *C;
+ List<Node3D *>::Element *C = nullptr;
- bool ignore_notification;
- bool notify_local_transform;
- bool notify_transform;
+ bool ignore_notification = false;
+ bool notify_local_transform = false;
+ bool notify_transform = false;
- bool visible;
- bool disable_scale;
+ bool visible = true;
+ bool disable_scale = false;
#ifdef TOOLS_ENABLED
Ref<Node3DGizmo> gizmo;
- bool gizmo_disabled;
- bool gizmo_dirty;
+ bool gizmo_disabled = false;
+ bool gizmo_dirty = false;
#endif
} data;
@@ -111,7 +111,6 @@ protected:
public:
enum {
-
NOTIFICATION_TRANSFORM_CHANGED = SceneTree::NOTIFICATION_TRANSFORM_CHANGED,
NOTIFICATION_ENTER_WORLD = 41,
NOTIFICATION_EXIT_WORLD = 42,
@@ -144,8 +143,8 @@ public:
virtual Transform get_local_gizmo_transform() const;
#endif
- void set_as_toplevel(bool p_enabled);
- bool is_set_as_toplevel() const;
+ void set_as_top_level(bool p_enabled);
+ bool is_set_as_top_level() const;
void set_disable_scale(bool p_enabled);
bool is_scale_disabled() const;
@@ -174,8 +173,8 @@ public:
void global_scale(const Vector3 &p_scale);
void global_translate(const Vector3 &p_offset);
- void look_at(const Vector3 &p_target, const Vector3 &p_up);
- void look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up);
+ void look_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
+ void look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
Vector3 to_local(Vector3 p_global) const;
Vector3 to_global(Vector3 p_local) const;
@@ -198,7 +197,6 @@ public:
void force_update_transform();
Node3D();
- ~Node3D();
};
#endif // NODE_3D_H
diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp
index dcfdf8efcf..7e2601902b 100644
--- a/scene/3d/path_3d.cpp
+++ b/scene/3d/path_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,7 +30,7 @@
#include "path_3d.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
#include "scene/scene_string_names.h"
void Path3D::_notification(int p_what) {
@@ -77,18 +77,14 @@ void Path3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path3D::set_curve);
ClassDB::bind_method(D_METHOD("get_curve"), &Path3D::get_curve);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve3D"), "set_curve", "get_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_curve", "get_curve");
ADD_SIGNAL(MethodInfo("curve_changed"));
}
-Path3D::Path3D() {
- set_curve(Ref<Curve3D>(memnew(Curve3D))); //create one by default
-}
-
//////////////
-void PathFollow3D::_update_transform() {
+void PathFollow3D::_update_transform(bool p_update_xyz_rot) {
if (!path) {
return;
}
@@ -98,10 +94,6 @@ void PathFollow3D::_update_transform() {
return;
}
- if (delta_offset == 0) {
- return;
- }
-
float bl = c->get_baked_length();
if (bl == 0.0) {
return;
@@ -160,45 +152,47 @@ void PathFollow3D::_update_transform() {
t.origin = pos;
- Vector3 t_prev = (pos - c->interpolate_baked(offset - delta_offset, cubic)).normalized();
- Vector3 t_cur = (c->interpolate_baked(offset + delta_offset, cubic) - pos).normalized();
-
- Vector3 axis = t_prev.cross(t_cur);
- float dot = t_prev.dot(t_cur);
- float angle = Math::acos(CLAMP(dot, -1, 1));
-
- if (likely(!Math::is_zero_approx(angle))) {
- if (rotation_mode == ROTATION_Y) {
- // assuming we're referring to global Y-axis. is this correct?
- axis.x = 0;
- axis.z = 0;
- } else if (rotation_mode == ROTATION_XY) {
- axis.z = 0;
- } else if (rotation_mode == ROTATION_XYZ) {
- // all components are allowed
- }
+ if (p_update_xyz_rot && delta_offset != 0) { // Only update rotation if some parameter has changed - i.e. not on addition to scene tree.
+ Vector3 t_prev = (pos - c->interpolate_baked(offset - delta_offset, cubic)).normalized();
+ Vector3 t_cur = (c->interpolate_baked(offset + delta_offset, cubic) - pos).normalized();
+
+ Vector3 axis = t_prev.cross(t_cur);
+ float dot = t_prev.dot(t_cur);
+ float angle = Math::acos(CLAMP(dot, -1, 1));
+
+ if (likely(!Math::is_zero_approx(angle))) {
+ if (rotation_mode == ROTATION_Y) {
+ // assuming we're referring to global Y-axis. is this correct?
+ axis.x = 0;
+ axis.z = 0;
+ } else if (rotation_mode == ROTATION_XY) {
+ axis.z = 0;
+ } else if (rotation_mode == ROTATION_XYZ) {
+ // all components are allowed
+ }
- if (likely(!Math::is_zero_approx(axis.length()))) {
- t.rotate_basis(axis.normalized(), angle);
+ if (likely(!Math::is_zero_approx(axis.length()))) {
+ t.rotate_basis(axis.normalized(), angle);
+ }
}
- }
- // do the additional tilting
- float tilt_angle = c->interpolate_baked_tilt(offset);
- Vector3 tilt_axis = t_cur; // not sure what tilt is supposed to do, is this correct??
-
- if (likely(!Math::is_zero_approx(Math::abs(tilt_angle)))) {
- if (rotation_mode == ROTATION_Y) {
- tilt_axis.x = 0;
- tilt_axis.z = 0;
- } else if (rotation_mode == ROTATION_XY) {
- tilt_axis.z = 0;
- } else if (rotation_mode == ROTATION_XYZ) {
- // all components are allowed
- }
+ // do the additional tilting
+ float tilt_angle = c->interpolate_baked_tilt(offset);
+ Vector3 tilt_axis = t_cur; // not sure what tilt is supposed to do, is this correct??
+
+ if (likely(!Math::is_zero_approx(Math::abs(tilt_angle)))) {
+ if (rotation_mode == ROTATION_Y) {
+ tilt_axis.x = 0;
+ tilt_axis.z = 0;
+ } else if (rotation_mode == ROTATION_XY) {
+ tilt_axis.z = 0;
+ } else if (rotation_mode == ROTATION_XYZ) {
+ // all components are allowed
+ }
- if (likely(!Math::is_zero_approx(tilt_axis.length()))) {
- t.rotate_basis(tilt_axis.normalized(), tilt_angle);
+ if (likely(!Math::is_zero_approx(tilt_axis.length()))) {
+ t.rotate_basis(tilt_axis.normalized(), tilt_angle);
+ }
}
}
@@ -217,7 +211,7 @@ void PathFollow3D::_notification(int p_what) {
if (parent) {
path = Object::cast_to<Path3D>(parent);
if (path) {
- _update_transform();
+ _update_transform(false);
}
}
@@ -252,16 +246,24 @@ String PathFollow3D::get_configuration_warning() const {
return String();
}
+ String warning = Node3D::get_configuration_warning();
+
if (!Object::cast_to<Path3D>(get_parent())) {
- return TTR("PathFollow3D only works when set as a child of a Path3D node.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("PathFollow3D only works when set as a child of a Path3D node.");
} else {
Path3D *path = Object::cast_to<Path3D>(get_parent());
if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) {
- return TTR("PathFollow3D's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path3D's Curve resource.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("PathFollow3D's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path3D's Curve resource.");
}
}
- return String();
+ return warning;
}
void PathFollow3D::_bind_methods() {
@@ -321,8 +323,6 @@ void PathFollow3D::set_offset(float p_offset) {
_update_transform();
}
- _change_notify("offset");
- _change_notify("unit_offset");
}
void PathFollow3D::set_h_offset(float p_h_offset) {
@@ -383,14 +383,3 @@ void PathFollow3D::set_loop(bool p_loop) {
bool PathFollow3D::has_loop() const {
return loop;
}
-
-PathFollow3D::PathFollow3D() {
- offset = 0;
- delta_offset = 0;
- h_offset = 0;
- v_offset = 0;
- path = nullptr;
- rotation_mode = ROTATION_XYZ;
- cubic = true;
- loop = true;
-}
diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h
index 5a33016bc6..17ee47593e 100644
--- a/scene/3d/path_3d.h
+++ b/scene/3d/path_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -49,7 +49,7 @@ public:
void set_curve(const Ref<Curve3D> &p_curve);
Ref<Curve3D> get_curve() const;
- Path3D();
+ Path3D() {}
};
class PathFollow3D : public Node3D {
@@ -57,7 +57,6 @@ class PathFollow3D : public Node3D {
public:
enum RotationMode {
-
ROTATION_NONE,
ROTATION_Y,
ROTATION_XY,
@@ -66,19 +65,19 @@ public:
};
private:
- Path3D *path;
- real_t delta_offset; // change in offset since last _update_transform
- real_t offset;
- real_t h_offset;
- real_t v_offset;
- bool cubic;
- bool loop;
- RotationMode rotation_mode;
+ Path3D *path = nullptr;
+ real_t delta_offset = 0.0; // Change in offset since last _update_transform.
+ real_t offset = 0.0;
+ real_t h_offset = 0.0;
+ real_t v_offset = 0.0;
+ bool cubic = true;
+ bool loop = true;
+ RotationMode rotation_mode = ROTATION_XYZ;
- void _update_transform();
+ void _update_transform(bool p_update_xyz_rot = true);
protected:
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
void _notification(int p_what);
static void _bind_methods();
@@ -105,9 +104,9 @@ public:
void set_cubic_interpolation(bool p_enable);
bool get_cubic_interpolation() const;
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
- PathFollow3D();
+ PathFollow3D() {}
};
VARIANT_ENUM_CAST(PathFollow3D::RotationMode);
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index de8f1eea2e..6d135c8283 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,12 +30,11 @@
#include "physics_body_3d.h"
+#include "core/config/engine.h"
#include "core/core_string_names.h"
-#include "core/engine.h"
-#include "core/list.h"
-#include "core/method_bind_ext.gen.inc"
-#include "core/object.h"
-#include "core/rid.h"
+#include "core/object/class_db.h"
+#include "core/templates/list.h"
+#include "core/templates/rid.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/scene_string_names.h"
#include "servers/navigation_server_3d.h"
@@ -52,7 +51,7 @@ Vector3 PhysicsBody3D::get_angular_velocity() const {
return Vector3();
}
-float PhysicsBody3D::get_inverse_mass() const {
+real_t PhysicsBody3D::get_inverse_mass() const {
return 0;
}
@@ -130,15 +129,6 @@ void PhysicsBody3D::remove_collision_exception_with(Node *p_node) {
PhysicsServer3D::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid());
}
-void PhysicsBody3D::_set_layers(uint32_t p_mask) {
- set_collision_layer(p_mask);
- set_collision_mask(p_mask);
-}
-
-uint32_t PhysicsBody3D::_get_layers() const {
- return get_collision_layer();
-}
-
void PhysicsBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &PhysicsBody3D::set_collision_layer);
ClassDB::bind_method(D_METHOD("get_collision_layer"), &PhysicsBody3D::get_collision_layer);
@@ -152,16 +142,14 @@ void PhysicsBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &PhysicsBody3D::set_collision_layer_bit);
ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &PhysicsBody3D::get_collision_layer_bit);
- ClassDB::bind_method(D_METHOD("_set_layers", "mask"), &PhysicsBody3D::_set_layers);
- ClassDB::bind_method(D_METHOD("_get_layers"), &PhysicsBody3D::_get_layers);
-
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");
}
PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) :
- CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(p_mode), false) {
+ CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) {
+ PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode);
collision_layer = 1;
collision_mask = 1;
}
@@ -324,7 +312,7 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
bool in_tree = E->get().in_tree;
- if (E->get().shapes.empty()) {
+ if (E->get().shapes.is_empty()) {
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree));
@@ -343,8 +331,8 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
struct _RigidBodyInOut {
ObjectID id;
- int shape;
- int local_shape;
+ int shape = 0;
+ int local_shape = 0;
};
void RigidBody3D::_direct_state_changed(Object *p_state) {
@@ -358,6 +346,7 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
set_global_transform(state->get_transform());
linear_velocity = state->get_linear_velocity();
angular_velocity = state->get_angular_velocity();
+ inverse_inertia_tensor = state->get_inverse_inertia_tensor();
if (sleeping != state->is_sleeping()) {
sleeping = state->is_sleeping();
emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed);
@@ -490,8 +479,6 @@ RigidBody3D::Mode RigidBody3D::get_mode() const {
void RigidBody3D::set_mass(real_t p_mass) {
ERR_FAIL_COND(p_mass <= 0);
mass = p_mass;
- _change_notify("mass");
- _change_notify("weight");
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_MASS, mass);
}
@@ -499,14 +486,6 @@ real_t RigidBody3D::get_mass() const {
return mass;
}
-void RigidBody3D::set_weight(real_t p_weight) {
- set_mass(p_weight / real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)));
-}
-
-real_t RigidBody3D::get_weight() const {
- return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8));
-}
-
void RigidBody3D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
if (physics_material_override.is_valid()) {
if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody3D::_reload_physics_characteristics))) {
@@ -594,6 +573,10 @@ Vector3 RigidBody3D::get_angular_velocity() const {
return angular_velocity;
}
+Basis RigidBody3D::get_inverse_inertia_tensor() {
+ return inverse_inertia_tensor;
+}
+
void RigidBody3D::set_use_custom_integrator(bool p_enable) {
if (custom_integrator == p_enable) {
return;
@@ -638,8 +621,9 @@ void RigidBody3D::add_central_force(const Vector3 &p_force) {
PhysicsServer3D::get_singleton()->body_add_central_force(get_rid(), p_force);
}
-void RigidBody3D::add_force(const Vector3 &p_force, const Vector3 &p_pos) {
- PhysicsServer3D::get_singleton()->body_add_force(get_rid(), p_force, p_pos);
+void RigidBody3D::add_force(const Vector3 &p_force, const Vector3 &p_position) {
+ PhysicsServer3D *singleton = PhysicsServer3D::get_singleton();
+ singleton->body_add_force(get_rid(), p_force, p_position);
}
void RigidBody3D::add_torque(const Vector3 &p_torque) {
@@ -650,8 +634,9 @@ void RigidBody3D::apply_central_impulse(const Vector3 &p_impulse) {
PhysicsServer3D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
}
-void RigidBody3D::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
- PhysicsServer3D::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
+void RigidBody3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
+ PhysicsServer3D *singleton = PhysicsServer3D::get_singleton();
+ singleton->body_apply_impulse(get_rid(), p_impulse, p_position);
}
void RigidBody3D::apply_torque_impulse(const Vector3 &p_impulse) {
@@ -730,7 +715,7 @@ String RigidBody3D::get_configuration_warning() const {
String warning = CollisionObject3D::get_configuration_warning();
if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) {
- if (warning != String()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Size changes to RigidBody3D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");
@@ -746,9 +731,6 @@ void RigidBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mass", "mass"), &RigidBody3D::set_mass);
ClassDB::bind_method(D_METHOD("get_mass"), &RigidBody3D::get_mass);
- ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody3D::set_weight);
- ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody3D::get_weight);
-
ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody3D::set_physics_material_override);
ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody3D::get_physics_material_override);
@@ -758,6 +740,8 @@ void RigidBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &RigidBody3D::set_angular_velocity);
ClassDB::bind_method(D_METHOD("get_angular_velocity"), &RigidBody3D::get_angular_velocity);
+ ClassDB::bind_method(D_METHOD("get_inverse_inertia_tensor"), &RigidBody3D::get_inverse_inertia_tensor);
+
ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidBody3D::set_gravity_scale);
ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidBody3D::get_gravity_scale);
@@ -782,11 +766,11 @@ void RigidBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody3D::set_axis_velocity);
ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidBody3D::add_central_force);
- ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidBody3D::add_force);
+ ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidBody3D::add_force, Vector3());
ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidBody3D::add_torque);
ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody3D::apply_central_impulse);
- ClassDB::bind_method(D_METHOD("apply_impulse", "position", "impulse"), &RigidBody3D::apply_impulse);
+ ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidBody3D::apply_impulse, Vector3());
ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &RigidBody3D::apply_torque_impulse);
ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidBody3D::set_sleeping);
@@ -806,7 +790,6 @@ void RigidBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,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, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight");
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");
@@ -843,24 +826,6 @@ void RigidBody3D::_bind_methods() {
RigidBody3D::RigidBody3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) {
- mode = MODE_RIGID;
-
- mass = 1;
- max_contacts_reported = 0;
- state = nullptr;
-
- gravity_scale = 1;
- linear_damp = -1;
- angular_damp = -1;
-
- //angular_velocity=0;
- sleeping = false;
- ccd = false;
-
- custom_integrator = false;
- contact_monitor = nullptr;
- can_sleep = true;
-
PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
}
@@ -942,9 +907,10 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
-Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) {
Vector3 body_velocity = p_linear_velocity;
Vector3 body_velocity_normal = body_velocity.normalized();
+ Vector3 up_direction = p_up_direction.normalized();
for (int i = 0; i < 3; i++) {
if (locked_axis & (1 << i)) {
@@ -988,11 +954,11 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
colliders.push_back(collision);
motion = collision.remainder;
- if (p_up_direction == Vector3()) {
+ if (up_direction == Vector3()) {
//all is a wall
on_wall = true;
} else {
- if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
+ if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true;
floor_normal = collision.normal;
@@ -1000,14 +966,14 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
floor_velocity = collision.collider_vel;
if (p_stop_on_slope) {
- if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) {
+ if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) {
Transform gt = get_global_transform();
- gt.origin -= collision.travel.slide(p_up_direction);
+ gt.origin -= collision.travel.slide(up_direction);
set_global_transform(gt);
return Vector3();
}
}
- } else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
+ } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true;
} else {
on_wall = true;
@@ -1035,10 +1001,11 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
return body_velocity;
}
-Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) {
+ Vector3 up_direction = p_up_direction.normalized();
bool was_on_floor = on_floor;
- Vector3 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
+ Vector3 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
if (!was_on_floor || p_snap == Vector3()) {
return ret;
}
@@ -1048,8 +1015,8 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
bool apply = true;
- if (p_up_direction != Vector3()) {
- if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
+ if (up_direction != Vector3()) {
+ if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
on_floor = true;
floor_normal = col.normal;
on_floor_body = col.collider_rid;
@@ -1057,7 +1024,7 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci
if (p_stop_on_slope) {
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
- col.travel = col.travel.project(p_up_direction);
+ col.travel = col.travel.project(up_direction);
}
} else {
apply = false; //snapped with floor direction, but did not snap to a floor, do not snap.
@@ -1106,7 +1073,7 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision
Vector3 recover;
int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin);
int deepest = -1;
- float deepest_depth;
+ real_t deepest_depth;
for (int i = 0; i < hits; i++) {
if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) {
deepest = i;
@@ -1147,12 +1114,12 @@ bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const {
return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis);
}
-void KinematicBody3D::set_safe_margin(float p_margin) {
+void KinematicBody3D::set_safe_margin(real_t p_margin) {
margin = p_margin;
PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin);
}
-float KinematicBody3D::get_safe_margin() const {
+real_t KinematicBody3D::get_safe_margin() const {
return margin;
}
@@ -1196,8 +1163,8 @@ void KinematicBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody3D::_direct_state_changed);
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody3D::test_move, DEFVAL(true));
@@ -1237,12 +1204,7 @@ void KinematicBody3D::_direct_state_changed(Object *p_state) {
KinematicBody3D::KinematicBody3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) {
- margin = 0.001;
- locked_axis = 0;
- on_floor = false;
- on_ceiling = false;
- on_wall = false;
-
+ set_safe_margin(0.001);
PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
}
@@ -1370,8 +1332,8 @@ void PhysicalBone3D::apply_central_impulse(const Vector3 &p_impulse) {
PhysicsServer3D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
}
-void PhysicalBone3D::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
- PhysicsServer3D::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
+void PhysicalBone3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
+ PhysicsServer3D::get_singleton()->body_apply_impulse(get_rid(), p_impulse, p_position);
}
void PhysicalBone3D::reset_physics_simulation_state() {
@@ -1732,6 +1694,10 @@ bool PhysicalBone3D::SixDOFJointData::_set(const StringName &p_name, const Varia
String path = p_name;
+ if (!path.begins_with("joint_constraints/")) {
+ return false;
+ }
+
Vector3::Axis axis;
{
const String axis_s = path.get_slicec('/', 1);
@@ -1888,6 +1854,10 @@ bool PhysicalBone3D::SixDOFJointData::_get(const StringName &p_name, Variant &r_
String path = p_name;
+ if (!path.begins_with("joint_constraints/")) {
+ return false;
+ }
+
int axis;
{
const String axis_s = path.get_slicec('/', 1);
@@ -1987,7 +1957,7 @@ bool PhysicalBone3D::_set(const StringName &p_name, const Variant &p_value) {
}
if (joint_data) {
- if (joint_data->_set(p_name, p_value)) {
+ if (joint_data->_set(p_name, p_value, joint)) {
#ifdef TOOLS_ENABLED
if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
@@ -2042,7 +2012,7 @@ void PhysicalBone3D::_notification(int p_what) {
update_bone_id();
reset_to_rest_position();
reset_physics_simulation_state();
- if (!joint.is_valid() && joint_data) {
+ if (joint_data) {
_reload_joint();
}
break;
@@ -2053,10 +2023,7 @@ void PhysicalBone3D::_notification(int p_what) {
}
}
parent_skeleton = nullptr;
- if (joint.is_valid()) {
- PhysicsServer3D::get_singleton()->free(joint);
- joint = RID();
- }
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
break;
case NOTIFICATION_TRANSFORM_CHANGED:
if (Engine::get_singleton()->is_editor_hint()) {
@@ -2097,7 +2064,7 @@ void PhysicalBone3D::_direct_state_changed(Object *p_state) {
void PhysicalBone3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &PhysicalBone3D::apply_central_impulse);
- ClassDB::bind_method(D_METHOD("apply_impulse", "position", "impulse"), &PhysicalBone3D::apply_impulse);
+ ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &PhysicalBone3D::apply_impulse, Vector3());
ClassDB::bind_method(D_METHOD("_direct_state_changed"), &PhysicalBone3D::_direct_state_changed);
@@ -2123,9 +2090,6 @@ void PhysicalBone3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mass", "mass"), &PhysicalBone3D::set_mass);
ClassDB::bind_method(D_METHOD("get_mass"), &PhysicalBone3D::get_mass);
- ClassDB::bind_method(D_METHOD("set_weight", "weight"), &PhysicalBone3D::set_weight);
- ClassDB::bind_method(D_METHOD("get_weight"), &PhysicalBone3D::get_weight);
-
ClassDB::bind_method(D_METHOD("set_friction", "friction"), &PhysicalBone3D::set_friction);
ClassDB::bind_method(D_METHOD("get_friction"), &PhysicalBone3D::get_friction);
@@ -2156,7 +2120,6 @@ void PhysicalBone3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "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, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_weight", "get_weight");
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");
@@ -2210,17 +2173,14 @@ void PhysicalBone3D::_fix_joint_offset() {
}
void PhysicalBone3D::_reload_joint() {
- if (joint.is_valid()) {
- PhysicsServer3D::get_singleton()->free(joint);
- joint = RID();
- }
-
if (!parent_skeleton) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
return;
}
PhysicalBone3D *body_a = parent_skeleton->get_physical_bone_parent(bone_id);
if (!body_a) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
return;
}
@@ -2230,7 +2190,7 @@ void PhysicalBone3D::_reload_joint() {
switch (get_joint_type()) {
case JOINT_TYPE_PIN: {
- joint = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin);
+ PhysicsServer3D::get_singleton()->joint_make_pin(joint, body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin);
const PinJointData *pjd(static_cast<const PinJointData *>(joint_data));
PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_BIAS, pjd->bias);
PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_DAMPING, pjd->damping);
@@ -2238,7 +2198,7 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_CONE: {
- joint = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset);
+ PhysicsServer3D::get_singleton()->joint_make_cone_twist(joint, body_a->get_rid(), local_a, get_rid(), joint_offset);
const ConeJointData *cjd(static_cast<const ConeJointData *>(joint_data));
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, cjd->swing_span);
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN, cjd->twist_span);
@@ -2248,7 +2208,7 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_HINGE: {
- joint = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset);
+ PhysicsServer3D::get_singleton()->joint_make_hinge(joint, body_a->get_rid(), local_a, get_rid(), joint_offset);
const HingeJointData *hjd(static_cast<const HingeJointData *>(joint_data));
PhysicsServer3D::get_singleton()->hinge_joint_set_flag(joint, PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT, hjd->angular_limit_enabled);
PhysicsServer3D::get_singleton()->hinge_joint_set_param(joint, PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER, hjd->angular_limit_upper);
@@ -2259,7 +2219,7 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_SLIDER: {
- joint = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset);
+ PhysicsServer3D::get_singleton()->joint_make_slider(joint, body_a->get_rid(), local_a, get_rid(), joint_offset);
const SliderJointData *sjd(static_cast<const SliderJointData *>(joint_data));
PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER, sjd->linear_limit_upper);
PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER, sjd->linear_limit_lower);
@@ -2274,7 +2234,7 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_6DOF: {
- joint = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset);
+ PhysicsServer3D::get_singleton()->joint_make_generic_6dof(joint, body_a->get_rid(), local_a, get_rid(), joint_offset);
const SixDOFJointData *g6dofjd(static_cast<const SixDOFJointData *>(joint_data));
for (int axis = 0; axis < 3; ++axis) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, g6dofjd->axis_data[axis].linear_limit_enabled);
@@ -2367,7 +2327,7 @@ void PhysicalBone3D::set_joint_type(JointType p_joint_type) {
_reload_joint();
#ifdef TOOLS_ENABLED
- _change_notify();
+ notify_property_list_changed();
if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
}
@@ -2382,7 +2342,6 @@ void PhysicalBone3D::set_joint_offset(const Transform &p_offset) {
joint_offset = p_offset;
_update_joint_offset();
- _change_notify("joint_rotation_degrees");
}
const Transform &PhysicalBone3D::get_joint_offset() const {
@@ -2393,7 +2352,6 @@ void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) {
joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale());
_update_joint_offset();
- _change_notify("joint_offset");
}
Vector3 PhysicalBone3D::get_joint_rotation() const {
@@ -2401,11 +2359,11 @@ Vector3 PhysicalBone3D::get_joint_rotation() const {
}
void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) {
- set_joint_rotation(p_euler_deg * Math_PI / 180.0);
+ 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;
+ return get_joint_rotation() * (180.0 / Math_PI);
}
const Transform &PhysicalBone3D::get_body_offset() const {
@@ -2458,14 +2416,6 @@ real_t PhysicalBone3D::get_mass() const {
return mass;
}
-void PhysicalBone3D::set_weight(real_t p_weight) {
- set_mass(p_weight / real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)));
-}
-
-real_t PhysicalBone3D::get_weight() const {
- return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8));
-}
-
void PhysicalBone3D::set_friction(real_t p_friction) {
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
@@ -2536,6 +2486,7 @@ bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const {
PhysicalBone3D::PhysicalBone3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) {
+ joint = PhysicsServer3D::get_singleton()->joint_create();
reset_physics_simulation_state();
}
@@ -2543,6 +2494,7 @@ PhysicalBone3D::~PhysicalBone3D() {
if (joint_data) {
memdelete(joint_data);
}
+ PhysicsServer3D::get_singleton()->free(joint);
}
void PhysicalBone3D::update_bone_id() {
@@ -2595,7 +2547,7 @@ void PhysicalBone3D::_start_physics_simulation() {
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(), this, "_direct_state_changed");
- set_as_toplevel(true);
+ set_as_top_level(true);
_internal_simulate_physics = true;
}
@@ -2615,7 +2567,7 @@ void PhysicalBone3D::_stop_physics_simulation() {
if (_internal_simulate_physics) {
PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), nullptr, "");
parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false);
- set_as_toplevel(false);
+ set_as_top_level(false);
_internal_simulate_physics = false;
}
}
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index 4c58c73942..1450fce6a6 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,7 +31,7 @@
#ifndef PHYSICS_BODY_3D_H
#define PHYSICS_BODY_3D_H
-#include "core/vset.h"
+#include "core/templates/vset.h"
#include "scene/3d/collision_object_3d.h"
#include "scene/resources/physics_material.h"
#include "servers/physics_server_3d.h"
@@ -43,9 +43,6 @@ class PhysicsBody3D : public CollisionObject3D {
uint32_t collision_layer;
uint32_t collision_mask;
- void _set_layers(uint32_t p_mask);
- uint32_t _get_layers() const;
-
protected:
static void _bind_methods();
PhysicsBody3D(PhysicsServer3D::BodyMode p_mode);
@@ -53,7 +50,7 @@ protected:
public:
virtual Vector3 get_linear_velocity() const;
virtual Vector3 get_angular_velocity() const;
- virtual float get_inverse_mass() const;
+ virtual real_t get_inverse_mass() const;
void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
@@ -114,30 +111,31 @@ public:
};
protected:
- bool can_sleep;
- PhysicsDirectBodyState3D *state;
- Mode mode;
+ bool can_sleep = true;
+ PhysicsDirectBodyState3D *state = nullptr;
+ Mode mode = MODE_RIGID;
- real_t mass;
+ real_t mass = 1.0;
Ref<PhysicsMaterial> physics_material_override;
Vector3 linear_velocity;
Vector3 angular_velocity;
- real_t gravity_scale;
- real_t linear_damp;
- real_t angular_damp;
+ Basis inverse_inertia_tensor;
+ real_t gravity_scale = 1.0;
+ real_t linear_damp = -1.0;
+ real_t angular_damp = -1.0;
- bool sleeping;
- bool ccd;
+ bool sleeping = false;
+ bool ccd = false;
- int max_contacts_reported;
+ int max_contacts_reported = 0;
- bool custom_integrator;
+ bool custom_integrator = false;
struct ShapePair {
- int body_shape;
- int local_shape;
- bool tagged;
+ int body_shape = 0;
+ int local_shape = 0;
+ bool tagged = false;
bool operator<(const ShapePair &p_sp) const {
if (body_shape == p_sp.body_shape) {
return local_shape < p_sp.local_shape;
@@ -159,16 +157,16 @@ protected:
};
struct BodyState {
//int rc;
- bool in_tree;
+ bool in_tree = false;
VSet<ShapePair> shapes;
};
struct ContactMonitor {
- bool locked;
+ bool locked = false;
Map<ObjectID, BodyState> body_map;
};
- ContactMonitor *contact_monitor;
+ ContactMonitor *contact_monitor = nullptr;
void _body_enter_tree(ObjectID p_id);
void _body_exit_tree(ObjectID p_id);
@@ -185,21 +183,20 @@ public:
void set_mass(real_t p_mass);
real_t get_mass() const;
- virtual float get_inverse_mass() const { return 1.0 / mass; }
-
- void set_weight(real_t p_weight);
- real_t get_weight() const;
+ virtual real_t get_inverse_mass() const override { return 1.0 / mass; }
void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
Ref<PhysicsMaterial> get_physics_material_override() const;
void set_linear_velocity(const Vector3 &p_velocity);
- Vector3 get_linear_velocity() const;
+ Vector3 get_linear_velocity() const override;
void set_axis_velocity(const Vector3 &p_axis);
void set_angular_velocity(const Vector3 &p_velocity);
- Vector3 get_angular_velocity() const;
+ Vector3 get_angular_velocity() const override;
+
+ Basis get_inverse_inertia_tensor();
void set_gravity_scale(real_t p_gravity_scale);
real_t get_gravity_scale() const;
@@ -234,14 +231,14 @@ public:
Array get_colliding_bodies() const;
void add_central_force(const Vector3 &p_force);
- void add_force(const Vector3 &p_force, const Vector3 &p_pos);
+ void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3());
void add_torque(const Vector3 &p_torque);
void apply_central_impulse(const Vector3 &p_impulse);
- void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
+ void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3());
void apply_torque_impulse(const Vector3 &p_impulse);
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
RigidBody3D();
~RigidBody3D();
@@ -264,27 +261,27 @@ public:
Vector3 collider_vel;
ObjectID collider;
RID collider_rid;
- int collider_shape;
+ int collider_shape = 0;
Variant collider_metadata;
Vector3 remainder;
Vector3 travel;
- int local_shape;
+ int local_shape = 0;
};
private:
Vector3 linear_velocity;
Vector3 angular_velocity;
- uint16_t locked_axis;
+ uint16_t locked_axis = 0;
- float margin;
+ real_t margin;
Vector3 floor_normal;
Vector3 floor_velocity;
RID on_floor_body;
- bool on_floor;
- bool on_ceiling;
- bool on_wall;
+ bool on_floor = false;
+ bool on_ceiling = false;
+ bool on_wall = false;
Vector<Collision> colliders;
Vector<Ref<KinematicCollision3D>> slide_colliders;
Ref<KinematicCollision3D> motion_cache;
@@ -301,8 +298,8 @@ protected:
virtual void _direct_state_changed(Object *p_state);
public:
- virtual Vector3 get_linear_velocity() const;
- virtual Vector3 get_angular_velocity() const;
+ virtual Vector3 get_linear_velocity() const override;
+ virtual Vector3 get_angular_velocity() const override;
bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia);
@@ -312,11 +309,11 @@ public:
void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
- void set_safe_margin(float p_margin);
- float get_safe_margin() const;
+ void set_safe_margin(real_t p_margin);
+ real_t get_safe_margin() const;
- Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
- Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true);
+ Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true);
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
@@ -373,7 +370,7 @@ public:
virtual JointType get_joint_type() { return JOINT_TYPE_NONE; }
/// "j" is used to set the parameter inside the PhysicsServer3D
- virtual bool _set(const StringName &p_name, const Variant &p_value, RID j = RID());
+ virtual bool _set(const StringName &p_name, const Variant &p_value, RID j);
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
@@ -383,105 +380,91 @@ public:
struct PinJointData : public JointData {
virtual JointType get_joint_type() { return JOINT_TYPE_PIN; }
- virtual bool _set(const StringName &p_name, const Variant &p_value, RID j = RID());
+ virtual bool _set(const StringName &p_name, const Variant &p_value, RID j);
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
real_t bias = 0.3;
- real_t damping = 1.;
- real_t impulse_clamp = 0;
-
- PinJointData() {}
+ real_t damping = 1.0;
+ real_t impulse_clamp = 0.0;
};
struct ConeJointData : public JointData {
virtual JointType get_joint_type() { return JOINT_TYPE_CONE; }
- virtual bool _set(const StringName &p_name, const Variant &p_value, RID j = RID());
+ virtual bool _set(const StringName &p_name, const Variant &p_value, RID j);
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
- real_t swing_span;
+ real_t swing_span = Math_PI * 0.25;
real_t twist_span = Math_PI;
real_t bias = 0.3;
real_t softness = 0.8;
real_t relaxation = 1.;
-
- ConeJointData() :
- swing_span(Math_PI * 0.25) {}
};
struct HingeJointData : public JointData {
virtual JointType get_joint_type() { return JOINT_TYPE_HINGE; }
- virtual bool _set(const StringName &p_name, const Variant &p_value, RID j = RID());
+ virtual bool _set(const StringName &p_name, const Variant &p_value, RID j);
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
bool angular_limit_enabled = false;
- real_t angular_limit_upper;
- real_t angular_limit_lower;
+ real_t angular_limit_upper = Math_PI * 0.5;
+ real_t angular_limit_lower = -Math_PI * 0.5;
real_t angular_limit_bias = 0.3;
real_t angular_limit_softness = 0.9;
real_t angular_limit_relaxation = 1.;
-
- HingeJointData() :
-
- angular_limit_upper(Math_PI * 0.5),
- angular_limit_lower(-Math_PI * 0.5) {}
};
struct SliderJointData : public JointData {
virtual JointType get_joint_type() { return JOINT_TYPE_SLIDER; }
- virtual bool _set(const StringName &p_name, const Variant &p_value, RID j = RID());
+ virtual bool _set(const StringName &p_name, const Variant &p_value, RID j);
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
- real_t linear_limit_upper = 1.;
- real_t linear_limit_lower = -1.;
- real_t linear_limit_softness = 1.;
+ real_t linear_limit_upper = 1.0;
+ real_t linear_limit_lower = -1.0;
+ real_t linear_limit_softness = 1.0;
real_t linear_limit_restitution = 0.7;
- real_t linear_limit_damping = 1.;
- real_t angular_limit_upper = 0;
- real_t angular_limit_lower = 0;
- real_t angular_limit_softness = 1.;
+ real_t linear_limit_damping = 1.0;
+ real_t angular_limit_upper = 0.0;
+ real_t angular_limit_lower = 0.0;
+ real_t angular_limit_softness = 1.0;
real_t angular_limit_restitution = 0.7;
- real_t angular_limit_damping = 1.;
-
- SliderJointData() {}
+ real_t angular_limit_damping = 1.0;
};
struct SixDOFJointData : public JointData {
struct SixDOFAxisData {
bool linear_limit_enabled = true;
- real_t linear_limit_upper = 0;
- real_t linear_limit_lower = 0;
+ real_t linear_limit_upper = 0.0;
+ real_t linear_limit_lower = 0.0;
real_t linear_limit_softness = 0.7;
real_t linear_restitution = 0.5;
- real_t linear_damping = 1.;
+ real_t linear_damping = 1.0;
bool linear_spring_enabled = false;
- real_t linear_spring_stiffness = 0;
- real_t linear_spring_damping = 0;
- real_t linear_equilibrium_point = 0;
+ real_t linear_spring_stiffness = 0.0;
+ real_t linear_spring_damping = 0.0;
+ real_t linear_equilibrium_point = 0.0;
bool angular_limit_enabled = true;
- real_t angular_limit_upper = 0;
- real_t angular_limit_lower = 0;
+ real_t angular_limit_upper = 0.0;
+ real_t angular_limit_lower = 0.0;
real_t angular_limit_softness = 0.5;
- real_t angular_restitution = 0;
- real_t angular_damping = 1.;
+ real_t angular_restitution = 0.0;
+ real_t angular_damping = 1.0;
real_t erp = 0.5;
bool angular_spring_enabled = false;
- real_t angular_spring_stiffness = 0;
- real_t angular_spring_damping = 0.;
- real_t angular_equilibrium_point = 0;
-
- SixDOFAxisData() {}
+ real_t angular_spring_stiffness = 0.0;
+ real_t angular_spring_damping = 0.0;
+ real_t angular_equilibrium_point = 0.0;
};
virtual JointType get_joint_type() { return JOINT_TYPE_6DOF; }
- virtual bool _set(const StringName &p_name, const Variant &p_value, RID j = RID());
+ virtual bool _set(const StringName &p_name, const Variant &p_value, RID j);
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
@@ -508,12 +491,12 @@ private:
int bone_id = -1;
String bone_name;
- real_t bounce = 0;
- real_t mass = 1;
- real_t friction = 1;
- real_t gravity_scale = 1;
- real_t linear_damp = -1;
- real_t angular_damp = -1;
+ real_t bounce = 0.0;
+ real_t mass = 1.0;
+ real_t friction = 1.0;
+ real_t gravity_scale = 1.0;
+ real_t linear_damp = -1.0;
+ real_t angular_damp = -1.0;
bool can_sleep = true;
protected:
@@ -538,8 +521,8 @@ public:
public:
#ifdef TOOLS_ENABLED
- virtual Transform get_global_gizmo_transform() const;
- virtual Transform get_local_gizmo_transform() const;
+ virtual Transform get_global_gizmo_transform() const override;
+ virtual Transform get_local_gizmo_transform() const override;
#endif
const JointData *get_joint_data() const;
@@ -572,9 +555,6 @@ public:
void set_mass(real_t p_mass);
real_t get_mass() const;
- void set_weight(real_t p_weight);
- real_t get_weight() const;
-
void set_friction(real_t p_friction);
real_t get_friction() const;
@@ -597,7 +577,7 @@ public:
bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
void apply_central_impulse(const Vector3 &p_impulse);
- void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
+ void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3());
void reset_physics_simulation_state();
void reset_to_rest_position();
diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp
index af4d6ae152..0463bed9d6 100644
--- a/scene/3d/physics_joint_3d.cpp
+++ b/scene/3d/physics_joint_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,47 +30,115 @@
#include "physics_joint_3d.h"
-void Joint3D::_update_joint(bool p_only_free) {
- if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid()) {
- PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb);
- }
+#include "scene/scene_string_names.h"
+
+void Joint3D::_disconnect_signals() {
+ Node *node_a = get_node_or_null(a);
+ PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a);
+ if (body_a) {
+ body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
+ }
+
+ Node *node_b = get_node_or_null(b);
+ PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b);
+ if (body_b) {
+ body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
+ }
+}
- PhysicsServer3D::get_singleton()->free(joint);
- joint = RID();
- ba = RID();
- bb = RID();
+void Joint3D::_body_exit_tree(const ObjectID &p_body_id) {
+ _disconnect_signals();
+ Object *object = ObjectDB::get_instance(p_body_id);
+ PhysicsBody3D *body = Object::cast_to<PhysicsBody3D>(object);
+ ERR_FAIL_NULL(body);
+ RID body_rid = body->get_rid();
+ if (ba == body_rid) {
+ a = NodePath();
}
+ if (bb == body_rid) {
+ b = NodePath();
+ }
+ _update_joint();
+}
+
+void Joint3D::_update_joint(bool p_only_free) {
+ if (ba.is_valid() && bb.is_valid()) {
+ PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb);
+ }
+
+ ba = RID();
+ bb = RID();
+
+ configured = false;
if (p_only_free || !is_inside_tree()) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
+ warning = String();
return;
}
- Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)nullptr;
- Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)nullptr;
+ Node *node_a = get_node_or_null(a);
+ Node *node_b = get_node_or_null(b);
PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a);
PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b);
- if (!body_a && body_b) {
- SWAP(body_a, body_b);
+ if (node_a && !body_a && node_b && !body_b) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
+ warning = TTR("Node A and Node B must be PhysicsBody3Ds");
+ update_configuration_warning();
+ return;
}
- if (!body_a) {
+ if (node_a && !body_a) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
+ warning = TTR("Node A must be a PhysicsBody3D");
+ update_configuration_warning();
return;
}
- joint = _configure_joint(body_a, body_b);
+ if (node_b && !body_b) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
+ warning = TTR("Node B must be a PhysicsBody3D");
+ update_configuration_warning();
+ return;
+ }
+
+ if (!body_a && !body_b) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
+ warning = TTR("Joint is not connected to any PhysicsBody3Ds");
+ update_configuration_warning();
+ return;
+ }
- if (!joint.is_valid()) {
+ if (body_a == body_b) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
+ warning = TTR("Node A and Node B must be different PhysicsBody3Ds");
+ update_configuration_warning();
return;
}
+ warning = String();
+ update_configuration_warning();
+
+ configured = true;
+
+ if (body_a) {
+ _configure_joint(joint, body_a, body_b);
+ } else if (body_b) {
+ _configure_joint(joint, body_b, nullptr);
+ }
+
PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority);
- ba = body_a->get_rid();
+ if (body_a) {
+ ba = body_a->get_rid();
+ body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree), make_binds(body_a->get_instance_id()));
+ }
+
if (body_b) {
bb = body_b->get_rid();
+ body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree), make_binds(body_b->get_instance_id()));
}
PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
@@ -81,6 +149,10 @@ void Joint3D::set_node_a(const NodePath &p_node_a) {
return;
}
+ if (joint.is_valid()) {
+ _disconnect_signals();
+ }
+
a = p_node_a;
_update_joint();
}
@@ -93,6 +165,11 @@ void Joint3D::set_node_b(const NodePath &p_node_b) {
if (b == p_node_b) {
return;
}
+
+ if (joint.is_valid()) {
+ _disconnect_signals();
+ }
+
b = p_node_b;
_update_joint();
}
@@ -119,6 +196,7 @@ void Joint3D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
if (joint.is_valid()) {
+ _disconnect_signals();
_update_joint(true);
}
} break;
@@ -137,6 +215,19 @@ bool Joint3D::get_exclude_nodes_from_collision() const {
return exclude_from_collision;
}
+String Joint3D::get_configuration_warning() const {
+ String node_warning = Node3D::get_configuration_warning();
+
+ if (!warning.is_empty()) {
+ if (!node_warning.is_empty()) {
+ node_warning += "\n\n";
+ }
+ node_warning += warning;
+ }
+
+ return node_warning;
+}
+
void Joint3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint3D::set_node_a);
ClassDB::bind_method(D_METHOD("get_node_a"), &Joint3D::get_node_a);
@@ -150,17 +241,20 @@ void Joint3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint3D::set_exclude_nodes_from_collision);
ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint3D::get_exclude_nodes_from_collision);
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject3D"), "set_node_a", "get_node_a");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject3D"), "set_node_b", "get_node_b");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody3D"), "set_node_a", "get_node_a");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody3D"), "set_node_b", "get_node_b");
ADD_PROPERTY(PropertyInfo(Variant::INT, "solver/priority", PROPERTY_HINT_RANGE, "1,8,1"), "set_solver_priority", "get_solver_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision/exclude_nodes"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision");
}
Joint3D::Joint3D() {
- exclude_from_collision = true;
- solver_priority = 1;
set_notify_transform(true);
+ joint = PhysicsServer3D::get_singleton()->joint_create();
+}
+
+Joint3D::~Joint3D() {
+ PhysicsServer3D::get_singleton()->free(joint);
}
///////////////////////////////////
@@ -178,20 +272,20 @@ void PinJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_IMPULSE_CLAMP);
}
-void PinJoint3D::set_param(Param p_param, float p_value) {
+void PinJoint3D::set_param(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, 3);
params[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer3D::PinJointParam(p_param), p_value);
}
}
-float PinJoint3D::get_param(Param p_param) const {
+real_t PinJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, 3, 0);
return params[p_param];
}
-RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void PinJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Vector3 pinpos = get_global_transform().origin;
Vector3 local_a = body_a->get_global_transform().affine_inverse().xform(pinpos);
Vector3 local_b;
@@ -202,11 +296,10 @@ RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
local_b = pinpos;
}
- RID j = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_pin(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < 3; i++) {
- PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PinJointParam(i), params[i]);
+ PhysicsServer3D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer3D::PinJointParam(i), params[i]);
}
- return j;
}
PinJoint3D::PinJoint3D() {
@@ -219,19 +312,19 @@ PinJoint3D::PinJoint3D() {
///////////////////////////////////
-void HingeJoint3D::_set_upper_limit(float p_limit) {
+void HingeJoint3D::_set_upper_limit(real_t p_limit) {
set_param(PARAM_LIMIT_UPPER, Math::deg2rad(p_limit));
}
-float HingeJoint3D::_get_upper_limit() const {
+real_t HingeJoint3D::_get_upper_limit() const {
return Math::rad2deg(get_param(PARAM_LIMIT_UPPER));
}
-void HingeJoint3D::_set_lower_limit(float p_limit) {
+void HingeJoint3D::_set_lower_limit(real_t p_limit) {
set_param(PARAM_LIMIT_LOWER, Math::deg2rad(p_limit));
}
-float HingeJoint3D::_get_lower_limit() const {
+real_t HingeJoint3D::_get_lower_limit() const {
return Math::rad2deg(get_param(PARAM_LIMIT_LOWER));
}
@@ -276,17 +369,17 @@ void HingeJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_MAX);
}
-void HingeJoint3D::set_param(Param p_param, float p_value) {
+void HingeJoint3D::set_param(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(get_joint(), PhysicsServer3D::HingeJointParam(p_param), p_value);
}
update_gizmo();
}
-float HingeJoint3D::get_param(Param p_param) const {
+real_t HingeJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
@@ -294,7 +387,7 @@ float HingeJoint3D::get_param(Param p_param) const {
void HingeJoint3D::set_flag(Flag p_flag, bool p_value) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags[p_flag] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_flag(get_joint(), PhysicsServer3D::HingeJointFlag(p_flag), p_value);
}
@@ -306,7 +399,7 @@ bool HingeJoint3D::get_flag(Flag p_flag) const {
return flags[p_flag];
}
-RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void HingeJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Transform gt = get_global_transform();
Transform ainv = body_a->get_global_transform().affine_inverse();
@@ -321,15 +414,14 @@ RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b)
local_b.orthonormalize();
- RID j = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_hinge(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < PARAM_MAX; i++) {
- PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HingeJointParam(i), params[i]);
+ PhysicsServer3D::get_singleton()->hinge_joint_set_param(p_joint, PhysicsServer3D::HingeJointParam(i), params[i]);
}
for (int i = 0; i < FLAG_MAX; i++) {
set_flag(Flag(i), flags[i]);
- PhysicsServer3D::get_singleton()->hinge_joint_set_flag(j, PhysicsServer3D::HingeJointFlag(i), flags[i]);
+ PhysicsServer3D::get_singleton()->hinge_joint_set_flag(p_joint, PhysicsServer3D::HingeJointFlag(i), flags[i]);
}
- return j;
}
HingeJoint3D::HingeJoint3D() {
@@ -350,19 +442,19 @@ HingeJoint3D::HingeJoint3D() {
//////////////////////////////////
-void SliderJoint3D::_set_upper_limit_angular(float p_limit_angular) {
+void SliderJoint3D::_set_upper_limit_angular(real_t p_limit_angular) {
set_param(PARAM_ANGULAR_LIMIT_UPPER, Math::deg2rad(p_limit_angular));
}
-float SliderJoint3D::_get_upper_limit_angular() const {
+real_t SliderJoint3D::_get_upper_limit_angular() const {
return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_UPPER));
}
-void SliderJoint3D::_set_lower_limit_angular(float p_limit_angular) {
+void SliderJoint3D::_set_lower_limit_angular(real_t p_limit_angular) {
set_param(PARAM_ANGULAR_LIMIT_LOWER, Math::deg2rad(p_limit_angular));
}
-float SliderJoint3D::_get_lower_limit_angular() const {
+real_t SliderJoint3D::_get_lower_limit_angular() const {
return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_LOWER));
}
@@ -427,21 +519,21 @@ void SliderJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_MAX);
}
-void SliderJoint3D::set_param(Param p_param, float p_value) {
+void SliderJoint3D::set_param(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(get_joint(), PhysicsServer3D::SliderJointParam(p_param), p_value);
}
update_gizmo();
}
-float SliderJoint3D::get_param(Param p_param) const {
+real_t SliderJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
-RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void SliderJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Transform gt = get_global_transform();
Transform ainv = body_a->get_global_transform().affine_inverse();
@@ -456,12 +548,10 @@ RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b
local_b.orthonormalize();
- RID j = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_slider(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < PARAM_MAX; i++) {
- PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SliderJointParam(i), params[i]);
+ PhysicsServer3D::get_singleton()->slider_joint_set_param(p_joint, PhysicsServer3D::SliderJointParam(i), params[i]);
}
-
- return j;
}
SliderJoint3D::SliderJoint3D() {
@@ -492,19 +582,19 @@ SliderJoint3D::SliderJoint3D() {
//////////////////////////////////
-void ConeTwistJoint3D::_set_swing_span(float p_limit_angular) {
+void ConeTwistJoint3D::_set_swing_span(real_t p_limit_angular) {
set_param(PARAM_SWING_SPAN, Math::deg2rad(p_limit_angular));
}
-float ConeTwistJoint3D::_get_swing_span() const {
+real_t ConeTwistJoint3D::_get_swing_span() const {
return Math::rad2deg(get_param(PARAM_SWING_SPAN));
}
-void ConeTwistJoint3D::_set_twist_span(float p_limit_angular) {
+void ConeTwistJoint3D::_set_twist_span(real_t p_limit_angular) {
set_param(PARAM_TWIST_SPAN, Math::deg2rad(p_limit_angular));
}
-float ConeTwistJoint3D::_get_twist_span() const {
+real_t ConeTwistJoint3D::_get_twist_span() const {
return Math::rad2deg(get_param(PARAM_TWIST_SPAN));
}
@@ -533,22 +623,22 @@ void ConeTwistJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_MAX);
}
-void ConeTwistJoint3D::set_param(Param p_param, float p_value) {
+void ConeTwistJoint3D::set_param(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(get_joint(), PhysicsServer3D::ConeTwistJointParam(p_param), p_value);
}
update_gizmo();
}
-float ConeTwistJoint3D::get_param(Param p_param) const {
+real_t ConeTwistJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
-RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void ConeTwistJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Transform gt = get_global_transform();
//Vector3 cone_twistpos = gt.origin;
//Vector3 cone_twistdir = gt.basis.get_axis(2);
@@ -566,12 +656,10 @@ RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *bod
local_b.orthonormalize();
- RID j = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_cone_twist(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < PARAM_MAX; i++) {
- PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::ConeTwistJointParam(i), params[i]);
+ PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(p_joint, PhysicsServer3D::ConeTwistJointParam(i), params[i]);
}
-
- return j;
}
ConeTwistJoint3D::ConeTwistJoint3D() {
@@ -584,51 +672,51 @@ ConeTwistJoint3D::ConeTwistJoint3D() {
/////////////////////////////////////////////////////////////////////
-void Generic6DOFJoint3D::_set_angular_hi_limit_x(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_hi_limit_x(real_t p_limit_angular) {
set_param_x(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_hi_limit_x() const {
+real_t Generic6DOFJoint3D::_get_angular_hi_limit_x() const {
return Math::rad2deg(get_param_x(PARAM_ANGULAR_UPPER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_lo_limit_x(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_lo_limit_x(real_t p_limit_angular) {
set_param_x(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_lo_limit_x() const {
+real_t Generic6DOFJoint3D::_get_angular_lo_limit_x() const {
return Math::rad2deg(get_param_x(PARAM_ANGULAR_LOWER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_hi_limit_y(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_hi_limit_y(real_t p_limit_angular) {
set_param_y(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_hi_limit_y() const {
+real_t Generic6DOFJoint3D::_get_angular_hi_limit_y() const {
return Math::rad2deg(get_param_y(PARAM_ANGULAR_UPPER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_lo_limit_y(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_lo_limit_y(real_t p_limit_angular) {
set_param_y(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_lo_limit_y() const {
+real_t Generic6DOFJoint3D::_get_angular_lo_limit_y() const {
return Math::rad2deg(get_param_y(PARAM_ANGULAR_LOWER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_hi_limit_z(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_hi_limit_z(real_t p_limit_angular) {
set_param_z(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_hi_limit_z() const {
+real_t Generic6DOFJoint3D::_get_angular_hi_limit_z() const {
return Math::rad2deg(get_param_z(PARAM_ANGULAR_UPPER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_lo_limit_z(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_lo_limit_z(real_t p_limit_angular) {
set_param_z(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_lo_limit_z() const {
+real_t Generic6DOFJoint3D::_get_angular_lo_limit_z() const {
return Math::rad2deg(get_param_z(PARAM_ANGULAR_LOWER_LIMIT));
}
@@ -669,9 +757,6 @@ void Generic6DOFJoint3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flag_z", "flag", "value"), &Generic6DOFJoint3D::set_flag_z);
ClassDB::bind_method(D_METHOD("get_flag_z", "flag"), &Generic6DOFJoint3D::get_flag_z);
- ClassDB::bind_method(D_METHOD("set_precision", "precision"), &Generic6DOFJoint3D::set_precision);
- ClassDB::bind_method(D_METHOD("get_precision"), &Generic6DOFJoint3D::get_precision);
-
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_LIMIT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/upper_distance"), "set_param_x", "get_param_x", PARAM_LINEAR_UPPER_LIMIT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/lower_distance"), "set_param_x", "get_param_x", PARAM_LINEAR_LOWER_LIMIT);
@@ -760,8 +845,6 @@ void Generic6DOFJoint3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/damping"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_DAMPING);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "precision", PROPERTY_HINT_RANGE, "1,99999,1"), "set_precision", "get_precision");
-
BIND_ENUM_CONSTANT(PARAM_LINEAR_LOWER_LIMIT);
BIND_ENUM_CONSTANT(PARAM_LINEAR_UPPER_LIMIT);
BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_SOFTNESS);
@@ -795,45 +878,45 @@ void Generic6DOFJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_MAX);
}
-void Generic6DOFJoint3D::set_param_x(Param p_param, float p_value) {
+void Generic6DOFJoint3D::set_param_x(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_x[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_x(Param p_param) const {
+real_t Generic6DOFJoint3D::get_param_x(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_x[p_param];
}
-void Generic6DOFJoint3D::set_param_y(Param p_param, float p_value) {
+void Generic6DOFJoint3D::set_param_y(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_y[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_y(Param p_param) const {
+real_t Generic6DOFJoint3D::get_param_y(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_y[p_param];
}
-void Generic6DOFJoint3D::set_param_z(Param p_param, float p_value) {
+void Generic6DOFJoint3D::set_param_z(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_z[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_z(Param p_param) const {
+real_t Generic6DOFJoint3D::get_param_z(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_z[p_param];
}
@@ -841,7 +924,7 @@ float Generic6DOFJoint3D::get_param_z(Param p_param) const {
void Generic6DOFJoint3D::set_flag_x(Flag p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_x[p_flag] = p_enabled;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
@@ -855,7 +938,7 @@ bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const {
void Generic6DOFJoint3D::set_flag_y(Flag p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_y[p_flag] = p_enabled;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
@@ -869,7 +952,7 @@ bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const {
void Generic6DOFJoint3D::set_flag_z(Flag p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_z[p_flag] = p_enabled;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
@@ -880,15 +963,7 @@ bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const {
return flags_z[p_flag];
}
-void Generic6DOFJoint3D::set_precision(int p_precision) {
- precision = p_precision;
-
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_precision(
- get_joint(),
- precision);
-}
-
-RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void Generic6DOFJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Transform gt = get_global_transform();
//Vector3 cone_twistpos = gt.origin;
//Vector3 cone_twistdir = gt.basis.get_axis(2);
@@ -906,19 +981,17 @@ RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *b
local_b.orthonormalize();
- RID j = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_generic_6dof(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < PARAM_MAX; i++) {
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]);
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]);
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]);
}
for (int i = 0; i < FLAG_MAX; i++) {
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]);
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]);
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]);
}
-
- return j;
}
Generic6DOFJoint3D::Generic6DOFJoint3D() {
diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/physics_joint_3d.h
index a3225ab01c..8d0a16e432 100644
--- a/scene/3d/physics_joint_3d.h
+++ b/scene/3d/physics_joint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -44,19 +44,27 @@ class Joint3D : public Node3D {
NodePath a;
NodePath b;
- int solver_priority;
- bool exclude_from_collision;
+ int solver_priority = 1;
+ bool exclude_from_collision = true;
+ String warning;
+ bool configured = false;
protected:
+ void _disconnect_signals();
+ void _body_exit_tree(const ObjectID &p_body_id);
void _update_joint(bool p_only_free = false);
void _notification(int p_what);
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0;
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0;
static void _bind_methods();
+ _FORCE_INLINE_ bool is_configured() const { return configured; }
+
public:
+ virtual String get_configuration_warning() const override;
+
void set_node_a(const NodePath &p_node_a);
NodePath get_node_a() const;
@@ -71,6 +79,7 @@ public:
RID get_joint() const { return joint; }
Joint3D();
+ ~Joint3D();
};
///////////////////////////////////////////
@@ -86,13 +95,13 @@ public:
};
protected:
- float params[3];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b);
+ real_t params[3];
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
public:
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
+ void set_param(Param p_param, real_t p_value);
+ real_t get_param(Param p_param) const;
PinJoint3D();
};
@@ -122,20 +131,20 @@ public:
};
protected:
- float params[PARAM_MAX];
+ real_t params[PARAM_MAX];
bool flags[FLAG_MAX];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b);
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
- void _set_upper_limit(float p_limit);
- float _get_upper_limit() const;
+ void _set_upper_limit(real_t p_limit);
+ real_t _get_upper_limit() const;
- void _set_lower_limit(float p_limit);
- float _get_lower_limit() const;
+ void _set_lower_limit(real_t p_limit);
+ real_t _get_lower_limit() const;
public:
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
+ void set_param(Param p_param, real_t p_value);
+ real_t get_param(Param p_param) const;
void set_flag(Flag p_flag, bool p_value);
bool get_flag(Flag p_flag) const;
@@ -179,19 +188,19 @@ public:
};
protected:
- void _set_upper_limit_angular(float p_limit_angular);
- float _get_upper_limit_angular() const;
+ void _set_upper_limit_angular(real_t p_limit_angular);
+ real_t _get_upper_limit_angular() const;
- void _set_lower_limit_angular(float p_limit_angular);
- float _get_lower_limit_angular() const;
+ void _set_lower_limit_angular(real_t p_limit_angular);
+ real_t _get_lower_limit_angular() const;
- float params[PARAM_MAX];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b);
+ real_t params[PARAM_MAX];
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
public:
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
+ void set_param(Param p_param, real_t p_value);
+ real_t get_param(Param p_param) const;
SliderJoint3D();
};
@@ -203,7 +212,6 @@ class ConeTwistJoint3D : public Joint3D {
public:
enum Param {
-
PARAM_SWING_SPAN,
PARAM_TWIST_SPAN,
PARAM_BIAS,
@@ -213,19 +221,19 @@ public:
};
protected:
- void _set_swing_span(float p_limit_angular);
- float _get_swing_span() const;
+ void _set_swing_span(real_t p_limit_angular);
+ real_t _get_swing_span() const;
- void _set_twist_span(float p_limit_angular);
- float _get_twist_span() const;
+ void _set_twist_span(real_t p_limit_angular);
+ real_t _get_twist_span() const;
- float params[PARAM_MAX];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b);
+ real_t params[PARAM_MAX];
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
public:
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
+ void set_param(Param p_param, real_t p_value);
+ real_t get_param(Param p_param) const;
ConeTwistJoint3D();
};
@@ -237,7 +245,6 @@ class Generic6DOFJoint3D : public Joint3D {
public:
enum Param {
-
PARAM_LINEAR_LOWER_LIMIT = PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT,
PARAM_LINEAR_UPPER_LIMIT = PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT,
PARAM_LINEAR_LIMIT_SOFTNESS = PhysicsServer3D::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS,
@@ -274,45 +281,43 @@ public:
};
protected:
- void _set_angular_hi_limit_x(float p_limit_angular);
- float _get_angular_hi_limit_x() const;
+ void _set_angular_hi_limit_x(real_t p_limit_angular);
+ real_t _get_angular_hi_limit_x() const;
- void _set_angular_hi_limit_y(float p_limit_angular);
- float _get_angular_hi_limit_y() const;
+ void _set_angular_hi_limit_y(real_t p_limit_angular);
+ real_t _get_angular_hi_limit_y() const;
- void _set_angular_hi_limit_z(float p_limit_angular);
- float _get_angular_hi_limit_z() const;
+ void _set_angular_hi_limit_z(real_t p_limit_angular);
+ real_t _get_angular_hi_limit_z() const;
- void _set_angular_lo_limit_x(float p_limit_angular);
- float _get_angular_lo_limit_x() const;
+ void _set_angular_lo_limit_x(real_t p_limit_angular);
+ real_t _get_angular_lo_limit_x() const;
- void _set_angular_lo_limit_y(float p_limit_angular);
- float _get_angular_lo_limit_y() const;
+ void _set_angular_lo_limit_y(real_t p_limit_angular);
+ real_t _get_angular_lo_limit_y() const;
- void _set_angular_lo_limit_z(float p_limit_angular);
- float _get_angular_lo_limit_z() const;
+ void _set_angular_lo_limit_z(real_t p_limit_angular);
+ real_t _get_angular_lo_limit_z() const;
- float params_x[PARAM_MAX];
+ real_t params_x[PARAM_MAX];
bool flags_x[FLAG_MAX];
- float params_y[PARAM_MAX];
+ real_t params_y[PARAM_MAX];
bool flags_y[FLAG_MAX];
- float params_z[PARAM_MAX];
+ real_t params_z[PARAM_MAX];
bool flags_z[FLAG_MAX];
- int precision = 1;
-
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b);
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
public:
- void set_param_x(Param p_param, float p_value);
- float get_param_x(Param p_param) const;
+ void set_param_x(Param p_param, real_t p_value);
+ real_t get_param_x(Param p_param) const;
- void set_param_y(Param p_param, float p_value);
- float get_param_y(Param p_param) const;
+ void set_param_y(Param p_param, real_t p_value);
+ real_t get_param_y(Param p_param) const;
- void set_param_z(Param p_param, float p_value);
- float get_param_z(Param p_param) const;
+ void set_param_z(Param p_param, real_t p_value);
+ real_t get_param_z(Param p_param) const;
void set_flag_x(Flag p_flag, bool p_enabled);
bool get_flag_x(Flag p_flag) const;
@@ -323,11 +328,6 @@ public:
void set_flag_z(Flag p_flag, bool p_enabled);
bool get_flag_z(Flag p_flag) const;
- void set_precision(int p_precision);
- int get_precision() const {
- return precision;
- }
-
Generic6DOFJoint3D();
};
diff --git a/scene/3d/position_3d.cpp b/scene/3d/position_3d.cpp
index e63c588e28..b231ba0df7 100644
--- a/scene/3d/position_3d.cpp
+++ b/scene/3d/position_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
diff --git a/scene/3d/position_3d.h b/scene/3d/position_3d.h
index 1c5f05ef95..065b14c3bd 100644
--- a/scene/3d/position_3d.h
+++ b/scene/3d/position_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
diff --git a/scene/3d/proximity_group_3d.cpp b/scene/3d/proximity_group_3d.cpp
index 1a0677c603..9d9fea68b0 100644
--- a/scene/3d/proximity_group_3d.cpp
+++ b/scene/3d/proximity_group_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -32,7 +32,7 @@
#include "core/math/math_funcs.h"
-void ProximityGroup3D::clear_groups() {
+void ProximityGroup3D::_clear_groups() {
Map<StringName, uint32_t>::Element *E;
{
@@ -43,21 +43,21 @@ void ProximityGroup3D::clear_groups() {
while (E && num < size) {
if (E->get() != group_version) {
remove_list[num++] = E->key();
- };
+ }
E = E->next();
- };
+ }
for (int i = 0; i < num; i++) {
groups.erase(remove_list[i]);
- };
- };
+ }
+ }
if (E) {
- clear_groups(); // call until we go through the whole list
- };
-};
+ _clear_groups(); // call until we go through the whole list
+ }
+}
-void ProximityGroup3D::update_groups() {
+void ProximityGroup3D::_update_groups() {
if (grid_radius == Vector3(0, 0, 0)) {
return;
}
@@ -68,20 +68,20 @@ void ProximityGroup3D::update_groups() {
Vector3 vcell = pos / cell_size;
int cell[3] = { Math::fast_ftoi(vcell.x), Math::fast_ftoi(vcell.y), Math::fast_ftoi(vcell.z) };
- add_groups(cell, group_name, 0);
+ _add_groups(cell, group_name, 0);
- clear_groups();
-};
+ _clear_groups();
+}
-void ProximityGroup3D::add_groups(int *p_cell, String p_base, int p_depth) {
+void ProximityGroup3D::_add_groups(int *p_cell, String p_base, int p_depth) {
p_base = p_base + "|";
if (grid_radius[p_depth] == 0) {
if (p_depth == 2) {
_new_group(p_base);
} else {
- add_groups(p_cell, p_base, p_depth + 1);
- };
- };
+ _add_groups(p_cell, p_base, p_depth + 1);
+ }
+ }
int start = p_cell[p_depth] - grid_radius[p_depth];
int end = p_cell[p_depth] + grid_radius[p_depth];
@@ -91,72 +91,72 @@ void ProximityGroup3D::add_groups(int *p_cell, String p_base, int p_depth) {
if (p_depth == 2) {
_new_group(gname);
} else {
- add_groups(p_cell, gname, p_depth + 1);
- };
- };
-};
+ _add_groups(p_cell, gname, p_depth + 1);
+ }
+ }
+}
void ProximityGroup3D::_new_group(StringName p_name) {
const Map<StringName, uint32_t>::Element *E = groups.find(p_name);
if (!E) {
add_to_group(p_name);
- };
+ }
groups[p_name] = group_version;
-};
+}
void ProximityGroup3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_EXIT_TREE:
++group_version;
- clear_groups();
+ _clear_groups();
break;
case NOTIFICATION_TRANSFORM_CHANGED:
- update_groups();
+ _update_groups();
break;
- };
-};
+ }
+}
-void ProximityGroup3D::broadcast(String p_name, Variant p_params) {
+void ProximityGroup3D::broadcast(String p_method, Variant p_parameters) {
Map<StringName, uint32_t>::Element *E;
E = groups.front();
while (E) {
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFAULT, E->key(), "_proximity_group_broadcast", p_name, p_params);
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFAULT, E->key(), "_proximity_group_broadcast", p_method, p_parameters);
E = E->next();
- };
-};
+ }
+}
-void ProximityGroup3D::_proximity_group_broadcast(String p_name, Variant p_params) {
+void ProximityGroup3D::_proximity_group_broadcast(String p_method, Variant p_parameters) {
if (dispatch_mode == MODE_PROXY) {
- get_parent()->call(p_name, p_params);
+ get_parent()->call(p_method, p_parameters);
} else {
- emit_signal("broadcast", p_name, p_params);
- };
-};
+ emit_signal("broadcast", p_method, p_parameters);
+ }
+}
void ProximityGroup3D::set_group_name(const String &p_group_name) {
group_name = p_group_name;
-};
+}
String ProximityGroup3D::get_group_name() const {
return group_name;
-};
+}
void ProximityGroup3D::set_dispatch_mode(DispatchMode p_mode) {
dispatch_mode = p_mode;
-};
+}
ProximityGroup3D::DispatchMode ProximityGroup3D::get_dispatch_mode() const {
return dispatch_mode;
-};
+}
void ProximityGroup3D::set_grid_radius(const Vector3 &p_radius) {
grid_radius = p_radius;
-};
+}
Vector3 ProximityGroup3D::get_grid_radius() const {
return grid_radius;
-};
+}
void ProximityGroup3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_group_name", "name"), &ProximityGroup3D::set_group_name);
@@ -165,19 +165,21 @@ void ProximityGroup3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_dispatch_mode"), &ProximityGroup3D::get_dispatch_mode);
ClassDB::bind_method(D_METHOD("set_grid_radius", "radius"), &ProximityGroup3D::set_grid_radius);
ClassDB::bind_method(D_METHOD("get_grid_radius"), &ProximityGroup3D::get_grid_radius);
- ClassDB::bind_method(D_METHOD("broadcast", "name", "parameters"), &ProximityGroup3D::broadcast);
- ClassDB::bind_method(D_METHOD("_proximity_group_broadcast", "name", "params"), &ProximityGroup3D::_proximity_group_broadcast);
+
+ ClassDB::bind_method(D_METHOD("broadcast", "method", "parameters"), &ProximityGroup3D::broadcast);
+
+ ClassDB::bind_method(D_METHOD("_proximity_group_broadcast", "method", "parameters"), &ProximityGroup3D::_proximity_group_broadcast);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "group_name"), "set_group_name", "get_group_name");
ADD_PROPERTY(PropertyInfo(Variant::INT, "dispatch_mode", PROPERTY_HINT_ENUM, "Proxy,Signal"), "set_dispatch_mode", "get_dispatch_mode");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "grid_radius"), "set_grid_radius", "get_grid_radius");
- ADD_SIGNAL(MethodInfo("broadcast", PropertyInfo(Variant::STRING, "group_name"), PropertyInfo(Variant::ARRAY, "parameters")));
+ ADD_SIGNAL(MethodInfo("broadcast", PropertyInfo(Variant::STRING, "method"), PropertyInfo(Variant::ARRAY, "parameters")));
BIND_ENUM_CONSTANT(MODE_PROXY);
BIND_ENUM_CONSTANT(MODE_SIGNAL);
-};
+}
ProximityGroup3D::ProximityGroup3D() {
set_notify_transform(true);
-};
+}
diff --git a/scene/3d/proximity_group_3d.h b/scene/3d/proximity_group_3d.h
index dd3a2f0a87..05aa00b228 100644
--- a/scene/3d/proximity_group_3d.h
+++ b/scene/3d/proximity_group_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -35,7 +35,6 @@
class ProximityGroup3D : public Node3D {
GDCLASS(ProximityGroup3D, Node3D);
- OBJ_CATEGORY("3D");
public:
enum DispatchMode {
@@ -43,25 +42,25 @@ public:
MODE_SIGNAL,
};
-public:
- void clear_groups();
- void update_groups();
-
- void _notification(int p_what);
-
- DispatchMode dispatch_mode = MODE_PROXY;
-
+private:
Map<StringName, uint32_t> groups;
+
String group_name;
+ DispatchMode dispatch_mode = MODE_PROXY;
+ Vector3 grid_radius = Vector3(1, 1, 1);
float cell_size = 1.0;
- Vector3 grid_radius = Vector3(1, 1, 1);
uint32_t group_version = 0;
- void add_groups(int *p_cell, String p_base, int p_depth);
+ void _clear_groups();
+ void _update_groups();
+ void _add_groups(int *p_cell, String p_base, int p_depth);
void _new_group(StringName p_name);
- void _proximity_group_broadcast(String p_name, Variant p_params);
+ void _proximity_group_broadcast(String p_method, Variant p_parameters);
+
+protected:
+ void _notification(int p_what);
static void _bind_methods();
@@ -75,7 +74,7 @@ public:
void set_grid_radius(const Vector3 &p_radius);
Vector3 get_grid_radius() const;
- void broadcast(String p_name, Variant p_params);
+ void broadcast(String p_method, Variant p_parameters);
ProximityGroup3D();
~ProximityGroup3D() {}
@@ -83,4 +82,4 @@ public:
VARIANT_ENUM_CAST(ProximityGroup3D::DispatchMode);
-#endif
+#endif // PROXIMITY_GROUP_H
diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp
index 68f4b3132c..bfe79f15f5 100644
--- a/scene/3d/ray_cast_3d.cpp
+++ b/scene/3d/ray_cast_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,12 +31,12 @@
#include "ray_cast_3d.h"
#include "collision_object_3d.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
#include "mesh_instance_3d.h"
#include "servers/physics_server_3d.h"
-void RayCast3D::set_cast_to(const Vector3 &p_point) {
- cast_to = p_point;
+void RayCast3D::set_target_position(const Vector3 &p_point) {
+ target_position = p_point;
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update_gizmo();
}
@@ -45,8 +45,8 @@ void RayCast3D::set_cast_to(const Vector3 &p_point) {
}
}
-Vector3 RayCast3D::get_cast_to() const {
- return cast_to;
+Vector3 RayCast3D::get_target_position() const {
+ return target_position;
}
void RayCast3D::set_collision_mask(uint32_t p_mask) {
@@ -148,14 +148,14 @@ void RayCast3D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
if (enabled && !Engine::get_singleton()->is_editor_hint()) {
set_physics_process_internal(true);
-
- if (get_tree()->is_debugging_collisions_hint()) {
- _update_debug_shape();
- }
} else {
set_physics_process_internal(false);
}
+ if (get_tree()->is_debugging_collisions_hint()) {
+ _update_debug_shape();
+ }
+
if (Object::cast_to<CollisionObject3D>(get_parent())) {
if (exclude_parent_body) {
exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
@@ -202,7 +202,7 @@ void RayCast3D::_update_raycast_state() {
Transform gt = get_global_transform();
- Vector3 to = cast_to;
+ Vector3 to = target_position;
if (to == Vector3()) {
to = Vector3(0, 0.01, 0);
}
@@ -276,8 +276,8 @@ void RayCast3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast3D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast3D::is_enabled);
- ClassDB::bind_method(D_METHOD("set_cast_to", "local_point"), &RayCast3D::set_cast_to);
- ClassDB::bind_method(D_METHOD("get_cast_to"), &RayCast3D::get_cast_to);
+ ClassDB::bind_method(D_METHOD("set_target_position", "local_point"), &RayCast3D::set_target_position);
+ ClassDB::bind_method(D_METHOD("get_target_position"), &RayCast3D::get_target_position);
ClassDB::bind_method(D_METHOD("is_colliding"), &RayCast3D::is_colliding);
ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast3D::force_raycast_update);
@@ -312,7 +312,7 @@ void RayCast3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), "set_cast_to", "get_cast_to");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_GROUP("Collide With", "collide_with");
@@ -348,23 +348,32 @@ void RayCast3D::_update_debug_shape() {
}
MeshInstance3D *mi = static_cast<MeshInstance3D *>(debug_shape);
- if (!mi->get_mesh().is_valid()) {
+ Ref<ArrayMesh> mesh = mi->get_mesh();
+ if (!mesh.is_valid()) {
return;
}
- Ref<ArrayMesh> mesh = mi->get_mesh();
- mesh->clear_surfaces();
-
- Array a;
- a.resize(Mesh::ARRAY_MAX);
-
Vector<Vector3> verts;
verts.push_back(Vector3());
- verts.push_back(cast_to);
- a[Mesh::ARRAY_VERTEX] = verts;
+ verts.push_back(target_position);
- mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
- mesh->surface_set_material(0, debug_material);
+ if (mesh->get_surface_count() == 0) {
+ Array a;
+ a.resize(Mesh::ARRAY_MAX);
+ a[Mesh::ARRAY_VERTEX] = verts;
+
+ uint32_t flags = Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE;
+
+ mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags);
+ mesh->surface_set_material(0, debug_material);
+ } else {
+ Vector<uint8_t> byte_array;
+ int array_size = sizeof(Vector3) * verts.size();
+ byte_array.resize(array_size);
+ copymem(byte_array.ptrw(), verts.ptr(), array_size);
+
+ RS::get_singleton()->mesh_surface_update_region(mesh->get_rid(), 0, 0, byte_array);
+ }
}
void RayCast3D::_clear_debug_shape() {
@@ -383,14 +392,4 @@ void RayCast3D::_clear_debug_shape() {
}
RayCast3D::RayCast3D() {
- enabled = false;
-
- collided = false;
- against_shape = 0;
- collision_mask = 1;
- cast_to = Vector3(0, -1, 0);
- debug_shape = nullptr;
- exclude_parent_body = true;
- collide_with_areas = false;
- collide_with_bodies = true;
}
diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h
index 8f617e5491..ae92189527 100644
--- a/scene/3d/ray_cast_3d.h
+++ b/scene/3d/ray_cast_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -36,28 +36,28 @@
class RayCast3D : public Node3D {
GDCLASS(RayCast3D, Node3D);
- bool enabled;
- bool collided;
+ bool enabled = true;
+ bool collided = false;
ObjectID against;
- int against_shape;
+ int against_shape = 0;
Vector3 collision_point;
Vector3 collision_normal;
- Vector3 cast_to;
+ Vector3 target_position = Vector3(0, -1, 0);
Set<RID> exclude;
- uint32_t collision_mask;
- bool exclude_parent_body;
+ uint32_t collision_mask = 1;
+ bool exclude_parent_body = true;
- Node *debug_shape;
+ Node *debug_shape = nullptr;
Ref<Material> debug_material;
void _create_debug_shape();
void _update_debug_shape();
void _clear_debug_shape();
- bool collide_with_areas;
- bool collide_with_bodies;
+ bool collide_with_areas = false;
+ bool collide_with_bodies = true;
protected:
void _notification(int p_what);
@@ -74,8 +74,8 @@ public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
- void set_cast_to(const Vector3 &p_point);
- Vector3 get_cast_to() const;
+ void set_target_position(const Vector3 &p_point);
+ Vector3 get_target_position() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index b1f19053d9..ad24f39bce 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -39,31 +39,32 @@ float ReflectionProbe::get_intensity() const {
return intensity;
}
-void ReflectionProbe::set_interior_ambient(Color p_ambient) {
- interior_ambient = p_ambient;
- RS::get_singleton()->reflection_probe_set_interior_ambient(probe, p_ambient);
+void ReflectionProbe::set_ambient_mode(AmbientMode p_mode) {
+ ambient_mode = p_mode;
+ RS::get_singleton()->reflection_probe_set_ambient_mode(probe, RS::ReflectionProbeAmbientMode(p_mode));
+ notify_property_list_changed();
}
-void ReflectionProbe::set_interior_ambient_energy(float p_energy) {
- interior_ambient_energy = p_energy;
- RS::get_singleton()->reflection_probe_set_interior_ambient_energy(probe, p_energy);
+ReflectionProbe::AmbientMode ReflectionProbe::get_ambient_mode() const {
+ return ambient_mode;
}
-float ReflectionProbe::get_interior_ambient_energy() const {
- return interior_ambient_energy;
+void ReflectionProbe::set_ambient_color(Color p_ambient) {
+ ambient_color = p_ambient;
+ RS::get_singleton()->reflection_probe_set_ambient_color(probe, p_ambient);
}
-Color ReflectionProbe::get_interior_ambient() const {
- return interior_ambient;
+void ReflectionProbe::set_ambient_color_energy(float p_energy) {
+ ambient_color_energy = p_energy;
+ RS::get_singleton()->reflection_probe_set_ambient_energy(probe, p_energy);
}
-void ReflectionProbe::set_interior_ambient_probe_contribution(float p_contribution) {
- interior_ambient_probe_contribution = p_contribution;
- RS::get_singleton()->reflection_probe_set_interior_ambient_probe_contribution(probe, p_contribution);
+float ReflectionProbe::get_ambient_color_energy() const {
+ return ambient_color_energy;
}
-float ReflectionProbe::get_interior_ambient_probe_contribution() const {
- return interior_ambient_probe_contribution;
+Color ReflectionProbe::get_ambient_color() const {
+ return ambient_color;
}
void ReflectionProbe::set_max_distance(float p_distance) {
@@ -75,6 +76,15 @@ float ReflectionProbe::get_max_distance() const {
return max_distance;
}
+void ReflectionProbe::set_lod_threshold(float p_pixels) {
+ lod_threshold = p_pixels;
+ RS::get_singleton()->reflection_probe_set_lod_threshold(probe, p_pixels);
+}
+
+float ReflectionProbe::get_lod_threshold() const {
+ return lod_threshold;
+}
+
void ReflectionProbe::set_extents(const Vector3 &p_extents) {
extents = p_extents;
@@ -85,13 +95,12 @@ void ReflectionProbe::set_extents(const Vector3 &p_extents) {
if (extents[i] - 0.01 < ABS(origin_offset[i])) {
origin_offset[i] = SGN(origin_offset[i]) * (extents[i] - 0.01);
- _change_notify("origin_offset");
}
}
RS::get_singleton()->reflection_probe_set_extents(probe, extents);
RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset);
- _change_notify("extents");
+
update_gizmo();
}
@@ -110,7 +119,6 @@ void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) {
RS::get_singleton()->reflection_probe_set_extents(probe, extents);
RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset);
- _change_notify("origin_offset");
update_gizmo();
}
@@ -130,7 +138,6 @@ bool ReflectionProbe::is_box_projection_enabled() const {
void ReflectionProbe::set_as_interior(bool p_enable) {
interior = p_enable;
RS::get_singleton()->reflection_probe_set_as_interior(probe, interior);
- _change_notify();
}
bool ReflectionProbe::is_set_as_interior() const {
@@ -176,8 +183,8 @@ Vector<Face3> ReflectionProbe::get_faces(uint32_t p_usage_flags) const {
}
void ReflectionProbe::_validate_property(PropertyInfo &property) const {
- if (property.name == "interior/ambient_color" || property.name == "interior/ambient_energy" || property.name == "interior/ambient_contrib") {
- if (!interior) {
+ if (property.name == "interior/ambient_color" || property.name == "interior/ambient_color_energy") {
+ if (ambient_mode != AMBIENT_COLOR) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
@@ -187,18 +194,21 @@ void ReflectionProbe::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_intensity", "intensity"), &ReflectionProbe::set_intensity);
ClassDB::bind_method(D_METHOD("get_intensity"), &ReflectionProbe::get_intensity);
- ClassDB::bind_method(D_METHOD("set_interior_ambient", "ambient"), &ReflectionProbe::set_interior_ambient);
- ClassDB::bind_method(D_METHOD("get_interior_ambient"), &ReflectionProbe::get_interior_ambient);
+ ClassDB::bind_method(D_METHOD("set_ambient_mode", "ambient"), &ReflectionProbe::set_ambient_mode);
+ ClassDB::bind_method(D_METHOD("get_ambient_mode"), &ReflectionProbe::get_ambient_mode);
- ClassDB::bind_method(D_METHOD("set_interior_ambient_energy", "ambient_energy"), &ReflectionProbe::set_interior_ambient_energy);
- ClassDB::bind_method(D_METHOD("get_interior_ambient_energy"), &ReflectionProbe::get_interior_ambient_energy);
+ ClassDB::bind_method(D_METHOD("set_ambient_color", "ambient"), &ReflectionProbe::set_ambient_color);
+ ClassDB::bind_method(D_METHOD("get_ambient_color"), &ReflectionProbe::get_ambient_color);
- ClassDB::bind_method(D_METHOD("set_interior_ambient_probe_contribution", "ambient_probe_contribution"), &ReflectionProbe::set_interior_ambient_probe_contribution);
- ClassDB::bind_method(D_METHOD("get_interior_ambient_probe_contribution"), &ReflectionProbe::get_interior_ambient_probe_contribution);
+ ClassDB::bind_method(D_METHOD("set_ambient_color_energy", "ambient_energy"), &ReflectionProbe::set_ambient_color_energy);
+ ClassDB::bind_method(D_METHOD("get_ambient_color_energy"), &ReflectionProbe::get_ambient_color_energy);
ClassDB::bind_method(D_METHOD("set_max_distance", "max_distance"), &ReflectionProbe::set_max_distance);
ClassDB::bind_method(D_METHOD("get_max_distance"), &ReflectionProbe::get_max_distance);
+ ClassDB::bind_method(D_METHOD("set_lod_threshold", "ratio"), &ReflectionProbe::set_lod_threshold);
+ ClassDB::bind_method(D_METHOD("get_lod_threshold"), &ReflectionProbe::get_lod_threshold);
+
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &ReflectionProbe::set_extents);
ClassDB::bind_method(D_METHOD("get_extents"), &ReflectionProbe::get_extents);
@@ -226,33 +236,25 @@ void ReflectionProbe::_bind_methods() {
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");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_as_interior", "is_set_as_interior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_shadows"), "set_enable_shadows", "are_shadows_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_lod_threshold", "get_lod_threshold");
- ADD_GROUP("Interior", "interior_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior_enable"), "set_as_interior", "is_set_as_interior");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "interior_ambient_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_interior_ambient", "get_interior_ambient");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interior_ambient_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_interior_ambient_energy", "get_interior_ambient_energy");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interior_ambient_contrib", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_interior_ambient_probe_contribution", "get_interior_ambient_probe_contribution");
+ ADD_GROUP("Ambient", "ambient_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_mode", PROPERTY_HINT_ENUM, "Disabled,Environment,ConstantColor"), "set_ambient_mode", "get_ambient_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ambient_color", "get_ambient_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_color_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_color_energy", "get_ambient_color_energy");
BIND_ENUM_CONSTANT(UPDATE_ONCE);
BIND_ENUM_CONSTANT(UPDATE_ALWAYS);
+
+ BIND_ENUM_CONSTANT(AMBIENT_DISABLED);
+ BIND_ENUM_CONSTANT(AMBIENT_ENVIRONMENT);
+ BIND_ENUM_CONSTANT(AMBIENT_COLOR);
}
ReflectionProbe::ReflectionProbe() {
- intensity = 1.0;
- interior_ambient = Color(0, 0, 0);
- interior_ambient_probe_contribution = 0;
- interior_ambient_energy = 1.0;
- max_distance = 0;
- extents = Vector3(1, 1, 1);
- origin_offset = Vector3(0, 0, 0);
- box_projection = false;
- interior = false;
- enable_shadows = false;
- cull_mask = (1 << 20) - 1;
- update_mode = UPDATE_ONCE;
-
probe = RenderingServer::get_singleton()->reflection_probe_create();
RS::get_singleton()->instance_set_base(get_instance(), probe);
set_disable_scale(true);
diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h
index 3867d13435..15c2da3ae0 100644
--- a/scene/3d/reflection_probe.h
+++ b/scene/3d/reflection_probe.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -45,35 +45,45 @@ public:
UPDATE_ALWAYS,
};
+ enum AmbientMode {
+ AMBIENT_DISABLED,
+ AMBIENT_ENVIRONMENT,
+ AMBIENT_COLOR
+ };
+
private:
RID probe;
- float intensity;
- float max_distance;
- Vector3 extents;
- Vector3 origin_offset;
- bool box_projection;
- bool enable_shadows;
- bool interior;
- Color interior_ambient;
- float interior_ambient_energy;
- float interior_ambient_probe_contribution;
-
- uint32_t cull_mask;
- UpdateMode update_mode;
+ float intensity = 1.0;
+ float max_distance = 0.0;
+ Vector3 extents = Vector3(1, 1, 1);
+ Vector3 origin_offset = Vector3(0, 0, 0);
+ bool box_projection = false;
+ bool enable_shadows = false;
+ bool interior = false;
+ AmbientMode ambient_mode = AMBIENT_ENVIRONMENT;
+ Color ambient_color = Color(0, 0, 0);
+ float ambient_color_energy = 1.0;
+ float lod_threshold = 1.0;
+
+ uint32_t cull_mask = (1 << 20) - 1;
+ UpdateMode update_mode = UPDATE_ONCE;
protected:
static void _bind_methods();
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_intensity(float p_intensity);
float get_intensity() const;
- void set_interior_ambient(Color p_ambient);
- Color get_interior_ambient() const;
+ void set_ambient_mode(AmbientMode p_mode);
+ AmbientMode get_ambient_mode() const;
- void set_interior_ambient_energy(float p_energy);
- float get_interior_ambient_energy() const;
+ void set_ambient_color(Color p_ambient);
+ Color get_ambient_color() const;
+
+ void set_ambient_color_energy(float p_energy);
+ float get_ambient_color_energy() const;
void set_interior_ambient_probe_contribution(float p_contribution);
float get_interior_ambient_probe_contribution() const;
@@ -81,6 +91,9 @@ public:
void set_max_distance(float p_distance);
float get_max_distance() const;
+ void set_lod_threshold(float p_pixels);
+ float get_lod_threshold() const;
+
void set_extents(const Vector3 &p_extents);
Vector3 get_extents() const;
@@ -102,13 +115,14 @@ public:
void set_update_mode(UpdateMode p_mode);
UpdateMode get_update_mode() const;
- virtual AABB get_aabb() const;
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual AABB get_aabb() const override;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
ReflectionProbe();
~ReflectionProbe();
};
+VARIANT_ENUM_CAST(ReflectionProbe::AmbientMode);
VARIANT_ENUM_CAST(ReflectionProbe::UpdateMode);
#endif // REFLECTIONPROBE_H
diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp
index 95fce6b802..83ac813c53 100644
--- a/scene/3d/remote_transform_3d.cpp
+++ b/scene/3d/remote_transform_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -180,11 +180,16 @@ void RemoteTransform3D::force_update_cache() {
}
String RemoteTransform3D::get_configuration_warning() const {
+ String warning = Node3D::get_configuration_warning();
+
if (!has_node(remote_node) || !Object::cast_to<Node3D>(get_node(remote_node))) {
- return TTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work.");
}
- return String();
+ return warning;
}
void RemoteTransform3D::_bind_methods() {
@@ -212,10 +217,5 @@ void RemoteTransform3D::_bind_methods() {
}
RemoteTransform3D::RemoteTransform3D() {
- use_global_coordinates = true;
- update_remote_position = true;
- update_remote_rotation = true;
- update_remote_scale = true;
-
set_notify_transform(true);
}
diff --git a/scene/3d/remote_transform_3d.h b/scene/3d/remote_transform_3d.h
index 50d7c5a9b2..21005d92d1 100644
--- a/scene/3d/remote_transform_3d.h
+++ b/scene/3d/remote_transform_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -40,10 +40,10 @@ class RemoteTransform3D : public Node3D {
ObjectID cache;
- bool use_global_coordinates;
- bool update_remote_position;
- bool update_remote_rotation;
- bool update_remote_scale;
+ bool use_global_coordinates = true;
+ bool update_remote_position = true;
+ bool update_remote_rotation = true;
+ bool update_remote_scale = true;
void _update_remote();
void _update_cache();
@@ -70,7 +70,7 @@ public:
void force_update_cache();
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
RemoteTransform3D();
};
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 7516cf95b0..be62fe801f 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,12 +30,13 @@
#include "skeleton_3d.h"
-#include "core/engine.h"
-#include "core/message_queue.h"
-#include "core/project_settings.h"
-#include "core/type_info.h"
+#include "core/config/engine.h"
+#include "core/config/project_settings.h"
+#include "core/object/message_queue.h"
+#include "core/variant/type_info.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/resources/surface_tool.h"
+#include "scene/scene_string_names.h"
void SkinReference::_skin_changed() {
if (skeleton_node) {
@@ -66,6 +67,8 @@ SkinReference::~SkinReference() {
RS::get_singleton()->free(skeleton);
}
+///////////////////////////////////////
+
bool Skeleton3D::_set(const StringName &p_path, const Variant &p_value) {
String path = p_path;
@@ -157,12 +160,12 @@ bool Skeleton3D::_get(const StringName &p_path, Variant &r_ret) const {
void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < bones.size(); i++) {
String prep = "bones/" + itos(i) + "/";
- p_list->push_back(PropertyInfo(Variant::STRING, prep + "name"));
- p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1"));
- p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest"));
- p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled"));
- p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, prep + "bound_children"));
+ p_list->push_back(PropertyInfo(Variant::STRING, prep + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, prep + "bound_children", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
}
@@ -214,7 +217,7 @@ void Skeleton3D::_update_process_order() {
}
if (pass_count == len * len) {
- ERR_PRINT("Skeleton parenthood graph is cyclic");
+ ERR_PRINT("Skeleton3D parenthood graph is cyclic");
}
process_order_dirty = false;
@@ -223,7 +226,7 @@ void Skeleton3D::_update_process_order() {
void Skeleton3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_UPDATE_SKELETON: {
- RenderingServer *vs = RenderingServer::get_singleton();
+ RenderingServer *rs = RenderingServer::get_singleton();
Bone *bonesptr = bones.ptrw();
int len = bones.size();
@@ -288,9 +291,9 @@ void Skeleton3D::_notification(int p_what) {
for (List<ObjectID>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
- Node3D *sp = Object::cast_to<Node3D>(obj);
- ERR_CONTINUE(!sp);
- sp->set_transform(b.pose_global);
+ Node3D *node_3d = Object::cast_to<Node3D>(obj);
+ ERR_CONTINUE(!node_3d);
+ node_3d->set_transform(b.pose_global);
}
}
@@ -301,7 +304,7 @@ void Skeleton3D::_notification(int p_what) {
uint32_t bind_count = skin->get_bind_count();
if (E->get()->bind_count != bind_count) {
- RS::get_singleton()->skeleton_allocate(skeleton, bind_count);
+ RS::get_singleton()->skeleton_allocate_data(skeleton, bind_count);
E->get()->bind_count = bind_count;
E->get()->skin_bone_indices.resize(bind_count);
E->get()->skin_bone_indices_ptrs = E->get()->skin_bone_indices.ptrw();
@@ -323,7 +326,7 @@ void Skeleton3D::_notification(int p_what) {
}
if (!found) {
- ERR_PRINT("Skin bind #" + itos(i) + " contains named bind '" + String(bind_name) + "' but Skeleton has no bone by that name.");
+ ERR_PRINT("Skin bind #" + itos(i) + " contains named bind '" + String(bind_name) + "' but Skeleton3D has no bone by that name.");
E->get()->skin_bone_indices_ptrs[i] = 0;
}
} else if (skin->get_bind_bone(i) >= 0) {
@@ -346,11 +349,16 @@ void Skeleton3D::_notification(int p_what) {
for (uint32_t i = 0; i < bind_count; i++) {
uint32_t bone_index = E->get()->skin_bone_indices_ptrs[i];
ERR_CONTINUE(bone_index >= (uint32_t)len);
- vs->skeleton_bone_set_transform(skeleton, i, bonesptr[bone_index].pose_global * skin->get_bind_pose(i));
+ rs->skeleton_bone_set_transform(skeleton, i, bonesptr[bone_index].pose_global * skin->get_bind_pose(i));
}
}
dirty = false;
+
+#ifdef TOOLS_ENABLED
+ emit_signal(SceneStringNames::get_singleton()->pose_updated);
+#endif // TOOLS_ENABLED
+
} break;
#ifndef _3D_DISABLED
@@ -603,6 +611,11 @@ int Skeleton3D::get_process_order(int p_idx) {
return process_order[p_idx];
}
+Vector<int> Skeleton3D::get_bone_process_orders() {
+ _update_process_order();
+ return process_order;
+}
+
void Skeleton3D::localize_rests() {
_update_process_order();
@@ -835,14 +848,24 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) {
skin_bindings.insert(skin_ref.operator->());
- skin->connect_compat("changed", skin_ref.operator->(), "_skin_changed");
+ skin->connect("changed", Callable(skin_ref.operator->(), "_skin_changed"));
_make_dirty(); //skin needs to be updated, so update skeleton
return skin_ref;
}
+// helper functions
+Transform Skeleton3D::bone_transform_to_world_transform(Transform p_bone_transform) {
+ return get_global_transform() * p_bone_transform;
+}
+
+Transform Skeleton3D::world_transform_to_bone_transform(Transform p_world_transform) {
+ return get_global_transform().affine_inverse() * p_world_transform;
+}
+
void Skeleton3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_bone_process_orders"), &Skeleton3D::get_bone_process_orders);
ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton3D::add_bone);
ClassDB::bind_method(D_METHOD("find_bone", "name"), &Skeleton3D::find_bone);
ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &Skeleton3D::get_bone_name);
@@ -880,6 +903,9 @@ void Skeleton3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bone_custom_pose", "bone_idx"), &Skeleton3D::get_bone_custom_pose);
ClassDB::bind_method(D_METHOD("set_bone_custom_pose", "bone_idx", "custom_pose"), &Skeleton3D::set_bone_custom_pose);
+ ClassDB::bind_method(D_METHOD("bone_transform_to_world_transform", "bone_transform"), &Skeleton3D::bone_transform_to_world_transform);
+ ClassDB::bind_method(D_METHOD("world_transform_to_bone_transform", "world_transform"), &Skeleton3D::world_transform_to_bone_transform);
+
#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("set_animate_physical_bones"), &Skeleton3D::set_animate_physical_bones);
@@ -893,14 +919,14 @@ void Skeleton3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones");
#endif // _3D_DISABLED
+#ifdef TOOLS_ENABLED
+ ADD_SIGNAL(MethodInfo("pose_updated"));
+#endif // TOOLS_ENABLED
+
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
}
Skeleton3D::Skeleton3D() {
- animate_physical_bones = true;
- dirty = false;
- version = 1;
- process_order_dirty = true;
}
Skeleton3D::~Skeleton3D() {
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index 1e864c1c48..9772bfcc95 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -31,7 +31,7 @@
#ifndef SKELETON_3D_H
#define SKELETON_3D_H
-#include "core/rid.h"
+#include "core/templates/rid.h"
#include "scene/3d/node_3d.h"
#include "scene/resources/skin.h"
@@ -71,60 +71,47 @@ class Skeleton3D : public Node3D {
private:
friend class SkinReference;
- Set<SkinReference *> skin_bindings;
-
- void _skin_changed();
-
struct Bone {
String name;
- bool enabled;
- int parent;
- int sort_index; //used for re-sorting process order
+ bool enabled = true;
+ int parent = -1;
+ int sort_index = 0; //used for re-sorting process order
- bool disable_rest;
+ bool disable_rest = false;
Transform rest;
Transform pose;
Transform pose_global;
- bool custom_pose_enable;
+ bool custom_pose_enable = false;
Transform custom_pose;
- float global_pose_override_amount;
- bool global_pose_override_reset;
+ float global_pose_override_amount = 0.0;
+ bool global_pose_override_reset = false;
Transform global_pose_override;
#ifndef _3D_DISABLED
- PhysicalBone3D *physical_bone;
- PhysicalBone3D *cache_parent_physical_bone;
+ PhysicalBone3D *physical_bone = nullptr;
+ PhysicalBone3D *cache_parent_physical_bone = nullptr;
#endif // _3D_DISABLED
List<ObjectID> nodes_bound;
-
- Bone() {
- parent = -1;
- enabled = true;
- disable_rest = false;
- custom_pose_enable = false;
- global_pose_override_amount = 0;
- global_pose_override_reset = false;
-#ifndef _3D_DISABLED
- physical_bone = nullptr;
- cache_parent_physical_bone = nullptr;
-#endif // _3D_DISABLED
- }
};
- bool animate_physical_bones;
+ Set<SkinReference *> skin_bindings;
+
+ void _skin_changed();
+
+ bool animate_physical_bones = true;
Vector<Bone> bones;
Vector<int> process_order;
- bool process_order_dirty;
+ bool process_order_dirty = true;
void _make_dirty();
- bool dirty;
+ bool dirty = false;
- uint64_t version;
+ uint64_t version = 1;
// bind helpers
Array _get_bound_child_nodes_to_bone(int p_bone) const {
@@ -149,7 +136,6 @@ protected:
public:
enum {
-
NOTIFICATION_UPDATE_SKELETON = 50
};
@@ -196,9 +182,14 @@ public:
void localize_rests(); // used for loaders and tools
int get_process_order(int p_idx);
+ Vector<int> get_bone_process_orders();
Ref<SkinReference> register_skin(const Ref<Skin> &p_skin);
+ // Helper functions
+ Transform bone_transform_to_world_transform(Transform p_transform);
+ Transform world_transform_to_bone_transform(Transform p_transform);
+
#ifndef _3D_DISABLED
// Physical bone API
@@ -212,7 +203,7 @@ public:
PhysicalBone3D *get_physical_bone_parent(int p_bone);
private:
- /// This is a slow API os it's cached
+ /// This is a slow API, so it's cached
PhysicalBone3D *_get_physical_bone_parent(int p_bone);
void _rebuild_physical_bones_cache();
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp
index 9023f3c68a..cb486a12ae 100644
--- a/scene/3d/skeleton_ik_3d.cpp
+++ b/scene/3d/skeleton_ik_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -204,7 +204,7 @@ void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_
while (sub_chain_root) { // Reach the tip
sub_chain_root->current_pos = origin;
- if (!sub_chain_root->children.empty()) {
+ if (!sub_chain_root->children.is_empty()) {
ChainItem &child(sub_chain_root->children.write[0]);
// Is not tip
@@ -301,7 +301,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
Transform new_bone_pose(ci->initial_transform);
new_bone_pose.origin = ci->current_pos;
- if (!ci->children.empty()) {
+ if (!ci->children.is_empty()) {
/// Rotate basis
const Vector3 initial_ori((ci->children[0].initial_transform.origin - ci->initial_transform.origin).normalized());
const Vector3 rot_axis(initial_ori.cross(ci->current_ori).normalized());
@@ -321,7 +321,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true);
- if (!ci->children.empty()) {
+ if (!ci->children.is_empty()) {
ci = &ci->children.write[0];
} else {
ci = nullptr;
@@ -511,6 +511,11 @@ bool SkeletonIK3D::is_running() {
void SkeletonIK3D::start(bool p_one_time) {
if (p_one_time) {
set_process_internal(false);
+
+ if (target_node_override) {
+ reload_goal();
+ }
+
_solve_chain();
} else {
set_process_internal(true);
diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h
index 0d948f13a9..eefecf68bb 100644
--- a/scene/3d/skeleton_ik_3d.h
+++ b/scene/3d/skeleton_ik_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -54,15 +54,13 @@ class FabrikInverseKinematic {
BoneId bone = -1;
PhysicalBone3D *pb = nullptr;
- real_t length = 0;
+ real_t length = 0.0;
/// Positions relative to root bone
Transform initial_transform;
Vector3 current_pos;
// Direction from this bone to child
Vector3 current_ori;
- ChainItem() {}
-
ChainItem *find_child(const BoneId p_bone_id);
ChainItem *add_child(const BoneId p_bone_id);
};
@@ -76,15 +74,11 @@ class FabrikInverseKinematic {
ChainTip(ChainItem *p_chain_item, const EndEffector *p_end_effector) :
chain_item(p_chain_item),
end_effector(p_end_effector) {}
-
- ChainTip(const ChainTip &p_other_ct) :
- chain_item(p_other_ct.chain_item),
- end_effector(p_other_ct.end_effector) {}
};
struct Chain {
ChainItem chain_root;
- ChainItem *middle_chain_item;
+ ChainItem *middle_chain_item = nullptr;
Vector<ChainTip> tips;
Vector3 magnet_position;
};
@@ -134,7 +128,7 @@ class SkeletonIK3D : public Node {
StringName root_bone;
StringName tip_bone;
- real_t interpolation = 1;
+ real_t interpolation = 1.0;
Transform target;
NodePath target_node_path_override;
bool override_tip_basis = true;
@@ -150,7 +144,7 @@ class SkeletonIK3D : public Node {
protected:
virtual void
- _validate_property(PropertyInfo &property) const;
+ _validate_property(PropertyInfo &property) const override;
static void _bind_methods();
virtual void _notification(int p_what);
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index a267c57f5e..2d8f22ab37 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,10 +30,10 @@
#include "soft_body_3d.h"
-#include "core/list.h"
-#include "core/object.h"
+#include "core/object/class_db.h"
#include "core/os/os.h"
-#include "core/rid.h"
+#include "core/templates/list.h"
+#include "core/templates/rid.h"
#include "scene/3d/collision_object_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/3d/skeleton_3d.h"
@@ -106,7 +106,7 @@ SoftBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
offset = obj_tocopy.offset;
}
-SoftBody3D::PinnedPoint SoftBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
+SoftBody3D::PinnedPoint &SoftBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
point_index = obj.point_index;
spatial_attachment_path = obj.spatial_attachment_path;
spatial_attachment = obj.spatial_attachment;
@@ -245,13 +245,11 @@ bool SoftBody3D::_get_property_pinned_points(int p_item, const String &p_what, V
return true;
}
-void SoftBody3D::_changed_callback(Object *p_changed, const char *p_prop) {
+void SoftBody3D::_softbody_changed() {
prepare_physics_server();
_reset_points_offsets();
#ifdef TOOLS_ENABLED
- if (p_changed == this) {
- update_configuration_warning();
- }
+ update_configuration_warning();
#endif
}
@@ -259,7 +257,9 @@ void SoftBody3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
if (Engine::get_singleton()->is_editor_hint()) {
- add_change_receptor(this);
+ // I have no idea what this is supposed to do, it's really weird
+ // leaving for upcoming PK work on physics
+ //add_change_receptor(this);
}
RID space = get_world_3d()->get_space();
@@ -282,7 +282,7 @@ void SoftBody3D::_notification(int p_what) {
set_notify_transform(false);
// Required to be top level with Transform at center of world in order to modify RenderingServer only to support custom Transform
- set_as_toplevel(true);
+ set_as_top_level(true);
set_transform(Transform());
set_notify_transform(true);
@@ -337,8 +337,8 @@ void SoftBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness);
ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness);
- ClassDB::bind_method(D_METHOD("set_areaAngular_stiffness", "areaAngular_stiffness"), &SoftBody3D::set_areaAngular_stiffness);
- ClassDB::bind_method(D_METHOD("get_areaAngular_stiffness"), &SoftBody3D::get_areaAngular_stiffness);
+ ClassDB::bind_method(D_METHOD("set_angular_stiffness", "angular_stiffness"), &SoftBody3D::set_angular_stiffness);
+ ClassDB::bind_method(D_METHOD("get_angular_stiffness"), &SoftBody3D::get_angular_stiffness);
ClassDB::bind_method(D_METHOD("set_volume_stiffness", "volume_stiffness"), &SoftBody3D::set_volume_stiffness);
ClassDB::bind_method(D_METHOD("get_volume_stiffness"), &SoftBody3D::get_volume_stiffness);
@@ -366,7 +366,7 @@ void SoftBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "areaAngular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_areaAngular_stiffness", "get_areaAngular_stiffness");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_angular_stiffness", "get_angular_stiffness");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient");
@@ -380,7 +380,7 @@ String SoftBody3D::get_configuration_warning() const {
String warning = MeshInstance3D::get_configuration_warning();
if (get_mesh().is_null()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
@@ -389,7 +389,7 @@ String SoftBody3D::get_configuration_warning() const {
Transform t = get_transform();
if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
@@ -425,7 +425,7 @@ void SoftBody3D::_draw_soft_mesh() {
/// Necessary in order to render the mesh correctly (Soft body nodes are in global space)
simulation_started = true;
- call_deferred("set_as_toplevel", true);
+ call_deferred("set_as_top_level", true);
call_deferred("set_transform", Transform());
}
@@ -480,7 +480,6 @@ void SoftBody3D::become_mesh_owner() {
Dictionary surface_lods = mesh->surface_get_lods(0);
uint32_t surface_format = mesh->surface_get_format(0);
- surface_format &= ~(Mesh::ARRAY_COMPRESS_NORMAL);
surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE;
Ref<ArrayMesh> soft_mesh;
@@ -613,12 +612,12 @@ real_t SoftBody3D::get_linear_stiffness() {
return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid);
}
-void SoftBody3D::set_areaAngular_stiffness(real_t p_areaAngular_stiffness) {
- PhysicsServer3D::get_singleton()->soft_body_set_areaAngular_stiffness(physics_rid, p_areaAngular_stiffness);
+void SoftBody3D::set_angular_stiffness(real_t p_angular_stiffness) {
+ PhysicsServer3D::get_singleton()->soft_body_set_angular_stiffness(physics_rid, p_angular_stiffness);
}
-real_t SoftBody3D::get_areaAngular_stiffness() {
- return PhysicsServer3D::get_singleton()->soft_body_get_areaAngular_stiffness(physics_rid);
+real_t SoftBody3D::get_angular_stiffness() {
+ return PhysicsServer3D::get_singleton()->soft_body_get_angular_stiffness(physics_rid);
}
void SoftBody3D::set_volume_stiffness(real_t p_volume_stiffness) {
@@ -725,7 +724,7 @@ void SoftBody3D::_update_cache_pin_points_datas() {
w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(w[i].spatial_attachment_path));
}
if (!w[i].spatial_attachment) {
- ERR_PRINT("Node3D node not defined in the pinned point, Softbody undefined behaviour!");
+ ERR_PRINT("Node3D node not defined in the pinned point, this is undefined behavior for SoftBody3D!");
}
}
}
diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h
index 0063e342f2..6e24a530bd 100644
--- a/scene/3d/soft_body_3d.h
+++ b/scene/3d/soft_body_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -39,13 +39,13 @@ class SoftBodyRenderingServerHandler {
friend class SoftBody3D;
RID mesh;
- int surface;
+ int surface = 0;
Vector<uint8_t> buffer;
- uint32_t stride;
- uint32_t offset_vertices;
- uint32_t offset_normal;
+ uint32_t stride = 0;
+ uint32_t offset_vertices = 0;
+ uint32_t offset_normal = 0;
- uint8_t *write_buffer;
+ uint8_t *write_buffer = nullptr;
private:
SoftBodyRenderingServerHandler();
@@ -74,7 +74,7 @@ public:
PinnedPoint();
PinnedPoint(const PinnedPoint &obj_tocopy);
- PinnedPoint operator=(const PinnedPoint &obj);
+ PinnedPoint &operator=(const PinnedPoint &obj);
};
private:
@@ -91,13 +91,15 @@ private:
bool pinned_points_cache_dirty = true;
Ref<ArrayMesh> debug_mesh_cache;
- class MeshInstance3D *debug_mesh;
+ class MeshInstance3D *debug_mesh = nullptr;
- bool capture_input_on_drag;
+ bool capture_input_on_drag = false;
bool ray_pickable = true;
void _update_pickable();
+ void _softbody_changed();
+
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
@@ -107,12 +109,10 @@ protected:
bool _set_property_pinned_points_attachment(int p_item, const String &p_what, const Variant &p_value);
bool _get_property_pinned_points(int p_item, const String &p_what, Variant &r_ret) const;
- virtual void _changed_callback(Object *p_changed, const char *p_prop);
-
void _notification(int p_what);
static void _bind_methods();
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
protected:
void _update_physics_server();
@@ -149,8 +149,8 @@ public:
void set_linear_stiffness(real_t p_linear_stiffness);
real_t get_linear_stiffness();
- void set_areaAngular_stiffness(real_t p_areaAngular_stiffness);
- real_t get_areaAngular_stiffness();
+ void set_angular_stiffness(real_t p_angular_stiffness);
+ real_t get_angular_stiffness();
void set_volume_stiffness(real_t p_volume_stiffness);
real_t get_volume_stiffness();
diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp
index 9775ecc6c6..9518b47696 100644
--- a/scene/3d/spring_arm_3d.cpp
+++ b/scene/3d/spring_arm_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,7 +30,7 @@
#include "spring_arm_3d.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
#include "scene/3d/collision_object_3d.h"
#include "scene/resources/sphere_shape_3d.h"
#include "servers/physics_server_3d.h"
@@ -78,11 +78,11 @@ void SpringArm3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin");
}
-float SpringArm3D::get_length() const {
+real_t SpringArm3D::get_length() const {
return spring_length;
}
-void SpringArm3D::set_length(float p_length) {
+void SpringArm3D::set_length(real_t p_length) {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update_gizmo();
}
@@ -106,11 +106,11 @@ uint32_t SpringArm3D::get_mask() {
return mask;
}
-float SpringArm3D::get_margin() {
+real_t SpringArm3D::get_margin() {
return margin;
}
-void SpringArm3D::set_margin(float p_margin) {
+void SpringArm3D::set_margin(real_t p_margin) {
margin = p_margin;
}
@@ -126,7 +126,7 @@ void SpringArm3D::clear_excluded_objects() {
excluded_objects.clear();
}
-float SpringArm3D::get_hit_length() {
+real_t SpringArm3D::get_hit_length() {
return current_spring_length;
}
@@ -143,7 +143,7 @@ void SpringArm3D::process_spring() {
PhysicsDirectSpaceState3D::RayResult r;
bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask);
if (intersected) {
- float dist = get_global_transform().origin.distance_to(r.position);
+ real_t dist = get_global_transform().origin.distance_to(r.position);
dist -= margin;
motion_delta = dist / (spring_length);
}
diff --git a/scene/3d/spring_arm_3d.h b/scene/3d/spring_arm_3d.h
index 7f6fe2f1a2..63505ab9d3 100644
--- a/scene/3d/spring_arm_3d.h
+++ b/scene/3d/spring_arm_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -38,19 +38,19 @@ class SpringArm3D : public Node3D {
Ref<Shape3D> shape;
Set<RID> excluded_objects;
- float spring_length = 1;
- float current_spring_length = 0;
+ real_t spring_length = 1.0;
+ real_t current_spring_length = 0.0;
bool keep_child_basis = false;
uint32_t mask = 1;
- float margin = 0.01;
+ real_t margin = 0.01;
protected:
void _notification(int p_what);
static void _bind_methods();
public:
- void set_length(float p_length);
- float get_length() const;
+ void set_length(real_t p_length);
+ real_t get_length() const;
void set_shape(Ref<Shape3D> p_shape);
Ref<Shape3D> get_shape() const;
void set_mask(uint32_t p_mask);
@@ -58,9 +58,9 @@ public:
void add_excluded_object(RID p_rid);
bool remove_excluded_object(RID p_rid);
void clear_excluded_objects();
- float get_hit_length();
- void set_margin(float p_margin);
- float get_margin();
+ real_t get_hit_length();
+ void set_margin(real_t p_margin);
+ real_t get_margin();
SpringArm3D() {}
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 3b76cb6499..cb2df9130f 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -204,7 +204,6 @@ 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,
@@ -340,24 +339,10 @@ void SpriteBase3D::_bind_methods() {
}
SpriteBase3D::SpriteBase3D() {
- color_dirty = true;
- centered = true;
- hflip = false;
- vflip = false;
- parent_sprite = nullptr;
- pI = nullptr;
-
for (int i = 0; i < FLAG_MAX; i++) {
flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED;
}
- alpha_cut = ALPHA_CUT_DISABLED;
- billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
- axis = Vector3::AXIS_Z;
- pixel_size = 0.01;
- modulate = Color(1, 1, 1, 1);
- pending_update = false;
- opacity = 1.0;
immediate = RenderingServer::get_singleton()->immediate_create();
set_base(immediate);
}
@@ -414,7 +399,6 @@ 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,
@@ -488,7 +472,7 @@ void Sprite3D::_draw() {
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[i]);
+ RS::get_singleton()->immediate_uv(immediate, uvs[index[i]]);
Vector3 vtx;
vtx[x_axis] = vertices[index[i]][0];
@@ -559,8 +543,6 @@ void Sprite3D::set_frame(int p_frame) {
_queue_update();
- _change_notify("frame");
- _change_notify("frame_coords");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -583,7 +565,7 @@ void Sprite3D::set_vframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
vframes = p_amount;
_queue_update();
- _change_notify();
+ notify_property_list_changed();
}
int Sprite3D::get_vframes() const {
@@ -594,7 +576,7 @@ void Sprite3D::set_hframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
hframes = p_amount;
_queue_update();
- _change_notify();
+ notify_property_list_changed();
}
int Sprite3D::get_hframes() const {
@@ -667,8 +649,8 @@ void Sprite3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_GROUP("Animation", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
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::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
@@ -740,7 +722,6 @@ 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,
@@ -818,7 +799,7 @@ void AnimatedSprite3D::_draw() {
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[i]);
+ RS::get_singleton()->immediate_uv(immediate, uvs[indices[i]]);
Vector3 vtx;
vtx[x_axis] = vertices[indices[i]][0];
@@ -907,12 +888,13 @@ void AnimatedSprite3D::_notification(int p_what) {
} else {
frame = fc - 1;
}
+ emit_signal(SceneStringNames::get_singleton()->animation_finished);
} else {
frame++;
}
_queue_update();
- _change_notify("frame");
+ emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
float to_process = MIN(timeout, remaining);
@@ -938,7 +920,7 @@ void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
set_frame(frame);
}
- _change_notify();
+ notify_property_list_changed();
_reset_timeout();
_queue_update();
update_configuration_warning();
@@ -971,7 +953,7 @@ void AnimatedSprite3D::set_frame(int p_frame) {
frame = p_frame;
_reset_timeout();
_queue_update();
- _change_notify("frame");
+
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -1007,8 +989,6 @@ Rect2 AnimatedSprite3D::get_item_rect() const {
void AnimatedSprite3D::_res_changed() {
set_frame(frame);
- _change_notify("frame");
- _change_notify("animation");
_queue_update();
}
@@ -1065,7 +1045,7 @@ void AnimatedSprite3D::set_animation(const StringName &p_animation) {
animation = p_animation;
_reset_timeout();
set_frame(0);
- _change_notify();
+ notify_property_list_changed();
_queue_update();
}
@@ -1074,11 +1054,16 @@ StringName AnimatedSprite3D::get_animation() const {
}
String AnimatedSprite3D::get_configuration_warning() const {
+ String warning = SpriteBase3D::get_configuration_warning();
+
if (frames.is_null()) {
- return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames.");
}
- return String();
+ return warning;
}
void AnimatedSprite3D::_bind_methods() {
@@ -1099,6 +1084,7 @@ void AnimatedSprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame);
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");
@@ -1107,8 +1093,4 @@ void AnimatedSprite3D::_bind_methods() {
}
AnimatedSprite3D::AnimatedSprite3D() {
- frame = 0;
- playing = false;
- animation = "default";
- timeout = 0;
}
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index 721bed56f1..a9ce2d8eee 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -55,32 +55,32 @@ public:
};
private:
- bool color_dirty;
+ bool color_dirty = true;
Color color_accum;
- SpriteBase3D *parent_sprite;
+ SpriteBase3D *parent_sprite = nullptr;
List<SpriteBase3D *> children;
- List<SpriteBase3D *>::Element *pI;
+ List<SpriteBase3D *>::Element *pI = nullptr;
- bool centered;
+ bool centered = true;
Point2 offset;
- bool hflip;
- bool vflip;
+ bool hflip = false;
+ bool vflip = false;
- Color modulate;
- float opacity;
+ Color modulate = Color(1, 1, 1, 1);
+ float opacity = 1.0;
- Vector3::Axis axis;
- float pixel_size;
+ Vector3::Axis axis = Vector3::AXIS_Z;
+ float pixel_size = 0.01;
AABB aabb;
RID immediate;
bool flags[FLAG_MAX];
- AlphaCutMode alpha_cut;
- StandardMaterial3D::BillboardMode billboard_mode;
- bool pending_update;
+ AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
+ StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
+ bool pending_update = false;
void _im_update();
void _propagate_color_changed();
@@ -135,8 +135,8 @@ public:
virtual Rect2 get_item_rect() const = 0;
- virtual AABB get_aabb() const;
- virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual AABB get_aabb() const override;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
Ref<TriangleMesh> generate_triangle_mesh() const;
SpriteBase3D();
@@ -158,10 +158,10 @@ class Sprite3D : public SpriteBase3D {
void _texture_changed();
protected:
- virtual void _draw();
+ virtual void _draw() override;
static void _bind_methods();
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
public:
void set_texture(const Ref<Texture2D> &p_texture);
@@ -185,7 +185,7 @@ public:
void set_hframes(int p_amount);
int get_hframes() const;
- virtual Rect2 get_item_rect() const;
+ virtual Rect2 get_item_rect() const override;
Sprite3D();
//~Sprite3D();
@@ -195,16 +195,16 @@ class AnimatedSprite3D : public SpriteBase3D {
GDCLASS(AnimatedSprite3D, SpriteBase3D);
Ref<SpriteFrames> frames;
- bool playing;
- StringName animation;
- int frame;
+ bool playing = false;
+ StringName animation = "default";
+ int frame = 0;
- bool centered;
+ bool centered = true;
- float timeout;
+ float timeout = 0.0;
- bool hflip;
- bool vflip;
+ bool hflip = 1;
+ bool vflip = 1;
Color modulate;
@@ -215,10 +215,10 @@ class AnimatedSprite3D : public SpriteBase3D {
bool _is_playing() const;
protected:
- virtual void _draw();
+ virtual void _draw() override;
static void _bind_methods();
void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
public:
void set_sprite_frames(const Ref<SpriteFrames> &p_frames);
@@ -234,9 +234,9 @@ public:
void set_frame(int p_frame);
int get_frame() const;
- virtual Rect2 get_item_rect() const;
+ virtual Rect2 get_item_rect() const override;
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
AnimatedSprite3D();
};
diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp
index 9c6b940b00..0d25e2f21f 100644
--- a/scene/3d/vehicle_body_3d.cpp
+++ b/scene/3d/vehicle_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -103,11 +103,16 @@ void VehicleWheel3D::_notification(int p_what) {
}
String VehicleWheel3D::get_configuration_warning() const {
+ String warning = Node3D::get_configuration_warning();
+
if (!Object::cast_to<VehicleBody3D>(get_parent())) {
- return TTR("VehicleWheel3D serves to provide a wheel system to a VehicleBody3D. Please use it as a child of a VehicleBody3D.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("VehicleWheel3D serves to provide a wheel system to a VehicleBody3D. Please use it as a child of a VehicleBody3D.");
}
- return String();
+ return warning;
}
void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) {
@@ -142,77 +147,77 @@ void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) {
}
}
-void VehicleWheel3D::set_radius(float p_radius) {
+void VehicleWheel3D::set_radius(real_t p_radius) {
m_wheelRadius = p_radius;
update_gizmo();
}
-float VehicleWheel3D::get_radius() const {
+real_t VehicleWheel3D::get_radius() const {
return m_wheelRadius;
}
-void VehicleWheel3D::set_suspension_rest_length(float p_length) {
+void VehicleWheel3D::set_suspension_rest_length(real_t p_length) {
m_suspensionRestLength = p_length;
update_gizmo();
}
-float VehicleWheel3D::get_suspension_rest_length() const {
+real_t VehicleWheel3D::get_suspension_rest_length() const {
return m_suspensionRestLength;
}
-void VehicleWheel3D::set_suspension_travel(float p_length) {
+void VehicleWheel3D::set_suspension_travel(real_t p_length) {
m_maxSuspensionTravelCm = p_length / 0.01;
}
-float VehicleWheel3D::get_suspension_travel() const {
+real_t VehicleWheel3D::get_suspension_travel() const {
return m_maxSuspensionTravelCm * 0.01;
}
-void VehicleWheel3D::set_suspension_stiffness(float p_value) {
+void VehicleWheel3D::set_suspension_stiffness(real_t p_value) {
m_suspensionStiffness = p_value;
}
-float VehicleWheel3D::get_suspension_stiffness() const {
+real_t VehicleWheel3D::get_suspension_stiffness() const {
return m_suspensionStiffness;
}
-void VehicleWheel3D::set_suspension_max_force(float p_value) {
+void VehicleWheel3D::set_suspension_max_force(real_t p_value) {
m_maxSuspensionForce = p_value;
}
-float VehicleWheel3D::get_suspension_max_force() const {
+real_t VehicleWheel3D::get_suspension_max_force() const {
return m_maxSuspensionForce;
}
-void VehicleWheel3D::set_damping_compression(float p_value) {
+void VehicleWheel3D::set_damping_compression(real_t p_value) {
m_wheelsDampingCompression = p_value;
}
-float VehicleWheel3D::get_damping_compression() const {
+real_t VehicleWheel3D::get_damping_compression() const {
return m_wheelsDampingCompression;
}
-void VehicleWheel3D::set_damping_relaxation(float p_value) {
+void VehicleWheel3D::set_damping_relaxation(real_t p_value) {
m_wheelsDampingRelaxation = p_value;
}
-float VehicleWheel3D::get_damping_relaxation() const {
+real_t VehicleWheel3D::get_damping_relaxation() const {
return m_wheelsDampingRelaxation;
}
-void VehicleWheel3D::set_friction_slip(float p_value) {
+void VehicleWheel3D::set_friction_slip(real_t p_value) {
m_frictionSlip = p_value;
}
-float VehicleWheel3D::get_friction_slip() const {
+real_t VehicleWheel3D::get_friction_slip() const {
return m_frictionSlip;
}
-void VehicleWheel3D::set_roll_influence(float p_value) {
+void VehicleWheel3D::set_roll_influence(real_t p_value) {
m_rollInfluence = p_value;
}
-float VehicleWheel3D::get_roll_influence() const {
+real_t VehicleWheel3D::get_roll_influence() const {
return m_rollInfluence;
}
@@ -290,27 +295,27 @@ void VehicleWheel3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_relaxation"), "set_damping_relaxation", "get_damping_relaxation");
}
-void VehicleWheel3D::set_engine_force(float p_engine_force) {
+void VehicleWheel3D::set_engine_force(real_t p_engine_force) {
m_engineForce = p_engine_force;
}
-float VehicleWheel3D::get_engine_force() const {
+real_t VehicleWheel3D::get_engine_force() const {
return m_engineForce;
}
-void VehicleWheel3D::set_brake(float p_brake) {
+void VehicleWheel3D::set_brake(real_t p_brake) {
m_brake = p_brake;
}
-float VehicleWheel3D::get_brake() const {
+real_t VehicleWheel3D::get_brake() const {
return m_brake;
}
-void VehicleWheel3D::set_steering(float p_steering) {
+void VehicleWheel3D::set_steering(real_t p_steering) {
m_steering = p_steering;
}
-float VehicleWheel3D::get_steering() const {
+real_t VehicleWheel3D::get_steering() const {
return m_steering;
}
@@ -330,39 +335,15 @@ bool VehicleWheel3D::is_used_as_steering() const {
return steers;
}
-float VehicleWheel3D::get_skidinfo() const {
+real_t VehicleWheel3D::get_skidinfo() const {
return m_skidInfo;
}
-float VehicleWheel3D::get_rpm() const {
+real_t VehicleWheel3D::get_rpm() const {
return m_rpm;
}
VehicleWheel3D::VehicleWheel3D() {
- steers = false;
- engine_traction = false;
- m_steering = real_t(0.);
- m_engineForce = real_t(0.);
- m_rotation = real_t(0.);
- m_deltaRotation = real_t(0.);
- m_brake = real_t(0.);
- m_rollInfluence = real_t(0.1);
-
- m_suspensionRestLength = 0.15;
- m_wheelRadius = 0.5; //0.28;
- m_suspensionStiffness = 5.88;
- m_wheelsDampingCompression = 0.83;
- m_wheelsDampingRelaxation = 0.88;
- m_frictionSlip = 10.5;
- m_bIsFrontWheel = false;
- m_maxSuspensionTravelCm = 500;
- m_maxSuspensionForce = 6000;
-
- m_suspensionRelativeVelocity = 0;
- m_clippedInvContactDotSuspension = 1.0;
- m_raycastInfo.m_isInContact = false;
-
- body = nullptr;
}
void VehicleBody3D::_update_wheel_transform(VehicleWheel3D &wheel, PhysicsDirectBodyState3D *s) {
@@ -559,7 +540,7 @@ void VehicleBody3D::_resolve_single_bilateral(PhysicsDirectBodyState3D *s, const
Vector3 vel = vel1 - vel2;
Basis b2trans;
- float b2invmass = 0;
+ real_t b2invmass = 0;
Vector3 b2lv;
Vector3 b2av;
Vector3 b2invinertia; //todo
@@ -617,8 +598,8 @@ VehicleBody3D::btVehicleWheelContactPoint::btVehicleWheelContactPoint(PhysicsDir
m_frictionPositionWorld(frictionPosWorld),
m_frictionDirectionWorld(frictionDirectionWorld),
m_maxImpulse(maxImpulse) {
- float denom0 = 0;
- float denom1 = 0;
+ real_t denom0 = 0;
+ real_t denom1 = 0;
{
Vector3 r0 = frictionPosWorld - s->get_transform().origin;
@@ -629,7 +610,6 @@ VehicleBody3D::btVehicleWheelContactPoint::btVehicleWheelContactPoint(PhysicsDir
/* TODO: Why is this code unused?
if (body1) {
-
Vector3 r0 = frictionPosWorld - body1->get_global_transform().origin;
Vector3 c0 = (r0).cross(frictionDirectionWorld);
Vector3 vec = s->get_inverse_inertia_tensor().xform_inv(c0).cross(r0);
@@ -794,7 +774,7 @@ void VehicleBody3D::_update_friction(PhysicsDirectBodyState3D *s) {
s->get_transform().origin;
if (m_forwardImpulse[wheel] != real_t(0.)) {
- s->apply_impulse(rel_pos, m_forwardWS[wheel] * (m_forwardImpulse[wheel]));
+ s->apply_impulse(m_forwardWS[wheel] * (m_forwardImpulse[wheel]), rel_pos);
}
if (m_sideImpulse[wheel] != real_t(0.)) {
PhysicsBody3D *groundObject = wheelInfo.m_raycastInfo.m_groundObject;
@@ -812,7 +792,7 @@ void VehicleBody3D::_update_friction(PhysicsDirectBodyState3D *s) {
#else
rel_pos[1] *= wheelInfo.m_rollInfluence; //?
#endif
- s->apply_impulse(rel_pos, sideImp);
+ s->apply_impulse(sideImp, rel_pos);
//apply friction impulse on the ground
//todo
@@ -827,7 +807,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) {
state = Object::cast_to<PhysicsDirectBodyState3D>(p_state);
- float step = state->get_step();
+ real_t step = state->get_step();
for (int i = 0; i < wheels.size(); i++) {
_update_wheel(i, state);
@@ -850,10 +830,9 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) {
suspensionForce = wheel.m_maxSuspensionForce;
}
Vector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step;
- Vector3 relpos = wheel.m_raycastInfo.m_contactPointWS - state->get_transform().origin;
+ Vector3 relative_position = wheel.m_raycastInfo.m_contactPointWS - state->get_transform().origin;
- state->apply_impulse(relpos, impulse);
- //getRigidBody()->applyImpulse(impulse, relpos);
+ state->apply_impulse(impulse, relative_position);
}
_update_friction(state);
@@ -888,7 +867,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) {
state = nullptr;
}
-void VehicleBody3D::set_engine_force(float p_engine_force) {
+void VehicleBody3D::set_engine_force(real_t p_engine_force) {
engine_force = p_engine_force;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
@@ -898,11 +877,11 @@ void VehicleBody3D::set_engine_force(float p_engine_force) {
}
}
-float VehicleBody3D::get_engine_force() const {
+real_t VehicleBody3D::get_engine_force() const {
return engine_force;
}
-void VehicleBody3D::set_brake(float p_brake) {
+void VehicleBody3D::set_brake(real_t p_brake) {
brake = p_brake;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
@@ -910,11 +889,11 @@ void VehicleBody3D::set_brake(float p_brake) {
}
}
-float VehicleBody3D::get_brake() const {
+real_t VehicleBody3D::get_brake() const {
return brake;
}
-void VehicleBody3D::set_steering(float p_steering) {
+void VehicleBody3D::set_steering(real_t p_steering) {
m_steeringValue = p_steering;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
@@ -924,7 +903,7 @@ void VehicleBody3D::set_steering(float p_steering) {
}
}
-float VehicleBody3D::get_steering() const {
+real_t VehicleBody3D::get_steering() const {
return m_steeringValue;
}
@@ -945,16 +924,6 @@ void VehicleBody3D::_bind_methods() {
}
VehicleBody3D::VehicleBody3D() {
- m_pitchControl = 0;
- m_currentVehicleSpeedKmHour = real_t(0.);
- m_steeringValue = real_t(0.);
-
- engine_force = 0;
- brake = 0;
-
- state = nullptr;
- ccd = false;
-
exclude.insert(get_rid());
//PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h
index e76f44acfd..860fa7e3b7 100644
--- a/scene/3d/vehicle_body_3d.h
+++ b/scene/3d/vehicle_body_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -42,52 +42,52 @@ class VehicleWheel3D : public Node3D {
Transform m_worldTransform;
Transform local_xform;
- bool engine_traction;
- bool steers;
+ bool engine_traction = false;
+ bool steers = false;
Vector3 m_chassisConnectionPointCS; //const
Vector3 m_wheelDirectionCS; //const
Vector3 m_wheelAxleCS; // const or modified by steering
- real_t m_suspensionRestLength;
- real_t m_maxSuspensionTravelCm;
- real_t m_wheelRadius;
+ real_t m_suspensionRestLength = 0.15;
+ real_t m_maxSuspensionTravelCm = 500.0;
+ real_t m_wheelRadius = 0.5;
- real_t m_suspensionStiffness;
- real_t m_wheelsDampingCompression;
- real_t m_wheelsDampingRelaxation;
- real_t m_frictionSlip;
- real_t m_maxSuspensionForce;
- bool m_bIsFrontWheel;
+ real_t m_suspensionStiffness = 5.88;
+ real_t m_wheelsDampingCompression = 0.83;
+ real_t m_wheelsDampingRelaxation = 0.88;
+ real_t m_frictionSlip = 10.5;
+ real_t m_maxSuspensionForce = 6000.0;
+ bool m_bIsFrontWheel = false;
- VehicleBody3D *body;
+ VehicleBody3D *body = nullptr;
//btVector3 m_wheelAxleCS; // const or modified by steering ?
- real_t m_steering;
- real_t m_rotation;
- real_t m_deltaRotation;
- real_t m_rpm;
- real_t m_rollInfluence;
- real_t m_engineForce;
- real_t m_brake;
+ real_t m_steering = 0.0;
+ real_t m_rotation = 0.0;
+ real_t m_deltaRotation = 0.0;
+ real_t m_rpm = 0.0;
+ real_t m_rollInfluence = 0.1;
+ real_t m_engineForce = 0.0;
+ real_t m_brake = 0.0;
- real_t m_clippedInvContactDotSuspension;
- real_t m_suspensionRelativeVelocity;
+ real_t m_clippedInvContactDotSuspension = 1.0;
+ real_t m_suspensionRelativeVelocity = 0.0;
//calculated by suspension
- real_t m_wheelsSuspensionForce;
- real_t m_skidInfo;
+ real_t m_wheelsSuspensionForce = 0.0;
+ real_t m_skidInfo = 0.0;
struct RaycastInfo {
//set by raycaster
Vector3 m_contactNormalWS; //contactnormal
Vector3 m_contactPointWS; //raycast hitpoint
- real_t m_suspensionLength;
+ real_t m_suspensionLength = 0.0;
Vector3 m_hardPointWS; //raycast starting point
Vector3 m_wheelDirectionWS; //direction in worldspace
Vector3 m_wheelAxleWS; // axle in worldspace
- bool m_isInContact;
- PhysicsBody3D *m_groundObject; //could be general void* ptr
+ bool m_isInContact = false;
+ PhysicsBody3D *m_groundObject = nullptr; //could be general void* ptr
} m_raycastInfo;
void _update(PhysicsDirectBodyState3D *s);
@@ -97,29 +97,29 @@ protected:
static void _bind_methods();
public:
- void set_radius(float p_radius);
- float get_radius() const;
+ void set_radius(real_t p_radius);
+ real_t get_radius() const;
- void set_suspension_rest_length(float p_length);
- float get_suspension_rest_length() const;
+ void set_suspension_rest_length(real_t p_length);
+ real_t get_suspension_rest_length() const;
- void set_suspension_travel(float p_length);
- float get_suspension_travel() const;
+ void set_suspension_travel(real_t p_length);
+ real_t get_suspension_travel() const;
- void set_suspension_stiffness(float p_value);
- float get_suspension_stiffness() const;
+ void set_suspension_stiffness(real_t p_value);
+ real_t get_suspension_stiffness() const;
- void set_suspension_max_force(float p_value);
- float get_suspension_max_force() const;
+ void set_suspension_max_force(real_t p_value);
+ real_t get_suspension_max_force() const;
- void set_damping_compression(float p_value);
- float get_damping_compression() const;
+ void set_damping_compression(real_t p_value);
+ real_t get_damping_compression() const;
- void set_damping_relaxation(float p_value);
- float get_damping_relaxation() const;
+ void set_damping_relaxation(real_t p_value);
+ real_t get_damping_relaxation() const;
- void set_friction_slip(float p_value);
- float get_friction_slip() const;
+ void set_friction_slip(real_t p_value);
+ real_t get_friction_slip() const;
void set_use_as_traction(bool p_enable);
bool is_used_as_traction() const;
@@ -129,23 +129,23 @@ public:
bool is_in_contact() const;
- void set_roll_influence(float p_value);
- float get_roll_influence() const;
+ void set_roll_influence(real_t p_value);
+ real_t get_roll_influence() const;
- float get_skidinfo() const;
+ real_t get_skidinfo() const;
- float get_rpm() const;
+ real_t get_rpm() const;
- void set_engine_force(float p_engine_force);
- float get_engine_force() const;
+ void set_engine_force(real_t p_engine_force);
+ real_t get_engine_force() const;
- void set_brake(float p_brake);
- float get_brake() const;
+ void set_brake(real_t p_brake);
+ real_t get_brake() const;
- void set_steering(float p_steering);
- float get_steering() const;
+ void set_steering(real_t p_steering);
+ real_t get_steering() const;
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
VehicleWheel3D();
};
@@ -153,12 +153,12 @@ public:
class VehicleBody3D : public RigidBody3D {
GDCLASS(VehicleBody3D, RigidBody3D);
- float engine_force;
- float brake;
+ real_t engine_force = 0.0;
+ real_t brake = 0.0;
- real_t m_pitchControl;
- real_t m_steeringValue;
- real_t m_currentVehicleSpeedKmHour;
+ real_t m_pitchControl = 0.0;
+ real_t m_steeringValue = 0.0;
+ real_t m_currentVehicleSpeedKmHour = 0.0;
Set<RID> exclude;
@@ -168,12 +168,12 @@ class VehicleBody3D : public RigidBody3D {
Vector<real_t> m_sideImpulse;
struct btVehicleWheelContactPoint {
- PhysicsDirectBodyState3D *m_s;
- PhysicsBody3D *m_body1;
+ PhysicsDirectBodyState3D *m_s = nullptr;
+ PhysicsBody3D *m_body1 = nullptr;
Vector3 m_frictionPositionWorld;
Vector3 m_frictionDirectionWorld;
- real_t m_jacDiagABInv;
- real_t m_maxImpulse;
+ real_t m_jacDiagABInv = 0.0;
+ real_t m_maxImpulse = 0.0;
btVehicleWheelContactPoint(PhysicsDirectBodyState3D *s, PhysicsBody3D *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse);
};
@@ -192,17 +192,17 @@ class VehicleBody3D : public RigidBody3D {
static void _bind_methods();
- void _direct_state_changed(Object *p_state);
+ void _direct_state_changed(Object *p_state) override;
public:
- void set_engine_force(float p_engine_force);
- float get_engine_force() const;
+ void set_engine_force(real_t p_engine_force);
+ real_t get_engine_force() const;
- void set_brake(float p_brake);
- float get_brake() const;
+ void set_brake(real_t p_brake);
+ real_t get_brake() const;
- void set_steering(float p_steering);
- float get_steering() const;
+ void set_steering(real_t p_steering);
+ real_t get_steering() const;
VehicleBody3D();
};
diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp
index db10f3273b..5b5cc06456 100644
--- a/scene/3d/velocity_tracker_3d.cpp
+++ b/scene/3d/velocity_tracker_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "velocity_tracker_3d.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
void VelocityTracker3D::set_track_physics_step(bool p_track_physics_step) {
physics_step = p_track_physics_step;
@@ -45,7 +45,7 @@ void VelocityTracker3D::update_position(const Vector3 &p_position) {
if (physics_step) {
ph.frame = Engine::get_singleton()->get_physics_frames();
} else {
- ph.frame = Engine::get_singleton()->get_idle_frame_ticks();
+ ph.frame = Engine::get_singleton()->get_frame_ticks();
}
if (position_history_len == 0 || position_history[0].frame != ph.frame) { //in same frame, use latest
@@ -72,7 +72,7 @@ Vector3 VelocityTracker3D::get_tracked_linear_velocity() const {
uint64_t base = Engine::get_singleton()->get_physics_frames();
base_time = float(base - position_history[0].frame) / Engine::get_singleton()->get_iterations_per_second();
} else {
- uint64_t base = Engine::get_singleton()->get_idle_frame_ticks();
+ uint64_t base = Engine::get_singleton()->get_frame_ticks();
base_time = double(base - position_history[0].frame) / 1000000.0;
}
}
@@ -109,7 +109,7 @@ void VelocityTracker3D::reset(const Vector3 &p_new_pos) {
if (physics_step) {
ph.frame = Engine::get_singleton()->get_physics_frames();
} else {
- ph.frame = Engine::get_singleton()->get_idle_frame_ticks();
+ ph.frame = Engine::get_singleton()->get_frame_ticks();
}
position_history.write[0] = ph;
@@ -128,6 +128,4 @@ void VelocityTracker3D::_bind_methods() {
VelocityTracker3D::VelocityTracker3D() {
position_history.resize(4); // should be configurable
- position_history_len = 0;
- physics_step = false;
}
diff --git a/scene/3d/velocity_tracker_3d.h b/scene/3d/velocity_tracker_3d.h
index a7ab3dce4d..e971f4755a 100644
--- a/scene/3d/velocity_tracker_3d.h
+++ b/scene/3d/velocity_tracker_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -37,13 +37,13 @@ class VelocityTracker3D : public Reference {
GDCLASS(VelocityTracker3D, Reference);
struct PositionHistory {
- uint64_t frame;
+ uint64_t frame = 0;
Vector3 position;
};
- bool physics_step;
+ bool physics_step = false;
Vector<PositionHistory> position_history;
- int position_history_len;
+ int position_history_len = 0;
protected:
static void _bind_methods();
diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp
index a64b0df1cc..471838b9d1 100644
--- a/scene/3d/visibility_notifier_3d.cpp
+++ b/scene/3d/visibility_notifier_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -30,7 +30,7 @@
#include "visibility_notifier_3d.h"
-#include "core/engine.h"
+#include "core/config/engine.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/animation/animation_player.h"
@@ -69,7 +69,6 @@ void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) {
get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb));
}
- _change_notify("aabb");
update_gizmo();
}
@@ -80,13 +79,16 @@ AABB VisibilityNotifier3D::get_aabb() const {
void VisibilityNotifier3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
- get_world_3d()->_register_notifier(this, get_global_transform().xform(aabb));
+ world = get_world_3d();
+ ERR_FAIL_COND(!world.is_valid());
+ world->_register_notifier(this, get_global_transform().xform(aabb));
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
- get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb));
+ world->_update_notifier(this, get_global_transform().xform(aabb));
} break;
case NOTIFICATION_EXIT_WORLD: {
- get_world_3d()->_remove_notifier(this);
+ ERR_FAIL_COND(!world.is_valid());
+ world->_remove_notifier(this);
} break;
}
}
@@ -109,7 +111,6 @@ void VisibilityNotifier3D::_bind_methods() {
}
VisibilityNotifier3D::VisibilityNotifier3D() {
- aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
set_notify_transform(true);
}
@@ -249,6 +250,4 @@ VisibilityEnabler3D::VisibilityEnabler3D() {
for (int i = 0; i < ENABLER_MAX; i++) {
enabler[i] = true;
}
-
- visible = false;
}
diff --git a/scene/3d/visibility_notifier_3d.h b/scene/3d/visibility_notifier_3d.h
index 3864b398f4..9f7705067f 100644
--- a/scene/3d/visibility_notifier_3d.h
+++ b/scene/3d/visibility_notifier_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -33,13 +33,15 @@
#include "scene/3d/node_3d.h"
+class World3D;
class Camera3D;
class VisibilityNotifier3D : public Node3D {
GDCLASS(VisibilityNotifier3D, Node3D);
+ Ref<World3D> world;
Set<Camera3D *> cameras;
- AABB aabb;
+ AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
protected:
virtual void _screen_enter() {}
@@ -71,10 +73,10 @@ public:
};
protected:
- virtual void _screen_enter();
- virtual void _screen_exit();
+ virtual void _screen_enter() override;
+ virtual void _screen_exit() override;
- bool visible;
+ bool visible = false;
void _find_nodes(Node *p_node);
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index a1c498e8ab..394c67e873 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -43,7 +43,6 @@ void VisualInstance3D::_update_visibility() {
return;
}
- _change_notify("visible");
RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree());
}
@@ -135,7 +134,6 @@ RID VisualInstance3D::get_base() const {
VisualInstance3D::VisualInstance3D() {
instance = RenderingServer::get_singleton()->instance_create();
RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id());
- layers = 1;
set_notify_transform(true);
}
@@ -278,6 +276,16 @@ float GeometryInstance3D::get_extra_cull_margin() const {
return extra_cull_margin;
}
+void GeometryInstance3D::set_lod_bias(float p_bias) {
+ ERR_FAIL_COND(p_bias < 0.0);
+ lod_bias = p_bias;
+ RS::get_singleton()->instance_geometry_set_lod_bias(get_instance(), lod_bias);
+}
+
+float GeometryInstance3D::get_lod_bias() const {
+ return lod_bias;
+}
+
void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value) {
if (p_value.get_type() == Variant::NIL) {
Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_uniform);
@@ -361,6 +369,9 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_gi_mode", "mode"), &GeometryInstance3D::set_gi_mode);
ClassDB::bind_method(D_METHOD("get_gi_mode"), &GeometryInstance3D::get_gi_mode);
+ ClassDB::bind_method(D_METHOD("set_lod_bias", "bias"), &GeometryInstance3D::set_lod_bias);
+ ClassDB::bind_method(D_METHOD("get_lod_bias"), &GeometryInstance3D::get_lod_bias);
+
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &GeometryInstance3D::set_custom_aabb);
ClassDB::bind_method(D_METHOD("get_aabb"), &GeometryInstance3D::get_aabb);
@@ -369,6 +380,7 @@ void GeometryInstance3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override", "get_material_override");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01"), "set_extra_cull_margin", "get_extra_cull_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_bias", PROPERTY_HINT_RANGE, "0.001,128,0.001"), "set_lod_bias", "get_lod_bias");
ADD_GROUP("Global Illumination", "gi_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Baked,Dynamic"), "set_gi_mode", "get_gi_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, "1x,2x,4x,8x"), "set_lightmap_scale", "get_lightmap_scale");
@@ -398,15 +410,5 @@ void GeometryInstance3D::_bind_methods() {
}
GeometryInstance3D::GeometryInstance3D() {
- lod_min_distance = 0;
- lod_max_distance = 0;
- lod_min_hysteresis = 0;
- lod_max_hysteresis = 0;
-
- gi_mode = GI_MODE_DISABLED;
- lightmap_scale = LIGHTMAP_SCALE_1X;
-
- shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
- extra_cull_margin = 0;
//RS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0);
}
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index 195674f62d..7fed8095ef 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -32,7 +32,7 @@
#define VISUAL_INSTANCE_H
#include "core/math/face3.h"
-#include "core/rid.h"
+#include "core/templates/rid.h"
#include "scene/3d/node_3d.h"
#include "scene/resources/material.h"
@@ -42,7 +42,7 @@ class VisualInstance3D : public Node3D {
RID base;
RID instance;
- uint32_t layers;
+ uint32_t layers = 1;
RID _get_visual_instance_rid() const;
@@ -105,19 +105,21 @@ public:
};
private:
- ShadowCastingSetting shadow_casting_setting;
+ ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
Ref<Material> material_override;
- float lod_min_distance;
- float lod_max_distance;
- float lod_min_hysteresis;
- float lod_max_hysteresis;
+ float lod_min_distance = 0.0;
+ float lod_max_distance = 0.0;
+ float lod_min_hysteresis = 0.0;
+ float lod_max_hysteresis = 0.0;
+
+ float lod_bias = 1.0;
mutable HashMap<StringName, Variant> instance_uniforms;
mutable HashMap<StringName, StringName> instance_uniform_property_remap;
- float extra_cull_margin;
- LightmapScale lightmap_scale;
- GIMode gi_mode;
+ float extra_cull_margin = 0.0;
+ LightmapScale lightmap_scale = LIGHTMAP_SCALE_1X;
+ GIMode gi_mode = GI_MODE_DISABLED;
const StringName *_instance_uniform_get_remap(const StringName p_name) const;
@@ -151,6 +153,9 @@ public:
void set_extra_cull_margin(float p_margin);
float get_extra_cull_margin() const;
+ void set_lod_bias(float p_bias);
+ float get_lod_bias() const;
+
void set_gi_mode(GIMode p_mode);
GIMode get_gi_mode() const;
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
index 9fc3feb49a..17c8596e8f 100644
--- a/scene/3d/voxelizer.cpp
+++ b/scene/3d/voxelizer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "voxelizer.h"
-#include "core/math/geometry.h"
+#include "core/math/geometry_3d.h"
#include "core/os/os.h"
#include "core/os/threaded_array_processor.h"
@@ -124,7 +124,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector3 half = (to - from) * 0.5;
//is in this cell?
- if (!Geometry::triangle_box_overlap(from + half, half, p_vtx)) {
+ if (!Geometry3D::triangle_box_overlap(from + half, half, p_vtx)) {
continue; //face does not span this cell
}
@@ -267,7 +267,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
//test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test
- if (!Geometry::triangle_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) {
+ if (!Geometry3D::triangle_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) {
//if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
//does not fit in child, go on
continue;
@@ -294,7 +294,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector<Color> Voxelizer::_get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add) {
Vector<Color> ret;
- if (p_image.is_null() || p_image->empty()) {
+ if (p_image.is_null() || p_image->is_empty()) {
ret.resize(bake_texture_size * bake_texture_size);
for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
ret.write[i] = p_color_add;
@@ -439,7 +439,7 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
}
//test against original bounds
- if (!Geometry::triangle_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) {
+ if (!Geometry3D::triangle_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) {
continue;
}
//plot
@@ -471,7 +471,7 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
}
//test against original bounds
- if (!Geometry::triangle_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) {
+ if (!Geometry3D::triangle_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) {
continue;
}
//plot face
@@ -580,7 +580,6 @@ void Voxelizer::_fixup_plot(int p_idx, int p_level) {
/*if (bake_light.size()) {
for(int i=0;i<6;i++) {
-
}
}*/
@@ -1008,7 +1007,4 @@ Transform Voxelizer::get_to_cell_space_xform() const {
}
Voxelizer::Voxelizer() {
- sorted = false;
- color_scan_cell_width = 4;
- bake_texture_size = 128;
}
diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h
index 3546fd7729..87f949e7db 100644
--- a/scene/3d/voxelizer.h
+++ b/scene/3d/voxelizer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -44,35 +44,25 @@ private:
struct Cell {
uint32_t children[8];
- float albedo[3]; //albedo in RGB24
- float emission[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
- float normal[3];
- uint32_t used_sides;
- float alpha; //used for upsampling
- uint16_t x;
- uint16_t y;
- uint16_t z;
- uint16_t level;
+ float albedo[3] = {}; //albedo in RGB24
+ float emission[3] = {}; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
+ float normal[3] = {};
+ uint32_t used_sides = 0;
+ float alpha = 0.0; //used for upsampling
+ uint16_t x = 0;
+ uint16_t y = 0;
+ uint16_t z = 0;
+ uint16_t level = 0;
Cell() {
for (int i = 0; i < 8; i++) {
children[i] = CHILD_EMPTY;
}
-
- for (int i = 0; i < 3; i++) {
- emission[i] = 0;
- albedo[i] = 0;
- normal[i] = 0;
- }
- alpha = 0;
- used_sides = 0;
- x = y = z = 0;
- level = 0;
}
};
Vector<Cell> bake_cells;
- int cell_subdiv;
+ int cell_subdiv = 0;
struct CellSort {
union {
@@ -82,10 +72,10 @@ private:
uint64_t x : 16;
uint64_t level : 16;
};
- uint64_t key;
+ uint64_t key = 0;
};
- int32_t index;
+ int32_t index = 0;
_FORCE_INLINE_ bool operator<(const CellSort &p_cell_sort) const {
return key < p_cell_sort.key;
@@ -101,16 +91,16 @@ private:
Map<Ref<Material>, MaterialCache> material_cache;
AABB original_bounds;
AABB po2_bounds;
- int axis_cell_size[3];
+ int axis_cell_size[3] = {};
Transform to_cell_space;
- int color_scan_cell_width;
- int bake_texture_size;
- float cell_size;
+ int color_scan_cell_width = 4;
+ int bake_texture_size = 128;
+ float cell_size = 0.0;
- int max_original_cells;
- int leaf_voxel_count;
+ int max_original_cells = 0;
+ int leaf_voxel_count = 0;
Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add);
MaterialCache _get_material_cache(Ref<Material> p_material);
@@ -119,7 +109,7 @@ private:
void _fixup_plot(int p_idx, int p_level);
void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx);
- bool sorted;
+ bool sorted = false;
void _sort();
public:
diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp
index 24071f31f3..214ffd6bd5 100644
--- a/scene/3d/world_environment.cpp
+++ b/scene/3d/world_environment.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -29,56 +29,75 @@
/*************************************************************************/
#include "world_environment.h"
+
#include "scene/main/window.h"
void WorldEnvironment::_notification(int p_what) {
if (p_what == Node3D::NOTIFICATION_ENTER_WORLD || p_what == Node3D::NOTIFICATION_ENTER_TREE) {
if (environment.is_valid()) {
- if (get_viewport()->find_world_3d()->get_environment().is_valid()) {
- WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
- }
- get_viewport()->find_world_3d()->set_environment(environment);
add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
+ _update_current_environment();
}
if (camera_effects.is_valid()) {
- if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) {
- WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding.");
- }
- get_viewport()->find_world_3d()->set_camera_effects(camera_effects);
add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
+ _update_current_camera_effects();
}
} else if (p_what == Node3D::NOTIFICATION_EXIT_WORLD || p_what == Node3D::NOTIFICATION_EXIT_TREE) {
- if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) {
- get_viewport()->find_world_3d()->set_environment(Ref<Environment>());
+ if (environment.is_valid()) {
remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
+ _update_current_environment();
}
- if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) {
- get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>());
+ if (camera_effects.is_valid()) {
remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
+ _update_current_camera_effects();
}
}
}
-void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) {
- if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) {
+void WorldEnvironment::_update_current_environment() {
+ WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())));
+
+ if (first) {
+ get_viewport()->find_world_3d()->set_environment(first->environment);
+ } else {
get_viewport()->find_world_3d()->set_environment(Ref<Environment>());
+ }
+ get_tree()->call_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warning");
+}
+
+void WorldEnvironment::_update_current_camera_effects() {
+ WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())));
+ if (first) {
+ get_viewport()->find_world_3d()->set_camera_effects(first->camera_effects);
+ } else {
+ get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>());
+ }
+
+ get_tree()->call_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warning");
+}
+
+void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) {
+ if (environment == p_environment) {
+ return;
+ }
+ if (is_inside_tree() && environment.is_valid()) {
remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
- //clean up
}
environment = p_environment;
+
if (is_inside_tree() && environment.is_valid()) {
- if (get_viewport()->find_world_3d()->get_environment().is_valid()) {
- WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
- }
- get_viewport()->find_world_3d()->set_environment(environment);
add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
- update_configuration_warning();
+ if (is_inside_tree()) {
+ _update_current_environment();
+ } else {
+ update_configuration_warning();
+ }
}
Ref<Environment> WorldEnvironment::get_environment() const {
@@ -86,22 +105,24 @@ Ref<Environment> WorldEnvironment::get_environment() const {
}
void WorldEnvironment::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) {
+ if (camera_effects == p_camera_effects) {
+ return;
+ }
+
if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) {
- get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>());
remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
- //clean up
}
camera_effects = p_camera_effects;
if (is_inside_tree() && camera_effects.is_valid()) {
- if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) {
- WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding.");
- }
- get_viewport()->find_world_3d()->set_camera_effects(camera_effects);
add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
- update_configuration_warning();
+ if (is_inside_tree()) {
+ _update_current_camera_effects();
+ } else {
+ update_configuration_warning();
+ }
}
Ref<CameraEffects> WorldEnvironment::get_camera_effects() const {
@@ -109,22 +130,34 @@ Ref<CameraEffects> WorldEnvironment::get_camera_effects() const {
}
String WorldEnvironment::get_configuration_warning() const {
+ String warning = Node::get_configuration_warning();
+
if (!environment.is_valid()) {
- return TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect.");
}
if (!is_inside_tree()) {
- return String();
+ return warning;
}
- List<Node *> nodes;
- get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), &nodes);
+ if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() != environment) {
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("Only the first Environment has an effect in a scene (or set of instantiated scenes).");
+ }
- if (nodes.size() > 1) {
- return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes).");
+ if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() != camera_effects) {
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("Only the first CameraEffects has an effect in a scene (or set of instantiated scenes).");
}
- return String();
+ return warning;
}
void WorldEnvironment::_bind_methods() {
diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h
index ddb2af7bd3..e3f28d6d6b 100644
--- a/scene/3d/world_environment.h
+++ b/scene/3d/world_environment.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -32,6 +32,8 @@
#define SCENARIO_FX_H
#include "scene/3d/node_3d.h"
+#include "scene/resources/camera_effects.h"
+#include "scene/resources/environment.h"
class WorldEnvironment : public Node {
GDCLASS(WorldEnvironment, Node);
@@ -39,6 +41,9 @@ class WorldEnvironment : public Node {
Ref<Environment> environment;
Ref<CameraEffects> camera_effects;
+ void _update_current_environment();
+ void _update_current_camera_effects();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -50,7 +55,7 @@ public:
void set_camera_effects(const Ref<CameraEffects> &p_camera_effects);
Ref<CameraEffects> get_camera_effects() const;
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
WorldEnvironment();
};
diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp
index f4a514cdd6..7fed34c7c6 100644
--- a/scene/3d/xr_nodes.cpp
+++ b/scene/3d/xr_nodes.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -60,13 +60,18 @@ String XRCamera3D::get_configuration_warning() const {
return String();
}
+ String warning = Camera3D::get_configuration_warning();
+
// must be child node of XROrigin3D!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- return TTR("XRCamera3D must have an XROrigin3D node as its parent.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("XRCamera3D must have an XROrigin3D node as its parent.");
};
- return String();
+ return warning;
};
Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const {
@@ -86,9 +91,9 @@ Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const {
Vector2 cpos = get_viewport()->get_camera_coords(p_pos);
Vector3 ray;
- CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_near(), get_far());
Vector2 screen_he = cm.get_viewport_half_extents();
- ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_znear()).normalized();
+ ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_near()).normalized();
return ray;
};
@@ -108,7 +113,7 @@ Point2 XRCamera3D::unproject_position(const Vector3 &p_pos) const {
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_near(), get_far());
Plane p(get_camera_transform().xform_inv(p_pos), 1.0);
@@ -137,7 +142,7 @@ Vector3 XRCamera3D::project_position(const Point2 &p_point, float p_z_depth) con
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_near(), get_far());
Vector2 vp_he = cm.get_viewport_half_extents();
@@ -165,7 +170,7 @@ Vector<Plane> XRCamera3D::get_frustum() const {
ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>());
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_near(), get_far());
return cm.get_projection_planes(get_camera_transform());
};
@@ -206,7 +211,7 @@ void XRController3D::_notification(int p_what) {
emit_signal("button_pressed", i);
button_states += mask;
} else if (was_pressed && !is_pressed) {
- emit_signal("button_release", i);
+ emit_signal("button_released", i);
button_states -= mask;
};
@@ -242,7 +247,7 @@ void XRController3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &XRController3D::get_joystick_axis);
ClassDB::bind_method(D_METHOD("get_is_active"), &XRController3D::get_is_active);
- ClassDB::bind_method(D_METHOD("get_hand"), &XRController3D::get_hand);
+ ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRController3D::get_tracker_hand);
ClassDB::bind_method(D_METHOD("get_rumble"), &XRController3D::get_rumble);
ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRController3D::set_rumble);
@@ -252,7 +257,7 @@ void XRController3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mesh"), &XRController3D::get_mesh);
ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button")));
- ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button")));
+ ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::INT, "button")));
ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh")));
};
@@ -277,7 +282,7 @@ String XRController3D::get_controller_name() const {
return String("Not connected");
};
- return tracker->get_name();
+ return tracker->get_tracker_name();
};
int XRController3D::get_joystick_id() const {
@@ -344,7 +349,7 @@ bool XRController3D::get_is_active() const {
return is_active;
};
-XRPositionalTracker::TrackerHand XRController3D::get_hand() const {
+XRPositionalTracker::TrackerHand XRController3D::get_tracker_hand() const {
// get our XRServer
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN);
@@ -354,7 +359,7 @@ XRPositionalTracker::TrackerHand XRController3D::get_hand() const {
return XRPositionalTracker::TRACKER_HAND_UNKNOWN;
};
- return tracker->get_hand();
+ return tracker->get_tracker_hand();
};
String XRController3D::get_configuration_warning() const {
@@ -362,17 +367,25 @@ String XRController3D::get_configuration_warning() const {
return String();
}
+ String warning = Node3D::get_configuration_warning();
+
// must be child node of XROrigin!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- return TTR("XRController3D must have an XROrigin3D node as its parent.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("XRController3D must have an XROrigin3D node as its parent.");
};
if (controller_id == 0) {
- return TTR("The controller ID must not be 0 or this controller won't be bound to an actual controller.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("The controller ID must not be 0 or this controller won't be bound to an actual controller.");
};
- return String();
+ return warning;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -467,7 +480,7 @@ String XRAnchor3D::get_anchor_name() const {
return String("Not connected");
};
- return tracker->get_name();
+ return tracker->get_tracker_name();
};
bool XRAnchor3D::get_is_active() const {
@@ -479,17 +492,25 @@ String XRAnchor3D::get_configuration_warning() const {
return String();
}
+ String warning = Node3D::get_configuration_warning();
+
// must be child node of XROrigin3D!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- return TTR("XRAnchor3D must have an XROrigin3D node as its parent.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("XRAnchor3D must have an XROrigin3D node as its parent.");
};
if (anchor_id == 0) {
- return TTR("The anchor ID must not be 0 or this anchor won't be bound to an actual anchor.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("The anchor ID must not be 0 or this anchor won't be bound to an actual anchor.");
};
- return String();
+ return warning;
};
Plane XRAnchor3D::get_plane() const {
@@ -512,11 +533,16 @@ String XROrigin3D::get_configuration_warning() const {
return String();
}
+ String warning = Node3D::get_configuration_warning();
+
if (tracked_camera == nullptr) {
- return TTR("XROrigin3D requires an XRCamera3D child node.");
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("XROrigin3D requires an XRCamera3D child node.");
}
- return String();
+ return warning;
};
void XROrigin3D::_bind_methods() {
diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h
index 4d4f82aa38..7cd6e2ac57 100644
--- a/scene/3d/xr_nodes.h
+++ b/scene/3d/xr_nodes.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* 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 */
@@ -50,12 +50,12 @@ protected:
void _notification(int p_what);
public:
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
- virtual Vector3 project_local_ray_normal(const Point2 &p_pos) const;
- virtual Point2 unproject_position(const Vector3 &p_pos) const;
- virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const;
- virtual Vector<Plane> get_frustum() const;
+ virtual Vector3 project_local_ray_normal(const Point2 &p_pos) const override;
+ virtual Point2 unproject_position(const Vector3 &p_pos) const override;
+ virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const override;
+ virtual Vector<Plane> get_frustum() const override;
XRCamera3D() {}
~XRCamera3D() {}
@@ -93,11 +93,11 @@ public:
void set_rumble(real_t p_rumble);
bool get_is_active() const;
- XRPositionalTracker::TrackerHand get_hand() const;
+ XRPositionalTracker::TrackerHand get_tracker_hand() const;
Ref<Mesh> get_mesh() const;
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
XRController3D() {}
~XRController3D() {}
@@ -133,7 +133,7 @@ public:
Ref<Mesh> get_mesh() const;
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
XRAnchor3D() {}
~XRAnchor3D() {}
@@ -158,7 +158,7 @@ protected:
static void _bind_methods();
public:
- String get_configuration_warning() const;
+ String get_configuration_warning() const override;
void set_tracked_camera(XRCamera3D *p_tracked_camera);
void clear_tracked_camera_if(XRCamera3D *p_tracked_camera);