summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/animation.cpp126
-rw-r--r--scene/resources/animation.h16
-rw-r--r--scene/resources/font.cpp3
-rw-r--r--scene/resources/packed_scene.cpp12
-rw-r--r--scene/resources/resource_format_text.cpp2
-rw-r--r--scene/resources/skeleton_modification_2d_ccdik.cpp4
-rw-r--r--scene/resources/skeleton_modification_stack_2d.cpp1
-rw-r--r--scene/resources/skeleton_modification_stack_3d.cpp1
-rw-r--r--scene/resources/sky_material.cpp16
-rw-r--r--scene/resources/visual_shader.cpp1
-rw-r--r--scene/resources/visual_shader_particle_nodes.cpp289
-rw-r--r--scene/resources/visual_shader_particle_nodes.h14
12 files changed, 363 insertions, 122 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 3700e87839..d31771e71a 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -317,7 +317,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
Vector<real_t> times = d["times"];
Vector<real_t> values = d["points"];
- ERR_FAIL_COND_V(times.size() * 5 != values.size(), false);
+ ERR_FAIL_COND_V(times.size() * 6 != values.size(), false);
if (times.size()) {
int valcount = times.size();
@@ -330,11 +330,12 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
for (int i = 0; i < valcount; i++) {
bt->values.write[i].time = rt[i];
bt->values.write[i].transition = 0; //unused in bezier
- bt->values.write[i].value.value = rv[i * 5 + 0];
- bt->values.write[i].value.in_handle.x = rv[i * 5 + 1];
- bt->values.write[i].value.in_handle.y = rv[i * 5 + 2];
- bt->values.write[i].value.out_handle.x = rv[i * 5 + 3];
- bt->values.write[i].value.out_handle.y = rv[i * 5 + 4];
+ bt->values.write[i].value.value = rv[i * 6 + 0];
+ bt->values.write[i].value.in_handle.x = rv[i * 6 + 1];
+ bt->values.write[i].value.in_handle.y = rv[i * 6 + 2];
+ bt->values.write[i].value.out_handle.x = rv[i * 6 + 3];
+ bt->values.write[i].value.out_handle.y = rv[i * 6 + 4];
+ bt->values.write[i].value.handle_mode = static_cast<HandleMode>((int)rv[i * 6 + 5]);
}
}
@@ -698,7 +699,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
int kk = bt->values.size();
key_times.resize(kk);
- key_points.resize(kk * 5);
+ key_points.resize(kk * 6);
real_t *wti = key_times.ptrw();
real_t *wpo = key_points.ptrw();
@@ -709,11 +710,12 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
for (int i = 0; i < kk; i++) {
wti[idx] = vls[i].time;
- wpo[idx * 5 + 0] = vls[i].value.value;
- wpo[idx * 5 + 1] = vls[i].value.in_handle.x;
- wpo[idx * 5 + 2] = vls[i].value.in_handle.y;
- wpo[idx * 5 + 3] = vls[i].value.out_handle.x;
- wpo[idx * 5 + 4] = vls[i].value.out_handle.y;
+ wpo[idx * 6 + 0] = vls[i].value.value;
+ wpo[idx * 6 + 1] = vls[i].value.in_handle.x;
+ wpo[idx * 6 + 2] = vls[i].value.in_handle.y;
+ wpo[idx * 6 + 3] = vls[i].value.out_handle.x;
+ wpo[idx * 6 + 4] = vls[i].value.out_handle.y;
+ wpo[idx * 6 + 5] = (double)vls[i].value.handle_mode;
idx++;
}
@@ -1623,7 +1625,7 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke
BezierTrack *bt = static_cast<BezierTrack *>(t);
Array arr = p_key;
- ERR_FAIL_COND(arr.size() != 5);
+ ERR_FAIL_COND(arr.size() != 6);
TKey<BezierKey> k;
k.time = p_time;
@@ -1632,6 +1634,7 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke
k.value.in_handle.y = arr[2];
k.value.out_handle.x = arr[3];
k.value.out_handle.y = arr[4];
+ k.value.handle_mode = static_cast<HandleMode>((int)arr[5]);
_insert(p_time, bt->values, k);
} break;
@@ -1770,12 +1773,13 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), Variant());
Array arr;
- arr.resize(5);
+ arr.resize(6);
arr[0] = bt->values[p_key_idx].value.value;
arr[1] = bt->values[p_key_idx].value.in_handle.x;
arr[2] = bt->values[p_key_idx].value.in_handle.y;
arr[3] = bt->values[p_key_idx].value.out_handle.x;
arr[4] = bt->values[p_key_idx].value.out_handle.y;
+ arr[5] = (double)bt->values[p_key_idx].value.handle_mode;
return arr;
} break;
@@ -2144,13 +2148,14 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
ERR_FAIL_INDEX(p_key_idx, bt->values.size());
Array arr = p_value;
- ERR_FAIL_COND(arr.size() != 5);
+ ERR_FAIL_COND(arr.size() != 6);
bt->values.write[p_key_idx].value.value = arr[0];
bt->values.write[p_key_idx].value.in_handle.x = arr[1];
bt->values.write[p_key_idx].value.in_handle.y = arr[2];
bt->values.write[p_key_idx].value.out_handle.x = arr[3];
bt->values.write[p_key_idx].value.out_handle.y = arr[4];
+ bt->values.write[p_key_idx].value.handle_mode = static_cast<HandleMode>((int)arr[5]);
} break;
case TYPE_AUDIO: {
@@ -3203,7 +3208,7 @@ StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
return pm->methods[p_key_idx].method;
}
-int Animation::bezier_track_insert_key(int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle) {
+int Animation::bezier_track_insert_key(int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle, const HandleMode p_handle_mode) {
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, -1);
@@ -3221,6 +3226,7 @@ int Animation::bezier_track_insert_key(int p_track, double p_time, real_t p_valu
if (k.value.out_handle.x < 0) {
k.value.out_handle.x = 0;
}
+ k.value.handle_mode = p_handle_mode;
int key = _insert(p_time, bt->values, k);
@@ -3229,6 +3235,30 @@ int Animation::bezier_track_insert_key(int p_track, double p_time, real_t p_valu
return key;
}
+void Animation::bezier_track_set_key_handle_mode(int p_track, int p_index, HandleMode p_mode, double p_balanced_value_time_ratio) {
+ ERR_FAIL_INDEX(p_track, tracks.size());
+ Track *t = tracks[p_track];
+ ERR_FAIL_COND(t->type != TYPE_BEZIER);
+
+ BezierTrack *bt = static_cast<BezierTrack *>(t);
+
+ ERR_FAIL_INDEX(p_index, bt->values.size());
+
+ bt->values.write[p_index].value.handle_mode = p_mode;
+
+ if (p_mode == HANDLE_MODE_BALANCED) {
+ Transform2D xform;
+ xform.set_scale(Vector2(1.0, 1.0 / p_balanced_value_time_ratio));
+
+ Vector2 vec_in = xform.xform(bt->values[p_index].value.in_handle);
+ Vector2 vec_out = xform.xform(bt->values[p_index].value.out_handle);
+
+ bt->values.write[p_index].value.in_handle = xform.affine_inverse().xform(-vec_out.normalized() * vec_in.length());
+ }
+
+ emit_changed();
+}
+
void Animation::bezier_track_set_key_value(int p_track, int p_index, real_t p_value) {
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
@@ -3242,7 +3272,7 @@ void Animation::bezier_track_set_key_value(int p_track, int p_index, real_t p_va
emit_changed();
}
-void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle) {
+void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio) {
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_BEZIER);
@@ -3251,14 +3281,26 @@ void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const V
ERR_FAIL_INDEX(p_index, bt->values.size());
- bt->values.write[p_index].value.in_handle = p_handle;
- if (bt->values[p_index].value.in_handle.x > 0) {
- bt->values.write[p_index].value.in_handle.x = 0;
+ Vector2 in_handle = p_handle;
+ if (in_handle.x > 0) {
+ in_handle.x = 0;
+ }
+ bt->values.write[p_index].value.in_handle = in_handle;
+
+ if (bt->values[p_index].value.handle_mode == HANDLE_MODE_BALANCED) {
+ Transform2D xform;
+ xform.set_scale(Vector2(1.0, 1.0 / p_balanced_value_time_ratio));
+
+ Vector2 vec_out = xform.xform(bt->values[p_index].value.out_handle);
+ Vector2 vec_in = xform.xform(in_handle);
+
+ bt->values.write[p_index].value.out_handle = xform.affine_inverse().xform(-vec_in.normalized() * vec_out.length());
}
+
emit_changed();
}
-void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle) {
+void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio) {
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_BEZIER);
@@ -3267,10 +3309,22 @@ void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const
ERR_FAIL_INDEX(p_index, bt->values.size());
- bt->values.write[p_index].value.out_handle = p_handle;
- if (bt->values[p_index].value.out_handle.x < 0) {
- bt->values.write[p_index].value.out_handle.x = 0;
+ Vector2 out_handle = p_handle;
+ if (out_handle.x < 0) {
+ out_handle.x = 0;
+ }
+ bt->values.write[p_index].value.out_handle = out_handle;
+
+ if (bt->values[p_index].value.handle_mode == HANDLE_MODE_BALANCED) {
+ Transform2D xform;
+ xform.set_scale(Vector2(1.0, 1.0 / p_balanced_value_time_ratio));
+
+ Vector2 vec_in = xform.xform(bt->values[p_index].value.in_handle);
+ Vector2 vec_out = xform.xform(out_handle);
+
+ bt->values.write[p_index].value.in_handle = xform.affine_inverse().xform(-vec_out.normalized() * vec_in.length());
}
+
emit_changed();
}
@@ -3286,6 +3340,18 @@ real_t Animation::bezier_track_get_key_value(int p_track, int p_index) const {
return bt->values[p_index].value.value;
}
+int Animation::bezier_track_get_key_handle_mode(int p_track, int p_index) const {
+ ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
+ Track *t = tracks[p_track];
+ ERR_FAIL_COND_V(t->type != TYPE_BEZIER, 0);
+
+ BezierTrack *bt = static_cast<BezierTrack *>(t);
+
+ ERR_FAIL_INDEX_V(p_index, bt->values.size(), 0);
+
+ return bt->values[p_index].value.handle_mode;
+}
+
Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
Track *t = tracks[p_track];
@@ -3718,11 +3784,11 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("method_track_get_name", "track_idx", "key_idx"), &Animation::method_track_get_name);
ClassDB::bind_method(D_METHOD("method_track_get_params", "track_idx", "key_idx"), &Animation::method_track_get_params);
- ClassDB::bind_method(D_METHOD("bezier_track_insert_key", "track_idx", "time", "value", "in_handle", "out_handle"), &Animation::bezier_track_insert_key, DEFVAL(Vector2()), DEFVAL(Vector2()));
+ ClassDB::bind_method(D_METHOD("bezier_track_insert_key", "track_idx", "time", "value", "in_handle", "out_handle", "handle_mode"), &Animation::bezier_track_insert_key, DEFVAL(Vector2()), DEFVAL(Vector2()), DEFVAL(Animation::HandleMode::HANDLE_MODE_BALANCED));
ClassDB::bind_method(D_METHOD("bezier_track_set_key_value", "track_idx", "key_idx", "value"), &Animation::bezier_track_set_key_value);
- ClassDB::bind_method(D_METHOD("bezier_track_set_key_in_handle", "track_idx", "key_idx", "in_handle"), &Animation::bezier_track_set_key_in_handle);
- ClassDB::bind_method(D_METHOD("bezier_track_set_key_out_handle", "track_idx", "key_idx", "out_handle"), &Animation::bezier_track_set_key_out_handle);
+ ClassDB::bind_method(D_METHOD("bezier_track_set_key_in_handle", "track_idx", "key_idx", "in_handle", "balanced_value_time_ratio"), &Animation::bezier_track_set_key_in_handle, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("bezier_track_set_key_out_handle", "track_idx", "key_idx", "out_handle", "balanced_value_time_ratio"), &Animation::bezier_track_set_key_out_handle, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("bezier_track_get_key_value", "track_idx", "key_idx"), &Animation::bezier_track_get_key_value);
ClassDB::bind_method(D_METHOD("bezier_track_get_key_in_handle", "track_idx", "key_idx"), &Animation::bezier_track_get_key_in_handle);
@@ -3738,6 +3804,9 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("audio_track_get_key_start_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_start_offset);
ClassDB::bind_method(D_METHOD("audio_track_get_key_end_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_end_offset);
+ ClassDB::bind_method(D_METHOD("bezier_track_set_key_handle_mode", "track_idx", "key_idx", "key_handle_mode", "balanced_value_time_ratio"), &Animation::bezier_track_set_key_handle_mode, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("bezier_track_get_key_handle_mode", "track_idx", "key_idx"), &Animation::bezier_track_get_key_handle_mode);
+
ClassDB::bind_method(D_METHOD("animation_track_insert_key", "track_idx", "time", "animation"), &Animation::animation_track_insert_key);
ClassDB::bind_method(D_METHOD("animation_track_set_key_animation", "track_idx", "key_idx", "animation"), &Animation::animation_track_set_key_animation);
ClassDB::bind_method(D_METHOD("animation_track_get_key_animation", "track_idx", "key_idx"), &Animation::animation_track_get_key_animation);
@@ -3784,6 +3853,9 @@ void Animation::_bind_methods() {
BIND_ENUM_CONSTANT(LOOP_NONE);
BIND_ENUM_CONSTANT(LOOP_LINEAR);
BIND_ENUM_CONSTANT(LOOP_PINGPONG);
+
+ BIND_ENUM_CONSTANT(HANDLE_MODE_FREE);
+ BIND_ENUM_CONSTANT(HANDLE_MODE_BALANCED);
}
void Animation::clear() {
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 510d6c8323..8e4287e4fb 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -72,6 +72,11 @@ public:
LOOP_PINGPONG,
};
+ enum HandleMode {
+ HANDLE_MODE_FREE,
+ HANDLE_MODE_BALANCED,
+ };
+
private:
struct Track {
TrackType type = TrackType::TYPE_ANIMATION;
@@ -157,10 +162,10 @@ private:
};
/* BEZIER TRACK */
-
struct BezierKey {
Vector2 in_handle; //relative (x always <0)
Vector2 out_handle; //relative (x always >0)
+ HandleMode handle_mode = HANDLE_MODE_BALANCED;
real_t value = 0.0;
};
@@ -419,11 +424,13 @@ public:
void track_set_interpolation_type(int p_track, InterpolationType p_interp);
InterpolationType track_get_interpolation_type(int p_track) const;
- int bezier_track_insert_key(int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle);
+ int bezier_track_insert_key(int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle, const HandleMode p_handle_mode = HandleMode::HANDLE_MODE_BALANCED);
+ void bezier_track_set_key_handle_mode(int p_track, int p_index, HandleMode p_mode, double p_balanced_value_time_ratio = 1.0);
void bezier_track_set_key_value(int p_track, int p_index, real_t p_value);
- void bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle);
- void bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle);
+ void bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio = 1.0);
+ void bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio = 1.0);
real_t bezier_track_get_key_value(int p_track, int p_index) const;
+ int bezier_track_get_key_handle_mode(int p_track, int p_index) const;
Vector2 bezier_track_get_key_in_handle(int p_track, int p_index) const;
Vector2 bezier_track_get_key_out_handle(int p_track, int p_index) const;
@@ -478,6 +485,7 @@ public:
VARIANT_ENUM_CAST(Animation::TrackType);
VARIANT_ENUM_CAST(Animation::InterpolationType);
VARIANT_ENUM_CAST(Animation::UpdateMode);
+VARIANT_ENUM_CAST(Animation::HandleMode);
VARIANT_ENUM_CAST(Animation::LoopMode);
#endif
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index d9de47afc7..6cd42e1456 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -88,6 +88,9 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_msdf_size", "msdf_size"), &FontData::set_msdf_size);
ClassDB::bind_method(D_METHOD("get_msdf_size"), &FontData::get_msdf_size);
+ ClassDB::bind_method(D_METHOD("set_fixed_size", "fixed_size"), &FontData::set_fixed_size);
+ ClassDB::bind_method(D_METHOD("get_fixed_size"), &FontData::get_fixed_size);
+
ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &FontData::set_force_autohinter);
ClassDB::bind_method(D_METHOD("is_force_autohinter"), &FontData::is_force_autohinter);
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index f43715a463..3f4765d20f 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -315,13 +315,13 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
node->_set_owner_nocheck(owner);
}
}
- }
- // we only want to deal with pinned flag if instancing as pure main (no instance, no inheriting)
- if (p_edit_state == GEN_EDIT_STATE_MAIN) {
- _sanitize_node_pinned_properties(node);
- } else {
- node->remove_meta("_edit_pinned_properties_");
+ // we only want to deal with pinned flag if instancing as pure main (no instance, no inheriting)
+ if (p_edit_state == GEN_EDIT_STATE_MAIN) {
+ _sanitize_node_pinned_properties(node);
+ } else {
+ node->remove_meta("_edit_pinned_properties_");
+ }
}
ret_nodes[i] = node;
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index ea3b72af1b..cead42b4e2 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -350,7 +350,7 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
} else if (next_tag.name == "editable") {
if (!next_tag.fields.has("path")) {
error = ERR_FILE_CORRUPT;
- error_text = "missing 'path' field from connection tag";
+ error_text = "missing 'path' field from editable tag";
_printerr();
return Ref<PackedScene>();
}
diff --git a/scene/resources/skeleton_modification_2d_ccdik.cpp b/scene/resources/skeleton_modification_2d_ccdik.cpp
index 6eab8d4afe..bea42109cb 100644
--- a/scene/resources/skeleton_modification_2d_ccdik.cpp
+++ b/scene/resources/skeleton_modification_2d_ccdik.cpp
@@ -205,8 +205,8 @@ void SkeletonModification2DCCDIK::_execute_ccdik_joint(int p_joint_idx, Node2D *
} else {
// How to rotate from the tip: get the difference of rotation needed from the tip to the target, from the perspective of the joint.
// Because we are only using the offset, we do not need to account for the bone angle of the Bone2D node.
- float joint_to_tip = operation_transform.get_origin().angle_to_point(p_tip->get_global_position());
- float joint_to_target = operation_transform.get_origin().angle_to_point(p_target->get_global_position());
+ float joint_to_tip = p_tip->get_global_position().angle_to_point(operation_transform.get_origin());
+ float joint_to_target = p_target->get_global_position().angle_to_point(operation_transform.get_origin());
operation_transform.set_rotation(
operation_transform.get_rotation() + (joint_to_target - joint_to_tip));
}
diff --git a/scene/resources/skeleton_modification_stack_2d.cpp b/scene/resources/skeleton_modification_stack_2d.cpp
index db9fe62b4d..25c3e9d2ef 100644
--- a/scene/resources/skeleton_modification_stack_2d.cpp
+++ b/scene/resources/skeleton_modification_stack_2d.cpp
@@ -195,6 +195,7 @@ void SkeletonModificationStack2D::set_modification(int p_mod_idx, Ref<SkeletonMo
}
void SkeletonModificationStack2D::set_modification_count(int p_count) {
+ ERR_FAIL_COND_MSG(p_count < 0, "Modification count cannot be less than zero.");
modifications.resize(p_count);
notify_property_list_changed();
diff --git a/scene/resources/skeleton_modification_stack_3d.cpp b/scene/resources/skeleton_modification_stack_3d.cpp
index c03210cf48..301811f0b6 100644
--- a/scene/resources/skeleton_modification_stack_3d.cpp
+++ b/scene/resources/skeleton_modification_stack_3d.cpp
@@ -149,6 +149,7 @@ void SkeletonModificationStack3D::set_modification(int p_mod_idx, Ref<SkeletonMo
}
void SkeletonModificationStack3D::set_modification_count(int p_count) {
+ ERR_FAIL_COND_MSG(p_count < 0, "Modification count cannot be less than zero.");
modifications.resize(p_count);
notify_property_list_changed();
}
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index de94c92cac..ff388e288c 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -37,7 +37,7 @@ RID ProceduralSkyMaterial::shader;
void ProceduralSkyMaterial::set_sky_top_color(const Color &p_sky_top) {
sky_top_color = p_sky_top;
- RS::get_singleton()->material_set_param(_get_material(), "sky_top_color", sky_top_color.to_linear());
+ RS::get_singleton()->material_set_param(_get_material(), "sky_top_color", sky_top_color);
}
Color ProceduralSkyMaterial::get_sky_top_color() const {
@@ -46,7 +46,7 @@ Color ProceduralSkyMaterial::get_sky_top_color() const {
void ProceduralSkyMaterial::set_sky_horizon_color(const Color &p_sky_horizon) {
sky_horizon_color = p_sky_horizon;
- RS::get_singleton()->material_set_param(_get_material(), "sky_horizon_color", sky_horizon_color.to_linear());
+ RS::get_singleton()->material_set_param(_get_material(), "sky_horizon_color", sky_horizon_color);
}
Color ProceduralSkyMaterial::get_sky_horizon_color() const {
@@ -73,7 +73,7 @@ float ProceduralSkyMaterial::get_sky_energy() const {
void ProceduralSkyMaterial::set_ground_bottom_color(const Color &p_ground_bottom) {
ground_bottom_color = p_ground_bottom;
- RS::get_singleton()->material_set_param(_get_material(), "ground_bottom_color", ground_bottom_color.to_linear());
+ RS::get_singleton()->material_set_param(_get_material(), "ground_bottom_color", ground_bottom_color);
}
Color ProceduralSkyMaterial::get_ground_bottom_color() const {
@@ -82,7 +82,7 @@ Color ProceduralSkyMaterial::get_ground_bottom_color() const {
void ProceduralSkyMaterial::set_ground_horizon_color(const Color &p_ground_horizon) {
ground_horizon_color = p_ground_horizon;
- RS::get_singleton()->material_set_param(_get_material(), "ground_horizon_color", ground_horizon_color.to_linear());
+ RS::get_singleton()->material_set_param(_get_material(), "ground_horizon_color", ground_horizon_color);
}
Color ProceduralSkyMaterial::get_ground_horizon_color() const {
@@ -564,10 +564,10 @@ void PhysicalSkyMaterial::_update_shader() {
shader_type sky;
uniform float rayleigh : hint_range(0, 64) = 2.0;
-uniform vec4 rayleigh_color : hint_color = vec4(0.056, 0.14, 0.3, 1.0);
+uniform vec4 rayleigh_color : hint_color = vec4(0.26, 0.41, 0.58, 1.0);
uniform float mie : hint_range(0, 1) = 0.005;
uniform float mie_eccentricity : hint_range(-1, 1) = 0.8;
-uniform vec4 mie_color : hint_color = vec4(0.36, 0.56, 0.82, 1.0);
+uniform vec4 mie_color : hint_color = vec4(0.63, 0.77, 0.92, 1.0);
uniform float turbidity : hint_range(0, 1000) = 10.0;
uniform float sun_disk_scale : hint_range(0, 360) = 1.0;
@@ -661,10 +661,10 @@ void sky() {
PhysicalSkyMaterial::PhysicalSkyMaterial() {
set_rayleigh_coefficient(2.0);
- set_rayleigh_color(Color(0.056, 0.14, 0.3));
+ set_rayleigh_color(Color(0.26, 0.41, 0.58));
set_mie_coefficient(0.005);
set_mie_eccentricity(0.8);
- set_mie_color(Color(0.36, 0.56, 0.82));
+ set_mie_color(Color(0.63, 0.77, 0.92));
set_turbidity(10.0);
set_sun_disk_scale(1.0);
set_ground_color(Color(1.0, 1.0, 1.0));
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 0bdc81330e..87ff225de9 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -1835,6 +1835,7 @@ void VisualShader::_update_shader() const {
code += " float __scalar_buff1;\n";
code += " float __scalar_buff2;\n";
code += " int __scalar_ibuff;\n";
+ code += " vec4 __vec4_buff;\n";
code += " vec3 __ndiff = normalize(__diff);\n\n";
}
if (has_start) {
diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp
index 7dd4eed15b..1a829968e3 100644
--- a/scene/resources/visual_shader_particle_nodes.cpp
+++ b/scene/resources/visual_shader_particle_nodes.cpp
@@ -264,7 +264,7 @@ String VisualShaderNodeParticleMeshEmitter::get_caption() const {
}
int VisualShaderNodeParticleMeshEmitter::get_output_port_count() const {
- return 2;
+ return 6;
}
VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleMeshEmitter::get_output_port_type(int p_port) const {
@@ -273,6 +273,14 @@ VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleMeshEmitter
return PORT_TYPE_VECTOR; // position
case 1:
return PORT_TYPE_VECTOR; // normal
+ case 2:
+ return PORT_TYPE_VECTOR; // color
+ case 3:
+ return PORT_TYPE_SCALAR; // alpha
+ case 4:
+ return PORT_TYPE_VECTOR; // uv
+ case 5:
+ return PORT_TYPE_VECTOR; // uv2
}
return PORT_TYPE_SCALAR;
}
@@ -283,6 +291,14 @@ String VisualShaderNodeParticleMeshEmitter::get_output_port_name(int p_port) con
return "position";
case 1:
return "normal";
+ case 2:
+ return "color";
+ case 3:
+ return "alpha";
+ case 4:
+ return "uv";
+ case 5:
+ return "uv2";
}
return String();
}
@@ -299,135 +315,263 @@ String VisualShaderNodeParticleMeshEmitter::get_input_port_name(int p_port) cons
return String();
}
-String VisualShaderNodeParticleMeshEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code;
if (mesh.is_valid()) {
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n";
+ if (is_output_port_connected(0)) { // position
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
+ }
+
+ if (is_output_port_connected(1)) { // normal
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n";
+ }
+
+ if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n";
+ }
+
+ if (is_output_port_connected(4)) { // uv
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n";
+ }
+
+ if (is_output_port_connected(5)) { // uv2
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n";
+ }
}
return code;
}
-String VisualShaderNodeParticleMeshEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeParticleMeshEmitter::_generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, bool p_ignore_mode2d) const {
String code;
-
- code += " __scalar_ibuff = int(__rand_from_seed(__seed) * 65535.0) % " + itos(position_texture->get_width()) + ";\n";
-
- if (position_texture->get_width() == 0) {
- code += " " + p_output_vars[0] + " = vec3(0.0);\n";
- } else {
- if (mode_2d) {
- code += " " + p_output_vars[0] + " = vec3(";
+ if (is_output_port_connected(p_index)) {
+ if (mode_2d && !p_ignore_mode2d) {
+ code += " " + p_output_vars[p_index] + " = vec3(";
code += "texelFetch(";
- code += make_unique_id(p_type, p_id, "mesh_vx") + ", ";
+ code += make_unique_id(p_type, p_id, p_texture_name) + ", ";
code += "ivec2(__scalar_ibuff, 0), 0).xy, 0.0);\n";
} else {
- code += " " + p_output_vars[0] + " = texelFetch(";
- code += make_unique_id(p_type, p_id, "mesh_vx") + ", ";
+ code += " " + p_output_vars[p_index] + " = texelFetch(";
+ code += make_unique_id(p_type, p_id, p_texture_name) + ", ";
code += "ivec2(__scalar_ibuff, 0), 0).xyz;\n";
}
}
+ return code;
+}
- if (normal_texture->get_width() == 0) {
- code += " " + p_output_vars[1] + " = vec3(0.0);\n";
- } else {
- if (mode_2d) {
- code += " " + p_output_vars[1] + " = vec3(";
- code += "texelFetch(";
- code += make_unique_id(p_type, p_id, "mesh_nm") + ", ";
- code += "ivec2(__scalar_ibuff, 0), 0).xy, 0.0);\n";
+String VisualShaderNodeParticleMeshEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ String code;
+ code += " __scalar_ibuff = int(__rand_from_seed(__seed) * 65535.0) % " + itos(position_texture->get_width()) + ";\n";
+
+ code += _generate_code(p_type, p_id, p_output_vars, 0, "mesh_vx");
+ code += _generate_code(p_type, p_id, p_output_vars, 1, "mesh_nm");
+
+ if (is_output_port_connected(2) || is_output_port_connected(3)) {
+ code += " __vec4_buff = texelFetch(";
+ code += make_unique_id(p_type, p_id, "mesh_col") + ", ";
+ code += "ivec2(__scalar_ibuff, 0), 0);\n";
+ if (is_output_port_connected(2)) {
+ code += " " + p_output_vars[2] + " = __vec4_buff.rgb;\n";
} else {
- code += " " + p_output_vars[1] + " = texelFetch(";
- code += make_unique_id(p_type, p_id, "mesh_nm") + ", ";
- code += "ivec2(__scalar_ibuff, 0), 0).xyz;\n";
+ code += " " + p_output_vars[2] + " = vec3(0.0);\n";
+ }
+ if (is_output_port_connected(3)) {
+ code += " " + p_output_vars[3] + " = __vec4_buff.a;\n";
+ } else {
+ code += " " + p_output_vars[3] + " = 0.0;\n";
}
}
+ code += _generate_code(p_type, p_id, p_output_vars, 4, "mesh_uv", true);
+ code += _generate_code(p_type, p_id, p_output_vars, 5, "mesh_uv2", true);
+
return code;
}
Vector<VisualShader::DefaultTextureParam> VisualShaderNodeParticleMeshEmitter::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
- VisualShader::DefaultTextureParam dtp_vx;
- dtp_vx.name = make_unique_id(p_type, p_id, "mesh_vx");
- dtp_vx.params.push_back(position_texture);
+ Vector<VisualShader::DefaultTextureParam> ret;
- VisualShader::DefaultTextureParam dtp_nm;
- dtp_nm.name = make_unique_id(p_type, p_id, "mesh_nm");
- dtp_nm.params.push_back(normal_texture);
+ if (is_output_port_connected(0)) {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "mesh_vx");
+ dtp.params.push_back(position_texture);
+ ret.push_back(dtp);
+ }
+
+ if (is_output_port_connected(1)) {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "mesh_nm");
+ dtp.params.push_back(normal_texture);
+ ret.push_back(dtp);
+ }
+
+ if (is_output_port_connected(2) || is_output_port_connected(3)) {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "mesh_col");
+ dtp.params.push_back(color_texture);
+ ret.push_back(dtp);
+ }
+
+ if (is_output_port_connected(4)) {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "mesh_uv");
+ dtp.params.push_back(uv_texture);
+ ret.push_back(dtp);
+ }
+
+ if (is_output_port_connected(5)) {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "mesh_uv2");
+ dtp.params.push_back(uv2_texture);
+ ret.push_back(dtp);
+ }
- Vector<VisualShader::DefaultTextureParam> ret;
- ret.push_back(dtp_vx);
- ret.push_back(dtp_nm);
return ret;
}
-void VisualShaderNodeParticleMeshEmitter::update_texture() {
+void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Vector2> &p_array, Ref<ImageTexture> &r_texture) {
+ Ref<Image> image;
+ image.instantiate();
+
+ if (p_array.size() == 0) {
+ image->create(1, 1, false, Image::Format::FORMAT_RGBF);
+ } else {
+ image->create(p_array.size(), 1, false, Image::Format::FORMAT_RGBF);
+ }
+
+ for (int i = 0; i < p_array.size(); i++) {
+ Vector2 v = p_array[i];
+ image->set_pixel(i, 0, Color(v.x, v.y, 0));
+ }
+ if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
+ r_texture->create_from_image(image);
+ } else {
+ r_texture->update(image);
+ }
+}
+
+void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Vector3> &p_array, Ref<ImageTexture> &r_texture) {
+ Ref<Image> image;
+ image.instantiate();
+
+ if (p_array.size() == 0) {
+ image->create(1, 1, false, Image::Format::FORMAT_RGBF);
+ } else {
+ image->create(p_array.size(), 1, false, Image::Format::FORMAT_RGBF);
+ }
+
+ for (int i = 0; i < p_array.size(); i++) {
+ Vector3 v = p_array[i];
+ image->set_pixel(i, 0, Color(v.x, v.y, v.z));
+ }
+ if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
+ r_texture->create_from_image(image);
+ } else {
+ r_texture->update(image);
+ }
+}
+
+void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Color> &p_array, Ref<ImageTexture> &r_texture) {
+ Ref<Image> image;
+ image.instantiate();
+
+ if (p_array.size() == 0) {
+ image->create(1, 1, false, Image::Format::FORMAT_RGBA8);
+ } else {
+ image->create(p_array.size(), 1, false, Image::Format::FORMAT_RGBA8);
+ }
+
+ for (int i = 0; i < p_array.size(); i++) {
+ image->set_pixel(i, 0, p_array[i]);
+ }
+ if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
+ r_texture->create_from_image(image);
+ } else {
+ r_texture->update(image);
+ }
+}
+
+void VisualShaderNodeParticleMeshEmitter::_update_textures() {
if (!mesh.is_valid()) {
return;
}
Vector<Vector3> vertices;
Vector<Vector3> normals;
+ Vector<Color> colors;
+ Vector<Vector2> uvs;
+ Vector<Vector2> uvs2;
if (use_all_surfaces) {
for (int i = 0; i < max_surface_index; i++) {
+ // position
Array vertex_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_VERTEX];
for (int j = 0; j < vertex_array.size(); j++) {
vertices.push_back((Vector3)vertex_array[j]);
}
+ // normal
Array normal_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_NORMAL];
- for (int j = 0; j < vertex_array.size(); j++) {
- normals.push_back((Vector3)vertex_array[j]);
+ for (int j = 0; j < normal_array.size(); j++) {
+ normals.push_back((Vector3)normal_array[j]);
+ }
+
+ // color
+ Array color_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_COLOR];
+ for (int j = 0; j < color_array.size(); j++) {
+ colors.push_back((Color)color_array[j]);
+ }
+
+ // uv
+ Array uv_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV];
+ for (int j = 0; j < uv_array.size(); j++) {
+ uvs.push_back((Vector2)uv_array[j]);
+ }
+
+ // uv2
+ Array uv2_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV2];
+ for (int j = 0; j < uv2_array.size(); j++) {
+ uvs2.push_back((Vector2)uv2_array[j]);
}
}
} else {
+ // position
Array vertex_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_VERTEX];
for (int i = 0; i < vertex_array.size(); i++) {
vertices.push_back((Vector3)vertex_array[i]);
}
+ // normal
Array normal_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_NORMAL];
for (int i = 0; i < normal_array.size(); i++) {
normals.push_back((Vector3)normal_array[i]);
}
- }
- // vertices
- {
- Ref<Image> image;
- image.instantiate();
- image->create(vertices.size(), 1, false, Image::Format::FORMAT_RGBF);
-
- for (int i = 0; i < vertices.size(); i++) {
- Vector3 v = vertices[i];
- image->set_pixel(i, 0, Color(v.x, v.y, v.z));
- }
- if (position_texture->get_width() != vertices.size()) {
- position_texture->create_from_image(image);
- } else {
- position_texture->update(image);
+ // color
+ Array color_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_COLOR];
+ for (int i = 0; i < color_array.size(); i++) {
+ colors.push_back((Color)color_array[i]);
}
- }
-
- // normals
- {
- Ref<Image> image;
- image.instantiate();
- image->create(normals.size(), 1, false, Image::Format::FORMAT_RGBF);
- for (int i = 0; i < normals.size(); i++) {
- Vector3 v = normals[i];
- image->set_pixel(i, 0, Color(v.x, v.y, v.z));
+ // uv
+ Array uv_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV];
+ for (int j = 0; j < uv_array.size(); j++) {
+ uvs.push_back((Vector2)uv_array[j]);
}
- if (normal_texture->get_width() != normals.size()) {
- normal_texture->create_from_image(image);
- } else {
- normal_texture->update(image);
+
+ // uv2
+ Array uv2_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV2];
+ for (int j = 0; j < uv2_array.size(); j++) {
+ uvs2.push_back((Vector2)uv2_array[j]);
}
}
+
+ _update_texture(vertices, position_texture);
+ _update_texture(normals, normal_texture);
+ _update_texture(colors, color_texture);
+ _update_texture(uvs, uv_texture);
+ _update_texture(uvs2, uv2_texture);
}
void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) {
@@ -442,7 +586,7 @@ void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) {
}
if (mesh.is_valid()) {
- Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::update_texture);
+ Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures);
if (mesh->is_connected(CoreStringNames::get_singleton()->changed, callable)) {
mesh->disconnect(CoreStringNames::get_singleton()->changed, callable);
@@ -452,7 +596,7 @@ void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) {
mesh = p_mesh;
if (mesh.is_valid()) {
- Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::update_texture);
+ Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures);
if (!mesh->is_connected(CoreStringNames::get_singleton()->changed, callable)) {
mesh->connect(CoreStringNames::get_singleton()->changed, callable);
@@ -528,10 +672,13 @@ void VisualShaderNodeParticleMeshEmitter::_bind_methods() {
}
VisualShaderNodeParticleMeshEmitter::VisualShaderNodeParticleMeshEmitter() {
- connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &VisualShaderNodeParticleMeshEmitter::update_texture));
+ connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures));
position_texture.instantiate();
normal_texture.instantiate();
+ color_texture.instantiate();
+ uv_texture.instantiate();
+ uv2_texture.instantiate();
}
// VisualShaderNodeParticleMultiplyByAxisAngle
diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h
index 0d0f21e4bf..79459432f1 100644
--- a/scene/resources/visual_shader_particle_nodes.h
+++ b/scene/resources/visual_shader_particle_nodes.h
@@ -115,6 +115,16 @@ class VisualShaderNodeParticleMeshEmitter : public VisualShaderNodeParticleEmitt
Ref<ImageTexture> position_texture;
Ref<ImageTexture> normal_texture;
+ Ref<ImageTexture> color_texture;
+ Ref<ImageTexture> uv_texture;
+ Ref<ImageTexture> uv2_texture;
+
+ String _generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, bool p_ignore_mode2d = false) const;
+
+ void _update_texture(const Vector<Vector2> &p_array, Ref<ImageTexture> &r_texture);
+ void _update_texture(const Vector<Vector3> &p_array, Ref<ImageTexture> &r_texture);
+ void _update_texture(const Vector<Color> &p_array, Ref<ImageTexture> &r_texture);
+ void _update_textures();
protected:
static void _bind_methods();
@@ -130,11 +140,9 @@ public:
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
- virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
- void update_texture();
-
void set_mesh(Ref<Mesh> p_mesh);
Ref<Mesh> get_mesh() const;