summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/windows/file_access_windows.cpp39
-rw-r--r--scene/3d/path_3d.cpp52
-rw-r--r--scene/3d/path_3d.h3
-rw-r--r--tests/scene/test_path_follow_3d.h31
4 files changed, 58 insertions, 67 deletions
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 43a9f61749..9d6aa13332 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -413,15 +413,40 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
file = file.substr(0, file.length() - 1);
}
- struct _stat st;
- int rv = _wstat((LPCWSTR)(file.utf16().get_data()), &st);
+ HANDLE handle = CreateFileW((LPCWSTR)(file.utf16().get_data()), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
- if (rv == 0) {
- return st.st_mtime;
- } else {
- print_verbose("Failed to get modified time for: " + p_file + "");
- return 0;
+ if (handle != INVALID_HANDLE_VALUE) {
+ FILETIME ft_create, ft_write;
+
+ bool status = GetFileTime(handle, &ft_create, nullptr, &ft_write);
+
+ CloseHandle(handle);
+
+ if (status) {
+ uint64_t ret = 0;
+
+ // If write time is invalid, fallback to creation time.
+ if (ft_write.dwHighDateTime == 0 && ft_write.dwLowDateTime == 0) {
+ ret = ft_create.dwHighDateTime;
+ ret <<= 32;
+ ret |= ft_create.dwLowDateTime;
+ } else {
+ ret = ft_write.dwHighDateTime;
+ ret <<= 32;
+ ret |= ft_write.dwLowDateTime;
+ }
+
+ const uint64_t WINDOWS_TICKS_PER_SECOND = 10000000;
+ const uint64_t TICKS_TO_UNIX_EPOCH = 116444736000000000LL;
+
+ if (ret >= TICKS_TO_UNIX_EPOCH) {
+ return (ret - TICKS_TO_UNIX_EPOCH) / WINDOWS_TICKS_PER_SECOND;
+ }
+ }
}
+
+ print_verbose("Failed to get modified time for: " + p_file);
+ return 0;
}
BitField<FileAccess::UnixPermissionFlags> FileAccessWindows::_get_unix_permissions(const String &p_file) {
diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp
index 20d646fe1e..64259a24b0 100644
--- a/scene/3d/path_3d.cpp
+++ b/scene/3d/path_3d.cpp
@@ -216,24 +216,7 @@ void Path3D::_bind_methods() {
ADD_SIGNAL(MethodInfo("curve_changed"));
}
-// Update transform, in deferred mode by default to avoid superfluity.
-void PathFollow3D::update_transform(bool p_immediate) {
- transform_dirty = true;
-
- if (p_immediate) {
- _update_transform();
- } else {
- callable_mp(this, &PathFollow3D::_update_transform).call_deferred();
- }
-}
-
-// Update transform immediately .
-void PathFollow3D::_update_transform() {
- if (!transform_dirty) {
- return;
- }
- transform_dirty = false;
-
+void PathFollow3D::update_transform() {
if (!path) {
return;
}
@@ -286,9 +269,7 @@ void PathFollow3D::_notification(int p_what) {
Node *parent = get_parent();
if (parent) {
path = Object::cast_to<Path3D>(parent);
- if (path) {
- update_transform();
- }
+ update_transform();
}
} break;
@@ -414,6 +395,9 @@ void PathFollow3D::_bind_methods() {
void PathFollow3D::set_progress(real_t p_progress) {
ERR_FAIL_COND(!isfinite(p_progress));
+ if (progress == p_progress) {
+ return;
+ }
progress = p_progress;
if (path) {
@@ -435,10 +419,11 @@ void PathFollow3D::set_progress(real_t p_progress) {
}
void PathFollow3D::set_h_offset(real_t p_h_offset) {
- h_offset = p_h_offset;
- if (path) {
- update_transform();
+ if (h_offset == p_h_offset) {
+ return;
}
+ h_offset = p_h_offset;
+ update_transform();
}
real_t PathFollow3D::get_h_offset() const {
@@ -446,10 +431,11 @@ real_t PathFollow3D::get_h_offset() const {
}
void PathFollow3D::set_v_offset(real_t p_v_offset) {
- v_offset = p_v_offset;
- if (path) {
- update_transform();
+ if (v_offset == p_v_offset) {
+ return;
}
+ v_offset = p_v_offset;
+ update_transform();
}
real_t PathFollow3D::get_v_offset() const {
@@ -476,6 +462,9 @@ real_t PathFollow3D::get_progress_ratio() const {
}
void PathFollow3D::set_rotation_mode(RotationMode p_rotation_mode) {
+ if (rotation_mode == p_rotation_mode) {
+ return;
+ }
rotation_mode = p_rotation_mode;
update_configuration_warnings();
@@ -487,6 +476,9 @@ PathFollow3D::RotationMode PathFollow3D::get_rotation_mode() const {
}
void PathFollow3D::set_use_model_front(bool p_use_model_front) {
+ if (use_model_front == p_use_model_front) {
+ return;
+ }
use_model_front = p_use_model_front;
update_transform();
}
@@ -496,6 +488,9 @@ bool PathFollow3D::is_using_model_front() const {
}
void PathFollow3D::set_loop(bool p_loop) {
+ if (loop == p_loop) {
+ return;
+ }
loop = p_loop;
update_transform();
}
@@ -505,6 +500,9 @@ bool PathFollow3D::has_loop() const {
}
void PathFollow3D::set_tilt_enabled(bool p_enabled) {
+ if (tilt_enabled == p_enabled) {
+ return;
+ }
tilt_enabled = p_enabled;
update_transform();
}
diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h
index 0c9111bb8e..fb4f301375 100644
--- a/scene/3d/path_3d.h
+++ b/scene/3d/path_3d.h
@@ -90,7 +90,6 @@ protected:
void _validate_property(PropertyInfo &p_property) const;
void _notification(int p_what);
- void _update_transform();
static void _bind_methods();
@@ -124,7 +123,7 @@ public:
PackedStringArray get_configuration_warnings() const override;
- void update_transform(bool p_immediate = false);
+ void update_transform();
static Transform3D correct_posture(Transform3D p_transform, PathFollow3D::RotationMode p_rotation_mode);
diff --git a/tests/scene/test_path_follow_3d.h b/tests/scene/test_path_follow_3d.h
index d08af3a70c..6a384bec2b 100644
--- a/tests/scene/test_path_follow_3d.h
+++ b/tests/scene/test_path_follow_3d.h
@@ -60,39 +60,30 @@ TEST_CASE("[SceneTree][PathFollow3D] Sampling with progress ratio") {
SceneTree::get_singleton()->get_root()->add_child(path);
path_follow_3d->set_progress_ratio(0);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(0, 0, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress_ratio(0.125);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(50, 0, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress_ratio(0.25);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 0, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress_ratio(0.375);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 50, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress_ratio(0.5);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 100, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress_ratio(0.625);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 100, 50), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress_ratio(0.75);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 100, 100), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress_ratio(0.875);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 50, 100), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress_ratio(1);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 0, 100), path_follow_3d->get_transform().get_origin()));
memdelete(path);
@@ -113,39 +104,30 @@ TEST_CASE("[SceneTree][PathFollow3D] Sampling with progress") {
SceneTree::get_singleton()->get_root()->add_child(path);
path_follow_3d->set_progress(0);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(0, 0, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress(50);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(50, 0, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress(100);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 0, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress(150);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 50, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress(200);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 100, 0), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress(250);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 100, 50), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress(300);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 100, 100), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress(350);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 50, 100), path_follow_3d->get_transform().get_origin()));
path_follow_3d->set_progress(400);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 0, 100), path_follow_3d->get_transform().get_origin()));
memdelete(path);
@@ -163,13 +145,11 @@ TEST_CASE("[SceneTree][PathFollow3D] Removal of a point in curve") {
SceneTree::get_singleton()->get_root()->add_child(path);
path_follow_3d->set_progress_ratio(0.5);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(100, 0, 0), path_follow_3d->get_transform().get_origin()));
curve->remove_point(1);
path_follow_3d->set_progress_ratio(0.5);
- path_follow_3d->update_transform(true);
CHECK_MESSAGE(
is_equal_approx(Vector3(50, 50, 0), path_follow_3d->get_transform().get_origin()),
"Path follow's position should be updated after removing a point from the curve");
@@ -270,47 +250,36 @@ TEST_CASE("[SceneTree][PathFollow3D] Calculate forward vector") {
path_follow_3d->set_rotation_mode(PathFollow3D::RotationMode::ROTATION_ORIENTED);
path_follow_3d->set_progress(-50);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(-1, 0, 0), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(0);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(-1, 0, 0), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(50);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(-1, 0, 0), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(100);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(-1, 0, 0), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(100 + dist_cube_100 / 2);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(-0.577348, -0.577348, 0.577348), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(100 + dist_cube_100 - 0.01);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(-0.577348, -0.577348, 0.577348), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(250 + dist_cube_100);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(0, 0, -1), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(400 + dist_cube_100 - 0.01);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(0, 0, -1), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(400 + 1.5 * dist_cube_100);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(0.577348, 0.577348, 0.577348), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(400 + 2 * dist_cube_100 - 0.01);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(0.577348, 0.577348, 0.577348), path_follow_3d->get_transform().get_basis().get_column(2)));
path_follow_3d->set_progress(500 + 2 * dist_cube_100);
- path_follow_3d->update_transform(true);
CHECK(is_equal_approx(Vector3(1, 0, 0), path_follow_3d->get_transform().get_basis().get_column(2)));
memdelete(path);