From 9d1b5f4e3b58d9287addc723d8ce34626523a302 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Mon, 7 May 2018 16:33:25 -0500 Subject: [Core] Move Vector2 to its own file Makes 2D math code easier to read and makes Vector2 consistent with Vector3. In the future, we may move other things out of math_2d as well. --- core/math/math_2d.cpp | 156 ------------------------------- core/math/math_2d.h | 214 +----------------------------------------- core/math/vector2.cpp | 187 +++++++++++++++++++++++++++++++++++++ core/math/vector2.h | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 438 insertions(+), 369 deletions(-) create mode 100644 core/math/vector2.cpp create mode 100644 core/math/vector2.h diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index a053ffbd93..7fa75cfc3a 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -30,162 +30,6 @@ #include "math_2d.h" -real_t Vector2::angle() const { - - return Math::atan2(y, x); -} - -real_t Vector2::length() const { - - return Math::sqrt(x * x + y * y); -} - -real_t Vector2::length_squared() const { - - return x * x + y * y; -} - -void Vector2::normalize() { - - real_t l = x * x + y * y; - if (l != 0) { - - l = Math::sqrt(l); - x /= l; - y /= l; - } -} - -Vector2 Vector2::normalized() const { - - Vector2 v = *this; - v.normalize(); - return v; -} - -bool Vector2::is_normalized() const { - // use length_squared() instead of length() to avoid sqrt(), makes it more stringent. - return Math::is_equal_approx(length_squared(), 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)); -} - -real_t Vector2::distance_squared_to(const Vector2 &p_vector2) const { - - return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y); -} - -real_t Vector2::angle_to(const Vector2 &p_vector2) const { - - return Math::atan2(cross(p_vector2), dot(p_vector2)); -} - -real_t Vector2::angle_to_point(const Vector2 &p_vector2) const { - - return Math::atan2(y - p_vector2.y, x - p_vector2.x); -} - -real_t Vector2::dot(const Vector2 &p_other) const { - - return x * p_other.x + y * p_other.y; -} - -real_t Vector2::cross(const Vector2 &p_other) const { - - return x * p_other.y - y * p_other.x; -} - -Vector2 Vector2::floor() const { - - return Vector2(Math::floor(x), Math::floor(y)); -} - -Vector2 Vector2::ceil() const { - - return Vector2(Math::ceil(x), Math::ceil(y)); -} - -Vector2 Vector2::round() const { - - return Vector2(Math::round(x), Math::round(y)); -} - -Vector2 Vector2::rotated(real_t p_by) const { - - Vector2 v; - v.set_rotation(angle() + p_by); - v *= length(); - return v; -} - -Vector2 Vector2::project(const Vector2 &p_vec) const { - - Vector2 v1 = p_vec; - Vector2 v2 = *this; - return v2 * (v1.dot(v2) / v2.dot(v2)); -} - -Vector2 Vector2::snapped(const Vector2 &p_by) const { - - return Vector2( - Math::stepify(x, p_by.x), - Math::stepify(y, p_by.y)); -} - -Vector2 Vector2::clamped(real_t p_len) const { - - real_t l = length(); - Vector2 v = *this; - if (l > 0 && p_len < l) { - - v /= l; - v *= p_len; - } - - return v; -} - -Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const { - - Vector2 p0 = p_pre_a; - Vector2 p1 = *this; - Vector2 p2 = p_b; - Vector2 p3 = p_post_b; - - real_t t = p_t; - real_t t2 = t * t; - real_t t3 = t2 * t; - - Vector2 out; - out = 0.5 * ((p1 * 2.0) + - (-p0 + p2) * t + - (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 + - (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3); - return out; -} - -// slide returns the component of the vector along the given plane, specified by its normal vector. -Vector2 Vector2::slide(const Vector2 &p_normal) const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2()); -#endif - return *this - p_normal * this->dot(p_normal); -} - -Vector2 Vector2::bounce(const Vector2 &p_normal) const { - return -reflect(p_normal); -} - -Vector2 Vector2::reflect(const Vector2 &p_normal) const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2()); -#endif - return 2.0 * p_normal * this->dot(p_normal) - *this; -} - bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const { real_t min = 0, max = 1; diff --git a/core/math/math_2d.h b/core/math/math_2d.h index 25c39e5d7a..d9694388a9 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -33,6 +33,7 @@ #include "math_funcs.h" #include "ustring.h" +#include "vector2.h" /** @author Juan Linietsky */ @@ -72,219 +73,6 @@ enum VAlign { VALIGN_BOTTOM }; -struct Vector2 { - - union { - real_t x; - real_t width; - }; - union { - real_t y; - real_t height; - }; - - _FORCE_INLINE_ real_t &operator[](int p_idx) { - return p_idx ? y : x; - } - _FORCE_INLINE_ const real_t &operator[](int p_idx) const { - return p_idx ? y : x; - } - - void normalize(); - Vector2 normalized() const; - bool is_normalized() const; - - real_t length() const; - real_t length_squared() const; - - real_t distance_to(const Vector2 &p_vector2) const; - real_t distance_squared_to(const Vector2 &p_vector2) const; - real_t angle_to(const Vector2 &p_vector2) const; - real_t angle_to_point(const Vector2 &p_vector2) const; - - real_t dot(const Vector2 &p_other) const; - real_t cross(const Vector2 &p_other) const; - Vector2 project(const Vector2 &p_vec) const; - - Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const; - - Vector2 clamped(real_t p_len) const; - - _FORCE_INLINE_ static Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t); - _FORCE_INLINE_ Vector2 linear_interpolate(const Vector2 &p_b, real_t p_t) const; - _FORCE_INLINE_ Vector2 slerp(const Vector2 &p_b, real_t p_t) const; - Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const; - - Vector2 slide(const Vector2 &p_normal) const; - Vector2 bounce(const Vector2 &p_normal) const; - Vector2 reflect(const Vector2 &p_normal) const; - - Vector2 operator+(const Vector2 &p_v) const; - void operator+=(const Vector2 &p_v); - Vector2 operator-(const Vector2 &p_v) const; - void operator-=(const Vector2 &p_v); - Vector2 operator*(const Vector2 &p_v1) const; - - Vector2 operator*(const real_t &rvalue) const; - void operator*=(const real_t &rvalue); - void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; } - - Vector2 operator/(const Vector2 &p_v1) const; - - Vector2 operator/(const real_t &rvalue) const; - - void operator/=(const real_t &rvalue); - - Vector2 operator-() const; - - bool operator==(const Vector2 &p_vec2) const; - bool operator!=(const Vector2 &p_vec2) const; - - bool operator<(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } - bool operator<=(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y <= p_vec2.y) : (x <= p_vec2.x); } - - real_t angle() const; - - void set_rotation(real_t p_radians) { - - x = Math::cos(p_radians); - y = Math::sin(p_radians); - } - - _FORCE_INLINE_ Vector2 abs() const { - - return Vector2(Math::abs(x), Math::abs(y)); - } - - Vector2 rotated(real_t p_by) const; - Vector2 tangent() const { - - return Vector2(y, -x); - } - - Vector2 floor() const; - Vector2 ceil() const; - Vector2 round() const; - Vector2 snapped(const Vector2 &p_by) const; - real_t aspect() const { return width / height; } - - operator String() const { return String::num(x) + ", " + String::num(y); } - - _FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) { - x = p_x; - y = p_y; - } - _FORCE_INLINE_ Vector2() { - x = 0; - y = 0; - } -}; - -_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const { - - return p_vec - *this * (dot(p_vec) - p_d); -} - -_FORCE_INLINE_ Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) { - - return p_vec * p_scalar; -} - -_FORCE_INLINE_ Vector2 Vector2::operator+(const Vector2 &p_v) const { - - return Vector2(x + p_v.x, y + p_v.y); -} -_FORCE_INLINE_ void Vector2::operator+=(const Vector2 &p_v) { - - x += p_v.x; - y += p_v.y; -} -_FORCE_INLINE_ Vector2 Vector2::operator-(const Vector2 &p_v) const { - - return Vector2(x - p_v.x, y - p_v.y); -} -_FORCE_INLINE_ void Vector2::operator-=(const Vector2 &p_v) { - - x -= p_v.x; - y -= p_v.y; -} - -_FORCE_INLINE_ Vector2 Vector2::operator*(const Vector2 &p_v1) const { - - return Vector2(x * p_v1.x, y * p_v1.y); -}; - -_FORCE_INLINE_ Vector2 Vector2::operator*(const real_t &rvalue) const { - - return Vector2(x * rvalue, y * rvalue); -}; -_FORCE_INLINE_ void Vector2::operator*=(const real_t &rvalue) { - - x *= rvalue; - y *= rvalue; -}; - -_FORCE_INLINE_ Vector2 Vector2::operator/(const Vector2 &p_v1) const { - - return Vector2(x / p_v1.x, y / p_v1.y); -}; - -_FORCE_INLINE_ Vector2 Vector2::operator/(const real_t &rvalue) const { - - return Vector2(x / rvalue, y / rvalue); -}; - -_FORCE_INLINE_ void Vector2::operator/=(const real_t &rvalue) { - - x /= rvalue; - y /= rvalue; -}; - -_FORCE_INLINE_ Vector2 Vector2::operator-() const { - - return Vector2(-x, -y); -} - -_FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const { - - return x == p_vec2.x && y == p_vec2.y; -} -_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const { - - return x != p_vec2.x || y != p_vec2.y; -} - -Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const { - - Vector2 res = *this; - - res.x += (p_t * (p_b.x - x)); - res.y += (p_t * (p_b.y - y)); - - return res; -} - -Vector2 Vector2::slerp(const Vector2 &p_b, real_t p_t) const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V(is_normalized() == false, Vector2()); -#endif - real_t theta = angle_to(p_b); - return rotated(theta * p_t); -} - -Vector2 Vector2::linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t) { - - Vector2 res = p_a; - - res.x += (p_t * (p_b.x - p_a.x)); - res.y += (p_t * (p_b.y - p_a.y)); - - return res; -} - -typedef Vector2 Size2; -typedef Vector2 Point2; - struct Transform2D; struct Rect2 { diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp new file mode 100644 index 0000000000..8e59ddbd07 --- /dev/null +++ b/core/math/vector2.cpp @@ -0,0 +1,187 @@ +/*************************************************************************/ +/* vector2.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "vector2.h" + +real_t Vector2::angle() const { + + return Math::atan2(y, x); +} + +real_t Vector2::length() const { + + return Math::sqrt(x * x + y * y); +} + +real_t Vector2::length_squared() const { + + return x * x + y * y; +} + +void Vector2::normalize() { + + real_t l = x * x + y * y; + if (l != 0) { + + l = Math::sqrt(l); + x /= l; + y /= l; + } +} + +Vector2 Vector2::normalized() const { + + Vector2 v = *this; + v.normalize(); + return v; +} + +bool Vector2::is_normalized() const { + // use length_squared() instead of length() to avoid sqrt(), makes it more stringent. + return Math::is_equal_approx(length_squared(), 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)); +} + +real_t Vector2::distance_squared_to(const Vector2 &p_vector2) const { + + return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y); +} + +real_t Vector2::angle_to(const Vector2 &p_vector2) const { + + return Math::atan2(cross(p_vector2), dot(p_vector2)); +} + +real_t Vector2::angle_to_point(const Vector2 &p_vector2) const { + + return Math::atan2(y - p_vector2.y, x - p_vector2.x); +} + +real_t Vector2::dot(const Vector2 &p_other) const { + + return x * p_other.x + y * p_other.y; +} + +real_t Vector2::cross(const Vector2 &p_other) const { + + return x * p_other.y - y * p_other.x; +} + +Vector2 Vector2::floor() const { + + return Vector2(Math::floor(x), Math::floor(y)); +} + +Vector2 Vector2::ceil() const { + + return Vector2(Math::ceil(x), Math::ceil(y)); +} + +Vector2 Vector2::round() const { + + return Vector2(Math::round(x), Math::round(y)); +} + +Vector2 Vector2::rotated(real_t p_by) const { + + Vector2 v; + v.set_rotation(angle() + p_by); + v *= length(); + return v; +} + +Vector2 Vector2::project(const Vector2 &p_vec) const { + + Vector2 v1 = p_vec; + Vector2 v2 = *this; + return v2 * (v1.dot(v2) / v2.dot(v2)); +} + +Vector2 Vector2::snapped(const Vector2 &p_by) const { + + return Vector2( + Math::stepify(x, p_by.x), + Math::stepify(y, p_by.y)); +} + +Vector2 Vector2::clamped(real_t p_len) const { + + real_t l = length(); + Vector2 v = *this; + if (l > 0 && p_len < l) { + + v /= l; + v *= p_len; + } + + return v; +} + +Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const { + + Vector2 p0 = p_pre_a; + Vector2 p1 = *this; + Vector2 p2 = p_b; + Vector2 p3 = p_post_b; + + real_t t = p_t; + real_t t2 = t * t; + real_t t3 = t2 * t; + + Vector2 out; + out = 0.5 * ((p1 * 2.0) + + (-p0 + p2) * t + + (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 + + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3); + return out; +} + +// slide returns the component of the vector along the given plane, specified by its normal vector. +Vector2 Vector2::slide(const Vector2 &p_normal) const { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2()); +#endif + return *this - p_normal * this->dot(p_normal); +} + +Vector2 Vector2::bounce(const Vector2 &p_normal) const { + return -reflect(p_normal); +} + +Vector2 Vector2::reflect(const Vector2 &p_normal) const { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2()); +#endif + return 2.0 * p_normal * this->dot(p_normal) - *this; +} diff --git a/core/math/vector2.h b/core/math/vector2.h new file mode 100644 index 0000000000..809cedf9c9 --- /dev/null +++ b/core/math/vector2.h @@ -0,0 +1,250 @@ +/*************************************************************************/ +/* vector2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 VECTOR2_H +#define VECTOR2_H + +#include "math_funcs.h" +#include "ustring.h" + +struct Vector2 { + + union { + real_t x; + real_t width; + }; + union { + real_t y; + real_t height; + }; + + _FORCE_INLINE_ real_t &operator[](int p_idx) { + return p_idx ? y : x; + } + _FORCE_INLINE_ const real_t &operator[](int p_idx) const { + return p_idx ? y : x; + } + + void normalize(); + Vector2 normalized() const; + bool is_normalized() const; + + real_t length() const; + real_t length_squared() const; + + real_t distance_to(const Vector2 &p_vector2) const; + real_t distance_squared_to(const Vector2 &p_vector2) const; + real_t angle_to(const Vector2 &p_vector2) const; + real_t angle_to_point(const Vector2 &p_vector2) const; + + real_t dot(const Vector2 &p_other) const; + real_t cross(const Vector2 &p_other) const; + Vector2 project(const Vector2 &p_vec) const; + + Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const; + + Vector2 clamped(real_t p_len) const; + + _FORCE_INLINE_ static Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t); + _FORCE_INLINE_ Vector2 linear_interpolate(const Vector2 &p_b, real_t p_t) const; + _FORCE_INLINE_ Vector2 slerp(const Vector2 &p_b, real_t p_t) const; + Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const; + + Vector2 slide(const Vector2 &p_normal) const; + Vector2 bounce(const Vector2 &p_normal) const; + Vector2 reflect(const Vector2 &p_normal) const; + + Vector2 operator+(const Vector2 &p_v) const; + void operator+=(const Vector2 &p_v); + Vector2 operator-(const Vector2 &p_v) const; + void operator-=(const Vector2 &p_v); + Vector2 operator*(const Vector2 &p_v1) const; + + Vector2 operator*(const real_t &rvalue) const; + void operator*=(const real_t &rvalue); + void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; } + + Vector2 operator/(const Vector2 &p_v1) const; + + Vector2 operator/(const real_t &rvalue) const; + + void operator/=(const real_t &rvalue); + + Vector2 operator-() const; + + bool operator==(const Vector2 &p_vec2) const; + bool operator!=(const Vector2 &p_vec2) const; + + bool operator<(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } + bool operator<=(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y <= p_vec2.y) : (x <= p_vec2.x); } + + real_t angle() const; + + void set_rotation(real_t p_radians) { + + x = Math::cos(p_radians); + y = Math::sin(p_radians); + } + + _FORCE_INLINE_ Vector2 abs() const { + + return Vector2(Math::abs(x), Math::abs(y)); + } + + Vector2 rotated(real_t p_by) const; + Vector2 tangent() const { + + return Vector2(y, -x); + } + + Vector2 floor() const; + Vector2 ceil() const; + Vector2 round() const; + Vector2 snapped(const Vector2 &p_by) const; + real_t aspect() const { return width / height; } + + operator String() const { return String::num(x) + ", " + String::num(y); } + + _FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) { + x = p_x; + y = p_y; + } + _FORCE_INLINE_ Vector2() { + x = 0; + y = 0; + } +}; + +_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const { + + return p_vec - *this * (dot(p_vec) - p_d); +} + +_FORCE_INLINE_ Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) { + + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector2 Vector2::operator+(const Vector2 &p_v) const { + + return Vector2(x + p_v.x, y + p_v.y); +} +_FORCE_INLINE_ void Vector2::operator+=(const Vector2 &p_v) { + + x += p_v.x; + y += p_v.y; +} +_FORCE_INLINE_ Vector2 Vector2::operator-(const Vector2 &p_v) const { + + return Vector2(x - p_v.x, y - p_v.y); +} +_FORCE_INLINE_ void Vector2::operator-=(const Vector2 &p_v) { + + x -= p_v.x; + y -= p_v.y; +} + +_FORCE_INLINE_ Vector2 Vector2::operator*(const Vector2 &p_v1) const { + + return Vector2(x * p_v1.x, y * p_v1.y); +}; + +_FORCE_INLINE_ Vector2 Vector2::operator*(const real_t &rvalue) const { + + return Vector2(x * rvalue, y * rvalue); +}; +_FORCE_INLINE_ void Vector2::operator*=(const real_t &rvalue) { + + x *= rvalue; + y *= rvalue; +}; + +_FORCE_INLINE_ Vector2 Vector2::operator/(const Vector2 &p_v1) const { + + return Vector2(x / p_v1.x, y / p_v1.y); +}; + +_FORCE_INLINE_ Vector2 Vector2::operator/(const real_t &rvalue) const { + + return Vector2(x / rvalue, y / rvalue); +}; + +_FORCE_INLINE_ void Vector2::operator/=(const real_t &rvalue) { + + x /= rvalue; + y /= rvalue; +}; + +_FORCE_INLINE_ Vector2 Vector2::operator-() const { + + return Vector2(-x, -y); +} + +_FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const { + + return x == p_vec2.x && y == p_vec2.y; +} +_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const { + + return x != p_vec2.x || y != p_vec2.y; +} + +Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const { + + Vector2 res = *this; + + res.x += (p_t * (p_b.x - x)); + res.y += (p_t * (p_b.y - y)); + + return res; +} + +Vector2 Vector2::slerp(const Vector2 &p_b, real_t p_t) const { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(is_normalized() == false, Vector2()); +#endif + real_t theta = angle_to(p_b); + return rotated(theta * p_t); +} + +Vector2 Vector2::linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t) { + + Vector2 res = p_a; + + res.x += (p_t * (p_b.x - p_a.x)); + res.y += (p_t * (p_b.y - p_a.y)); + + return res; +} + +typedef Vector2 Size2; +typedef Vector2 Point2; + +#endif // VECTOR2_H -- cgit v1.2.3 From 28fc19533902dbc2614c949486bb4edf9450cc05 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Mon, 7 May 2018 16:35:17 -0500 Subject: [Core] Change math_2d includes to vector2 includes where relevant --- core/math/triangulate.h | 2 +- drivers/convex_decomp/b2d_decompose.h | 2 +- modules/gdnative/gdnative/pool_arrays.cpp | 2 +- modules/gdnative/gdnative/vector2.cpp | 2 +- scene/2d/line_builder.h | 2 +- thirdparty/b2d_convexdecomp/b2Glue.h | 2 +- thirdparty/misc/triangulator.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/math/triangulate.h b/core/math/triangulate.h index b1a583d0c5..a0f56f5f27 100644 --- a/core/math/triangulate.h +++ b/core/math/triangulate.h @@ -31,7 +31,7 @@ #ifndef TRIANGULATE_H #define TRIANGULATE_H -#include "math_2d.h" +#include "vector2.h" /* http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml diff --git a/drivers/convex_decomp/b2d_decompose.h b/drivers/convex_decomp/b2d_decompose.h index 068689d73d..b21792047e 100644 --- a/drivers/convex_decomp/b2d_decompose.h +++ b/drivers/convex_decomp/b2d_decompose.h @@ -31,8 +31,8 @@ #ifndef B2D_DECOMPOSE_H #define B2D_DECOMPOSE_H -#include "math_2d.h" #include "vector.h" +#include "vector2.h" Vector > b2d_decompose(const Vector &p_polygon); #endif // B2D_DECOMPOSE_H diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp index 6688be1a0d..2b6b7a823a 100644 --- a/modules/gdnative/gdnative/pool_arrays.cpp +++ b/modules/gdnative/gdnative/pool_arrays.cpp @@ -35,7 +35,7 @@ #include "dvector.h" #include "core/color.h" -#include "core/math/math_2d.h" +#include "core/math/vector2.h" #include "core/math/vector3.h" #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index 9e40b42373..c7902e06ee 100644 --- a/modules/gdnative/gdnative/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -30,7 +30,7 @@ #include "gdnative/vector2.h" -#include "core/math/math_2d.h" +#include "core/math/vector2.h" #include "core/variant.h" #ifdef __cplusplus diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index b1c62f84e2..edfdf97c47 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -33,8 +33,8 @@ #include "color.h" #include "line_2d.h" -#include "math_2d.h" #include "scene/resources/color_ramp.h" +#include "vector2.h" class LineBuilder { public: diff --git a/thirdparty/b2d_convexdecomp/b2Glue.h b/thirdparty/b2d_convexdecomp/b2Glue.h index 425486356e..10c2f62361 100644 --- a/thirdparty/b2d_convexdecomp/b2Glue.h +++ b/thirdparty/b2d_convexdecomp/b2Glue.h @@ -19,7 +19,7 @@ #ifndef B2GLUE_H #define B2GLUE_H -#include "math_2d.h" +#include "vector2.h" #include namespace b2ConvexDecomp { diff --git a/thirdparty/misc/triangulator.h b/thirdparty/misc/triangulator.h index b6dd7e8236..d1538cfae5 100644 --- a/thirdparty/misc/triangulator.h +++ b/thirdparty/misc/triangulator.h @@ -21,9 +21,9 @@ #ifndef TRIANGULATOR_H #define TRIANGULATOR_H -#include "math_2d.h" #include "list.h" #include "set.h" +#include "vector2.h" //2D point structure -- cgit v1.2.3 From 9170d932e3832c86e5e1fc09a6a555b4efd95992 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Fri, 20 Jul 2018 13:09:17 -0500 Subject: [Core] Grammar, move defs to defs Math constant definitions belong in `math_defs.h`. Also, the grammer in these files really needed some updating. --- core/math/math_2d.h | 36 ------------------------------ core/math/math_defs.h | 59 ++++++++++++++++++++++++++++++++++++++++++-------- core/math/math_funcs.h | 7 ------ core/typedefs.h | 8 +++---- 4 files changed, 54 insertions(+), 56 deletions(-) diff --git a/core/math/math_2d.h b/core/math/math_2d.h index d9694388a9..a764e3e3cf 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -37,42 +37,6 @@ /** @author Juan Linietsky */ -enum Margin { - - MARGIN_LEFT, - MARGIN_TOP, - MARGIN_RIGHT, - MARGIN_BOTTOM -}; - -enum Corner { - - CORNER_TOP_LEFT, - CORNER_TOP_RIGHT, - CORNER_BOTTOM_RIGHT, - CORNER_BOTTOM_LEFT -}; - -enum Orientation { - - HORIZONTAL, - VERTICAL -}; - -enum HAlign { - - HALIGN_LEFT, - HALIGN_CENTER, - HALIGN_RIGHT -}; - -enum VAlign { - - VALIGN_TOP, - VALIGN_CENTER, - VALIGN_BOTTOM -}; - struct Transform2D; struct Rect2 { diff --git a/core/math/math_defs.h b/core/math/math_defs.h index d3484d8d02..a5feee6eb5 100644 --- a/core/math/math_defs.h +++ b/core/math/math_defs.h @@ -36,30 +36,71 @@ #define CMP_NORMALIZE_TOLERANCE 0.000001 #define CMP_POINT_IN_PLANE_EPSILON 0.00001 +#define Math_SQRT12 0.7071067811865475244008443621048490 +#define Math_SQRT2 1.4142135623730950488016887242 +#define Math_LN2 0.6931471805599453094172321215 +#define Math_TAU 6.2831853071795864769252867666 +#define Math_PI 3.1415926535897932384626433833 +#define Math_E 2.7182818284590452353602874714 +#define Math_INF INFINITY +#define Math_NAN NAN + #ifdef DEBUG_ENABLED #define MATH_CHECKS #endif #define USEC_TO_SEC(m_usec) ((m_usec) / 1000000.0) -/** - * "Real" is a type that will be translated to either floats or fixed depending - * on the compilation setting - */ enum ClockDirection { - CLOCKWISE, COUNTERCLOCKWISE }; -#ifdef REAL_T_IS_DOUBLE +enum Orientation { -typedef double real_t; + HORIZONTAL, + VERTICAL +}; -#else +enum HAlign { -typedef float real_t; + HALIGN_LEFT, + HALIGN_CENTER, + HALIGN_RIGHT +}; + +enum VAlign { + + VALIGN_TOP, + VALIGN_CENTER, + VALIGN_BOTTOM +}; +enum Margin { + + MARGIN_LEFT, + MARGIN_TOP, + MARGIN_RIGHT, + MARGIN_BOTTOM +}; + +enum Corner { + + CORNER_TOP_LEFT, + CORNER_TOP_RIGHT, + CORNER_BOTTOM_RIGHT, + CORNER_BOTTOM_LEFT +}; + +/** + * The "Real" type is an abstract type used for real numbers, such as 1.5, + * in contrast to integer numbers. Precision can be controlled with the + * presence or absence of the REAL_T_IS_DOUBLE define. + */ +#ifdef REAL_T_IS_DOUBLE +typedef double real_t; +#else +typedef float real_t; #endif #endif // MATH_DEFS_H diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index f0c0268f31..992084a653 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -39,13 +39,6 @@ #include #include -#define Math_PI 3.14159265358979323846 -#define Math_TAU 6.28318530717958647692 -#define Math_SQRT12 0.7071067811865475244008443621048490 -#define Math_LN2 0.693147180559945309417 -#define Math_INF INFINITY -#define Math_NAN NAN - class Math { static pcg32_random_t default_pcg; diff --git a/core/typedefs.h b/core/typedefs.h index 57afa3bdb4..094f1bbfd5 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -33,7 +33,7 @@ #include /** - * Basic definitions and simple functions to be used everywhere.. + * Basic definitions and simple functions to be used everywhere. */ #include "platform_config.h" @@ -71,7 +71,7 @@ T *_nullptr() { #define OFFSET_OF(st, m) \ ((size_t)((char *)&(_nullptr()->m) - (char *)0)) /** - * Some platforms (devices) not define NULL + * Some platforms (devices) don't define NULL */ #ifndef NULL @@ -79,7 +79,7 @@ T *_nullptr() { #endif /** - * Windows defines a lot of badly stuff we'll never ever use. undefine it. + * Windows badly defines a lot of stuff we'll never use. Undefine it. */ #ifdef _WIN32 @@ -296,4 +296,4 @@ struct _GlobalLock { #define unlikely(x) x #endif -#endif /* typedefs.h */ +#endif // TYPEDEFS_H -- cgit v1.2.3 From 2eb8a9749ea005325e6918288a1b6f1be311eebf Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Fri, 10 Aug 2018 23:40:44 -0500 Subject: [Core] Move Rect2 and Transform2D to their own files Math2D includes Transform2D, which includes Rect2, which includes Vector2. --- core/math/math_2d.cpp | 299 -------------------------- core/math/math_2d.h | 520 +-------------------------------------------- core/math/rect2.cpp | 240 +++++++++++++++++++++ core/math/rect2.h | 236 ++++++++++++++++++++ core/math/transform_2d.cpp | 272 ++++++++++++++++++++++++ core/math/transform_2d.h | 201 ++++++++++++++++++ 6 files changed, 950 insertions(+), 818 deletions(-) create mode 100644 core/math/rect2.cpp create mode 100644 core/math/rect2.h create mode 100644 core/math/transform_2d.cpp create mode 100644 core/math/transform_2d.h diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index 7fa75cfc3a..eccf0552b6 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -30,64 +30,6 @@ #include "math_2d.h" -bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const { - - real_t min = 0, max = 1; - int axis = 0; - real_t sign = 0; - - for (int i = 0; i < 2; i++) { - real_t seg_from = p_from[i]; - real_t seg_to = p_to[i]; - real_t box_begin = position[i]; - real_t box_end = box_begin + size[i]; - real_t cmin, cmax; - real_t csign; - - if (seg_from < seg_to) { - - if (seg_from > box_end || seg_to < box_begin) - return false; - real_t length = seg_to - seg_from; - cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0; - cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1; - csign = -1.0; - - } else { - - if (seg_to > box_end || seg_from < box_begin) - return false; - real_t length = seg_to - seg_from; - cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0; - cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1; - csign = 1.0; - } - - if (cmin > min) { - min = cmin; - axis = i; - sign = csign; - } - if (cmax < max) - max = cmax; - if (max < min) - return false; - } - - Vector2 rel = p_to - p_from; - - if (r_normal) { - Vector2 normal; - normal[axis] = sign; - *r_normal = normal; - } - - if (r_pos) - *r_pos = p_from + rel * min; - - return true; -} - /* Point2i */ Point2i Point2i::operator+(const Point2i &p_v) const { @@ -153,244 +95,3 @@ bool Point2i::operator!=(const Point2i &p_vec2) const { return x != p_vec2.x || y != p_vec2.y; } - -void Transform2D::invert() { - // FIXME: this function assumes the basis is a rotation matrix, with no scaling. - // Transform2D::affine_inverse can handle matrices with scaling, so GDScript should eventually use that. - SWAP(elements[0][1], elements[1][0]); - elements[2] = basis_xform(-elements[2]); -} - -Transform2D Transform2D::inverse() const { - - Transform2D inv = *this; - inv.invert(); - return inv; -} - -void Transform2D::affine_invert() { - - real_t det = basis_determinant(); -#ifdef MATH_CHECKS - ERR_FAIL_COND(det == 0); -#endif - real_t idet = 1.0 / det; - - SWAP(elements[0][0], elements[1][1]); - elements[0] *= Vector2(idet, -idet); - elements[1] *= Vector2(-idet, idet); - - elements[2] = basis_xform(-elements[2]); -} - -Transform2D Transform2D::affine_inverse() const { - - Transform2D inv = *this; - inv.affine_invert(); - return inv; -} - -void Transform2D::rotate(real_t p_phi) { - *this = Transform2D(p_phi, Vector2()) * (*this); -} - -real_t Transform2D::get_rotation() const { - real_t det = basis_determinant(); - Transform2D m = orthonormalized(); - if (det < 0) { - m.scale_basis(Size2(1, -1)); // convention to separate rotation and reflection for 2D is to absorb a flip along y into scaling. - } - return Math::atan2(m[0].y, m[0].x); -} - -void Transform2D::set_rotation(real_t p_rot) { - - real_t cr = Math::cos(p_rot); - real_t sr = Math::sin(p_rot); - elements[0][0] = cr; - elements[0][1] = sr; - elements[1][0] = -sr; - elements[1][1] = cr; -} - -Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) { - - real_t cr = Math::cos(p_rot); - real_t sr = Math::sin(p_rot); - elements[0][0] = cr; - elements[0][1] = sr; - elements[1][0] = -sr; - elements[1][1] = cr; - elements[2] = p_pos; -} - -Size2 Transform2D::get_scale() const { - real_t det_sign = basis_determinant() > 0 ? 1 : -1; - return Size2(elements[0].length(), det_sign * elements[1].length()); -} - -void Transform2D::scale(const Size2 &p_scale) { - scale_basis(p_scale); - elements[2] *= p_scale; -} -void Transform2D::scale_basis(const Size2 &p_scale) { - - elements[0][0] *= p_scale.x; - elements[0][1] *= p_scale.y; - elements[1][0] *= p_scale.x; - elements[1][1] *= p_scale.y; -} -void Transform2D::translate(real_t p_tx, real_t p_ty) { - - translate(Vector2(p_tx, p_ty)); -} -void Transform2D::translate(const Vector2 &p_translation) { - - elements[2] += basis_xform(p_translation); -} - -void Transform2D::orthonormalize() { - - // Gram-Schmidt Process - - Vector2 x = elements[0]; - Vector2 y = elements[1]; - - x.normalize(); - y = (y - x * (x.dot(y))); - y.normalize(); - - elements[0] = x; - elements[1] = y; -} -Transform2D Transform2D::orthonormalized() const { - - Transform2D on = *this; - on.orthonormalize(); - return on; -} - -bool Transform2D::operator==(const Transform2D &p_transform) const { - - for (int i = 0; i < 3; i++) { - if (elements[i] != p_transform.elements[i]) - return false; - } - - return true; -} - -bool Transform2D::operator!=(const Transform2D &p_transform) const { - - for (int i = 0; i < 3; i++) { - if (elements[i] != p_transform.elements[i]) - return true; - } - - return false; -} - -void Transform2D::operator*=(const Transform2D &p_transform) { - - elements[2] = xform(p_transform.elements[2]); - - real_t x0, x1, y0, y1; - - x0 = tdotx(p_transform.elements[0]); - x1 = tdoty(p_transform.elements[0]); - y0 = tdotx(p_transform.elements[1]); - y1 = tdoty(p_transform.elements[1]); - - elements[0][0] = x0; - elements[0][1] = x1; - elements[1][0] = y0; - elements[1][1] = y1; -} - -Transform2D Transform2D::operator*(const Transform2D &p_transform) const { - - Transform2D t = *this; - t *= p_transform; - return t; -} - -Transform2D Transform2D::scaled(const Size2 &p_scale) const { - - Transform2D copy = *this; - copy.scale(p_scale); - return copy; -} - -Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const { - - Transform2D copy = *this; - copy.scale_basis(p_scale); - return copy; -} - -Transform2D Transform2D::untranslated() const { - - Transform2D copy = *this; - copy.elements[2] = Vector2(); - return copy; -} - -Transform2D Transform2D::translated(const Vector2 &p_offset) const { - - Transform2D copy = *this; - copy.translate(p_offset); - return copy; -} - -Transform2D Transform2D::rotated(real_t p_phi) const { - - Transform2D copy = *this; - copy.rotate(p_phi); - return copy; -} - -real_t Transform2D::basis_determinant() const { - - return elements[0].x * elements[1].y - elements[0].y * elements[1].x; -} - -Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t p_c) const { - - //extract parameters - Vector2 p1 = get_origin(); - Vector2 p2 = p_transform.get_origin(); - - real_t r1 = get_rotation(); - real_t r2 = p_transform.get_rotation(); - - Size2 s1 = get_scale(); - Size2 s2 = p_transform.get_scale(); - - //slerp rotation - Vector2 v1(Math::cos(r1), Math::sin(r1)); - Vector2 v2(Math::cos(r2), Math::sin(r2)); - - real_t dot = v1.dot(v2); - - dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1] - - Vector2 v; - - if (dot > 0.9995) { - v = Vector2::linear_interpolate(v1, v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues - } else { - real_t angle = p_c * Math::acos(dot); - Vector2 v3 = (v2 - v1 * dot).normalized(); - v = v1 * Math::cos(angle) + v3 * Math::sin(angle); - } - - //construct matrix - Transform2D res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c)); - res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c)); - return res; -} - -Transform2D::operator String() const { - - return String(String() + elements[0] + ", " + elements[1] + ", " + elements[2]); -} diff --git a/core/math/math_2d.h b/core/math/math_2d.h index a764e3e3cf..e5edb08a1f 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -31,212 +31,10 @@ #ifndef MATH_2D_H #define MATH_2D_H -#include "math_funcs.h" -#include "ustring.h" -#include "vector2.h" +#include "transform_2d.h" /** @author Juan Linietsky */ -struct Transform2D; - -struct Rect2 { - - Point2 position; - Size2 size; - - const Vector2 &get_position() const { return position; } - void set_position(const Vector2 &p_pos) { position = p_pos; } - const Vector2 &get_size() const { return size; } - void set_size(const Vector2 &p_size) { size = p_size; } - - 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 real_t distance_to(const Vector2 &p_point) const { - - real_t dist = 0.0; - bool inside = true; - - if (p_point.x < position.x) { - real_t d = position.x - p_point.x; - dist = inside ? d : MIN(dist, d); - inside = false; - } - if (p_point.y < position.y) { - real_t d = position.y - p_point.y; - dist = inside ? d : MIN(dist, d); - inside = false; - } - if (p_point.x >= (position.x + size.x)) { - real_t d = p_point.x - (position.x + size.x); - dist = inside ? d : MIN(dist, d); - inside = false; - } - if (p_point.y >= (position.y + size.y)) { - real_t d = p_point.y - (position.y + size.y); - dist = inside ? d : MIN(dist, d); - inside = false; - } - - if (inside) - return 0; - else - return dist; - } - - _FORCE_INLINE_ 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; - - inline bool encloses(const Rect2 &p_rect) const { - - return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && - ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && - ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); - } - - inline bool has_no_area() const { - - return (size.x <= 0 || size.y <= 0); - } - inline Rect2 clip(const Rect2 &p_rect) const { /// return a clipped rect - - Rect2 new_rect = p_rect; - - if (!intersects(new_rect)) - return Rect2(); - - new_rect.position.x = MAX(p_rect.position.x, position.x); - new_rect.position.y = MAX(p_rect.position.y, position.y); - - Point2 p_rect_end = p_rect.position + p_rect.size; - Point2 end = position + size; - - new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x; - new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y; - - return new_rect; - } - - inline Rect2 merge(const Rect2 &p_rect) const { ///< return a merged rect - - Rect2 new_rect; - - new_rect.position.x = MIN(p_rect.position.x, position.x); - new_rect.position.y = MIN(p_rect.position.y, position.y); - - new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); - new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); - - new_rect.size = new_rect.size - new_rect.position; //make relative again - - return new_rect; - }; - inline bool has_point(const Point2 &p_point) const { - if (p_point.x < position.x) - return false; - if (p_point.y < position.y) - return false; - - if (p_point.x >= (position.x + size.x)) - return false; - if (p_point.y >= (position.y + size.y)) - return false; - - return true; - } - - inline bool no_area() const { return (size.width <= 0 || size.height <= 0); } - - bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } - bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } - - inline Rect2 grow(real_t p_by) const { - - Rect2 g = *this; - g.position.x -= p_by; - g.position.y -= p_by; - g.size.width += p_by * 2; - g.size.height += p_by * 2; - return g; - } - - inline Rect2 grow_margin(Margin p_margin, real_t p_amount) const { - Rect2 g = *this; - g = g.grow_individual((MARGIN_LEFT == p_margin) ? p_amount : 0, - (MARGIN_TOP == p_margin) ? p_amount : 0, - (MARGIN_RIGHT == p_margin) ? p_amount : 0, - (MARGIN_BOTTOM == p_margin) ? p_amount : 0); - return g; - } - - inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const { - - Rect2 g = *this; - g.position.x -= p_left; - g.position.y -= p_top; - g.size.width += p_left + p_right; - g.size.height += p_top + p_bottom; - - return g; - } - - inline Rect2 expand(const Vector2 &p_vector) const { - - Rect2 r = *this; - r.expand_to(p_vector); - return r; - } - - inline void expand_to(const Vector2 &p_vector) { //in place function for speed - - Vector2 begin = position; - Vector2 end = position + size; - - if (p_vector.x < begin.x) - begin.x = p_vector.x; - if (p_vector.y < begin.y) - begin.y = p_vector.y; - - if (p_vector.x > end.x) - end.x = p_vector.x; - if (p_vector.y > end.y) - end.y = p_vector.y; - - position = begin; - size = end - begin; - } - - inline Rect2 abs() const { - - return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); - } - - operator String() const { return String(position) + ", " + String(size); } - - Rect2() {} - Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) : - position(Point2(p_x, p_y)), - size(Size2(p_width, p_height)) { - } - Rect2(const Point2 &p_pos, const Size2 &p_size) : - position(p_pos), - size(p_size) { - } -}; - /* INTEGER STUFF */ struct Point2i { @@ -435,320 +233,4 @@ struct Rect2i { } }; -struct Transform2D { - // Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper": - // M = (elements[0][0] elements[1][0]) - // (elements[0][1] elements[1][1]) - // This is such that the columns, which can be interpreted as basis vectors of the coordinate system "painted" on the object, can be accessed as elements[i]. - // Note that this is the opposite of the indices in mathematical texts, meaning: $M_{12}$ in a math book corresponds to elements[1][0] here. - // This requires additional care when working with explicit indices. - // See https://en.wikipedia.org/wiki/Row-_and_column-major_order for further reading. - - // Warning #2: 2D be aware that unlike 3D code, 2D code uses a left-handed coordinate system: Y-axis points down, - // and angle is measure from +X to +Y in a clockwise-fashion. - - Vector2 elements[3]; - - _FORCE_INLINE_ real_t tdotx(const Vector2 &v) const { return elements[0][0] * v.x + elements[1][0] * v.y; } - _FORCE_INLINE_ real_t tdoty(const Vector2 &v) const { return elements[0][1] * v.x + elements[1][1] * v.y; } - - const Vector2 &operator[](int p_idx) const { return elements[p_idx]; } - Vector2 &operator[](int p_idx) { return elements[p_idx]; } - - _FORCE_INLINE_ Vector2 get_axis(int p_axis) const { - ERR_FAIL_INDEX_V(p_axis, 3, Vector2()); - return elements[p_axis]; - } - _FORCE_INLINE_ void set_axis(int p_axis, const Vector2 &p_vec) { - ERR_FAIL_INDEX(p_axis, 3); - elements[p_axis] = p_vec; - } - - void invert(); - Transform2D inverse() const; - - void affine_invert(); - Transform2D affine_inverse() const; - - void set_rotation(real_t p_rot); - real_t get_rotation() const; - _FORCE_INLINE_ void set_rotation_and_scale(real_t p_rot, const Size2 &p_scale); - void rotate(real_t p_phi); - - void scale(const Size2 &p_scale); - void scale_basis(const Size2 &p_scale); - void translate(real_t p_tx, real_t p_ty); - void translate(const Vector2 &p_translation); - - real_t basis_determinant() const; - - Size2 get_scale() const; - - _FORCE_INLINE_ const Vector2 &get_origin() const { return elements[2]; } - _FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; } - - Transform2D scaled(const Size2 &p_scale) const; - Transform2D basis_scaled(const Size2 &p_scale) const; - Transform2D translated(const Vector2 &p_offset) const; - Transform2D rotated(real_t p_phi) const; - - Transform2D untranslated() const; - - void orthonormalize(); - Transform2D orthonormalized() const; - - bool operator==(const Transform2D &p_transform) const; - bool operator!=(const Transform2D &p_transform) const; - - void operator*=(const Transform2D &p_transform); - Transform2D operator*(const Transform2D &p_transform) const; - - Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const; - - _FORCE_INLINE_ Vector2 basis_xform(const Vector2 &p_vec) const; - _FORCE_INLINE_ Vector2 basis_xform_inv(const Vector2 &p_vec) const; - _FORCE_INLINE_ Vector2 xform(const Vector2 &p_vec) const; - _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; - - operator String() const; - - Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) { - - elements[0][0] = xx; - elements[0][1] = xy; - elements[1][0] = yx; - elements[1][1] = yy; - elements[2][0] = ox; - elements[2][1] = oy; - } - - Transform2D(real_t p_rot, const Vector2 &p_pos); - Transform2D() { - elements[0][0] = 1.0; - elements[1][1] = 1.0; - } -}; - -bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const { - - //SAT intersection between local and transformed rect2 - - Vector2 xf_points[4] = { - p_xform.xform(p_rect.position), - p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)), - p_xform.xform(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)), - p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)), - }; - - real_t low_limit; - - //base rect2 first (faster) - - if (xf_points[0].y > position.y) - goto next1; - if (xf_points[1].y > position.y) - goto next1; - if (xf_points[2].y > position.y) - goto next1; - if (xf_points[3].y > position.y) - goto next1; - - return false; - -next1: - - low_limit = position.y + size.y; - - if (xf_points[0].y < low_limit) - goto next2; - if (xf_points[1].y < low_limit) - goto next2; - if (xf_points[2].y < low_limit) - goto next2; - if (xf_points[3].y < low_limit) - goto next2; - - return false; - -next2: - - if (xf_points[0].x > position.x) - goto next3; - if (xf_points[1].x > position.x) - goto next3; - if (xf_points[2].x > position.x) - goto next3; - if (xf_points[3].x > position.x) - goto next3; - - return false; - -next3: - - low_limit = position.x + size.x; - - if (xf_points[0].x < low_limit) - goto next4; - if (xf_points[1].x < low_limit) - goto next4; - if (xf_points[2].x < low_limit) - goto next4; - if (xf_points[3].x < low_limit) - goto next4; - - return false; - -next4: - - Vector2 xf_points2[4] = { - position, - Vector2(position.x + size.x, position.y), - Vector2(position.x, position.y + size.y), - Vector2(position.x + size.x, position.y + size.y), - }; - - real_t maxa = p_xform.elements[0].dot(xf_points2[0]); - real_t mina = maxa; - - real_t dp = p_xform.elements[0].dot(xf_points2[1]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - dp = p_xform.elements[0].dot(xf_points2[2]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - dp = p_xform.elements[0].dot(xf_points2[3]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - real_t maxb = p_xform.elements[0].dot(xf_points[0]); - real_t minb = maxb; - - dp = p_xform.elements[0].dot(xf_points[1]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - dp = p_xform.elements[0].dot(xf_points[2]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - dp = p_xform.elements[0].dot(xf_points[3]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - if (mina > maxb) - return false; - if (minb > maxa) - return false; - - maxa = p_xform.elements[1].dot(xf_points2[0]); - mina = maxa; - - dp = p_xform.elements[1].dot(xf_points2[1]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - dp = p_xform.elements[1].dot(xf_points2[2]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - dp = p_xform.elements[1].dot(xf_points2[3]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - maxb = p_xform.elements[1].dot(xf_points[0]); - minb = maxb; - - dp = p_xform.elements[1].dot(xf_points[1]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - dp = p_xform.elements[1].dot(xf_points[2]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - dp = p_xform.elements[1].dot(xf_points[3]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - if (mina > maxb) - return false; - if (minb > maxa) - return false; - - return true; -} - -Vector2 Transform2D::basis_xform(const Vector2 &p_vec) const { - - return Vector2( - tdotx(p_vec), - tdoty(p_vec)); -} - -Vector2 Transform2D::basis_xform_inv(const Vector2 &p_vec) const { - - return Vector2( - elements[0].dot(p_vec), - elements[1].dot(p_vec)); -} - -Vector2 Transform2D::xform(const Vector2 &p_vec) const { - - return Vector2( - tdotx(p_vec), - tdoty(p_vec)) + - elements[2]; -} -Vector2 Transform2D::xform_inv(const Vector2 &p_vec) const { - - Vector2 v = p_vec - elements[2]; - - return Vector2( - elements[0].dot(v), - elements[1].dot(v)); -} -Rect2 Transform2D::xform(const Rect2 &p_rect) const { - - Vector2 x = elements[0] * p_rect.size.x; - Vector2 y = elements[1] * p_rect.size.y; - Vector2 pos = xform(p_rect.position); - - Rect2 new_rect; - new_rect.position = pos; - new_rect.expand_to(pos + x); - new_rect.expand_to(pos + y); - new_rect.expand_to(pos + x + y); - return new_rect; -} - -void Transform2D::set_rotation_and_scale(real_t p_rot, const Size2 &p_scale) { - - elements[0][0] = Math::cos(p_rot) * p_scale.x; - elements[1][1] = Math::cos(p_rot) * p_scale.y; - elements[1][0] = -Math::sin(p_rot) * p_scale.y; - elements[0][1] = Math::sin(p_rot) * p_scale.x; -} - -Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const { - - Vector2 ends[4] = { - xform_inv(p_rect.position), - xform_inv(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)), - xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)), - xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)) - }; - - Rect2 new_rect; - new_rect.position = ends[0]; - new_rect.expand_to(ends[1]); - new_rect.expand_to(ends[2]); - new_rect.expand_to(ends[3]); - - return new_rect; -} - #endif diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp new file mode 100644 index 0000000000..480bccdff1 --- /dev/null +++ b/core/math/rect2.cpp @@ -0,0 +1,240 @@ +/*************************************************************************/ +/* rect2.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D + +bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const { + + real_t min = 0, max = 1; + int axis = 0; + real_t sign = 0; + + for (int i = 0; i < 2; i++) { + real_t seg_from = p_from[i]; + real_t seg_to = p_to[i]; + real_t box_begin = position[i]; + real_t box_end = box_begin + size[i]; + real_t cmin, cmax; + real_t csign; + + if (seg_from < seg_to) { + + if (seg_from > box_end || seg_to < box_begin) + return false; + real_t length = seg_to - seg_from; + cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0; + cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1; + csign = -1.0; + + } else { + + if (seg_to > box_end || seg_from < box_begin) + return false; + real_t length = seg_to - seg_from; + cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0; + cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1; + csign = 1.0; + } + + if (cmin > min) { + min = cmin; + axis = i; + sign = csign; + } + if (cmax < max) + max = cmax; + if (max < min) + return false; + } + + Vector2 rel = p_to - p_from; + + if (r_normal) { + Vector2 normal; + normal[axis] = sign; + *r_normal = normal; + } + + if (r_pos) + *r_pos = p_from + rel * min; + + return true; +} + +bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const { + + //SAT intersection between local and transformed rect2 + + Vector2 xf_points[4] = { + p_xform.xform(p_rect.position), + p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)), + p_xform.xform(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)), + p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)), + }; + + real_t low_limit; + + //base rect2 first (faster) + + if (xf_points[0].y > position.y) + goto next1; + if (xf_points[1].y > position.y) + goto next1; + if (xf_points[2].y > position.y) + goto next1; + if (xf_points[3].y > position.y) + goto next1; + + return false; + +next1: + + low_limit = position.y + size.y; + + if (xf_points[0].y < low_limit) + goto next2; + if (xf_points[1].y < low_limit) + goto next2; + if (xf_points[2].y < low_limit) + goto next2; + if (xf_points[3].y < low_limit) + goto next2; + + return false; + +next2: + + if (xf_points[0].x > position.x) + goto next3; + if (xf_points[1].x > position.x) + goto next3; + if (xf_points[2].x > position.x) + goto next3; + if (xf_points[3].x > position.x) + goto next3; + + return false; + +next3: + + low_limit = position.x + size.x; + + if (xf_points[0].x < low_limit) + goto next4; + if (xf_points[1].x < low_limit) + goto next4; + if (xf_points[2].x < low_limit) + goto next4; + if (xf_points[3].x < low_limit) + goto next4; + + return false; + +next4: + + Vector2 xf_points2[4] = { + position, + Vector2(position.x + size.x, position.y), + Vector2(position.x, position.y + size.y), + Vector2(position.x + size.x, position.y + size.y), + }; + + real_t maxa = p_xform.elements[0].dot(xf_points2[0]); + real_t mina = maxa; + + real_t dp = p_xform.elements[0].dot(xf_points2[1]); + maxa = MAX(dp, maxa); + mina = MIN(dp, mina); + + dp = p_xform.elements[0].dot(xf_points2[2]); + maxa = MAX(dp, maxa); + mina = MIN(dp, mina); + + dp = p_xform.elements[0].dot(xf_points2[3]); + maxa = MAX(dp, maxa); + mina = MIN(dp, mina); + + real_t maxb = p_xform.elements[0].dot(xf_points[0]); + real_t minb = maxb; + + dp = p_xform.elements[0].dot(xf_points[1]); + maxb = MAX(dp, maxb); + minb = MIN(dp, minb); + + dp = p_xform.elements[0].dot(xf_points[2]); + maxb = MAX(dp, maxb); + minb = MIN(dp, minb); + + dp = p_xform.elements[0].dot(xf_points[3]); + maxb = MAX(dp, maxb); + minb = MIN(dp, minb); + + if (mina > maxb) + return false; + if (minb > maxa) + return false; + + maxa = p_xform.elements[1].dot(xf_points2[0]); + mina = maxa; + + dp = p_xform.elements[1].dot(xf_points2[1]); + maxa = MAX(dp, maxa); + mina = MIN(dp, mina); + + dp = p_xform.elements[1].dot(xf_points2[2]); + maxa = MAX(dp, maxa); + mina = MIN(dp, mina); + + dp = p_xform.elements[1].dot(xf_points2[3]); + maxa = MAX(dp, maxa); + mina = MIN(dp, mina); + + maxb = p_xform.elements[1].dot(xf_points[0]); + minb = maxb; + + dp = p_xform.elements[1].dot(xf_points[1]); + maxb = MAX(dp, maxb); + minb = MIN(dp, minb); + + dp = p_xform.elements[1].dot(xf_points[2]); + maxb = MAX(dp, maxb); + minb = MIN(dp, minb); + + dp = p_xform.elements[1].dot(xf_points[3]); + maxb = MAX(dp, maxb); + minb = MIN(dp, minb); + + if (mina > maxb) + return false; + if (minb > maxa) + return false; + + return true; +} diff --git a/core/math/rect2.h b/core/math/rect2.h new file mode 100644 index 0000000000..d156618be6 --- /dev/null +++ b/core/math/rect2.h @@ -0,0 +1,236 @@ +/*************************************************************************/ +/* rect2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 RECT2_H +#define RECT2_H + +#include "vector2.h" // also includes math_funcs and ustring + +struct Transform2D; + +struct Rect2 { + + Point2 position; + Size2 size; + + const Vector2 &get_position() const { return position; } + void set_position(const Vector2 &p_pos) { position = p_pos; } + const Vector2 &get_size() const { return size; } + void set_size(const Vector2 &p_size) { size = p_size; } + + 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 real_t distance_to(const Vector2 &p_point) const { + + real_t dist = 0.0; + bool inside = true; + + if (p_point.x < position.x) { + real_t d = position.x - p_point.x; + dist = inside ? d : MIN(dist, d); + inside = false; + } + if (p_point.y < position.y) { + real_t d = position.y - p_point.y; + dist = inside ? d : MIN(dist, d); + inside = false; + } + if (p_point.x >= (position.x + size.x)) { + real_t d = p_point.x - (position.x + size.x); + dist = inside ? d : MIN(dist, d); + inside = false; + } + if (p_point.y >= (position.y + size.y)) { + real_t d = p_point.y - (position.y + size.y); + dist = inside ? d : MIN(dist, d); + inside = false; + } + + if (inside) + return 0; + else + return dist; + } + + 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; + + inline bool encloses(const Rect2 &p_rect) const { + + return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && + ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && + ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); + } + + inline bool has_no_area() const { + + return (size.x <= 0 || size.y <= 0); + } + inline Rect2 clip(const Rect2 &p_rect) const { /// return a clipped rect + + Rect2 new_rect = p_rect; + + if (!intersects(new_rect)) + return Rect2(); + + new_rect.position.x = MAX(p_rect.position.x, position.x); + new_rect.position.y = MAX(p_rect.position.y, position.y); + + Point2 p_rect_end = p_rect.position + p_rect.size; + Point2 end = position + size; + + new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x; + new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y; + + return new_rect; + } + + inline Rect2 merge(const Rect2 &p_rect) const { ///< return a merged rect + + Rect2 new_rect; + + new_rect.position.x = MIN(p_rect.position.x, position.x); + new_rect.position.y = MIN(p_rect.position.y, position.y); + + new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); + new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); + + new_rect.size = new_rect.size - new_rect.position; //make relative again + + return new_rect; + }; + inline bool has_point(const Point2 &p_point) const { + if (p_point.x < position.x) + return false; + if (p_point.y < position.y) + return false; + + if (p_point.x >= (position.x + size.x)) + return false; + if (p_point.y >= (position.y + size.y)) + return false; + + return true; + } + + inline bool no_area() const { return (size.width <= 0 || size.height <= 0); } + + bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } + bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } + + inline Rect2 grow(real_t p_by) const { + + Rect2 g = *this; + g.position.x -= p_by; + g.position.y -= p_by; + g.size.width += p_by * 2; + g.size.height += p_by * 2; + return g; + } + + inline Rect2 grow_margin(Margin p_margin, real_t p_amount) const { + Rect2 g = *this; + g = g.grow_individual((MARGIN_LEFT == p_margin) ? p_amount : 0, + (MARGIN_TOP == p_margin) ? p_amount : 0, + (MARGIN_RIGHT == p_margin) ? p_amount : 0, + (MARGIN_BOTTOM == p_margin) ? p_amount : 0); + return g; + } + + inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const { + + Rect2 g = *this; + g.position.x -= p_left; + g.position.y -= p_top; + g.size.width += p_left + p_right; + g.size.height += p_top + p_bottom; + + return g; + } + + inline Rect2 expand(const Vector2 &p_vector) const { + + Rect2 r = *this; + r.expand_to(p_vector); + return r; + } + + inline void expand_to(const Vector2 &p_vector) { //in place function for speed + + Vector2 begin = position; + Vector2 end = position + size; + + if (p_vector.x < begin.x) + begin.x = p_vector.x; + if (p_vector.y < begin.y) + begin.y = p_vector.y; + + if (p_vector.x > end.x) + end.x = p_vector.x; + if (p_vector.y > end.y) + end.y = p_vector.y; + + position = begin; + size = end - begin; + } + + inline Rect2 abs() const { + + return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); + } + + operator String() const { return String(position) + ", " + String(size); } + + Rect2() {} + Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) : + position(Point2(p_x, p_y)), + size(Size2(p_width, p_height)) { + } + Rect2(const Point2 &p_pos, const Size2 &p_size) : + position(p_pos), + size(p_size) { + } +}; + +#endif // RECT2_H diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp new file mode 100644 index 0000000000..4bb763c879 --- /dev/null +++ b/core/math/transform_2d.cpp @@ -0,0 +1,272 @@ +/*************************************************************************/ +/* transform_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "transform_2d.h" + +void Transform2D::invert() { + // FIXME: this function assumes the basis is a rotation matrix, with no scaling. + // Transform2D::affine_inverse can handle matrices with scaling, so GDScript should eventually use that. + SWAP(elements[0][1], elements[1][0]); + elements[2] = basis_xform(-elements[2]); +} + +Transform2D Transform2D::inverse() const { + + Transform2D inv = *this; + inv.invert(); + return inv; +} + +void Transform2D::affine_invert() { + + real_t det = basis_determinant(); +#ifdef MATH_CHECKS + ERR_FAIL_COND(det == 0); +#endif + real_t idet = 1.0 / det; + + SWAP(elements[0][0], elements[1][1]); + elements[0] *= Vector2(idet, -idet); + elements[1] *= Vector2(-idet, idet); + + elements[2] = basis_xform(-elements[2]); +} + +Transform2D Transform2D::affine_inverse() const { + + Transform2D inv = *this; + inv.affine_invert(); + return inv; +} + +void Transform2D::rotate(real_t p_phi) { + *this = Transform2D(p_phi, Vector2()) * (*this); +} + +real_t Transform2D::get_rotation() const { + real_t det = basis_determinant(); + Transform2D m = orthonormalized(); + if (det < 0) { + m.scale_basis(Size2(1, -1)); // convention to separate rotation and reflection for 2D is to absorb a flip along y into scaling. + } + return Math::atan2(m[0].y, m[0].x); +} + +void Transform2D::set_rotation(real_t p_rot) { + + real_t cr = Math::cos(p_rot); + real_t sr = Math::sin(p_rot); + elements[0][0] = cr; + elements[0][1] = sr; + elements[1][0] = -sr; + elements[1][1] = cr; +} + +Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) { + + real_t cr = Math::cos(p_rot); + real_t sr = Math::sin(p_rot); + elements[0][0] = cr; + elements[0][1] = sr; + elements[1][0] = -sr; + elements[1][1] = cr; + elements[2] = p_pos; +} + +Size2 Transform2D::get_scale() const { + real_t det_sign = basis_determinant() > 0 ? 1 : -1; + return Size2(elements[0].length(), det_sign * elements[1].length()); +} + +void Transform2D::scale(const Size2 &p_scale) { + scale_basis(p_scale); + elements[2] *= p_scale; +} +void Transform2D::scale_basis(const Size2 &p_scale) { + + elements[0][0] *= p_scale.x; + elements[0][1] *= p_scale.y; + elements[1][0] *= p_scale.x; + elements[1][1] *= p_scale.y; +} +void Transform2D::translate(real_t p_tx, real_t p_ty) { + + translate(Vector2(p_tx, p_ty)); +} +void Transform2D::translate(const Vector2 &p_translation) { + + elements[2] += basis_xform(p_translation); +} + +void Transform2D::orthonormalize() { + + // Gram-Schmidt Process + + Vector2 x = elements[0]; + Vector2 y = elements[1]; + + x.normalize(); + y = (y - x * (x.dot(y))); + y.normalize(); + + elements[0] = x; + elements[1] = y; +} +Transform2D Transform2D::orthonormalized() const { + + Transform2D on = *this; + on.orthonormalize(); + return on; +} + +bool Transform2D::operator==(const Transform2D &p_transform) const { + + for (int i = 0; i < 3; i++) { + if (elements[i] != p_transform.elements[i]) + return false; + } + + return true; +} + +bool Transform2D::operator!=(const Transform2D &p_transform) const { + + for (int i = 0; i < 3; i++) { + if (elements[i] != p_transform.elements[i]) + return true; + } + + return false; +} + +void Transform2D::operator*=(const Transform2D &p_transform) { + + elements[2] = xform(p_transform.elements[2]); + + real_t x0, x1, y0, y1; + + x0 = tdotx(p_transform.elements[0]); + x1 = tdoty(p_transform.elements[0]); + y0 = tdotx(p_transform.elements[1]); + y1 = tdoty(p_transform.elements[1]); + + elements[0][0] = x0; + elements[0][1] = x1; + elements[1][0] = y0; + elements[1][1] = y1; +} + +Transform2D Transform2D::operator*(const Transform2D &p_transform) const { + + Transform2D t = *this; + t *= p_transform; + return t; +} + +Transform2D Transform2D::scaled(const Size2 &p_scale) const { + + Transform2D copy = *this; + copy.scale(p_scale); + return copy; +} + +Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const { + + Transform2D copy = *this; + copy.scale_basis(p_scale); + return copy; +} + +Transform2D Transform2D::untranslated() const { + + Transform2D copy = *this; + copy.elements[2] = Vector2(); + return copy; +} + +Transform2D Transform2D::translated(const Vector2 &p_offset) const { + + Transform2D copy = *this; + copy.translate(p_offset); + return copy; +} + +Transform2D Transform2D::rotated(real_t p_phi) const { + + Transform2D copy = *this; + copy.rotate(p_phi); + return copy; +} + +real_t Transform2D::basis_determinant() const { + + return elements[0].x * elements[1].y - elements[0].y * elements[1].x; +} + +Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t p_c) const { + + //extract parameters + Vector2 p1 = get_origin(); + Vector2 p2 = p_transform.get_origin(); + + real_t r1 = get_rotation(); + real_t r2 = p_transform.get_rotation(); + + Size2 s1 = get_scale(); + Size2 s2 = p_transform.get_scale(); + + //slerp rotation + Vector2 v1(Math::cos(r1), Math::sin(r1)); + Vector2 v2(Math::cos(r2), Math::sin(r2)); + + real_t dot = v1.dot(v2); + + dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1] + + Vector2 v; + + if (dot > 0.9995) { + v = Vector2::linear_interpolate(v1, v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues + } else { + real_t angle = p_c * Math::acos(dot); + Vector2 v3 = (v2 - v1 * dot).normalized(); + v = v1 * Math::cos(angle) + v3 * Math::sin(angle); + } + + //construct matrix + Transform2D res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c)); + res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c)); + return res; +} + +Transform2D::operator String() const { + + return String(String() + elements[0] + ", " + elements[1] + ", " + elements[2]); +} diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h new file mode 100644 index 0000000000..bf73755f0d --- /dev/null +++ b/core/math/transform_2d.h @@ -0,0 +1,201 @@ +/*************************************************************************/ +/* transform_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 TRANSFORM_2D_H +#define TRANSFORM_2D_H + +#include "rect2.h" // also includes vector2, math_funcs, and ustring + +struct Transform2D { + // Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper": + // M = (elements[0][0] elements[1][0]) + // (elements[0][1] elements[1][1]) + // This is such that the columns, which can be interpreted as basis vectors of the coordinate system "painted" on the object, can be accessed as elements[i]. + // Note that this is the opposite of the indices in mathematical texts, meaning: $M_{12}$ in a math book corresponds to elements[1][0] here. + // This requires additional care when working with explicit indices. + // See https://en.wikipedia.org/wiki/Row-_and_column-major_order for further reading. + + // Warning #2: 2D be aware that unlike 3D code, 2D code uses a left-handed coordinate system: Y-axis points down, + // and angle is measure from +X to +Y in a clockwise-fashion. + + Vector2 elements[3]; + + _FORCE_INLINE_ real_t tdotx(const Vector2 &v) const { return elements[0][0] * v.x + elements[1][0] * v.y; } + _FORCE_INLINE_ real_t tdoty(const Vector2 &v) const { return elements[0][1] * v.x + elements[1][1] * v.y; } + + const Vector2 &operator[](int p_idx) const { return elements[p_idx]; } + Vector2 &operator[](int p_idx) { return elements[p_idx]; } + + _FORCE_INLINE_ Vector2 get_axis(int p_axis) const { + ERR_FAIL_INDEX_V(p_axis, 3, Vector2()); + return elements[p_axis]; + } + _FORCE_INLINE_ void set_axis(int p_axis, const Vector2 &p_vec) { + ERR_FAIL_INDEX(p_axis, 3); + elements[p_axis] = p_vec; + } + + void invert(); + Transform2D inverse() const; + + void affine_invert(); + Transform2D affine_inverse() const; + + void set_rotation(real_t p_rot); + real_t get_rotation() const; + _FORCE_INLINE_ void set_rotation_and_scale(real_t p_rot, const Size2 &p_scale); + void rotate(real_t p_phi); + + void scale(const Size2 &p_scale); + void scale_basis(const Size2 &p_scale); + void translate(real_t p_tx, real_t p_ty); + void translate(const Vector2 &p_translation); + + real_t basis_determinant() const; + + Size2 get_scale() const; + + _FORCE_INLINE_ const Vector2 &get_origin() const { return elements[2]; } + _FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; } + + Transform2D scaled(const Size2 &p_scale) const; + Transform2D basis_scaled(const Size2 &p_scale) const; + Transform2D translated(const Vector2 &p_offset) const; + Transform2D rotated(real_t p_phi) const; + + Transform2D untranslated() const; + + void orthonormalize(); + Transform2D orthonormalized() const; + + bool operator==(const Transform2D &p_transform) const; + bool operator!=(const Transform2D &p_transform) const; + + void operator*=(const Transform2D &p_transform); + Transform2D operator*(const Transform2D &p_transform) const; + + Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const; + + _FORCE_INLINE_ Vector2 basis_xform(const Vector2 &p_vec) const; + _FORCE_INLINE_ Vector2 basis_xform_inv(const Vector2 &p_vec) const; + _FORCE_INLINE_ Vector2 xform(const Vector2 &p_vec) const; + _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; + + operator String() const; + + Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) { + + elements[0][0] = xx; + elements[0][1] = xy; + elements[1][0] = yx; + elements[1][1] = yy; + elements[2][0] = ox; + elements[2][1] = oy; + } + + Transform2D(real_t p_rot, const Vector2 &p_pos); + Transform2D() { + elements[0][0] = 1.0; + elements[1][1] = 1.0; + } +}; + +Vector2 Transform2D::basis_xform(const Vector2 &p_vec) const { + + return Vector2( + tdotx(p_vec), + tdoty(p_vec)); +} + +Vector2 Transform2D::basis_xform_inv(const Vector2 &p_vec) const { + + return Vector2( + elements[0].dot(p_vec), + elements[1].dot(p_vec)); +} + +Vector2 Transform2D::xform(const Vector2 &p_vec) const { + + return Vector2( + tdotx(p_vec), + tdoty(p_vec)) + + elements[2]; +} +Vector2 Transform2D::xform_inv(const Vector2 &p_vec) const { + + Vector2 v = p_vec - elements[2]; + + return Vector2( + elements[0].dot(v), + elements[1].dot(v)); +} +Rect2 Transform2D::xform(const Rect2 &p_rect) const { + + Vector2 x = elements[0] * p_rect.size.x; + Vector2 y = elements[1] * p_rect.size.y; + Vector2 pos = xform(p_rect.position); + + Rect2 new_rect; + new_rect.position = pos; + new_rect.expand_to(pos + x); + new_rect.expand_to(pos + y); + new_rect.expand_to(pos + x + y); + return new_rect; +} + +void Transform2D::set_rotation_and_scale(real_t p_rot, const Size2 &p_scale) { + + elements[0][0] = Math::cos(p_rot) * p_scale.x; + elements[1][1] = Math::cos(p_rot) * p_scale.y; + elements[1][0] = -Math::sin(p_rot) * p_scale.y; + elements[0][1] = Math::sin(p_rot) * p_scale.x; +} + +Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const { + + Vector2 ends[4] = { + xform_inv(p_rect.position), + xform_inv(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)), + xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)), + xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)) + }; + + Rect2 new_rect; + new_rect.position = ends[0]; + new_rect.expand_to(ends[1]); + new_rect.expand_to(ends[2]); + new_rect.expand_to(ends[3]); + + return new_rect; +} + +#endif // TRANSFORM_2D_H -- cgit v1.2.3 From 14fe7230f4db402fba1efb74a1a17ce8a4dd20bb Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sat, 11 Aug 2018 00:32:45 -0500 Subject: [Core] Move Vector2i and Rect2i out of math_2d.h --- core/math/math_2d.cpp | 97 ------------------------ core/math/math_2d.h | 200 -------------------------------------------------- core/math/rect2.h | 135 ++++++++++++++++++++++++++++++++++ core/math/vector2.cpp | 66 +++++++++++++++++ core/math/vector2.h | 66 +++++++++++++++++ 5 files changed, 267 insertions(+), 297 deletions(-) delete mode 100644 core/math/math_2d.cpp diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp deleted file mode 100644 index eccf0552b6..0000000000 --- a/core/math/math_2d.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************/ -/* math_2d.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 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 "math_2d.h" - -/* Point2i */ - -Point2i Point2i::operator+(const Point2i &p_v) const { - - return Point2i(x + p_v.x, y + p_v.y); -} -void Point2i::operator+=(const Point2i &p_v) { - - x += p_v.x; - y += p_v.y; -} -Point2i Point2i::operator-(const Point2i &p_v) const { - - return Point2i(x - p_v.x, y - p_v.y); -} -void Point2i::operator-=(const Point2i &p_v) { - - x -= p_v.x; - y -= p_v.y; -} - -Point2i Point2i::operator*(const Point2i &p_v1) const { - - return Point2i(x * p_v1.x, y * p_v1.y); -}; - -Point2i Point2i::operator*(const int &rvalue) const { - - return Point2i(x * rvalue, y * rvalue); -}; -void Point2i::operator*=(const int &rvalue) { - - x *= rvalue; - y *= rvalue; -}; - -Point2i Point2i::operator/(const Point2i &p_v1) const { - - return Point2i(x / p_v1.x, y / p_v1.y); -}; - -Point2i Point2i::operator/(const int &rvalue) const { - - return Point2i(x / rvalue, y / rvalue); -}; - -void Point2i::operator/=(const int &rvalue) { - - x /= rvalue; - y /= rvalue; -}; - -Point2i Point2i::operator-() const { - - return Point2i(-x, -y); -} - -bool Point2i::operator==(const Point2i &p_vec2) const { - - return x == p_vec2.x && y == p_vec2.y; -} -bool Point2i::operator!=(const Point2i &p_vec2) const { - - return x != p_vec2.x || y != p_vec2.y; -} diff --git a/core/math/math_2d.h b/core/math/math_2d.h index e5edb08a1f..6105eba81b 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -32,205 +32,5 @@ #define MATH_2D_H #include "transform_2d.h" -/** - @author Juan Linietsky -*/ -/* INTEGER STUFF */ - -struct Point2i { - - union { - int x; - int width; - }; - union { - int y; - int height; - }; - - _FORCE_INLINE_ int &operator[](int p_idx) { - return p_idx ? y : x; - } - _FORCE_INLINE_ const int &operator[](int p_idx) const { - return p_idx ? y : x; - } - - Point2i operator+(const Point2i &p_v) const; - void operator+=(const Point2i &p_v); - Point2i operator-(const Point2i &p_v) const; - void operator-=(const Point2i &p_v); - Point2i operator*(const Point2i &p_v1) const; - - Point2i operator*(const int &rvalue) const; - void operator*=(const int &rvalue); - - Point2i operator/(const Point2i &p_v1) const; - - Point2i operator/(const int &rvalue) const; - - void operator/=(const int &rvalue); - - Point2i operator-() const; - bool operator<(const Point2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } - bool operator>(const Point2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } - - bool operator==(const Point2i &p_vec2) const; - bool operator!=(const Point2i &p_vec2) const; - - real_t get_aspect() const { return width / (real_t)height; } - - operator String() const { return String::num(x) + ", " + String::num(y); } - - operator Vector2() const { return Vector2(x, y); } - inline Point2i(const Vector2 &p_vec2) { - x = (int)p_vec2.x; - y = (int)p_vec2.y; - } - inline Point2i(int p_x, int p_y) { - x = p_x; - y = p_y; - } - inline Point2i() { - x = 0; - y = 0; - } -}; - -typedef Point2i Size2i; - -struct Rect2i { - - Point2i position; - Size2i size; - - const Point2i &get_position() const { return position; } - void set_position(const Point2i &p_pos) { position = p_pos; } - const Point2i &get_size() const { return size; } - void set_size(const Point2i &p_size) { size = p_size; } - - int get_area() const { return size.width * size.height; } - - inline bool intersects(const Rect2i &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 encloses(const Rect2i &p_rect) const { - - return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && - ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && - ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); - } - - inline bool has_no_area() const { - - return (size.x <= 0 || size.y <= 0); - } - inline Rect2i clip(const Rect2i &p_rect) const { /// return a clipped rect - - Rect2i new_rect = p_rect; - - if (!intersects(new_rect)) - return Rect2i(); - - new_rect.position.x = MAX(p_rect.position.x, position.x); - new_rect.position.y = MAX(p_rect.position.y, position.y); - - Point2 p_rect_end = p_rect.position + p_rect.size; - Point2 end = position + size; - - new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x); - new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y); - - return new_rect; - } - - inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect - - Rect2i new_rect; - - new_rect.position.x = MIN(p_rect.position.x, position.x); - new_rect.position.y = MIN(p_rect.position.y, position.y); - - new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); - new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); - - new_rect.size = new_rect.size - new_rect.position; //make relative again - - return new_rect; - }; - bool has_point(const Point2 &p_point) const { - if (p_point.x < position.x) - return false; - if (p_point.y < position.y) - return false; - - if (p_point.x >= (position.x + size.x)) - return false; - if (p_point.y >= (position.y + size.y)) - return false; - - return true; - } - - bool no_area() { return (size.width <= 0 || size.height <= 0); } - - bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } - bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } - - Rect2i grow(int p_by) const { - - Rect2i g = *this; - g.position.x -= p_by; - g.position.y -= p_by; - g.size.width += p_by * 2; - g.size.height += p_by * 2; - return g; - } - - inline void expand_to(const Point2i &p_vector) { - - Point2i begin = position; - Point2i end = position + size; - - if (p_vector.x < begin.x) - begin.x = p_vector.x; - if (p_vector.y < begin.y) - begin.y = p_vector.y; - - if (p_vector.x > end.x) - end.x = p_vector.x; - if (p_vector.y > end.y) - end.y = p_vector.y; - - position = begin; - size = end - begin; - } - - operator String() const { return String(position) + ", " + String(size); } - - operator Rect2() const { return Rect2(position, size); } - Rect2i(const Rect2 &p_r2) : - position(p_r2.position), - size(p_r2.size) { - } - Rect2i() {} - Rect2i(int p_x, int p_y, int p_width, int p_height) : - position(Point2(p_x, p_y)), - size(Size2(p_width, p_height)) { - } - Rect2i(const Point2 &p_pos, const Size2 &p_size) : - position(p_pos), - size(p_size) { - } -}; #endif diff --git a/core/math/rect2.h b/core/math/rect2.h index d156618be6..20329bee0d 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -233,4 +233,139 @@ struct Rect2 { } }; +struct Rect2i { + + Point2i position; + Size2i size; + + const Point2i &get_position() const { return position; } + void set_position(const Point2i &p_position) { position = p_position; } + const Size2i &get_size() const { return size; } + void set_size(const Size2i &p_size) { size = p_size; } + + int get_area() const { return size.width * size.height; } + + inline bool intersects(const Rect2i &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 encloses(const Rect2i &p_rect) const { + + return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && + ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && + ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); + } + + inline bool has_no_area() const { + + return (size.x <= 0 || size.y <= 0); + } + inline Rect2i clip(const Rect2i &p_rect) const { /// return a clipped rect + + Rect2i new_rect = p_rect; + + if (!intersects(new_rect)) + return Rect2i(); + + new_rect.position.x = MAX(p_rect.position.x, position.x); + new_rect.position.y = MAX(p_rect.position.y, position.y); + + Point2 p_rect_end = p_rect.position + p_rect.size; + Point2 end = position + size; + + new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x); + new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y); + + return new_rect; + } + + inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect + + Rect2i new_rect; + + new_rect.position.x = MIN(p_rect.position.x, position.x); + new_rect.position.y = MIN(p_rect.position.y, position.y); + + new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); + new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); + + new_rect.size = new_rect.size - new_rect.position; //make relative again + + return new_rect; + }; + bool has_point(const Point2 &p_point) const { + if (p_point.x < position.x) + return false; + if (p_point.y < position.y) + return false; + + if (p_point.x >= (position.x + size.x)) + return false; + if (p_point.y >= (position.y + size.y)) + return false; + + return true; + } + + bool no_area() { return (size.width <= 0 || size.height <= 0); } + + bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } + bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } + + Rect2i grow(int p_by) const { + + Rect2i g = *this; + g.position.x -= p_by; + g.position.y -= p_by; + g.size.width += p_by * 2; + g.size.height += p_by * 2; + return g; + } + + inline void expand_to(const Point2i &p_vector) { + + Point2i begin = position; + Point2i end = position + size; + + if (p_vector.x < begin.x) + begin.x = p_vector.x; + if (p_vector.y < begin.y) + begin.y = p_vector.y; + + if (p_vector.x > end.x) + end.x = p_vector.x; + if (p_vector.y > end.y) + end.y = p_vector.y; + + position = begin; + size = end - begin; + } + + operator String() const { return String(position) + ", " + String(size); } + + operator Rect2() const { return Rect2(position, size); } + Rect2i(const Rect2 &p_r2) : + position(p_r2.position), + size(p_r2.size) { + } + Rect2i() {} + Rect2i(int p_x, int p_y, int p_width, int p_height) : + position(Point2(p_x, p_y)), + size(Size2(p_width, p_height)) { + } + Rect2i(const Point2 &p_pos, const Size2 &p_size) : + position(p_pos), + size(p_size) { + } +}; + #endif // RECT2_H diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 8e59ddbd07..441e7d8907 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -185,3 +185,69 @@ Vector2 Vector2::reflect(const Vector2 &p_normal) const { #endif return 2.0 * p_normal * this->dot(p_normal) - *this; } + +/* Vector2i */ + +Vector2i Vector2i::operator+(const Vector2i &p_v) const { + + return Vector2i(x + p_v.x, y + p_v.y); +} +void Vector2i::operator+=(const Vector2i &p_v) { + + x += p_v.x; + y += p_v.y; +} +Vector2i Vector2i::operator-(const Vector2i &p_v) const { + + return Vector2i(x - p_v.x, y - p_v.y); +} +void Vector2i::operator-=(const Vector2i &p_v) { + + x -= p_v.x; + y -= p_v.y; +} + +Vector2i Vector2i::operator*(const Vector2i &p_v1) const { + + return Vector2i(x * p_v1.x, y * p_v1.y); +}; + +Vector2i Vector2i::operator*(const int &rvalue) const { + + return Vector2i(x * rvalue, y * rvalue); +}; +void Vector2i::operator*=(const int &rvalue) { + + x *= rvalue; + y *= rvalue; +}; + +Vector2i Vector2i::operator/(const Vector2i &p_v1) const { + + return Vector2i(x / p_v1.x, y / p_v1.y); +}; + +Vector2i Vector2i::operator/(const int &rvalue) const { + + return Vector2i(x / rvalue, y / rvalue); +}; + +void Vector2i::operator/=(const int &rvalue) { + + x /= rvalue; + y /= rvalue; +}; + +Vector2i Vector2i::operator-() const { + + return Vector2i(-x, -y); +} + +bool Vector2i::operator==(const Vector2i &p_vec2) const { + + return x == p_vec2.x && y == p_vec2.y; +} +bool Vector2i::operator!=(const Vector2i &p_vec2) const { + + return x != p_vec2.x || y != p_vec2.y; +} diff --git a/core/math/vector2.h b/core/math/vector2.h index 809cedf9c9..7c8882f6e2 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -34,6 +34,8 @@ #include "math_funcs.h" #include "ustring.h" +struct Vector2i; + struct Vector2 { union { @@ -247,4 +249,68 @@ Vector2 Vector2::linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real typedef Vector2 Size2; typedef Vector2 Point2; +/* INTEGER STUFF */ + +struct Vector2i { + + union { + int x; + int width; + }; + union { + int y; + int height; + }; + + _FORCE_INLINE_ int &operator[](int p_idx) { + return p_idx ? y : x; + } + _FORCE_INLINE_ const int &operator[](int p_idx) const { + return p_idx ? y : x; + } + + Vector2i operator+(const Vector2i &p_v) const; + void operator+=(const Vector2i &p_v); + Vector2i operator-(const Vector2i &p_v) const; + void operator-=(const Vector2i &p_v); + Vector2i operator*(const Vector2i &p_v1) const; + + Vector2i operator*(const int &rvalue) const; + void operator*=(const int &rvalue); + + Vector2i operator/(const Vector2i &p_v1) const; + + Vector2i operator/(const int &rvalue) const; + + void operator/=(const int &rvalue); + + Vector2i operator-() const; + 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; } + + operator String() const { return String::num(x) + ", " + String::num(y); } + + operator Vector2() const { return Vector2(x, y); } + inline Vector2i(const Vector2 &p_vec2) { + x = (int)p_vec2.x; + y = (int)p_vec2.y; + } + inline Vector2i(int p_x, int p_y) { + x = p_x; + y = p_y; + } + inline Vector2i() { + x = 0; + y = 0; + } +}; + +typedef Vector2i Size2i; +typedef Vector2i Point2i; + #endif // VECTOR2_H -- cgit v1.2.3 From cf136a91d60509a99f9ba47c7dbc6fbb9cb6240d Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sat, 11 Aug 2018 03:08:26 -0500 Subject: [Core] Completely kill math_2d.h, change includes --- core/image.h | 2 +- core/math/camera_matrix.h | 2 +- core/math/delaunay.h | 2 +- core/math/geometry.h | 2 +- core/math/math_2d.h | 36 ------------------------------- core/method_ptrcall.h | 2 +- core/os/input_event.h | 2 +- core/variant.h | 2 +- modules/csg/csg.h | 2 +- modules/gdnative/gdnative/rect2.cpp | 2 +- modules/gdnative/gdnative/transform2d.cpp | 2 +- platform/uwp/os_uwp.h | 2 +- scene/gui/control.h | 2 +- scene/main/viewport.h | 2 +- scene/resources/texture.h | 2 +- servers/physics_2d/broad_phase_2d_sw.h | 2 +- servers/visual_server.h | 2 +- 17 files changed, 16 insertions(+), 52 deletions(-) delete mode 100644 core/math/math_2d.h diff --git a/core/image.h b/core/image.h index c8dd647c31..c450e88290 100644 --- a/core/image.h +++ b/core/image.h @@ -33,7 +33,7 @@ #include "color.h" #include "dvector.h" -#include "math_2d.h" +#include "rect2.h" #include "resource.h" /** diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 226b4d572b..a689c7238a 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -31,7 +31,7 @@ #ifndef CAMERA_MATRIX_H #define CAMERA_MATRIX_H -#include "math_2d.h" +#include "rect2.h" #include "transform.h" /** @author Juan Linietsky diff --git a/core/math/delaunay.h b/core/math/delaunay.h index 13fbc0c6ae..46535d5ce9 100644 --- a/core/math/delaunay.h +++ b/core/math/delaunay.h @@ -1,7 +1,7 @@ #ifndef DELAUNAY_H #define DELAUNAY_H -#include "math_2d.h" +#include "rect2.h" class Delaunay2D { public: diff --git a/core/math/geometry.h b/core/math/geometry.h index 186a05fb37..83b9467a30 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -33,9 +33,9 @@ #include "dvector.h" #include "face3.h" -#include "math_2d.h" #include "object.h" #include "print_string.h" +#include "rect2.h" #include "triangulate.h" #include "vector.h" #include "vector3.h" diff --git a/core/math/math_2d.h b/core/math/math_2d.h deleted file mode 100644 index 6105eba81b..0000000000 --- a/core/math/math_2d.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************/ -/* math_2d.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 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 MATH_2D_H -#define MATH_2D_H - -#include "transform_2d.h" - -#endif diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h index 2f6dcb3178..6a33cf4d70 100644 --- a/core/method_ptrcall.h +++ b/core/method_ptrcall.h @@ -31,7 +31,7 @@ #ifndef METHOD_PTRCALL_H #define METHOD_PTRCALL_H -#include "math_2d.h" +#include "transform_2d.h" #include "typedefs.h" #include "variant.h" diff --git a/core/os/input_event.h b/core/os/input_event.h index 07df81488b..8732c7e377 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -31,9 +31,9 @@ #ifndef INPUT_EVENT_H #define INPUT_EVENT_H -#include "math_2d.h" #include "os/copymem.h" #include "resource.h" +#include "transform_2d.h" #include "typedefs.h" #include "ustring.h" /** diff --git a/core/variant.h b/core/variant.h index b48a0b3e73..577a33aa4d 100644 --- a/core/variant.h +++ b/core/variant.h @@ -42,7 +42,6 @@ #include "dvector.h" #include "face3.h" #include "io/ip_address.h" -#include "math_2d.h" #include "matrix3.h" #include "node_path.h" #include "plane.h" @@ -50,6 +49,7 @@ #include "ref_ptr.h" #include "rid.h" #include "transform.h" +#include "transform_2d.h" #include "ustring.h" #include "vector3.h" diff --git a/modules/csg/csg.h b/modules/csg/csg.h index 53303a6533..2e07c23e28 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -34,9 +34,9 @@ #include "aabb.h" #include "dvector.h" #include "map.h" -#include "math_2d.h" #include "oa_hash_map.h" #include "plane.h" +#include "rect2.h" #include "scene/resources/material.h" #include "transform.h" #include "vector3.h" diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp index 83c58db520..54b98fc4e5 100644 --- a/modules/gdnative/gdnative/rect2.cpp +++ b/modules/gdnative/gdnative/rect2.cpp @@ -30,7 +30,7 @@ #include "gdnative/rect2.h" -#include "core/math/math_2d.h" +#include "core/math/transform_2d.h" #include "core/variant.h" #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index c69607a18a..fa0e15d9d2 100644 --- a/modules/gdnative/gdnative/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -30,7 +30,7 @@ #include "gdnative/transform2d.h" -#include "core/math/math_2d.h" +#include "core/math/transform_2d.h" #include "core/variant.h" #ifdef __cplusplus diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 3b48063fe9..89f71f0013 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -31,7 +31,7 @@ #ifndef OSUWP_H #define OSUWP_H -#include "core/math/math_2d.h" +#include "core/math/transform_2d.h" #include "core/ustring.h" #include "drivers/xaudio2/audio_driver_xaudio2.h" #include "gl_context_egl.h" diff --git a/scene/gui/control.h b/scene/gui/control.h index 6bea04345b..c6bd2f097d 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -31,13 +31,13 @@ #ifndef CONTROL_H #define CONTROL_H -#include "math_2d.h" #include "rid.h" #include "scene/2d/canvas_item.h" #include "scene/gui/shortcut.h" #include "scene/main/node.h" #include "scene/main/timer.h" #include "scene/resources/theme.h" +#include "transform_2d.h" /** @author Juan Linietsky */ diff --git a/scene/main/viewport.h b/scene/main/viewport.h index e717d27069..e4ef373c77 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -31,11 +31,11 @@ #ifndef VIEWPORT_H #define VIEWPORT_H -#include "math_2d.h" #include "scene/main/node.h" #include "scene/resources/texture.h" #include "scene/resources/world_2d.h" #include "servers/visual_server.h" +#include "transform_2d.h" /** @author Juan Linietsky */ diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 1c18189b2c..e5d1166de5 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -33,9 +33,9 @@ #include "curve.h" #include "io/resource_loader.h" -#include "math_2d.h" #include "os/mutex.h" #include "os/thread_safe.h" +#include "rect2.h" #include "resource.h" #include "scene/resources/color_ramp.h" #include "servers/visual_server.h" diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h index 80ae970624..d7d236c4c6 100644 --- a/servers/physics_2d/broad_phase_2d_sw.h +++ b/servers/physics_2d/broad_phase_2d_sw.h @@ -31,8 +31,8 @@ #ifndef BROAD_PHASE_2D_SW_H #define BROAD_PHASE_2D_SW_H -#include "math_2d.h" #include "math_funcs.h" +#include "rect2.h" class CollisionObject2DSW; diff --git a/servers/visual_server.h b/servers/visual_server.h index 0ec902c18c..fd7f96339e 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -34,9 +34,9 @@ #include "bsp_tree.h" #include "geometry.h" #include "image.h" -#include "math_2d.h" #include "object.h" #include "rid.h" +#include "transform_2d.h" #include "variant.h" /** -- cgit v1.2.3