diff options
Diffstat (limited to 'core/math')
| -rw-r--r-- | core/math/a_star.cpp | 25 | ||||
| -rw-r--r-- | core/math/a_star.h | 3 | ||||
| -rw-r--r-- | core/math/math_2d.cpp | 22 | ||||
| -rw-r--r-- | core/math/math_2d.h | 2 | ||||
| -rw-r--r-- | core/math/transform.h | 23 | ||||
| -rw-r--r-- | core/math/vector3.h | 20 |
6 files changed, 60 insertions, 35 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 110185c2d..c82a40f30 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -28,6 +28,8 @@ /*************************************************************************/ #include "a_star.h" #include "geometry.h" +#include "scene/scene_string_names.h" +#include "script_language.h" int AStar::get_available_point_id() const { @@ -187,7 +189,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { Point *n = begin_point->neighbours[i]; n->prev_point = begin_point; - n->distance = n->pos.distance_to(begin_point->pos); + n->distance = _compute_cost(n->id, begin_point->id); n->distance *= n->weight_scale; n->last_pass = pass; open_list.add(&n->list); @@ -215,7 +217,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { Point *p = E->self(); real_t cost = p->distance; - cost += p->pos.distance_to(end_point->pos); + cost += _estimate_cost(p->id, end_point->id); cost *= p->weight_scale; if (cost < least_cost) { @@ -233,7 +235,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { Point *e = p->neighbours[i]; - real_t distance = p->pos.distance_to(e->pos) + p->distance; + real_t distance = _compute_cost(p->id, e->id) + p->distance; distance *= e->weight_scale; if (e->last_pass == pass) { @@ -274,6 +276,20 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { return found_route; } +float AStar::_estimate_cost(int p_from_id, int p_to_id) { + if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) + return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id); + + return points[p_from_id]->pos.distance_to(points[p_to_id]->pos); +} + +float AStar::_compute_cost(int p_from_id, int p_to_id) { + if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) + return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id); + + return points[p_from_id]->pos.distance_to(points[p_to_id]->pos); +} + PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) { ERR_FAIL_COND_V(!points.has(p_from_id), PoolVector<Vector3>()); @@ -395,6 +411,9 @@ 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("_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id"))); + BIND_VMETHOD(MethodInfo("_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id"))); } AStar::AStar() { diff --git a/core/math/a_star.h b/core/math/a_star.h index 2ac855737..43c9c4457 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -93,6 +93,9 @@ 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); + public: int get_available_point_id() const; diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index 8f942c423..77cff6a05 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -61,6 +61,10 @@ Vector2 Vector2::normalized() const { return v; } +bool Vector2::is_normalized() const { + return Math::isequal_approx(length(), (real_t)1.0); +} + real_t Vector2::distance_to(const Vector2 &p_vector2) const { return Math::sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y)); @@ -274,13 +278,23 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c */ } -Vector2 Vector2::slide(const Vector2 &p_vec) const { +// slide returns the component of the vector along the given plane, specified by its normal vector. +Vector2 Vector2::slide(const Vector2 &p_n) const { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector2()); +#endif + return *this - p_n * this->dot(p_n); +} - return p_vec - *this * this->dot(p_vec); +Vector2 Vector2::bounce(const Vector2 &p_n) const { + return -reflect(p_n); } -Vector2 Vector2::reflect(const Vector2 &p_vec) const { - return p_vec - *this * this->dot(p_vec) * 2.0; +Vector2 Vector2::reflect(const Vector2 &p_n) const { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector2()); +#endif + return 2.0 * p_n * this->dot(p_n) - *this; } bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const { diff --git a/core/math/math_2d.h b/core/math/math_2d.h index af6437d7f..50ebcb845 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -82,6 +82,7 @@ struct Vector2 { void normalize(); Vector2 normalized() const; + bool is_normalized() const; real_t length() const; real_t length_squared() const; @@ -106,6 +107,7 @@ struct Vector2 { Vector2 cubic_interpolate_soft(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const; Vector2 slide(const Vector2 &p_vec) const; + Vector2 bounce(const Vector2 &p_vec) const; Vector2 reflect(const Vector2 &p_vec) const; Vector2 operator+(const Vector2 &p_v) const; diff --git a/core/math/transform.h b/core/math/transform.h index e307aba12..64b4b23aa 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -229,27 +229,4 @@ _FORCE_INLINE_ Rect3 Transform::xform_inv(const Rect3 &p_aabb) const { return ret; } -#ifdef OPTIMIZED_TRANSFORM_IMPL_OVERRIDE - -#else - -struct OptimizedTransform { - - Transform transform; - - _FORCE_INLINE_ void invert() { transform.invert(); } - _FORCE_INLINE_ void affine_invert() { transform.affine_invert(); } - _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec) const { return transform.xform(p_vec); }; - _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vec) const { return transform.xform_inv(p_vec); }; - _FORCE_INLINE_ OptimizedTransform operator*(const OptimizedTransform &p_ot) const { return OptimizedTransform(transform * p_ot.transform); } - _FORCE_INLINE_ Transform get_transform() const { return transform; } - _FORCE_INLINE_ void set_transform(const Transform &p_transform) { transform = p_transform; } - - OptimizedTransform(const Transform &p_transform) { - transform = p_transform; - } -}; - -#endif - #endif diff --git a/core/math/vector3.h b/core/math/vector3.h index 951380e89..8550ae700 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -107,6 +107,7 @@ struct Vector3 { _FORCE_INLINE_ real_t angle_to(const Vector3 &p_b) const; _FORCE_INLINE_ Vector3 slide(const Vector3 &p_vec) const; + _FORCE_INLINE_ Vector3 bounce(const Vector3 &p_vec) const; _FORCE_INLINE_ Vector3 reflect(const Vector3 &p_vec) const; /* Operators */ @@ -400,14 +401,23 @@ void Vector3::zero() { x = y = z = 0; } -Vector3 Vector3::slide(const Vector3 &p_vec) const { - - return p_vec - *this * this->dot(p_vec); +// slide returns the component of the vector along the given plane, specified by its normal vector. +Vector3 Vector3::slide(const Vector3 &p_n) const { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector3()); +#endif + return *this - p_n * this->dot(p_n); } -Vector3 Vector3::reflect(const Vector3 &p_vec) const { +Vector3 Vector3::bounce(const Vector3 &p_n) const { + return -reflect(p_n); +} - return p_vec - *this * this->dot(p_vec) * 2.0; +Vector3 Vector3::reflect(const Vector3 &p_n) const { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector3()); +#endif + return 2.0 * p_n * this->dot(p_n) - *this; } #endif |
