summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/core_constants.cpp3
-rw-r--r--core/variant/binder_common.h1
-rw-r--r--doc/classes/Area2D.xml8
-rw-r--r--doc/classes/Area3D.xml8
-rw-r--r--platform/linuxbsd/detect.py7
-rw-r--r--scene/2d/area_2d.cpp8
-rw-r--r--scene/3d/area_3d.cpp8
-rw-r--r--tests/test_path_follow_3d.h220
8 files changed, 246 insertions, 17 deletions
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index ef5dbf17bb..f9edff1899 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -125,6 +125,9 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(VERTICAL);
BIND_CORE_ENUM_CONSTANT(HORIZONTAL);
+ BIND_CORE_ENUM_CONSTANT(CLOCKWISE);
+ BIND_CORE_ENUM_CONSTANT(COUNTERCLOCKWISE);
+
BIND_CORE_ENUM_CONSTANT(HALIGN_LEFT);
BIND_CORE_ENUM_CONSTANT(HALIGN_CENTER);
BIND_CORE_ENUM_CONSTANT(HALIGN_RIGHT);
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 9d8e262cc9..490bd45b7b 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -88,6 +88,7 @@ VARIANT_ENUM_CAST(Vector3::Axis);
VARIANT_ENUM_CAST(Error);
VARIANT_ENUM_CAST(Side);
+VARIANT_ENUM_CAST(ClockDirection);
VARIANT_ENUM_CAST(Corner);
VARIANT_ENUM_CAST(Orientation);
VARIANT_ENUM_CAST(HAlign);
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index a02f077cf7..9711a2a35b 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -187,7 +187,7 @@
</description>
</signal>
<signal name="body_entered">
- <argument index="0" name="body" type="Node">
+ <argument index="0" name="body" type="Node2D">
</argument>
<description>
Emitted when a [PhysicsBody2D] or [TileMap] enters this Area2D. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
@@ -195,7 +195,7 @@
</description>
</signal>
<signal name="body_exited">
- <argument index="0" name="body" type="Node">
+ <argument index="0" name="body" type="Node2D">
</argument>
<description>
Emitted when a [PhysicsBody2D] or [TileMap] exits this Area2D. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
@@ -205,7 +205,7 @@
<signal name="body_shape_entered">
<argument index="0" name="body_id" type="int">
</argument>
- <argument index="1" name="body" type="Node">
+ <argument index="1" name="body" type="Node2D">
</argument>
<argument index="2" name="body_shape" type="int">
</argument>
@@ -222,7 +222,7 @@
<signal name="body_shape_exited">
<argument index="0" name="body_id" type="int">
</argument>
- <argument index="1" name="body" type="Node">
+ <argument index="1" name="body" type="Node2D">
</argument>
<argument index="2" name="body_shape" type="int">
</argument>
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index bd43d619dd..4271769155 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -197,7 +197,7 @@
</description>
</signal>
<signal name="body_entered">
- <argument index="0" name="body" type="Node">
+ <argument index="0" name="body" type="Node3D">
</argument>
<description>
Emitted when a [PhysicsBody3D] or [GridMap] enters this Area3D. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
@@ -205,7 +205,7 @@
</description>
</signal>
<signal name="body_exited">
- <argument index="0" name="body" type="Node">
+ <argument index="0" name="body" type="Node3D">
</argument>
<description>
Emitted when a [PhysicsBody3D] or [GridMap] exits this Area3D. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
@@ -215,7 +215,7 @@
<signal name="body_shape_entered">
<argument index="0" name="body_id" type="int">
</argument>
- <argument index="1" name="body" type="Node">
+ <argument index="1" name="body" type="Node3D">
</argument>
<argument index="2" name="body_shape" type="int">
</argument>
@@ -232,7 +232,7 @@
<signal name="body_shape_exited">
<argument index="0" name="body_id" type="int">
</argument>
- <argument index="1" name="body" type="Node">
+ <argument index="1" name="body" type="Node3D">
</argument>
<argument index="2" name="body_shape" type="int">
</argument>
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index ff521e4e7f..8f1afe0e66 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -127,7 +127,6 @@ def configure(env):
env["CC"] = "clang"
env["CXX"] = "clang++"
env.extra_suffix = ".llvm" + env.extra_suffix
- env.Append(LIBS=["atomic"])
if env["use_lld"]:
if env["use_llvm"]:
@@ -394,3 +393,9 @@ def configure(env):
# That doesn't make any sense but it's likely a Ubuntu bug?
if is64 or env["bits"] == "64":
env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"])
+ if env["use_llvm"]:
+ env["LINKCOM"] = env["LINKCOM"] + " -l:libatomic.a"
+
+ else:
+ if env["use_llvm"]:
+ env.Append(LIBS=["atomic"])
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 68d5b4b540..49d1654e3f 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -590,10 +590,10 @@ void Area2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout);
ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout);
- 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, "local_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, "local_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, "Node2D"), 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, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
+ ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), 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, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 99c5276636..23eda379be 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -640,10 +640,10 @@ 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, "local_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, "local_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, "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")));
diff --git a/tests/test_path_follow_3d.h b/tests/test_path_follow_3d.h
new file mode 100644
index 0000000000..b6b4c88222
--- /dev/null
+++ b/tests/test_path_follow_3d.h
@@ -0,0 +1,220 @@
+/*************************************************************************/
+/* test_path_follow_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 TEST_PATH_FOLLOW_3D_H
+#define TEST_PATH_FOLLOW_3D_H
+
+#include "scene/3d/path_3d.h"
+#include "scene/resources/curve.h"
+
+#include "tests/test_macros.h"
+
+namespace TestPathFollow3D {
+
+TEST_CASE("[PathFollow3D] Sampling with unit offset") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ curve->add_point(Vector3(100, 100, 0));
+ curve->add_point(Vector3(100, 100, 100));
+ curve->add_point(Vector3(100, 0, 100));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_unit_offset(0);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(0, 0, 0));
+
+ path_follow_3d->set_unit_offset(0.125);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(50, 0, 0));
+
+ path_follow_3d->set_unit_offset(0.25);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 0);
+
+ path_follow_3d->set_unit_offset(0.375);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 0)));
+
+ path_follow_3d->set_unit_offset(0.5);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 0)));
+
+ path_follow_3d->set_unit_offset(0.625);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 50)));
+
+ path_follow_3d->set_unit_offset(0.75);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 100)));
+
+ path_follow_3d->set_unit_offset(0.875);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 100)));
+
+ path_follow_3d->set_unit_offset(1);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 100)));
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow3D] Sampling with offset") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ curve->add_point(Vector3(100, 100, 0));
+ curve->add_point(Vector3(100, 100, 100));
+ curve->add_point(Vector3(100, 0, 100));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_offset(0);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(0, 0, 0));
+
+ path_follow_3d->set_offset(50);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(50, 0, 0));
+
+ path_follow_3d->set_offset(100);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 0);
+
+ path_follow_3d->set_offset(150);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 0)));
+
+ path_follow_3d->set_offset(200);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 0)));
+
+ path_follow_3d->set_offset(250);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 50)));
+
+ path_follow_3d->set_offset(300);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 100)));
+
+ path_follow_3d->set_offset(350);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 100)));
+
+ path_follow_3d->set_offset(400);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 100)));
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow3D] Removal of a point in curve") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ curve->add_point(Vector3(100, 100, 0));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_unit_offset(0.5);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector2(100, 0, 0)));
+
+ curve->remove_point(1);
+
+ CHECK_MESSAGE(
+ path_follow_3d->get_transform().get_origin().is_equal_approx(Vector2(50, 50, 0)),
+ "Path follow's position should be updated after removing a point from the curve");
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow3D] Unit offset out of range") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_loop(true);
+
+ path_follow_3d->set_unit_offset(-0.3);
+ CHECK_MESSAGE(
+ path_follow_3d->get_unit_offset() == 0.7,
+ "Unit Offset should loop back from the end in the opposite direction");
+
+ path_follow_3d->set_unit_offset(1.3);
+ CHECK_MESSAGE(
+ path_follow_3d->get_unit_offset() == 0.3,
+ "Unit Offset should loop back from the end in the opposite direction");
+
+ path_follow_3d->set_loop(false);
+
+ path_follow_3d->set_unit_offset(-0.3);
+ CHECK_MESSAGE(
+ path_follow_3d->get_unit_offset() == 0,
+ "Unit Offset should be clamped at 0");
+
+ path_follow_3d->set_unit_offset(1.3);
+ CHECK_MESSAGE(
+ path_follow_3d->get_unit_offset() == 1,
+ "Unit Offset should be clamped at 1");
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow3D] Offset out of range") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_loop(true);
+
+ path_follow_3d->set_offset(-50);
+ CHECK_MESSAGE(
+ path_follow_3d->get_offset() == 50,
+ "Offset should loop back from the end in the opposite direction");
+
+ path_follow_3d->set_offset(150);
+ CHECK_MESSAGE(
+ path_follow_3d->get_offset() == 50,
+ "Offset should loop back from the end in the opposite direction");
+
+ path_follow_3d->set_loop(false);
+
+ path_follow_3d->set_offset(-50);
+ CHECK_MESSAGE(
+ path_follow_3d->get_offset() == 0,
+ "Offset should be clamped at 0");
+
+ path_follow_3d->set_offset(150);
+ CHECK_MESSAGE(
+ path_follow_3d->get_offset() == 100,
+ "Offset should be clamped at max value of curve");
+
+ memdelete(path);
+}
+} // namespace TestPathFollow3D
+
+#endif // TEST_PATH_FOLLOW_3D_H