Add Vector2/3 sign and posmod functions, misc additions

Also make the docs more consistent, add Axis enum to Vector2, add > and >=. and C# also gets % and an override for vector-vector mod.
This commit is contained in:
Aaron Franke 2019-08-04 18:50:28 -07:00
parent cc9f2a2d8b
commit 092346d82b
No known key found for this signature in database
GPG key ID: 40A1750B977E56BF
8 changed files with 237 additions and 14 deletions

View file

@ -98,6 +98,11 @@ real_t Vector2::cross(const Vector2 &p_other) const {
return x * p_other.y - y * p_other.x;
}
Vector2 Vector2::sign() const {
return Vector2(SGN(x), SGN(y));
}
Vector2 Vector2::floor() const {
return Vector2(Math::floor(x), Math::floor(y));
@ -121,6 +126,14 @@ Vector2 Vector2::rotated(real_t p_by) const {
return v;
}
Vector2 Vector2::posmod(const real_t p_mod) const {
return Vector2(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod));
}
Vector2 Vector2::posmodv(const Vector2 &p_modv) const {
return Vector2(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y));
}
Vector2 Vector2::project(const Vector2 &p_b) const {
return p_b * (dot(p_b) / p_b.length_squared());
}

View file

@ -38,6 +38,11 @@ struct Vector2i;
struct Vector2 {
enum Axis {
AXIS_X,
AXIS_Y,
};
union {
real_t x;
real_t width;
@ -69,6 +74,8 @@ struct Vector2 {
real_t dot(const Vector2 &p_other) const;
real_t cross(const Vector2 &p_other) const;
Vector2 posmod(const real_t p_mod) const;
Vector2 posmodv(const Vector2 &p_modv) const;
Vector2 project(const Vector2 &p_b) const;
Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const;
@ -107,8 +114,10 @@ struct Vector2 {
bool operator==(const Vector2 &p_vec2) const;
bool operator!=(const Vector2 &p_vec2) const;
bool operator<(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y < p_vec2.y) : (x < p_vec2.x); }
bool operator<=(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y <= p_vec2.y) : (x < p_vec2.x); }
bool operator<(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
bool operator>(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
bool operator<=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y <= p_vec2.y) : (x < p_vec2.x); }
bool operator>=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y >= p_vec2.y) : (x > p_vec2.x); }
real_t angle() const;
@ -129,6 +138,7 @@ struct Vector2 {
return Vector2(y, -x);
}
Vector2 sign() const;
Vector2 floor() const;
Vector2 ceil() const;
Vector2 round() const;
@ -141,10 +151,7 @@ struct Vector2 {
x = p_x;
y = p_y;
}
_FORCE_INLINE_ Vector2() {
x = 0;
y = 0;
}
_FORCE_INLINE_ Vector2() { x = y = 0; }
};
_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const {
@ -262,6 +269,11 @@ typedef Vector2 Point2;
struct Vector2i {
enum Axis {
AXIS_X,
AXIS_Y,
};
union {
int x;
int width;

View file

@ -31,9 +31,7 @@
#ifndef VECTOR3_H
#define VECTOR3_H
#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
#include "core/typedefs.h"
#include "core/ustring.h"
class Basis;
@ -110,6 +108,8 @@ struct Vector3 {
_FORCE_INLINE_ real_t distance_to(const Vector3 &p_b) const;
_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_b) const;
_FORCE_INLINE_ Vector3 posmod(const real_t p_mod) const;
_FORCE_INLINE_ Vector3 posmodv(const Vector3 &p_modv) const;
_FORCE_INLINE_ Vector3 project(const Vector3 &p_b) const;
_FORCE_INLINE_ real_t angle_to(const Vector3 &p_b) const;
@ -141,15 +141,17 @@ struct Vector3 {
_FORCE_INLINE_ bool operator!=(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator<(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator<=(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator>(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const;
operator String() const;
_FORCE_INLINE_ Vector3() { x = y = z = 0; }
_FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) {
x = p_x;
y = p_y;
z = p_z;
}
_FORCE_INLINE_ Vector3() { x = y = z = 0; }
};
// Should be included after class definition, otherwise we get circular refs
@ -233,6 +235,14 @@ real_t Vector3::distance_squared_to(const Vector3 &p_b) const {
return (p_b - *this).length_squared();
}
Vector3 Vector3::posmod(const real_t p_mod) const {
return Vector3(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod), Math::fposmod(z, p_mod));
}
Vector3 Vector3::posmodv(const Vector3 &p_modv) const {
return Vector3(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y), Math::fposmod(z, p_modv.z));
}
Vector3 Vector3::project(const Vector3 &p_b) const {
return p_b * (dot(p_b) / p_b.length_squared());
}
@ -357,6 +367,18 @@ bool Vector3::operator<(const Vector3 &p_v) const {
}
}
bool Vector3::operator>(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y)
return z > p_v.z;
else
return y > p_v.y;
} else {
return x > p_v.x;
}
}
bool Vector3::operator<=(const Vector3 &p_v) const {
if (Math::is_equal_approx(x, p_v.x)) {
@ -369,6 +391,18 @@ bool Vector3::operator<=(const Vector3 &p_v) const {
}
}
bool Vector3::operator>=(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y)
return z >= p_v.z;
else
return y > p_v.y;
} else {
return x > p_v.x;
}
}
_FORCE_INLINE_ Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) {
return p_a.cross(p_b);

View file

@ -347,6 +347,8 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Vector2, is_normalized);
VCALL_LOCALMEM1R(Vector2, distance_to);
VCALL_LOCALMEM1R(Vector2, distance_squared_to);
VCALL_LOCALMEM1R(Vector2, posmod);
VCALL_LOCALMEM1R(Vector2, posmodv);
VCALL_LOCALMEM1R(Vector2, project);
VCALL_LOCALMEM1R(Vector2, angle_to);
VCALL_LOCALMEM1R(Vector2, angle_to_point);
@ -370,6 +372,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Vector2, cross);
VCALL_LOCALMEM0R(Vector2, abs);
VCALL_LOCALMEM1R(Vector2, clamped);
VCALL_LOCALMEM0R(Vector2, sign);
VCALL_LOCALMEM0R(Rect2, get_area);
VCALL_LOCALMEM1R(Rect2, intersects);
@ -407,12 +410,15 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Vector3, round);
VCALL_LOCALMEM1R(Vector3, distance_to);
VCALL_LOCALMEM1R(Vector3, distance_squared_to);
VCALL_LOCALMEM1R(Vector3, posmod);
VCALL_LOCALMEM1R(Vector3, posmodv);
VCALL_LOCALMEM1R(Vector3, project);
VCALL_LOCALMEM1R(Vector3, angle_to);
VCALL_LOCALMEM1R(Vector3, direction_to);
VCALL_LOCALMEM1R(Vector3, slide);
VCALL_LOCALMEM1R(Vector3, bounce);
VCALL_LOCALMEM1R(Vector3, reflect);
VCALL_LOCALMEM0R(Vector3, sign);
VCALL_LOCALMEM0R(Plane, normalized);
VCALL_LOCALMEM0R(Plane, center);
@ -1590,6 +1596,8 @@ void register_variant_methods() {
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, direction_to, VECTOR2, "b", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, distance_to, VECTOR2, "to", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, distance_squared_to, VECTOR2, "to", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmod, REAL, "mod", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmodv, VECTOR2, "modv", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, project, VECTOR2, "b", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to, VECTOR2, "to", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to_point, VECTOR2, "to", varray());
@ -1611,6 +1619,7 @@ void register_variant_methods() {
ADDFUNC1R(VECTOR2, REAL, Vector2, cross, VECTOR2, "with", varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, abs, varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, clamped, REAL, "length", varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, sign, varray());
ADDFUNC0R(RECT2, REAL, Rect2, get_area, varray());
ADDFUNC1R(RECT2, BOOL, Rect2, intersects, RECT2, "b", varray());
@ -1649,11 +1658,14 @@ void register_variant_methods() {
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, round, varray());
ADDFUNC1R(VECTOR3, REAL, Vector3, distance_to, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, REAL, Vector3, distance_squared_to, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmod, REAL, "mod", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmodv, VECTOR3, "modv", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, project, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, REAL, Vector3, angle_to, VECTOR3, "to", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, slide, VECTOR3, "n", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, bounce, VECTOR3, "n", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, reflect, VECTOR3, "n", varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, sign, varray());
ADDFUNC0R(PLANE, PLANE, Plane, normalized, varray());
ADDFUNC0R(PLANE, VECTOR3, Plane, center, varray());
@ -1946,6 +1958,9 @@ void register_variant_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1));
_VariantCall::add_constant(Variant::VECTOR2, "AXIS_X", Vector2::AXIS_X);
_VariantCall::add_constant(Variant::VECTOR2, "AXIS_Y", Vector2::AXIS_Y);
_VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1));
_VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF));

View file

@ -203,6 +203,24 @@
Returns the vector scaled to unit length. Equivalent to [code]v / v.length()[/code].
</description>
</method>
<method name="posmod">
<return type="Vector2">
</return>
<argument index="0" name="mod" type="float">
</argument>
<description>
Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]mod[/code].
</description>
</method>
<method name="posmodv">
<return type="Vector2">
</return>
<argument index="0" name="mod" type="float">
</argument>
<description>
Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]modv[/code]'s components.
</description>
</method>
<method name="project">
<return type="Vector2">
</return>
@ -237,6 +255,13 @@
Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
</description>
</method>
<method name="sign">
<return type="Vector2">
</return>
<description>
Returns the vector with each component set to one or negative one, depending on the signs of the components.
</description>
</method>
<method name="slerp">
<return type="Vector2">
</return>
@ -284,6 +309,12 @@
</member>
</members>
<constants>
<constant name="AXIS_X" value="0">
Enumerated value for the X axis. Returned by [method max_axis] and [method min_axis].
</constant>
<constant name="AXIS_Y" value="1">
Enumerated value for the Y axis.
</constant>
<constant name="ZERO" value="Vector2( 0, 0 )">
Zero vector.
</constant>
@ -291,7 +322,7 @@
One vector.
</constant>
<constant name="INF" value="Vector2( inf, inf )">
Infinite vector.
Infinity vector.
</constant>
<constant name="LEFT" value="Vector2( -1, 0 )">
Left unit vector.

View file

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Vector3" category="Built-In Types" version="3.2">
<brief_description>
Vector class, which performs basic 3D vector math operations.
Vector used for 3D math.
</brief_description>
<description>
Vector3 is one of the core classes of the engine, and includes several built-in helper functions to perform basic vector math operations.
3-element structure that can be used to represent positions in 3D space or any other pair of numeric values.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
@ -202,6 +202,24 @@
Returns the outer product with [code]b[/code].
</description>
</method>
<method name="posmod">
<return type="Vector3">
</return>
<argument index="0" name="mod" type="float">
</argument>
<description>
Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]mod[/code].
</description>
</method>
<method name="posmodv">
<return type="Vector3">
</return>
<argument index="0" name="mod" type="float">
</argument>
<description>
Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]modv[/code]'s components.
</description>
</method>
<method name="project">
<return type="Vector3">
</return>
@ -238,6 +256,13 @@
Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
</description>
</method>
<method name="sign">
<return type="Vector3">
</return>
<description>
Returns the vector with each component set to one or negative one, depending on the signs of the components.
</description>
</method>
<method name="slerp">
<return type="Vector3">
</return>
@ -304,7 +329,7 @@
One vector.
</constant>
<constant name="INF" value="Vector3( inf, inf, inf )">
Infinite vector.
Infinity vector.
</constant>
<constant name="LEFT" value="Vector3( -1, 0, 0 )">
Left unit vector.

View file

@ -14,10 +14,19 @@ using real_t = System.Single;
namespace Godot
{
/// <summary>
/// 2-element structure that can be used to represent positions in 2D space or any other pair of numeric values.
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Vector2 : IEquatable<Vector2>
{
public enum Axis
{
X = 0,
Y
}
public real_t x;
public real_t y;
@ -202,6 +211,22 @@ namespace Godot
return v;
}
public Vector2 PosMod(real_t mod)
{
Vector2 v;
v.x = Mathf.PosMod(x, mod);
v.y = Mathf.PosMod(y, mod);
return v;
}
public Vector2 PosMod(Vector2 modv)
{
Vector2 v;
v.x = Mathf.PosMod(x, modv.x);
v.y = Mathf.PosMod(y, modv.y);
return v;
}
public Vector2 Project(Vector2 onNormal)
{
return onNormal * (Dot(onNormal) / onNormal.LengthSquared());
@ -236,6 +261,14 @@ namespace Godot
y = v.y;
}
public Vector2 Sign()
{
Vector2 v;
v.x = Mathf.Sign(x);
v.y = Mathf.Sign(y);
return v;
}
public Vector2 Slerp(Vector2 b, real_t t)
{
real_t theta = AngleTo(b);
@ -265,7 +298,7 @@ namespace Godot
private static readonly Vector2 _up = new Vector2(0, -1);
private static readonly Vector2 _down = new Vector2(0, 1);
private static readonly Vector2 _right = new Vector2(1, 0);
private static readonly Vector2 _right = new Vector2(1, 0);
private static readonly Vector2 _left = new Vector2(-1, 0);
public static Vector2 Zero { get { return _zero; } }
@ -346,6 +379,20 @@ namespace Godot
return left;
}
public static Vector2 operator %(Vector2 vec, real_t divisor)
{
vec.x %= divisor;
vec.y %= divisor;
return vec;
}
public static Vector2 operator %(Vector2 vec, Vector2 divisorv)
{
vec.x %= divisorv.x;
vec.y %= divisorv.y;
return vec;
}
public static bool operator ==(Vector2 left, Vector2 right)
{
return left.Equals(right);

View file

@ -14,6 +14,9 @@ using real_t = System.Single;
namespace Godot
{
/// <summary>
/// 3-element structure that can be used to represent positions in 3D space or any other pair of numeric values.
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Vector3 : IEquatable<Vector3>
@ -225,6 +228,24 @@ namespace Godot
);
}
public Vector3 PosMod(real_t mod)
{
Vector3 v;
v.x = Mathf.PosMod(x, mod);
v.y = Mathf.PosMod(y, mod);
v.z = Mathf.PosMod(z, mod);
return v;
}
public Vector3 PosMod(Vector3 modv)
{
Vector3 v;
v.x = Mathf.PosMod(x, modv.x);
v.y = Mathf.PosMod(y, modv.y);
v.z = Mathf.PosMod(z, modv.z);
return v;
}
public Vector3 Project(Vector3 onNormal)
{
return onNormal * (Dot(onNormal) / onNormal.LengthSquared());
@ -264,6 +285,15 @@ namespace Godot
z = v.z;
}
public Vector3 Sign()
{
Vector3 v;
v.x = Mathf.Sign(x);
v.y = Mathf.Sign(y);
v.z = Mathf.Sign(z);
return v;
}
public Vector3 Slerp(Vector3 b, real_t t)
{
real_t theta = AngleTo(b);
@ -397,6 +427,22 @@ namespace Godot
return left;
}
public static Vector3 operator %(Vector3 vec, real_t divisor)
{
vec.x %= divisor;
vec.y %= divisor;
vec.z %= divisor;
return vec;
}
public static Vector3 operator %(Vector3 vec, Vector3 divisorv)
{
vec.x %= divisorv.x;
vec.y %= divisorv.y;
vec.z %= divisorv.z;
return vec;
}
public static bool operator ==(Vector3 left, Vector3 right)
{
return left.Equals(right);