summaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
Diffstat (limited to 'core/math')
-rw-r--r--core/math/SCsub2
-rw-r--r--core/math/a_star.cpp249
-rw-r--r--core/math/a_star.h28
-rw-r--r--core/math/aabb.h4
-rw-r--r--core/math/audio_frame.h6
-rw-r--r--core/math/basis.cpp16
-rw-r--r--core/math/basis.h3
-rw-r--r--core/math/bsp_tree.cpp581
-rw-r--r--core/math/bsp_tree.h159
-rw-r--r--core/math/camera_matrix.cpp60
-rw-r--r--core/math/camera_matrix.h21
-rw-r--r--core/math/disjoint_set.h2
-rw-r--r--core/math/expression.cpp179
-rw-r--r--core/math/expression.h7
-rw-r--r--core/math/geometry.cpp61
-rw-r--r--core/math/geometry.h44
-rw-r--r--core/math/octree.h54
-rw-r--r--core/math/quat.h2
-rw-r--r--core/math/quick_hull.cpp6
-rw-r--r--core/math/quick_hull.h8
-rw-r--r--core/math/random_pcg.h8
-rw-r--r--core/math/rect2.h49
-rw-r--r--core/math/transform.h21
-rw-r--r--core/math/transform_2d.h21
-rw-r--r--core/math/triangle_mesh.cpp80
-rw-r--r--core/math/triangle_mesh.h16
-rw-r--r--core/math/triangulate.h2
-rw-r--r--core/math/vector2.h7
-rw-r--r--core/math/vector3.cpp4
-rw-r--r--core/math/vector3.h10
-rw-r--r--core/math/vector3i.cpp55
-rw-r--r--core/math/vector3i.h272
32 files changed, 936 insertions, 1101 deletions
diff --git a/core/math/SCsub b/core/math/SCsub
index be438fcfbe..c8fdac207e 100644
--- a/core/math/SCsub
+++ b/core/math/SCsub
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-Import('env')
+Import("env")
env_math = env.Clone()
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 73f190a330..3e3e6c50a7 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -66,7 +66,7 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
pt->id = p_id;
pt->pos = p_pos;
pt->weight_scale = p_weight_scale;
- pt->prev_point = NULL;
+ pt->prev_point = nullptr;
pt->open_pass = 0;
pt->closed_pass = 0;
pt->enabled = true;
@@ -167,7 +167,7 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
if (bidirectional) s.direction = Segment::BIDIRECTIONAL;
Set<Segment>::Element *element = segments.find(s);
- if (element != NULL) {
+ if (element != nullptr) {
s.direction |= element->get().direction;
if (s.direction == Segment::BIDIRECTIONAL) {
// Both are neighbours of each other now
@@ -194,7 +194,7 @@ void AStar::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
int remove_direction = bidirectional ? (int)Segment::BIDIRECTIONAL : s.direction;
Set<Segment>::Element *element = segments.find(s);
- if (element != NULL) {
+ if (element != nullptr) {
// s is the new segment
// Erase the directions to be removed
s.direction = (element->get().direction & ~remove_direction);
@@ -235,13 +235,13 @@ Array AStar::get_points() {
return point_list;
}
-PoolVector<int> AStar::get_point_connections(int p_id) {
+Vector<int> AStar::get_point_connections(int p_id) {
Point *p;
bool p_exists = points.lookup(p_id, p);
- ERR_FAIL_COND_V(!p_exists, PoolVector<int>());
+ ERR_FAIL_COND_V(!p_exists, Vector<int>());
- PoolVector<int> point_list;
+ Vector<int> point_list;
for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
point_list.push_back((*it.key));
@@ -255,7 +255,7 @@ bool AStar::are_points_connected(int p_id, int p_with_id, bool bidirectional) co
Segment s(p_id, p_with_id);
const Set<Segment>::Element *element = segments.find(s);
- return element != NULL &&
+ return element != nullptr &&
(bidirectional || (element->get().direction & s.direction) == s.direction);
}
@@ -399,7 +399,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
return found_route;
}
-float AStar::_estimate_cost(int p_from_id, int p_to_id) {
+real_t 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);
@@ -415,7 +415,7 @@ float AStar::_estimate_cost(int p_from_id, int p_to_id) {
return from_point->pos.distance_to(to_point->pos);
}
-float AStar::_compute_cost(int p_from_id, int p_to_id) {
+real_t 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);
@@ -431,18 +431,18 @@ float AStar::_compute_cost(int p_from_id, int p_to_id) {
return from_point->pos.distance_to(to_point->pos);
}
-PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
+Vector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
Point *a;
bool from_exists = points.lookup(p_from_id, a);
- ERR_FAIL_COND_V(!from_exists, PoolVector<Vector3>());
+ ERR_FAIL_COND_V(!from_exists, Vector<Vector3>());
Point *b;
bool to_exists = points.lookup(p_to_id, b);
- ERR_FAIL_COND_V(!to_exists, PoolVector<Vector3>());
+ ERR_FAIL_COND_V(!to_exists, Vector<Vector3>());
if (a == b) {
- PoolVector<Vector3> ret;
+ Vector<Vector3> ret;
ret.push_back(a->pos);
return ret;
}
@@ -451,7 +451,7 @@ 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 Vector<Vector3>();
Point *p = end_point;
int pc = 1; // Begin point
@@ -460,11 +460,11 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
p = p->prev_point;
}
- PoolVector<Vector3> path;
+ Vector<Vector3> path;
path.resize(pc);
{
- PoolVector<Vector3>::Write w = path.write();
+ Vector3 *w = path.ptrw();
Point *p2 = end_point;
int idx = pc - 1;
@@ -479,18 +479,18 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
return path;
}
-PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
+Vector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
Point *a;
bool from_exists = points.lookup(p_from_id, a);
- ERR_FAIL_COND_V(!from_exists, PoolVector<int>());
+ ERR_FAIL_COND_V(!from_exists, Vector<int>());
Point *b;
bool to_exists = points.lookup(p_to_id, b);
- ERR_FAIL_COND_V(!to_exists, PoolVector<int>());
+ ERR_FAIL_COND_V(!to_exists, Vector<int>());
if (a == b) {
- PoolVector<int> ret;
+ Vector<int> ret;
ret.push_back(a->id);
return ret;
}
@@ -499,7 +499,7 @@ 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 Vector<int>();
Point *p = end_point;
int pc = 1; // Begin point
@@ -508,11 +508,11 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
p = p->prev_point;
}
- PoolVector<int> path;
+ Vector<int> path;
path.resize(pc);
{
- PoolVector<int>::Write w = path.write();
+ int *w = path.ptrw();
p = end_point;
int idx = pc - 1;
@@ -576,8 +576,8 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar::get_id_path);
- BIND_VMETHOD(MethodInfo(Variant::REAL, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
- BIND_VMETHOD(MethodInfo(Variant::REAL, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
}
AStar::AStar() {
@@ -624,7 +624,7 @@ bool AStar2D::has_point(int p_id) const {
return astar.has_point(p_id);
}
-PoolVector<int> AStar2D::get_point_connections(int p_id) {
+Vector<int> AStar2D::get_point_connections(int p_id) {
return astar.get_point_connections(p_id);
}
@@ -677,25 +677,195 @@ Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const {
return Vector2(p.x, p.y);
}
-PoolVector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
+real_t AStar2D::_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);
+
+ AStar::Point *from_point;
+ bool from_exists = astar.points.lookup(p_from_id, from_point);
+ ERR_FAIL_COND_V(!from_exists, 0);
+
+ AStar::Point *to_point;
+ bool to_exists = astar.points.lookup(p_to_id, to_point);
+ ERR_FAIL_COND_V(!to_exists, 0);
+
+ return from_point->pos.distance_to(to_point->pos);
+}
+
+real_t AStar2D::_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);
+
+ AStar::Point *from_point;
+ bool from_exists = astar.points.lookup(p_from_id, from_point);
+ ERR_FAIL_COND_V(!from_exists, 0);
+
+ AStar::Point *to_point;
+ bool to_exists = astar.points.lookup(p_to_id, to_point);
+ ERR_FAIL_COND_V(!to_exists, 0);
+
+ return from_point->pos.distance_to(to_point->pos);
+}
+
+Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
+
+ AStar::Point *a;
+ bool from_exists = astar.points.lookup(p_from_id, a);
+ ERR_FAIL_COND_V(!from_exists, Vector<Vector2>());
+
+ AStar::Point *b;
+ bool to_exists = astar.points.lookup(p_to_id, b);
+ ERR_FAIL_COND_V(!to_exists, Vector<Vector2>());
+
+ if (a == b) {
+ Vector<Vector2> ret;
+ ret.push_back(Vector2(a->pos.x, a->pos.y));
+ return ret;
+ }
+
+ AStar::Point *begin_point = a;
+ AStar::Point *end_point = b;
+
+ bool found_route = _solve(begin_point, end_point);
+ if (!found_route) return Vector<Vector2>();
+
+ AStar::Point *p = end_point;
+ int pc = 1; // Begin point
+ while (p != begin_point) {
+ pc++;
+ p = p->prev_point;
+ }
+
+ Vector<Vector2> path;
+ path.resize(pc);
+
+ {
+ Vector2 *w = path.ptrw();
+
+ AStar::Point *p2 = end_point;
+ int idx = pc - 1;
+ while (p2 != begin_point) {
+ w[idx--] = Vector2(p2->pos.x, p2->pos.y);
+ p2 = p2->prev_point;
+ }
+
+ w[0] = Vector2(p2->pos.x, p2->pos.y); // Assign first
+ }
+
+ return path;
+}
+
+Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
+
+ AStar::Point *a;
+ bool from_exists = astar.points.lookup(p_from_id, a);
+ ERR_FAIL_COND_V(!from_exists, Vector<int>());
+
+ AStar::Point *b;
+ bool to_exists = astar.points.lookup(p_to_id, b);
+ ERR_FAIL_COND_V(!to_exists, Vector<int>());
+
+ if (a == b) {
+ Vector<int> ret;
+ ret.push_back(a->id);
+ return ret;
+ }
+
+ AStar::Point *begin_point = a;
+ AStar::Point *end_point = b;
+
+ bool found_route = _solve(begin_point, end_point);
+ if (!found_route) return Vector<int>();
+
+ AStar::Point *p = end_point;
+ int pc = 1; // Begin point
+ while (p != begin_point) {
+ pc++;
+ p = p->prev_point;
+ }
+
+ Vector<int> path;
+ path.resize(pc);
- PoolVector3Array pv = astar.get_point_path(p_from_id, p_to_id);
- int size = pv.size();
- PoolVector2Array path;
- path.resize(size);
{
- PoolVector<Vector3>::Read r = pv.read();
- PoolVector<Vector2>::Write w = path.write();
- for (int i = 0; i < size; i++) {
- Vector3 p = r[i];
- w[i] = Vector2(p.x, p.y);
+ int *w = path.ptrw();
+
+ p = end_point;
+ int idx = pc - 1;
+ while (p != begin_point) {
+ w[idx--] = p->id;
+ p = p->prev_point;
}
+
+ w[0] = p->id; // Assign first
}
+
return path;
}
-PoolVector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
- return astar.get_id_path(p_from_id, p_to_id);
+bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
+
+ astar.pass++;
+
+ if (!end_point->enabled) return false;
+
+ bool found_route = false;
+
+ Vector<AStar::Point *> open_list;
+ SortArray<AStar::Point *, AStar::SortPoints> sorter;
+
+ begin_point->g_score = 0;
+ begin_point->f_score = _estimate_cost(begin_point->id, end_point->id);
+ open_list.push_back(begin_point);
+
+ while (!open_list.empty()) {
+
+ AStar::Point *p = open_list[0]; // The currently processed point
+
+ if (p == end_point) {
+ found_route = true;
+ break;
+ }
+
+ sorter.pop_heap(0, open_list.size(), open_list.ptrw()); // Remove the current point from the open list
+ open_list.remove(open_list.size() - 1);
+ p->closed_pass = astar.pass; // Mark the point as closed
+
+ for (OAHashMap<int, AStar::Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
+
+ AStar::Point *e = *(it.value); // The neighbour point
+
+ if (!e->enabled || e->closed_pass == astar.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 != astar.pass) { // The point wasn't inside the open list.
+ e->open_pass = astar.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.
+ continue;
+ }
+
+ e->prev_point = p;
+ 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.
+ sorter.push_heap(0, open_list.size() - 1, 0, e, open_list.ptrw());
+ } else {
+ sorter.push_heap(0, open_list.find(e), 0, e, open_list.ptrw());
+ }
+ }
+ }
+
+ return found_route;
}
void AStar2D::_bind_methods() {
@@ -728,6 +898,9 @@ void AStar2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar2D::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar2D::get_id_path);
+
+ BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
}
AStar2D::AStar2D() {
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 0b10976932..8c10ace33c 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ASTAR_H
-#define ASTAR_H
+#ifndef A_STAR_H
+#define A_STAR_H
#include "core/oa_hash_map.h"
#include "core/reference.h"
@@ -43,6 +43,7 @@
class AStar : public Reference {
GDCLASS(AStar, Reference);
+ friend class AStar2D;
struct Point {
@@ -124,8 +125,8 @@ class AStar : public Reference {
protected:
static void _bind_methods();
- virtual float _estimate_cost(int p_from_id, int p_to_id);
- virtual float _compute_cost(int p_from_id, int p_to_id);
+ virtual real_t _estimate_cost(int p_from_id, int p_to_id);
+ virtual real_t _compute_cost(int p_from_id, int p_to_id);
public:
int get_available_point_id() const;
@@ -137,7 +138,7 @@ public:
void set_point_weight_scale(int p_id, real_t p_weight_scale);
void remove_point(int p_id);
bool has_point(int p_id) const;
- PoolVector<int> get_point_connections(int p_id);
+ Vector<int> get_point_connections(int p_id);
Array get_points();
void set_point_disabled(int p_id, bool p_disabled = true);
@@ -155,8 +156,8 @@ public:
int get_closest_point(const Vector3 &p_point, bool p_include_disabled = false) const;
Vector3 get_closest_position_in_segment(const Vector3 &p_point) const;
- PoolVector<Vector3> get_point_path(int p_from_id, int p_to_id);
- PoolVector<int> get_id_path(int p_from_id, int p_to_id);
+ Vector<Vector3> get_point_path(int p_from_id, int p_to_id);
+ Vector<int> get_id_path(int p_from_id, int p_to_id);
AStar();
~AStar();
@@ -166,9 +167,14 @@ class AStar2D : public Reference {
GDCLASS(AStar2D, Reference);
AStar astar;
+ bool _solve(AStar::Point *begin_point, AStar::Point *end_point);
+
protected:
static void _bind_methods();
+ virtual real_t _estimate_cost(int p_from_id, int p_to_id);
+ virtual real_t _compute_cost(int p_from_id, int p_to_id);
+
public:
int get_available_point_id() const;
@@ -179,7 +185,7 @@ public:
void set_point_weight_scale(int p_id, real_t p_weight_scale);
void remove_point(int p_id);
bool has_point(int p_id) const;
- PoolVector<int> get_point_connections(int p_id);
+ Vector<int> get_point_connections(int p_id);
Array get_points();
void set_point_disabled(int p_id, bool p_disabled = true);
@@ -197,11 +203,11 @@ public:
int get_closest_point(const Vector2 &p_point, bool p_include_disabled = false) const;
Vector2 get_closest_position_in_segment(const Vector2 &p_point) const;
- PoolVector<Vector2> get_point_path(int p_from_id, int p_to_id);
- PoolVector<int> get_id_path(int p_from_id, int p_to_id);
+ Vector<Vector2> get_point_path(int p_from_id, int p_to_id);
+ Vector<int> get_id_path(int p_from_id, int p_to_id);
AStar2D();
~AStar2D();
};
-#endif // ASTAR_H
+#endif // A_STAR_H
diff --git a/core/math/aabb.h b/core/math/aabb.h
index d9d50c7139..eca74e6755 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -72,8 +72,8 @@ public:
AABB merge(const AABB &p_with) const;
void merge_with(const AABB &p_aabb); ///merge with another AABB
AABB intersection(const AABB &p_aabb) const; ///get box where two intersect, empty if no intersection occurs
- bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip = NULL, Vector3 *r_normal = NULL) const;
- bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = NULL, Vector3 *r_normal = NULL) const;
+ bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const;
+ bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const;
_FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const;
_FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_planes, int p_plane_count) const;
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index 6477d029d5..e1dbb385e4 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef AUDIOFRAME_H
-#define AUDIOFRAME_H
+#ifndef AUDIO_FRAME_H
+#define AUDIO_FRAME_H
#include "core/math/vector2.h"
#include "core/typedefs.h"
@@ -140,4 +140,4 @@ struct AudioFrame {
_ALWAYS_INLINE_ AudioFrame() {}
};
-#endif
+#endif // AUDIO_FRAME_H
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index ddf5f13d55..0f519a20d8 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -77,10 +77,6 @@ void Basis::invert() {
void Basis::orthonormalize() {
-#ifdef MATH_CHECKS
- ERR_FAIL_COND(determinant() == 0);
-#endif
-
// Gram-Schmidt Process
Vector3 x = get_axis(0);
@@ -244,6 +240,18 @@ void Basis::scale_local(const Vector3 &p_scale) {
*this = scaled_local(p_scale);
}
+float Basis::get_uniform_scale() const {
+ return (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0;
+}
+
+void Basis::make_scale_uniform() {
+ float l = (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0;
+ for (int i = 0; i < 3; i++) {
+ elements[i].normalize();
+ elements[i] *= l;
+ }
+}
+
Basis Basis::scaled_local(const Vector3 &p_scale) const {
Basis b;
b.set_diagonal(p_scale);
diff --git a/core/math/basis.h b/core/math/basis.h
index 6c3a939d70..0261cf67c6 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -108,6 +108,9 @@ public:
void scale_local(const Vector3 &p_scale);
Basis scaled_local(const Vector3 &p_scale) const;
+ void make_scale_uniform();
+ float get_uniform_scale() const;
+
Vector3 get_scale() const;
Vector3 get_scale_abs() const;
Vector3 get_scale_local() const;
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
deleted file mode 100644
index 7ad907db97..0000000000
--- a/core/math/bsp_tree.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/*************************************************************************/
-/* bsp_tree.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 "bsp_tree.h"
-
-#include "core/error_macros.h"
-#include "core/print_string.h"
-
-void BSP_Tree::from_aabb(const AABB &p_aabb) {
-
- planes.clear();
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 n;
- n[i] = 1;
- planes.push_back(Plane(n, p_aabb.position[i] + p_aabb.size[i]));
- planes.push_back(Plane(-n, -p_aabb.position[i]));
- }
-
- nodes.clear();
-
- for (int i = 0; i < 6; i++) {
-
- Node n;
- n.plane = i;
- n.under = (i == 0) ? UNDER_LEAF : i - 1;
- n.over = OVER_LEAF;
- nodes.push_back(n);
- }
-
- aabb = p_aabb;
- error_radius = 0;
-}
-
-Vector<BSP_Tree::Node> BSP_Tree::get_nodes() const {
-
- return nodes;
-}
-Vector<Plane> BSP_Tree::get_planes() const {
-
- return planes;
-}
-
-AABB BSP_Tree::get_aabb() const {
-
- return aabb;
-}
-
-int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_indices, const Vector3 &p_center, const Vector3 &p_half_extents, int p_indices_count) const {
-
- const Node *node = &nodes[p_node];
- const Plane &p = planes[node->plane];
-
- Vector3 min(
- (p.normal.x > 0) ? -p_half_extents.x : p_half_extents.x,
- (p.normal.y > 0) ? -p_half_extents.y : p_half_extents.y,
- (p.normal.z > 0) ? -p_half_extents.z : p_half_extents.z);
- Vector3 max = -min;
- max += p_center;
- min += p_center;
-
- real_t dist_min = p.distance_to(min);
- real_t dist_max = p.distance_to(max);
-
- if ((dist_min * dist_max) < CMP_EPSILON) { //intersection, test point by point
-
- int under_count = 0;
-
- //sort points, so the are under first, over last
- for (int i = 0; i < p_indices_count; i++) {
-
- int index = p_indices[i];
-
- if (p.is_point_over(p_points[index])) {
-
- // kind of slow (but cache friendly), should try something else,
- // but this is a corner case most of the time
-
- for (int j = index; j < p_indices_count - 1; j++)
- p_indices[j] = p_indices[j + 1];
-
- p_indices[p_indices_count - 1] = index;
-
- } else {
- under_count++;
- }
- }
-
- int total = 0;
-
- if (under_count > 0) {
- if (node->under == UNDER_LEAF) {
- total += under_count;
- } else {
- total += _get_points_inside(node->under, p_points, p_indices, p_center, p_half_extents, under_count);
- }
- }
-
- if (under_count != p_indices_count) {
- if (node->over == OVER_LEAF) {
- //total+=0 //if they are over an OVER_LEAF, they are outside the model
- } else {
- total += _get_points_inside(node->over, p_points, &p_indices[under_count], p_center, p_half_extents, p_indices_count - under_count);
- }
- }
-
- return total;
-
- } else if (dist_min > 0) { //all points over plane
-
- if (node->over == OVER_LEAF) {
-
- return 0; // all these points are not visible
- }
-
- return _get_points_inside(node->over, p_points, p_indices, p_center, p_half_extents, p_indices_count);
- } else { //all points behind plane
-
- if (node->under == UNDER_LEAF) {
-
- return p_indices_count; // all these points are visible
- }
- return _get_points_inside(node->under, p_points, p_indices, p_center, p_half_extents, p_indices_count);
- }
-}
-
-int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) const {
-
- if (nodes.size() == 0)
- return 0;
-
-#if 1
- //this version is easier to debug, and and MUCH faster in real world cases
-
- int pass_count = 0;
- const Node *nodesptr = &nodes[0];
- const Plane *planesptr = &planes[0];
- int node_count = nodes.size();
-
- if (node_count == 0) // no nodes!
- return 0;
-
- for (int i = 0; i < p_point_count; i++) {
-
- const Vector3 &point = p_points[i];
- if (!aabb.has_point(point)) {
- continue;
- }
-
- int idx = node_count - 1;
-
- bool pass = false;
-
- while (true) {
-
- if (idx == OVER_LEAF) {
- pass = false;
- break;
- } else if (idx == UNDER_LEAF) {
- pass = true;
- break;
- }
-
-#ifdef DEBUG_ENABLED
- int plane_count = planes.size();
- uint16_t plane = nodesptr[idx].plane;
- ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, 0);
-#endif
-
- idx = planesptr[nodesptr[idx].plane].is_point_over(point) ? nodes[idx].over : nodes[idx].under;
-
-#ifdef DEBUG_ENABLED
-
- ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, 0);
-#endif
- }
-
- if (pass)
- pass_count++;
- }
-
- return pass_count;
-
-#else
- //this version scales better but it's slower for real world cases
-
- int *indices = (int *)alloca(p_point_count * sizeof(int));
- AABB bounds;
-
- for (int i = 0; i < p_point_count; i++) {
-
- indices[i] = i;
- if (i == 0)
- bounds.pos = p_points[i];
- else
- bounds.expand_to(p_points[i]);
- }
-
- Vector3 half_extents = bounds.size / 2.0;
- return _get_points_inside(nodes.size() + 1, p_points, indices, bounds.pos + half_extents, half_extents, p_point_count);
-#endif
-}
-
-bool BSP_Tree::point_is_inside(const Vector3 &p_point) const {
-
- if (!aabb.has_point(p_point)) {
- return false;
- }
-
- int node_count = nodes.size();
-
- if (node_count == 0) // no nodes!
- return false;
-
- const Node *nodesptr = &nodes[0];
- const Plane *planesptr = &planes[0];
-
- int idx = node_count - 1;
-
- while (true) {
-
- if (idx == OVER_LEAF) {
- return false;
- }
- if (idx == UNDER_LEAF) {
-
- return true;
- }
-
-#ifdef DEBUG_ENABLED
- int plane_count = planes.size();
- uint16_t plane = nodesptr[idx].plane;
- ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false);
-#endif
-
- bool over = planesptr[nodesptr[idx].plane].is_point_over(p_point);
-
- idx = over ? nodes[idx].over : nodes[idx].under;
-
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, false);
-#endif
- }
-}
-
-static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector<int> &p_indices, real_t p_tolerance) {
-
- int ic = p_indices.size();
- const int *indices = p_indices.ptr();
-
- int best_plane = -1;
- real_t best_plane_cost = 1e20;
-
- // Loop to find the polygon that best divides the set.
-
- for (int i = 0; i < ic; i++) {
-
- const Face3 &f = p_faces[indices[i]];
- Plane p = f.get_plane();
-
- int num_over = 0, num_under = 0, num_spanning = 0;
-
- for (int j = 0; j < ic; j++) {
-
- if (i == j)
- continue;
-
- const Face3 &g = p_faces[indices[j]];
- int over = 0, under = 0;
-
- for (int k = 0; k < 3; k++) {
-
- real_t d = p.distance_to(g.vertex[j]);
-
- if (Math::abs(d) > p_tolerance) {
-
- if (d > 0)
- over++;
- else
- under++;
- }
- }
-
- if (over && under)
- num_spanning++;
- else if (over)
- num_over++;
- else
- num_under++;
- }
-
- //real_t split_cost = num_spanning / (real_t) face_count;
- real_t relation = Math::abs(num_over - num_under) / (real_t)ic;
-
- // being honest, i never found a way to add split cost to the mix in a meaninguful way
- // in this engine, also, will likely be ignored anyway
-
- real_t plane_cost = /*split_cost +*/ relation;
-
- //printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost);
- if (plane_cost < best_plane_cost) {
-
- best_plane = i;
- best_plane_cost = plane_cost;
- }
- }
-
- return best_plane;
-}
-
-static int _bsp_create_node(const Face3 *p_faces, const Vector<int> &p_indices, Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes, real_t p_tolerance) {
-
- ERR_FAIL_COND_V(p_nodes.size() == BSP_Tree::MAX_NODES, -1);
-
- // should not reach here
- ERR_FAIL_COND_V(p_indices.size() == 0, -1);
-
- int ic = p_indices.size();
- const int *indices = p_indices.ptr();
-
- int divisor_idx = _bsp_find_best_half_plane(p_faces, p_indices, p_tolerance);
-
- // returned error
- ERR_FAIL_COND_V(divisor_idx < 0, -1);
-
- Vector<int> faces_over;
- Vector<int> faces_under;
-
- Plane divisor_plane = p_faces[indices[divisor_idx]].get_plane();
-
- for (int i = 0; i < ic; i++) {
-
- if (i == divisor_idx)
- continue;
-
- const Face3 &f = p_faces[indices[i]];
-
- /*
- if (f.get_plane().is_equal_approx(divisor_plane))
- continue;
- */
-
- int over_count = 0;
- int under_count = 0;
-
- for (int j = 0; j < 3; j++) {
-
- real_t d = divisor_plane.distance_to(f.vertex[j]);
- if (Math::abs(d) > p_tolerance) {
-
- if (d > 0)
- over_count++;
- else
- under_count++;
- }
- }
-
- if (over_count)
- faces_over.push_back(indices[i]);
- if (under_count)
- faces_under.push_back(indices[i]);
- }
-
- uint16_t over_idx = BSP_Tree::OVER_LEAF, under_idx = BSP_Tree::UNDER_LEAF;
-
- if (faces_over.size() > 0) { //have facess above?
-
- int idx = _bsp_create_node(p_faces, faces_over, p_planes, p_nodes, p_tolerance);
- if (idx >= 0)
- over_idx = idx;
- }
-
- if (faces_under.size() > 0) { //have facess above?
-
- int idx = _bsp_create_node(p_faces, faces_under, p_planes, p_nodes, p_tolerance);
- if (idx >= 0)
- under_idx = idx;
- }
-
- /* Create the node */
-
- // find existing divisor plane
- int divisor_plane_idx = -1;
-
- for (int i = 0; i < p_planes.size(); i++) {
-
- if (p_planes[i].is_equal_approx(divisor_plane)) {
- divisor_plane_idx = i;
- break;
- }
- }
-
- if (divisor_plane_idx == -1) {
-
- ERR_FAIL_COND_V(p_planes.size() == BSP_Tree::MAX_PLANES, -1);
- divisor_plane_idx = p_planes.size();
- p_planes.push_back(divisor_plane);
- }
-
- BSP_Tree::Node node;
- node.plane = divisor_plane_idx;
- node.under = under_idx;
- node.over = over_idx;
-
- p_nodes.push_back(node);
-
- return p_nodes.size() - 1;
-}
-
-BSP_Tree::operator Variant() const {
-
- Dictionary d;
- d["error_radius"] = error_radius;
-
- Vector<real_t> plane_values;
- plane_values.resize(planes.size() * 4);
-
- for (int i = 0; i < planes.size(); i++) {
-
- plane_values.write[i * 4 + 0] = planes[i].normal.x;
- plane_values.write[i * 4 + 1] = planes[i].normal.y;
- plane_values.write[i * 4 + 2] = planes[i].normal.z;
- plane_values.write[i * 4 + 3] = planes[i].d;
- }
-
- d["planes"] = plane_values;
-
- PoolVector<int> dst_nodes;
- dst_nodes.resize(nodes.size() * 3);
-
- for (int i = 0; i < nodes.size(); i++) {
-
- dst_nodes.set(i * 3 + 0, nodes[i].over);
- dst_nodes.set(i * 3 + 1, nodes[i].under);
- dst_nodes.set(i * 3 + 2, nodes[i].plane);
- }
-
- d["nodes"] = dst_nodes;
- d["aabb"] = aabb;
-
- return Variant(d);
-}
-
-BSP_Tree::BSP_Tree() {
-}
-
-BSP_Tree::BSP_Tree(const Variant &p_variant) {
-
- Dictionary d = p_variant;
- ERR_FAIL_COND(!d.has("nodes"));
- ERR_FAIL_COND(!d.has("planes"));
- ERR_FAIL_COND(!d.has("aabb"));
- ERR_FAIL_COND(!d.has("error_radius"));
-
- PoolVector<int> src_nodes = d["nodes"];
- ERR_FAIL_COND(src_nodes.size() % 3);
-
- if (d["planes"].get_type() == Variant::POOL_REAL_ARRAY) {
-
- PoolVector<real_t> src_planes = d["planes"];
- int plane_count = src_planes.size();
- ERR_FAIL_COND(plane_count % 4);
- planes.resize(plane_count / 4);
-
- if (plane_count) {
- PoolVector<real_t>::Read r = src_planes.read();
- for (int i = 0; i < plane_count / 4; i++) {
-
- planes.write[i].normal.x = r[i * 4 + 0];
- planes.write[i].normal.y = r[i * 4 + 1];
- planes.write[i].normal.z = r[i * 4 + 2];
- planes.write[i].d = r[i * 4 + 3];
- }
- }
-
- } else {
-
- planes = d["planes"];
- }
-
- error_radius = d["error"];
- aabb = d["aabb"];
-
- //int node_count = src_nodes.size();
- nodes.resize(src_nodes.size() / 3);
-
- PoolVector<int>::Read r = src_nodes.read();
-
- for (int i = 0; i < nodes.size(); i++) {
-
- nodes.write[i].over = r[i * 3 + 0];
- nodes.write[i].under = r[i * 3 + 1];
- nodes.write[i].plane = r[i * 3 + 2];
- }
-}
-
-BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) {
-
- // compute aabb
-
- int face_count = p_faces.size();
- PoolVector<Face3>::Read faces_r = p_faces.read();
- const Face3 *facesptr = faces_r.ptr();
-
- bool first = true;
-
- Vector<int> indices;
-
- for (int i = 0; i < face_count; i++) {
-
- const Face3 &f = facesptr[i];
-
- if (f.is_degenerate())
- continue;
-
- for (int j = 0; j < 3; j++) {
-
- if (first) {
-
- aabb.position = f.vertex[0];
- first = false;
- } else {
-
- aabb.expand_to(f.vertex[j]);
- }
- }
-
- indices.push_back(i);
- }
-
- ERR_FAIL_COND(aabb.has_no_area());
-
- int top = _bsp_create_node(faces_r.ptr(), indices, planes, nodes, aabb.get_longest_axis_size() * 0.0001);
-
- if (top < 0) {
-
- nodes.clear();
- planes.clear();
- ERR_FAIL_COND(top < 0);
- }
-
- error_radius = p_error_radius;
-}
-
-BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius) :
- nodes(p_nodes),
- planes(p_planes),
- aabb(p_aabb),
- error_radius(p_error_radius) {
-}
-
-BSP_Tree::~BSP_Tree() {
-}
diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h
deleted file mode 100644
index 1c8ea380ff..0000000000
--- a/core/math/bsp_tree.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*************************************************************************/
-/* bsp_tree.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 BSP_TREE_H
-#define BSP_TREE_H
-
-#include "core/math/aabb.h"
-#include "core/math/face3.h"
-#include "core/math/plane.h"
-#include "core/method_ptrcall.h"
-#include "core/pool_vector.h"
-#include "core/variant.h"
-#include "core/vector.h"
-
-class BSP_Tree {
-public:
- enum {
-
- UNDER_LEAF = 0xFFFF,
- OVER_LEAF = 0xFFFE,
- MAX_NODES = 0xFFFE,
- MAX_PLANES = (1 << 16)
- };
-
- struct Node {
-
- uint16_t plane;
- uint16_t under;
- uint16_t over;
- };
-
-private:
- // thanks to the properties of Vector,
- // this class can be assigned and passed around between threads
- // with no cost.
-
- Vector<Node> nodes;
- Vector<Plane> planes;
- AABB aabb;
- real_t error_radius;
-
- int _get_points_inside(int p_node, const Vector3 *p_points, int *p_indices, const Vector3 &p_center, const Vector3 &p_half_extents, int p_indices_count) const;
-
- template <class T>
- bool _test_convex(const Node *p_nodes, const Plane *p_planes, int p_current, const T &p_convex) const;
-
-public:
- bool is_empty() const { return nodes.size() == 0; }
- Vector<Node> get_nodes() const;
- Vector<Plane> get_planes() const;
- AABB get_aabb() const;
-
- bool point_is_inside(const Vector3 &p_point) const;
- int get_points_inside(const Vector3 *p_points, int p_point_count) const;
- template <class T>
- bool convex_is_inside(const T &p_convex) const;
-
- operator Variant() const;
-
- void from_aabb(const AABB &p_aabb);
-
- BSP_Tree();
- BSP_Tree(const Variant &p_variant);
- BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius = 0);
- BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius = 0);
- ~BSP_Tree();
-};
-
-template <class T>
-bool BSP_Tree::_test_convex(const Node *p_nodes, const Plane *p_planes, int p_current, const T &p_convex) const {
-
- if (p_current == UNDER_LEAF)
- return true;
- else if (p_current == OVER_LEAF)
- return false;
-
- bool collided = false;
- const Node &n = p_nodes[p_current];
-
- const Plane &p = p_planes[n.plane];
-
- real_t min, max;
- p_convex.project_range(p.normal, min, max);
-
- bool go_under = min < p.d;
- bool go_over = max >= p.d;
-
- if (go_under && _test_convex(p_nodes, p_planes, n.under, p_convex))
- collided = true;
- if (go_over && _test_convex(p_nodes, p_planes, n.over, p_convex))
- collided = true;
-
- return collided;
-}
-
-template <class T>
-bool BSP_Tree::convex_is_inside(const T &p_convex) const {
-
- int node_count = nodes.size();
- if (node_count == 0)
- return false;
- const Node *nodes = &this->nodes[0];
- const Plane *planes = &this->planes[0];
-
- return _test_convex(nodes, planes, node_count - 1, p_convex);
-}
-
-#ifdef PTRCALL_ENABLED
-
-template <>
-struct PtrToArg<BSP_Tree> {
- _FORCE_INLINE_ static BSP_Tree convert(const void *p_ptr) {
- BSP_Tree s(Variant(*reinterpret_cast<const Dictionary *>(p_ptr)));
- return s;
- }
- _FORCE_INLINE_ static void encode(BSP_Tree p_val, void *p_ptr) {
- Dictionary *d = reinterpret_cast<Dictionary *>(p_ptr);
- *d = Variant(p_val);
- }
-};
-
-template <>
-struct PtrToArg<const BSP_Tree &> {
- _FORCE_INLINE_ static BSP_Tree convert(const void *p_ptr) {
- BSP_Tree s(Variant(*reinterpret_cast<const Dictionary *>(p_ptr)));
- return s;
- }
-};
-
-#endif
-
-#endif
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 380bae871a..c36070e47f 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -145,7 +145,7 @@ void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_
f3 *= p_oversample;
// always apply KEEP_WIDTH aspect ratio
- f3 *= p_aspect;
+ f3 /= p_aspect;
switch (p_eye) {
case 1: { // left eye
@@ -276,6 +276,36 @@ Vector2 CameraMatrix::get_viewport_half_extents() const {
return Vector2(res.x, res.y);
}
+void CameraMatrix::get_far_plane_size(real_t &r_width, real_t &r_height) const {
+
+ const real_t *matrix = (const real_t *)this->matrix;
+ ///////--- Far Plane ---///////
+ Plane far_plane = Plane(matrix[3] - matrix[2],
+ matrix[7] - matrix[6],
+ matrix[11] - matrix[10],
+ -matrix[15] + matrix[14]);
+ far_plane.normalize();
+
+ ///////--- Right Plane ---///////
+ Plane right_plane = Plane(matrix[3] - matrix[0],
+ matrix[7] - matrix[4],
+ matrix[11] - matrix[8],
+ -matrix[15] + matrix[12]);
+ right_plane.normalize();
+
+ Plane top_plane = Plane(matrix[3] - matrix[1],
+ matrix[7] - matrix[5],
+ matrix[11] - matrix[9],
+ -matrix[15] + matrix[13]);
+ top_plane.normalize();
+
+ Vector3 res;
+ far_plane.intersect_3(right_plane, top_plane, &res);
+
+ r_width = res.x;
+ r_height = res.y;
+}
+
bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const {
Vector<Plane> planes = get_projection_planes(Transform());
@@ -485,6 +515,12 @@ void CameraMatrix::invert() {
}
}
+void CameraMatrix::flip_y() {
+ for (int i = 0; i < 4; i++) {
+ matrix[1][i] = -matrix[1][i];
+ }
+}
+
CameraMatrix::CameraMatrix() {
set_identity();
@@ -506,6 +542,28 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const {
return new_matrix;
}
+void CameraMatrix::set_depth_correction(bool p_flip_y) {
+
+ real_t *m = &matrix[0][0];
+
+ m[0] = 1;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+ m[4] = 0.0;
+ m[5] = p_flip_y ? -1 : 1;
+ m[6] = 0.0;
+ m[7] = 0.0;
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = 0.5;
+ m[11] = 0.0;
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = 0.5;
+ m[15] = 1.0;
+}
+
void CameraMatrix::set_light_bias() {
real_t *m = &matrix[0][0];
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index 2eed6d25d6..c10193bc84 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -50,6 +50,7 @@ struct CameraMatrix {
void set_identity();
void set_zero();
void set_light_bias();
+ void set_depth_correction(bool p_flip_y = true);
void set_light_atlas_rect(const Rect2 &p_rect);
void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov = false);
void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist);
@@ -74,6 +75,7 @@ struct CameraMatrix {
bool get_endpoints(const Transform &p_transform, Vector3 *p_8points) const;
Vector2 get_viewport_half_extents() const;
+ void get_far_plane_size(real_t &r_width, real_t &r_height) const;
void invert();
CameraMatrix inverse() const;
@@ -90,6 +92,23 @@ struct CameraMatrix {
int get_pixels_per_meter(int p_for_pixel_width) const;
operator Transform() const;
+ void flip_y();
+
+ bool operator==(const CameraMatrix &p_cam) const {
+ for (uint32_t i = 0; i < 4; i++) {
+ for (uint32_t j = 0; j < 4; j++) {
+ if (matrix[i][j] != p_cam.matrix[i][j]) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ bool operator!=(const CameraMatrix &p_cam) const {
+ return !(*this == p_cam);
+ }
+
CameraMatrix();
CameraMatrix(const Transform &p_transform);
~CameraMatrix();
@@ -105,4 +124,4 @@ Vector3 CameraMatrix::xform(const Vector3 &p_vec3) const {
return ret / w;
}
-#endif
+#endif // CAMERA_MATRIX_H
diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h
index fb89941ce4..32b9875e4c 100644
--- a/core/math/disjoint_set.h
+++ b/core/math/disjoint_set.h
@@ -152,4 +152,4 @@ void DisjointSet<T, C, AL>::get_members(Vector<T> &out_members, T representative
}
}
-#endif
+#endif // DISJOINT_SET_H
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 655098376c..859b9be8c5 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -64,7 +64,6 @@ const char *Expression::func_name[Expression::FUNC_MAX] = {
"is_nan",
"is_inf",
"ease",
- "decimals",
"step_decimals",
"stepify",
"lerp",
@@ -153,7 +152,6 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) {
case MATH_EXP:
case MATH_ISNAN:
case MATH_ISINF:
- case MATH_DECIMALS:
case MATH_STEP_DECIMALS:
case MATH_SEED:
case MATH_RANDSEED:
@@ -210,16 +208,16 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) {
return 0;
}
-#define VALIDATE_ARG_NUM(m_arg) \
- if (!p_inputs[m_arg]->is_num()) { \
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; \
- r_error.argument = m_arg; \
- r_error.expected = Variant::REAL; \
- return; \
+#define VALIDATE_ARG_NUM(m_arg) \
+ if (!p_inputs[m_arg]->is_num()) { \
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \
+ r_error.argument = m_arg; \
+ r_error.expected = Variant::FLOAT; \
+ return; \
}
-void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str) {
- r_error.error = Variant::CallError::CALL_OK;
+void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str) {
+ r_error.error = Callable::CallError::CALL_OK;
switch (p_func) {
case MATH_SIN: {
@@ -316,15 +314,15 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
int64_t i = *p_inputs[0];
*r_return = ABS(i);
- } else if (p_inputs[0]->get_type() == Variant::REAL) {
+ } else if (p_inputs[0]->get_type() == Variant::FLOAT) {
real_t r = *p_inputs[0];
*r_return = Math::abs(r);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::REAL;
+ r_error.expected = Variant::FLOAT;
}
} break;
case MATH_SIGN: {
@@ -333,15 +331,15 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
int64_t i = *p_inputs[0];
*r_return = i < 0 ? -1 : (i > 0 ? +1 : 0);
- } else if (p_inputs[0]->get_type() == Variant::REAL) {
+ } else if (p_inputs[0]->get_type() == Variant::FLOAT) {
real_t r = *p_inputs[0];
*r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::REAL;
+ r_error.expected = Variant::FLOAT;
}
} break;
case MATH_POW: {
@@ -376,11 +374,6 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
VALIDATE_ARG_NUM(1);
*r_return = Math::ease((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
- case MATH_DECIMALS: {
-
- VALIDATE_ARG_NUM(0);
- *r_return = Math::step_decimals((double)*p_inputs[0]);
- } break;
case MATH_STEP_DECIMALS: {
VALIDATE_ARG_NUM(0);
@@ -587,7 +580,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (p_inputs[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -621,7 +614,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (p_inputs[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -629,7 +622,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
}
if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
@@ -651,7 +644,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (type < 0 || type >= Variant::VARIANT_MAX) {
r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::INT;
return;
@@ -682,7 +675,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (p_inputs[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -694,7 +687,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (str.length() != 1) {
r_error_str = RTR("Expected a string of length 1 (a character).");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -739,7 +732,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
case STR_TO_VAR: {
if (p_inputs[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -754,7 +747,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
Error err = VariantParser::parse(&ss, *r_return, errs, line);
if (err != OK) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
*r_return = "Parse error at line " + itos(line) + ": " + errs;
@@ -764,12 +757,12 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case VAR_TO_BYTES: {
- PoolByteArray barr;
+ PackedByteArray barr;
bool full_objects = *p_inputs[1];
int len;
- Error err = encode_variant(*p_inputs[0], NULL, len, full_objects);
+ Error err = encode_variant(*p_inputs[0], nullptr, len, full_objects);
if (err) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::NIL;
r_error_str = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
@@ -778,32 +771,32 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
barr.resize(len);
{
- PoolByteArray::Write w = barr.write();
- encode_variant(*p_inputs[0], w.ptr(), len, full_objects);
+ uint8_t *w = barr.ptrw();
+ encode_variant(*p_inputs[0], w, len, full_objects);
}
*r_return = barr;
} break;
case BYTES_TO_VAR: {
- if (p_inputs[0]->get_type() != Variant::POOL_BYTE_ARRAY) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::POOL_BYTE_ARRAY;
+ r_error.expected = Variant::PACKED_BYTE_ARRAY;
return;
}
- PoolByteArray varr = *p_inputs[0];
+ PackedByteArray varr = *p_inputs[0];
bool allow_objects = *p_inputs[1];
Variant ret;
{
- PoolByteArray::Read r = varr.read();
- Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, allow_objects);
+ const uint8_t *r = varr.ptr();
+ Error err = decode_variant(ret, r, varr.size(), nullptr, allow_objects);
if (err != OK) {
r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::POOL_BYTE_ARRAY;
+ r_error.expected = Variant::PACKED_BYTE_ARRAY;
return;
}
}
@@ -1036,8 +1029,7 @@ Error Expression::_get_token(Token &r_token) {
case 'f': res = 12; break;
case 'r': res = 13; break;
case 'u': {
- //hexnumbarh - oct is deprecated
-
+ // hex number
for (int j = 0; j < 4; j++) {
CharType c = GET_CHAR();
@@ -1062,7 +1054,7 @@ Error Expression::_get_token(Token &r_token) {
v = c - 'A';
v += 10;
} else {
- ERR_PRINT("BUG");
+ ERR_PRINT("Bug parsing hex constant.");
v = 0;
}
@@ -1071,13 +1063,8 @@ Error Expression::_get_token(Token &r_token) {
}
} break;
- //case '\"': res='\"'; break;
- //case '\\': res='\\'; break;
- //case '/': res='/'; break;
default: {
res = next;
- //r_err_str="Invalid escape sequence";
- //return ERR_PARSE_ERROR;
} break;
}
@@ -1174,7 +1161,7 @@ Error Expression::_get_token(Token &r_token) {
if (is_float)
r_token.value = num.to_double();
else
- r_token.value = num.to_int();
+ r_token.value = num.to_int64();
return OK;
} else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
@@ -1311,12 +1298,12 @@ Expression::ENode *Expression::_parse_expression() {
while (true) {
//keep appending stuff to expression
- ENode *expr = NULL;
+ ENode *expr = nullptr;
Token tk;
_get_token(tk);
if (error_set)
- return NULL;
+ return nullptr;
switch (tk.type) {
case TK_CURLY_BRACKET_OPEN: {
@@ -1334,18 +1321,18 @@ Expression::ENode *Expression::_parse_expression() {
//parse an expression
ENode *subexpr = _parse_expression();
if (!subexpr)
- return NULL;
+ return nullptr;
dn->dict.push_back(subexpr);
_get_token(tk);
if (tk.type != TK_COLON) {
_set_error("Expected ':'");
- return NULL;
+ return nullptr;
}
subexpr = _parse_expression();
if (!subexpr)
- return NULL;
+ return nullptr;
dn->dict.push_back(subexpr);
@@ -1378,7 +1365,7 @@ Expression::ENode *Expression::_parse_expression() {
//parse an expression
ENode *subexpr = _parse_expression();
if (!subexpr)
- return NULL;
+ return nullptr;
an->array.push_back(subexpr);
cofs = str_ofs;
@@ -1398,11 +1385,11 @@ Expression::ENode *Expression::_parse_expression() {
//a suexpression
ENode *e = _parse_expression();
if (error_set)
- return NULL;
+ return nullptr;
_get_token(tk);
if (tk.type != TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')'");
- return NULL;
+ return nullptr;
}
expr = e;
@@ -1432,7 +1419,7 @@ Expression::ENode *Expression::_parse_expression() {
//parse an expression
ENode *subexpr = _parse_expression();
if (!subexpr)
- return NULL;
+ return nullptr;
func_call->arguments.push_back(subexpr);
@@ -1497,7 +1484,7 @@ Expression::ENode *Expression::_parse_expression() {
_get_token(tk);
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '('");
- return NULL;
+ return nullptr;
}
ConstructorNode *constructor = alloc_node<ConstructorNode>();
@@ -1514,7 +1501,7 @@ Expression::ENode *Expression::_parse_expression() {
//parse an expression
ENode *subexpr = _parse_expression();
if (!subexpr)
- return NULL;
+ return nullptr;
constructor->arguments.push_back(subexpr);
@@ -1538,7 +1525,7 @@ Expression::ENode *Expression::_parse_expression() {
_get_token(tk);
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '('");
- return NULL;
+ return nullptr;
}
BuiltinFuncNode *bifunc = alloc_node<BuiltinFuncNode>();
@@ -1555,7 +1542,7 @@ Expression::ENode *Expression::_parse_expression() {
//parse an expression
ENode *subexpr = _parse_expression();
if (!subexpr)
- return NULL;
+ return nullptr;
bifunc->arguments.push_back(subexpr);
@@ -1597,7 +1584,7 @@ Expression::ENode *Expression::_parse_expression() {
default: {
_set_error("Expected expression.");
- return NULL;
+ return nullptr;
} break;
}
@@ -1607,7 +1594,7 @@ Expression::ENode *Expression::_parse_expression() {
int cofs2 = str_ofs;
_get_token(tk);
if (error_set)
- return NULL;
+ return nullptr;
bool done = false;
@@ -1620,14 +1607,14 @@ Expression::ENode *Expression::_parse_expression() {
ENode *what = _parse_expression();
if (!what)
- return NULL;
+ return nullptr;
index->index = what;
_get_token(tk);
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']' at end of index.");
- return NULL;
+ return nullptr;
}
expr = index;
@@ -1637,7 +1624,7 @@ Expression::ENode *Expression::_parse_expression() {
_get_token(tk);
if (tk.type != TK_IDENTIFIER) {
_set_error("Expected identifier after '.'");
- return NULL;
+ return nullptr;
}
StringName identifier = tk.value;
@@ -1661,7 +1648,7 @@ Expression::ENode *Expression::_parse_expression() {
//parse an expression
ENode *subexpr = _parse_expression();
if (!subexpr)
- return NULL;
+ return nullptr;
func_call->arguments.push_back(subexpr);
@@ -1711,7 +1698,7 @@ Expression::ENode *Expression::_parse_expression() {
int cofs = str_ofs;
_get_token(tk);
if (error_set)
- return NULL;
+ return nullptr;
Variant::Operator op = Variant::OP_MAX;
@@ -1818,7 +1805,7 @@ Expression::ENode *Expression::_parse_expression() {
default: {
_set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op));
- return NULL;
+ return nullptr;
}
}
@@ -1835,7 +1822,7 @@ Expression::ENode *Expression::_parse_expression() {
if (next_op == -1) {
_set_error("Yet another parser bug....");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
// OK! create operator..
@@ -1848,17 +1835,17 @@ Expression::ENode *Expression::_parse_expression() {
if (expr_pos == expression.size()) {
//can happen..
_set_error("Unexpected end of expression...");
- return NULL;
+ return nullptr;
}
}
- //consecutively do unary opeators
+ //consecutively do unary operators
for (int i = expr_pos - 1; i >= next_op; i--) {
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
op->nodes[0] = expression[i + 1].node;
- op->nodes[1] = NULL;
+ op->nodes[1] = nullptr;
expression.write[i].is_op = false;
expression.write[i].node = op;
expression.remove(i + 1);
@@ -1868,7 +1855,7 @@ Expression::ENode *Expression::_parse_expression() {
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
OperatorNode *op = alloc_node<OperatorNode>();
@@ -1877,7 +1864,7 @@ Expression::ENode *Expression::_parse_expression() {
if (expression[next_op - 1].is_op) {
_set_error("Parser bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
if (expression[next_op + 1].is_op) {
@@ -1887,7 +1874,7 @@ Expression::ENode *Expression::_parse_expression() {
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators.");
- return NULL;
+ return nullptr;
}
op->nodes[0] = expression[next_op - 1].node; //expression goes as left
@@ -1910,8 +1897,8 @@ bool Expression::_compile_expression() {
if (nodes) {
memdelete(nodes);
- nodes = NULL;
- root = NULL;
+ nodes = nullptr;
+ root = nullptr;
}
error_str = String();
@@ -1921,11 +1908,11 @@ bool Expression::_compile_expression() {
root = _parse_expression();
if (error_set) {
- root = NULL;
+ root = nullptr;
if (nodes) {
memdelete(nodes);
}
- nodes = NULL;
+ nodes = nullptr;
return true;
}
@@ -2084,10 +2071,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.write[i] = &arr[i];
}
- Variant::CallError ce;
+ Callable::CallError ce;
r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = vformat(RTR("Invalid arguments to construct '%s'"), Variant::get_type_name(constructor->data_type));
return true;
}
@@ -2112,10 +2099,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.write[i] = &arr[i];
}
- Variant::CallError ce;
+ Callable::CallError ce;
exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = "Builtin Call Failed. " + r_error_str;
return true;
}
@@ -2147,10 +2134,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.write[i] = &arr[i];
}
- Variant::CallError ce;
+ Callable::CallError ce;
r_ret = base.call(call->method, (const Variant **)argp.ptr(), argp.size(), ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = vformat(RTR("On call to '%s':"), String(call->method));
return true;
}
@@ -2164,8 +2151,8 @@ Error Expression::parse(const String &p_expression, const Vector<String> &p_inpu
if (nodes) {
memdelete(nodes);
- nodes = NULL;
- root = NULL;
+ nodes = nullptr;
+ root = nullptr;
}
error_str = String();
@@ -2177,11 +2164,11 @@ Error Expression::parse(const String &p_expression, const Vector<String> &p_inpu
root = _parse_expression();
if (error_set) {
- root = NULL;
+ root = nullptr;
if (nodes) {
memdelete(nodes);
}
- nodes = NULL;
+ nodes = nullptr;
return ERR_INVALID_PARAMETER;
}
@@ -2225,9 +2212,11 @@ Expression::Expression() :
output_type(Variant::NIL),
sequenced(false),
error_set(true),
- root(NULL),
- nodes(NULL),
+ root(nullptr),
+ nodes(nullptr),
execution_error(false) {
+ str_ofs = 0;
+ expression_dirty = false;
}
Expression::~Expression() {
diff --git a/core/math/expression.h b/core/math/expression.h
index c5b9d79a16..78de225ebf 100644
--- a/core/math/expression.h
+++ b/core/math/expression.h
@@ -63,7 +63,6 @@ public:
MATH_ISNAN,
MATH_ISINF,
MATH_EASE,
- MATH_DECIMALS,
MATH_STEP_DECIMALS,
MATH_STEPIFY,
MATH_LERP,
@@ -112,7 +111,7 @@ public:
static int get_func_argument_count(BuiltinFunc p_func);
static String get_func_name(BuiltinFunc p_func);
- static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str);
+ static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str);
static BuiltinFunc find_function(const String &p_string);
private:
@@ -220,7 +219,7 @@ private:
Type type;
- ENode() { next = NULL; }
+ ENode() { next = nullptr; }
virtual ~ENode() {
if (next) {
memdelete(next);
@@ -353,7 +352,7 @@ protected:
public:
Error parse(const String &p_expression, const Vector<String> &p_input_names = Vector<String>());
- Variant execute(Array p_inputs, Object *p_base = NULL, bool p_show_error = true);
+ Variant execute(Array p_inputs, Object *p_base = nullptr, bool p_show_error = true);
bool has_execute_failed() const;
String get_error_text() const;
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 7eb48290a8..3e07e9253e 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -214,23 +214,19 @@ static bool _group_face(_FaceClassify *p_faces, int len, int p_index, int p_grou
return true;
}
-PoolVector<PoolVector<Face3> > Geometry::separate_objects(PoolVector<Face3> p_array) {
+Vector<Vector<Face3>> Geometry::separate_objects(Vector<Face3> p_array) {
- PoolVector<PoolVector<Face3> > objects;
+ Vector<Vector<Face3>> objects;
int len = p_array.size();
- PoolVector<Face3>::Read r = p_array.read();
+ const Face3 *arrayptr = p_array.ptr();
- const Face3 *arrayptr = r.ptr();
-
- PoolVector<_FaceClassify> fc;
+ Vector<_FaceClassify> fc;
fc.resize(len);
- PoolVector<_FaceClassify>::Write fcw = fc.write();
-
- _FaceClassify *_fcptr = fcw.ptr();
+ _FaceClassify *_fcptr = fc.ptrw();
for (int i = 0; i < len; i++) {
@@ -239,7 +235,7 @@ PoolVector<PoolVector<Face3> > Geometry::separate_objects(PoolVector<Face3> p_ar
bool error = _connect_faces(_fcptr, len, -1);
- ERR_FAIL_COND_V_MSG(error, PoolVector<PoolVector<Face3> >(), "Invalid geometry.");
+ ERR_FAIL_COND_V_MSG(error, Vector<Vector<Face3>>(), "Invalid geometry.");
// Group connected faces in separate objects.
@@ -263,8 +259,7 @@ PoolVector<PoolVector<Face3> > Geometry::separate_objects(PoolVector<Face3> p_ar
if (group >= 0) {
objects.resize(group);
- PoolVector<PoolVector<Face3> >::Write obw = objects.write();
- PoolVector<Face3> *group_faces = obw.ptr();
+ Vector<Face3> *group_faces = objects.ptrw();
for (int i = 0; i < len; i++) {
if (!_fcptr[i].valid)
@@ -470,7 +465,7 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
}
}
-static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, PoolVector<Face3> &p_faces) {
+static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, Vector<Face3> &p_faces) {
ERR_FAIL_INDEX(x, len_x);
ERR_FAIL_INDEX(y, len_y);
@@ -530,14 +525,13 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
}
}
-PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_error) {
+Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
#define _MIN_SIZE 1.0
#define _MAX_LENGTH 20
int face_count = p_array.size();
- PoolVector<Face3>::Read facesr = p_array.read();
- const Face3 *faces = facesr.ptr();
+ const Face3 *faces = p_array.ptr();
AABB global_aabb;
@@ -638,7 +632,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
// Build faces for the inside-outside cell divisors.
- PoolVector<Face3> wrapped_faces;
+ Vector<Face3> wrapped_faces;
for (int i = 0; i < div_x; i++) {
@@ -654,8 +648,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
// Transform face vertices to global coords.
int wrapped_faces_count = wrapped_faces.size();
- PoolVector<Face3>::Write wrapped_facesw = wrapped_faces.write();
- Face3 *wrapped_faces_ptr = wrapped_facesw.ptr();
+ Face3 *wrapped_faces_ptr = wrapped_faces.ptrw();
for (int i = 0; i < wrapped_faces_count; i++) {
@@ -686,8 +679,8 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
return wrapped_faces;
}
-Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> polygon) {
- Vector<Vector<Vector2> > decomp;
+Vector<Vector<Vector2>> Geometry::decompose_polygon_in_convex(Vector<Point2> polygon) {
+ Vector<Vector<Vector2>> decomp;
List<TriangulatorPoly> in_poly, out_poly;
TriangulatorPoly inp;
@@ -720,7 +713,7 @@ Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> po
return decomp;
}
-Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes) {
+Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
MeshData mesh;
@@ -859,9 +852,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
return mesh;
}
-PoolVector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {
+Vector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
planes.push_back(Plane(Vector3(1, 0, 0), p_extents.x));
planes.push_back(Plane(Vector3(-1, 0, 0), p_extents.x));
@@ -873,9 +866,9 @@ PoolVector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {
return planes;
}
-PoolVector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) {
+Vector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) {
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
for (int i = 0; i < p_sides; i++) {
@@ -895,9 +888,9 @@ PoolVector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_heig
return planes;
}
-PoolVector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis) {
+Vector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis) {
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
Vector3 axis;
axis[p_axis] = 1.0;
@@ -928,9 +921,9 @@ PoolVector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int
return planes;
}
-PoolVector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
+Vector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
Vector3 axis;
axis[p_axis] = 1.0;
@@ -1083,7 +1076,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
r_size = Size2(results[best].max_w, results[best].max_h);
}
-Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open) {
+Vector<Vector<Point2>> Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open) {
using namespace ClipperLib;
@@ -1118,7 +1111,7 @@ Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p
clp.Execute(op, paths); // Works on closed polygons only.
}
// Have to scale points down now.
- Vector<Vector<Point2> > polypaths;
+ Vector<Vector<Point2>> polypaths;
for (Paths::size_type i = 0; i < paths.size(); ++i) {
Vector<Vector2> polypath;
@@ -1135,7 +1128,7 @@ Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p
return polypaths;
}
-Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
+Vector<Vector<Point2>> Geometry::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
using namespace ClipperLib;
@@ -1169,7 +1162,7 @@ Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polyp
co.Execute(paths, p_delta * SCALE_FACTOR); // Inflate/deflate.
// Have to scale points down now.
- Vector<Vector<Point2> > polypaths;
+ Vector<Vector<Point2>> polypaths;
for (Paths::size_type i = 0; i < paths.size(); ++i) {
Vector<Vector2> polypath;
diff --git a/core/math/geometry.h b/core/math/geometry.h
index b9193242bc..e47d18b056 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -37,7 +37,7 @@
#include "core/math/triangulate.h"
#include "core/math/vector3.h"
#include "core/object.h"
-#include "core/pool_vector.h"
+
#include "core/print_string.h"
#include "core/vector.h"
@@ -790,44 +790,44 @@ public:
END_ROUND
};
- static Vector<Vector<Point2> > merge_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
+ static Vector<Vector<Point2>> merge_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
return _polypaths_do_operation(OPERATION_UNION, p_polygon_a, p_polygon_b);
}
- static Vector<Vector<Point2> > clip_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
+ static Vector<Vector<Point2>> clip_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polygon_a, p_polygon_b);
}
- static Vector<Vector<Point2> > intersect_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
+ static Vector<Vector<Point2>> intersect_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
return _polypaths_do_operation(OPERATION_INTERSECTION, p_polygon_a, p_polygon_b);
}
- static Vector<Vector<Point2> > exclude_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
+ static Vector<Vector<Point2>> exclude_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
return _polypaths_do_operation(OPERATION_XOR, p_polygon_a, p_polygon_b);
}
- static Vector<Vector<Point2> > clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
+ static Vector<Vector<Point2>> clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polyline, p_polygon, true);
}
- static Vector<Vector<Point2> > intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
+ static Vector<Vector<Point2>> intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
return _polypaths_do_operation(OPERATION_INTERSECTION, p_polyline, p_polygon, true);
}
- static Vector<Vector<Point2> > offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) {
+ static Vector<Vector<Point2>> offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) {
return _polypath_offset(p_polygon, p_delta, p_join_type, END_POLYGON);
}
- static Vector<Vector<Point2> > offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
+ 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_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).");
+ 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);
}
@@ -891,7 +891,7 @@ public:
for (int i = 0; i < c; i++) {
const Vector2 &v1 = p[i];
const Vector2 &v2 = p[(i + 1) % c];
- if (segment_intersects_segment_2d(v1, v2, p_point, further_away, NULL)) {
+ if (segment_intersects_segment_2d(v1, v2, p_point, further_away, nullptr)) {
intersections++;
}
}
@@ -899,10 +899,10 @@ public:
return (intersections & 1);
}
- static PoolVector<PoolVector<Face3> > separate_objects(PoolVector<Face3> p_array);
+ static Vector<Vector<Face3>> separate_objects(Vector<Face3> p_array);
// Create a "wrap" that encloses the given geometry.
- static PoolVector<Face3> wrap_geometry(PoolVector<Face3> p_array, real_t *p_error = NULL);
+ static Vector<Face3> wrap_geometry(Vector<Face3> p_array, real_t *p_error = nullptr);
struct MeshData {
@@ -1004,19 +1004,19 @@ public:
H.resize(k);
return H;
}
- static Vector<Vector<Vector2> > decompose_polygon_in_convex(Vector<Point2> polygon);
+ static Vector<Vector<Vector2>> decompose_polygon_in_convex(Vector<Point2> polygon);
- static MeshData build_convex_mesh(const PoolVector<Plane> &p_planes);
- static PoolVector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z);
- static PoolVector<Plane> build_box_planes(const Vector3 &p_extents);
- static PoolVector<Plane> build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
- static PoolVector<Plane> build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
+ static MeshData build_convex_mesh(const Vector<Plane> &p_planes);
+ static Vector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z);
+ static Vector<Plane> build_box_planes(const Vector3 &p_extents);
+ static Vector<Plane> build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
+ static Vector<Plane> build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
static void make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size);
private:
- static Vector<Vector<Point2> > _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
- static Vector<Vector<Point2> > _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
+ static Vector<Vector<Point2>> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
+ static Vector<Vector<Point2>> _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
};
-#endif
+#endif // GEOMETRY_H
diff --git a/core/math/octree.h b/core/math/octree.h
index 5478bdaf77..5225fbecb4 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -119,9 +119,9 @@ private:
children_count = 0;
parent_index = -1;
last_pass = 0;
- parent = NULL;
+ parent = nullptr;
for (int i = 0; i < 8; i++)
- children[i] = NULL;
+ children[i] = nullptr;
}
~Octant() {
@@ -171,7 +171,7 @@ private:
octree = 0;
pairable_mask = 0;
pairable_type = 0;
- common_parent = NULL;
+ common_parent = nullptr;
}
};
@@ -308,19 +308,19 @@ private:
while (root && root->children_count < 2 && !root->elements.size() && !(use_pairs && root->pairable_elements.size())) {
- Octant *new_root = NULL;
+ Octant *new_root = nullptr;
if (root->children_count == 1) {
for (int i = 0; i < 8; i++) {
if (root->children[i]) {
new_root = root->children[i];
- root->children[i] = NULL;
+ root->children[i] = nullptr;
break;
}
}
ERR_FAIL_COND(!new_root);
- new_root->parent = NULL;
+ new_root->parent = nullptr;
new_root->parent_index = -1;
}
@@ -332,7 +332,7 @@ private:
void _insert_element(Element *p_element, Octant *p_octant);
void _ensure_valid_root(const AABB &p_aabb);
- bool _remove_element_from_octant(Element *p_element, Octant *p_octant, Octant *p_limit = NULL);
+ bool _remove_element_from_octant(Element *p_element, Octant *p_octant, Octant *p_limit = nullptr);
void _remove_element(Element *p_element);
void _pair_element(Element *p_element, Octant *p_octant);
void _unpair_element(Element *p_element, Octant *p_octant);
@@ -377,10 +377,10 @@ public:
int get_subindex(OctreeElementID p_id) const;
int cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF);
- int cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF);
- int cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF);
+ int cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
+ int cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
- int cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF);
+ int cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
void set_pair_callback(PairCallback p_callback, void *p_userdata);
void set_unpair_callback(UnpairCallback p_callback, void *p_userdata);
@@ -396,7 +396,7 @@ public:
template <class T, bool use_pairs, class AL>
T *Octree<T, use_pairs, AL>::get(OctreeElementID p_id) const {
const typename ElementMap::Element *E = element_map.find(p_id);
- ERR_FAIL_COND_V(!E, NULL);
+ ERR_FAIL_COND_V(!E, nullptr);
return E->get().userdata;
}
@@ -442,7 +442,7 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
p_element->octant_owners.push_back(owner);
- if (p_element->common_parent == NULL) {
+ if (p_element->common_parent == nullptr) {
p_element->common_parent = p_octant;
p_element->container_aabb = p_octant->aabb;
} else {
@@ -463,7 +463,7 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
} else {
/* not big enough, send it to subitems */
int splits = 0;
- bool candidate = p_element->common_parent == NULL;
+ bool candidate = p_element->common_parent == nullptr;
for (int i = 0; i < 8; i++) {
@@ -552,7 +552,7 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) {
root = memnew_allocator(Octant, AL);
- root->parent = NULL;
+ root->parent = nullptr;
root->parent_index = -1;
root->aabb = base;
@@ -634,11 +634,11 @@ bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, O
if (p_octant == root) { // won't have a parent, just erase
- root = NULL;
+ root = nullptr;
} else {
ERR_FAIL_INDEX_V(p_octant->parent_index, 8, octant_removed);
- parent->children[p_octant->parent_index] = NULL;
+ parent->children[p_octant->parent_index] = nullptr;
parent->children_count--;
}
@@ -852,12 +852,12 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
if (old_has_surf) {
_remove_element(&e); // removing
- e.common_parent = NULL;
+ e.common_parent = nullptr;
e.aabb = AABB();
_optimize();
} else {
_ensure_valid_root(p_aabb); // inserting
- e.common_parent = NULL;
+ e.common_parent = nullptr;
e.aabb = p_aabb;
_insert_element(&e, root);
if (use_pairs)
@@ -884,7 +884,7 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
combined.merge_with(p_aabb);
_ensure_valid_root(combined);
- ERR_FAIL_COND(e.octant_owners.front() == NULL);
+ ERR_FAIL_COND(e.octant_owners.front() == nullptr);
/* FIND COMMON PARENT */
@@ -902,7 +902,7 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
//prepare for reinsert
e.octant_owners.clear();
- e.common_parent = NULL;
+ e.common_parent = nullptr;
e.aabb = p_aabb;
_insert_element(&e, common_parent); // reinsert from this point
@@ -971,7 +971,7 @@ void Octree<T, use_pairs, AL>::set_pairable(OctreeElementID p_id, bool p_pairabl
e.pairable = p_pairable;
e.pairable_type = p_pairable_type;
e.pairable_mask = p_pairable_mask;
- e.common_parent = NULL;
+ e.common_parent = nullptr;
if (!e.aabb.has_no_surface()) {
_ensure_valid_root(e.aabb);
@@ -1364,15 +1364,15 @@ Octree<T, use_pairs, AL>::Octree(real_t p_unit_size) {
last_element_id = 1;
pass = 1;
unit_size = p_unit_size;
- root = NULL;
+ root = nullptr;
octant_count = 0;
pair_count = 0;
- pair_callback = NULL;
- unpair_callback = NULL;
- pair_callback_userdata = NULL;
- unpair_callback_userdata = NULL;
+ pair_callback = nullptr;
+ unpair_callback = nullptr;
+ pair_callback_userdata = nullptr;
+ unpair_callback_userdata = nullptr;
}
-#endif
+#endif // OCTREE_H
diff --git a/core/math/quat.h b/core/math/quat.h
index 11ae03dffb..b3135ad1ca 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -231,4 +231,4 @@ bool Quat::operator!=(const Quat &p_quat) const {
return x != p_quat.x || y != p_quat.y || z != p_quat.z || w != p_quat.w;
}
-#endif
+#endif // QUAT_H
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 63dd18091f..7fbb26c377 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -399,7 +399,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
ERR_CONTINUE(!F);
List<Geometry::MeshData::Face>::Element *O = F->get().left == E ? F->get().right : F->get().left;
ERR_CONTINUE(O == E);
- ERR_CONTINUE(O == NULL);
+ ERR_CONTINUE(O == nullptr);
if (O->get().plane.is_equal_approx(f.plane)) {
//merge and delete edge and contiguous face, while repointing edges (uuugh!)
@@ -440,10 +440,10 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
// remove all edge connections to this face
for (Map<Edge, RetFaceConnect>::Element *G = ret_edges.front(); G; G = G->next()) {
if (G->get().left == O)
- G->get().left = NULL;
+ G->get().left = nullptr;
if (G->get().right == O)
- G->get().right = NULL;
+ G->get().right = nullptr;
}
ret_edges.erase(F); //remove the edge
diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h
index aea9ffad8b..173f919a73 100644
--- a/core/math/quick_hull.h
+++ b/core/math/quick_hull.h
@@ -77,15 +77,15 @@ private:
struct FaceConnect {
List<Face>::Element *left, *right;
FaceConnect() {
- left = NULL;
- right = NULL;
+ left = nullptr;
+ right = nullptr;
}
};
struct RetFaceConnect {
List<Geometry::MeshData::Face>::Element *left, *right;
RetFaceConnect() {
- left = NULL;
- right = NULL;
+ left = nullptr;
+ right = nullptr;
}
};
diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h
index ac65ce3509..8fd5a056fa 100644
--- a/core/math/random_pcg.h
+++ b/core/math/random_pcg.h
@@ -37,10 +37,10 @@
#include "thirdparty/misc/pcg.h"
-#if defined(__GNUC__) || (_llvm_has_builtin(__builtin_clz))
+#if defined(__GNUC__)
#define CLZ32(x) __builtin_clz(x)
#elif defined(_MSC_VER)
-#include "intrin.h"
+#include <intrin.h>
static int __bsr_clz32(uint32_t x) {
unsigned long index;
_BitScanReverse(&index, x);
@@ -50,11 +50,11 @@ static int __bsr_clz32(uint32_t x) {
#else
#endif
-#if defined(__GNUC__) || (_llvm_has_builtin(__builtin_ldexp) && _llvm_has_builtin(__builtin_ldexpf))
+#if defined(__GNUC__)
#define LDEXP(s, e) __builtin_ldexp(s, e)
#define LDEXPF(s, e) __builtin_ldexpf(s, e)
#else
-#include "math.h"
+#include <math.h>
#define LDEXP(s, e) ldexp(s, e)
#define LDEXPF(s, e) ldexp(s, e)
#endif
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 0d2e7eb6e5..30dbfdbbe5 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -47,28 +47,26 @@ struct Rect2 {
real_t get_area() const { return size.width * size.height; }
- inline bool intersects(const Rect2 &p_rect) const {
- if (position.x >= (p_rect.position.x + p_rect.size.width))
- return false;
- if ((position.x + size.width) <= p_rect.position.x)
- return false;
- if (position.y >= (p_rect.position.y + p_rect.size.height))
- return false;
- if ((position.y + size.height) <= p_rect.position.y)
- return false;
-
- return true;
- }
-
- inline bool intersects_touch(const Rect2 &p_rect) const {
- if (position.x > (p_rect.position.x + p_rect.size.width))
- return false;
- if ((position.x + size.width) < p_rect.position.x)
- return false;
- if (position.y > (p_rect.position.y + p_rect.size.height))
- return false;
- if ((position.y + size.height) < p_rect.position.y)
- return false;
+ inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const {
+ if (p_include_borders) {
+ if (position.x > (p_rect.position.x + p_rect.size.width))
+ return false;
+ if ((position.x + size.width) < p_rect.position.x)
+ return false;
+ if (position.y > (p_rect.position.y + p_rect.size.height))
+ return false;
+ if ((position.y + size.height) < p_rect.position.y)
+ return false;
+ } else {
+ if (position.x >= (p_rect.position.x + p_rect.size.width))
+ return false;
+ if ((position.x + size.width) <= p_rect.position.x)
+ return false;
+ if (position.y >= (p_rect.position.y + p_rect.size.height))
+ return false;
+ if ((position.y + size.height) <= p_rect.position.y)
+ return false;
+ }
return true;
}
@@ -107,7 +105,7 @@ struct Rect2 {
bool intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const;
- bool intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos = NULL, Point2 *r_normal = NULL) const;
+ bool intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos = nullptr, Point2 *r_normal = nullptr) const;
inline bool encloses(const Rect2 &p_rect) const {
@@ -387,6 +385,11 @@ struct Rect2i {
size = end - begin;
}
+ _FORCE_INLINE_ Rect2i abs() const {
+
+ return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
+ }
+
operator String() const { return String(position) + ", " + String(size); }
operator Rect2() const { return Rect2(position, size); }
diff --git a/core/math/transform.h b/core/math/transform.h
index ad397d9c09..c6e3be4c70 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -34,7 +34,6 @@
#include "core/math/aabb.h"
#include "core/math/basis.h"
#include "core/math/plane.h"
-#include "core/pool_vector.h"
class Transform {
public:
@@ -84,8 +83,8 @@ public:
_FORCE_INLINE_ AABB xform(const AABB &p_aabb) const;
_FORCE_INLINE_ AABB xform_inv(const AABB &p_aabb) const;
- _FORCE_INLINE_ PoolVector<Vector3> xform(const PoolVector<Vector3> &p_array) const;
- _FORCE_INLINE_ PoolVector<Vector3> xform_inv(const PoolVector<Vector3> &p_array) const;
+ _FORCE_INLINE_ Vector<Vector3> xform(const Vector<Vector3> &p_array) const;
+ _FORCE_INLINE_ Vector<Vector3> xform_inv(const Vector<Vector3> &p_array) const;
void operator*=(const Transform &p_transform);
Transform operator*(const Transform &p_transform) const;
@@ -210,13 +209,13 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const {
return ret;
}
-PoolVector<Vector3> Transform::xform(const PoolVector<Vector3> &p_array) const {
+Vector<Vector3> Transform::xform(const Vector<Vector3> &p_array) const {
- PoolVector<Vector3> array;
+ Vector<Vector3> array;
array.resize(p_array.size());
- PoolVector<Vector3>::Read r = p_array.read();
- PoolVector<Vector3>::Write w = array.write();
+ const Vector3 *r = p_array.ptr();
+ Vector3 *w = array.ptrw();
for (int i = 0; i < p_array.size(); ++i) {
w[i] = xform(r[i]);
@@ -224,13 +223,13 @@ PoolVector<Vector3> Transform::xform(const PoolVector<Vector3> &p_array) const {
return array;
}
-PoolVector<Vector3> Transform::xform_inv(const PoolVector<Vector3> &p_array) const {
+Vector<Vector3> Transform::xform_inv(const Vector<Vector3> &p_array) const {
- PoolVector<Vector3> array;
+ Vector<Vector3> array;
array.resize(p_array.size());
- PoolVector<Vector3>::Read r = p_array.read();
- PoolVector<Vector3>::Write w = array.write();
+ const Vector3 *r = p_array.ptr();
+ Vector3 *w = array.ptrw();
for (int i = 0; i < p_array.size(); ++i) {
w[i] = xform_inv(r[i]);
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 367f697ccf..fa43762aa4 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -32,7 +32,6 @@
#define TRANSFORM_2D_H
#include "core/math/rect2.h" // also includes vector2, math_funcs, and ustring
-#include "core/pool_vector.h"
struct Transform2D {
// Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper":
@@ -112,8 +111,8 @@ struct Transform2D {
_FORCE_INLINE_ Vector2 xform_inv(const Vector2 &p_vec) const;
_FORCE_INLINE_ Rect2 xform(const Rect2 &p_rect) const;
_FORCE_INLINE_ Rect2 xform_inv(const Rect2 &p_rect) const;
- _FORCE_INLINE_ PoolVector<Vector2> xform(const PoolVector<Vector2> &p_array) const;
- _FORCE_INLINE_ PoolVector<Vector2> xform_inv(const PoolVector<Vector2> &p_array) const;
+ _FORCE_INLINE_ Vector<Vector2> xform(const Vector<Vector2> &p_array) const;
+ _FORCE_INLINE_ Vector<Vector2> xform_inv(const Vector<Vector2> &p_array) const;
operator String() const;
@@ -203,13 +202,13 @@ Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const {
return new_rect;
}
-PoolVector<Vector2> Transform2D::xform(const PoolVector<Vector2> &p_array) const {
+Vector<Vector2> Transform2D::xform(const Vector<Vector2> &p_array) const {
- PoolVector<Vector2> array;
+ Vector<Vector2> array;
array.resize(p_array.size());
- PoolVector<Vector2>::Read r = p_array.read();
- PoolVector<Vector2>::Write w = array.write();
+ const Vector2 *r = p_array.ptr();
+ Vector2 *w = array.ptrw();
for (int i = 0; i < p_array.size(); ++i) {
w[i] = xform(r[i]);
@@ -217,13 +216,13 @@ PoolVector<Vector2> Transform2D::xform(const PoolVector<Vector2> &p_array) const
return array;
}
-PoolVector<Vector2> Transform2D::xform_inv(const PoolVector<Vector2> &p_array) const {
+Vector<Vector2> Transform2D::xform_inv(const Vector<Vector2> &p_array) const {
- PoolVector<Vector2> array;
+ Vector<Vector2> array;
array.resize(p_array.size());
- PoolVector<Vector2>::Read r = p_array.read();
- PoolVector<Vector2>::Write w = array.write();
+ const Vector2 *r = p_array.ptr();
+ Vector2 *w = array.ptrw();
for (int i = 0; i < p_array.size(); ++i) {
w[i] = xform_inv(r[i]);
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 53d4ea0a96..01d38cf24e 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -89,7 +89,7 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in
return index;
}
-void TriangleMesh::get_indices(PoolVector<int> *r_triangles_indices) const {
+void TriangleMesh::get_indices(Vector<int> *r_triangles_indices) const {
if (!valid)
return;
@@ -97,10 +97,10 @@ void TriangleMesh::get_indices(PoolVector<int> *r_triangles_indices) const {
const int triangles_num = triangles.size();
// Parse vertices indices
- PoolVector<Triangle>::Read triangles_read = triangles.read();
+ const Triangle *triangles_read = triangles.ptr();
r_triangles_indices->resize(triangles_num * 3);
- PoolVector<int>::Write r_indices_write = r_triangles_indices->write();
+ int *r_indices_write = r_triangles_indices->ptrw();
for (int i = 0; i < triangles_num; ++i) {
r_indices_write[3 * i + 0] = triangles_read[i].indices[0];
@@ -109,7 +109,7 @@ void TriangleMesh::get_indices(PoolVector<int> *r_triangles_indices) const {
}
}
-void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
+void TriangleMesh::create(const Vector<Vector3> &p_faces) {
valid = false;
@@ -119,7 +119,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
triangles.resize(fc);
bvh.resize(fc * 3); //will never be larger than this (todo make better)
- PoolVector<BVH>::Write bw = bvh.write();
+ BVH *bw = bvh.ptrw();
{
@@ -127,8 +127,8 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
//except for the Set for repeated triangles, everything
//goes in-place.
- PoolVector<Vector3>::Read r = p_faces.read();
- PoolVector<Triangle>::Write w = triangles.write();
+ const Vector3 *r = p_faces.ptr();
+ Triangle *w = triangles.ptrw();
Map<Vector3, int> db;
for (int i = 0; i < fc; i++) {
@@ -164,15 +164,15 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
}
vertices.resize(db.size());
- PoolVector<Vector3>::Write vw = vertices.write();
+ Vector3 *vw = vertices.ptrw();
for (Map<Vector3, int>::Element *E = db.front(); E; E = E->next()) {
vw[E->get()] = E->key();
}
}
- PoolVector<BVH *> bwptrs;
+ Vector<BVH *> bwptrs;
bwptrs.resize(fc);
- PoolVector<BVH *>::Write bwp = bwptrs.write();
+ BVH **bwp = bwptrs.ptrw();
for (int i = 0; i < fc; i++) {
bwp[i] = &bw[i];
@@ -180,9 +180,8 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
max_depth = 0;
int max_alloc = fc;
- _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc);
+ _create_bvh(bw, bwp, 0, fc, 1, max_depth, max_alloc);
- bw.release(); //clearup
bvh.resize(max_alloc); //resize back
valid = true;
@@ -208,13 +207,11 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const {
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ // const Vector3 *verticesr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
- const Triangle *triangleptr = trianglesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -304,14 +301,11 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ const Vector3 *vertexptr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
- const Triangle *triangleptr = trianglesr.ptr();
- const Vector3 *vertexptr = verticesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -419,14 +413,11 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ const Vector3 *vertexptr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
- const Triangle *triangleptr = trianglesr.ptr();
- const Vector3 *vertexptr = verticesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -529,14 +520,11 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ const Vector3 *vertexptr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
- const Triangle *triangleptr = trianglesr.ptr();
- const Vector3 *vertexptr = verticesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -645,16 +633,13 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count,
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ const Vector3 *vertexptr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
Transform scale(Basis().scaled(p_scale));
- const Triangle *triangleptr = trianglesr.ptr();
- const Vector3 *vertexptr = verticesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -732,18 +717,18 @@ bool TriangleMesh::is_valid() const {
return valid;
}
-PoolVector<Face3> TriangleMesh::get_faces() const {
+Vector<Face3> TriangleMesh::get_faces() const {
if (!valid)
- return PoolVector<Face3>();
+ return Vector<Face3>();
- PoolVector<Face3> faces;
+ Vector<Face3> faces;
int ts = triangles.size();
faces.resize(triangles.size());
- PoolVector<Face3>::Write w = faces.write();
- PoolVector<Triangle>::Read r = triangles.read();
- PoolVector<Vector3>::Read rv = vertices.read();
+ Face3 *w = faces.ptrw();
+ const Triangle *r = triangles.ptr();
+ const Vector3 *rv = vertices.ptr();
for (int i = 0; i < ts; i++) {
for (int j = 0; j < 3; j++) {
@@ -751,7 +736,6 @@ PoolVector<Face3> TriangleMesh::get_faces() const {
}
}
- w.release();
return faces;
}
diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h
index 575a78b0b5..fdbfb90465 100644
--- a/core/math/triangle_mesh.h
+++ b/core/math/triangle_mesh.h
@@ -44,8 +44,8 @@ class TriangleMesh : public Reference {
int indices[3];
};
- PoolVector<Triangle> triangles;
- PoolVector<Vector3> vertices;
+ Vector<Triangle> triangles;
+ Vector<Vector3> vertices;
struct BVH {
@@ -82,7 +82,7 @@ class TriangleMesh : public Reference {
int _create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc);
- PoolVector<BVH> bvh;
+ Vector<BVH> bvh;
int max_depth;
bool valid;
@@ -93,13 +93,13 @@ public:
bool intersect_convex_shape(const Plane *p_planes, int p_plane_count) const;
bool inside_convex_shape(const Plane *p_planes, int p_plane_count, Vector3 p_scale = Vector3(1, 1, 1)) const;
Vector3 get_area_normal(const AABB &p_aabb) const;
- PoolVector<Face3> get_faces() const;
+ Vector<Face3> get_faces() const;
- PoolVector<Triangle> get_triangles() const { return triangles; }
- PoolVector<Vector3> get_vertices() const { return vertices; }
- void get_indices(PoolVector<int> *r_triangles_indices) const;
+ Vector<Triangle> get_triangles() const { return triangles; }
+ Vector<Vector3> get_vertices() const { return vertices; }
+ void get_indices(Vector<int> *r_triangles_indices) const;
- void create(const PoolVector<Vector3> &p_faces);
+ void create(const Vector<Vector3> &p_faces);
TriangleMesh();
};
diff --git a/core/math/triangulate.h b/core/math/triangulate.h
index f9bcb37141..c453b77ecf 100644
--- a/core/math/triangulate.h
+++ b/core/math/triangulate.h
@@ -58,4 +58,4 @@ private:
static bool snip(const Vector<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V, bool relaxed);
};
-#endif
+#endif // TRIANGULATE_H
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 1dec830821..ba5558102f 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -311,10 +311,15 @@ struct Vector2i {
bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
+ bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
+ bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
+
bool operator==(const Vector2i &p_vec2) const;
bool operator!=(const Vector2i &p_vec2) const;
- real_t get_aspect() const { return width / (real_t)height; }
+ real_t aspect() const { return width / (real_t)height; }
+ Vector2i sign() const { return Vector2i(SGN(x), SGN(y)); }
+ Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); }
operator String() const { return String::num(x) + ", " + String::num(y); }
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index 71ff79c0fc..353b2acd16 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -103,7 +103,7 @@ Vector3 Vector3::cubic_interpolaten(const Vector3 &p_b, const Vector3 &p_pre_a,
Vector3 out;
out = 0.5 * ((p1 * 2.0) +
(-p0 + p2) * t +
- (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
+ (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 +
(-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
return out;
}
@@ -122,7 +122,7 @@ Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, c
Vector3 out;
out = 0.5 * ((p1 * 2.0) +
(-p0 + p2) * t +
- (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
+ (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 +
(-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
return out;
}
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 4ad3017109..3bf8644af9 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -32,6 +32,7 @@
#define VECTOR3_H
#include "core/math/math_funcs.h"
+#include "core/math/vector3i.h"
#include "core/ustring.h"
class Basis;
@@ -147,6 +148,15 @@ struct Vector3 {
_FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const;
operator String() const;
+ _FORCE_INLINE_ operator Vector3i() const {
+ return Vector3i(x, y, z);
+ }
+
+ _FORCE_INLINE_ Vector3(const Vector3i &p_ivec) {
+ x = p_ivec.x;
+ y = p_ivec.y;
+ z = p_ivec.z;
+ }
_FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) {
x = p_x;
diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp
new file mode 100644
index 0000000000..8a4ddf03b9
--- /dev/null
+++ b/core/math/vector3i.cpp
@@ -0,0 +1,55 @@
+/*************************************************************************/
+/* vector3i.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 "vector3i.h"
+
+void Vector3i::set_axis(int p_axis, int32_t p_value) {
+ ERR_FAIL_INDEX(p_axis, 3);
+ coord[p_axis] = p_value;
+}
+int32_t Vector3i::get_axis(int p_axis) const {
+
+ ERR_FAIL_INDEX_V(p_axis, 3, 0);
+ return operator[](p_axis);
+}
+
+int Vector3i::min_axis() const {
+
+ return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
+}
+int Vector3i::max_axis() const {
+
+ return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
+}
+
+Vector3i::operator String() const {
+
+ return (itos(x) + ", " + itos(y) + ", " + itos(z));
+}
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
new file mode 100644
index 0000000000..6f9754d3b9
--- /dev/null
+++ b/core/math/vector3i.h
@@ -0,0 +1,272 @@
+/*************************************************************************/
+/* vector3i.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 VECTOR3I_H
+#define VECTOR3I_H
+
+#include "core/typedefs.h"
+#include "core/ustring.h"
+
+struct Vector3i {
+
+ enum Axis {
+ AXIS_X,
+ AXIS_Y,
+ AXIS_Z,
+ };
+
+ union {
+ struct {
+ int32_t x;
+ int32_t y;
+ int32_t z;
+ };
+
+ int32_t coord[3];
+ };
+
+ _FORCE_INLINE_ const int32_t &operator[](int p_axis) const {
+
+ return coord[p_axis];
+ }
+
+ _FORCE_INLINE_ int32_t &operator[](int p_axis) {
+
+ return coord[p_axis];
+ }
+
+ void set_axis(int p_axis, int32_t p_value);
+ int32_t get_axis(int p_axis) const;
+
+ int min_axis() const;
+ int max_axis() const;
+
+ _FORCE_INLINE_ void zero();
+
+ _FORCE_INLINE_ Vector3i abs() const;
+ _FORCE_INLINE_ Vector3i sign() const;
+
+ /* Operators */
+
+ _FORCE_INLINE_ Vector3i &operator+=(const Vector3i &p_v);
+ _FORCE_INLINE_ Vector3i operator+(const Vector3i &p_v) const;
+ _FORCE_INLINE_ Vector3i &operator-=(const Vector3i &p_v);
+ _FORCE_INLINE_ Vector3i operator-(const Vector3i &p_v) const;
+ _FORCE_INLINE_ Vector3i &operator*=(const Vector3i &p_v);
+ _FORCE_INLINE_ Vector3i operator*(const Vector3i &p_v) const;
+ _FORCE_INLINE_ Vector3i &operator/=(const Vector3i &p_v);
+ _FORCE_INLINE_ Vector3i operator/(const Vector3i &p_v) const;
+
+ _FORCE_INLINE_ Vector3i &operator*=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector3i operator*(int32_t p_scalar) const;
+ _FORCE_INLINE_ Vector3i &operator/=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector3i operator/(int32_t p_scalar) const;
+
+ _FORCE_INLINE_ Vector3i operator-() const;
+
+ _FORCE_INLINE_ bool operator==(const Vector3i &p_v) const;
+ _FORCE_INLINE_ bool operator!=(const Vector3i &p_v) const;
+ _FORCE_INLINE_ bool operator<(const Vector3i &p_v) const;
+ _FORCE_INLINE_ bool operator<=(const Vector3i &p_v) const;
+ _FORCE_INLINE_ bool operator>(const Vector3i &p_v) const;
+ _FORCE_INLINE_ bool operator>=(const Vector3i &p_v) const;
+
+ operator String() const;
+
+ _FORCE_INLINE_ Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) {
+ x = p_x;
+ y = p_y;
+ z = p_z;
+ }
+ _FORCE_INLINE_ Vector3i() { x = y = z = 0; }
+};
+
+Vector3i Vector3i::abs() const {
+
+ return Vector3i(ABS(x), ABS(y), ABS(z));
+}
+
+Vector3i Vector3i::sign() const {
+
+ return Vector3i(SGN(x), SGN(y), SGN(z));
+}
+
+/* Operators */
+
+Vector3i &Vector3i::operator+=(const Vector3i &p_v) {
+
+ x += p_v.x;
+ y += p_v.y;
+ z += p_v.z;
+ return *this;
+}
+
+Vector3i Vector3i::operator+(const Vector3i &p_v) const {
+
+ return Vector3i(x + p_v.x, y + p_v.y, z + p_v.z);
+}
+
+Vector3i &Vector3i::operator-=(const Vector3i &p_v) {
+
+ x -= p_v.x;
+ y -= p_v.y;
+ z -= p_v.z;
+ return *this;
+}
+Vector3i Vector3i::operator-(const Vector3i &p_v) const {
+
+ return Vector3i(x - p_v.x, y - p_v.y, z - p_v.z);
+}
+
+Vector3i &Vector3i::operator*=(const Vector3i &p_v) {
+
+ x *= p_v.x;
+ y *= p_v.y;
+ z *= p_v.z;
+ return *this;
+}
+Vector3i Vector3i::operator*(const Vector3i &p_v) const {
+
+ return Vector3i(x * p_v.x, y * p_v.y, z * p_v.z);
+}
+
+Vector3i &Vector3i::operator/=(const Vector3i &p_v) {
+
+ x /= p_v.x;
+ y /= p_v.y;
+ z /= p_v.z;
+ return *this;
+}
+
+Vector3i Vector3i::operator/(const Vector3i &p_v) const {
+
+ return Vector3i(x / p_v.x, y / p_v.y, z / p_v.z);
+}
+
+Vector3i &Vector3i::operator*=(int32_t p_scalar) {
+
+ x *= p_scalar;
+ y *= p_scalar;
+ z *= p_scalar;
+ return *this;
+}
+
+_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar, const Vector3i &p_vec) {
+
+ return p_vec * p_scalar;
+}
+
+Vector3i Vector3i::operator*(int32_t p_scalar) const {
+
+ return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar);
+}
+
+Vector3i &Vector3i::operator/=(int32_t p_scalar) {
+
+ x /= p_scalar;
+ y /= p_scalar;
+ z /= p_scalar;
+ return *this;
+}
+
+Vector3i Vector3i::operator/(int32_t p_scalar) const {
+
+ return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar);
+}
+
+Vector3i Vector3i::operator-() const {
+
+ return Vector3i(-x, -y, -z);
+}
+
+bool Vector3i::operator==(const Vector3i &p_v) const {
+
+ return (x == p_v.x && y == p_v.y && z == p_v.z);
+}
+
+bool Vector3i::operator!=(const Vector3i &p_v) const {
+
+ return (x != p_v.x || y != p_v.y || z != p_v.z);
+}
+
+bool Vector3i::operator<(const Vector3i &p_v) const {
+
+ if (x == p_v.x) {
+ if (y == p_v.y)
+ return z < p_v.z;
+ else
+ return y < p_v.y;
+ } else {
+ return x < p_v.x;
+ }
+}
+
+bool Vector3i::operator>(const Vector3i &p_v) const {
+
+ if (x == p_v.x) {
+ if (y == p_v.y)
+ return z > p_v.z;
+ else
+ return y > p_v.y;
+ } else {
+ return x > p_v.x;
+ }
+}
+
+bool Vector3i::operator<=(const Vector3i &p_v) const {
+
+ if (x == p_v.x) {
+ if (y == p_v.y)
+ return z <= p_v.z;
+ else
+ return y < p_v.y;
+ } else {
+ return x < p_v.x;
+ }
+}
+
+bool Vector3i::operator>=(const Vector3i &p_v) const {
+
+ if (x == p_v.x) {
+ if (y == p_v.y)
+ return z >= p_v.z;
+ else
+ return y > p_v.y;
+ } else {
+ return x > p_v.x;
+ }
+}
+
+void Vector3i::zero() {
+
+ x = y = z = 0;
+}
+
+#endif // VECTOR3I_H