diff options
Diffstat (limited to 'core/math')
-rw-r--r-- | core/math/SCsub | 33 | ||||
-rw-r--r-- | core/math/a_star.cpp | 271 | ||||
-rw-r--r-- | core/math/a_star.h | 37 | ||||
-rw-r--r-- | core/math/basis.cpp | 5 | ||||
-rw-r--r-- | core/math/basis.h | 4 | ||||
-rw-r--r-- | core/math/bsp_tree.h | 4 | ||||
-rw-r--r-- | core/math/camera_matrix.h | 4 | ||||
-rw-r--r-- | core/math/crypto_core.cpp | 157 | ||||
-rw-r--r-- | core/math/crypto_core.h | 90 | ||||
-rw-r--r-- | core/math/delaunay.h | 4 | ||||
-rw-r--r-- | core/math/expression.cpp | 11 | ||||
-rw-r--r-- | core/math/geometry.h | 7 | ||||
-rw-r--r-- | core/math/math_funcs.h | 12 | ||||
-rw-r--r-- | core/math/octree.h | 9 | ||||
-rw-r--r-- | core/math/quat.h | 4 | ||||
-rw-r--r-- | core/math/transform.cpp | 5 | ||||
-rw-r--r-- | core/math/transform.h | 5 | ||||
-rw-r--r-- | core/math/vector2.cpp | 13 | ||||
-rw-r--r-- | core/math/vector2.h | 24 | ||||
-rw-r--r-- | core/math/vector3.h | 40 |
20 files changed, 288 insertions, 451 deletions
diff --git a/core/math/SCsub b/core/math/SCsub index 0995298a4b..be438fcfbe 100644 --- a/core/math/SCsub +++ b/core/math/SCsub @@ -2,37 +2,6 @@ Import('env') -env_math = env.Clone() # Maybe make one specific for crypto? - -is_builtin = env["builtin_mbedtls"] -has_module = env["module_mbedtls_enabled"] - -if is_builtin or not has_module: - # Use our headers for builtin or if the module is not going to be compiled. - # We decided not to depend on system mbedtls just for these few files that can - # be easily extracted. - env_math.Prepend(CPPPATH=["#thirdparty/mbedtls/include"]) - -# MbedTLS core functions (for CryptoCore). -# If the mbedtls module is compiled we don't need to add the .c files with our -# custom config since they will be built by the module itself. -# Only if the module is not enabled, we must compile here the required sources -# to make a "light" build with only the necessary mbedtls files. -if not has_module: - env_thirdparty = env_math.Clone() - env_thirdparty.disable_warnings() - # Custom config file - env_thirdparty.Append(CPPDEFINES=[('MBEDTLS_CONFIG_FILE', '\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\"')]) - thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/" - thirdparty_mbedtls_sources = [ - "aes.c", - "base64.c", - "md5.c", - "sha1.c", - "sha256.c", - "godot_core_mbedtls_platform.c" - ] - thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources] - env_thirdparty.add_source_files(env.core_sources, thirdparty_mbedtls_sources) +env_math = env.Clone() env_math.add_source_files(env.core_sources, "*.cpp") diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index b61119d8df..60b7326c29 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -40,7 +40,17 @@ int AStar::get_available_point_id() const { return 1; } - return points.back()->key() + 1; + // calculate our new next available point id if bigger than before or next id already contained in set of points. + if (points.has(last_free_id)) { + int cur_new_id = last_free_id; + while (points.has(cur_new_id)) { + cur_new_id++; + } + int &non_const = const_cast<int &>(last_free_id); + non_const = cur_new_id; + } + + return last_free_id; } void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) { @@ -48,7 +58,10 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) { ERR_FAIL_COND(p_id < 0); ERR_FAIL_COND(p_weight_scale < 1); - if (!points.has(p_id)) { + Point *found_pt; + bool p_exists = points.lookup(p_id, found_pt); + + if (!p_exists) { Point *pt = memnew(Point); pt->id = p_id; pt->pos = p_pos; @@ -57,84 +70,98 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) { pt->open_pass = 0; pt->closed_pass = 0; pt->enabled = true; - points[p_id] = pt; + points.set(p_id, pt); } else { - points[p_id]->pos = p_pos; - points[p_id]->weight_scale = p_weight_scale; + found_pt->pos = p_pos; + found_pt->weight_scale = p_weight_scale; } } Vector3 AStar::get_point_position(int p_id) const { - ERR_FAIL_COND_V(!points.has(p_id), Vector3()); + Point *p; + bool p_exists = points.lookup(p_id, p); + ERR_FAIL_COND_V(!p_exists, Vector3()); - return points[p_id]->pos; + return p->pos; } void AStar::set_point_position(int p_id, const Vector3 &p_pos) { - ERR_FAIL_COND(!points.has(p_id)); + Point *p; + bool p_exists = points.lookup(p_id, p); + ERR_FAIL_COND(!p_exists); - points[p_id]->pos = p_pos; + p->pos = p_pos; } real_t AStar::get_point_weight_scale(int p_id) const { - ERR_FAIL_COND_V(!points.has(p_id), 0); + Point *p; + bool p_exists = points.lookup(p_id, p); + ERR_FAIL_COND_V(!p_exists, 0); - return points[p_id]->weight_scale; + return p->weight_scale; } void AStar::set_point_weight_scale(int p_id, real_t p_weight_scale) { - ERR_FAIL_COND(!points.has(p_id)); + Point *p; + bool p_exists = points.lookup(p_id, p); + ERR_FAIL_COND(!p_exists); ERR_FAIL_COND(p_weight_scale < 1); - points[p_id]->weight_scale = p_weight_scale; + p->weight_scale = p_weight_scale; } void AStar::remove_point(int p_id) { - ERR_FAIL_COND(!points.has(p_id)); - - Point *p = points[p_id]; + Point *p; + bool p_exists = points.lookup(p_id, p); + ERR_FAIL_COND(!p_exists); - for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) { + for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) { - Segment s(p_id, E->get()->id); + Segment s(p_id, (*it.key)); segments.erase(s); - E->get()->neighbours.erase(p); - E->get()->unlinked_neighbours.erase(p); + (*it.value)->neighbours.remove(p->id); + (*it.value)->unlinked_neighbours.remove(p->id); } - for (Set<Point *>::Element *E = p->unlinked_neighbours.front(); E; E = E->next()) { + for (OAHashMap<int, Point *>::Iterator it = p->unlinked_neighbours.iter(); it.valid; it = p->unlinked_neighbours.next_iter(it)) { - Segment s(p_id, E->get()->id); + Segment s(p_id, (*it.key)); segments.erase(s); - E->get()->neighbours.erase(p); - E->get()->unlinked_neighbours.erase(p); + (*it.value)->neighbours.remove(p->id); + (*it.value)->unlinked_neighbours.remove(p->id); } memdelete(p); - points.erase(p_id); + points.remove(p_id); + last_free_id = p_id; } void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) { - ERR_FAIL_COND(!points.has(p_id)); - ERR_FAIL_COND(!points.has(p_with_id)); ERR_FAIL_COND(p_id == p_with_id); - Point *a = points[p_id]; - Point *b = points[p_with_id]; - a->neighbours.insert(b); + Point *a; + bool from_exists = points.lookup(p_id, a); + ERR_FAIL_COND(!from_exists); + + Point *b; + bool to_exists = points.lookup(p_with_id, b); + ERR_FAIL_COND(!to_exists); - if (bidirectional) - b->neighbours.insert(a); - else - b->unlinked_neighbours.insert(a); + a->neighbours.set(b->id, b); + + if (bidirectional) { + b->neighbours.set(a->id, a); + } else { + b->unlinked_neighbours.set(a->id, a); + } Segment s(p_id, p_with_id); if (s.from == p_id) { @@ -147,6 +174,7 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) { segments.insert(s); } + void AStar::disconnect_points(int p_id, int p_with_id) { Segment s(p_id, p_with_id); @@ -154,12 +182,18 @@ void AStar::disconnect_points(int p_id, int p_with_id) { segments.erase(s); - Point *a = points[p_id]; - Point *b = points[p_with_id]; - a->neighbours.erase(b); - a->unlinked_neighbours.erase(b); - b->neighbours.erase(a); - b->unlinked_neighbours.erase(a); + Point *a; + bool a_exists = points.lookup(p_id, a); + CRASH_COND(!a_exists); + + Point *b; + bool b_exists = points.lookup(p_with_id, b); + CRASH_COND(!b_exists); + + a->neighbours.remove(b->id); + a->unlinked_neighbours.remove(b->id); + b->neighbours.remove(a->id); + b->unlinked_neighbours.remove(a->id); } bool AStar::has_point(int p_id) const { @@ -171,8 +205,8 @@ Array AStar::get_points() { Array point_list; - for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) { - point_list.push_back(E->key()); + for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) { + point_list.push_back(*(it.key)); } return point_list; @@ -180,14 +214,14 @@ Array AStar::get_points() { PoolVector<int> AStar::get_point_connections(int p_id) { - ERR_FAIL_COND_V(!points.has(p_id), PoolVector<int>()); + Point *p; + bool p_exists = points.lookup(p_id, p); + ERR_FAIL_COND_V(!p_exists, PoolVector<int>()); PoolVector<int> point_list; - Point *p = points[p_id]; - - for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) { - point_list.push_back(E->get()->id); + for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) { + point_list.push_back((*it.key)); } return point_list; @@ -201,27 +235,41 @@ bool AStar::are_points_connected(int p_id, int p_with_id) const { void AStar::clear() { - for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) { - - memdelete(E->get()); + last_free_id = 0; + for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) { + memdelete(*(it.value)); } segments.clear(); points.clear(); } +int AStar::get_point_count() const { + return points.get_num_elements(); +} + +int AStar::get_point_capacity() const { + return points.get_capacity(); +} + +void AStar::reserve_space(int p_num_nodes) { + ERR_FAIL_COND_MSG(p_num_nodes <= 0, "New capacity must be greater than 0, was: " + itos(p_num_nodes) + "."); + ERR_FAIL_COND_MSG((uint32_t)p_num_nodes < points.get_capacity(), "New capacity must be greater than current capacity: " + itos(points.get_capacity()) + ", new was: " + itos(p_num_nodes) + "."); + points.reserve(p_num_nodes); +} + int AStar::get_closest_point(const Vector3 &p_point) const { int closest_id = -1; real_t closest_dist = 1e20; - for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) { + for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) { + + if (!(*it.value)->enabled) continue; // Disabled points should not be considered. - if (!E->get()->enabled) - continue; //Disabled points should not be considered - real_t d = p_point.distance_squared_to(E->get()->pos); + real_t d = p_point.distance_squared_to((*it.value)->pos); if (closest_id < 0 || d < closest_dist) { closest_dist = d; - closest_id = E->key(); + closest_id = *(it.key); } } @@ -230,8 +278,8 @@ int AStar::get_closest_point(const Vector3 &p_point) const { Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const { - real_t closest_dist = 1e20; bool found = false; + real_t closest_dist = 1e20; Vector3 closest_point; for (const Set<Segment>::Element *E = segments.front(); E; E = E->next()) { @@ -262,8 +310,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { pass++; - if (!end_point->enabled) - return false; + if (!end_point->enabled) return false; bool found_route = false; @@ -272,13 +319,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { begin_point->g_score = 0; begin_point->f_score = _estimate_cost(begin_point->id, end_point->id); - open_list.push_back(begin_point); - while (true) { - - if (open_list.size() == 0) // No path found - break; + while (!open_list.empty()) { Point *p = open_list[0]; // The currently processed point @@ -291,24 +334,23 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { open_list.remove(open_list.size() - 1); p->closed_pass = pass; // Mark the point as closed - for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) { + for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) { - Point *e = E->get(); // The neighbour point + Point *e = *(it.value); // The neighbour point - if (!e->enabled || e->closed_pass == pass) + if (!e->enabled || e->closed_pass == pass) { continue; + } real_t tentative_g_score = p->g_score + _compute_cost(p->id, e->id) * e->weight_scale; bool new_point = false; - if (e->open_pass != pass) { // The point wasn't inside the open list - + if (e->open_pass != pass) { // The point wasn't inside the open list. e->open_pass = pass; open_list.push_back(e); new_point = true; - } else if (tentative_g_score >= e->g_score) { // The new path is worse than the previous - + } else if (tentative_g_score >= e->g_score) { // The new path is worse than the previous. continue; } @@ -316,10 +358,11 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { e->g_score = tentative_g_score; e->f_score = e->g_score + _estimate_cost(e->id, end_point->id); - if (new_point) // The position of the new points is already known + if (new_point) { // The position of the new points is already known. sorter.push_heap(0, open_list.size() - 1, 0, e, open_list.ptrw()); - else + } else { sorter.push_heap(0, open_list.find(e), 0, e, open_list.ptrw()); + } } } @@ -331,7 +374,15 @@ float AStar::_estimate_cost(int p_from_id, int p_to_id) { if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id); - return points[p_from_id]->pos.distance_to(points[p_to_id]->pos); + Point *from_point; + bool from_exists = points.lookup(p_from_id, from_point); + CRASH_COND(!from_exists); + + Point *to_point; + bool to_exists = points.lookup(p_to_id, to_point); + CRASH_COND(!to_exists); + + return from_point->pos.distance_to(to_point->pos); } float AStar::_compute_cost(int p_from_id, int p_to_id) { @@ -339,16 +390,26 @@ float AStar::_compute_cost(int p_from_id, int p_to_id) { if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id); - return points[p_from_id]->pos.distance_to(points[p_to_id]->pos); + Point *from_point; + bool from_exists = points.lookup(p_from_id, from_point); + CRASH_COND(!from_exists); + + Point *to_point; + bool to_exists = points.lookup(p_to_id, to_point); + CRASH_COND(!to_exists); + + return from_point->pos.distance_to(to_point->pos); } PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) { - ERR_FAIL_COND_V(!points.has(p_from_id), PoolVector<Vector3>()); - ERR_FAIL_COND_V(!points.has(p_to_id), PoolVector<Vector3>()); + Point *a; + bool from_exists = points.lookup(p_from_id, a); + ERR_FAIL_COND_V(!from_exists, PoolVector<Vector3>()); - Point *a = points[p_from_id]; - Point *b = points[p_to_id]; + Point *b; + bool to_exists = points.lookup(p_to_id, b); + ERR_FAIL_COND_V(!to_exists, PoolVector<Vector3>()); if (a == b) { PoolVector<Vector3> ret; @@ -360,11 +421,8 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) { Point *end_point = b; bool found_route = _solve(begin_point, end_point); + if (!found_route) return PoolVector<Vector3>(); - if (!found_route) - return PoolVector<Vector3>(); - - // Midpoints Point *p = end_point; int pc = 1; // Begin point while (p != begin_point) { @@ -393,11 +451,13 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) { PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) { - ERR_FAIL_COND_V(!points.has(p_from_id), PoolVector<int>()); - ERR_FAIL_COND_V(!points.has(p_to_id), PoolVector<int>()); + Point *a; + bool from_exists = points.lookup(p_from_id, a); + ERR_FAIL_COND_V(!from_exists, PoolVector<int>()); - Point *a = points[p_from_id]; - Point *b = points[p_to_id]; + Point *b; + bool to_exists = points.lookup(p_to_id, b); + ERR_FAIL_COND_V(!to_exists, PoolVector<int>()); if (a == b) { PoolVector<int> ret; @@ -409,11 +469,8 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) { Point *end_point = b; bool found_route = _solve(begin_point, end_point); + if (!found_route) return PoolVector<int>(); - if (!found_route) - return PoolVector<int>(); - - // Midpoints Point *p = end_point; int pc = 1; // Begin point while (p != begin_point) { @@ -442,16 +499,20 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) { void AStar::set_point_disabled(int p_id, bool p_disabled) { - ERR_FAIL_COND(!points.has(p_id)); + Point *p; + bool p_exists = points.lookup(p_id, p); + ERR_FAIL_COND(!p_exists); - points[p_id]->enabled = !p_disabled; + p->enabled = !p_disabled; } bool AStar::is_point_disabled(int p_id) const { - ERR_FAIL_COND_V(!points.has(p_id), false); + Point *p; + bool p_exists = points.lookup(p_id, p); + ERR_FAIL_COND_V(!p_exists, false); - return !points[p_id]->enabled; + return !p->enabled; } void AStar::_bind_methods() { @@ -474,6 +535,9 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points); ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar::are_points_connected); + ClassDB::bind_method(D_METHOD("get_point_count"), &AStar::get_point_count); + ClassDB::bind_method(D_METHOD("get_point_capacity"), &AStar::get_point_capacity); + ClassDB::bind_method(D_METHOD("reserve_space", "num_nodes"), &AStar::reserve_space); ClassDB::bind_method(D_METHOD("clear"), &AStar::clear); ClassDB::bind_method(D_METHOD("get_closest_point", "to_position"), &AStar::get_closest_point); @@ -487,13 +551,11 @@ void AStar::_bind_methods() { } AStar::AStar() { - + last_free_id = 0; pass = 1; } AStar::~AStar() { - - pass = 1; clear(); } @@ -560,10 +622,22 @@ bool AStar2D::are_points_connected(int p_id, int p_with_id) const { return astar.are_points_connected(p_id, p_with_id); } +int AStar2D::get_point_count() const { + return astar.get_point_count(); +} + +int AStar2D::get_point_capacity() const { + return astar.get_point_capacity(); +} + void AStar2D::clear() { astar.clear(); } +void AStar2D::reserve_space(int p_num_nodes) { + astar.reserve_space(p_num_nodes); +} + int AStar2D::get_closest_point(const Vector2 &p_point) const { return astar.get_closest_point(Vector3(p_point.x, p_point.y, 0)); } @@ -614,6 +688,9 @@ void AStar2D::_bind_methods() { ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar2D::disconnect_points); ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar2D::are_points_connected); + ClassDB::bind_method(D_METHOD("get_point_count"), &AStar2D::get_point_count); + ClassDB::bind_method(D_METHOD("get_point_capacity"), &AStar2D::get_point_capacity); + ClassDB::bind_method(D_METHOD("reserve_space", "num_nodes"), &AStar2D::reserve_space); ClassDB::bind_method(D_METHOD("clear"), &AStar2D::clear); ClassDB::bind_method(D_METHOD("get_closest_point", "to_position"), &AStar2D::get_closest_point); diff --git a/core/math/a_star.h b/core/math/a_star.h index ec333efc1d..ec2a06f07f 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -31,8 +31,8 @@ #ifndef ASTAR_H #define ASTAR_H +#include "core/oa_hash_map.h" #include "core/reference.h" -#include "core/self_list.h" /** A* pathfinding algorithm @@ -44,19 +44,21 @@ class AStar : public Reference { GDCLASS(AStar, Reference); - uint64_t pass; - struct Point { + Point() : + neighbours(4u), + unlinked_neighbours(4u) {} + int id; Vector3 pos; real_t weight_scale; bool enabled; - Set<Point *> neighbours; - Set<Point *> unlinked_neighbours; + OAHashMap<int, Point *> neighbours; + OAHashMap<int, Point *> unlinked_neighbours; - // Used for pathfinding + // Used for pathfinding. Point *prev_point; real_t g_score; real_t f_score; @@ -64,16 +66,15 @@ class AStar : public Reference { uint64_t closed_pass; }; - Map<int, Point *> points; - struct SortPoints { - _FORCE_INLINE_ bool operator()(const Point *A, const Point *B) const { // Returns true when the Point A is worse than Point B - if (A->f_score > B->f_score) + _FORCE_INLINE_ bool operator()(const Point *A, const Point *B) const { // Returns true when the Point A is worse than Point B. + if (A->f_score > B->f_score) { return true; - else if (A->f_score < B->f_score) + } else if (A->f_score < B->f_score) { return false; - else - return A->g_score < B->g_score; // If the f_costs are the same then prioritize the points that are further away from the start + } else { + return A->g_score < B->g_score; // If the f_costs are the same then prioritize the points that are further away from the start. + } } }; @@ -101,6 +102,10 @@ class AStar : public Reference { } }; + int last_free_id; + uint64_t pass; + + OAHashMap<int, Point *> points; Set<Segment> segments; bool _solve(Point *begin_point, Point *end_point); @@ -131,6 +136,9 @@ public: void disconnect_points(int p_id, int p_with_id); bool are_points_connected(int p_id, int p_with_id) const; + int get_point_count() const; + int get_point_capacity() const; + void reserve_space(int p_num_nodes); void clear(); int get_closest_point(const Vector3 &p_point) const; @@ -170,6 +178,9 @@ public: void disconnect_points(int p_id, int p_with_id); bool are_points_connected(int p_id, int p_with_id) const; + int get_point_count() const; + int get_point_capacity() const; + void reserve_space(int p_num_nodes); void clear(); int get_closest_point(const Vector2 &p_point) const; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 400f342018..2985959113 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -618,10 +618,7 @@ Basis::operator String() const { Quat Basis::get_quat() const { #ifdef MATH_CHECKS - if (!is_rotation()) { - ERR_EXPLAIN("Basis must be normalized in order to be casted to a Quaternion. Use get_rotation_quat() or call orthonormalized() instead."); - ERR_FAIL_V(Quat()); - } + ERR_FAIL_COND_V_MSG(!is_rotation(), Quat(), "Basis must be normalized in order to be casted to a Quaternion. Use get_rotation_quat() or call orthonormalized() instead."); #endif /* Allow getting a quaternion from an unnormalized transform */ Basis m = *this; diff --git a/core/math/basis.h b/core/math/basis.h index d3adad3d90..053effda69 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -36,10 +36,6 @@ #include "core/math/quat.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - class Basis { public: Vector3 elements[3]; diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h index a7a3697990..90b5e8322a 100644 --- a/core/math/bsp_tree.h +++ b/core/math/bsp_tree.h @@ -38,9 +38,7 @@ #include "core/pool_vector.h" #include "core/variant.h" #include "core/vector.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ + class BSP_Tree { public: enum { diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 3bcf48f5da..63cc88553d 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -34,10 +34,6 @@ #include "core/math/rect2.h" #include "core/math/transform.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - struct CameraMatrix { enum Planes { diff --git a/core/math/crypto_core.cpp b/core/math/crypto_core.cpp deleted file mode 100644 index d7ba54e469..0000000000 --- a/core/math/crypto_core.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************/ -/* crypto_core.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 "crypto_core.h" - -#include <mbedtls/aes.h> -#include <mbedtls/base64.h> -#include <mbedtls/md5.h> -#include <mbedtls/sha1.h> -#include <mbedtls/sha256.h> - -// MD5 -CryptoCore::MD5Context::MD5Context() { - ctx = memalloc(sizeof(mbedtls_md5_context)); - mbedtls_md5_init((mbedtls_md5_context *)ctx); -} - -CryptoCore::MD5Context::~MD5Context() { - mbedtls_md5_free((mbedtls_md5_context *)ctx); - memfree((mbedtls_md5_context *)ctx); -} - -Error CryptoCore::MD5Context::start() { - int ret = mbedtls_md5_starts_ret((mbedtls_md5_context *)ctx); - return ret ? FAILED : OK; -} - -Error CryptoCore::MD5Context::update(uint8_t *p_src, size_t p_len) { - int ret = mbedtls_md5_update_ret((mbedtls_md5_context *)ctx, p_src, p_len); - return ret ? FAILED : OK; -} - -Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) { - int ret = mbedtls_md5_finish_ret((mbedtls_md5_context *)ctx, r_hash); - return ret ? FAILED : OK; -} - -// SHA256 -CryptoCore::SHA256Context::SHA256Context() { - ctx = memalloc(sizeof(mbedtls_sha256_context)); - mbedtls_sha256_init((mbedtls_sha256_context *)ctx); -} - -CryptoCore::SHA256Context::~SHA256Context() { - mbedtls_sha256_free((mbedtls_sha256_context *)ctx); - memfree((mbedtls_sha256_context *)ctx); -} - -Error CryptoCore::SHA256Context::start() { - int ret = mbedtls_sha256_starts_ret((mbedtls_sha256_context *)ctx, 0); - return ret ? FAILED : OK; -} - -Error CryptoCore::SHA256Context::update(uint8_t *p_src, size_t p_len) { - int ret = mbedtls_sha256_update_ret((mbedtls_sha256_context *)ctx, p_src, p_len); - return ret ? FAILED : OK; -} - -Error CryptoCore::SHA256Context::finish(unsigned char r_hash[16]) { - int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash); - return ret ? FAILED : OK; -} - -// AES256 -CryptoCore::AESContext::AESContext() { - ctx = memalloc(sizeof(mbedtls_aes_context)); - mbedtls_aes_init((mbedtls_aes_context *)ctx); -} - -CryptoCore::AESContext::~AESContext() { - mbedtls_aes_free((mbedtls_aes_context *)ctx); - memfree((mbedtls_aes_context *)ctx); -} - -Error CryptoCore::AESContext::set_encode_key(const uint8_t *p_key, size_t p_bits) { - int ret = mbedtls_aes_setkey_enc((mbedtls_aes_context *)ctx, p_key, p_bits); - return ret ? FAILED : OK; -} - -Error CryptoCore::AESContext::set_decode_key(const uint8_t *p_key, size_t p_bits) { - int ret = mbedtls_aes_setkey_dec((mbedtls_aes_context *)ctx, p_key, p_bits); - return ret ? FAILED : OK; -} - -Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) { - int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_src, r_dst); - return ret ? FAILED : OK; -} - -Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) { - int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst); - return ret ? FAILED : OK; -} - -// CryptoCore -String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { - int b64len = p_src_len / 3 * 4 + 4 + 1; - PoolVector<uint8_t> b64buff; - b64buff.resize(b64len); - PoolVector<uint8_t>::Write w64 = b64buff.write(); - size_t strlen = 0; - int ret = b64_encode(&w64[0], b64len, &strlen, p_src, p_src_len); - w64[strlen] = 0; - return ret ? String() : (const char *)&w64[0]; -} - -Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { - int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len); - return ret ? FAILED : OK; -} - -Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { - int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len); - return ret ? FAILED : OK; -} - -Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) { - int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash); - return ret ? FAILED : OK; -} - -Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) { - int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash); - return ret ? FAILED : OK; -} - -Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) { - int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0); - return ret ? FAILED : OK; -} diff --git a/core/math/crypto_core.h b/core/math/crypto_core.h deleted file mode 100644 index e28cb5a792..0000000000 --- a/core/math/crypto_core.h +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************/ -/* crypto_core.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 CRYPTO_CORE_H -#define CRYPTO_CORE_H - -#include "core/reference.h" - -class CryptoCore { - -public: - class MD5Context { - - private: - void *ctx; // To include, or not to include... - - public: - MD5Context(); - ~MD5Context(); - - Error start(); - Error update(uint8_t *p_src, size_t p_len); - Error finish(unsigned char r_hash[16]); - }; - - class SHA256Context { - - private: - void *ctx; // To include, or not to include... - - public: - SHA256Context(); - ~SHA256Context(); - - Error start(); - Error update(uint8_t *p_src, size_t p_len); - Error finish(unsigned char r_hash[16]); - }; - - class AESContext { - - private: - void *ctx; // To include, or not to include... - - public: - AESContext(); - ~AESContext(); - - Error set_encode_key(const uint8_t *p_key, size_t p_bits); - Error set_decode_key(const uint8_t *p_key, size_t p_bits); - Error encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); - Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); - }; - - static String b64_encode_str(const uint8_t *p_src, int p_src_len); - static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); - static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); - - static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]); - static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]); - static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]); -}; -#endif // CRYPTO_CORE_H diff --git a/core/math/delaunay.h b/core/math/delaunay.h index ed52c506db..3f8013a3e6 100644 --- a/core/math/delaunay.h +++ b/core/math/delaunay.h @@ -80,11 +80,11 @@ public: } static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) { - if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[0]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[1]]))) { + if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[0]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[1]]) { return true; } - if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[1]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[0]]))) { + if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[1]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[0]]) { return true; } diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 15eea1d308..46f81ce5c3 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -2161,10 +2161,8 @@ Error Expression::parse(const String &p_expression, const Vector<String> &p_inpu } Variant Expression::execute(Array p_inputs, Object *p_base, bool p_show_error) { - if (error_set) { - ERR_EXPLAIN("There was previously a parse error: " + error_str); - ERR_FAIL_V(Variant()); - } + + ERR_FAIL_COND_V_MSG(error_set, Variant(), "There was previously a parse error: " + error_str + "."); execution_error = false; Variant output; @@ -2173,10 +2171,7 @@ Variant Expression::execute(Array p_inputs, Object *p_base, bool p_show_error) { if (err) { execution_error = true; error_str = error_txt; - if (p_show_error) { - ERR_EXPLAIN(error_str); - ERR_FAIL_V(Variant()); - } + ERR_FAIL_COND_V_MSG(p_show_error, Variant(), error_str); } return output; diff --git a/core/math/geometry.h b/core/math/geometry.h index e4f3ff799e..82d9884e9b 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -41,10 +41,6 @@ #include "core/print_string.h" #include "core/vector.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - class Geometry { Geometry(); @@ -838,8 +834,7 @@ public: static Vector<Vector<Point2> > offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { - ERR_EXPLAIN("Attempt to offset a polyline like a polygon (use offset_polygon_2d instead)."); - ERR_FAIL_COND_V(p_end_type == END_POLYGON, Vector<Vector<Point2> >()); + ERR_FAIL_COND_V_MSG(p_end_type == END_POLYGON, Vector<Vector<Point2> >(), "Attempt to offset a polyline like a polygon (use offset_polygon_2d instead)."); return _polypath_offset(p_polygon, p_delta, p_join_type, p_end_type); } diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index a712356ddc..af845ca01e 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -255,16 +255,16 @@ public: static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); } static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) { - int64_t rng = max - min; - return (rng != 0) ? min + ((((value - min) % rng) + rng) % rng) : min; + int64_t range = max - min; + return range == 0 ? min : min + ((((value - min) % range) + range) % range); } static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) { - double rng = max - min; - return (!is_equal_approx(rng, 0.0)) ? value - (rng * Math::floor((value - min) / rng)) : min; + double range = max - min; + return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range)); } static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) { - float rng = max - min; - return (!is_equal_approx(rng, 0.0f)) ? value - (rng * Math::floor((value - min) / rng)) : min; + float range = max - min; + return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range)); } // double only, as these functions are mainly used by the editor and not performance-critical, diff --git a/core/math/octree.h b/core/math/octree.h index d6fc9776bc..db15c8a1f8 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -38,10 +38,6 @@ #include "core/print_string.h" #include "core/variant.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - typedef uint32_t OctreeElementID; #define OCTREE_ELEMENT_INVALID_ID 0 @@ -568,10 +564,7 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) { while (!base.encloses(p_aabb)) { - if (base.size.x > OCTREE_SIZE_LIMIT) { - ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?"); - ERR_FAIL(); - } + ERR_FAIL_COND_MSG(base.size.x > OCTREE_SIZE_LIMIT, "Octree upper size limit reached, does the AABB supplied contain NAN?"); Octant *gp = memnew_allocator(Octant, AL); octant_count++; diff --git a/core/math/quat.h b/core/math/quat.h index 8ed2fa7cc2..3d6602e466 100644 --- a/core/math/quat.h +++ b/core/math/quat.h @@ -38,10 +38,6 @@ #include "core/math/math_funcs.h" #include "core/ustring.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - class Quat { public: real_t x, y, z, w; diff --git a/core/math/transform.cpp b/core/math/transform.cpp index 7ff7cac914..4056975da8 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -213,3 +213,8 @@ Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) : basis(p_basis), origin(p_origin) { } + +Transform::Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz) { + basis = Basis(xx, xy, xz, yx, yy, yz, zx, zy, zz); + origin = Vector3(ox, oy, oz); +} diff --git a/core/math/transform.h b/core/math/transform.h index 2f43f6b035..4c8d915305 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -35,10 +35,6 @@ #include "core/math/basis.h" #include "core/math/plane.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - class Transform { public: Basis basis; @@ -108,6 +104,7 @@ public: operator String() const; + Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz); Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3()); Transform() {} }; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 779a28be66..972bccc0ac 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -98,6 +98,11 @@ real_t Vector2::cross(const Vector2 &p_other) const { return x * p_other.y - y * p_other.x; } +Vector2 Vector2::sign() const { + + return Vector2(SGN(x), SGN(y)); +} + Vector2 Vector2::floor() const { return Vector2(Math::floor(x), Math::floor(y)); @@ -121,6 +126,14 @@ Vector2 Vector2::rotated(real_t p_by) const { return v; } +Vector2 Vector2::posmod(const real_t p_mod) const { + return Vector2(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod)); +} + +Vector2 Vector2::posmodv(const Vector2 &p_modv) const { + return Vector2(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y)); +} + Vector2 Vector2::project(const Vector2 &p_b) const { return p_b * (dot(p_b) / p_b.length_squared()); } diff --git a/core/math/vector2.h b/core/math/vector2.h index 78a1641c1e..1a73831891 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -38,6 +38,11 @@ struct Vector2i; struct Vector2 { + enum Axis { + AXIS_X, + AXIS_Y, + }; + union { real_t x; real_t width; @@ -69,6 +74,8 @@ struct Vector2 { real_t dot(const Vector2 &p_other) const; real_t cross(const Vector2 &p_other) const; + Vector2 posmod(const real_t p_mod) const; + Vector2 posmodv(const Vector2 &p_modv) const; Vector2 project(const Vector2 &p_b) const; Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const; @@ -107,8 +114,10 @@ struct Vector2 { bool operator==(const Vector2 &p_vec2) const; bool operator!=(const Vector2 &p_vec2) const; - bool operator<(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y < p_vec2.y) : (x < p_vec2.x); } - bool operator<=(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y <= p_vec2.y) : (x < p_vec2.x); } + bool operator<(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } + bool operator>(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } + bool operator<=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y <= p_vec2.y) : (x < p_vec2.x); } + bool operator>=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y >= p_vec2.y) : (x > p_vec2.x); } real_t angle() const; @@ -129,6 +138,7 @@ struct Vector2 { return Vector2(y, -x); } + Vector2 sign() const; Vector2 floor() const; Vector2 ceil() const; Vector2 round() const; @@ -141,10 +151,7 @@ struct Vector2 { x = p_x; y = p_y; } - _FORCE_INLINE_ Vector2() { - x = 0; - y = 0; - } + _FORCE_INLINE_ Vector2() { x = y = 0; } }; _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const { @@ -262,6 +269,11 @@ typedef Vector2 Point2; struct Vector2i { + enum Axis { + AXIS_X, + AXIS_Y, + }; + union { int x; int width; diff --git a/core/math/vector3.h b/core/math/vector3.h index 45bdfee487..c68b075613 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -31,9 +31,7 @@ #ifndef VECTOR3_H #define VECTOR3_H -#include "core/math/math_defs.h" #include "core/math/math_funcs.h" -#include "core/typedefs.h" #include "core/ustring.h" class Basis; @@ -110,6 +108,8 @@ struct Vector3 { _FORCE_INLINE_ real_t distance_to(const Vector3 &p_b) const; _FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_b) const; + _FORCE_INLINE_ Vector3 posmod(const real_t p_mod) const; + _FORCE_INLINE_ Vector3 posmodv(const Vector3 &p_modv) const; _FORCE_INLINE_ Vector3 project(const Vector3 &p_b) const; _FORCE_INLINE_ real_t angle_to(const Vector3 &p_b) const; @@ -141,15 +141,17 @@ struct Vector3 { _FORCE_INLINE_ bool operator!=(const Vector3 &p_v) const; _FORCE_INLINE_ bool operator<(const Vector3 &p_v) const; _FORCE_INLINE_ bool operator<=(const Vector3 &p_v) const; + _FORCE_INLINE_ bool operator>(const Vector3 &p_v) const; + _FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const; operator String() const; - _FORCE_INLINE_ Vector3() { x = y = z = 0; } _FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) { x = p_x; y = p_y; z = p_z; } + _FORCE_INLINE_ Vector3() { x = y = z = 0; } }; // Should be included after class definition, otherwise we get circular refs @@ -233,6 +235,14 @@ real_t Vector3::distance_squared_to(const Vector3 &p_b) const { return (p_b - *this).length_squared(); } +Vector3 Vector3::posmod(const real_t p_mod) const { + return Vector3(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod), Math::fposmod(z, p_mod)); +} + +Vector3 Vector3::posmodv(const Vector3 &p_modv) const { + return Vector3(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y), Math::fposmod(z, p_modv.z)); +} + Vector3 Vector3::project(const Vector3 &p_b) const { return p_b * (dot(p_b) / p_b.length_squared()); } @@ -357,6 +367,18 @@ bool Vector3::operator<(const Vector3 &p_v) const { } } +bool Vector3::operator>(const Vector3 &p_v) const { + + if (Math::is_equal_approx(x, p_v.x)) { + if (Math::is_equal_approx(y, p_v.y)) + return z > p_v.z; + else + return y > p_v.y; + } else { + return x > p_v.x; + } +} + bool Vector3::operator<=(const Vector3 &p_v) const { if (Math::is_equal_approx(x, p_v.x)) { @@ -369,6 +391,18 @@ bool Vector3::operator<=(const Vector3 &p_v) const { } } +bool Vector3::operator>=(const Vector3 &p_v) const { + + if (Math::is_equal_approx(x, p_v.x)) { + if (Math::is_equal_approx(y, p_v.y)) + return z >= p_v.z; + else + return y > p_v.y; + } else { + return x > p_v.x; + } +} + _FORCE_INLINE_ Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) { return p_a.cross(p_b); |