summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp2
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp6
-rw-r--r--modules/gdscript/gdscript_parser.cpp10
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs61
-rw-r--r--modules/noise/doc_classes/Noise.xml4
-rw-r--r--modules/noise/doc_classes/NoiseTexture2D.xml4
-rw-r--r--modules/noise/noise.cpp77
-rw-r--r--modules/noise/noise.h4
-rw-r--r--modules/noise/noise_texture_2d.cpp20
-rw-r--r--modules/noise/noise_texture_2d.h4
10 files changed, 108 insertions, 84 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 23be913a24..5883ec863d 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -307,7 +307,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
in_number = true;
}
- if (!in_word && (is_ascii_char(str[j]) || is_underscore(str[j])) && !in_number) {
+ if (!in_word && is_unicode_identifier_start(str[j]) && !in_number) {
in_word = true;
}
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 7ea0603d57..8dd65a700a 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -1049,7 +1049,7 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class, co
resolve_class_body(base_class, p_class);
}
- // Do functions and properties now.
+ // Do functions, properties, and groups now.
for (int i = 0; i < p_class->members.size(); i++) {
GDScriptParser::ClassNode::Member member = p_class->members[i];
if (member.type == GDScriptParser::ClassNode::Member::FUNCTION) {
@@ -1089,6 +1089,10 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class, co
resolve_function_body(member.variable->setter);
}
}
+ } else if (member.type == GDScriptParser::ClassNode::Member::GROUP) {
+ // Apply annotation (`@export_{category,group,subgroup}`).
+ resolve_annotation(member.annotation);
+ member.annotation->apply(parser, nullptr);
}
}
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 74d7f94d7c..267718207f 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -840,14 +840,19 @@ void GDScriptParser::parse_class_body(bool p_is_multiline) {
case GDScriptTokenizer::Token::ANNOTATION: {
advance();
- // Check for class-level annotations.
+ // Check for standalone and class-level annotations.
AnnotationNode *annotation = parse_annotation(AnnotationInfo::STANDALONE | AnnotationInfo::CLASS_LEVEL);
if (annotation != nullptr) {
if (annotation->applies_to(AnnotationInfo::STANDALONE)) {
if (previous.type != GDScriptTokenizer::Token::NEWLINE) {
push_error(R"(Expected newline after a standalone annotation.)");
}
- head->annotations.push_back(annotation);
+ if (annotation->name == "@export_category" || annotation->name == "@export_group" || annotation->name == "@export_subgroup") {
+ current_class->add_member_group(annotation);
+ } else {
+ // For potential non-group standalone annotations.
+ push_error(R"(Unexpected standalone annotation in class body.)");
+ }
} else {
annotation_stack.push_back(annotation);
}
@@ -3841,7 +3846,6 @@ bool GDScriptParser::export_group_annotations(const AnnotationNode *p_annotation
} break;
}
- current_class->add_member_group(annotation);
return true;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index e939396926..5d41e33d0b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -50,6 +50,18 @@ namespace Godot
}
/// <summary>
+ /// Returns the transform's skew (in radians).
+ /// </summary>
+ public readonly real_t Skew
+ {
+ get
+ {
+ real_t detSign = Mathf.Sign(BasisDeterminant());
+ return Mathf.Acos(X.Normalized().Dot(detSign * Y.Normalized())) - Mathf.Pi * 0.5f;
+ }
+ }
+
+ /// <summary>
/// Access whole columns in the form of <see cref="Vector2"/>.
/// The third column is the <see cref="Origin"/> vector.
/// </summary>
@@ -190,48 +202,13 @@ namespace Godot
/// <returns>The interpolated transform.</returns>
public readonly Transform2D InterpolateWith(Transform2D transform, real_t weight)
{
- real_t r1 = Rotation;
- real_t r2 = transform.Rotation;
-
- Vector2 s1 = Scale;
- Vector2 s2 = transform.Scale;
-
- // Slerp rotation
- (real_t sin1, real_t cos1) = Mathf.SinCos(r1);
- (real_t sin2, real_t cos2) = Mathf.SinCos(r2);
- var v1 = new Vector2(cos1, sin1);
- var v2 = new Vector2(cos2, sin2);
-
- real_t dot = v1.Dot(v2);
-
- dot = Mathf.Clamp(dot, -1.0f, 1.0f);
-
- Vector2 v;
-
- if (dot > 0.9995f)
- {
- // Linearly interpolate to avoid numerical precision issues
- v = v1.Lerp(v2, weight).Normalized();
- }
- else
- {
- real_t angle = weight * Mathf.Acos(dot);
- Vector2 v3 = (v2 - (v1 * dot)).Normalized();
- (real_t sine, real_t cos) = Mathf.SinCos(angle);
- v = (v1 * sine) + (v3 * cos);
- }
-
- // Extract parameters
- Vector2 p1 = Origin;
- Vector2 p2 = transform.Origin;
-
- // Construct matrix
- var res = new Transform2D(Mathf.Atan2(v.Y, v.X), p1.Lerp(p2, weight));
- Vector2 scale = s1.Lerp(s2, weight);
- res.X *= scale;
- res.Y *= scale;
-
- return res;
+ return new Transform2D
+ (
+ Mathf.LerpAngle(Rotation, transform.Rotation, weight),
+ Scale.Lerp(transform.Scale, weight),
+ Mathf.LerpAngle(Skew, transform.Skew, weight),
+ Origin.Lerp(transform.Origin, weight)
+ );
}
/// <summary>
diff --git a/modules/noise/doc_classes/Noise.xml b/modules/noise/doc_classes/Noise.xml
index 735ca388de..78d7d6a15b 100644
--- a/modules/noise/doc_classes/Noise.xml
+++ b/modules/noise/doc_classes/Noise.xml
@@ -17,8 +17,10 @@
<param index="1" name="height" type="int" />
<param index="2" name="invert" type="bool" default="false" />
<param index="3" name="in_3d_space" type="bool" default="false" />
+ <param index="4" name="normalize" type="bool" default="true" />
<description>
Returns a 2D [Image] noise image.
+ Note: With [param normalize] set to [code]false[/code] the default implementation expects the noise generator to return values in the range [code]-1.0[/code] to [code]1.0[/code].
</description>
</method>
<method name="get_noise_1d" qualifiers="const">
@@ -66,8 +68,10 @@
<param index="2" name="invert" type="bool" default="false" />
<param index="3" name="in_3d_space" type="bool" default="false" />
<param index="4" name="skirt" type="float" default="0.1" />
+ <param index="5" name="normalize" type="bool" default="true" />
<description>
Returns a seamless 2D [Image] noise image.
+ Note: With [param normalize] set to [code]false[/code] the default implementation expects the noise generator to return values in the range [code]-1.0[/code] to [code]1.0[/code].
</description>
</method>
</methods>
diff --git a/modules/noise/doc_classes/NoiseTexture2D.xml b/modules/noise/doc_classes/NoiseTexture2D.xml
index 0a800a143b..0f10a3f32f 100644
--- a/modules/noise/doc_classes/NoiseTexture2D.xml
+++ b/modules/noise/doc_classes/NoiseTexture2D.xml
@@ -44,6 +44,10 @@
<member name="noise" type="Noise" setter="set_noise" getter="get_noise">
The instance of the [Noise] object.
</member>
+ <member name="normalize" type="bool" setter="set_normalize" getter="is_normalized" default="true">
+ If [code]true[/code], the noise image coming from the noise generator is normalized to the range [code]0.0[/code] to [code]1.0[/code].
+ Turning normalization off can affect the contrast and allows you to generate non repeating tileable noise textures.
+ </member>
<member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" />
<member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false">
If [code]true[/code], a seamless texture is requested from the [Noise] resource.
diff --git a/modules/noise/noise.cpp b/modules/noise/noise.cpp
index 5a901cb6e1..e95788b863 100644
--- a/modules/noise/noise.cpp
+++ b/modules/noise/noise.cpp
@@ -32,7 +32,7 @@
#include <float.h>
-Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, real_t p_blend_skirt) const {
+Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, real_t p_blend_skirt, bool p_normalize) const {
ERR_FAIL_COND_V(p_width <= 0 || p_height <= 0, Ref<Image>());
int skirt_width = MAX(1, p_width * p_blend_skirt);
@@ -40,7 +40,7 @@ Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, b
int src_width = p_width + skirt_width;
int src_height = p_height + skirt_height;
- Ref<Image> src = get_image(src_width, src_height, p_invert, p_in_3d_space);
+ Ref<Image> src = get_image(src_width, src_height, p_invert, p_in_3d_space, p_normalize);
bool grayscale = (src->get_format() == Image::FORMAT_L8);
if (grayscale) {
return _generate_seamless_image<uint8_t>(src, p_width, p_height, p_invert, p_blend_skirt);
@@ -58,7 +58,7 @@ uint8_t Noise::_alpha_blend<uint8_t>(uint8_t p_bg, uint8_t p_fg, int p_alpha) co
return (uint8_t)((alpha * p_fg + inv_alpha * p_bg) >> 8);
}
-Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space) const {
+Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, bool p_normalize) const {
ERR_FAIL_COND_V(p_width <= 0 || p_height <= 0, Ref<Image>());
Vector<uint8_t> data;
@@ -66,38 +66,49 @@ Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_
uint8_t *wd8 = data.ptrw();
- // Get all values and identify min/max values.
- Vector<real_t> values;
- values.resize(p_width * p_height);
- real_t min_val = FLT_MAX;
- real_t max_val = -FLT_MAX;
-
- for (int y = 0, i = 0; y < p_height; y++) {
- for (int x = 0; x < p_width; x++, i++) {
- values.set(i, p_in_3d_space ? get_noise_3d(x, y, 0.0) : get_noise_2d(x, y));
- if (values[i] > max_val) {
- max_val = values[i];
- }
- if (values[i] < min_val) {
- min_val = values[i];
+ if (p_normalize) {
+ // Get all values and identify min/max values.
+ Vector<real_t> values;
+ values.resize(p_width * p_height);
+ real_t min_val = FLT_MAX;
+ real_t max_val = -FLT_MAX;
+ for (int y = 0, i = 0; y < p_height; y++) {
+ for (int x = 0; x < p_width; x++, i++) {
+ values.set(i, p_in_3d_space ? get_noise_3d(x, y, 0.0) : get_noise_2d(x, y));
+ if (values[i] > max_val) {
+ max_val = values[i];
+ }
+ if (values[i] < min_val) {
+ min_val = values[i];
+ }
}
}
- }
-
- // Normalize values and write to texture.
- uint8_t value;
- for (int i = 0, x = 0; i < p_height; i++) {
- for (int j = 0; j < p_width; j++, x++) {
- if (max_val == min_val) {
- value = 0;
- } else {
- value = uint8_t(CLAMP((values[x] - min_val) / (max_val - min_val) * 255.f, 0, 255));
+ // Normalize values and write to texture.
+ uint8_t ivalue;
+ for (int i = 0, x = 0; i < p_height; i++) {
+ for (int j = 0; j < p_width; j++, x++) {
+ if (max_val == min_val) {
+ ivalue = 0;
+ } else {
+ ivalue = static_cast<uint8_t>(CLAMP((values[x] - min_val) / (max_val - min_val) * 255.f, 0, 255));
+ }
+
+ if (p_invert) {
+ ivalue = 255 - ivalue;
+ }
+
+ wd8[x] = ivalue;
}
- if (p_invert) {
- value = 255 - value;
+ }
+ } else {
+ // Without normalization, the expected range of the noise function is [-1, 1].
+ uint8_t ivalue;
+ for (int y = 0, i = 0; y < p_height; y++) {
+ for (int x = 0; x < p_width; x++, i++) {
+ float value = (p_in_3d_space ? get_noise_3d(x, y, 0.0) : get_noise_2d(x, y));
+ ivalue = static_cast<uint8_t>(CLAMP(value * 127.5f + 127.5f, 0.0f, 255.0f));
+ wd8[i] = p_invert ? (255 - ivalue) : ivalue;
}
-
- wd8[x] = value;
}
}
@@ -113,6 +124,6 @@ void Noise::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_noise_3dv", "v"), &Noise::get_noise_3dv);
// Textures.
- ClassDB::bind_method(D_METHOD("get_image", "width", "height", "invert", "in_3d_space"), &Noise::get_image, DEFVAL(false), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("get_seamless_image", "width", "height", "invert", "in_3d_space", "skirt"), &Noise::get_seamless_image, DEFVAL(false), DEFVAL(false), DEFVAL(0.1));
+ ClassDB::bind_method(D_METHOD("get_image", "width", "height", "invert", "in_3d_space", "normalize"), &Noise::get_image, DEFVAL(false), DEFVAL(false), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("get_seamless_image", "width", "height", "invert", "in_3d_space", "skirt", "normalize"), &Noise::get_seamless_image, DEFVAL(false), DEFVAL(false), DEFVAL(0.1), DEFVAL(true));
}
diff --git a/modules/noise/noise.h b/modules/noise/noise.h
index 8f8ecf29a5..f7e615c2aa 100644
--- a/modules/noise/noise.h
+++ b/modules/noise/noise.h
@@ -233,8 +233,8 @@ public:
virtual real_t get_noise_3dv(Vector3 p_v) const = 0;
virtual real_t get_noise_3d(real_t p_x, real_t p_y, real_t p_z) const = 0;
- virtual Ref<Image> get_image(int p_width, int p_height, bool p_invert = false, bool p_in_3d_space = false) const;
- virtual Ref<Image> get_seamless_image(int p_width, int p_height, bool p_invert = false, bool p_in_3d_space = false, real_t p_blend_skirt = 0.1) const;
+ virtual Ref<Image> get_image(int p_width, int p_height, bool p_invert = false, bool p_in_3d_space = false, bool p_normalize = true) const;
+ virtual Ref<Image> get_seamless_image(int p_width, int p_height, bool p_invert = false, bool p_in_3d_space = false, real_t p_blend_skirt = 0.1, bool p_normalize = true) const;
};
#endif // NOISE_H
diff --git a/modules/noise/noise_texture_2d.cpp b/modules/noise/noise_texture_2d.cpp
index 0eedb286bd..0d5e778875 100644
--- a/modules/noise/noise_texture_2d.cpp
+++ b/modules/noise/noise_texture_2d.cpp
@@ -76,6 +76,9 @@ void NoiseTexture2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture2D::set_bump_strength);
ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture2D::get_bump_strength);
+ ClassDB::bind_method(D_METHOD("set_normalize", "normalize"), &NoiseTexture2D::set_normalize);
+ ClassDB::bind_method(D_METHOD("is_normalized"), &NoiseTexture2D::is_normalized);
+
ClassDB::bind_method(D_METHOD("set_color_ramp", "gradient"), &NoiseTexture2D::set_color_ramp);
ClassDB::bind_method(D_METHOD("get_color_ramp"), &NoiseTexture2D::get_color_ramp);
@@ -91,6 +94,7 @@ void NoiseTexture2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "seamless_blend_skirt", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_seamless_blend_skirt", "get_seamless_blend_skirt");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normal_map"), "set_as_normal_map", "is_normal_map");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalize"), "set_normalize", "is_normalized");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "Noise"), "set_noise", "get_noise");
}
@@ -156,9 +160,9 @@ Ref<Image> NoiseTexture2D::_generate_texture() {
Ref<Image> new_image;
if (seamless) {
- new_image = ref_noise->get_seamless_image(size.x, size.y, invert, in_3d_space, seamless_blend_skirt);
+ new_image = ref_noise->get_seamless_image(size.x, size.y, invert, in_3d_space, seamless_blend_skirt, normalize);
} else {
- new_image = ref_noise->get_image(size.x, size.y, invert, in_3d_space);
+ new_image = ref_noise->get_image(size.x, size.y, invert, in_3d_space, normalize);
}
if (color_ramp.is_valid()) {
new_image = _modulate_with_gradient(new_image, color_ramp);
@@ -349,6 +353,18 @@ void NoiseTexture2D::set_color_ramp(const Ref<Gradient> &p_gradient) {
_queue_update();
}
+void NoiseTexture2D::set_normalize(bool p_normalize) {
+ if (normalize == p_normalize) {
+ return;
+ }
+ normalize = p_normalize;
+ _queue_update();
+}
+
+bool NoiseTexture2D::is_normalized() const {
+ return normalize;
+}
+
Ref<Gradient> NoiseTexture2D::get_color_ramp() const {
return color_ramp;
}
diff --git a/modules/noise/noise_texture_2d.h b/modules/noise/noise_texture_2d.h
index cda14df6c2..f53670b690 100644
--- a/modules/noise/noise_texture_2d.h
+++ b/modules/noise/noise_texture_2d.h
@@ -59,6 +59,7 @@ private:
real_t seamless_blend_skirt = 0.1;
bool as_normal_map = false;
float bump_strength = 8.0;
+ bool normalize = true;
Ref<Gradient> color_ramp;
Ref<Noise> noise;
@@ -105,6 +106,9 @@ public:
void set_bump_strength(float p_bump_strength);
float get_bump_strength();
+ void set_normalize(bool p_normalize);
+ bool is_normalized() const;
+
void set_color_ramp(const Ref<Gradient> &p_gradient);
Ref<Gradient> get_color_ramp() const;