Refactor Vector types to support 64-bit precision via define switch
This commit is contained in:
@@ -31,7 +31,7 @@ namespace CSG
|
||||
Surface()
|
||||
: Plane()
|
||||
, TexCoordScale(1)
|
||||
, TexCoordOffset(0)
|
||||
, TexCoordOffset(0.0f)
|
||||
, TexCoordRotation(0)
|
||||
, ScaleInLightmap(1)
|
||||
{
|
||||
@@ -41,7 +41,7 @@ namespace CSG
|
||||
: Plane(plane)
|
||||
, Material(Guid::Empty)
|
||||
, TexCoordScale(1)
|
||||
, TexCoordOffset(0)
|
||||
, TexCoordOffset(0.0f)
|
||||
, TexCoordRotation(0)
|
||||
, ScaleInLightmap(1)
|
||||
{
|
||||
@@ -51,7 +51,7 @@ namespace CSG
|
||||
: Plane(plane)
|
||||
, Material(plane.Material)
|
||||
, TexCoordScale(1)
|
||||
, TexCoordOffset(0)
|
||||
, TexCoordOffset(0.0f)
|
||||
, TexCoordRotation(0)
|
||||
, ScaleInLightmap(1)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ namespace CSG
|
||||
: Plane(normal, d)
|
||||
, Material(Guid::Empty)
|
||||
, TexCoordScale(1)
|
||||
, TexCoordOffset(0)
|
||||
, TexCoordOffset(0.0f)
|
||||
, TexCoordRotation(0)
|
||||
, ScaleInLightmap(1)
|
||||
{
|
||||
@@ -71,7 +71,7 @@ namespace CSG
|
||||
: Plane(point1, point2, point3)
|
||||
, Material(Guid::Empty)
|
||||
, TexCoordScale(1)
|
||||
, TexCoordOffset(0)
|
||||
, TexCoordOffset(0.0f)
|
||||
, TexCoordRotation(0)
|
||||
, ScaleInLightmap(1)
|
||||
{
|
||||
|
||||
@@ -46,7 +46,6 @@ using namespace CSGBuilderImpl;
|
||||
class CSGBuilderService : public EngineService
|
||||
{
|
||||
public:
|
||||
|
||||
CSGBuilderService()
|
||||
: EngineService(TEXT("CSG Builder"), 90)
|
||||
{
|
||||
@@ -336,7 +335,8 @@ bool CSGBuilderImpl::buildInner(Scene* scene, BuildData& data)
|
||||
for (int32 meshIndex = 0; meshIndex < lod->Meshes.Count(); meshIndex++)
|
||||
{
|
||||
const auto v = &lod->Meshes[meshIndex]->Positions;
|
||||
Vector3::Transform(v->Get(), m2, v->Get(), v->Count());
|
||||
for (int32 i = 0; i < v->Count(); i++)
|
||||
Vector3::Transform(v->Get()[i], m2, v->Get()[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
struct Vector2;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Ray;
|
||||
struct Plane;
|
||||
struct Rectangle;
|
||||
struct BoundingBox;
|
||||
struct BoundingSphere;
|
||||
struct BoundingFrustum;
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
|
||||
/// <summary>
|
||||
/// Describes how one bounding volume contains another.
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
class String;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Color32;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
class String;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Color;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Double2.h"
|
||||
#include "Double3.h"
|
||||
#include "Double4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
#include "Color.h"
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
static_assert(sizeof(Double2) == 16, "Invalid Double2 type size.");
|
||||
|
||||
const Double2 Double2::Zero(0.0);
|
||||
const Double2 Double2::One(1.0);
|
||||
const Double2 Double2::UnitX(1.0, 0.0);
|
||||
const Double2 Double2::UnitY(0.0, 1.0);
|
||||
const Double2 Double2::Minimum(MIN_double);
|
||||
const Double2 Double2::Maximum(MAX_double);
|
||||
|
||||
Double2::Double2(const Int2& xy)
|
||||
: X(static_cast<double>(xy.X))
|
||||
, Y(static_cast<double>(xy.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Double2::Double2(const Int3& xyz)
|
||||
: X(static_cast<double>(xyz.X))
|
||||
, Y(static_cast<double>(xyz.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Double2::Double2(const Int4& xyzw)
|
||||
: X(static_cast<double>(xyzw.X))
|
||||
, Y(static_cast<double>(xyzw.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Double2::Double2(const Vector2& xy)
|
||||
: X(static_cast<double>(xy.X))
|
||||
, Y(static_cast<double>(xy.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Double2::Double2(const Vector3& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Double2::Double2(const Vector4& xyzw)
|
||||
: X(xyzw.X)
|
||||
, Y(xyzw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Double2::Double2(const Double3& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Double2::Double2(const Double4& xyzw)
|
||||
: X(xyzw.X)
|
||||
, Y(xyzw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Double2::Double2(const Color& color)
|
||||
: X(color.R)
|
||||
, Y(color.G)
|
||||
{
|
||||
}
|
||||
|
||||
String Double2::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
Double2 Double2::Normalize(const Double2& v)
|
||||
{
|
||||
Double2 result = v;
|
||||
const double length = v.Length();
|
||||
if (!Math::IsZero(length))
|
||||
{
|
||||
const double inv = 1. / length;
|
||||
result.X *= inv;
|
||||
result.Y *= inv;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Int2 Double2::CeilToInt(const Double2& v)
|
||||
{
|
||||
return Int2((int32)Math::CeilToInt(v.X), (int32)Math::CeilToInt(v.Y));
|
||||
}
|
||||
|
||||
Int2 Double2::FloorToInt(const Double2& v)
|
||||
{
|
||||
return Int2((int32)Math::FloorToInt(v.X), (int32)Math::FloorToInt(v.Y));
|
||||
}
|
||||
|
||||
double Double2::TriangleArea(const Double2& v0, const Double2& v1, const Double2& v2)
|
||||
{
|
||||
return Math::Abs((v0.X * (v1.Y - v2.Y) + v1.X * (v2.Y - v0.Y) + v2.X * (v0.Y - v1.Y)) / 2.);
|
||||
}
|
||||
|
||||
double Double2::Angle(const Double2& from, const Double2& to)
|
||||
{
|
||||
const double dot = Math::Clamp(Dot(Normalize(from), Normalize(to)), -1.0, 1.0);
|
||||
if (Math::Abs(dot) > (1.0 - ZeroTolerance))
|
||||
return dot > 0.0 ? 0.0 : PI;
|
||||
return Math::Acos(dot);
|
||||
}
|
||||
@@ -2,625 +2,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Math.h"
|
||||
#include "Mathd.h"
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
struct Double3;
|
||||
struct Double4;
|
||||
struct Vector2;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Int2;
|
||||
struct Int3;
|
||||
struct Int4;
|
||||
struct Color;
|
||||
struct Matrix;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a two dimensional mathematical vector with 64-bit precision (per-component).
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API Double2
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Double2);
|
||||
public:
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component of the vector.
|
||||
/// </summary>
|
||||
API_FIELD() double X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the vector.
|
||||
/// </summary>
|
||||
API_FIELD() double Y;
|
||||
};
|
||||
|
||||
// Raw values
|
||||
double Raw[2];
|
||||
};
|
||||
|
||||
public:
|
||||
// Vector with all components equal 0
|
||||
static const Double2 Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Double2 One;
|
||||
|
||||
// Vector X=1, Y=0
|
||||
static const Double2 UnitX;
|
||||
|
||||
// Vector X=0, Y=1
|
||||
static const Double2 UnitY;
|
||||
|
||||
// A minimum Double2
|
||||
static const Double2 Minimum;
|
||||
|
||||
// A maximum Double2
|
||||
static const Double2 Maximum;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor.
|
||||
/// </summary>
|
||||
Double2()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xy Value to assign to the all components
|
||||
Double2(double xy)
|
||||
: X(xy)
|
||||
, Y(xy)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param x X component value
|
||||
// @param y Y component value
|
||||
Double2(double x, double y)
|
||||
: X(x)
|
||||
, Y(y)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init
|
||||
/// </summary>
|
||||
/// <param name="v">X and Z components in an array</param>
|
||||
explicit Double2(double xy[2])
|
||||
: X(xy[0])
|
||||
, Y(xy[1])
|
||||
{
|
||||
}
|
||||
|
||||
explicit Double2(const Int2& xy);
|
||||
explicit Double2(const Int3& xyz);
|
||||
explicit Double2(const Int4& xyzw);
|
||||
Double2(const Vector2& xy);
|
||||
explicit Double2(const Vector3& xyz);
|
||||
explicit Double2(const Vector4& xyzw);
|
||||
explicit Double2(const Double3& xyz);
|
||||
explicit Double2(const Double4& xyzw);
|
||||
explicit Double2(const Color& color);
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
|
||||
public:
|
||||
// Arithmetic operators with Double2
|
||||
Double2 operator+(const Double2& b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Double2 operator-(const Double2& b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Double2 operator*(const Double2& b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Double2 operator/(const Double2& b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
Double2 operator-() const
|
||||
{
|
||||
return Double2(-X, -Y);
|
||||
}
|
||||
|
||||
// op= operators with Double2
|
||||
Double2& operator+=(const Double2& b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double2& operator-=(const Double2& b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double2& operator*=(const Double2& b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double2& operator/=(const Double2& b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators with double
|
||||
Double2 operator+(double b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Double2 operator-(double b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Double2 operator*(double b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Double2 operator/(double b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
// op= operators with double
|
||||
Double2& operator+=(double b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double2& operator-=(double b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double2& operator*=(double b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double2& operator/=(double b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
bool operator==(const Double2& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y;
|
||||
}
|
||||
|
||||
bool operator!=(const Double2& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y;
|
||||
}
|
||||
|
||||
bool operator>(const Double2& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y;
|
||||
}
|
||||
|
||||
bool operator>=(const Double2& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y;
|
||||
}
|
||||
|
||||
bool operator<(const Double2& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y;
|
||||
}
|
||||
|
||||
bool operator<=(const Double2& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y;
|
||||
}
|
||||
|
||||
public:
|
||||
static bool NearEqual(const Double2& a, const Double2& b)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X) && Math::NearEqual(a.Y, b.Y);
|
||||
}
|
||||
|
||||
static bool NearEqual(const Double2& a, const Double2& b, double epsilon)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X, epsilon) && Math::NearEqual(a.Y, b.Y, epsilon);
|
||||
}
|
||||
|
||||
public:
|
||||
static double Dot(const Double2& a, const Double2& b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y;
|
||||
}
|
||||
|
||||
static double Cross(const Double2& a, const Double2& b)
|
||||
{
|
||||
return a.X * b.Y - a.Y * b.X;
|
||||
}
|
||||
|
||||
static void Add(const Double2& a, const Double2& b, Double2& result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
}
|
||||
|
||||
static Double2 Add(const Double2& a, const Double2& b)
|
||||
{
|
||||
Double2 result;
|
||||
Add(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Subtract(const Double2& a, const Double2& b, Double2& result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
}
|
||||
|
||||
static Double2 Subtract(const Double2& a, const Double2& b)
|
||||
{
|
||||
Double2 result;
|
||||
Subtract(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Double2 Multiply(const Double2& a, const Double2& b)
|
||||
{
|
||||
return Double2(a.X * b.X, a.Y * b.Y);
|
||||
}
|
||||
|
||||
static Double2 Multiply(const Double2& a, double b)
|
||||
{
|
||||
return Double2(a.X * b, a.Y * b);
|
||||
}
|
||||
|
||||
static Double2 Divide(const Double2& a, const Double2& b)
|
||||
{
|
||||
return Double2(a.X / b.X, a.Y / b.Y);
|
||||
}
|
||||
|
||||
static Double2 Divide(const Double2& a, double b)
|
||||
{
|
||||
return Double2(a.X / b, a.Y / b);
|
||||
}
|
||||
|
||||
// Calculates distance between two points in 2D
|
||||
// @param a 1st point
|
||||
// @param b 2nd point
|
||||
// @returns Distance
|
||||
static double Distance(const Double2& a, const Double2& b)
|
||||
{
|
||||
const double x = a.X - b.X;
|
||||
const double y = a.Y - b.Y;
|
||||
return Math::Sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
// Calculates the squared distance between two points in 2D
|
||||
// @param a 1st point
|
||||
// @param b 2nd point
|
||||
// @returns Distance
|
||||
static double DistanceSquared(const Double2& a, const Double2& b)
|
||||
{
|
||||
const double x = a.X - b.X;
|
||||
const double y = a.Y - b.Y;
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
// Clamp vector values within given range
|
||||
// @param v Vector to clamp
|
||||
// @param min Minimum value
|
||||
// @param max Maximum value
|
||||
// @returns Clamped vector
|
||||
static Double2 Clamp(const Double2& v, double min, double max)
|
||||
{
|
||||
return Double2(Math::Clamp(v.X, min, max), Math::Clamp(v.Y, min, max));
|
||||
}
|
||||
|
||||
// Clamp vector values within given range
|
||||
// @param v Vector to clamp
|
||||
// @param min Minimum value
|
||||
// @param max Maximum value
|
||||
// @returns Clamped vector
|
||||
static Double2 Clamp(const Double2& v, const Double2& min, const Double2& max)
|
||||
{
|
||||
return Double2(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y));
|
||||
}
|
||||
|
||||
// Performs vector normalization (scales vector up to unit length)
|
||||
void Normalize()
|
||||
{
|
||||
const double length = Length();
|
||||
if (!Math::IsZero(length))
|
||||
{
|
||||
const double invLength = 1.0 / length;
|
||||
X *= invLength;
|
||||
Y *= invLength;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// Gets a value indicting whether this instance is normalized.
|
||||
bool IsNormalized() const
|
||||
{
|
||||
return Math::IsOne(X * X + Y * Y);
|
||||
}
|
||||
|
||||
// Gets a value indicting whether this vector is zero.
|
||||
bool IsZero() const
|
||||
{
|
||||
return Math::IsZero(X) && Math::IsZero(Y);
|
||||
}
|
||||
|
||||
// Gets a value indicting whether any vector component is zero.
|
||||
bool IsAnyZero() const
|
||||
{
|
||||
return Math::IsZero(X) || Math::IsZero(Y);
|
||||
}
|
||||
|
||||
// Gets a value indicting whether this vector is zero.
|
||||
bool IsOne() const
|
||||
{
|
||||
return Math::IsOne(X) && Math::IsOne(Y);
|
||||
}
|
||||
|
||||
// Calculates length of the vector.
|
||||
double Length() const
|
||||
{
|
||||
return Math::Sqrt(X * X + Y * Y);
|
||||
}
|
||||
|
||||
// Calculates the squared length of the vector.
|
||||
double LengthSquared() const
|
||||
{
|
||||
return X * X + Y * Y;
|
||||
}
|
||||
|
||||
// Calculates inverted length of the vector (1 / length).
|
||||
double InvLength() const
|
||||
{
|
||||
return 1. / Length();
|
||||
}
|
||||
|
||||
// Calculates a vector with values being absolute values of that vector.
|
||||
Double2 GetAbsolute() const
|
||||
{
|
||||
return Double2(Math::Abs(X), Math::Abs(Y));
|
||||
}
|
||||
|
||||
// Calculates a vector with values being opposite to values of that vector.
|
||||
Double2 GetNegative() const
|
||||
{
|
||||
return Double2(-X, -Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the average arithmetic of all the components.
|
||||
/// </summary>
|
||||
double AverageArithmetic() const
|
||||
{
|
||||
return (X + Y) * 0.5;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sum of all vector components values.
|
||||
/// </summary>
|
||||
double SumValues() const
|
||||
{
|
||||
return X + Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the multiplication result of all vector components values.
|
||||
/// </summary>
|
||||
double MulValues() const
|
||||
{
|
||||
return X * Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the minimum value of all the components.
|
||||
/// </summary>
|
||||
double MinValue() const
|
||||
{
|
||||
return Math::Min(X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum value of all the components.
|
||||
/// </summary>
|
||||
double MaxValue() const
|
||||
{
|
||||
return Math::Max(X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components is not a number (NaN).
|
||||
/// </summary>
|
||||
bool IsNaN() const
|
||||
{
|
||||
return isnan(X) || isnan(Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components equal to +/- infinity.
|
||||
/// </summary>
|
||||
bool IsInfinity() const
|
||||
{
|
||||
return isinf(X) || isinf(Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components equal to +/- infinity or NaN.
|
||||
/// </summary>
|
||||
bool IsNanOrInfinity() const
|
||||
{
|
||||
return IsInfinity() || IsNaN();
|
||||
}
|
||||
|
||||
public:
|
||||
// Performs a linear interpolation between two vectors
|
||||
// @param start Start vector
|
||||
// @param end End vector
|
||||
// @param amount Value between 0 and 1 indicating the weight of end
|
||||
// @param result When the method completes, contains the linear interpolation of the two vectors
|
||||
static void Lerp(const Double2& start, const Double2& end, double amount, Double2& result)
|
||||
{
|
||||
result.X = Math::Lerp(start.X, end.X, amount);
|
||||
result.Y = Math::Lerp(start.Y, end.Y, amount);
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// Performs a linear interpolation between two vectors.
|
||||
// </summary>
|
||||
// @param start Start vector,
|
||||
// @param end End vector,
|
||||
// @param amount Value between 0 and 1 indicating the weight of @paramref end"/>,
|
||||
// @returns The linear interpolation of the two vectors
|
||||
static Double2 Lerp(const Double2& start, const Double2& end, double amount)
|
||||
{
|
||||
Double2 result;
|
||||
Lerp(start, end, amount, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Double2 Abs(const Double2& v)
|
||||
{
|
||||
return Double2(Math::Abs(v.X), Math::Abs(v.Y));
|
||||
}
|
||||
|
||||
// Creates vector from minimum components of two vectors
|
||||
static Double2 Min(const Double2& a, const Double2& b)
|
||||
{
|
||||
return Double2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Creates vector from minimum components of two vectors
|
||||
static void Min(const Double2& a, const Double2& b, Double2& result)
|
||||
{
|
||||
result = Double2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Creates vector from maximum components of two vectors
|
||||
static Double2 Max(const Double2& a, const Double2& b)
|
||||
{
|
||||
return Double2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Creates vector from maximum components of two vectors
|
||||
static void Max(const Double2& a, const Double2& b, Double2& result)
|
||||
{
|
||||
result = Double2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Returns normalized vector
|
||||
static Double2 Normalize(const Double2& v);
|
||||
|
||||
static Double2 Round(const Double2& v)
|
||||
{
|
||||
return Double2(Math::Round(v.X), Math::Round(v.Y));
|
||||
}
|
||||
|
||||
static Double2 Ceil(const Double2& v)
|
||||
{
|
||||
return Double2(Math::Ceil(v.X), Math::Ceil(v.Y));
|
||||
}
|
||||
|
||||
static Double2 Floor(const Double2& v)
|
||||
{
|
||||
return Double2(Math::Floor(v.X), Math::Floor(v.Y));
|
||||
}
|
||||
|
||||
static Double2 Frac(const Double2& v)
|
||||
{
|
||||
return Double2(v.X - (int64)v.X, v.Y - (int64)v.Y);
|
||||
}
|
||||
|
||||
static Int2 CeilToInt(const Double2& v);
|
||||
static Int2 FloorToInt(const Double2& v);
|
||||
|
||||
static Double2 Mod(const Double2& v)
|
||||
{
|
||||
return Double2(
|
||||
v.X - (int64)v.X,
|
||||
v.Y - (int64)v.Y
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Calculates the area of the triangle.
|
||||
/// </summary>
|
||||
/// <param name="v0">The first triangle vertex.</param>
|
||||
/// <param name="v1">The second triangle vertex.</param>
|
||||
/// <param name="v2">The third triangle vertex.</param>
|
||||
/// <returns>The triangle area.</returns>
|
||||
static double TriangleArea(const Double2& v0, const Double2& v1, const Double2& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the angle (in radians) between from and to. This is always the smallest value.
|
||||
/// </summary>
|
||||
/// <param name="from">The first vector.</param>
|
||||
/// <param name="to">The second vector.</param>
|
||||
/// <returns>The angle (in radians).</returns>
|
||||
static double Angle(const Double2& from, const Double2& to);
|
||||
};
|
||||
|
||||
inline Double2 operator+(double a, const Double2& b)
|
||||
{
|
||||
return b + a;
|
||||
}
|
||||
|
||||
inline Double2 operator-(double a, const Double2& b)
|
||||
{
|
||||
return Double2(a) - b;
|
||||
}
|
||||
|
||||
inline Double2 operator*(double a, const Double2& b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline Double2 operator/(double a, const Double2& b)
|
||||
{
|
||||
return Double2(a) / b;
|
||||
}
|
||||
|
||||
namespace Math
|
||||
{
|
||||
FORCE_INLINE static bool NearEqual(const Double2& a, const Double2& b)
|
||||
{
|
||||
return Double2::NearEqual(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Double2>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Double2, "X:{0} Y:{1}", v.X, v.Y);
|
||||
#include "Vector2.h"
|
||||
|
||||
@@ -1,344 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Double2.h"
|
||||
#include "Double3.h"
|
||||
#include "Double4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
#include "Quaternion.h"
|
||||
#include "Matrix.h"
|
||||
#include "Color.h"
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
static_assert(sizeof(Double3) == 24, "Invalid Double3 type size.");
|
||||
|
||||
const Double3 Double3::Zero(0.0);
|
||||
const Double3 Double3::One(1.0);
|
||||
const Double3 Double3::Half(0.5);
|
||||
const Double3 Double3::UnitX(1.0, 0.0, 0.0);
|
||||
const Double3 Double3::UnitY(0.0, 1.0, 0.0);
|
||||
const Double3 Double3::UnitZ(0.0, 0.0, 1.0);
|
||||
const Double3 Double3::Up(0.0, 1.0, 0.0);
|
||||
const Double3 Double3::Down(0.0, -1.0, 0.0);
|
||||
const Double3 Double3::Left(-1.0, 0.0, 0.0);
|
||||
const Double3 Double3::Right(1.0, 0.0, 0.0);
|
||||
const Double3 Double3::Forward(0.0, 0.0, 1.0);
|
||||
const Double3 Double3::Backward(0.0, 0.0, -1.0);
|
||||
const Double3 Double3::Minimum(MIN_double);
|
||||
const Double3 Double3::Maximum(MAX_double);
|
||||
|
||||
Double3::Double3(const Vector2& xy, double z)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Vector2& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(0)
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Vector3& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Vector4& xyzw)
|
||||
: X(xyzw.X)
|
||||
, Y(xyzw.Y)
|
||||
, Z(xyzw.Z)
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Int2& xy, double z)
|
||||
: X(static_cast<double>(xy.X))
|
||||
, Y(static_cast<double>(xy.Y))
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Int3& xyz)
|
||||
: X(static_cast<double>(xyz.X))
|
||||
, Y(static_cast<double>(xyz.Y))
|
||||
, Z(static_cast<double>(xyz.Z))
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Int4& xyzw)
|
||||
: X(static_cast<double>(xyzw.X))
|
||||
, Y(static_cast<double>(xyzw.Y))
|
||||
, Z(static_cast<double>(xyzw.Z))
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Double2& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(0)
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Double2& xy, double z)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Double4& xyzw)
|
||||
: X(xyzw.X)
|
||||
, Y(xyzw.Y)
|
||||
, Z(xyzw.Z)
|
||||
{
|
||||
}
|
||||
|
||||
Double3::Double3(const Color& color)
|
||||
: X(color.R)
|
||||
, Y(color.G)
|
||||
, Z(color.B)
|
||||
{
|
||||
}
|
||||
|
||||
String Double3::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
void Double3::UnwindEuler()
|
||||
{
|
||||
X = Math::UnwindDegrees(X);
|
||||
Y = Math::UnwindDegrees(Y);
|
||||
Z = Math::UnwindDegrees(Z);
|
||||
}
|
||||
|
||||
Double3 Double3::Floor(const Double3& v)
|
||||
{
|
||||
return Double3(
|
||||
Math::Floor(v.X),
|
||||
Math::Floor(v.Y),
|
||||
Math::Floor(v.Z)
|
||||
);
|
||||
}
|
||||
|
||||
Double3 Double3::Frac(const Double3& v)
|
||||
{
|
||||
return Double3(
|
||||
v.X - (int64)v.X,
|
||||
v.Y - (int64)v.Y,
|
||||
v.Z - (int64)v.Z
|
||||
);
|
||||
}
|
||||
|
||||
Double3 Double3::Clamp(const Double3& value, const Double3& min, const Double3& max)
|
||||
{
|
||||
double x = value.X;
|
||||
x = x > max.X ? max.X : x;
|
||||
x = x < min.X ? min.X : x;
|
||||
|
||||
double y = value.Y;
|
||||
y = y > max.Y ? max.Y : y;
|
||||
y = y < min.Y ? min.Y : y;
|
||||
|
||||
double z = value.Z;
|
||||
z = z > max.Z ? max.Z : z;
|
||||
z = z < min.Z ? min.Z : z;
|
||||
|
||||
return Double3(x, y, z);
|
||||
}
|
||||
|
||||
void Double3::Clamp(const Double3& value, const Double3& min, const Double3& max, Double3& result)
|
||||
{
|
||||
double x = value.X;
|
||||
x = x > max.X ? max.X : x;
|
||||
x = x < min.X ? min.X : x;
|
||||
|
||||
double y = value.Y;
|
||||
y = y > max.Y ? max.Y : y;
|
||||
y = y < min.Y ? min.Y : y;
|
||||
|
||||
double z = value.Z;
|
||||
z = z > max.Z ? max.Z : z;
|
||||
z = z < min.Z ? min.Z : z;
|
||||
|
||||
result = Double3(x, y, z);
|
||||
}
|
||||
|
||||
double Double3::Distance(const Double3& value1, const Double3& value2)
|
||||
{
|
||||
const double x = value1.X - value2.X;
|
||||
const double y = value1.Y - value2.Y;
|
||||
const double z = value1.Z - value2.Z;
|
||||
return Math::Sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
double Double3::DistanceSquared(const Double3& value1, const Double3& value2)
|
||||
{
|
||||
const double x = value1.X - value2.X;
|
||||
const double y = value1.Y - value2.Y;
|
||||
const double z = value1.Z - value2.Z;
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
Double3 Double3::Normalize(const Double3& input)
|
||||
{
|
||||
Double3 output = input;
|
||||
const double length = input.Length();
|
||||
if (!Math::IsZero(length))
|
||||
{
|
||||
const double inv = 1.0 / length;
|
||||
output.X *= inv;
|
||||
output.Y *= inv;
|
||||
output.Z *= inv;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
void Double3::Normalize(const Double3& input, Double3& result)
|
||||
{
|
||||
result = input;
|
||||
const double length = input.Length();
|
||||
if (!Math::IsZero(length))
|
||||
{
|
||||
const double inv = 1.0 / length;
|
||||
result.X *= inv;
|
||||
result.Y *= inv;
|
||||
result.Z *= inv;
|
||||
}
|
||||
}
|
||||
|
||||
void Double3::Hermite(const Double3& value1, const Double3& tangent1, const Double3& value2, const Double3& tangent2, double amount, Double3& result)
|
||||
{
|
||||
const double squared = amount * amount;
|
||||
const double cubed = amount * squared;
|
||||
const double part1 = 2.0 * cubed - 3.0 * squared + 1.0;
|
||||
const double part2 = -2.0 * cubed + 3.0 * squared;
|
||||
const double part3 = cubed - 2.0 * squared + amount;
|
||||
const double part4 = cubed - squared;
|
||||
|
||||
result.X = value1.X * part1 + value2.X * part2 + tangent1.X * part3 + tangent2.X * part4;
|
||||
result.Y = value1.Y * part1 + value2.Y * part2 + tangent1.Y * part3 + tangent2.Y * part4;
|
||||
result.Z = value1.Z * part1 + value2.Z * part2 + tangent1.Z * part3 + tangent2.Z * part4;
|
||||
}
|
||||
|
||||
void Double3::Reflect(const Double3& vector, const Double3& normal, Double3& result)
|
||||
{
|
||||
const double dot = vector.X * normal.X + vector.Y * normal.Y + vector.Z * normal.Z;
|
||||
result.X = vector.X - 2.0 * dot * normal.X;
|
||||
result.Y = vector.Y - 2.0 * dot * normal.Y;
|
||||
result.Z = vector.Z - 2.0 * dot * normal.Z;
|
||||
}
|
||||
|
||||
void Double3::Transform(const Double3& vector, const Quaternion& rotation, Double3& result)
|
||||
{
|
||||
const double x = rotation.X + rotation.X;
|
||||
const double y = rotation.Y + rotation.Y;
|
||||
const double z = rotation.Z + rotation.Z;
|
||||
const double wx = rotation.W * x;
|
||||
const double wy = rotation.W * y;
|
||||
const double wz = rotation.W * z;
|
||||
const double xx = rotation.X * x;
|
||||
const double xy = rotation.X * y;
|
||||
const double xz = rotation.X * z;
|
||||
const double yy = rotation.Y * y;
|
||||
const double yz = rotation.Y * z;
|
||||
const double zz = rotation.Z * z;
|
||||
|
||||
result = Double3(
|
||||
vector.X * (1.0 - yy - zz) + vector.Y * (xy - wz) + vector.Z * (xz + wy),
|
||||
vector.X * (xy + wz) + vector.Y * (1.0 - xx - zz) + vector.Z * (yz - wx),
|
||||
vector.X * (xz - wy) + vector.Y * (yz + wx) + vector.Z * (1.0 - xx - yy));
|
||||
}
|
||||
|
||||
Double3 Double3::Transform(const Double3& vector, const Quaternion& rotation)
|
||||
{
|
||||
const double x = rotation.X + rotation.X;
|
||||
const double y = rotation.Y + rotation.Y;
|
||||
const double z = rotation.Z + rotation.Z;
|
||||
const double wx = rotation.W * x;
|
||||
const double wy = rotation.W * y;
|
||||
const double wz = rotation.W * z;
|
||||
const double xx = rotation.X * x;
|
||||
const double xy = rotation.X * y;
|
||||
const double xz = rotation.X * z;
|
||||
const double yy = rotation.Y * y;
|
||||
const double yz = rotation.Y * z;
|
||||
const double zz = rotation.Z * z;
|
||||
|
||||
return Double3(
|
||||
vector.X * (1.0 - yy - zz) + vector.Y * (xy - wz) + vector.Z * (xz + wy),
|
||||
vector.X * (xy + wz) + vector.Y * (1.0 - xx - zz) + vector.Z * (yz - wx),
|
||||
vector.X * (xz - wy) + vector.Y * (yz + wx) + vector.Z * (1.0 - xx - yy));
|
||||
}
|
||||
|
||||
void Double3::Transform(const Double3& vector, const Matrix& transform, Double4& result)
|
||||
{
|
||||
result = Double4(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43,
|
||||
vector.X * transform.M14 + vector.Y * transform.M24 + vector.Z * transform.M34 + transform.M44);
|
||||
}
|
||||
|
||||
void Double3::Transform(const Double3& vector, const Matrix& transform, Double3& result)
|
||||
{
|
||||
result = Double3(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43);
|
||||
}
|
||||
|
||||
void Double3::Transform(const Double3* vectors, const Matrix& transform, Double3* results, int32 vectorsCount)
|
||||
{
|
||||
for (int32 i = 0; i < vectorsCount; i++)
|
||||
{
|
||||
Transform(vectors[i], transform, results[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Double3 Double3::Transform(const Double3& vector, const Matrix& transform)
|
||||
{
|
||||
return Double3(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43);
|
||||
}
|
||||
|
||||
void Double3::TransformCoordinate(const Double3& coordinate, const Matrix& transform, Double3& result)
|
||||
{
|
||||
Double4 vector;
|
||||
vector.X = coordinate.X * transform.M11 + coordinate.Y * transform.M21 + coordinate.Z * transform.M31 + transform.M41;
|
||||
vector.Y = coordinate.X * transform.M12 + coordinate.Y * transform.M22 + coordinate.Z * transform.M32 + transform.M42;
|
||||
vector.Z = coordinate.X * transform.M13 + coordinate.Y * transform.M23 + coordinate.Z * transform.M33 + transform.M43;
|
||||
vector.W = 1.0 / (coordinate.X * transform.M14 + coordinate.Y * transform.M24 + coordinate.Z * transform.M34 + transform.M44);
|
||||
result = Double3(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W);
|
||||
}
|
||||
|
||||
void Double3::TransformNormal(const Double3& normal, const Matrix& transform, Double3& result)
|
||||
{
|
||||
result = Double3(
|
||||
normal.X * transform.M11 + normal.Y * transform.M21 + normal.Z * transform.M31,
|
||||
normal.X * transform.M12 + normal.Y * transform.M22 + normal.Z * transform.M32,
|
||||
normal.X * transform.M13 + normal.Y * transform.M23 + normal.Z * transform.M33);
|
||||
}
|
||||
|
||||
double Double3::TriangleArea(const Double3& v0, const Double3& v1, const Double3& v2)
|
||||
{
|
||||
return (v2 - v0 ^ v1 - v0).Length() * 0.5;
|
||||
}
|
||||
|
||||
double Double3::Angle(const Double3& from, const Double3& to)
|
||||
{
|
||||
const double dot = Math::Clamp(Dot(Normalize(from), Normalize(to)), -1.0, 1.0);
|
||||
if (Math::Abs(dot) > (1.0 - ZeroTolerance))
|
||||
return dot > 0.0 ? 0.0 : PI;
|
||||
return Math::Acos(dot);
|
||||
}
|
||||
@@ -337,16 +337,6 @@ namespace FlaxEngine
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of the vector.
|
||||
/// </summary>
|
||||
public void Negate()
|
||||
{
|
||||
X *= -1;
|
||||
Y *= -1;
|
||||
Z *= -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When this vector contains Euler angles (degrees), ensure that angles are between +/-180
|
||||
/// </summary>
|
||||
|
||||
@@ -2,812 +2,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Math.h"
|
||||
#include "Mathd.h"
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
struct Double2;
|
||||
struct Double4;
|
||||
struct Vector2;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Int2;
|
||||
struct Int3;
|
||||
struct Int4;
|
||||
struct Color;
|
||||
struct Matrix;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a two dimensional mathematical vector with 64-bit precision (per-component).
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API Double3
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Double3);
|
||||
public:
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component of the vector.
|
||||
/// </summary>
|
||||
API_FIELD() double X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the vector.
|
||||
/// </summary>
|
||||
API_FIELD() double Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component of the vector.
|
||||
/// </summary>
|
||||
API_FIELD() double Z;
|
||||
};
|
||||
|
||||
// Raw values
|
||||
double Raw[3];
|
||||
};
|
||||
|
||||
public:
|
||||
// Vector with all components equal 0.
|
||||
static const Double3 Zero;
|
||||
|
||||
// Vector with all components equal 1.
|
||||
static const Double3 One;
|
||||
|
||||
// Vector with all components equal half (0.5, 0.5, 0.5).
|
||||
static const Double3 Half;
|
||||
|
||||
// Vector X=1, Y=0, Z=0.
|
||||
static const Double3 UnitX;
|
||||
|
||||
// Vector X=0, Y=1, Z=0.
|
||||
static const Double3 UnitY;
|
||||
|
||||
// Vector X=0, Y=0, Z=1.
|
||||
static const Double3 UnitZ;
|
||||
|
||||
// A unit vector designating up (0, 1, 0).
|
||||
static const Double3 Up;
|
||||
|
||||
// A unit vector designating down (0, -1, 0).
|
||||
static const Double3 Down;
|
||||
|
||||
// A unit vector designating a (-1, 0, 0).
|
||||
static const Double3 Left;
|
||||
|
||||
// A unit vector designating b (1, 0, 0).
|
||||
static const Double3 Right;
|
||||
|
||||
// A unit vector designating forward in a a-handed coordinate system (0, 0, 1).
|
||||
static const Double3 Forward;
|
||||
|
||||
// A unit vector designating backward in a a-handed coordinate system (0, 0, -1).
|
||||
static const Double3 Backward;
|
||||
|
||||
// A minimum Double3.
|
||||
static const Double3 Minimum;
|
||||
|
||||
// A maximum Double3.
|
||||
static const Double3 Maximum;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor.
|
||||
/// </summary>
|
||||
Double3()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xyz Value to assign to the all components
|
||||
Double3(double xyz)
|
||||
: X(xyz)
|
||||
, Y(xyz)
|
||||
, Z(xyz)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param x X component value
|
||||
// @param y Y component value
|
||||
// @param z Z component value
|
||||
Double3(double x, double y, double z)
|
||||
: X(x)
|
||||
, Y(y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init
|
||||
/// </summary>
|
||||
/// <param name="xyz">X, Y and Z components in an array</param>
|
||||
explicit Double3(double xyz[3])
|
||||
: X(xyz[0])
|
||||
, Y(xyz[1])
|
||||
, Z(xyz[2])
|
||||
{
|
||||
}
|
||||
|
||||
explicit Double3(const Vector2& xy, double z);
|
||||
explicit Double3(const Vector2& xy);
|
||||
Double3(const Vector3& xyz);
|
||||
explicit Double3(const Vector4& xyzw);
|
||||
explicit Double3(const Int2& xy, double z);
|
||||
explicit Double3(const Int3& xyz);
|
||||
explicit Double3(const Int4& xyzw);
|
||||
explicit Double3(const Double2& xy);
|
||||
explicit Double3(const Double2& xy, double z);
|
||||
explicit Double3(const Double4& xyzw);
|
||||
explicit Double3(const Color& color);
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
|
||||
public:
|
||||
// Gets a value indicting whether this instance is normalized.
|
||||
bool IsNormalized() const
|
||||
{
|
||||
return Math::IsOne(X * X + Y * Y + Z * Z);
|
||||
}
|
||||
|
||||
// Gets a value indicting whether this vector is zero.
|
||||
bool IsZero() const
|
||||
{
|
||||
return Math::IsZero(X) && Math::IsZero(Y) && Math::IsZero(Z);
|
||||
}
|
||||
|
||||
// Gets a value indicting whether any vector component is zero.
|
||||
bool IsAnyZero() const
|
||||
{
|
||||
return Math::IsZero(X) || Math::IsZero(Y) || Math::IsZero(Z);
|
||||
}
|
||||
|
||||
// Gets a value indicting whether this vector is one.
|
||||
bool IsOne() const
|
||||
{
|
||||
return Math::IsOne(X) && Math::IsOne(Y) && Math::IsOne(Z);
|
||||
}
|
||||
|
||||
// Calculates the length of the vector.
|
||||
double Length() const
|
||||
{
|
||||
return Math::Sqrt(X * X + Y * Y + Z * Z);
|
||||
}
|
||||
|
||||
// Calculates the squared length of the vector.
|
||||
double LengthSquared() const
|
||||
{
|
||||
return X * X + Y * Y + Z * Z;
|
||||
}
|
||||
|
||||
// Calculates inverted length of the vector (1 / length).
|
||||
double InvLength() const
|
||||
{
|
||||
return 1.0 / Length();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being absolute values of that vector.
|
||||
/// </summary>
|
||||
Double3 GetAbsolute() const
|
||||
{
|
||||
return Double3(Math::Abs(X), Math::Abs(Y), Math::Abs(Z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being opposite to values of that vector.
|
||||
/// </summary>
|
||||
Double3 GetNegative() const
|
||||
{
|
||||
return Double3(-X, -Y, -Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a normalized vector that has length equal to 1.
|
||||
/// </summary>
|
||||
Double3 GetNormalized() const
|
||||
{
|
||||
const double rcp = 1.0 / Length();
|
||||
return Double3(X * rcp, Y * rcp, Z * rcp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the average arithmetic of all the components.
|
||||
/// </summary>
|
||||
double AverageArithmetic() const
|
||||
{
|
||||
return (X + Y + Z) * 0.333333334;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sum of all vector components values.
|
||||
/// </summary>
|
||||
double SumValues() const
|
||||
{
|
||||
return X + Y + Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the minimum value of all the components.
|
||||
/// </summary>
|
||||
double MinValue() const
|
||||
{
|
||||
return Math::Min(X, Y, Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum value of all the components.
|
||||
/// </summary>
|
||||
double MaxValue() const
|
||||
{
|
||||
return Math::Max(X, Y, Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components is not a number (NaN).
|
||||
/// </summary>
|
||||
bool IsNaN() const
|
||||
{
|
||||
return isnan(X) || isnan(Y) || isnan(Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components equal to +/- infinity.
|
||||
/// </summary>
|
||||
bool IsInfinity() const
|
||||
{
|
||||
return isinf(X) || isinf(Y) || isinf(Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components equal to +/- infinity or NaN.
|
||||
/// </summary>
|
||||
bool IsNanOrInfinity() const
|
||||
{
|
||||
return IsInfinity() || IsNaN();
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Performs vector normalization (scales vector up to unit length).
|
||||
/// </summary>
|
||||
void Normalize()
|
||||
{
|
||||
const double length = Math::Sqrt(X * X + Y * Y + Z * Z);
|
||||
if (Math::Abs(length) >= ZeroTolerance)
|
||||
{
|
||||
const double inv = 1.0 / length;
|
||||
X *= inv;
|
||||
Y *= inv;
|
||||
Z *= inv;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs fast vector normalization (scales vector up to unit length).
|
||||
/// </summary>
|
||||
void NormalizeFast()
|
||||
{
|
||||
const double inv = 1.0 / Math::Sqrt(X * X + Y * Y + Z * Z);
|
||||
X *= inv;
|
||||
Y *= inv;
|
||||
Z *= inv;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets all vector components to the absolute values.
|
||||
/// </summary>
|
||||
void Absolute()
|
||||
{
|
||||
X = Math::Abs(X);
|
||||
Y = Math::Abs(Y);
|
||||
Z = Math::Abs(Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates all components of that vector.
|
||||
/// </summary>
|
||||
void Negate()
|
||||
{
|
||||
X = -X;
|
||||
Y = -Y;
|
||||
Z = -Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When this vector contains Euler angles (degrees), ensure that angles are between +/-180.
|
||||
/// </summary>
|
||||
void UnwindEuler();
|
||||
|
||||
public:
|
||||
Double3 operator+(const Double3& b) const
|
||||
{
|
||||
return Double3(X + b.X, Y + b.Y, Z + b.Z);
|
||||
}
|
||||
|
||||
Double3 operator-(const Double3& b) const
|
||||
{
|
||||
return Double3(X - b.X, Y - b.Y, Z - b.Z);
|
||||
}
|
||||
|
||||
Double3 operator*(const Double3& b) const
|
||||
{
|
||||
return Double3(X * b.X, Y * b.Y, Z * b.Z);
|
||||
}
|
||||
|
||||
Double3 operator/(const Double3& b) const
|
||||
{
|
||||
return Double3(X / b.X, Y / b.Y, Z / b.Z);
|
||||
}
|
||||
|
||||
Double3 operator-() const
|
||||
{
|
||||
return Double3(-X, -Y, -Z);
|
||||
}
|
||||
|
||||
Double3 operator^(const Double3& b) const
|
||||
{
|
||||
return Cross(*this, b);
|
||||
}
|
||||
|
||||
double operator|(const Double3& b) const
|
||||
{
|
||||
return Dot(*this, b);
|
||||
}
|
||||
|
||||
Double3& operator+=(const Double3& b)
|
||||
{
|
||||
X += b.X;
|
||||
Y += b.Y;
|
||||
Z += b.Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double3& operator-=(const Double3& b)
|
||||
{
|
||||
X -= b.X;
|
||||
Y -= b.Y;
|
||||
Z -= b.Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double3& operator*=(const Double3& b)
|
||||
{
|
||||
X *= b.X;
|
||||
Y *= b.Y;
|
||||
Z *= b.Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double3& operator/=(const Double3& b)
|
||||
{
|
||||
X /= b.X;
|
||||
Y /= b.Y;
|
||||
Z /= b.Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double3 operator+(double b) const
|
||||
{
|
||||
return Double3(X + b, Y + b, Z + b);
|
||||
}
|
||||
|
||||
Double3 operator-(double b) const
|
||||
{
|
||||
return Double3(X - b, Y - b, Z - b);
|
||||
}
|
||||
|
||||
Double3 operator*(double b) const
|
||||
{
|
||||
return Double3(X * b, Y * b, Z * b);
|
||||
}
|
||||
|
||||
Double3 operator/(double b) const
|
||||
{
|
||||
return Double3(X / b, Y / b, Z / b);
|
||||
}
|
||||
|
||||
Double3& operator+=(double b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double3& operator-=(double b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double3& operator*=(double b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Double3& operator/=(double b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Double3& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y && Z == b.Z;
|
||||
}
|
||||
|
||||
bool operator!=(const Double3& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y || Z != b.Z;
|
||||
}
|
||||
|
||||
bool operator>(const Double3& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y && Z > b.Z;
|
||||
}
|
||||
|
||||
bool operator>=(const Double3& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y && Z >= b.Z;
|
||||
}
|
||||
|
||||
bool operator<(const Double3& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y && Z < b.Z;
|
||||
}
|
||||
|
||||
bool operator<=(const Double3& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y && Z <= b.Z;
|
||||
}
|
||||
|
||||
public:
|
||||
static bool NearEqual(const Double3& a, const Double3& b)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X) && Math::NearEqual(a.Y, b.Y) && Math::NearEqual(a.Z, b.Z);
|
||||
}
|
||||
|
||||
static bool NearEqual(const Double3& a, const Double3& b, double epsilon)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X, epsilon) && Math::NearEqual(a.Y, b.Y, epsilon) && Math::NearEqual(a.Z, b.Z, epsilon);
|
||||
}
|
||||
|
||||
public:
|
||||
static void Add(const Double3& a, const Double3& b, Double3& result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
result.Z = a.Z + b.Z;
|
||||
}
|
||||
|
||||
static Double3 Add(const Double3& a, const Double3& b)
|
||||
{
|
||||
Double3 result;
|
||||
Add(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Subtract(const Double3& a, const Double3& b, Double3& result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
result.Z = a.Z - b.Z;
|
||||
}
|
||||
|
||||
static Double3 Subtract(const Double3& a, const Double3& b)
|
||||
{
|
||||
Double3 result;
|
||||
Subtract(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Double3 Multiply(const Double3& a, const Double3& b)
|
||||
{
|
||||
return Double3(a.X * b.X, a.Y * b.Y, a.Z * b.Z);
|
||||
}
|
||||
|
||||
static void Multiply(const Double3& a, const Double3& b, Double3& result)
|
||||
{
|
||||
result = Double3(a.X * b.X, a.Y * b.Y, a.Z * b.Z);
|
||||
}
|
||||
|
||||
static Double3 Multiply(const Double3& a, double b)
|
||||
{
|
||||
return Double3(a.X * b, a.Y * b, a.Z * b);
|
||||
}
|
||||
|
||||
static Double3 Divide(const Double3& a, const Double3& b)
|
||||
{
|
||||
return Double3(a.X / b.X, a.Y / b.Y, a.Z / b.Z);
|
||||
}
|
||||
|
||||
static void Divide(const Double3& a, const Double3& b, Double3& result)
|
||||
{
|
||||
result = Double3(a.X / b.X, a.Y / b.Y, a.Z / b.Z);
|
||||
}
|
||||
|
||||
static Double3 Divide(const Double3& a, double b)
|
||||
{
|
||||
return Double3(a.X / b, a.Y / b, a.Z / b);
|
||||
}
|
||||
|
||||
static Double3 Floor(const Double3& v);
|
||||
static Double3 Frac(const Double3& v);
|
||||
|
||||
static double ScalarProduct(const Double3& a, const Double3& b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
||||
}
|
||||
|
||||
public:
|
||||
// Restricts a value to be within a specified range.
|
||||
// @param value The value to clamp.
|
||||
// @param min The minimum value.
|
||||
// @param max The maximum value.
|
||||
// @returns Clamped value
|
||||
static Double3 Clamp(const Double3& value, const Double3& min, const Double3& max);
|
||||
|
||||
// Restricts a value to be within a specified range.
|
||||
// @param value The value to clamp.
|
||||
// @param min The minimum value.
|
||||
// @param max The maximum value.
|
||||
// @param result When the method completes, contains the clamped value.
|
||||
static void Clamp(const Double3& value, const Double3& min, const Double3& max, Double3& result);
|
||||
|
||||
// Calculates the distance between two vectors.
|
||||
// @param value1 The first vector.
|
||||
// @param value2 The second vector.
|
||||
// @returns The distance between the two vectors.
|
||||
static double Distance(const Double3& value1, const Double3& value2);
|
||||
|
||||
// Calculates the squared distance between two vectors.
|
||||
// @param value1 The first vector.
|
||||
// @param value2 The second vector.
|
||||
// @returns The squared distance between the two vectors.
|
||||
static double DistanceSquared(const Double3& value1, const Double3& value2);
|
||||
|
||||
// Performs vector normalization (scales vector up to unit length).
|
||||
// @param inout Input vector to normalize.
|
||||
// @returns Output vector that is normalized (has unit length).
|
||||
static Double3 Normalize(const Double3& input);
|
||||
|
||||
// Performs vector normalization (scales vector up to unit length). This is a faster version that does not performs check for length equal 0 (it assumes that input vector is not empty).
|
||||
// @param inout Input vector to normalize (cannot be zero).
|
||||
// @returns Output vector that is normalized (has unit length).
|
||||
static Double3 NormalizeFast(const Double3& input)
|
||||
{
|
||||
const double inv = 1.0 / input.Length();
|
||||
return Double3(input.X * inv, input.Y * inv, input.Z * inv);
|
||||
}
|
||||
|
||||
// Performs vector normalization (scales vector up to unit length).
|
||||
// @param inout Input vector to normalize.
|
||||
// @param output Output vector that is normalized (has unit length).
|
||||
static void Normalize(const Double3& input, Double3& result);
|
||||
|
||||
// dot product with another vector.
|
||||
static double Dot(const Double3& a, const Double3& b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
||||
}
|
||||
|
||||
// Calculates the cross product of two vectors.
|
||||
// @param a First source vector.
|
||||
// @param b Second source vector.
|
||||
// @param result When the method completes, contains the cross product of the two vectors.
|
||||
static void Cross(const Double3& a, const Double3& b, Double3& result)
|
||||
{
|
||||
result = Double3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
|
||||
}
|
||||
|
||||
// Calculates the cross product of two vectors.
|
||||
// @param a First source vector.
|
||||
// @param b Second source vector.
|
||||
// @returns Cross product of the two vectors.
|
||||
static Double3 Cross(const Double3& a, const Double3& b)
|
||||
{
|
||||
return Double3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
|
||||
}
|
||||
|
||||
// Performs a linear interpolation between two vectors.
|
||||
// @param start Start vector.
|
||||
// @param end End vector.
|
||||
// @param amount Value between 0 and 1 indicating the weight of end.
|
||||
// @param result When the method completes, contains the linear interpolation of the two vectors.
|
||||
static void Lerp(const Double3& start, const Double3& end, double amount, Double3& result)
|
||||
{
|
||||
result.X = Math::Lerp(start.X, end.X, amount);
|
||||
result.Y = Math::Lerp(start.Y, end.Y, amount);
|
||||
result.Z = Math::Lerp(start.Z, end.Z, amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two vectors.
|
||||
/// </summary>
|
||||
static Double3 Lerp(const Double3& start, const Double3& end, double amount)
|
||||
{
|
||||
Double3 result;
|
||||
Lerp(start, end, amount, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two vectors
|
||||
/// </summary>
|
||||
static void SmoothStep(const Double3& start, const Double3& end, double amount, Double3& result)
|
||||
{
|
||||
amount = Math::SmoothStep(amount);
|
||||
Lerp(start, end, amount, result);
|
||||
}
|
||||
|
||||
// Performs a Hermite spline interpolation.
|
||||
// @param value1 First source position vector
|
||||
// @param tangent1 First source tangent vector
|
||||
// @param value2 Second source position vector
|
||||
// @param tangent2 Second source tangent vector
|
||||
// @param amount Weighting factor,
|
||||
// @param result When the method completes, contains the result of the Hermite spline interpolation,
|
||||
static void Hermite(const Double3& value1, const Double3& tangent1, const Double3& value2, const Double3& tangent2, double amount, Double3& result);
|
||||
|
||||
// Returns the reflection of a vector off a surface that has the specified normal
|
||||
// @param vector The source vector
|
||||
// @param normal Normal of the surface
|
||||
// @param result When the method completes, contains the reflected vector
|
||||
static void Reflect(const Double3& vector, const Double3& normal, Double3& result);
|
||||
|
||||
// Transforms a 3D vector by the given Quaternion rotation
|
||||
// @param vector The vector to rotate
|
||||
// @param rotation The Quaternion rotation to apply
|
||||
// @param result When the method completes, contains the transformed Vector4
|
||||
static void Transform(const Double3& vector, const Quaternion& rotation, Double3& result);
|
||||
|
||||
// Transforms a 3D vector by the given Quaternion rotation
|
||||
// @param vector The vector to rotate
|
||||
// @param rotation The Quaternion rotation to apply
|
||||
// @returns The transformed Double3
|
||||
static Double3 Transform(const Double3& vector, const Quaternion& rotation);
|
||||
|
||||
// Transforms a 3D vector by the given matrix
|
||||
// @param vector The source vector
|
||||
// @param transform The transformation matrix
|
||||
// @param result When the method completes, contains the transformed Double3
|
||||
static void Transform(const Double3& vector, const Matrix& transform, Double3& result);
|
||||
|
||||
// Transforms a 3D vectors by the given matrix
|
||||
// @param vectors The source vectors
|
||||
// @param transform The transformation matrix
|
||||
// @param results When the method completes, contains the transformed Vector3s
|
||||
// @param vectorsCount Amount of vectors to transform
|
||||
static void Transform(const Double3* vectors, const Matrix& transform, Double3* results, int32 vectorsCount);
|
||||
|
||||
// Transforms a 3D vector by the given matrix
|
||||
// @param vector The source vector
|
||||
// @param transform The transformation matrix
|
||||
// @returns Transformed Double3
|
||||
static Double3 Transform(const Double3& vector, const Matrix& transform);
|
||||
|
||||
// Transforms a 3D vector by the given matrix
|
||||
// @param vector The source vector
|
||||
// @param transform The transformation matrix
|
||||
// @param result When the method completes, contains the transformed Double4
|
||||
static void Transform(const Double3& vector, const Matrix& transform, Double4& result);
|
||||
|
||||
// Performs a coordinate transformation using the given matrix
|
||||
// @param coordinate The coordinate vector to transform
|
||||
// @param transform The transformation matrix
|
||||
// @param result When the method completes, contains the transformed coordinates
|
||||
static void TransformCoordinate(const Double3& coordinate, const Matrix& transform, Double3& result);
|
||||
|
||||
// Performs a normal transformation using the given matrix
|
||||
// @param normal The normal vector to transform
|
||||
// @param transform The transformation matrix
|
||||
// @param result When the method completes, contains the transformed normal
|
||||
static void TransformNormal(const Double3& normal, const Matrix& transform, Double3& result);
|
||||
|
||||
// Returns a vector containing the largest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
|
||||
static Double3 Max(const Double3& a, const Double3& b)
|
||||
{
|
||||
return Double3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z);
|
||||
}
|
||||
|
||||
// Returns a vector containing the smallest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
|
||||
static Double3 Min(const Double3& a, const Double3& b)
|
||||
{
|
||||
return Double3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z);
|
||||
}
|
||||
|
||||
// Returns a vector containing the largest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
|
||||
static void Max(const Double3& a, const Double3& b, Double3& result)
|
||||
{
|
||||
result = Double3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z);
|
||||
}
|
||||
|
||||
// Returns a vector containing the smallest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
|
||||
static void Min(const Double3& a, const Double3& b, Double3& result)
|
||||
{
|
||||
result = Double3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z);
|
||||
}
|
||||
|
||||
static Double3 Round(const Double3& v)
|
||||
{
|
||||
return Double3(Math::Round(v.X), Math::Round(v.Y), Math::Round(v.Z));
|
||||
}
|
||||
|
||||
static Double3 Ceil(const Double3& v)
|
||||
{
|
||||
return Double3(Math::Ceil(v.X), Math::Ceil(v.Y), Math::Ceil(v.Z));
|
||||
}
|
||||
|
||||
static Double3 Abs(const Double3& v)
|
||||
{
|
||||
return Double3(Math::Abs(v.X), Math::Abs(v.Y), Math::Abs(v.Z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the area of the triangle.
|
||||
/// </summary>
|
||||
/// <param name="v0">The first triangle vertex.</param>
|
||||
/// <param name="v1">The second triangle vertex.</param>
|
||||
/// <param name="v2">The third triangle vertex.</param>
|
||||
/// <returns>The triangle area.</returns>
|
||||
static double TriangleArea(const Double3& v0, const Double3& v1, const Double3& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the angle (in radians) between from and to. This is always the smallest value.
|
||||
/// </summary>
|
||||
/// <param name="from">The first vector.</param>
|
||||
/// <param name="to">The second vector.</param>
|
||||
/// <returns>The angle (in radians).</returns>
|
||||
static double Angle(const Double3& from, const Double3& to);
|
||||
};
|
||||
|
||||
inline Double3 operator+(double a, const Double3& b)
|
||||
{
|
||||
return b + a;
|
||||
}
|
||||
|
||||
inline Double3 operator-(double a, const Double3& b)
|
||||
{
|
||||
return Double3(a) - b;
|
||||
}
|
||||
|
||||
inline Double3 operator*(double a, const Double3& b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline Double3 operator/(double a, const Double3& b)
|
||||
{
|
||||
return Double3(a) / b;
|
||||
}
|
||||
|
||||
namespace Math
|
||||
{
|
||||
FORCE_INLINE static bool NearEqual(const Double3& a, const Double3& b)
|
||||
{
|
||||
return Double3::NearEqual(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Double3>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Double3, "X:{0} Y:{1} Z:{2}", v.X, v.Y, v.Z);
|
||||
#include "Vector3.h"
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Double2.h"
|
||||
#include "Double3.h"
|
||||
#include "Double4.h"
|
||||
#include "Vector4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "Color.h"
|
||||
#include "Matrix.h"
|
||||
#include "Rectangle.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
static_assert(sizeof(Double4) == 32, "Invalid Double4 type size.");
|
||||
|
||||
const Double4 Double4::Zero(0.0);
|
||||
const Double4 Double4::One(1.0);
|
||||
const Double4 Double4::UnitX(1, 0, 0, 0);
|
||||
const Double4 Double4::UnitY(0, 1, 0, 0);
|
||||
const Double4 Double4::UnitZ(0, 0, 1, 0);
|
||||
const Double4 Double4::UnitW(0, 0, 0, 1);
|
||||
const Double4 Double4::Minimum(MIN_double);
|
||||
const Double4 Double4::Maximum(MAX_double);
|
||||
|
||||
Double4::Double4(double xyzw[4])
|
||||
{
|
||||
Platform::MemoryCopy(Raw, xyzw, sizeof(double) * 4);
|
||||
}
|
||||
|
||||
Double4::Double4(const Vector2& xy, double z, double w)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Vector2& xy, const Vector2& zw)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(zw.X)
|
||||
, W(zw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Vector3& xyz, double w)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Vector4& xyzw)
|
||||
: X(xyzw.X)
|
||||
, Y(xyzw.Y)
|
||||
, Z(xyzw.Z)
|
||||
, W(xyzw.W)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Int2& xy, double z, double w)
|
||||
: X(static_cast<double>(xy.X))
|
||||
, Y(static_cast<double>(xy.Y))
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Int3& xyz, double w)
|
||||
: X(static_cast<double>(xyz.X))
|
||||
, Y(static_cast<double>(xyz.Y))
|
||||
, Z(static_cast<double>(xyz.Z))
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Int4& xyzw)
|
||||
: X(static_cast<double>(xyzw.X))
|
||||
, Y(static_cast<double>(xyzw.Y))
|
||||
, Z(static_cast<double>(xyzw.X))
|
||||
, W(static_cast<double>(xyzw.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Double2& xy, double z, double w)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Double3& xyz, double w)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Color& color)
|
||||
: X(color.R)
|
||||
, Y(color.G)
|
||||
, Z(color.B)
|
||||
, W(color.A)
|
||||
{
|
||||
}
|
||||
|
||||
Double4::Double4(const Rectangle& rect)
|
||||
: X(rect.Location.X)
|
||||
, Y(rect.Location.Y)
|
||||
, Z(rect.Size.X)
|
||||
, W(rect.Size.Y)
|
||||
{
|
||||
}
|
||||
|
||||
String Double4::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
Double4 Double4::Floor(const Double4& v)
|
||||
{
|
||||
return Double4(
|
||||
Math::Floor(v.X),
|
||||
Math::Floor(v.Y),
|
||||
Math::Floor(v.Z),
|
||||
Math::Floor(v.W)
|
||||
);
|
||||
}
|
||||
|
||||
Double4 Double4::Frac(const Double4& v)
|
||||
{
|
||||
return Double4(
|
||||
v.X - (int64)v.X,
|
||||
v.Y - (int64)v.Y,
|
||||
v.Z - (int64)v.Z,
|
||||
v.W - (int64)v.W
|
||||
);
|
||||
}
|
||||
|
||||
Double4 Double4::Round(const Double4& v)
|
||||
{
|
||||
return Double4(
|
||||
Math::Round(v.X),
|
||||
Math::Round(v.Y),
|
||||
Math::Round(v.Z),
|
||||
Math::Round(v.W)
|
||||
);
|
||||
}
|
||||
|
||||
Double4 Double4::Ceil(const Double4& v)
|
||||
{
|
||||
return Double4(
|
||||
Math::Ceil(v.X),
|
||||
Math::Ceil(v.Y),
|
||||
Math::Ceil(v.Z),
|
||||
Math::Ceil(v.W)
|
||||
);
|
||||
}
|
||||
|
||||
Double4 Double4::Clamp(const Double4& value, const Double4& min, const Double4& max)
|
||||
{
|
||||
double x = value.X;
|
||||
x = x > max.X ? max.X : x;
|
||||
x = x < min.X ? min.X : x;
|
||||
|
||||
double y = value.Y;
|
||||
y = y > max.Y ? max.Y : y;
|
||||
y = y < min.Y ? min.Y : y;
|
||||
|
||||
double z = value.Z;
|
||||
z = z > max.Z ? max.Z : z;
|
||||
z = z < min.Z ? min.Z : z;
|
||||
|
||||
double w = value.W;
|
||||
w = w > max.W ? max.W : w;
|
||||
w = w < min.W ? min.W : w;
|
||||
|
||||
return Double4(x, y, z, w);
|
||||
}
|
||||
|
||||
void Double4::Clamp(const Double4& value, const Double4& min, const Double4& max, Double4& result)
|
||||
{
|
||||
double x = value.X;
|
||||
x = x > max.X ? max.X : x;
|
||||
x = x < min.X ? min.X : x;
|
||||
|
||||
double y = value.Y;
|
||||
y = y > max.Y ? max.Y : y;
|
||||
y = y < min.Y ? min.Y : y;
|
||||
|
||||
double z = value.Z;
|
||||
z = z > max.Z ? max.Z : z;
|
||||
z = z < min.Z ? min.Z : z;
|
||||
|
||||
double w = value.W;
|
||||
w = w > max.W ? max.W : w;
|
||||
w = w < min.W ? min.W : w;
|
||||
|
||||
result = Double4(x, y, z, w);
|
||||
}
|
||||
|
||||
Double4 Double4::Transform(const Double4& v, const Matrix& m)
|
||||
{
|
||||
return Double4(
|
||||
m.Values[0][0] * v.Raw[0] + m.Values[1][0] * v.Raw[1] + m.Values[2][0] * v.Raw[2] + m.Values[3][0] * v.Raw[3],
|
||||
m.Values[0][1] * v.Raw[0] + m.Values[1][1] * v.Raw[1] + m.Values[2][1] * v.Raw[2] + m.Values[3][1] * v.Raw[3],
|
||||
m.Values[0][2] * v.Raw[0] + m.Values[1][2] * v.Raw[1] + m.Values[2][2] * v.Raw[2] + m.Values[3][2] * v.Raw[3],
|
||||
m.Values[0][3] * v.Raw[0] + m.Values[1][3] * v.Raw[1] + m.Values[2][3] * v.Raw[2] + m.Values[3][3] * v.Raw[3]
|
||||
);
|
||||
}
|
||||
@@ -2,496 +2,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Math.h"
|
||||
#include "Mathd.h"
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
struct Double2;
|
||||
struct Double3;
|
||||
struct Vector2;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Color;
|
||||
struct Matrix;
|
||||
struct Rectangle;
|
||||
class String;
|
||||
struct Int2;
|
||||
struct Int3;
|
||||
struct Int4;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a four dimensional mathematical vector with 64-bit precision (per-component).
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API Double4
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Double4);
|
||||
public:
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component.
|
||||
/// </summary>
|
||||
API_FIELD() double X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component.
|
||||
/// </summary>
|
||||
API_FIELD() double Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component.
|
||||
/// </summary>
|
||||
API_FIELD() double Z;
|
||||
|
||||
/// <summary>
|
||||
/// The W component.
|
||||
/// </summary>
|
||||
API_FIELD() double W;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The raw vector values (in xyzw order).
|
||||
/// </summary>
|
||||
double Raw[4];
|
||||
};
|
||||
|
||||
public:
|
||||
// Vector with all components equal 0
|
||||
static const Double4 Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Double4 One;
|
||||
|
||||
// Vector X=1, Y=0, Z=0, W=0
|
||||
static const Double4 UnitX;
|
||||
|
||||
// Vector X=0, Y=1, Z=0, W=0
|
||||
static const Double4 UnitY;
|
||||
|
||||
// Vector X=0, Y=0, Z=1, W=0
|
||||
static const Double4 UnitZ;
|
||||
|
||||
// Vector X=0, Y=0, Z=0, W=1
|
||||
static const Double4 UnitW;
|
||||
|
||||
// A minimum Double4
|
||||
static const Double4 Minimum;
|
||||
|
||||
// A maximum Double4
|
||||
static const Double4 Maximum;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor.
|
||||
/// </summary>
|
||||
Double4()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xyzw Value to assign to the all components
|
||||
Double4(double xyzw)
|
||||
: X(xyzw)
|
||||
, Y(xyzw)
|
||||
, Z(xyzw)
|
||||
, W(xyzw)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xyzw Values to assign
|
||||
explicit Double4(double xyzw[4]);
|
||||
|
||||
// Init
|
||||
// @param x X component value
|
||||
// @param y Y component value
|
||||
// @param z Z component value
|
||||
// @param w W component value
|
||||
Double4(double x, double y, double z, double w)
|
||||
: X(x)
|
||||
, Y(y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
explicit Double4(const Vector2& xy, double z, double w);
|
||||
explicit Double4(const Vector2& xy, const Vector2& zw);
|
||||
explicit Double4(const Vector3& xyz, double w);
|
||||
Double4(const Vector4& xyzw);
|
||||
explicit Double4(const Int2& xy, double z, double w);
|
||||
explicit Double4(const Int3& xyz, double w);
|
||||
explicit Double4(const Int4& xyzw);
|
||||
explicit Double4(const Double2& xy, double z, double w);
|
||||
explicit Double4(const Double3& xyz, double w);
|
||||
explicit Double4(const Color& color);
|
||||
explicit Double4(const Rectangle& rect);
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
|
||||
public:
|
||||
// Gets a value indicting whether this vector is zero.
|
||||
bool IsZero() const
|
||||
{
|
||||
return Math::IsZero(X) && Math::IsZero(Y) && Math::IsZero(Z) && Math::IsZero(W);
|
||||
}
|
||||
|
||||
// Gets a value indicting whether any vector component is zero.
|
||||
bool IsAnyZero() const
|
||||
{
|
||||
return Math::IsZero(X) || Math::IsZero(Y) || Math::IsZero(Z) || Math::IsZero(W);
|
||||
}
|
||||
|
||||
// Gets a value indicting whether this vector is one.
|
||||
bool IsOne() const
|
||||
{
|
||||
return Math::IsOne(X) && Math::IsOne(Y) && Math::IsOne(Z) && Math::IsOne(W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being absolute values of that vector.
|
||||
/// </summary>
|
||||
Double4 GetAbsolute() const
|
||||
{
|
||||
return Double4(Math::Abs(X), Math::Abs(Y), Math::Abs(Z), Math::Abs(W));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being opposite to values of that vector.
|
||||
/// </summary>
|
||||
Double4 GetNegative() const
|
||||
{
|
||||
return Double4(-X, -Y, -Z, -W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the average arithmetic of all the components.
|
||||
/// </summary>
|
||||
double AverageArithmetic() const
|
||||
{
|
||||
return (X + Y + Z + W) * 0.25;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sum of all vector components values.
|
||||
/// </summary>
|
||||
double SumValues() const
|
||||
{
|
||||
return X + Y + Z + W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the minimum value of all the components.
|
||||
/// </summary>
|
||||
double MinValue() const
|
||||
{
|
||||
return Math::Min(X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum value of all the components.
|
||||
/// </summary>
|
||||
double MaxValue() const
|
||||
{
|
||||
return Math::Max(X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components is not a number (NaN).
|
||||
/// </summary>
|
||||
bool IsNaN() const
|
||||
{
|
||||
return isnan(X) || isnan(Y) || isnan(Z) || isnan(W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components equal to +/- infinity.
|
||||
/// </summary>
|
||||
bool IsInfinity() const
|
||||
{
|
||||
return isinf(X) || isinf(Y) || isinf(Z) || isinf(W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if vector has one or more components equal to +/- infinity or NaN.
|
||||
/// </summary>
|
||||
bool IsNanOrInfinity() const
|
||||
{
|
||||
return IsInfinity() || IsNaN();
|
||||
}
|
||||
|
||||
public:
|
||||
// Arithmetic operators with Double4
|
||||
inline Double4 operator+(const Double4& b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
inline Double4 operator-(const Double4& b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
inline Double4 operator*(const Double4& b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
inline Double4 operator/(const Double4& b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
// op= operators with Double4
|
||||
inline Double4& operator+=(const Double4& b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Double4& operator-=(const Double4& b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Double4& operator*=(const Double4& b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Double4& operator/=(const Double4& b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators with double
|
||||
inline Double4 operator+(double b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
inline Double4 operator-(double b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
inline Double4 operator*(double b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
inline Double4 operator/(double b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
// op= operators with double
|
||||
inline Double4& operator+=(double b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Double4& operator-=(double b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Double4& operator*=(double b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Double4& operator/=(double b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison
|
||||
inline bool operator==(const Double4& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y && Z == b.Z && W == b.W;
|
||||
}
|
||||
|
||||
inline bool operator!=(const Double4& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y || Z != b.Z || W != b.W;
|
||||
}
|
||||
|
||||
inline bool operator>(const Double4& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y && Z > b.Z && W > b.W;
|
||||
}
|
||||
|
||||
inline bool operator>=(const Double4& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y && Z >= b.Z && W >= b.W;
|
||||
}
|
||||
|
||||
inline bool operator<(const Double4& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y && Z < b.Z && W < b.W;
|
||||
}
|
||||
|
||||
inline bool operator<=(const Double4& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y && Z <= b.Z && W <= b.W;
|
||||
}
|
||||
|
||||
public:
|
||||
static bool NearEqual(const Double4& a, const Double4& b)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X) && Math::NearEqual(a.Y, b.Y) && Math::NearEqual(a.Z, b.Z) && Math::NearEqual(a.W, b.W);
|
||||
}
|
||||
|
||||
static bool NearEqual(const Double4& a, const Double4& b, double epsilon)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X, epsilon) && Math::NearEqual(a.Y, b.Y, epsilon) && Math::NearEqual(a.Z, b.Z, epsilon) && Math::NearEqual(a.W, b.W, epsilon);
|
||||
}
|
||||
|
||||
public:
|
||||
static void Add(const Double4& a, const Double4& b, Double4& result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
result.Z = a.Z + b.Z;
|
||||
result.W = a.W + b.W;
|
||||
}
|
||||
|
||||
static Double4 Add(const Double4& a, const Double4& b)
|
||||
{
|
||||
Double4 result;
|
||||
Add(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Subtract(const Double4& a, const Double4& b, Double4& result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
result.Z = a.Z - b.Z;
|
||||
result.W = a.W - b.W;
|
||||
}
|
||||
|
||||
static Double4 Subtract(const Double4& a, const Double4& b)
|
||||
{
|
||||
Double4 result;
|
||||
Subtract(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Double4 Multiply(const Double4& a, const Double4& b)
|
||||
{
|
||||
return Double4(a.X * b.X, a.Y * b.Y, a.Z * b.Z, a.W * b.W);
|
||||
}
|
||||
|
||||
static Double4 Multiply(const Double4& a, double b)
|
||||
{
|
||||
return Double4(a.X * b, a.Y * b, a.Z * b, a.W * b);
|
||||
}
|
||||
|
||||
static Double4 Divide(const Double4& a, const Double4& b)
|
||||
{
|
||||
return Double4(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W);
|
||||
}
|
||||
|
||||
static Double4 Divide(const Double4& a, double b)
|
||||
{
|
||||
return Double4(a.X / b, a.Y / b, a.Z / b, a.W / b);
|
||||
}
|
||||
|
||||
static Double4 Floor(const Double4& v);
|
||||
static Double4 Frac(const Double4& v);
|
||||
static Double4 Round(const Double4& v);
|
||||
static Double4 Ceil(const Double4& v);
|
||||
|
||||
public:
|
||||
// Restricts a value to be within a specified range
|
||||
// @param value The value to clamp
|
||||
// @param min The minimum value,
|
||||
// @param max The maximum value
|
||||
// @returns Clamped value
|
||||
static Double4 Clamp(const Double4& value, const Double4& min, const Double4& max);
|
||||
|
||||
// Restricts a value to be within a specified range
|
||||
// @param value The value to clamp
|
||||
// @param min The minimum value,
|
||||
// @param max The maximum value
|
||||
// @param result When the method completes, contains the clamped value
|
||||
static void Clamp(const Double4& value, const Double4& min, const Double4& max, Double4& result);
|
||||
|
||||
// Performs a linear interpolation between two vectors
|
||||
// @param start Start vector
|
||||
// @param end End vector
|
||||
// @param amount Value between 0 and 1 indicating the weight of end
|
||||
// @param result When the method completes, contains the linear interpolation of the two vectors
|
||||
static void Lerp(const Double4& start, const Double4& end, double amount, Double4& result)
|
||||
{
|
||||
result.X = Math::Lerp(start.X, end.X, amount);
|
||||
result.Y = Math::Lerp(start.Y, end.Y, amount);
|
||||
result.Z = Math::Lerp(start.Z, end.Z, amount);
|
||||
result.W = Math::Lerp(start.W, end.W, amount);
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// Performs a linear interpolation between two vectors.
|
||||
// </summary>
|
||||
// @param start Start vector,
|
||||
// @param end End vector,
|
||||
// @param amount Value between 0 and 1 indicating the weight of @paramref end"/>,
|
||||
// @returns The linear interpolation of the two vectors
|
||||
static Double4 Lerp(const Double4& start, const Double4& end, double amount)
|
||||
{
|
||||
Double4 result;
|
||||
Lerp(start, end, amount, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Double4 Transform(const Double4& v, const Matrix& m);
|
||||
};
|
||||
|
||||
inline Double4 operator+(double a, const Double4& b)
|
||||
{
|
||||
return b + a;
|
||||
}
|
||||
|
||||
inline Double4 operator-(double a, const Double4& b)
|
||||
{
|
||||
return Double4(a) - b;
|
||||
}
|
||||
|
||||
inline Double4 operator*(double a, const Double4& b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline Double4 operator/(double a, const Double4& b)
|
||||
{
|
||||
return Double4(a) / b;
|
||||
}
|
||||
|
||||
namespace Math
|
||||
{
|
||||
FORCE_INLINE static bool NearEqual(const Double4& a, const Double4& b)
|
||||
{
|
||||
return Double4::NearEqual(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Double4>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Double4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W);
|
||||
#include "Vector4.h"
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
|
||||
static_assert(sizeof(Int2) == 8, "Invalid Int2 type size.");
|
||||
|
||||
const Int2 Int2::Zero(0);
|
||||
const Int2 Int2::One(1);
|
||||
const Int2 Int2::Minimum(MIN_int32);
|
||||
const Int2 Int2::Maximum(MAX_int32);
|
||||
|
||||
Int2::Int2(const Int3& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Int2::Int2(const Int4& xyzw)
|
||||
: X(xyzw.X)
|
||||
, Y(xyzw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Int2::Int2(const Vector2& xy)
|
||||
: X(static_cast<int32>(xy.X))
|
||||
, Y(static_cast<int32>(xy.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Int2::Int2(const Vector3& xyz)
|
||||
: X(static_cast<int32>(xyz.X))
|
||||
, Y(static_cast<int32>(xyz.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Int2::Int2(const Vector4& xyzw)
|
||||
: X(static_cast<int32>(xyzw.X))
|
||||
, Y(static_cast<int32>(xyzw.Y))
|
||||
{
|
||||
}
|
||||
|
||||
String Int2::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
@@ -2,389 +2,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Math.h"
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
/// <summary>
|
||||
/// Two-components vector (32 bit integer type).
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API Int2
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Int2);
|
||||
public:
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 Y;
|
||||
};
|
||||
|
||||
// Raw values
|
||||
int32 Raw[2];
|
||||
};
|
||||
|
||||
public:
|
||||
// Vector with all components equal 0
|
||||
static const Int2 Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Int2 One;
|
||||
|
||||
// A minimum Int2
|
||||
static const Int2 Minimum;
|
||||
|
||||
// A maximum Int2
|
||||
static const Int2 Maximum;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor.
|
||||
/// </summary>
|
||||
Int2()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xy Value to assign to the all components
|
||||
Int2(int32 xy)
|
||||
: X(xy)
|
||||
, Y(xy)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param x X component value
|
||||
// @param y Y component value
|
||||
Int2(int32 x, int32 y)
|
||||
: X(x)
|
||||
, Y(y)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xyz Int3 to use X and Y components
|
||||
Int2(const Int3& xyz);
|
||||
|
||||
// Init
|
||||
// @param xyzw Int4 to use X and Y components
|
||||
Int2(const Int4& xyzw);
|
||||
|
||||
// Init
|
||||
// @param xy Vector2 to use X and Y components
|
||||
explicit Int2(const Vector2& xy);
|
||||
|
||||
// Init
|
||||
// @param xyz Vector3 to use X and Y components
|
||||
explicit Int2(const Vector3& xyz);
|
||||
|
||||
// Init
|
||||
// @param xyzw Vector4 to use X and Y components
|
||||
explicit Int2(const Vector4& xyzw);
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
|
||||
public:
|
||||
// Arithmetic operators with Int2
|
||||
|
||||
Int2 operator+(const Int2& b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Int2 operator-(const Int2& b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Int2 operator*(const Int2& b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Int2 operator/(const Int2& b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
Int2 operator-() const
|
||||
{
|
||||
return Int2(-X, -Y);
|
||||
}
|
||||
|
||||
// op= operators with Int2
|
||||
|
||||
Int2& operator+=(const Int2& b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int2& operator-=(const Int2& b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int2& operator*=(const Int2& b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int2& operator/=(const Int2& b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators with int32
|
||||
|
||||
Int2 operator+(int32 b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Int2 operator-(int32 b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Int2 operator*(int32 b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Int2 operator/(int32 b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
// op= operators with int32
|
||||
|
||||
Int2& operator+=(int32 b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int2& operator-=(int32 b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int2& operator*=(int32 b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int2& operator/=(int32 b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
|
||||
bool operator==(const Int2& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y;
|
||||
}
|
||||
|
||||
bool operator!=(const Int2& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y;
|
||||
}
|
||||
|
||||
bool operator>(const Int2& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y;
|
||||
}
|
||||
|
||||
bool operator>=(const Int2& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y;
|
||||
}
|
||||
|
||||
bool operator<(const Int2& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y;
|
||||
}
|
||||
|
||||
bool operator<=(const Int2& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y;
|
||||
}
|
||||
|
||||
public:
|
||||
static void Add(const Int2& a, const Int2& b, Int2& result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
}
|
||||
|
||||
static Int2 Add(const Int2& a, const Int2& b)
|
||||
{
|
||||
Int2 result;
|
||||
Add(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Subtract(const Int2& a, const Int2& b, Int2& result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
}
|
||||
|
||||
static Int2 Subtract(const Int2& a, const Int2& b)
|
||||
{
|
||||
Int2 result;
|
||||
Subtract(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Int2 Multiply(const Int2& a, const Int2& b)
|
||||
{
|
||||
return Int2(a.X * b.X, a.Y * b.Y);
|
||||
}
|
||||
|
||||
static Int2 Multiply(const Int2& a, int32 b)
|
||||
{
|
||||
return Int2(a.X * b, a.Y * b);
|
||||
}
|
||||
|
||||
static Int2 Divide(const Int2& a, const Int2& b)
|
||||
{
|
||||
return Int2(a.X / b.X, a.Y / b.Y);
|
||||
}
|
||||
|
||||
static Int2 Divide(const Int2& a, int32 b)
|
||||
{
|
||||
return Int2(a.X / b, a.Y / b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether this vector is zero.
|
||||
/// </summary>
|
||||
/// <returns> True if the vector is zero, otherwise false.</returns>
|
||||
bool IsZero() const
|
||||
{
|
||||
return X == 0 && Y == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether any vector component is zero.
|
||||
/// </summary>
|
||||
/// <returns> True if a component is zero, otherwise false.</returns>
|
||||
bool IsAnyZero() const
|
||||
{
|
||||
return X == 0 || Y == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether this vector is one.
|
||||
/// </summary>
|
||||
/// <returns> True if the vector is one, otherwise false.</returns>
|
||||
bool IsOne() const
|
||||
{
|
||||
return X == 1 && Y == 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being opposite to values of that vector
|
||||
/// </summary>
|
||||
/// <returns>Negative vector</returns>
|
||||
Int2 GetNegative() const
|
||||
{
|
||||
return Int2(-X, -Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns average arithmetic of all the components
|
||||
/// </summary>
|
||||
/// <returns>Average arithmetic of all the components</returns>
|
||||
float AverageArithmetic() const
|
||||
{
|
||||
return (X + Y) * 0.5f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets sum of all vector components values
|
||||
/// </summary>
|
||||
/// <returns>Sum of X, Y, Z and W</returns>
|
||||
int32 SumValues() const
|
||||
{
|
||||
return X + Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns minimum value of all the components
|
||||
/// </summary>
|
||||
/// <returns>Minimum value</returns>
|
||||
int32 MinValue() const
|
||||
{
|
||||
return Math::Min(X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns maximum value of all the components
|
||||
/// </summary>
|
||||
/// <returns>Maximum value</returns>
|
||||
int32 MaxValue() const
|
||||
{
|
||||
return Math::Max(X, Y);
|
||||
}
|
||||
|
||||
// Returns a vector containing the smallest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
static Int2 Min(const Int2& a, const Int2& b)
|
||||
{
|
||||
return Int2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Returns a vector containing the largest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
static Int2 Max(const Int2& a, const Int2& b)
|
||||
{
|
||||
return Int2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Returns a vector containing the smallest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
|
||||
static void Min(const Int2& a, const Int2& b, Int2& result)
|
||||
{
|
||||
result = Int2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Returns a vector containing the largest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
|
||||
static void Max(const Int2& a, const Int2& b, Int2& result)
|
||||
{
|
||||
result = Int2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Int2>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Int2, "X:{0} Y:{1}", v.X, v.Y);
|
||||
#include "Vector2.h"
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
|
||||
static_assert(sizeof(Int3) == 12, "Invalid Int3 type size.");
|
||||
|
||||
const Int3 Int3::Zero(0);
|
||||
const Int3 Int3::One(1);
|
||||
const Int3 Int3::Minimum(MIN_int32);
|
||||
const Int3 Int3::Maximum(MAX_int32);
|
||||
|
||||
Int3::Int3(const Int2& xy, int32 z)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Int3::Int3(const Int4& xyzw)
|
||||
: X(xyzw.X)
|
||||
, Y(xyzw.Y)
|
||||
, Z(xyzw.Z)
|
||||
{
|
||||
}
|
||||
|
||||
Int3::Int3(const Vector2& xy, int32 z)
|
||||
: X(static_cast<int32>(xy.X))
|
||||
, Y(static_cast<int32>(xy.Y))
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Int3::Int3(const Vector3& xyz)
|
||||
: X(static_cast<int32>(xyz.X))
|
||||
, Y(static_cast<int32>(xyz.Y))
|
||||
, Z(static_cast<int32>(xyz.Z))
|
||||
{
|
||||
}
|
||||
|
||||
Int3::Int3(const Vector4& xyzw)
|
||||
: X(static_cast<int32>(xyzw.X))
|
||||
, Y(static_cast<int32>(xyzw.Y))
|
||||
, Z(static_cast<int32>(xyzw.Z))
|
||||
{
|
||||
}
|
||||
|
||||
String Int3::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
@@ -2,402 +2,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Math.h"
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
/// <summary>
|
||||
/// Three-components vector (32 bit integer type).
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API Int3
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Int3);
|
||||
public:
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 Z;
|
||||
};
|
||||
|
||||
// Raw values
|
||||
int32 Raw[3];
|
||||
};
|
||||
|
||||
public:
|
||||
// Vector with all components equal 0
|
||||
static const Int3 Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Int3 One;
|
||||
|
||||
// A minimum Int3
|
||||
static const Int3 Minimum;
|
||||
|
||||
// A maximum Int3
|
||||
static const Int3 Maximum;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor.
|
||||
/// </summary>
|
||||
Int3()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xy Value to assign to the all components
|
||||
Int3(int32 xyz)
|
||||
: X(xyz)
|
||||
, Y(xyz)
|
||||
, Z(xyz)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param x X component value
|
||||
// @param y Y component value
|
||||
// @param z Z component value
|
||||
Int3(int32 x, int32 y, int32 z)
|
||||
: X(x)
|
||||
, Y(y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param v Int2 to use X and Y components
|
||||
// @param z Z component value
|
||||
Int3(const Int2& xy, int32 z);
|
||||
|
||||
// Init
|
||||
// @param v Int4 to use X and Y components
|
||||
Int3(const Int4& xyzw);
|
||||
|
||||
// Init
|
||||
// @param v Vector2 to use X and Y components
|
||||
// @param z Z component value
|
||||
explicit Int3(const Vector2& xy, int32 z);
|
||||
|
||||
// Init
|
||||
// @param v Vector3 to use X, Y and Z components
|
||||
explicit Int3(const Vector3& xyz);
|
||||
|
||||
// Init
|
||||
// @param v Vector4 to use X and Y components
|
||||
explicit Int3(const Vector4& xyzw);
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
|
||||
public:
|
||||
// Arithmetic operators with Int2
|
||||
|
||||
Int3 operator+(const Int3& b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Int3 operator-(const Int3& b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Int3 operator*(const Int3& b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Int3 operator/(const Int3& b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
Int3 operator-() const
|
||||
{
|
||||
return Int3(-X, -Y, -Z);
|
||||
}
|
||||
|
||||
// op= operators with Int2
|
||||
|
||||
Int3& operator+=(const Int3& b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int3& operator-=(const Int3& b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int3& operator*=(const Int3& b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int3& operator/=(const Int3& b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators with int32
|
||||
|
||||
Int3 operator+(int32 b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Int3 operator-(int32 b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Int3 operator*(int32 b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Int3 operator/(int32 b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
// op= operators with int32
|
||||
|
||||
Int3& operator+=(int32 b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int3& operator-=(int32 b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int3& operator*=(int32 b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int3& operator/=(int32 b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
|
||||
bool operator==(const Int3& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y;
|
||||
}
|
||||
|
||||
bool operator!=(const Int3& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y;
|
||||
}
|
||||
|
||||
bool operator>(const Int3& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y;
|
||||
}
|
||||
|
||||
bool operator>=(const Int3& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y;
|
||||
}
|
||||
|
||||
bool operator<(const Int3& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y;
|
||||
}
|
||||
|
||||
bool operator<=(const Int3& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y;
|
||||
}
|
||||
|
||||
public:
|
||||
static void Add(const Int3& a, const Int3& b, Int3& result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
result.Z = a.Z + b.Z;
|
||||
}
|
||||
|
||||
static Int3 Add(const Int3& a, const Int3& b)
|
||||
{
|
||||
Int3 result;
|
||||
Add(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Subtract(const Int3& a, const Int3& b, Int3& result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
result.Z = a.Z - b.Z;
|
||||
}
|
||||
|
||||
static Int3 Subtract(const Int3& a, const Int3& b)
|
||||
{
|
||||
Int3 result;
|
||||
Subtract(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Int3 Multiply(const Int3& a, const Int3& b)
|
||||
{
|
||||
return Int3(a.X * b.X, a.Y * b.Y, a.Z * b.Z);
|
||||
}
|
||||
|
||||
static Int3 Multiply(const Int3& a, int32 b)
|
||||
{
|
||||
return Int3(a.X * b, a.Y * b, a.Z * b);
|
||||
}
|
||||
|
||||
static Int3 Divide(const Int3& a, const Int3& b)
|
||||
{
|
||||
return Int3(a.X / b.X, a.Y / b.Y, a.Z / b.Z);
|
||||
}
|
||||
|
||||
static Int3 Divide(const Int3& a, int32 b)
|
||||
{
|
||||
return Int3(a.X / b, a.Y / b, a.Z / b);
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether this vector is zero.
|
||||
/// </summary>
|
||||
/// <returns> True if the vector is zero, otherwise false.</returns>
|
||||
bool IsZero() const
|
||||
{
|
||||
return X == 0 && Y == 0 && Z == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether any vector component is zero.
|
||||
/// </summary>
|
||||
/// <returns> True if a component is zero, otherwise false.</returns>
|
||||
bool IsAnyZero() const
|
||||
{
|
||||
return X == 0 || Y == 0 || Z == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether this vector is one.
|
||||
/// </summary>
|
||||
/// <returns> True if the vector is one, otherwise false.</returns>
|
||||
bool IsOne() const
|
||||
{
|
||||
return X == 1 && Y == 1 && Z == 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being opposite to values of that vector
|
||||
/// </summary>
|
||||
/// <returns>Negative vector</returns>
|
||||
Int3 GetNegative() const
|
||||
{
|
||||
return Int3(-X, -Y, -Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns average arithmetic of all the components
|
||||
/// </summary>
|
||||
/// <returns>Average arithmetic of all the components</returns>
|
||||
float AverageArithmetic() const
|
||||
{
|
||||
return (X + Y + Z) / 3.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets sum of all vector components values
|
||||
/// </summary>
|
||||
/// <returns>Sum of X, Y, Z and W</returns>
|
||||
int32 SumValues() const
|
||||
{
|
||||
return X + Y + Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns minimum value of all the components
|
||||
/// </summary>
|
||||
/// <returns>Minimum value</returns>
|
||||
int32 MinValue() const
|
||||
{
|
||||
return Math::Min(X, Y, Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns maximum value of all the components
|
||||
/// </summary>
|
||||
/// <returns>Maximum value</returns>
|
||||
int32 MaxValue() const
|
||||
{
|
||||
return Math::Max(X, Y, Z);
|
||||
}
|
||||
|
||||
// Returns a vector containing the largest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
static Int3 Max(const Int3& a, const Int3& b)
|
||||
{
|
||||
return Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z);
|
||||
}
|
||||
|
||||
// Returns a vector containing the smallest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
static Int3 Min(const Int3& a, const Int3& b)
|
||||
{
|
||||
return Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z);
|
||||
}
|
||||
|
||||
// Returns a vector containing the largest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
|
||||
static void Max(const Int3& a, const Int3& b, Int3& result)
|
||||
{
|
||||
result = Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z);
|
||||
}
|
||||
|
||||
// Returns a vector containing the smallest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
|
||||
static void Min(const Int3& a, const Int3& b, Int3 result)
|
||||
{
|
||||
result = Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Int3>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Int3, "X:{0} Y:{1} Z:{2}", v.X, v.Y, v.Z);
|
||||
#include "Vector3.h"
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
|
||||
static_assert(sizeof(Int4) == 16, "Invalid Int4 type size.");
|
||||
|
||||
const Int4 Int4::Zero(0);
|
||||
const Int4 Int4::One(1);
|
||||
const Int4 Int4::Minimum(MIN_int32);
|
||||
const Int4 Int4::Maximum(MAX_int32);
|
||||
|
||||
Int4::Int4(const Int2& xy, int32 z, int32 w)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Int4::Int4(const Int3& xyz, int32 w)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Int4::Int4(const Vector2& v, int32 z, int32 w)
|
||||
: X(static_cast<int32>(v.X))
|
||||
, Y(static_cast<int32>(v.Y))
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Int4::Int4(const Vector3& v, int32 w)
|
||||
: X(static_cast<int32>(v.X))
|
||||
, Y(static_cast<int32>(v.Y))
|
||||
, Z(static_cast<int32>(v.Z))
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Int4::Int4(const Vector4& v)
|
||||
: X(static_cast<int32>(v.X))
|
||||
, Y(static_cast<int32>(v.Y))
|
||||
, Z(static_cast<int32>(v.Z))
|
||||
, W(static_cast<int32>(v.W))
|
||||
{
|
||||
}
|
||||
|
||||
String Int4::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
@@ -2,416 +2,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Math.h"
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
/// <summary>
|
||||
/// Four-components vector (32 bit integer type).
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API Int4
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Int4);
|
||||
public:
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 Z;
|
||||
|
||||
/// <summary>
|
||||
/// The W component.
|
||||
/// </summary>
|
||||
API_FIELD() int32 W;
|
||||
};
|
||||
|
||||
// Raw values
|
||||
int32 Raw[4];
|
||||
};
|
||||
|
||||
public:
|
||||
// Vector with all components equal 0
|
||||
static const Int4 Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Int4 One;
|
||||
|
||||
// A minimum Int4
|
||||
static const Int4 Minimum;
|
||||
|
||||
// A maximum Int4
|
||||
static const Int4 Maximum;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor.
|
||||
/// </summary>
|
||||
Int4()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xy Value to assign to the all components
|
||||
Int4(int32 xyzw)
|
||||
: X(xyzw)
|
||||
, Y(xyzw)
|
||||
, Z(xyzw)
|
||||
, W(xyzw)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param x X component value
|
||||
// @param y Y component value
|
||||
// @param z Z component value
|
||||
// @param w W component value
|
||||
Int4(int32 x, int32 y, int32 z, int32 w)
|
||||
: X(x)
|
||||
, Y(y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param v Int2 to use X and Y components
|
||||
// @param z Z component value
|
||||
// @param w W component value
|
||||
Int4(const Int2& xy, int32 z, int32 w);
|
||||
|
||||
// Init
|
||||
// @param v Int3 to use X , Y and Z components
|
||||
// @param w W component value
|
||||
Int4(const Int3& xyz, int32 w);
|
||||
|
||||
// Init
|
||||
// @param v Vector2 to use X and Y components
|
||||
// @param z Z component value
|
||||
// @param w W component value
|
||||
explicit Int4(const Vector2& xy, int32 z, int32 w);
|
||||
|
||||
// Init
|
||||
// @param v Vector3 to use X , Y and Z components
|
||||
// @param w W component value
|
||||
explicit Int4(const Vector3& xyz, int32 w);
|
||||
|
||||
// Init
|
||||
// @param v Vector to use X, Y, Z and W components
|
||||
explicit Int4(const Vector4& xyzw);
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
|
||||
public:
|
||||
// Arithmetic operators with Int2
|
||||
|
||||
Int4 operator+(const Int4& b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Int4 operator-(const Int4& b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Int4 operator*(const Int4& b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Int4 operator/(const Int4& b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
Int4 operator-() const
|
||||
{
|
||||
return Int4(-X, -Y, -Z, -W);
|
||||
}
|
||||
|
||||
// op= operators with Int2
|
||||
|
||||
Int4& operator+=(const Int4& b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int4& operator-=(const Int4& b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int4& operator*=(const Int4& b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int4& operator/=(const Int4& b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators with int32
|
||||
|
||||
Int4 operator+(int32 b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Int4 operator-(int32 b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Int4 operator*(int32 b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Int4 operator/(int32 b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
// op= operators with int32
|
||||
|
||||
Int4& operator+=(int32 b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int4& operator-=(int32 b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int4& operator*=(int32 b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Int4& operator/=(int32 b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
|
||||
bool operator==(const Int4& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y;
|
||||
}
|
||||
|
||||
bool operator!=(const Int4& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y;
|
||||
}
|
||||
|
||||
bool operator>(const Int4& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y;
|
||||
}
|
||||
|
||||
bool operator>=(const Int4& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y;
|
||||
}
|
||||
|
||||
bool operator<(const Int4& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y;
|
||||
}
|
||||
|
||||
bool operator<=(const Int4& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y;
|
||||
}
|
||||
|
||||
public:
|
||||
static void Add(const Int4& a, const Int4& b, Int4& result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
result.Z = a.Z + b.Z;
|
||||
result.W = a.W + b.W;
|
||||
}
|
||||
|
||||
static Int4 Add(const Int4& a, const Int4& b)
|
||||
{
|
||||
Int4 result;
|
||||
Add(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Subtract(const Int4& a, const Int4& b, Int4& result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
result.Z = a.Z - b.Z;
|
||||
result.W = a.W - b.W;
|
||||
}
|
||||
|
||||
static Int4 Subtract(const Int4& a, const Int4& b)
|
||||
{
|
||||
Int4 result;
|
||||
Subtract(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Int4 Multiply(const Int4& a, const Int4& b)
|
||||
{
|
||||
return Int4(a.X * b.X, a.Y * b.Y, a.Z * b.Z, a.W * b.W);
|
||||
}
|
||||
|
||||
static Int4 Multiply(const Int4& a, int32 b)
|
||||
{
|
||||
return Int4(a.X * b, a.Y * b, a.Z * b, a.W * b);
|
||||
}
|
||||
|
||||
static Int4 Divide(const Int4& a, const Int4& b)
|
||||
{
|
||||
return Int4(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W);
|
||||
}
|
||||
|
||||
static Int4 Divide(const Int4& a, int32 b)
|
||||
{
|
||||
return Int4(a.X / b, a.Y / b, a.Z / b, a.Y / b);
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether this vector is zero.
|
||||
/// </summary>
|
||||
/// <returns> True if the vector is zero, otherwise false.</returns>
|
||||
bool IsZero() const
|
||||
{
|
||||
return X == 0 && Y == 0 && Z == 0 && W == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether any vector component is zero.
|
||||
/// </summary>
|
||||
/// <returns> True if a component is zero, otherwise false.</returns>
|
||||
bool IsAnyZero() const
|
||||
{
|
||||
return X == 0 || Y == 0 || Z == 0 || W == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicting whether this vector is one.
|
||||
/// </summary>
|
||||
/// <returns> True if the vector is one, otherwise false.</returns>
|
||||
bool IsOne() const
|
||||
{
|
||||
return X == 1 && Y == 1 && Z == 1 && W == 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being opposite to values of that vector
|
||||
/// </summary>
|
||||
/// <returns>Negative vector</returns>
|
||||
Int4 GetNegative() const
|
||||
{
|
||||
return Int4(-X, -Y, -Z, -W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns average arithmetic of all the components
|
||||
/// </summary>
|
||||
/// <returns>Average arithmetic of all the components</returns>
|
||||
float AverageArithmetic() const
|
||||
{
|
||||
return (X + Y + Z + W) * 0.25f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets sum of all vector components values
|
||||
/// </summary>
|
||||
/// <returns>Sum of X, Y, Z and W</returns>
|
||||
int32 SumValues() const
|
||||
{
|
||||
return X + Y + Z + W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns minimum value of all the components
|
||||
/// </summary>
|
||||
/// <returns>Minimum value</returns>
|
||||
int32 MinValue() const
|
||||
{
|
||||
return Math::Min(X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns maximum value of all the components
|
||||
/// </summary>
|
||||
/// <returns>Maximum value</returns>
|
||||
int32 MaxValue() const
|
||||
{
|
||||
return Math::Max(X, Y, Z, W);
|
||||
}
|
||||
|
||||
// Returns a vector containing the largest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
static Int4 Max(const Int4& a, const Int4& b)
|
||||
{
|
||||
return Int4(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z, a.W > b.W ? a.W : b.W);
|
||||
}
|
||||
|
||||
// Returns a vector containing the smallest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
static Int4 Min(const Int4& a, const Int4& b)
|
||||
{
|
||||
return Int4(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z, a.W < b.W ? a.W : b.W);
|
||||
}
|
||||
|
||||
// Returns a vector containing the largest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the largest components of the source vectors
|
||||
static void Max(const Int4& a, const Int4& b, Int4& result)
|
||||
{
|
||||
result = Int4(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z, a.W > b.W ? a.W : b.W);
|
||||
}
|
||||
|
||||
// Returns a vector containing the smallest components of the specified vectors
|
||||
// @param a The first source vector
|
||||
// @param b The second source vector
|
||||
// @param result When the method completes, contains an new vector composed of the smallest components of the source vectors
|
||||
static void Min(const Int4& a, const Int4& b, Int4& result)
|
||||
{
|
||||
result = Int4(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z, a.W < b.W ? a.W : b.W);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Int4>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Int4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W);
|
||||
#include "Vector4.h"
|
||||
|
||||
@@ -631,7 +631,8 @@ namespace Math
|
||||
}
|
||||
|
||||
// Given a heading which may be outside the +/- PI range, 'unwind' it back into that range
|
||||
static float UnwindRadians(float a)
|
||||
template<typename T>
|
||||
static T UnwindRadians(T a)
|
||||
{
|
||||
while (a > PI)
|
||||
a -= TWO_PI;
|
||||
@@ -641,12 +642,13 @@ namespace Math
|
||||
}
|
||||
|
||||
// Utility to ensure angle is between +/- 180 degrees by unwinding
|
||||
static float UnwindDegrees(float a)
|
||||
template<typename T>
|
||||
static T UnwindDegrees(T a)
|
||||
{
|
||||
while (a > 180.f)
|
||||
a -= 360.f;
|
||||
while (a < -180.f)
|
||||
a += 360.f;
|
||||
while (a > 180)
|
||||
a -= 360;
|
||||
while (a < -180)
|
||||
a += 360;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
@@ -294,26 +294,6 @@ namespace Math
|
||||
return delta;
|
||||
}
|
||||
|
||||
// Given a heading which may be outside the +/- PI range, 'unwind' it back into that range
|
||||
static double UnwindRadians(double a)
|
||||
{
|
||||
while (a > PI)
|
||||
a -= TWO_PI;
|
||||
while (a < -PI)
|
||||
a += TWO_PI;
|
||||
return a;
|
||||
}
|
||||
|
||||
// Utility to ensure angle is between +/- 180 degrees by unwinding
|
||||
static double UnwindDegrees(double a)
|
||||
{
|
||||
while (a > 180.)
|
||||
a -= 360.;
|
||||
while (a < -180.)
|
||||
a += 360.;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns value based on comparand. The main purpose of this function is to avoid branching based on floating point comparison which can be avoided via compiler intrinsics.
|
||||
/// </summary>
|
||||
|
||||
@@ -611,7 +611,7 @@ void Matrix::CreateWorld(const Vector3& position, const Vector3& forward, const
|
||||
Vector3 vector3, vector31, vector32;
|
||||
|
||||
Vector3::Normalize(forward, vector3);
|
||||
vector3.Negate();
|
||||
vector3 = vector3.GetNegative();
|
||||
Vector3::Normalize(Vector3::Cross(up, vector3), vector31);
|
||||
Vector3::Cross(vector3, vector31, vector32);
|
||||
|
||||
|
||||
@@ -2899,7 +2899,7 @@ namespace FlaxEngine
|
||||
public static void CreateWorld(ref Vector3 position, ref Vector3 forward, ref Vector3 up, out Matrix result)
|
||||
{
|
||||
Vector3.Normalize(ref forward, out var vector3);
|
||||
vector3.Negate();
|
||||
vector3 = vector3.Negative;
|
||||
Vector3 vector31 = Vector3.Cross(up, vector3);
|
||||
vector31.Normalize();
|
||||
Vector3.Cross(ref vector3, ref vector31, out var vector32);
|
||||
|
||||
@@ -135,8 +135,7 @@ ContainmentType OrientedBoundingBox::Contains(const Vector3& point, float* dista
|
||||
// Get minimum distance to edge in local space
|
||||
Vector3 tmp;
|
||||
Vector3::Subtract(Extents, locPoint, tmp);
|
||||
tmp.Absolute();
|
||||
const float minDstToEdgeLocal = tmp.MinValue();
|
||||
const float minDstToEdgeLocal = tmp.GetAbsolute().MinValue();
|
||||
|
||||
// Transform distance to world space
|
||||
Vector3 dstVec = Vector3::UnitX * minDstToEdgeLocal;
|
||||
|
||||
@@ -71,9 +71,7 @@ Vector3 Quaternion::GetEuler() const
|
||||
result.Z = Math::Atan2(2.0f * q.X * q.Y + 2.0f * q.Z * q.W, 1 - 2.0f * (q.Y * q.Y + q.Z * q.Z));
|
||||
}
|
||||
|
||||
result *= RadiansToDegrees;
|
||||
result.UnwindEuler();
|
||||
return result;
|
||||
return Math::UnwindDegrees(result * RadiansToDegrees);
|
||||
}
|
||||
|
||||
void Quaternion::Multiply(const Quaternion& other)
|
||||
|
||||
@@ -221,8 +221,7 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
result *= Mathf.RadiansToDegrees;
|
||||
result.UnwindEuler();
|
||||
return result;
|
||||
return new Vector3(Mathf.UnwindDegrees(result.X), Mathf.UnwindDegrees(result.Y), Mathf.UnwindDegrees(result.Z));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
struct Vector2;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Matrix;
|
||||
struct Matrix3x3;
|
||||
|
||||
@@ -232,17 +229,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of the quaternion.
|
||||
/// </summary>
|
||||
void Negate()
|
||||
{
|
||||
X = -X;
|
||||
Y = -Y;
|
||||
Z = -Z;
|
||||
W = -W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the quaternion into a unit quaternion.
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Transform.h"
|
||||
#include "Matrix.h"
|
||||
#include "Vector2.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
Transform Transform::Identity(Vector3(0, 0, 0));
|
||||
@@ -70,13 +71,6 @@ Transform Transform::Subtract(const Transform& other) const
|
||||
return result;
|
||||
}
|
||||
|
||||
Transform Transform::LocalToWorld(const Transform& other) const
|
||||
{
|
||||
Transform result;
|
||||
LocalToWorld(other, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Transform::LocalToWorld(const Transform& other, Transform& result) const
|
||||
{
|
||||
//Quaternion::Multiply(Orientation, other.Orientation, result.Orientation);
|
||||
@@ -128,13 +122,6 @@ void Transform::LocalToWorld(const Transform& other, Transform& result) const
|
||||
result.Translation = Vector3(tmp.X + Translation.X, tmp.Y + Translation.Y, tmp.Z + Translation.Z);
|
||||
}
|
||||
|
||||
Vector3 Transform::LocalToWorld(const Vector3& point) const
|
||||
{
|
||||
Vector3 result = point * Scale;
|
||||
Vector3::Transform(result, Orientation, result);
|
||||
return result + Translation;
|
||||
}
|
||||
|
||||
Vector3 Transform::LocalToWorldVector(const Vector3& vector) const
|
||||
{
|
||||
Vector3 result = vector * Scale;
|
||||
@@ -149,38 +136,6 @@ void Transform::LocalToWorld(const Vector3& point, Vector3& result) const
|
||||
Vector3::Add(tmp, Translation, result);
|
||||
}
|
||||
|
||||
void Transform::LocalToWorld(const Vector3* points, int32 pointsCount, Vector3* result) const
|
||||
{
|
||||
for (int32 i = 0; i < pointsCount; i++)
|
||||
{
|
||||
result[i] = Vector3::Transform(points[i] * Scale, Orientation) + Translation;
|
||||
}
|
||||
}
|
||||
|
||||
Transform Transform::WorldToLocal(const Transform& other) const
|
||||
{
|
||||
Transform result;
|
||||
|
||||
Vector3 invScale = Scale;
|
||||
if (invScale.X != 0.0f)
|
||||
invScale.X = 1.0f / invScale.X;
|
||||
if (invScale.Y != 0.0f)
|
||||
invScale.Y = 1.0f / invScale.Y;
|
||||
if (invScale.Z != 0.0f)
|
||||
invScale.Z = 1.0f / invScale.Z;
|
||||
|
||||
const Quaternion invRotation = Orientation.Conjugated();
|
||||
|
||||
Quaternion::Multiply(invRotation, other.Orientation, result.Orientation);
|
||||
result.Orientation.Normalize();
|
||||
Vector3::Multiply(other.Scale, invScale, result.Scale);
|
||||
const Vector3 tmp = other.Translation - Translation;
|
||||
Vector3::Transform(tmp, invRotation, result.Translation);
|
||||
Vector3::Multiply(result.Translation, invScale, result.Translation);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Transform::WorldToLocal(const Transform& other, Transform& result) const
|
||||
{
|
||||
Vector3 invScale = Scale;
|
||||
@@ -201,7 +156,7 @@ void Transform::WorldToLocal(const Transform& other, Transform& result) const
|
||||
Vector3::Multiply(result.Translation, invScale, result.Translation);
|
||||
}
|
||||
|
||||
Vector3 Transform::WorldToLocal(const Vector3& point) const
|
||||
void Transform::WorldToLocal(const Vector3& point, Vector3& result) const
|
||||
{
|
||||
Vector3 invScale = Scale;
|
||||
if (invScale.X != 0.0f)
|
||||
@@ -210,13 +165,10 @@ Vector3 Transform::WorldToLocal(const Vector3& point) const
|
||||
invScale.Y = 1.0f / invScale.Y;
|
||||
if (invScale.Z != 0.0f)
|
||||
invScale.Z = 1.0f / invScale.Z;
|
||||
|
||||
const Quaternion invRotation = Orientation.Conjugated();
|
||||
|
||||
Vector3 result = point - Translation;
|
||||
result = point - Translation;
|
||||
Vector3::Transform(result, invRotation, result);
|
||||
|
||||
return result * invScale;
|
||||
result *= invScale;
|
||||
}
|
||||
|
||||
Vector3 Transform::WorldToLocalVector(const Vector3& vector) const
|
||||
@@ -237,26 +189,6 @@ Vector3 Transform::WorldToLocalVector(const Vector3& vector) const
|
||||
return result * invScale;
|
||||
}
|
||||
|
||||
void Transform::WorldToLocal(const Vector3* points, int32 pointsCount, Vector3* result) const
|
||||
{
|
||||
Vector3 invScale = Scale;
|
||||
if (invScale.X != 0.0f)
|
||||
invScale.X = 1.0f / invScale.X;
|
||||
if (invScale.Y != 0.0f)
|
||||
invScale.Y = 1.0f / invScale.Y;
|
||||
if (invScale.Z != 0.0f)
|
||||
invScale.Z = 1.0f / invScale.Z;
|
||||
|
||||
const Quaternion invRotation = Orientation.Conjugated();
|
||||
|
||||
for (int32 i = 0; i < pointsCount; i++)
|
||||
{
|
||||
result[i] = points[i] - Translation;
|
||||
Vector3::Transform(result[i], invRotation, result[i]);
|
||||
result[i] *= invScale;
|
||||
}
|
||||
}
|
||||
|
||||
Transform Transform::Lerp(const Transform& t1, const Transform& t2, float amount)
|
||||
{
|
||||
Transform result;
|
||||
|
||||
@@ -85,18 +85,16 @@ public:
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Checks if transform is an identity transformation
|
||||
/// Checks if transform is an identity transformation.
|
||||
/// </summary>
|
||||
/// <returns>True if is identity, otherwise false</returns>
|
||||
bool IsIdentity() const
|
||||
{
|
||||
return Translation.IsZero() && Orientation.IsIdentity() && Scale.IsOne();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if transform has one or more components equal to +/- infinity or NaN
|
||||
/// Returns true if transform has one or more components equal to +/- infinity or NaN.
|
||||
/// </summary>
|
||||
/// <returns>True if one or more components equal to +/- infinity or NaN</returns>
|
||||
bool IsNanOrInfinity() const
|
||||
{
|
||||
return Translation.IsNanOrInfinity() || Orientation.IsNanOrInfinity() || Scale.IsNanOrInfinity();
|
||||
@@ -105,7 +103,6 @@ public:
|
||||
/// <summary>
|
||||
/// Calculates the determinant of this transformation.
|
||||
/// </summary>
|
||||
/// <returns>The determinant.</returns>
|
||||
FORCE_INLINE float GetDeterminant() const
|
||||
{
|
||||
return Scale.X * Scale.Y * Scale.Z;
|
||||
@@ -113,31 +110,31 @@ public:
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets rotation matrix (from Orientation)
|
||||
/// Gets rotation matrix (from Orientation).
|
||||
/// </summary>
|
||||
/// <returns>Rotation matrix</returns>
|
||||
Matrix GetRotation() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets rotation matrix (from Orientation)
|
||||
/// Gets rotation matrix (from Orientation).
|
||||
/// </summary>
|
||||
/// <param name="result">Matrix to set</param>
|
||||
void GetRotation(Matrix& result) const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets rotation matrix (from Orientation)
|
||||
/// Sets rotation matrix (from Orientation).
|
||||
/// </summary>
|
||||
/// <param name="value">Rotation matrix</param>
|
||||
void SetRotation(const Matrix& value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets world matrix that describes transformation as a 4 by 4 matrix
|
||||
/// Gets world matrix that describes transformation as a 4 by 4 matrix.
|
||||
/// </summary>
|
||||
/// <returns>World matrix</returns>
|
||||
Matrix GetWorld() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets world matrix that describes transformation as a 4 by 4 matrix
|
||||
/// Gets world matrix that describes transformation as a 4 by 4 matrix.
|
||||
/// </summary>
|
||||
/// <param name="result">World matrix</param>
|
||||
void GetWorld(Matrix& result) const;
|
||||
@@ -169,7 +166,12 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="other">The local space transformation.</param>
|
||||
/// <returns>The world space transformation.</returns>
|
||||
Transform LocalToWorld(const Transform& other) const;
|
||||
Transform LocalToWorld(const Transform& other) const
|
||||
{
|
||||
Transform result;
|
||||
LocalToWorld(other, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given transform in local space to the world space of this transform.
|
||||
@@ -183,7 +185,12 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="point">The local space point.</param>
|
||||
/// <returns>The world space point.</returns>
|
||||
Vector3 LocalToWorld(const Vector3& point) const;
|
||||
Vector3 LocalToWorld(const Vector3& point) const
|
||||
{
|
||||
Vector3 result;
|
||||
LocalToWorld(point, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given vector in local space to the world space of this transform.
|
||||
@@ -199,20 +206,17 @@ public:
|
||||
/// <param name="result">The world space point.</param>
|
||||
void LocalToWorld(const Vector3& point, Vector3& result) const;
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given points in local space to the world space of this transform.
|
||||
/// </summary>
|
||||
/// <param name="points">The local space points.</param>
|
||||
/// <param name="pointsCount">The amount of the points.</param>
|
||||
/// <param name="result">The world space points.</param>
|
||||
void LocalToWorld(const Vector3* points, int32 pointsCount, Vector3* result) const;
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given transform in local space to the world space of this transform.
|
||||
/// </summary>
|
||||
/// <param name="other">The world space transformation.</param>
|
||||
/// <returns>The local space transformation.</returns>
|
||||
Transform WorldToLocal(const Transform& other) const;
|
||||
Transform WorldToLocal(const Transform& other) const
|
||||
{
|
||||
Transform result;
|
||||
WorldToLocal(other, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given transform in world space to the local space of this transform.
|
||||
@@ -221,12 +225,24 @@ public:
|
||||
/// <param name="result">The local space transformation.</param>
|
||||
void WorldToLocal(const Transform& other, Transform& result) const;
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given point in world space to the local space of this transform.
|
||||
/// </summary>
|
||||
/// <param name="point">The world space point.</param>
|
||||
/// <param name="result">The local space point.</param>
|
||||
void WorldToLocal(const Vector3& point, Vector3& result) const;
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given point in world space to the local space of this transform.
|
||||
/// </summary>
|
||||
/// <param name="point">The world space point.</param>
|
||||
/// <returns>The local space point.</returns>
|
||||
Vector3 WorldToLocal(const Vector3& point) const;
|
||||
Vector3 WorldToLocal(const Vector3& point) const
|
||||
{
|
||||
Vector3 result;
|
||||
WorldToLocal(point, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given vector in world space to the local space of this transform.
|
||||
@@ -235,14 +251,6 @@ public:
|
||||
/// <returns>The local space vector.</returns>
|
||||
Vector3 WorldToLocalVector(const Vector3& vector) const;
|
||||
|
||||
/// <summary>
|
||||
/// Performs transformation of the given points in world space to the local space of this transform.
|
||||
/// </summary>
|
||||
/// <param name="points">The world space points.</param>
|
||||
/// <param name="pointsCount">The amount of the points.</param>
|
||||
/// <param name="result">The local space points.</param>
|
||||
void WorldToLocal(const Vector3* points, int32 pointsCount, Vector3* result) const;
|
||||
|
||||
public:
|
||||
FORCE_INLINE Transform operator*(const Transform& other) const
|
||||
{
|
||||
|
||||
@@ -1,117 +1,265 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Double2.h"
|
||||
#include "Double3.h"
|
||||
#include "Double4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
#include "Color.h"
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
static_assert(sizeof(Vector2) == 8, "Invalid Vector2 type size.");
|
||||
// Float
|
||||
|
||||
const Vector2 Vector2::Zero(0);
|
||||
const Vector2 Vector2::One(1);
|
||||
const Vector2 Vector2::UnitX(1, 0);
|
||||
const Vector2 Vector2::UnitY(0, 1);
|
||||
const Vector2 Vector2::Minimum(MIN_float);
|
||||
const Vector2 Vector2::Maximum(MAX_float);
|
||||
static_assert(sizeof(Float2) == 8, "Invalid Float2 type size.");
|
||||
|
||||
Vector2::Vector2(const Int2& xy)
|
||||
: X(static_cast<float>(xy.X))
|
||||
, Y(static_cast<float>(xy.Y))
|
||||
template<>
|
||||
const Float2 Float2::Zero(0.0f);
|
||||
template<>
|
||||
const Float2 Float2::One(1.0f);
|
||||
template<>
|
||||
const Float2 Float2::UnitX(1.0f, 0.0f);
|
||||
template<>
|
||||
const Float2 Float2::UnitY(0.0f, 1.0f);
|
||||
template<>
|
||||
const Float2 Float2::Minimum(MIN_float);
|
||||
template<>
|
||||
const Float2 Float2::Maximum(MAX_float);
|
||||
|
||||
template<>
|
||||
Float2::Vector2Base(const Int3& xy)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Vector2::Vector2(const Int3& xyz)
|
||||
: X(static_cast<float>(xyz.X))
|
||||
, Y(static_cast<float>(xyz.Y))
|
||||
template<>
|
||||
Float2::Vector2Base(const Int4& xy)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Vector2::Vector2(const Int4& xyzw)
|
||||
: X(static_cast<float>(xyzw.X))
|
||||
, Y(static_cast<float>(xyzw.Y))
|
||||
template<>
|
||||
Float2::Vector2Base(const Float3& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Vector2::Vector2(const Vector3& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
template<>
|
||||
Float2::Vector2Base(const Float4& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Vector2::Vector2(const Vector4& xyzw)
|
||||
: X(xyzw.X)
|
||||
, Y(xyzw.Y)
|
||||
template<>
|
||||
Float2::Vector2Base(const Double3& xy)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Vector2::Vector2(const Double2& xy)
|
||||
: X(static_cast<float>(xy.X))
|
||||
, Y(static_cast<float>(xy.Y))
|
||||
template<>
|
||||
Float2::Vector2Base(const Double4& xy)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
Vector2::Vector2(const Double3& xyz)
|
||||
: X(static_cast<float>(xyz.X))
|
||||
, Y(static_cast<float>(xyz.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Vector2::Vector2(const Double4& xyzw)
|
||||
: X(static_cast<float>(xyzw.X))
|
||||
, Y(static_cast<float>(xyzw.Y))
|
||||
{
|
||||
}
|
||||
|
||||
Vector2::Vector2(const Color& color)
|
||||
template<>
|
||||
Float2::Vector2Base(const Color& color)
|
||||
: X(color.R)
|
||||
, Y(color.G)
|
||||
{
|
||||
}
|
||||
|
||||
String Vector2::ToString() const
|
||||
template<>
|
||||
String Float2::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
Vector2 Vector2::Normalize(const Vector2& v)
|
||||
{
|
||||
Vector2 result = v;
|
||||
const float length = v.Length();
|
||||
if (!Math::IsZero(length))
|
||||
{
|
||||
const float inv = 1.0f / length;
|
||||
result.X *= inv;
|
||||
result.Y *= inv;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Int2 Vector2::CeilToInt(const Vector2& v)
|
||||
{
|
||||
return Int2(Math::CeilToInt(v.X), Math::CeilToInt(v.Y));
|
||||
}
|
||||
|
||||
Int2 Vector2::FloorToInt(const Vector2& v)
|
||||
{
|
||||
return Int2(Math::FloorToInt(v.X), Math::FloorToInt(v.Y));
|
||||
}
|
||||
|
||||
float Vector2::TriangleArea(const Vector2& v0, const Vector2& v1, const Vector2& v2)
|
||||
template<>
|
||||
float Float2::TriangleArea(const Float2& v0, const Float2& v1, const Float2& v2)
|
||||
{
|
||||
return Math::Abs((v0.X * (v1.Y - v2.Y) + v1.X * (v2.Y - v0.Y) + v2.X * (v0.Y - v1.Y)) / 2);
|
||||
}
|
||||
|
||||
float Vector2::Angle(const Vector2& from, const Vector2& to)
|
||||
template<>
|
||||
float Float2::Angle(const Float2& from, const Float2& to)
|
||||
{
|
||||
const float dot = Math::Clamp(Dot(Normalize(from), Normalize(to)), -1.0f, 1.0f);
|
||||
if (Math::Abs(dot) > (1.0f - ZeroTolerance))
|
||||
if (Math::Abs(dot) > 1.0f - ZeroTolerance)
|
||||
return dot > 0.0f ? 0.0f : PI;
|
||||
return Math::Acos(dot);
|
||||
}
|
||||
|
||||
// Double
|
||||
|
||||
static_assert(sizeof(Double2) == 16, "Invalid Double2 type size.");
|
||||
|
||||
template<>
|
||||
const Double2 Double2::Zero(0.0);
|
||||
template<>
|
||||
const Double2 Double2::One(1.0);
|
||||
template<>
|
||||
const Double2 Double2::UnitX(1.0, 0.0);
|
||||
template<>
|
||||
const Double2 Double2::UnitY(0.0, 1.0);
|
||||
template<>
|
||||
const Double2 Double2::Minimum(MIN_double);
|
||||
template<>
|
||||
const Double2 Double2::Maximum(MAX_double);
|
||||
|
||||
template<>
|
||||
Double2::Vector2Base(const Int3& xy)
|
||||
: X((double)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double2::Vector2Base(const Int4& xy)
|
||||
: X((double)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double2::Vector2Base(const Float3& xy)
|
||||
: X((double)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double2::Vector2Base(const Float4& xy)
|
||||
: X((int32)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double2::Vector2Base(const Double3& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double2::Vector2Base(const Double4& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double2::Vector2Base(const Color& color)
|
||||
: X((double)color.R)
|
||||
, Y((double)color.G)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
String Double2::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
template<>
|
||||
double Double2::TriangleArea(const Double2& v0, const Double2& v1, const Double2& v2)
|
||||
{
|
||||
return Math::Abs((v0.X * (v1.Y - v2.Y) + v1.X * (v2.Y - v0.Y) + v2.X * (v0.Y - v1.Y)) / 2);
|
||||
}
|
||||
|
||||
template<>
|
||||
double Double2::Angle(const Double2& from, const Double2& to)
|
||||
{
|
||||
const double dot = Math::Clamp(Dot(Normalize(from), Normalize(to)), -1.0, 1.0);
|
||||
if (Math::Abs(dot) > 1.0 - ZeroTolerance)
|
||||
return dot > 0.0 ? 0.0 : PI;
|
||||
return Math::Acos(dot);
|
||||
}
|
||||
|
||||
// Int
|
||||
|
||||
static_assert(sizeof(Int2) == 8, "Invalid Int2 type size.");
|
||||
|
||||
template<>
|
||||
const Int2 Int2::Zero(0);
|
||||
template<>
|
||||
const Int2 Int2::One(1);
|
||||
template<>
|
||||
const Int2 Int2::UnitX(1, 0);
|
||||
template<>
|
||||
const Int2 Int2::UnitY(0, 1);
|
||||
template<>
|
||||
const Int2 Int2::Minimum(MIN_int32);
|
||||
template<>
|
||||
const Int2 Int2::Maximum(MAX_int32);
|
||||
|
||||
template<>
|
||||
Int2::Vector2Base(const Int3& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int2::Vector2Base(const Int4& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int2::Vector2Base(const Float3& xy)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int2::Vector2Base(const Float4& xy)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int2::Vector2Base(const Double3& xy)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int2::Vector2Base(const Double4& xy)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int2::Vector2Base(const Color& color)
|
||||
: X((int32)color.R)
|
||||
, Y((int32)color.G)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
String Int2::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
template<>
|
||||
int32 Int2::TriangleArea(const Int2& v0, const Int2& v1, const Int2& v2)
|
||||
{
|
||||
return Math::Abs((v0.X * (v1.Y - v2.Y) + v1.X * (v2.Y - v0.Y) + v2.X * (v0.Y - v1.Y)) / 2);
|
||||
}
|
||||
|
||||
template<>
|
||||
int32 Int2::Angle(const Int2& from, const Int2& to)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,24 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a two dimensional mathematical vector.
|
||||
/// </summary>
|
||||
[Unmanaged]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe partial struct Vector2
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component.
|
||||
/// </summary>
|
||||
public float X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component.
|
||||
/// </summary>
|
||||
public float Y;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[TypeConverter(typeof(TypeConverters.Vector2Converter))]
|
||||
partial struct Vector2 : IEquatable<Vector2>, IFormattable
|
||||
|
||||
@@ -3,27 +3,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Math.h"
|
||||
#include "Mathd.h"
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
struct Double2;
|
||||
struct Double3;
|
||||
struct Double4;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Int2;
|
||||
struct Int3;
|
||||
struct Int4;
|
||||
struct Color;
|
||||
struct Matrix;
|
||||
#include <type_traits>
|
||||
|
||||
/// <summary>
|
||||
/// Represents a two dimensional mathematical vector with 32-bit precision (per-component).
|
||||
/// Represents a two dimensional mathematical vector.
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API Vector2
|
||||
template<typename T>
|
||||
API_STRUCT(Template) struct Vector2Base
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Vector2);
|
||||
public:
|
||||
typedef T Real;
|
||||
static struct ScriptingTypeInitializer TypeInitializer;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
@@ -31,325 +25,82 @@ public:
|
||||
/// <summary>
|
||||
/// The X component of the vector.
|
||||
/// </summary>
|
||||
API_FIELD() float X;
|
||||
API_FIELD() T X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the vector.
|
||||
/// </summary>
|
||||
API_FIELD() float Y;
|
||||
API_FIELD() T Y;
|
||||
};
|
||||
|
||||
// Raw values
|
||||
float Raw[2];
|
||||
/// <summary>
|
||||
/// The raw vector values (in XY order).
|
||||
/// </summary>
|
||||
T Raw[2];
|
||||
};
|
||||
|
||||
public:
|
||||
// Vector with all components equal 0
|
||||
static const Vector2 Zero;
|
||||
static FLAXENGINE_API const Vector2Base<T> Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Vector2 One;
|
||||
static FLAXENGINE_API const Vector2Base<T> One;
|
||||
|
||||
// Vector X=1, Y=0
|
||||
static const Vector2 UnitX;
|
||||
static FLAXENGINE_API const Vector2Base<T> UnitX;
|
||||
|
||||
// Vector X=0, Y=1
|
||||
static const Vector2 UnitY;
|
||||
static FLAXENGINE_API const Vector2Base<T> UnitY;
|
||||
|
||||
// A minimum Vector2
|
||||
static const Vector2 Minimum;
|
||||
// Vector with all components equal maximum value.
|
||||
static FLAXENGINE_API const Vector2Base<T> Minimum;
|
||||
|
||||
// A maximum Vector2
|
||||
static const Vector2 Maximum;
|
||||
// Vector with all components equal minimum value.
|
||||
static FLAXENGINE_API const Vector2Base<T> Maximum;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor.
|
||||
/// </summary>
|
||||
Vector2()
|
||||
Vector2Base()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xy Value to assign to the all components
|
||||
Vector2(float xy)
|
||||
FORCE_INLINE Vector2Base(T xy)
|
||||
: X(xy)
|
||||
, Y(xy)
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param x X component value
|
||||
// @param y Y component value
|
||||
Vector2(float x, float y)
|
||||
FORCE_INLINE explicit Vector2Base(const T* xy)
|
||||
: X(xy[0])
|
||||
, Y(xy[1])
|
||||
{
|
||||
}
|
||||
|
||||
FORCE_INLINE Vector2Base(T x, T y)
|
||||
: X(x)
|
||||
, Y(y)
|
||||
{
|
||||
}
|
||||
|
||||
explicit Vector2(const Int2& xy);
|
||||
explicit Vector2(const Int3& xyz);
|
||||
explicit Vector2(const Int4& xyzw);
|
||||
explicit Vector2(const Vector3& xyz);
|
||||
explicit Vector2(const Vector4& xyzw);
|
||||
Vector2(const Double2& xy);
|
||||
explicit Vector2(const Double3& xyz);
|
||||
explicit Vector2(const Double4& xyzw);
|
||||
explicit Vector2(const Color& color);
|
||||
template<typename U = T, typename TEnableIf<TNot<TIsTheSame<T, U>>::Value>::Type...>
|
||||
FORCE_INLINE explicit Vector2Base(const Vector2Base<U>& xy)
|
||||
: X((T)xy.X)
|
||||
, Y((T)xy.Y)
|
||||
{
|
||||
}
|
||||
|
||||
FLAXENGINE_API explicit Vector2Base(const Int3& xy);
|
||||
FLAXENGINE_API explicit Vector2Base(const Int4& xy);
|
||||
FLAXENGINE_API explicit Vector2Base(const Float3& xy);
|
||||
FLAXENGINE_API explicit Vector2Base(const Float4& xy);
|
||||
FLAXENGINE_API explicit Vector2Base(const Double3& xy);
|
||||
FLAXENGINE_API explicit Vector2Base(const Double4& xy);
|
||||
FLAXENGINE_API explicit Vector2Base(const Color& color);
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
|
||||
public:
|
||||
// Arithmetic operators with Vector2
|
||||
Vector2 operator+(const Vector2& b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Vector2 operator-(const Vector2& b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Vector2 operator*(const Vector2& b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Vector2 operator/(const Vector2& b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
Vector2 operator-() const
|
||||
{
|
||||
return Vector2(-X, -Y);
|
||||
}
|
||||
|
||||
// op= operators with Vector2
|
||||
Vector2& operator+=(const Vector2& b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2& operator-=(const Vector2& b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2& operator*=(const Vector2& b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2& operator/=(const Vector2& b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators with float
|
||||
Vector2 operator+(float b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
Vector2 operator-(float b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
Vector2 operator*(float b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
Vector2 operator/(float b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
// op= operators with float
|
||||
Vector2& operator+=(float b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2& operator-=(float b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2& operator*=(float b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2& operator/=(float b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
bool operator==(const Vector2& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y;
|
||||
}
|
||||
|
||||
bool operator!=(const Vector2& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y;
|
||||
}
|
||||
|
||||
bool operator>(const Vector2& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y;
|
||||
}
|
||||
|
||||
bool operator>=(const Vector2& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y;
|
||||
}
|
||||
|
||||
bool operator<(const Vector2& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y;
|
||||
}
|
||||
|
||||
bool operator<=(const Vector2& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y;
|
||||
}
|
||||
|
||||
public:
|
||||
static bool NearEqual(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X) && Math::NearEqual(a.Y, b.Y);
|
||||
}
|
||||
|
||||
static bool NearEqual(const Vector2& a, const Vector2& b, float epsilon)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X, epsilon) && Math::NearEqual(a.Y, b.Y, epsilon);
|
||||
}
|
||||
|
||||
public:
|
||||
static float Dot(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y;
|
||||
}
|
||||
|
||||
static float Cross(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
return a.X * b.Y - a.Y * b.X;
|
||||
}
|
||||
|
||||
static void Add(const Vector2& a, const Vector2& b, Vector2& result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
}
|
||||
|
||||
static Vector2 Add(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
Vector2 result;
|
||||
Add(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Subtract(const Vector2& a, const Vector2& b, Vector2& result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
}
|
||||
|
||||
static Vector2 Subtract(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
Vector2 result;
|
||||
Subtract(a, b, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Vector2 Multiply(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
return Vector2(a.X * b.X, a.Y * b.Y);
|
||||
}
|
||||
|
||||
static Vector2 Multiply(const Vector2& a, float b)
|
||||
{
|
||||
return Vector2(a.X * b, a.Y * b);
|
||||
}
|
||||
|
||||
static Vector2 Divide(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
return Vector2(a.X / b.X, a.Y / b.Y);
|
||||
}
|
||||
|
||||
static Vector2 Divide(const Vector2& a, float b)
|
||||
{
|
||||
return Vector2(a.X / b, a.Y / b);
|
||||
}
|
||||
|
||||
// Calculates distance between two points in 2D
|
||||
// @param a 1st point
|
||||
// @param b 2nd point
|
||||
// @returns Distance
|
||||
static float Distance(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
const float x = a.X - b.X;
|
||||
const float y = a.Y - b.Y;
|
||||
return Math::Sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
// Calculates the squared distance between two points in 2D
|
||||
// @param a 1st point
|
||||
// @param b 2nd point
|
||||
// @returns Distance
|
||||
static float DistanceSquared(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
const float x = a.X - b.X;
|
||||
const float y = a.Y - b.Y;
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
// Clamp vector values within given range
|
||||
// @param v Vector to clamp
|
||||
// @param min Minimum value
|
||||
// @param max Maximum value
|
||||
// @returns Clamped vector
|
||||
static Vector2 Clamp(const Vector2& v, float min, float max)
|
||||
{
|
||||
return Vector2(Math::Clamp(v.X, min, max), Math::Clamp(v.Y, min, max));
|
||||
}
|
||||
|
||||
// Clamp vector values within given range
|
||||
// @param v Vector to clamp
|
||||
// @param min Minimum value
|
||||
// @param max Maximum value
|
||||
// @returns Clamped vector
|
||||
static Vector2 Clamp(const Vector2& v, const Vector2& min, const Vector2& max)
|
||||
{
|
||||
return Vector2(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y));
|
||||
}
|
||||
|
||||
// Performs vector normalization (scales vector up to unit length)
|
||||
void Normalize()
|
||||
{
|
||||
const float length = Length();
|
||||
if (!Math::IsZero(length))
|
||||
{
|
||||
const float invLength = 1.0f / length;
|
||||
X *= invLength;
|
||||
Y *= invLength;
|
||||
}
|
||||
}
|
||||
FLAXENGINE_API String ToString() const;
|
||||
|
||||
public:
|
||||
// Gets a value indicting whether this instance is normalized.
|
||||
@@ -377,39 +128,27 @@ public:
|
||||
}
|
||||
|
||||
// Calculates the length of the vector.
|
||||
float Length() const
|
||||
T Length() const
|
||||
{
|
||||
return Math::Sqrt(X * X + Y * Y);
|
||||
}
|
||||
|
||||
// Calculates the squared length of the vector.
|
||||
float LengthSquared() const
|
||||
T LengthSquared() const
|
||||
{
|
||||
return X * X + Y * Y;
|
||||
}
|
||||
|
||||
// Calculates inverted length of the vector (1 / length).
|
||||
float InvLength() const
|
||||
T InvLength() const
|
||||
{
|
||||
return 1.0f / Length();
|
||||
}
|
||||
|
||||
// Calculates a vector with values being absolute values of that vector.
|
||||
Vector2 GetAbsolute() const
|
||||
{
|
||||
return Vector2(Math::Abs(X), Math::Abs(Y));
|
||||
}
|
||||
|
||||
// Calculates a vector with values being opposite to values of that vector.
|
||||
Vector2 GetNegative() const
|
||||
{
|
||||
return Vector2(-X, -Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the average arithmetic of all the components.
|
||||
/// </summary>
|
||||
float AverageArithmetic() const
|
||||
T AverageArithmetic() const
|
||||
{
|
||||
return (X + Y) * 0.5f;
|
||||
}
|
||||
@@ -417,7 +156,7 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the sum of all vector components values.
|
||||
/// </summary>
|
||||
float SumValues() const
|
||||
T SumValues() const
|
||||
{
|
||||
return X + Y;
|
||||
}
|
||||
@@ -425,7 +164,7 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the multiplication result of all vector components values.
|
||||
/// </summary>
|
||||
float MulValues() const
|
||||
T MulValues() const
|
||||
{
|
||||
return X * Y;
|
||||
}
|
||||
@@ -433,7 +172,7 @@ public:
|
||||
/// <summary>
|
||||
/// Returns the minimum value of all the components.
|
||||
/// </summary>
|
||||
float MinValue() const
|
||||
T MinValue() const
|
||||
{
|
||||
return Math::Min(X, Y);
|
||||
}
|
||||
@@ -441,7 +180,7 @@ public:
|
||||
/// <summary>
|
||||
/// Returns the maximum value of all the components.
|
||||
/// </summary>
|
||||
float MaxValue() const
|
||||
T MaxValue() const
|
||||
{
|
||||
return Math::Max(X, Y);
|
||||
}
|
||||
@@ -470,13 +209,322 @@ public:
|
||||
return IsInfinity() || IsNaN();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being absolute values of that vector.
|
||||
/// </summary>
|
||||
Vector2Base GetAbsolute() const
|
||||
{
|
||||
return Vector2Base(Math::Abs(X), Math::Abs(Y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being opposite to values of that vector.
|
||||
/// </summary>
|
||||
Vector2Base GetNegative() const
|
||||
{
|
||||
return Vector2Base(-X, -Y);
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Performs vector normalization (scales vector up to unit length).
|
||||
/// </summary>
|
||||
void Normalize()
|
||||
{
|
||||
const T length = Math::Sqrt(X * X + Y * Y);
|
||||
if (!Math::IsZero(length))
|
||||
{
|
||||
const T invLength = 1.0f / length;
|
||||
X *= invLength;
|
||||
Y *= invLength;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Vector2Base operator+(const Vector2Base& b) const
|
||||
{
|
||||
return Vector2Base(X + b.X, Y + b.Y);
|
||||
}
|
||||
|
||||
Vector2Base operator-(const Vector2Base& b) const
|
||||
{
|
||||
return Vector2Base(X - b.X, Y - b.Y);
|
||||
}
|
||||
|
||||
Vector2Base operator*(const Vector2Base& b) const
|
||||
{
|
||||
return Vector2Base(X * b.X, Y * b.Y);
|
||||
}
|
||||
|
||||
Vector2Base operator/(const Vector2Base& b) const
|
||||
{
|
||||
return Vector2Base(X / b.X, Y / b.Y);
|
||||
}
|
||||
|
||||
Vector2Base operator-() const
|
||||
{
|
||||
return Vector2Base(-X, -Y);
|
||||
}
|
||||
|
||||
Vector2Base operator+(T b) const
|
||||
{
|
||||
return Vector2Base(X + b, Y + b);
|
||||
}
|
||||
|
||||
Vector2Base operator-(T b) const
|
||||
{
|
||||
return Vector2Base(X - b, Y - b);
|
||||
}
|
||||
|
||||
Vector2Base operator*(T b) const
|
||||
{
|
||||
return Vector2Base(X * b, Y * b);
|
||||
}
|
||||
|
||||
Vector2Base operator/(T b) const
|
||||
{
|
||||
return Vector2Base(X / b, Y / b);
|
||||
}
|
||||
|
||||
Vector2Base& operator+=(const Vector2Base& b)
|
||||
{
|
||||
X += b.X;
|
||||
Y += b.Y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2Base& operator-=(const Vector2Base& b)
|
||||
{
|
||||
X -= b.X;
|
||||
Y -= b.Y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2Base& operator*=(const Vector2Base& b)
|
||||
{
|
||||
X *= b.X;
|
||||
Y *= b.Y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2Base& operator/=(const Vector2Base& b)
|
||||
{
|
||||
X /= b.X;
|
||||
Y /= b.Y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2Base& operator+=(T b)
|
||||
{
|
||||
X += b;
|
||||
Y += b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2Base& operator-=(T b)
|
||||
{
|
||||
X -= b;
|
||||
Y -= b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2Base& operator*=(T b)
|
||||
{
|
||||
X *= b;
|
||||
Y *= b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2Base& operator/=(T b)
|
||||
{
|
||||
X /= b;
|
||||
Y /= b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vector2Base& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y;
|
||||
}
|
||||
|
||||
bool operator!=(const Vector2Base& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y;
|
||||
}
|
||||
|
||||
bool operator>(const Vector2Base& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y;
|
||||
}
|
||||
|
||||
bool operator>=(const Vector2Base& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y;
|
||||
}
|
||||
|
||||
bool operator<(const Vector2Base& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y;
|
||||
}
|
||||
|
||||
bool operator<=(const Vector2Base& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y;
|
||||
}
|
||||
|
||||
public:
|
||||
static bool NearEqual(const Vector2Base& a, const Vector2Base& b)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X) && Math::NearEqual(a.Y, b.Y);
|
||||
}
|
||||
|
||||
static bool NearEqual(const Vector2Base& a, const Vector2Base& b, T epsilon)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X, epsilon) && Math::NearEqual(a.Y, b.Y, epsilon);
|
||||
}
|
||||
|
||||
public:
|
||||
static T Dot(const Vector2Base& a, const Vector2Base& b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y;
|
||||
}
|
||||
|
||||
static T Cross(const Vector2Base& a, const Vector2Base& b)
|
||||
{
|
||||
return a.X * b.Y - a.Y * b.X;
|
||||
}
|
||||
|
||||
static void Add(const Vector2Base& a, const Vector2Base& b, Vector2Base& result)
|
||||
{
|
||||
result = Vector2Base(a.X + b.X, a.Y + b.Y);
|
||||
}
|
||||
|
||||
static void Subtract(const Vector2Base& a, const Vector2Base& b, Vector2Base& result)
|
||||
{
|
||||
result = Vector2Base(a.X - b.X, a.Y - b.Y);
|
||||
}
|
||||
|
||||
static void Multiply(const Vector2Base& a, const Vector2Base& b, Vector2Base& result)
|
||||
{
|
||||
result = Vector2Base(a.X * b.X, a.Y * b.Y);
|
||||
}
|
||||
|
||||
static void Divide(const Vector2Base& a, const Vector2Base& b, Vector2Base& result)
|
||||
{
|
||||
result = Vector2Base(a.X / b.X, a.Y / b.Y);
|
||||
}
|
||||
|
||||
static void Min(const Vector2Base& a, const Vector2Base& b, Vector2Base& result)
|
||||
{
|
||||
result = Vector2Base(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
static void Max(const Vector2Base& a, const Vector2Base& b, Vector2Base& result)
|
||||
{
|
||||
result = Vector2Base(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
public:
|
||||
static Vector2Base Min(const Vector2Base& a, const Vector2Base& b)
|
||||
{
|
||||
return Vector2Base(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
static Vector2Base Max(const Vector2Base& a, const Vector2Base& b)
|
||||
{
|
||||
return Vector2Base(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
static Vector2Base Floor(const Vector2Base& v)
|
||||
{
|
||||
return Vector2Base(Math::Floor(v.X), Math::Floor(v.Y));
|
||||
}
|
||||
|
||||
static Vector2Base Frac(const Vector2Base& v)
|
||||
{
|
||||
return Vector3(v.X - (int32)v.X, v.Y - (int32)v.Y);
|
||||
}
|
||||
|
||||
static Vector2Base Round(const Vector2Base& v)
|
||||
{
|
||||
return Vector2Base(Math::Round(v.X), Math::Round(v.Y));
|
||||
}
|
||||
|
||||
static Vector2Base Ceil(const Vector2Base& v)
|
||||
{
|
||||
return Vector2Base(Math::Ceil(v.X), Math::Ceil(v.Y));
|
||||
}
|
||||
|
||||
static Vector2Base Abs(const Vector2Base& v)
|
||||
{
|
||||
return Vector2Base(Math::Abs(v.X), Math::Abs(v.Y));
|
||||
}
|
||||
|
||||
public:
|
||||
// Clamp vector values within given range
|
||||
// @param v Vector to clamp
|
||||
// @param min Minimum value
|
||||
// @param max Maximum value
|
||||
// @returns Clamped vector
|
||||
static Vector2Base Clamp(const Vector2Base& v, const Vector2Base& min, const Vector2Base& max)
|
||||
{
|
||||
Vector2Base result;
|
||||
Clamp(v, min, max, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Restricts a value to be within a specified range
|
||||
// @param v The value to clamp
|
||||
// @param min The minimum value,
|
||||
// @param max The maximum value
|
||||
// @param result When the method completes, contains the clamped value
|
||||
static void Clamp(const Vector2Base& v, const Vector2Base& min, const Vector2Base& max, Vector2Base& result)
|
||||
{
|
||||
result = Vector2Base(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y));
|
||||
}
|
||||
|
||||
// Calculates distance between two points in 2D
|
||||
// @param a 1st point
|
||||
// @param b 2nd point
|
||||
// @returns Distance
|
||||
static T Distance(const Vector2Base& a, const Vector2Base& b)
|
||||
{
|
||||
const T x = a.X - b.X;
|
||||
const T y = a.Y - b.Y;
|
||||
return Math::Sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
// Calculates the squared distance between two points in 2D
|
||||
// @param a 1st point
|
||||
// @param b 2nd point
|
||||
// @returns Distance
|
||||
static T DistanceSquared(const Vector2Base& a, const Vector2Base& b)
|
||||
{
|
||||
const T x = a.X - b.X;
|
||||
const T y = a.Y - b.Y;
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
// Performs vector normalization (scales vector up to unit length).
|
||||
static Vector2Base Normalize(const Vector2Base& v)
|
||||
{
|
||||
Vector2Base r = v;
|
||||
const T length = Math::Sqrt(r.X * r.X + r.Y * r.Y);
|
||||
if (Math::Abs(length) >= ZeroTolerance)
|
||||
{
|
||||
const T inv = 1.0f / length;
|
||||
r.X *= inv;
|
||||
r.Y *= inv;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// Performs a linear interpolation between two vectors
|
||||
// @param start Start vector
|
||||
// @param end End vector
|
||||
// @param amount Value between 0 and 1 indicating the weight of end
|
||||
// @param result When the method completes, contains the linear interpolation of the two vectors
|
||||
static void Lerp(const Vector2& start, const Vector2& end, float amount, Vector2& result)
|
||||
static void Lerp(const Vector2Base& start, const Vector2Base& end, T amount, Vector2Base& result)
|
||||
{
|
||||
result.X = Math::Lerp(start.X, end.X, amount);
|
||||
result.Y = Math::Lerp(start.Y, end.Y, amount);
|
||||
@@ -489,76 +537,13 @@ public:
|
||||
// @param end End vector,
|
||||
// @param amount Value between 0 and 1 indicating the weight of @paramref end"/>,
|
||||
// @returns The linear interpolation of the two vectors
|
||||
static Vector2 Lerp(const Vector2& start, const Vector2& end, float amount)
|
||||
static Vector2Base Lerp(const Vector2Base& start, const Vector2Base& end, T amount)
|
||||
{
|
||||
Vector2 result;
|
||||
Vector2Base result;
|
||||
Lerp(start, end, amount, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Vector2 Abs(const Vector2& v)
|
||||
{
|
||||
return Vector2(Math::Abs(v.X), Math::Abs(v.Y));
|
||||
}
|
||||
|
||||
// Creates vector from minimum components of two vectors
|
||||
static Vector2 Min(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
return Vector2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Creates vector from minimum components of two vectors
|
||||
static void Min(const Vector2& a, const Vector2& b, Vector2& result)
|
||||
{
|
||||
result = Vector2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Creates vector from maximum components of two vectors
|
||||
static Vector2 Max(const Vector2& a, const Vector2& b)
|
||||
{
|
||||
return Vector2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Creates vector from maximum components of two vectors
|
||||
static void Max(const Vector2& a, const Vector2& b, Vector2& result)
|
||||
{
|
||||
result = Vector2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y);
|
||||
}
|
||||
|
||||
// Returns normalized vector
|
||||
static Vector2 Normalize(const Vector2& v);
|
||||
|
||||
static Vector2 Round(const Vector2& v)
|
||||
{
|
||||
return Vector2(Math::Round(v.X), Math::Round(v.Y));
|
||||
}
|
||||
|
||||
static Vector2 Ceil(const Vector2& v)
|
||||
{
|
||||
return Vector2(Math::Ceil(v.X), Math::Ceil(v.Y));
|
||||
}
|
||||
|
||||
static Vector2 Floor(const Vector2& v)
|
||||
{
|
||||
return Vector2(Math::Floor(v.X), Math::Floor(v.Y));
|
||||
}
|
||||
|
||||
static Vector2 Frac(const Vector2& v)
|
||||
{
|
||||
return Vector2(v.X - (int32)v.X, v.Y - (int32)v.Y);
|
||||
}
|
||||
|
||||
static Int2 CeilToInt(const Vector2& v);
|
||||
static Int2 FloorToInt(const Vector2& v);
|
||||
|
||||
static Vector2 Mod(const Vector2& v)
|
||||
{
|
||||
return Vector2(
|
||||
(float)(v.X - (int32)v.X),
|
||||
(float)(v.Y - (int32)v.Y)
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Calculates the area of the triangle.
|
||||
@@ -567,7 +552,7 @@ public:
|
||||
/// <param name="v1">The second triangle vertex.</param>
|
||||
/// <param name="v2">The third triangle vertex.</param>
|
||||
/// <returns>The triangle area.</returns>
|
||||
static float TriangleArea(const Vector2& v0, const Vector2& v1, const Vector2& v2);
|
||||
FLAXENGINE_API static T TriangleArea(const Vector2Base& v0, const Vector2Base& v1, const Vector2Base& v2);
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the angle (in radians) between from and to. This is always the smallest value.
|
||||
@@ -575,41 +560,62 @@ public:
|
||||
/// <param name="from">The first vector.</param>
|
||||
/// <param name="to">The second vector.</param>
|
||||
/// <returns>The angle (in radians).</returns>
|
||||
static float Angle(const Vector2& from, const Vector2& to);
|
||||
FLAXENGINE_API static T Angle(const Vector2Base& from, const Vector2Base& to);
|
||||
};
|
||||
|
||||
inline Vector2 operator+(float a, const Vector2& b)
|
||||
template<typename T>
|
||||
inline Vector2Base<T> operator+(T a, const Vector2Base<T>& b)
|
||||
{
|
||||
return b + a;
|
||||
}
|
||||
|
||||
inline Vector2 operator-(float a, const Vector2& b)
|
||||
template<typename T>
|
||||
inline Vector2Base<T> operator-(T a, const Vector2Base<T>& b)
|
||||
{
|
||||
return Vector2(a) - b;
|
||||
return Vector2Base<T>(a) - b;
|
||||
}
|
||||
|
||||
inline Vector2 operator*(float a, const Vector2& b)
|
||||
template<typename T>
|
||||
inline Vector2Base<T> operator*(T a, const Vector2Base<T>& b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline Vector2 operator/(float a, const Vector2& b)
|
||||
template<typename T>
|
||||
inline Vector2Base<T> operator/(T a, const Vector2Base<T>& b)
|
||||
{
|
||||
return Vector2(a) / b;
|
||||
return Vector2Base<T>(a) / b;
|
||||
}
|
||||
|
||||
namespace Math
|
||||
{
|
||||
FORCE_INLINE static bool NearEqual(const Vector2& a, const Vector2& b)
|
||||
template<typename T>
|
||||
FORCE_INLINE static bool NearEqual(const Vector2Base<T>& a, const Vector2Base<T>& b)
|
||||
{
|
||||
return Vector2::NearEqual(a, b);
|
||||
return Vector2Base<T>::NearEqual(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Vector2>
|
||||
struct TIsPODType<Float2>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Vector2, "X:{0} Y:{1}", v.X, v.Y);
|
||||
DEFINE_DEFAULT_FORMATTING(Float2, "X:{0} Y:{1}", v.X, v.Y);
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Double2>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Double2, "X:{0} Y:{1}", v.X, v.Y);
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Int2>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Int2, "X:{0} Y:{1}", v.X, v.Y);
|
||||
|
||||
@@ -1,138 +1,119 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Double2.h"
|
||||
#include "Double3.h"
|
||||
#include "Double4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector4.h"
|
||||
#include "Color.h"
|
||||
#include "Quaternion.h"
|
||||
#include "Matrix.h"
|
||||
#include "Matrix3x3.h"
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
static_assert(sizeof(Vector3) == 12, "Invalid Vector3 type size.");
|
||||
// Float
|
||||
|
||||
const Vector3 Vector3::Zero(0.0f);
|
||||
const Vector3 Vector3::One(1.0f);
|
||||
const Vector3 Vector3::Half(0.5f);
|
||||
const Vector3 Vector3::UnitX(1.0f, 0.0f, 0.0f);
|
||||
const Vector3 Vector3::UnitY(0.0f, 1.0f, 0.0f);
|
||||
const Vector3 Vector3::UnitZ(0.0f, 0.0f, 1.0f);
|
||||
const Vector3 Vector3::Up(0.0f, 1.0f, 0.0f);
|
||||
const Vector3 Vector3::Down(0.0f, -1.0f, 0.0f);
|
||||
const Vector3 Vector3::Left(-1.0f, 0.0f, 0.0f);
|
||||
const Vector3 Vector3::Right(1.0f, 0.0f, 0.0f);
|
||||
const Vector3 Vector3::Forward(0.0f, 0.0f, 1.0f);
|
||||
const Vector3 Vector3::Backward(0.0f, 0.0f, -1.0f);
|
||||
const Vector3 Vector3::Minimum(MIN_float);
|
||||
const Vector3 Vector3::Maximum(MAX_float);
|
||||
static_assert(sizeof(Float3) == 12, "Invalid Float3 type size.");
|
||||
|
||||
Vector3::Vector3(const Vector2& xy, float z)
|
||||
template<>
|
||||
const Float3 Float3::Zero(0.0f);
|
||||
template<>
|
||||
const Float3 Float3::One(1.0f);
|
||||
template<>
|
||||
const Float3 Float3::Half(0.5f);
|
||||
template<>
|
||||
const Float3 Float3::UnitX(1.0f, 0.0f, 0.0f);
|
||||
template<>
|
||||
const Float3 Float3::UnitY(0.0f, 1.0f, 0.0f);
|
||||
template<>
|
||||
const Float3 Float3::UnitZ(0.0f, 0.0f, 1.0f);
|
||||
template<>
|
||||
const Float3 Float3::Up(0.0f, 1.0f, 0.0f);
|
||||
template<>
|
||||
const Float3 Float3::Down(0.0f, -1.0f, 0.0f);
|
||||
template<>
|
||||
const Float3 Float3::Left(-1.0f, 0.0f, 0.0f);
|
||||
template<>
|
||||
const Float3 Float3::Right(1.0f, 0.0f, 0.0f);
|
||||
template<>
|
||||
const Float3 Float3::Forward(0.0f, 0.0f, 1.0f);
|
||||
template<>
|
||||
const Float3 Float3::Backward(0.0f, 0.0f, -1.0f);
|
||||
template<>
|
||||
const Float3 Float3::Minimum(MIN_float);
|
||||
template<>
|
||||
const Float3 Float3::Maximum(MAX_float);
|
||||
|
||||
template<>
|
||||
Float3::Vector3Base(const Float2& xy, float z)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Vector2& xy)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
template<>
|
||||
Float3::Vector3Base(const Double2& xy, float z)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
, Z(0)
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Int2& xy, float z)
|
||||
: X(static_cast<float>(xy.X))
|
||||
, Y(static_cast<float>(xy.Y))
|
||||
, Z(static_cast<float>(z))
|
||||
template<>
|
||||
Float3::Vector3Base(const Int2& xy, float z)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Int3& xyz)
|
||||
: X(static_cast<float>(xyz.X))
|
||||
, Y(static_cast<float>(xyz.Y))
|
||||
, Z(static_cast<float>(xyz.Z))
|
||||
template<>
|
||||
Float3::Vector3Base(const Int3& xyz)
|
||||
: X((float)xyz.X)
|
||||
, Y((float)xyz.Y)
|
||||
, Z((float)xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Int4& xyzw)
|
||||
: X(static_cast<float>(xyzw.X))
|
||||
, Y(static_cast<float>(xyzw.Y))
|
||||
, Z(static_cast<float>(xyzw.Z))
|
||||
template<>
|
||||
Float3::Vector3Base(const Int4& xyz)
|
||||
: X((float)xyz.X)
|
||||
, Y((float)xyz.Y)
|
||||
, Z((float)xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Vector4& xyz)
|
||||
template<>
|
||||
Float3::Vector3Base(const Vector4& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Double2& xy, float z)
|
||||
: X(static_cast<float>(xy.X))
|
||||
, Y(static_cast<float>(xy.Y))
|
||||
, Z(z)
|
||||
template<>
|
||||
Float3::Vector3Base(const Double4& xyz)
|
||||
: X((float)xyz.X)
|
||||
, Y((float)xyz.Y)
|
||||
, Z((float)xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Double3& xyz)
|
||||
: X(static_cast<float>(xyz.X))
|
||||
, Y(static_cast<float>(xyz.Y))
|
||||
, Z(static_cast<float>(xyz.Z))
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Double4& xyzw)
|
||||
: X(static_cast<float>(xyzw.X))
|
||||
, Y(static_cast<float>(xyzw.Y))
|
||||
, Z(static_cast<float>(xyzw.Z))
|
||||
{
|
||||
}
|
||||
|
||||
Vector3::Vector3(const Color& color)
|
||||
template<>
|
||||
Float3::Vector3Base(const Color& color)
|
||||
: X(color.R)
|
||||
, Y(color.G)
|
||||
, Z(color.B)
|
||||
{
|
||||
}
|
||||
|
||||
String Vector3::ToString() const
|
||||
template<>
|
||||
String Float3::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
void Vector3::UnwindEuler()
|
||||
{
|
||||
X = Math::UnwindDegrees(X);
|
||||
Y = Math::UnwindDegrees(Y);
|
||||
Z = Math::UnwindDegrees(Z);
|
||||
}
|
||||
|
||||
Vector3 Vector3::Floor(const Vector3& v)
|
||||
{
|
||||
return Vector3(
|
||||
Math::Floor(v.X),
|
||||
Math::Floor(v.Y),
|
||||
Math::Floor(v.Z)
|
||||
);
|
||||
}
|
||||
|
||||
Vector3 Vector3::Frac(const Vector3& v)
|
||||
{
|
||||
return Vector3(
|
||||
v.X - (int32)v.X,
|
||||
v.Y - (int32)v.Y,
|
||||
v.Z - (int32)v.Z
|
||||
);
|
||||
}
|
||||
|
||||
void Vector3::Hermite(const Vector3& value1, const Vector3& tangent1, const Vector3& value2, const Vector3& tangent2, float amount, Vector3& result)
|
||||
template<>
|
||||
void Float3::Hermite(const Float3& value1, const Float3& tangent1, const Float3& value2, const Float3& tangent2, float amount, Float3& result)
|
||||
{
|
||||
const float squared = amount * amount;
|
||||
const float cubed = amount * squared;
|
||||
@@ -140,21 +121,22 @@ void Vector3::Hermite(const Vector3& value1, const Vector3& tangent1, const Vect
|
||||
const float part2 = -2.0f * cubed + 3.0f * squared;
|
||||
const float part3 = cubed - 2.0f * squared + amount;
|
||||
const float part4 = cubed - squared;
|
||||
|
||||
result.X = value1.X * part1 + value2.X * part2 + tangent1.X * part3 + tangent2.X * part4;
|
||||
result.Y = value1.Y * part1 + value2.Y * part2 + tangent1.Y * part3 + tangent2.Y * part4;
|
||||
result.Z = value1.Z * part1 + value2.Z * part2 + tangent1.Z * part3 + tangent2.Z * part4;
|
||||
}
|
||||
|
||||
void Vector3::Reflect(const Vector3& vector, const Vector3& normal, Vector3& result)
|
||||
template<>
|
||||
void Float3::Reflect(const Float3& vector, const Float3& normal, Float3& result)
|
||||
{
|
||||
const float dot = vector.X * normal.X + vector.Y * normal.Y + vector.Z * normal.Z;
|
||||
const Real dot = vector.X * normal.X + vector.Y * normal.Y + vector.Z * normal.Z;
|
||||
result.X = vector.X - 2.0f * dot * normal.X;
|
||||
result.Y = vector.Y - 2.0f * dot * normal.Y;
|
||||
result.Z = vector.Z - 2.0f * dot * normal.Z;
|
||||
}
|
||||
|
||||
void Vector3::Transform(const Vector3& vector, const Quaternion& rotation, Vector3& result)
|
||||
template<>
|
||||
void Float3::Transform(const Float3& vector, const Quaternion& rotation, Float3& result)
|
||||
{
|
||||
const float x = rotation.X + rotation.X;
|
||||
const float y = rotation.Y + rotation.Y;
|
||||
@@ -168,14 +150,14 @@ void Vector3::Transform(const Vector3& vector, const Quaternion& rotation, Vecto
|
||||
const float yy = rotation.Y * y;
|
||||
const float yz = rotation.Y * z;
|
||||
const float zz = rotation.Z * z;
|
||||
|
||||
result = Vector3(
|
||||
result = Float3(
|
||||
vector.X * (1.0f - yy - zz) + vector.Y * (xy - wz) + vector.Z * (xz + wy),
|
||||
vector.X * (xy + wz) + vector.Y * (1.0f - xx - zz) + vector.Z * (yz - wx),
|
||||
vector.X * (xz - wy) + vector.Y * (yz + wx) + vector.Z * (1.0f - xx - yy));
|
||||
}
|
||||
|
||||
Vector3 Vector3::Transform(const Vector3& vector, const Quaternion& rotation)
|
||||
template<>
|
||||
Float3 Float3::Transform(const Float3& vector, const Quaternion& rotation)
|
||||
{
|
||||
const float x = rotation.X + rotation.X;
|
||||
const float y = rotation.Y + rotation.Y;
|
||||
@@ -189,71 +171,71 @@ Vector3 Vector3::Transform(const Vector3& vector, const Quaternion& rotation)
|
||||
const float yy = rotation.Y * y;
|
||||
const float yz = rotation.Y * z;
|
||||
const float zz = rotation.Z * z;
|
||||
|
||||
return Vector3(
|
||||
return Float3(
|
||||
vector.X * (1.0f - yy - zz) + vector.Y * (xy - wz) + vector.Z * (xz + wy),
|
||||
vector.X * (xy + wz) + vector.Y * (1.0f - xx - zz) + vector.Z * (yz - wx),
|
||||
vector.X * (xz - wy) + vector.Y * (yz + wx) + vector.Z * (1.0f - xx - yy));
|
||||
}
|
||||
|
||||
void Vector3::Transform(const Vector3& vector, const Matrix& transform, Vector4& result)
|
||||
template<>
|
||||
void Float3::Transform(const Float3& vector, const Matrix& transform, Float4& result)
|
||||
{
|
||||
result = Vector4(
|
||||
result = Float4(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43,
|
||||
vector.X * transform.M14 + vector.Y * transform.M24 + vector.Z * transform.M34 + transform.M44);
|
||||
}
|
||||
|
||||
void Vector3::Transform(const Vector3& vector, const Matrix& transform, Vector3& result)
|
||||
template<>
|
||||
void Float3::Transform(const Float3& vector, const Matrix& transform, Float3& result)
|
||||
{
|
||||
result = Vector3(
|
||||
result = Float3(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43);
|
||||
}
|
||||
|
||||
void Vector3::Transform(const Vector3* vectors, const Matrix& transform, Vector3* results, int32 vectorsCount)
|
||||
template<>
|
||||
void Float3::Transform(const Float3& vector, const Matrix3x3& transform, Float3& result)
|
||||
{
|
||||
for (int32 i = 0; i < vectorsCount; i++)
|
||||
Transform(vectors[i], transform, results[i]);
|
||||
}
|
||||
|
||||
void Vector3::Transform(const Vector3& vector, const Matrix3x3& transform, Vector3& result)
|
||||
{
|
||||
result = Vector3(
|
||||
result = Float3(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33);
|
||||
}
|
||||
|
||||
Vector3 Vector3::Transform(const Vector3& vector, const Matrix& transform)
|
||||
template<>
|
||||
Float3 Float3::Transform(const Float3& vector, const Matrix& transform)
|
||||
{
|
||||
return Vector3(
|
||||
return Float3(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43);
|
||||
}
|
||||
|
||||
void Vector3::TransformCoordinate(const Vector3& coordinate, const Matrix& transform, Vector3& result)
|
||||
template<>
|
||||
void Float3::TransformCoordinate(const Float3& coordinate, const Matrix& transform, Float3& result)
|
||||
{
|
||||
Vector4 vector;
|
||||
vector.X = coordinate.X * transform.M11 + coordinate.Y * transform.M21 + coordinate.Z * transform.M31 + transform.M41;
|
||||
vector.Y = coordinate.X * transform.M12 + coordinate.Y * transform.M22 + coordinate.Z * transform.M32 + transform.M42;
|
||||
vector.Z = coordinate.X * transform.M13 + coordinate.Y * transform.M23 + coordinate.Z * transform.M33 + transform.M43;
|
||||
vector.W = 1.0f / (coordinate.X * transform.M14 + coordinate.Y * transform.M24 + coordinate.Z * transform.M34 + transform.M44);
|
||||
result = Vector3(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W);
|
||||
Float4 v;
|
||||
v.X = coordinate.X * transform.M11 + coordinate.Y * transform.M21 + coordinate.Z * transform.M31 + transform.M41;
|
||||
v.Y = coordinate.X * transform.M12 + coordinate.Y * transform.M22 + coordinate.Z * transform.M32 + transform.M42;
|
||||
v.Z = coordinate.X * transform.M13 + coordinate.Y * transform.M23 + coordinate.Z * transform.M33 + transform.M43;
|
||||
v.W = 1.0f / (coordinate.X * transform.M14 + coordinate.Y * transform.M24 + coordinate.Z * transform.M34 + transform.M44);
|
||||
result = Float3(v.X * v.W, v.Y * v.W, v.Z * v.W);
|
||||
}
|
||||
|
||||
void Vector3::TransformNormal(const Vector3& normal, const Matrix& transform, Vector3& result)
|
||||
template<>
|
||||
void Float3::TransformNormal(const Float3& normal, const Matrix& transform, Float3& result)
|
||||
{
|
||||
result = Vector3(
|
||||
result = Float3(
|
||||
normal.X * transform.M11 + normal.Y * transform.M21 + normal.Z * transform.M31,
|
||||
normal.X * transform.M12 + normal.Y * transform.M22 + normal.Z * transform.M32,
|
||||
normal.X * transform.M13 + normal.Y * transform.M23 + normal.Z * transform.M33);
|
||||
}
|
||||
|
||||
Vector3 Vector3::Project(const Vector3& vector, const Vector3& onNormal)
|
||||
template<>
|
||||
Float3 Float3::Project(const Float3& vector, const Float3& onNormal)
|
||||
{
|
||||
const float sqrMag = Dot(onNormal, onNormal);
|
||||
if (sqrMag < ZeroTolerance)
|
||||
@@ -261,63 +243,559 @@ Vector3 Vector3::Project(const Vector3& vector, const Vector3& onNormal)
|
||||
return onNormal * Dot(vector, onNormal) / sqrMag;
|
||||
}
|
||||
|
||||
void Vector3::Project(const Vector3& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Vector3& result)
|
||||
template<>
|
||||
void Float3::Project(const Float3& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Float3& result)
|
||||
{
|
||||
Vector3 v;
|
||||
Float3 v;
|
||||
TransformCoordinate(vector, worldViewProjection, v);
|
||||
|
||||
result = Vector3((1.0f + v.X) * 0.5f * width + x, (1.0f - v.Y) * 0.5f * height + y, v.Z * (maxZ - minZ) + minZ);
|
||||
result = Float3((1.0f + v.X) * 0.5f * width + x, (1.0f - v.Y) * 0.5f * height + y, v.Z * (maxZ - minZ) + minZ);
|
||||
}
|
||||
|
||||
void Vector3::Unproject(const Vector3& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Vector3& result)
|
||||
template<>
|
||||
void Float3::Unproject(const Float3& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Float3& result)
|
||||
{
|
||||
Matrix matrix;
|
||||
Matrix::Invert(worldViewProjection, matrix);
|
||||
|
||||
const Vector3 v = Vector3((vector.X - x) / width * 2.0f - 1.0f, -((vector.Y - y) / height * 2.0f - 1.0f), (vector.Z - minZ) / (maxZ - minZ));
|
||||
|
||||
const Float3 v((vector.X - x) / width * 2.0f - 1.0f, -((vector.Y - y) / height * 2.0f - 1.0f), (vector.Z - minZ) / (maxZ - minZ));
|
||||
TransformCoordinate(v, matrix, result);
|
||||
}
|
||||
|
||||
void Vector3::CreateOrthonormalBasis(Vector3& xAxis, Vector3& yAxis, Vector3& zAxis)
|
||||
template<>
|
||||
void Float3::CreateOrthonormalBasis(Float3& xAxis, Float3& yAxis, Float3& zAxis)
|
||||
{
|
||||
xAxis -= (xAxis | zAxis) / (zAxis | zAxis) * zAxis;
|
||||
yAxis -= (yAxis | zAxis) / (zAxis | zAxis) * zAxis;
|
||||
|
||||
if (xAxis.LengthSquared() < ZeroTolerance)
|
||||
xAxis = yAxis ^ zAxis;
|
||||
if (yAxis.LengthSquared() < ZeroTolerance)
|
||||
yAxis = xAxis ^ zAxis;
|
||||
|
||||
xAxis.Normalize();
|
||||
yAxis.Normalize();
|
||||
zAxis.Normalize();
|
||||
}
|
||||
|
||||
void Vector3::FindBestAxisVectors(Vector3& firstAxis, Vector3& secondAxis) const
|
||||
template<>
|
||||
void Float3::FindBestAxisVectors(Float3& firstAxis, Float3& secondAxis) const
|
||||
{
|
||||
const float absX = Math::Abs(X);
|
||||
const float absY = Math::Abs(Y);
|
||||
const float absZ = Math::Abs(Z);
|
||||
|
||||
if (absZ > absX && absZ > absY)
|
||||
firstAxis = Vector3(1, 0, 0);
|
||||
firstAxis = Float3(1, 0, 0);
|
||||
else
|
||||
firstAxis = Vector3(0, 0, 1);
|
||||
|
||||
firstAxis = Float3(0, 0, 1);
|
||||
firstAxis = (firstAxis - *this * (firstAxis | *this)).GetNormalized();
|
||||
secondAxis = firstAxis ^ *this;
|
||||
}
|
||||
|
||||
float Vector3::TriangleArea(const Vector3& v0, const Vector3& v1, const Vector3& v2)
|
||||
template<>
|
||||
float Float3::TriangleArea(const Float3& v0, const Float3& v1, const Float3& v2)
|
||||
{
|
||||
return (v2 - v0 ^ v1 - v0).Length() * 0.5f;
|
||||
}
|
||||
|
||||
float Vector3::Angle(const Vector3& from, const Vector3& to)
|
||||
template<>
|
||||
float Float3::Angle(const Float3& from, const Float3& to)
|
||||
{
|
||||
const float dot = Math::Clamp(Dot(Normalize(from), Normalize(to)), -1.0f, 1.0f);
|
||||
if (Math::Abs(dot) > (1.0f - ZeroTolerance))
|
||||
if (Math::Abs(dot) > 1.0f - ZeroTolerance)
|
||||
return dot > 0.0f ? 0.0f : PI;
|
||||
return Math::Acos(dot);
|
||||
}
|
||||
|
||||
// Double
|
||||
|
||||
static_assert(sizeof(Double3) == 24, "Invalid Double3 type size.");
|
||||
|
||||
template<>
|
||||
const Double3 Double3::Zero(0.0);
|
||||
template<>
|
||||
const Double3 Double3::One(1.0);
|
||||
template<>
|
||||
const Double3 Double3::Half(0.5);
|
||||
template<>
|
||||
const Double3 Double3::UnitX(1.0, 0.0, 0.0);
|
||||
template<>
|
||||
const Double3 Double3::UnitY(0.0, 1.0, 0.0);
|
||||
template<>
|
||||
const Double3 Double3::UnitZ(0.0, 0.0, 1.0);
|
||||
template<>
|
||||
const Double3 Double3::Up(0.0, 1.0, 0.0);
|
||||
template<>
|
||||
const Double3 Double3::Down(0.0, -1.0, 0.0);
|
||||
template<>
|
||||
const Double3 Double3::Left(-1.0, 0.0, 0.0);
|
||||
template<>
|
||||
const Double3 Double3::Right(1.0, 0.0, 0.0);
|
||||
template<>
|
||||
const Double3 Double3::Forward(0.0, 0.0, 1.0);
|
||||
template<>
|
||||
const Double3 Double3::Backward(0.0, 0.0, -1.0);
|
||||
template<>
|
||||
const Double3 Double3::Minimum(MIN_double);
|
||||
template<>
|
||||
const Double3 Double3::Maximum(MAX_double);
|
||||
|
||||
template<>
|
||||
Double3::Vector3Base(const Float2& xy, double z)
|
||||
: X((double)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3::Vector3Base(const Double2& xy, double z)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3::Vector3Base(const Int2& xy, double z)
|
||||
: X((double)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3::Vector3Base(const Int3& xyz)
|
||||
: X((double)xyz.X)
|
||||
, Y((double)xyz.Y)
|
||||
, Z((double)xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3::Vector3Base(const Int4& xyz)
|
||||
: X((double)xyz.X)
|
||||
, Y((double)xyz.Y)
|
||||
, Z((double)xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3::Vector3Base(const Float4& xyz)
|
||||
: X((double)xyz.X)
|
||||
, Y((double)xyz.Y)
|
||||
, Z((double)xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3::Vector3Base(const Double4& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3::Vector3Base(const Color& color)
|
||||
: X((double)color.R)
|
||||
, Y((double)color.G)
|
||||
, Z((double)color.B)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
String Double3::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::Hermite(const Double3& value1, const Double3& tangent1, const Double3& value2, const Double3& tangent2, double amount, Double3& result)
|
||||
{
|
||||
const double squared = amount * amount;
|
||||
const double cubed = amount * squared;
|
||||
const double part1 = 2.0 * cubed - 3.0 * squared + 1.0;
|
||||
const double part2 = -2.0 * cubed + 3.0 * squared;
|
||||
const double part3 = cubed - 2.0 * squared + amount;
|
||||
const double part4 = cubed - squared;
|
||||
result.X = value1.X * part1 + value2.X * part2 + tangent1.X * part3 + tangent2.X * part4;
|
||||
result.Y = value1.Y * part1 + value2.Y * part2 + tangent1.Y * part3 + tangent2.Y * part4;
|
||||
result.Z = value1.Z * part1 + value2.Z * part2 + tangent1.Z * part3 + tangent2.Z * part4;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::Reflect(const Double3& vector, const Double3& normal, Double3& result)
|
||||
{
|
||||
const double dot = vector.X * normal.X + vector.Y * normal.Y + vector.Z * normal.Z;
|
||||
result.X = vector.X - 2.0 * dot * normal.X;
|
||||
result.Y = vector.Y - 2.0 * dot * normal.Y;
|
||||
result.Z = vector.Z - 2.0 * dot * normal.Z;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::Transform(const Double3& vector, const Quaternion& rotation, Double3& result)
|
||||
{
|
||||
const float x = rotation.X + rotation.X;
|
||||
const float y = rotation.Y + rotation.Y;
|
||||
const float z = rotation.Z + rotation.Z;
|
||||
const float wx = rotation.W * x;
|
||||
const float wy = rotation.W * y;
|
||||
const float wz = rotation.W * z;
|
||||
const float xx = rotation.X * x;
|
||||
const float xy = rotation.X * y;
|
||||
const float xz = rotation.X * z;
|
||||
const float yy = rotation.Y * y;
|
||||
const float yz = rotation.Y * z;
|
||||
const float zz = rotation.Z * z;
|
||||
result = Double3(
|
||||
vector.X * (1.0f - yy - zz) + vector.Y * (xy - wz) + vector.Z * (xz + wy),
|
||||
vector.X * (xy + wz) + vector.Y * (1.0f - xx - zz) + vector.Z * (yz - wx),
|
||||
vector.X * (xz - wy) + vector.Y * (yz + wx) + vector.Z * (1.0f - xx - yy));
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3 Double3::Transform(const Double3& vector, const Quaternion& rotation)
|
||||
{
|
||||
const float x = rotation.X + rotation.X;
|
||||
const float y = rotation.Y + rotation.Y;
|
||||
const float z = rotation.Z + rotation.Z;
|
||||
const float wx = rotation.W * x;
|
||||
const float wy = rotation.W * y;
|
||||
const float wz = rotation.W * z;
|
||||
const float xx = rotation.X * x;
|
||||
const float xy = rotation.X * y;
|
||||
const float xz = rotation.X * z;
|
||||
const float yy = rotation.Y * y;
|
||||
const float yz = rotation.Y * z;
|
||||
const float zz = rotation.Z * z;
|
||||
return Double3(
|
||||
vector.X * double(1.0f - yy - zz) + vector.Y * double(xy - wz) + vector.Z * double(xz + wy),
|
||||
vector.X * double(xy + wz) + vector.Y * double(1.0f - xx - zz) + vector.Z * double(yz - wx),
|
||||
vector.X * double(xz - wy) + vector.Y * double(yz + wx) + vector.Z * double(1.0f - xx - yy));
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::Transform(const Double3& vector, const Matrix& transform, Double4& result)
|
||||
{
|
||||
result = Double4(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43,
|
||||
vector.X * transform.M14 + vector.Y * transform.M24 + vector.Z * transform.M34 + transform.M44);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::Transform(const Double3& vector, const Matrix& transform, Double3& result)
|
||||
{
|
||||
result = Double3(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::Transform(const Double3& vector, const Matrix3x3& transform, Double3& result)
|
||||
{
|
||||
result = Double3(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33);
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3 Double3::Transform(const Double3& vector, const Matrix& transform)
|
||||
{
|
||||
return Double3(
|
||||
vector.X * transform.M11 + vector.Y * transform.M21 + vector.Z * transform.M31 + transform.M41,
|
||||
vector.X * transform.M12 + vector.Y * transform.M22 + vector.Z * transform.M32 + transform.M42,
|
||||
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::TransformCoordinate(const Double3& coordinate, const Matrix& transform, Double3& result)
|
||||
{
|
||||
Double4 v;
|
||||
v.X = coordinate.X * transform.M11 + coordinate.Y * transform.M21 + coordinate.Z * transform.M31 + transform.M41;
|
||||
v.Y = coordinate.X * transform.M12 + coordinate.Y * transform.M22 + coordinate.Z * transform.M32 + transform.M42;
|
||||
v.Z = coordinate.X * transform.M13 + coordinate.Y * transform.M23 + coordinate.Z * transform.M33 + transform.M43;
|
||||
v.W = 1.0 / (coordinate.X * transform.M14 + coordinate.Y * transform.M24 + coordinate.Z * transform.M34 + transform.M44);
|
||||
result = Double3(v.X * v.W, v.Y * v.W, v.Z * v.W);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::TransformNormal(const Double3& normal, const Matrix& transform, Double3& result)
|
||||
{
|
||||
result = Double3(
|
||||
normal.X * transform.M11 + normal.Y * transform.M21 + normal.Z * transform.M31,
|
||||
normal.X * transform.M12 + normal.Y * transform.M22 + normal.Z * transform.M32,
|
||||
normal.X * transform.M13 + normal.Y * transform.M23 + normal.Z * transform.M33);
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3 Double3::Project(const Double3& vector, const Double3& onNormal)
|
||||
{
|
||||
const Real sqrMag = Dot(onNormal, onNormal);
|
||||
if (sqrMag < ZeroTolerance)
|
||||
return Zero;
|
||||
return onNormal * Dot(vector, onNormal) / sqrMag;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::Project(const Double3& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Double3& result)
|
||||
{
|
||||
Double3 v;
|
||||
TransformCoordinate(vector, worldViewProjection, v);
|
||||
result = Double3((1.0f + v.X) * 0.5f * width + x, (1.0f - v.Y) * 0.5f * height + y, v.Z * (maxZ - minZ) + minZ);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::Unproject(const Double3& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Double3& result)
|
||||
{
|
||||
Matrix matrix;
|
||||
Matrix::Invert(worldViewProjection, matrix);
|
||||
const Double3 v((vector.X - x) / width * 2.0f - 1.0f, -((vector.Y - y) / height * 2.0f - 1.0f), (vector.Z - minZ) / (maxZ - minZ));
|
||||
TransformCoordinate(v, matrix, result);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::CreateOrthonormalBasis(Double3& xAxis, Double3& yAxis, Double3& zAxis)
|
||||
{
|
||||
xAxis -= (xAxis | zAxis) / (zAxis | zAxis) * zAxis;
|
||||
yAxis -= (yAxis | zAxis) / (zAxis | zAxis) * zAxis;
|
||||
if (xAxis.LengthSquared() < ZeroTolerance)
|
||||
xAxis = yAxis ^ zAxis;
|
||||
if (yAxis.LengthSquared() < ZeroTolerance)
|
||||
yAxis = xAxis ^ zAxis;
|
||||
xAxis.Normalize();
|
||||
yAxis.Normalize();
|
||||
zAxis.Normalize();
|
||||
}
|
||||
|
||||
template<>
|
||||
void Double3::FindBestAxisVectors(Double3& firstAxis, Double3& secondAxis) const
|
||||
{
|
||||
const double absX = Math::Abs(X);
|
||||
const double absY = Math::Abs(Y);
|
||||
const double absZ = Math::Abs(Z);
|
||||
if (absZ > absX && absZ > absY)
|
||||
firstAxis = Double3(1, 0, 0);
|
||||
else
|
||||
firstAxis = Double3(0, 0, 1);
|
||||
firstAxis = (firstAxis - *this * (firstAxis | *this)).GetNormalized();
|
||||
secondAxis = firstAxis ^ *this;
|
||||
}
|
||||
|
||||
template<>
|
||||
double Double3::TriangleArea(const Double3& v0, const Double3& v1, const Double3& v2)
|
||||
{
|
||||
return (v2 - v0 ^ v1 - v0).Length() * 0.5;
|
||||
}
|
||||
|
||||
template<>
|
||||
double Double3::Angle(const Double3& from, const Double3& to)
|
||||
{
|
||||
const double dot = Math::Clamp(Dot(Normalize(from), Normalize(to)), -1.0, 1.0);
|
||||
if (Math::Abs(dot) > 1.0 - ZeroTolerance)
|
||||
return dot > 0.0 ? 0.0 : PI;
|
||||
return Math::Acos(dot);
|
||||
}
|
||||
|
||||
// Int
|
||||
|
||||
static_assert(sizeof(Int3) == 12, "Invalid Int3 type size.");
|
||||
|
||||
template<>
|
||||
const Int3 Int3::Zero(0);
|
||||
template<>
|
||||
const Int3 Int3::One(1);
|
||||
template<>
|
||||
const Int3 Int3::Half(1);
|
||||
template<>
|
||||
const Int3 Int3::UnitX(1, 0, 0);
|
||||
template<>
|
||||
const Int3 Int3::UnitY(0, 1, 0);
|
||||
template<>
|
||||
const Int3 Int3::UnitZ(0, 0, 1);
|
||||
template<>
|
||||
const Int3 Int3::Up(0, 1, 0);
|
||||
template<>
|
||||
const Int3 Int3::Down(0, -1, 0);
|
||||
template<>
|
||||
const Int3 Int3::Left(-1, 0, 0);
|
||||
template<>
|
||||
const Int3 Int3::Right(1, 0, 0);
|
||||
template<>
|
||||
const Int3 Int3::Forward(0, 0, 1);
|
||||
template<>
|
||||
const Int3 Int3::Backward(0, 0, -1);
|
||||
template<>
|
||||
const Int3 Int3::Minimum(MIN_int32);
|
||||
template<>
|
||||
const Int3 Int3::Maximum(MAX_int32);
|
||||
|
||||
template<>
|
||||
Int3::Vector3Base(const Float2& xy, int32 z)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3::Vector3Base(const Double2& xy, int32 z)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
, Z(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3::Vector3Base(const Int2& xy, int32 z)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3::Vector3Base(const Int3& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3::Vector3Base(const Int4& xyz)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3::Vector3Base(const Float4& xyz)
|
||||
: X((int32)xyz.X)
|
||||
, Y((int32)xyz.Y)
|
||||
, Z((int32)xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3::Vector3Base(const Double4& xyz)
|
||||
: X((int32)xyz.X)
|
||||
, Y((int32)xyz.Y)
|
||||
, Z((int32)xyz.Z)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3::Vector3Base(const Color& color)
|
||||
: X((int32)color.R)
|
||||
, Y((int32)color.G)
|
||||
, Z((int32)color.B)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
String Int3::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::Hermite(const Int3& value1, const Int3& tangent1, const Int3& value2, const Int3& tangent2, int32 amount, Int3& result)
|
||||
{
|
||||
result = value1;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::Reflect(const Int3& vector, const Int3& normal, Int3& result)
|
||||
{
|
||||
result = vector;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::Transform(const Int3& vector, const Quaternion& rotation, Int3& result)
|
||||
{
|
||||
result = vector;
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3 Int3::Transform(const Int3& vector, const Quaternion& rotation)
|
||||
{
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::Transform(const Int3& vector, const Matrix& transform, Int4& result)
|
||||
{
|
||||
result = Int4(vector);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::Transform(const Int3& vector, const Matrix& transform, Int3& result)
|
||||
{
|
||||
result = vector;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::Transform(const Int3& vector, const Matrix3x3& transform, Int3& result)
|
||||
{
|
||||
result = vector;
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3 Int3::Transform(const Int3& vector, const Matrix& transform)
|
||||
{
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::TransformCoordinate(const Int3& coordinate, const Matrix& transform, Int3& result)
|
||||
{
|
||||
result = coordinate;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::TransformNormal(const Int3& normal, const Matrix& transform, Int3& result)
|
||||
{
|
||||
result = normal;
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3 Int3::Project(const Int3& vector, const Int3& onNormal)
|
||||
{
|
||||
return Zero;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::Project(const Int3& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Int3& result)
|
||||
{
|
||||
result = vector;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::Unproject(const Int3& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Int3& result)
|
||||
{
|
||||
result = vector;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::CreateOrthonormalBasis(Int3& xAxis, Int3& yAxis, Int3& zAxis)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Int3::FindBestAxisVectors(Int3& firstAxis, Int3& secondAxis) const
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
int32 Int3::TriangleArea(const Int3& v0, const Int3& v1, const Int3& v2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<>
|
||||
int32 Int3::Angle(const Int3& from, const Int3& to)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,29 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a three dimensional mathematical vector.
|
||||
/// </summary>
|
||||
[Unmanaged]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe partial struct Vector3
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component.
|
||||
/// </summary>
|
||||
public float X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component.
|
||||
/// </summary>
|
||||
public float Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component.
|
||||
/// </summary>
|
||||
public float Z;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[TypeConverter(typeof(TypeConverters.Vector3Converter))]
|
||||
partial struct Vector3 : IEquatable<Vector3>, IFormattable
|
||||
@@ -326,26 +349,6 @@ namespace FlaxEngine
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of the vector.
|
||||
/// </summary>
|
||||
public void Negate()
|
||||
{
|
||||
X *= -1;
|
||||
Y *= -1;
|
||||
Z *= -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When this vector contains Euler angles (degrees), ensure that angles are between +/-180
|
||||
/// </summary>
|
||||
public void UnwindEuler()
|
||||
{
|
||||
X = Mathf.UnwindDegrees(X);
|
||||
Y = Mathf.UnwindDegrees(Y);
|
||||
Z = Mathf.UnwindDegrees(Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the vector.
|
||||
/// </summary>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,36 +1,36 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Double4.h"
|
||||
#include "Double3.h"
|
||||
#include "Double2.h"
|
||||
#include "Vector4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Int2.h"
|
||||
#include "Int3.h"
|
||||
#include "Int4.h"
|
||||
#include "Color.h"
|
||||
#include "Matrix.h"
|
||||
#include "Rectangle.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
static_assert(sizeof(Vector4) == 16, "Invalid Vector4 type size.");
|
||||
// Float
|
||||
|
||||
const Vector4 Vector4::Zero(0.0f);
|
||||
const Vector4 Vector4::One(1.0f);
|
||||
const Vector4 Vector4::UnitX(1, 0, 0, 0);
|
||||
const Vector4 Vector4::UnitY(0, 1, 0, 0);
|
||||
const Vector4 Vector4::UnitZ(0, 0, 1, 0);
|
||||
const Vector4 Vector4::UnitW(0, 0, 0, 1);
|
||||
const Vector4 Vector4::Minimum(MIN_float);
|
||||
const Vector4 Vector4::Maximum(MAX_float);
|
||||
static_assert(sizeof(Float4) == 16, "Invalid Float4 type size.");
|
||||
|
||||
Vector4::Vector4(float xyzw[4])
|
||||
{
|
||||
Platform::MemoryCopy(Raw, xyzw, sizeof(float) * 4);
|
||||
}
|
||||
template<>
|
||||
const Float4 Float4::Zero(0.0f);
|
||||
template<>
|
||||
const Float4 Float4::One(1.0f);
|
||||
template<>
|
||||
const Float4 Float4::UnitX(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
template<>
|
||||
const Float4 Float4::UnitY(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
template<>
|
||||
const Float4 Float4::UnitZ(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
template<>
|
||||
const Float4 Float4::UnitW(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
template<>
|
||||
const Float4 Float4::Minimum(MIN_float);
|
||||
template<>
|
||||
const Float4 Float4::Maximum(MAX_float);
|
||||
|
||||
Vector4::Vector4(const Vector2& xy, float z, float w)
|
||||
template<>
|
||||
Float4::Vector4Base(const Float2& xy, float z, float w)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
@@ -38,7 +38,8 @@ Vector4::Vector4(const Vector2& xy, float z, float w)
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Vector2& xy, const Vector2& zw)
|
||||
template<>
|
||||
Float4::Vector4Base(const Float2& xy, const Float2& zw)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(zw.X)
|
||||
@@ -46,7 +47,8 @@ Vector4::Vector4(const Vector2& xy, const Vector2& zw)
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Vector3& xyz, float w)
|
||||
template<>
|
||||
Float4::Vector4Base(const Float3& xyz, float w)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
@@ -54,55 +56,53 @@ Vector4::Vector4(const Vector3& xyz, float w)
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Int2& xy, float z, float w)
|
||||
: X(static_cast<float>(xy.X))
|
||||
, Y(static_cast<float>(xy.Y))
|
||||
template<>
|
||||
Float4::Vector4Base(const Int2& xy, float z, float w)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Int3& xyz, float w)
|
||||
: X(static_cast<float>(xyz.X))
|
||||
, Y(static_cast<float>(xyz.Y))
|
||||
, Z(static_cast<float>(xyz.Z))
|
||||
template<>
|
||||
Float4::Vector4Base(const Int3& xyz, float w)
|
||||
: X((float)xyz.X)
|
||||
, Y((float)xyz.Y)
|
||||
, Z((float)xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Int4& xyzw)
|
||||
: X(static_cast<float>(xyzw.X))
|
||||
, Y(static_cast<float>(xyzw.Y))
|
||||
, Z(static_cast<float>(xyzw.Z))
|
||||
, W(static_cast<float>(xyzw.W))
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Double2& xy, float z, float w)
|
||||
: X(static_cast<float>(xy.X))
|
||||
, Y(static_cast<float>(xy.Y))
|
||||
template<>
|
||||
Float4::Vector4Base(const Double2& xy, float z, float w)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Double3& xyz, float w)
|
||||
: X(static_cast<float>(xyz.X))
|
||||
, Y(static_cast<float>(xyz.Y))
|
||||
, Z(static_cast<float>(xyz.Z))
|
||||
template<>
|
||||
Float4::Vector4Base(const Double2& xy, const Double2& zw)
|
||||
: X((float)xy.X)
|
||||
, Y((float)xy.Y)
|
||||
, Z((float)zw.X)
|
||||
, W((float)zw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Float4::Vector4Base(const Double3& xyz, float w)
|
||||
: X((float)xyz.X)
|
||||
, Y((float)xyz.Y)
|
||||
, Z((float)xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Double4& xyzw)
|
||||
: X(static_cast<float>(xyzw.X))
|
||||
, Y(static_cast<float>(xyzw.Y))
|
||||
, Z(static_cast<float>(xyzw.Z))
|
||||
, W(static_cast<float>(xyzw.W))
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Color& color)
|
||||
template<>
|
||||
Float4::Vector4Base(const Color& color)
|
||||
: X(color.R)
|
||||
, Y(color.G)
|
||||
, Z(color.B)
|
||||
@@ -110,7 +110,8 @@ Vector4::Vector4(const Color& color)
|
||||
{
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Rectangle& rect)
|
||||
template<>
|
||||
Float4::Vector4Base(const Rectangle& rect)
|
||||
: X(rect.Location.X)
|
||||
, Y(rect.Location.Y)
|
||||
, Z(rect.Size.X)
|
||||
@@ -118,99 +119,270 @@ Vector4::Vector4(const Rectangle& rect)
|
||||
{
|
||||
}
|
||||
|
||||
String Vector4::ToString() const
|
||||
template<>
|
||||
String Float4::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
Vector4 Vector4::Floor(const Vector4& v)
|
||||
template<>
|
||||
Float4 Float4::Transform(const Float4& v, const Matrix& m)
|
||||
{
|
||||
return Vector4(
|
||||
Math::Floor(v.X),
|
||||
Math::Floor(v.Y),
|
||||
Math::Floor(v.Z),
|
||||
Math::Floor(v.W)
|
||||
);
|
||||
}
|
||||
|
||||
Vector4 Vector4::Frac(const Vector4& v)
|
||||
{
|
||||
return Vector4(
|
||||
v.X - (int32)v.X,
|
||||
v.Y - (int32)v.Y,
|
||||
v.Z - (int32)v.Z,
|
||||
v.W - (int32)v.W
|
||||
);
|
||||
}
|
||||
|
||||
Vector4 Vector4::Round(const Vector4& v)
|
||||
{
|
||||
return Vector4(
|
||||
Math::Round(v.X),
|
||||
Math::Round(v.Y),
|
||||
Math::Round(v.Z),
|
||||
Math::Round(v.W)
|
||||
);
|
||||
}
|
||||
|
||||
Vector4 Vector4::Ceil(const Vector4& v)
|
||||
{
|
||||
return Vector4(
|
||||
Math::Ceil(v.X),
|
||||
Math::Ceil(v.Y),
|
||||
Math::Ceil(v.Z),
|
||||
Math::Ceil(v.W)
|
||||
);
|
||||
}
|
||||
|
||||
Vector4 Vector4::Clamp(const Vector4& value, const Vector4& min, const Vector4& max)
|
||||
{
|
||||
float x = value.X;
|
||||
x = x > max.X ? max.X : x;
|
||||
x = x < min.X ? min.X : x;
|
||||
|
||||
float y = value.Y;
|
||||
y = y > max.Y ? max.Y : y;
|
||||
y = y < min.Y ? min.Y : y;
|
||||
|
||||
float z = value.Z;
|
||||
z = z > max.Z ? max.Z : z;
|
||||
z = z < min.Z ? min.Z : z;
|
||||
|
||||
float w = value.W;
|
||||
w = w > max.W ? max.W : w;
|
||||
w = w < min.W ? min.W : w;
|
||||
|
||||
return Vector4(x, y, z, w);
|
||||
}
|
||||
|
||||
void Vector4::Clamp(const Vector4& value, const Vector4& min, const Vector4& max, Vector4& result)
|
||||
{
|
||||
float x = value.X;
|
||||
x = x > max.X ? max.X : x;
|
||||
x = x < min.X ? min.X : x;
|
||||
|
||||
float y = value.Y;
|
||||
y = y > max.Y ? max.Y : y;
|
||||
y = y < min.Y ? min.Y : y;
|
||||
|
||||
float z = value.Z;
|
||||
z = z > max.Z ? max.Z : z;
|
||||
z = z < min.Z ? min.Z : z;
|
||||
|
||||
float w = value.W;
|
||||
w = w > max.W ? max.W : w;
|
||||
w = w < min.W ? min.W : w;
|
||||
|
||||
result = Vector4(x, y, z, w);
|
||||
}
|
||||
|
||||
Vector4 Vector4::Transform(const Vector4& v, const Matrix& m)
|
||||
{
|
||||
return Vector4(
|
||||
return Float4(
|
||||
m.Values[0][0] * v.Raw[0] + m.Values[1][0] * v.Raw[1] + m.Values[2][0] * v.Raw[2] + m.Values[3][0] * v.Raw[3],
|
||||
m.Values[0][1] * v.Raw[0] + m.Values[1][1] * v.Raw[1] + m.Values[2][1] * v.Raw[2] + m.Values[3][1] * v.Raw[3],
|
||||
m.Values[0][2] * v.Raw[0] + m.Values[1][2] * v.Raw[1] + m.Values[2][2] * v.Raw[2] + m.Values[3][2] * v.Raw[3],
|
||||
m.Values[0][3] * v.Raw[0] + m.Values[1][3] * v.Raw[1] + m.Values[2][3] * v.Raw[2] + m.Values[3][3] * v.Raw[3]
|
||||
);
|
||||
}
|
||||
|
||||
// Double
|
||||
|
||||
static_assert(sizeof(Double4) == 32, "Invalid Double4 type size.");
|
||||
|
||||
template<>
|
||||
const Double4 Double4::Zero(0.0);
|
||||
template<>
|
||||
const Double4 Double4::One(1.0);
|
||||
template<>
|
||||
const Double4 Double4::UnitX(1.0, 0.0, 0.0, 0.0);
|
||||
template<>
|
||||
const Double4 Double4::UnitY(0.0, 1.0, 0.0, 0.0);
|
||||
template<>
|
||||
const Double4 Double4::UnitZ(0.0, 0.0, 1.0, 0.0);
|
||||
template<>
|
||||
const Double4 Double4::UnitW(0.0, 0.0, 0.0, 1.0);
|
||||
template<>
|
||||
const Double4 Double4::Minimum(MIN_double);
|
||||
template<>
|
||||
const Double4 Double4::Maximum(MAX_double);
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Float2& xy, double z, double w)
|
||||
: X((double)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Float2& xy, const Float2& zw)
|
||||
: X((double)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
, Z((double)zw.X)
|
||||
, W((double)zw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Float3& xyz, double w)
|
||||
: X((double)xyz.X)
|
||||
, Y((double)xyz.Y)
|
||||
, Z((double)xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Int2& xy, double z, double w)
|
||||
: X((double)xy.X)
|
||||
, Y((double)xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Int3& xyz, double w)
|
||||
: X((double)xyz.X)
|
||||
, Y((double)xyz.Y)
|
||||
, Z((double)xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Double2& xy, double z, double w)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Double2& xy, const Double2& zw)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(zw.X)
|
||||
, W(zw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Double3& xyz, double w)
|
||||
: X((double)xyz.X)
|
||||
, Y((double)xyz.Y)
|
||||
, Z((double)xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Color& color)
|
||||
: X((double)color.R)
|
||||
, Y((double)color.G)
|
||||
, Z((double)color.B)
|
||||
, W((double)color.A)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4::Vector4Base(const Rectangle& rect)
|
||||
: X((double)rect.Location.X)
|
||||
, Y((double)rect.Location.Y)
|
||||
, Z((double)rect.Size.X)
|
||||
, W((double)rect.Size.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
String Double4::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
template<>
|
||||
Double4 Double4::Transform(const Double4& v, const Matrix& m)
|
||||
{
|
||||
return Double4(
|
||||
m.Values[0][0] * v.Raw[0] + m.Values[1][0] * v.Raw[1] + m.Values[2][0] * v.Raw[2] + m.Values[3][0] * v.Raw[3],
|
||||
m.Values[0][1] * v.Raw[0] + m.Values[1][1] * v.Raw[1] + m.Values[2][1] * v.Raw[2] + m.Values[3][1] * v.Raw[3],
|
||||
m.Values[0][2] * v.Raw[0] + m.Values[1][2] * v.Raw[1] + m.Values[2][2] * v.Raw[2] + m.Values[3][2] * v.Raw[3],
|
||||
m.Values[0][3] * v.Raw[0] + m.Values[1][3] * v.Raw[1] + m.Values[2][3] * v.Raw[2] + m.Values[3][3] * v.Raw[3]
|
||||
);
|
||||
}
|
||||
|
||||
// Int
|
||||
|
||||
static_assert(sizeof(Int4) == 16, "Invalid Int4 type size.");
|
||||
|
||||
template<>
|
||||
const Int4 Int4::Zero(0);
|
||||
template<>
|
||||
const Int4 Int4::One(1);
|
||||
template<>
|
||||
const Int4 Int4::UnitX(1, 0, 0, 0);
|
||||
template<>
|
||||
const Int4 Int4::UnitY(0, 1, 0, 0);
|
||||
template<>
|
||||
const Int4 Int4::UnitZ(0, 0, 1, 0);
|
||||
template<>
|
||||
const Int4 Int4::UnitW(0, 0, 0, 1);
|
||||
template<>
|
||||
const Int4 Int4::Minimum(MIN_int32);
|
||||
template<>
|
||||
const Int4 Int4::Maximum(MAX_int32);
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Float2& xy, int32 z, int32 w)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Float2& xy, const Float2& zw)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
, Z((int32)zw.X)
|
||||
, W((int32)zw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Float3& xyz, int32 w)
|
||||
: X((int32)xyz.X)
|
||||
, Y((int32)xyz.Y)
|
||||
, Z((int32)xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Int2& xy, int32 z, int32 w)
|
||||
: X(xy.X)
|
||||
, Y(xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Int3& xyz, int32 w)
|
||||
: X(xyz.X)
|
||||
, Y(xyz.Y)
|
||||
, Z(xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Double2& xy, int32 z, int32 w)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
, Z(z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Double2& xy, const Double2& zw)
|
||||
: X((int32)xy.X)
|
||||
, Y((int32)xy.Y)
|
||||
, Z((int32)zw.X)
|
||||
, W((int32)zw.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Double3& xyz, int32 w)
|
||||
: X((int32)xyz.X)
|
||||
, Y((int32)xyz.Y)
|
||||
, Z((int32)xyz.Z)
|
||||
, W(w)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Color& color)
|
||||
: X((int32)color.R)
|
||||
, Y((int32)color.G)
|
||||
, Z((int32)color.B)
|
||||
, W((int32)color.A)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4::Vector4Base(const Rectangle& rect)
|
||||
: X((int32)rect.Location.X)
|
||||
, Y((int32)rect.Location.Y)
|
||||
, Z((int32)rect.Size.X)
|
||||
, W((int32)rect.Size.Y)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
String Int4::ToString() const
|
||||
{
|
||||
return String::Format(TEXT("{}"), *this);
|
||||
}
|
||||
|
||||
template<>
|
||||
Int4 Int4::Transform(const Int4& v, const Matrix& m)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,34 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a four dimensional mathematical vector.
|
||||
/// </summary>
|
||||
[Unmanaged]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe partial struct Vector4
|
||||
{
|
||||
/// <summary>
|
||||
/// The X component.
|
||||
/// </summary>
|
||||
public float X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component.
|
||||
/// </summary>
|
||||
public float Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component.
|
||||
/// </summary>
|
||||
public float Z;
|
||||
|
||||
/// <summary>
|
||||
/// The W component.
|
||||
/// </summary>
|
||||
public float W;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[TypeConverter(typeof(TypeConverters.Vector4Converter))]
|
||||
partial struct Vector4 : IEquatable<Vector4>, IFormattable
|
||||
|
||||
@@ -3,29 +3,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "Math.h"
|
||||
#include "Mathd.h"
|
||||
#include "Engine/Core/Formatting.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
struct Double2;
|
||||
struct Double3;
|
||||
struct Double4;
|
||||
struct Vector2;
|
||||
struct Vector3;
|
||||
struct Color;
|
||||
struct Matrix;
|
||||
struct Rectangle;
|
||||
class String;
|
||||
struct Int2;
|
||||
struct Int3;
|
||||
struct Int4;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a four dimensional mathematical vector with 32-bit precision (per-component).
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API Vector4
|
||||
template<typename T>
|
||||
API_STRUCT(Template) struct Vector4Base
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Vector4);
|
||||
public:
|
||||
typedef T Real;
|
||||
static struct ScriptingTypeInitializer TypeInitializer;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
@@ -33,66 +23,64 @@ public:
|
||||
/// <summary>
|
||||
/// The X component.
|
||||
/// </summary>
|
||||
API_FIELD() float X;
|
||||
API_FIELD() T X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component.
|
||||
/// </summary>
|
||||
API_FIELD() float Y;
|
||||
API_FIELD() T Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component.
|
||||
/// </summary>
|
||||
API_FIELD() float Z;
|
||||
API_FIELD() T Z;
|
||||
|
||||
/// <summary>
|
||||
/// The W component.
|
||||
/// </summary>
|
||||
API_FIELD() float W;
|
||||
API_FIELD() T W;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The raw vector values (in xyzw order).
|
||||
/// The raw vector values (in XYZW order).
|
||||
/// </summary>
|
||||
float Raw[4];
|
||||
T Raw[4];
|
||||
};
|
||||
|
||||
public:
|
||||
// Vector with all components equal 0
|
||||
static const Vector4 Zero;
|
||||
static FLAXENGINE_API const Vector4Base<T> Zero;
|
||||
|
||||
// Vector with all components equal 1
|
||||
static const Vector4 One;
|
||||
static FLAXENGINE_API const Vector4Base<T> One;
|
||||
|
||||
// Vector X=1, Y=0, Z=0, W=0
|
||||
static const Vector4 UnitX;
|
||||
static FLAXENGINE_API const Vector4Base<T> UnitX;
|
||||
|
||||
// Vector X=0, Y=1, Z=0, W=0
|
||||
static const Vector4 UnitY;
|
||||
static FLAXENGINE_API const Vector4Base<T> UnitY;
|
||||
|
||||
// Vector X=0, Y=0, Z=1, W=0
|
||||
static const Vector4 UnitZ;
|
||||
static FLAXENGINE_API const Vector4Base<T> UnitZ;
|
||||
|
||||
// Vector X=0, Y=0, Z=0, W=1
|
||||
static const Vector4 UnitW;
|
||||
static FLAXENGINE_API const Vector4Base<T> UnitW;
|
||||
|
||||
// A minimum Vector4
|
||||
static const Vector4 Minimum;
|
||||
// Vector with all components equal maximum value.
|
||||
static FLAXENGINE_API const Vector4Base<T> Minimum;
|
||||
|
||||
// A maximum Vector4
|
||||
static const Vector4 Maximum;
|
||||
// Vector with all components equal minimum value.
|
||||
static FLAXENGINE_API const Vector4Base<T> Maximum;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor.
|
||||
/// </summary>
|
||||
Vector4()
|
||||
Vector4Base()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xyzw Value to assign to the all components
|
||||
Vector4(float xyzw)
|
||||
FORCE_INLINE Vector4Base(T xyzw)
|
||||
: X(xyzw)
|
||||
, Y(xyzw)
|
||||
, Z(xyzw)
|
||||
@@ -100,16 +88,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param xyzw Values to assign
|
||||
explicit Vector4(float xyzw[4]);
|
||||
FORCE_INLINE explicit Vector4Base(const T* xyzw)
|
||||
: X(xyzw[0])
|
||||
, Y(xyzw[1])
|
||||
, Z(xyzw[2])
|
||||
, W(xyzw[3])
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param x X component value
|
||||
// @param y Y component value
|
||||
// @param z Z component value
|
||||
// @param w W component value
|
||||
Vector4(float x, float y, float z, float w)
|
||||
FORCE_INLINE Vector4Base(T x, T y, T z, T w)
|
||||
: X(x)
|
||||
, Y(y)
|
||||
, Z(z)
|
||||
@@ -117,20 +104,28 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
explicit Vector4(const Vector2& xy, float z, float w);
|
||||
explicit Vector4(const Vector2& xy, const Vector2& zw);
|
||||
explicit Vector4(const Vector3& xyz, float w);
|
||||
explicit Vector4(const Int2& xy, float z, float w);
|
||||
explicit Vector4(const Int3& xyz, float w);
|
||||
explicit Vector4(const Int4& xyzw);
|
||||
explicit Vector4(const Double2& xy, float z, float w);
|
||||
explicit Vector4(const Double3& xyz, float w);
|
||||
Vector4(const Double4& xyzw);
|
||||
explicit Vector4(const Color& color);
|
||||
explicit Vector4(const Rectangle& rect);
|
||||
template<typename U = T, typename TEnableIf<TNot<TIsTheSame<T, U>>::Value>::Type...>
|
||||
FORCE_INLINE explicit Vector4Base(const Vector4Base<U>& xyzw)
|
||||
: X((T)xyzw.X)
|
||||
, Y((T)xyzw.Y)
|
||||
, Z((T)xyzw.Z)
|
||||
, W((T)xyzw.W)
|
||||
{
|
||||
}
|
||||
|
||||
FLAXENGINE_API explicit Vector4Base(const Float2& xy, T z = 0, T w = 0);
|
||||
FLAXENGINE_API explicit Vector4Base(const Float2& xy, const Float2& zw);
|
||||
FLAXENGINE_API explicit Vector4Base(const Float3& xyz, T w = 0);
|
||||
FLAXENGINE_API explicit Vector4Base(const Int2& xy, T z = 0, T w = 0);
|
||||
FLAXENGINE_API explicit Vector4Base(const Int3& xyz, T w = 0);
|
||||
FLAXENGINE_API explicit Vector4Base(const Double2& xy, T z = 0, T w = 0);
|
||||
FLAXENGINE_API explicit Vector4Base(const Double2& xy, const Double2& zw);
|
||||
FLAXENGINE_API explicit Vector4Base(const Double3& xyz, T w = 0);
|
||||
FLAXENGINE_API explicit Vector4Base(const Color& color);
|
||||
FLAXENGINE_API explicit Vector4Base(const Rectangle& rect);
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
FLAXENGINE_API String ToString() const;
|
||||
|
||||
public:
|
||||
// Gets a value indicting whether this vector is zero.
|
||||
@@ -151,26 +146,10 @@ public:
|
||||
return Math::IsOne(X) && Math::IsOne(Y) && Math::IsOne(Z) && Math::IsOne(W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being absolute values of that vector.
|
||||
/// </summary>
|
||||
Vector4 GetAbsolute() const
|
||||
{
|
||||
return Vector4(Math::Abs(X), Math::Abs(Y), Math::Abs(Z), Math::Abs(W));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being opposite to values of that vector.
|
||||
/// </summary>
|
||||
Vector4 GetNegative() const
|
||||
{
|
||||
return Vector4(-X, -Y, -Z, -W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the average arithmetic of all the components.
|
||||
/// </summary>
|
||||
float AverageArithmetic() const
|
||||
T AverageArithmetic() const
|
||||
{
|
||||
return (X + Y + Z + W) * 0.25f;
|
||||
}
|
||||
@@ -178,7 +157,7 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the sum of all vector components values.
|
||||
/// </summary>
|
||||
float SumValues() const
|
||||
T SumValues() const
|
||||
{
|
||||
return X + Y + Z + W;
|
||||
}
|
||||
@@ -186,7 +165,7 @@ public:
|
||||
/// <summary>
|
||||
/// Returns the minimum value of all the components.
|
||||
/// </summary>
|
||||
float MinValue() const
|
||||
T MinValue() const
|
||||
{
|
||||
return Math::Min(X, Y, Z, W);
|
||||
}
|
||||
@@ -194,7 +173,7 @@ public:
|
||||
/// <summary>
|
||||
/// Returns the maximum value of all the components.
|
||||
/// </summary>
|
||||
float MaxValue() const
|
||||
T MaxValue() const
|
||||
{
|
||||
return Math::Max(X, Y, Z, W);
|
||||
}
|
||||
@@ -223,218 +202,257 @@ public:
|
||||
return IsInfinity() || IsNaN();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being absolute values of that vector.
|
||||
/// </summary>
|
||||
Vector4Base GetAbsolute() const
|
||||
{
|
||||
return Vector4Base(Math::Abs(X), Math::Abs(Y), Math::Abs(Z), Math::Abs(W));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a vector with values being opposite to values of that vector.
|
||||
/// </summary>
|
||||
Vector4Base GetNegative() const
|
||||
{
|
||||
return Vector4Base(-X, -Y, -Z, -W);
|
||||
}
|
||||
|
||||
public:
|
||||
// Arithmetic operators with Vector4
|
||||
inline Vector4 operator+(const Vector4& b) const
|
||||
Vector4Base operator+(const Vector4Base& b) const
|
||||
{
|
||||
return Add(*this, b);
|
||||
return Vector4Base(X + b.X, Y + b.Y, Z + b.Z, W + b.W);
|
||||
}
|
||||
|
||||
inline Vector4 operator-(const Vector4& b) const
|
||||
Vector4Base operator-(const Vector4Base& b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
return Vector4Base(X - b.X, Y - b.Y, Z - b.Z, W - b.W);
|
||||
}
|
||||
|
||||
inline Vector4 operator*(const Vector4& b) const
|
||||
Vector4Base operator*(const Vector4Base& b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
return Vector4Base(X * b.X, Y * b.Y, Z * b.Z, W * b.W);
|
||||
}
|
||||
|
||||
inline Vector4 operator/(const Vector4& b) const
|
||||
Vector4Base operator/(const Vector4Base& b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
return Vector4Base(X / b.X, Y / b.Y, Z / b.Z, W / b.W);
|
||||
}
|
||||
|
||||
// op= operators with Vector4
|
||||
inline Vector4& operator+=(const Vector4& b)
|
||||
Vector4Base operator-() const
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
return Vector4Base(-X, -Y, -Z, -W);
|
||||
}
|
||||
|
||||
Vector4Base operator+(T b) const
|
||||
{
|
||||
return Vector4Base(X + b, Y + b, Z + b, W + b);
|
||||
}
|
||||
|
||||
Vector4Base operator-(T b) const
|
||||
{
|
||||
return Vector4Base(X - b, Y - b, Z - b, W - b);
|
||||
}
|
||||
|
||||
Vector4Base operator*(T b) const
|
||||
{
|
||||
return Vector4Base(X * b, Y * b, Z * b, W * b);
|
||||
}
|
||||
|
||||
Vector4Base operator/(T b) const
|
||||
{
|
||||
return Vector4Base(X / b, Y / b, Z / b, W / b);
|
||||
}
|
||||
|
||||
Vector4Base& operator+=(const Vector4Base& b)
|
||||
{
|
||||
X += b.X;
|
||||
Y += b.Y;
|
||||
Z += b.Z;
|
||||
W += b.W;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4& operator-=(const Vector4& b)
|
||||
Vector4Base& operator-=(const Vector4Base& b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
X -= b.X;
|
||||
Y -= b.Y;
|
||||
Z -= b.Z;
|
||||
W -= b.W;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4& operator*=(const Vector4& b)
|
||||
Vector4Base& operator*=(const Vector4Base& b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
X *= b.X;
|
||||
Y *= b.Y;
|
||||
Z *= b.Z;
|
||||
W *= b.W;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4& operator/=(const Vector4& b)
|
||||
Vector4Base& operator/=(const Vector4Base& b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
X /= b.X;
|
||||
Y /= b.Y;
|
||||
Z /= b.Z;
|
||||
W /= b.W;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Arithmetic operators with float
|
||||
inline Vector4 operator+(float b) const
|
||||
Vector4Base& operator+=(T b)
|
||||
{
|
||||
return Add(*this, b);
|
||||
}
|
||||
|
||||
inline Vector4 operator-(float b) const
|
||||
{
|
||||
return Subtract(*this, b);
|
||||
}
|
||||
|
||||
inline Vector4 operator*(float b) const
|
||||
{
|
||||
return Multiply(*this, b);
|
||||
}
|
||||
|
||||
inline Vector4 operator/(float b) const
|
||||
{
|
||||
return Divide(*this, b);
|
||||
}
|
||||
|
||||
// op= operators with float
|
||||
inline Vector4& operator+=(float b)
|
||||
{
|
||||
*this = Add(*this, b);
|
||||
X += b;
|
||||
Y += b;
|
||||
Z += b;
|
||||
W += b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4& operator-=(float b)
|
||||
Vector4Base& operator-=(T b)
|
||||
{
|
||||
*this = Subtract(*this, b);
|
||||
X -= b;
|
||||
Y -= b;
|
||||
Z -= b;
|
||||
W -= b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4& operator*=(float b)
|
||||
Vector4Base& operator*=(T b)
|
||||
{
|
||||
*this = Multiply(*this, b);
|
||||
X *= b;
|
||||
Y *= b;
|
||||
Z *= b;
|
||||
W *= b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4& operator/=(float b)
|
||||
Vector4Base& operator/=(T b)
|
||||
{
|
||||
*this = Divide(*this, b);
|
||||
X /= b;
|
||||
Y /= b;
|
||||
Z /= b;
|
||||
W /= b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison
|
||||
inline bool operator==(const Vector4& b) const
|
||||
bool operator==(const Vector4Base& b) const
|
||||
{
|
||||
return X == b.X && Y == b.Y && Z == b.Z && W == b.W;
|
||||
}
|
||||
|
||||
inline bool operator!=(const Vector4& b) const
|
||||
bool operator!=(const Vector4Base& b) const
|
||||
{
|
||||
return X != b.X || Y != b.Y || Z != b.Z || W != b.W;
|
||||
}
|
||||
|
||||
inline bool operator>(const Vector4& b) const
|
||||
bool operator>(const Vector4Base& b) const
|
||||
{
|
||||
return X > b.X && Y > b.Y && Z > b.Z && W > b.W;
|
||||
}
|
||||
|
||||
inline bool operator>=(const Vector4& b) const
|
||||
bool operator>=(const Vector4Base& b) const
|
||||
{
|
||||
return X >= b.X && Y >= b.Y && Z >= b.Z && W >= b.W;
|
||||
}
|
||||
|
||||
inline bool operator<(const Vector4& b) const
|
||||
bool operator<(const Vector4Base& b) const
|
||||
{
|
||||
return X < b.X && Y < b.Y && Z < b.Z && W < b.W;
|
||||
}
|
||||
|
||||
inline bool operator<=(const Vector4& b) const
|
||||
bool operator<=(const Vector4Base& b) const
|
||||
{
|
||||
return X <= b.X && Y <= b.Y && Z <= b.Z && W <= b.W;
|
||||
}
|
||||
|
||||
public:
|
||||
static bool NearEqual(const Vector4& a, const Vector4& b)
|
||||
static bool NearEqual(const Vector4Base& a, const Vector4Base& b)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X) && Math::NearEqual(a.Y, b.Y) && Math::NearEqual(a.Z, b.Z) && Math::NearEqual(a.W, b.W);
|
||||
}
|
||||
|
||||
static bool NearEqual(const Vector4& a, const Vector4& b, float epsilon)
|
||||
static bool NearEqual(const Vector4Base& a, const Vector4Base& b, T epsilon)
|
||||
{
|
||||
return Math::NearEqual(a.X, b.X, epsilon) && Math::NearEqual(a.Y, b.Y, epsilon) && Math::NearEqual(a.Z, b.Z, epsilon) && Math::NearEqual(a.W, b.W, epsilon);
|
||||
}
|
||||
|
||||
public:
|
||||
static void Add(const Vector4& a, const Vector4& b, Vector4& result)
|
||||
static void Add(const Vector4Base& a, const Vector4Base& b, Vector4Base& result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
result.Z = a.Z + b.Z;
|
||||
result.W = a.W + b.W;
|
||||
result = Vector4Base(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W);
|
||||
}
|
||||
|
||||
static Vector4 Add(const Vector4& a, const Vector4& b)
|
||||
static void Subtract(const Vector4Base& a, const Vector4Base& b, Vector4Base& result)
|
||||
{
|
||||
Vector4 result;
|
||||
Add(a, b, result);
|
||||
return result;
|
||||
result = Vector4Base(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W);
|
||||
}
|
||||
|
||||
static void Subtract(const Vector4& a, const Vector4& b, Vector4& result)
|
||||
static void Multiply(const Vector4Base& a, const Vector4Base& b, Vector4Base& result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
result.Z = a.Z - b.Z;
|
||||
result.W = a.W - b.W;
|
||||
result = Vector4Base(a.X * b, a.Y * b, a.Z * b, a.W * b);
|
||||
}
|
||||
|
||||
static Vector4 Subtract(const Vector4& a, const Vector4& b)
|
||||
static void Divide(const Vector4Base& a, const Vector4Base& b, Vector4Base& result)
|
||||
{
|
||||
Vector4 result;
|
||||
Subtract(a, b, result);
|
||||
return result;
|
||||
result = Vector4Base(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W);
|
||||
}
|
||||
|
||||
static Vector4 Multiply(const Vector4& a, const Vector4& b)
|
||||
public:
|
||||
static Vector4Base Floor(const Vector4Base& v)
|
||||
{
|
||||
return Vector4(a.X * b.X, a.Y * b.Y, a.Z * b.Z, a.W * b.W);
|
||||
return Vector4Base(Math::Floor(v.X), Math::Floor(v.Y), Math::Floor(v.Z), Math::Floor(v.W));
|
||||
}
|
||||
|
||||
static Vector4 Multiply(const Vector4& a, float b)
|
||||
static Vector4Base Frac(const Vector4Base& v)
|
||||
{
|
||||
return Vector4(a.X * b, a.Y * b, a.Z * b, a.W * b);
|
||||
return Vector4Base(v.X - (int32)v.X, v.Y - (int32)v.Y, v.Z - (int32)v.Z, v.W - (int32)v.W);
|
||||
}
|
||||
|
||||
static Vector4 Divide(const Vector4& a, const Vector4& b)
|
||||
static Vector4Base Round(const Vector4Base& v)
|
||||
{
|
||||
return Vector4(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W);
|
||||
return Vector4Base(Math::Round(v.X), Math::Round(v.Y), Math::Round(v.Z), Math::Round(v.W));
|
||||
}
|
||||
|
||||
static Vector4 Divide(const Vector4& a, float b)
|
||||
static Vector4Base Ceil(const Vector4Base& v)
|
||||
{
|
||||
return Vector4(a.X / b, a.Y / b, a.Z / b, a.W / b);
|
||||
return Vector4Base(Math::Ceil(v.X), Math::Ceil(v.Y), Math::Ceil(v.Z), Math::Ceil(v.W));
|
||||
}
|
||||
|
||||
static Vector4 Floor(const Vector4& v);
|
||||
static Vector4 Frac(const Vector4& v);
|
||||
static Vector4 Round(const Vector4& v);
|
||||
static Vector4 Ceil(const Vector4& v);
|
||||
static Vector4Base Abs(const Vector4Base& v)
|
||||
{
|
||||
return Vector4Base(Math::Abs(v.X), Math::Abs(v.Y), Math::Abs(v.Z), Math::Abs(v.W));
|
||||
}
|
||||
|
||||
public:
|
||||
// Restricts a value to be within a specified range
|
||||
// @param value The value to clamp
|
||||
// @param v The value to clamp
|
||||
// @param min The minimum value,
|
||||
// @param max The maximum value
|
||||
// @returns Clamped value
|
||||
static Vector4 Clamp(const Vector4& value, const Vector4& min, const Vector4& max);
|
||||
static Vector4Base Clamp(const Vector4Base& v, const Vector4Base& min, const Vector4Base& max)
|
||||
{
|
||||
Vector4Base result;
|
||||
Clamp(v, min, max, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Restricts a value to be within a specified range
|
||||
// @param value The value to clamp
|
||||
// @param v The value to clamp
|
||||
// @param min The minimum value,
|
||||
// @param max The maximum value
|
||||
// @param result When the method completes, contains the clamped value
|
||||
static void Clamp(const Vector4& value, const Vector4& min, const Vector4& max, Vector4& result);
|
||||
static void Clamp(const Vector4Base& v, const Vector4Base& min, const Vector4Base& max, Vector4Base& result)
|
||||
{
|
||||
result = Vector4Base(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y), Math::Clamp(v.Z, min.Z, max.Z), Math::Clamp(v.W, min.W, max.W));
|
||||
}
|
||||
|
||||
// Performs a linear interpolation between two vectors
|
||||
// @param start Start vector
|
||||
// @param end End vector
|
||||
// @param amount Value between 0 and 1 indicating the weight of end
|
||||
// @param result When the method completes, contains the linear interpolation of the two vectors
|
||||
static void Lerp(const Vector4& start, const Vector4& end, float amount, Vector4& result)
|
||||
static void Lerp(const Vector4Base& start, const Vector4Base& end, T amount, Vector4Base& result)
|
||||
{
|
||||
result.X = Math::Lerp(start.X, end.X, amount);
|
||||
result.Y = Math::Lerp(start.Y, end.Y, amount);
|
||||
@@ -449,48 +467,69 @@ public:
|
||||
// @param end End vector,
|
||||
// @param amount Value between 0 and 1 indicating the weight of @paramref end"/>,
|
||||
// @returns The linear interpolation of the two vectors
|
||||
static Vector4 Lerp(const Vector4& start, const Vector4& end, float amount)
|
||||
static Vector4Base Lerp(const Vector4Base& start, const Vector4Base& end, T amount)
|
||||
{
|
||||
Vector4 result;
|
||||
Vector4Base result;
|
||||
Lerp(start, end, amount, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Vector4 Transform(const Vector4& v, const Matrix& m);
|
||||
FLAXENGINE_API static Vector4Base Transform(const Vector4Base& v, const Matrix& m);
|
||||
};
|
||||
|
||||
inline Vector4 operator+(float a, const Vector4& b)
|
||||
template<typename T>
|
||||
inline Vector4Base<T> operator+(T a, const Vector4Base<T>& b)
|
||||
{
|
||||
return b + a;
|
||||
}
|
||||
|
||||
inline Vector4 operator-(float a, const Vector4& b)
|
||||
template<typename T>
|
||||
inline Vector4Base<T> operator-(T a, const Vector4Base<T>& b)
|
||||
{
|
||||
return Vector4(a) - b;
|
||||
return Vector4Base<T>(a) - b;
|
||||
}
|
||||
|
||||
inline Vector4 operator*(float a, const Vector4& b)
|
||||
template<typename T>
|
||||
inline Vector4Base<T> operator*(T a, const Vector4Base<T>& b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline Vector4 operator/(float a, const Vector4& b)
|
||||
template<typename T>
|
||||
inline Vector4Base<T> operator/(T a, const Vector4Base<T>& b)
|
||||
{
|
||||
return Vector4(a) / b;
|
||||
return Vector4Base<T>(a) / b;
|
||||
}
|
||||
|
||||
namespace Math
|
||||
{
|
||||
FORCE_INLINE static bool NearEqual(const Vector4& a, const Vector4& b)
|
||||
template<typename T>
|
||||
FORCE_INLINE static bool NearEqual(const Vector4Base<T>& a, const Vector4Base<T>& b)
|
||||
{
|
||||
return Vector4::NearEqual(a, b);
|
||||
return Vector4Base<T>::NearEqual(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Vector4>
|
||||
struct TIsPODType<Float4>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Vector4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W);
|
||||
DEFINE_DEFAULT_FORMATTING(Float4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W);
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Double4>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Double4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W);
|
||||
|
||||
template<>
|
||||
struct TIsPODType<Int4>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING(Int4, "X:{0} Y:{1} Z:{2} W:{3}", v.X, v.Y, v.Z, v.W);
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "Vector2.h"
|
||||
|
||||
struct Vector3;
|
||||
struct Matrix;
|
||||
struct Rectangle;
|
||||
|
||||
|
||||
@@ -69,25 +69,6 @@ class StringAnsiView;
|
||||
struct Guid;
|
||||
struct DateTime;
|
||||
struct TimeSpan;
|
||||
struct Vector2;
|
||||
struct Vector3;
|
||||
struct Vector4;
|
||||
struct Double2;
|
||||
struct Double3;
|
||||
struct Double4;
|
||||
struct Int2;
|
||||
struct Int3;
|
||||
struct Int4;
|
||||
struct Quaternion;
|
||||
struct Matrix;
|
||||
struct Ray;
|
||||
struct Rectangle;
|
||||
struct Plane;
|
||||
struct BoundingBox;
|
||||
struct BoundingSphere;
|
||||
struct BoundingFrustum;
|
||||
struct Color;
|
||||
struct Color32;
|
||||
struct Variant;
|
||||
template<typename T>
|
||||
class Span;
|
||||
@@ -107,6 +88,55 @@ class Function;
|
||||
template<typename... Params>
|
||||
class Delegate;
|
||||
|
||||
// @formatter:off
|
||||
|
||||
// TODO: move it to Engine configuration
|
||||
#define USE_LARGE_WORLDS 0
|
||||
|
||||
#if USE_LARGE_WORLDS
|
||||
// 64-bit precision for world coordinates
|
||||
API_TYPEDEF(Alias) typedef double Real;
|
||||
#else
|
||||
// 32-bit precision for world coordinates
|
||||
API_TYPEDEF(Alias) typedef float Real;
|
||||
#endif
|
||||
|
||||
// Vector2
|
||||
template<typename T> struct Vector2Base;
|
||||
API_TYPEDEF() typedef Vector2Base<float> Float2;
|
||||
API_TYPEDEF() typedef Vector2Base<double> Double2;
|
||||
API_TYPEDEF() typedef Vector2Base<int32> Int2;
|
||||
API_TYPEDEF(Alias) typedef Vector2Base<Real> Vector2;
|
||||
|
||||
// Vector3
|
||||
template<typename T> struct Vector3Base;
|
||||
API_TYPEDEF() typedef Vector3Base<float> Float3;
|
||||
API_TYPEDEF() typedef Vector3Base<double> Double3;
|
||||
API_TYPEDEF() typedef Vector3Base<int32> Int3;
|
||||
API_TYPEDEF(Alias) typedef Vector3Base<Real> Vector3;
|
||||
|
||||
// Vector4
|
||||
template<typename T> struct Vector4Base;
|
||||
API_TYPEDEF() typedef Vector4Base<float> Float4;
|
||||
API_TYPEDEF() typedef Vector4Base<double> Double4;
|
||||
API_TYPEDEF() typedef Vector4Base<int32> Int4;
|
||||
API_TYPEDEF(Alias) typedef Vector4Base<Real> Vector4;
|
||||
|
||||
struct BoundingBox;
|
||||
struct Matrix;
|
||||
struct Matrix3x3;
|
||||
struct Ray;
|
||||
struct Plane;
|
||||
struct Rectangle;
|
||||
struct Quaternion;
|
||||
struct BoundingSphere;
|
||||
struct BoundingFrustum;
|
||||
struct OrientedBoundingBox;
|
||||
struct Color;
|
||||
struct Color32;
|
||||
|
||||
// @formatter:on
|
||||
|
||||
// Declares full set of operators for the enum type (using binary operation on integer values)
|
||||
#define DECLARE_ENUM_OPERATORS(T) \
|
||||
inline T operator~ (T a) { return (T)~(int)a; } \
|
||||
|
||||
@@ -1555,7 +1555,7 @@ void DebugDraw::DrawArc(const Vector3& position, const Quaternion& orientation,
|
||||
t.Color = Color32(color);
|
||||
t.TimeLeft = duration;
|
||||
t.V0 = world.GetTranslation();
|
||||
Vector3 pos(Math::Cos(0) * radius, Math::Sin(0) * radius, 0);
|
||||
Vector3 pos(Math::Cos(0.0f) * radius, Math::Sin(0.0f) * radius, 0);
|
||||
Vector3::Transform(pos, world, t.V2);
|
||||
for (int32 i = 0; i < resolution; i++)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "Engine/Core/Types/Span.h"
|
||||
|
||||
struct RenderContext;
|
||||
struct OrientedBoundingBox;
|
||||
class GPUTextureView;
|
||||
class GPUContext;
|
||||
class RenderTask;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "Engine/Input/Enums.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
|
||||
/// <summary>
|
||||
/// Helper class to access display information.
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "PixelFormat.h"
|
||||
#include "Config.h"
|
||||
|
||||
struct Color;
|
||||
struct Vector4;
|
||||
class GPUConstantBuffer;
|
||||
class GPUShaderProgramCS;
|
||||
class GPUBuffer;
|
||||
|
||||
@@ -84,8 +84,8 @@ void BoxVolume::OnDebugDrawSelected()
|
||||
for (int32 i = 0; i < 6; i++)
|
||||
{
|
||||
sideLinksFinal[i] = sideLinks[i] * _size;
|
||||
_transform.LocalToWorld(sideLinksFinal[i], sideLinksFinal[i]);
|
||||
}
|
||||
_transform.LocalToWorld(sideLinksFinal, 6, sideLinksFinal);
|
||||
for (int32 i = 0; i < 6; i++)
|
||||
{
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(sideLinksFinal[i], 10.0f), Color::YellowGreen, 0, true);
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#if COMPILE_WITH_NAV_MESH_BUILDER
|
||||
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
|
||||
class Scene;
|
||||
|
||||
/// <summary>
|
||||
@@ -18,7 +20,7 @@ public:
|
||||
static float GetNavMeshBuildingProgress();
|
||||
static void Update();
|
||||
static void Build(Scene* scene, float timeoutMs);
|
||||
static void Build(Scene* scene, const struct BoundingBox& dirtyBounds, float timeoutMs);
|
||||
static void Build(Scene* scene, const BoundingBox& dirtyBounds, float timeoutMs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -136,8 +136,7 @@ void BoxCollider::UpdateBounds()
|
||||
void BoxCollider::GetGeometry(CollisionShape& collision)
|
||||
{
|
||||
Vector3 size = _size * _cachedScale;
|
||||
size.Absolute();
|
||||
const float minSize = 0.001f;
|
||||
size = Vector3::Max(size * 0.5f, Vector3(minSize));
|
||||
size = Vector3::Max(size.GetAbsolute() * 0.5f, Vector3(minSize));
|
||||
collision.SetBox(size.Raw);
|
||||
}
|
||||
|
||||
@@ -150,9 +150,8 @@ void MeshCollider::GetGeometry(CollisionShape& collision)
|
||||
{
|
||||
// Prepare scale
|
||||
Vector3 scale = _cachedScale;
|
||||
scale.Absolute();
|
||||
const float minSize = 0.001f;
|
||||
scale = Vector3::Max(scale, minSize);
|
||||
scale = Vector3::Max(scale.GetNegative(), minSize);
|
||||
|
||||
// Setup shape (based on type)
|
||||
CollisionDataType type = CollisionDataType::None;
|
||||
|
||||
@@ -280,8 +280,7 @@ void SplineCollider::GetGeometry(CollisionShape& collision)
|
||||
|
||||
// Prepare scale
|
||||
Vector3 scale = _cachedScale;
|
||||
scale.Absolute();
|
||||
scale = Vector3::Max(scale, minSize);
|
||||
scale = Vector3::Max(scale.GetAbsolute(), minSize);
|
||||
|
||||
// TODO: add support for cooking collision for static splines in editor and reusing it in game
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include "Engine/Platform/Types.h"
|
||||
#include "../Win32/WindowsMinimal.h"
|
||||
|
||||
struct Vector2;
|
||||
|
||||
/// <summary>
|
||||
/// Windows platform specific implementation of the input system parts. Handles XInput devices.
|
||||
/// </summary>
|
||||
|
||||
@@ -883,8 +883,7 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
|
||||
// Calculate optimal tile resolution for the object side
|
||||
Vector3 boundsSizeTile = boundsSize;
|
||||
boundsSizeTile.Raw[tileIndex / 2] = MAX_float; // Ignore depth size
|
||||
boundsSizeTile.Absolute();
|
||||
uint16 tileResolution = (uint16)(boundsSizeTile.MinValue() * tilesScale);
|
||||
uint16 tileResolution = (uint16)(boundsSizeTile.GetAbsolute().MinValue() * tilesScale);
|
||||
if (tileResolution < 4)
|
||||
{
|
||||
// Skip too small surfaces
|
||||
|
||||
@@ -387,7 +387,8 @@ RenderList::RenderList(const SpawnParams& params)
|
||||
void RenderList::Init(RenderContext& renderContext)
|
||||
{
|
||||
renderContext.View.Frustum.GetCorners(FrustumCornersWs);
|
||||
Vector3::Transform(FrustumCornersWs, renderContext.View.View, FrustumCornersVs, 8);
|
||||
for (int32 i = 0; i < 8; i++)
|
||||
Vector3::Transform(FrustumCornersWs[i], renderContext.View.View, FrustumCornersVs[i]);
|
||||
}
|
||||
|
||||
void RenderList::Clear()
|
||||
|
||||
@@ -629,8 +629,8 @@ bool ModifyCollision(const TerrainDataUpdateInfo& info, TextureBase::InitData* i
|
||||
const int32 collisionLOD = Math::Clamp<int32>(collisionLod, 0, initData->Mips.Count() - 1);
|
||||
const int32 heightFieldChunkSize = ((info.ChunkSize + 1) >> collisionLOD) - 1;
|
||||
const int32 heightFieldSize = heightFieldChunkSize * TerrainPatch::CHUNKS_COUNT_EDGE + 1;
|
||||
const Int2 samplesOffset = Vector2::FloorToInt(modifiedOffsetRatio * (float)heightFieldSize);
|
||||
Int2 samplesSize = Vector2::CeilToInt(modifiedSizeRatio * (float)heightFieldSize);
|
||||
const Int2 samplesOffset(Vector2::Floor(modifiedOffsetRatio * (float)heightFieldSize));
|
||||
Int2 samplesSize(Vector2::Ceil(modifiedSizeRatio * (float)heightFieldSize));
|
||||
samplesSize.X = Math::Max(samplesSize.X, 1);
|
||||
samplesSize.Y = Math::Max(samplesSize.Y, 1);
|
||||
Int2 samplesEnd = samplesOffset + samplesSize;
|
||||
|
||||
@@ -107,7 +107,8 @@ TEST_CASE("Transform")
|
||||
|
||||
Vector3 a4T[1];
|
||||
Vector3 a4Ta[1] = { t2.Translation };
|
||||
t1.LocalToWorld(a4Ta, ARRAY_COUNT(a4Ta), a4T);
|
||||
for (int32 i = 0; i < ARRAY_COUNT(a4Ta); i++)
|
||||
a4T[i] = t1.LocalToWorld(a4Ta[i]);
|
||||
Vector3 a4 = a4T[0];
|
||||
|
||||
CHECK(Vector3::NearEqual(a1.Translation, a2));
|
||||
@@ -135,7 +136,8 @@ TEST_CASE("Transform")
|
||||
|
||||
Vector3 a4T[1];
|
||||
Vector3 a4Ta[1] = { t2.Translation };
|
||||
t1.WorldToLocal(a4Ta, ARRAY_COUNT(a4Ta), a4T);
|
||||
for (int32 i = 0; i < ARRAY_COUNT(a4Ta); i++)
|
||||
a4T[i] = t1.WorldToLocal(a4Ta[i]);
|
||||
Vector3 a4 = a4T[0];
|
||||
|
||||
CHECK(Vector3::NearEqual(a1.Translation, a2));
|
||||
|
||||
@@ -223,7 +223,7 @@ public:
|
||||
// Transform
|
||||
float Scale = 1.0f;
|
||||
Quaternion Rotation = Quaternion::Identity;
|
||||
Vector3 Translation = Vector3::Zero;
|
||||
Float3 Translation = Float3::Zero;
|
||||
bool CenterGeometry = false;
|
||||
|
||||
// Animation
|
||||
|
||||
@@ -338,13 +338,13 @@ void VisjectExecutor::ProcessGroupMath(Box* box, Node* node, Value& value)
|
||||
switch (v1.Type.Type)
|
||||
{
|
||||
case VariantType::Vector2:
|
||||
value = v1.AsVector2() - 2 * v2.AsVector2() * Vector2::Dot(v1.AsVector2(), v2.AsVector2());
|
||||
value = v1.AsVector2() - 2.0f * v2.AsVector2() * Vector2::Dot(v1.AsVector2(), v2.AsVector2());
|
||||
break;
|
||||
case VariantType::Vector3:
|
||||
value = v1.AsVector3() - 2 * v2.AsVector3() * Vector3::Dot(v1.AsVector3(), v2.AsVector3());
|
||||
value = v1.AsVector3() - 2.0f * v2.AsVector3() * Vector3::Dot(v1.AsVector3(), v2.AsVector3());
|
||||
break;
|
||||
case VariantType::Vector4:
|
||||
value = Vector4(v1.AsVector4() - 2 * v2.AsVector4() * Vector3::Dot((Vector3)v1, (Vector3)v2));
|
||||
value = Vector4(v1.AsVector4() - 2.0f * v2.AsVector4() * Vector3::Dot((Vector3)v1, (Vector3)v2));
|
||||
break;
|
||||
default: CRASH;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user