* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef API_BASE_MATH_VECTOR_H
#define API_BASE_MATH_VECTOR_H
#include <cstddef>
#include <cstdint>
#if defined(BASE_SIMD) && defined(_M_X64)
#include <immintrin.h>
#elif defined(_M_ARM64) || defined(__ARM_ARCH_ISA_A64)
#include <arm_neon.h>
#endif
#include <base/math/mathf.h>
#include <base/namespace.h>
BASE_BEGIN_NAMESPACE()
namespace Math {
#include <base/math/disable_warning_4201_heading.h>
class Vec2;
class Vec3;
class Vec4;
class Vec2 final {
public:
union {
struct {
float x;
float y;
};
float data[2];
};
constexpr float& operator[](size_t index)
{
return data[index];
}
constexpr const float& operator[](size_t index) const
{
return data[index];
}
inline constexpr Vec2() noexcept : data{}
{}
* from float to vector. For example Normalize(1.0f) would be illegal. */
inline constexpr explicit Vec2(float value) noexcept : x(value), y(value)
{}
inline constexpr Vec2(float xParameter, float yParameter) noexcept : x(xParameter), y(yParameter)
{}
inline constexpr Vec2(const float parameter[2]) noexcept : x(parameter[0]), y(parameter[1])
{}
inline constexpr Vec2 operator+(const Vec2& v2) const
{
return Vec2(x + v2.x, y + v2.y);
}
inline constexpr Vec2& operator+=(const Vec2& rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
inline constexpr Vec2 operator-() const
{
return Vec2(-x, -y);
}
inline constexpr Vec2 operator-(const Vec2& v2) const
{
return Vec2(x - v2.x, y - v2.y);
}
inline constexpr Vec2& operator-=(const Vec2& rhs)
{
x -= rhs.x;
y -= rhs.y;
return *this;
}
inline constexpr Vec2 operator*(const Vec2& v2) const
{
return Vec2(x * v2.x, y * v2.y);
}
inline constexpr Vec2& operator*=(const Vec2& rhs)
{
x *= rhs.x;
y *= rhs.y;
return *this;
}
inline constexpr Vec2 operator/(const Vec2& v2) const
{
return Vec2(x / v2.x, y / v2.y);
}
inline constexpr Vec2& operator/=(const Vec2& rhs)
{
x /= rhs.x;
y /= rhs.y;
return *this;
}
inline constexpr Vec2 operator*(float d) const
{
return Vec2(x * d, y * d);
}
friend inline constexpr Vec2 operator*(float d, const Vec2& v2)
{
return v2 * d;
}
inline constexpr Vec2& operator*=(float d)
{
x *= d;
y *= d;
return *this;
}
inline constexpr Vec2 operator/(float d) const
{
return Vec2(x / d, y / d);
}
inline constexpr Vec2& operator/=(float d)
{
x /= d;
y /= d;
return *this;
}
inline constexpr Vec2 operator+(float d) const
{
return Vec2(x + d, y + d);
}
inline constexpr Vec2& operator+=(float d)
{
x += d;
y += d;
return *this;
}
inline constexpr Vec2 operator-(float d) const
{
return Vec2(x - d, y - d);
}
inline constexpr Vec2& operator-=(float d)
{
x -= d;
y -= d;
return *this;
}
constexpr bool operator==(const Vec2& rhs) const
{
const Vec2 temp = *this - rhs;
const float sqmgt = temp.x * temp.x + temp.y * temp.y;
return sqmgt < Math::EPSILON * Math::EPSILON;
}
constexpr bool operator!=(const Vec2& rhs) const
{
return !(*this == rhs);
}
};
static_assert(sizeof(Vec2) == 2 * sizeof(float));
static constexpr Vec2 ZERO_VEC2(0.0f, 0.0f);
class Vec3 final {
public:
union {
struct {
float x;
float y;
float z;
};
float data[3];
};
constexpr float& operator[](size_t index);
constexpr const float& operator[](size_t index) const;
inline constexpr Vec3() noexcept;
* from float to vector. For example Normalize(1.0f) would be illegal. */
inline constexpr explicit Vec3(float value) noexcept;
inline constexpr Vec3(float xParameter, float yParameter, float zParameter) noexcept;
inline constexpr Vec3(const float d[]) noexcept;
inline constexpr Vec3(const Vec2& vec, float zParameter) noexcept;
inline constexpr Vec3(const Vec4& vec) noexcept;
inline constexpr Vec3 operator+(const Vec3& v2) const;
inline constexpr Vec3& operator+=(const Vec3& rhs);
inline constexpr Vec3 operator-() const;
inline constexpr Vec3 operator-(const Vec3& v2) const;
inline constexpr Vec3& operator-=(const Vec3& rhs);
inline constexpr Vec3 operator*(const Vec3& v2) const;
inline constexpr Vec3& operator*=(const Vec3& rhs);
inline constexpr Vec3 operator/(const Vec3& v2) const;
inline constexpr Vec3& operator/=(const Vec3& rhs);
constexpr bool operator==(const Vec3& rhs) const;
constexpr bool operator!=(const Vec3& rhs) const;
inline constexpr Vec3 operator+(float d) const;
inline constexpr Vec3& operator+=(float d);
inline constexpr Vec3 operator-(float d) const;
inline constexpr Vec3& operator-=(float d);
inline constexpr Vec3 operator*(float d) const;
friend inline constexpr Vec3 operator*(float d, const Vec3& v2);
inline constexpr Vec3& operator*=(float d);
inline constexpr Vec3 operator/(float d) const;
inline constexpr Vec3& operator/=(float d);
};
static_assert(sizeof(Vec3) == 3 * sizeof(float));
class Vec4 final {
public:
union {
struct {
float x;
float y;
float z;
float w;
};
float data[4];
#if defined(BASE_SIMD) && defined(_M_X64)
__m128 vec4;
#elif defined(_M_ARM64) || defined(__ARM_ARCH_ISA_A64)
float32x4_t vec4;
#endif
};
constexpr float& operator[](size_t index);
constexpr const float& operator[](size_t index) const;
inline constexpr Vec4() noexcept;
* from float to vector. For example Normalize(1.0f) would be illegal. */
inline constexpr explicit Vec4(float value) noexcept;
inline constexpr Vec4(float xParameter, float yParameter, float zParameter, float wParameter) noexcept;
inline constexpr Vec4(const float d[4]) noexcept;
inline constexpr Vec4(const Vec2& vec, float zParameter, float wParameter) noexcept;
inline constexpr Vec4(const Vec3& vec, float w) noexcept;
inline constexpr Vec4 operator+(const Vec4& v2) const;
inline constexpr Vec4& operator+=(const Vec4& rhs);
inline constexpr Vec4 operator-() const;
inline constexpr Vec4 operator-(const Vec4& v2) const;
inline constexpr Vec4& operator-=(const Vec4& rhs);
inline constexpr Vec4 operator*(const Vec4& v2) const;
inline constexpr Vec4& operator*=(const Vec4& rhs);
inline constexpr Vec4 operator/(const Vec4& v2) const;
inline constexpr Vec4& operator/=(const Vec4& rhs);
inline constexpr Vec4 operator+(float d) const;
inline constexpr Vec4& operator+=(float d);
inline constexpr Vec4 operator-(float d) const;
inline constexpr Vec4& operator-=(float d);
inline constexpr Vec4 operator*(float d) const;
friend inline constexpr Vec4 operator*(float d, const Vec4& v2);
inline constexpr Vec4& operator*=(float d);
inline constexpr Vec4 operator/(float d) const;
inline constexpr Vec4& operator/=(float d);
constexpr bool operator==(const Vec4& rhs) const;
constexpr bool operator!=(const Vec4& rhs) const;
};
static_assert(sizeof(Vec4) == 4 * sizeof(float));
class UVec2 final {
public:
union {
struct {
uint32_t x;
uint32_t y;
};
uint32_t data[2];
};
constexpr uint32_t& operator[](size_t index)
{
return data[index];
}
constexpr const uint32_t& operator[](size_t index) const
{
return data[index];
}
inline constexpr UVec2() : data{}
{}
inline constexpr UVec2(uint32_t xParameter, uint32_t yParameter) : x(xParameter), y(yParameter)
{}
inline constexpr UVec2 operator+(const UVec2& v2) const
{
return UVec2(x + v2.x, y + v2.y);
}
inline constexpr UVec2& operator+=(const UVec2& rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
inline constexpr UVec2 operator-(const UVec2& v2) const
{
return UVec2(x - v2.x, y - v2.y);
}
inline constexpr UVec2& operator-=(const UVec2& rhs)
{
x -= rhs.x;
y -= rhs.y;
return *this;
}
inline constexpr UVec2 operator*(const UVec2& v2) const
{
return UVec2(x * v2.x, y * v2.y);
}
inline constexpr UVec2& operator*=(const UVec2& rhs)
{
x *= rhs.x;
y *= rhs.y;
return *this;
}
inline constexpr UVec2 operator/(const UVec2& v2) const
{
return UVec2(x / v2.x, y / v2.y);
}
inline constexpr UVec2& operator/=(const UVec2& rhs)
{
x /= rhs.x;
y /= rhs.y;
return *this;
}
inline constexpr UVec2 operator*(uint32_t d) const
{
return UVec2(x * d, y * d);
}
friend inline constexpr UVec2 operator*(uint32_t d, const UVec2& v2)
{
return v2 * d;
}
inline constexpr UVec2& operator*=(uint32_t d)
{
x *= d;
y *= d;
return *this;
}
inline constexpr UVec2 operator/(uint32_t d) const
{
return UVec2(x / d, y / d);
}
inline constexpr UVec2& operator/=(uint32_t d)
{
if (d == 0) {
x = y = UINT32_MAX;
return *this;
}
x /= d;
y /= d;
return *this;
}
inline constexpr UVec2 operator+(uint32_t d) const
{
return UVec2(x + d, y + d);
}
inline constexpr UVec2& operator+=(uint32_t d)
{
x += d;
y += d;
return *this;
}
inline constexpr UVec2 operator-(uint32_t d) const
{
return UVec2(x - d, y - d);
}
inline constexpr UVec2& operator-=(uint32_t d)
{
x -= d;
y -= d;
return *this;
}
constexpr bool operator==(const UVec2& rhs) const
{
if (x != rhs.x) {
return false;
}
if (y != rhs.y) {
return false;
}
return true;
}
constexpr bool operator!=(const UVec2& rhs) const
{
return !(*this == rhs);
}
};
static_assert(sizeof(UVec2) == 2 * sizeof(uint32_t));
static constexpr UVec2 ZERO_UVEC2(0U, 0U);
class UVec3 {
public:
union {
struct {
uint32_t x;
uint32_t y;
uint32_t z;
};
uint32_t data[3];
};
inline constexpr UVec3() : data{}
{}
inline constexpr UVec3(uint32_t x, uint32_t y, uint32_t z) : x(x), y(y), z(z)
{}
constexpr uint32_t& operator[](size_t index)
{
return data[index];
}
constexpr const uint32_t& operator[](size_t index) const
{
return data[index];
}
constexpr bool operator==(const UVec3& rhs) const
{
if (x != rhs.x) {
return false;
}
if (y != rhs.y) {
return false;
}
if (z != rhs.z) {
return false;
}
return true;
}
constexpr bool operator!=(const UVec3& rhs) const
{
return !(*this == rhs);
}
};
static_assert(sizeof(UVec3) == 3 * sizeof(uint32_t));
static constexpr UVec3 ZERO_UVEC3(0U, 0U, 0U);
class UVec4 {
public:
union {
struct {
uint32_t x;
uint32_t y;
uint32_t z;
uint32_t w;
};
uint32_t data[4];
};
inline constexpr UVec4() : data{}
{}
inline constexpr UVec4(uint32_t x, uint32_t y, uint32_t z, uint32_t w) : x(x), y(y), z(z), w(w)
{}
constexpr uint32_t& operator[](size_t index)
{
return data[index];
}
constexpr const uint32_t& operator[](size_t index) const
{
return data[index];
}
constexpr bool operator==(const UVec4& rhs) const
{
if (x != rhs.x) {
return false;
}
if (y != rhs.y) {
return false;
}
if (z != rhs.z) {
return false;
}
if (w != rhs.w) {
return false;
}
return true;
}
constexpr bool operator!=(const UVec4& rhs) const
{
return !(*this == rhs);
}
};
static_assert(sizeof(UVec4) == 4 * sizeof(uint32_t));
static constexpr UVec4 ZERO_UVEC4(0U, 0U, 0U, 0U);
class IVec2 final {
public:
union {
struct {
int32_t x;
int32_t y;
};
int32_t data[2];
};
constexpr int32_t& operator[](size_t index)
{
return data[index];
}
constexpr const int32_t& operator[](size_t index) const
{
return data[index];
}
inline constexpr IVec2() : data{}
{}
inline constexpr IVec2(int32_t xParameter, int32_t yParameter) : x(xParameter), y(yParameter)
{}
~IVec2() = default;
inline constexpr IVec2 operator+(const IVec2& v2) const
{
return IVec2(x + v2.x, y + v2.y);
}
inline constexpr IVec2& operator+=(const IVec2& rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
inline constexpr IVec2 operator-(const IVec2& v2) const
{
return IVec2(x - v2.x, y - v2.y);
}
inline constexpr IVec2& operator-=(const IVec2& rhs)
{
x -= rhs.x;
y -= rhs.y;
return *this;
}
inline constexpr IVec2 operator*(const IVec2& v2) const
{
return IVec2(x * v2.x, y * v2.y);
}
inline constexpr IVec2& operator*=(const IVec2& rhs)
{
x *= rhs.x;
y *= rhs.y;
return *this;
}
inline constexpr IVec2 operator/(const IVec2& v2) const
{
return IVec2(x / v2.x, y / v2.y);
}
inline constexpr IVec2& operator/=(const IVec2& rhs)
{
x /= rhs.x;
y /= rhs.y;
return *this;
}
inline constexpr IVec2 operator*(int32_t d) const
{
return IVec2(x * d, y * d);
}
friend inline constexpr IVec2 operator*(int32_t d, const IVec2& v2)
{
return v2 * d;
}
inline constexpr IVec2& operator*=(int32_t d)
{
x *= d;
y *= d;
return *this;
}
inline constexpr IVec2 operator/(int32_t d) const
{
return IVec2(x / d, y / d);
}
inline constexpr IVec2& operator/=(int32_t d)
{
if (d == 0) {
x = y = INT32_MAX;
return *this;
}
x /= d;
y /= d;
return *this;
}
inline constexpr IVec2 operator+(int32_t d) const
{
return IVec2(x + d, y + d);
}
inline constexpr IVec2& operator+=(int32_t d)
{
x += d;
y += d;
return *this;
}
inline constexpr IVec2 operator-(int32_t d) const
{
return IVec2(x - d, y - d);
}
inline constexpr IVec2& operator-=(int32_t d)
{
x -= d;
y -= d;
return *this;
}
constexpr bool operator==(const IVec2& rhs) const
{
if (x != rhs.x) {
return false;
}
if (y != rhs.y) {
return false;
}
return true;
}
constexpr bool operator!=(const IVec2& rhs) const
{
return !(*this == rhs);
}
};
static_assert(sizeof(IVec2) == 2 * sizeof(int32_t));
static constexpr IVec2 ZERO_IVEC2(0, 0);
class IVec3 {
public:
union {
struct {
int32_t x;
int32_t y;
int32_t z;
};
int32_t data[3];
};
inline constexpr IVec3() : data{}
{}
inline constexpr IVec3(int32_t x, int32_t y, int32_t z) : x(x), y(y), z(z)
{}
~IVec3() = default;
constexpr int32_t& operator[](size_t index)
{
return data[index];
}
constexpr const int32_t& operator[](size_t index) const
{
return data[index];
}
constexpr bool operator==(const IVec3& rhs) const
{
if (x != rhs.x) {
return false;
}
if (y != rhs.y) {
return false;
}
if (z != rhs.z) {
return false;
}
return true;
}
constexpr bool operator!=(const IVec3& rhs) const
{
return !(*this == rhs);
}
};
static_assert(sizeof(IVec3) == 3 * sizeof(int32_t));
static constexpr IVec3 ZERO_IVEC3(0, 0, 0);
class IVec4 {
public:
union {
struct {
int32_t x;
int32_t y;
int32_t z;
int32_t w;
};
int32_t data[4];
};
inline constexpr IVec4() : data{}
{}
inline constexpr IVec4(int32_t x, int32_t y, int32_t z, int32_t w) : x(x), y(y), z(z), w(w)
{}
~IVec4() = default;
constexpr int32_t& operator[](size_t index)
{
return data[index];
}
constexpr const int32_t& operator[](size_t index) const
{
return data[index];
}
constexpr bool operator==(const IVec4& rhs) const
{
if (x != rhs.x) {
return false;
}
if (y != rhs.y) {
return false;
}
if (z != rhs.z) {
return false;
}
if (w != rhs.w) {
return false;
}
return true;
}
constexpr bool operator!=(const IVec4& rhs) const
{
return !(*this == rhs);
}
};
static_assert(sizeof(IVec4) == 4 * sizeof(int32_t));
static constexpr IVec4 ZERO_IVEC4(0, 0, 0, 0);
constexpr float& Vec3::operator[](size_t index)
{
return data[index];
}
constexpr const float& Vec3::operator[](size_t index) const
{
return data[index];
}
inline constexpr Vec3::Vec3() noexcept : data{}
{}
inline constexpr Vec3::Vec3(float value) noexcept : x(value), y(value), z(value)
{}
inline constexpr Vec3::Vec3(float xParameter, float yParameter, float zParameter) noexcept
: x(xParameter), y(yParameter), z(zParameter)
{}
inline constexpr Vec3::Vec3(const float d[]) noexcept : x(d[0]), y(d[1]), z(d[2])
{}
inline constexpr Vec3::Vec3(const Vec2& vec, float zParameter) noexcept : x(vec.x), y(vec.y), z(zParameter)
{}
inline constexpr Vec3::Vec3(const Vec4& vec) noexcept : x(vec.x), y(vec.y), z(vec.z)
{}
inline constexpr Vec3 Vec3::operator+(const Vec3& v2) const
{
return Vec3(x + v2.x, y + v2.y, z + v2.z);
}
inline constexpr Vec3& Vec3::operator+=(const Vec3& rhs)
{
x += rhs.x;
y += rhs.y;
z += rhs.z;
return *this;
}
inline constexpr Vec3 Vec3::operator-() const
{
return Vec3(-x, -y, -z);
}
inline constexpr Vec3 Vec3::operator-(const Vec3& v2) const
{
return Vec3(x - v2.x, y - v2.y, z - v2.z);
}
inline constexpr Vec3& Vec3::operator-=(const Vec3& rhs)
{
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
return *this;
}
inline constexpr Vec3 Vec3::operator*(const Vec3& v2) const
{
return Vec3(x * v2.x, y * v2.y, z * v2.z);
}
inline constexpr Vec3& Vec3::operator*=(const Vec3& rhs)
{
x *= rhs.x;
y *= rhs.y;
z *= rhs.z;
return *this;
}
inline constexpr Vec3 Vec3::operator/(const Vec3& v2) const
{
return Vec3(x / v2.x, y / v2.y, z / v2.z);
}
inline constexpr Vec3& Vec3::operator/=(const Vec3& rhs)
{
x /= rhs.x;
y /= rhs.y;
z /= rhs.z;
return *this;
}
constexpr bool Vec3::operator==(const Vec3& rhs) const
{
const Vec3 temp = *this - rhs;
const float sqmgt = temp.x * temp.x + temp.y * temp.y + temp.z * temp.z;
return sqmgt < Math::EPSILON * Math::EPSILON;
}
constexpr bool Vec3::operator!=(const Vec3& rhs) const
{
return !(*this == rhs);
}
inline constexpr Vec3 Vec3::operator+(float d) const
{
return Vec3(x + d, y + d, z + d);
}
inline constexpr Vec3& Vec3::operator+=(float d)
{
x += d;
y += d;
z += d;
return *this;
}
inline constexpr Vec3 Vec3::operator-(float d) const
{
return Vec3(x - d, y - d, z - d);
}
inline constexpr Vec3& Vec3::operator-=(float d)
{
x -= d;
y -= d;
z -= d;
return *this;
}
inline constexpr Vec3 Vec3::operator*(float d) const
{
return Vec3(x * d, y * d, z * d);
}
constexpr Vec3 operator*(float d, const Vec3& v2)
{
return v2 * d;
}
inline constexpr Vec3& Vec3::operator*=(float d)
{
x *= d;
y *= d;
z *= d;
return *this;
}
inline constexpr Vec3 Vec3::operator/(float d) const
{
return Vec3(x / d, y / d, z / d);
}
inline constexpr Vec3& Vec3::operator/=(float d)
{
x /= d;
y /= d;
z /= d;
return *this;
}
constexpr float& Vec4::operator[](size_t index)
{
return data[index];
}
constexpr const float& Vec4::operator[](size_t index) const
{
return data[index];
}
static constexpr Vec3 ZERO_VEC3(0.0f, 0.0f, 0.0f);
inline constexpr Vec4::Vec4() noexcept : data{}
{}
inline constexpr Vec4::Vec4(float value) noexcept : x(value), y(value), z(value), w(value)
{}
inline constexpr Vec4::Vec4(float xParameter, float yParameter, float zParameter, float wParameter) noexcept
: x(xParameter), y(yParameter), z(zParameter), w(wParameter)
{}
inline constexpr Vec4::Vec4(const float d[4]) noexcept : x(d[0]), y(d[1]), z(d[2]), w(d[3])
{}
inline constexpr Vec4::Vec4(const Vec3& vec, float w) noexcept : x(vec.x), y(vec.y), z(vec.z), w(w)
{}
inline constexpr Vec4::Vec4(const Vec2& vec, float zParameter, float wParameter) noexcept
: x(vec.x), y(vec.y), z(zParameter), w(wParameter)
{}
inline constexpr Vec4 Vec4::operator+(const Vec4& v2) const
{
return Vec4(x + v2.x, y + v2.y, z + v2.z, w + v2.w);
}
inline constexpr Vec4 Vec4::operator+(float d) const
{
return Vec4(x + d, y + d, z + d, w + d);
}
inline constexpr Vec4& Vec4::operator+=(const Vec4& rhs)
{
x += rhs.x;
y += rhs.y;
z += rhs.z;
w += rhs.w;
return *this;
}
inline constexpr Vec4& Vec4::operator+=(float d)
{
x += d;
y += d;
z += d;
w += d;
return *this;
}
inline constexpr Vec4 Vec4::operator-() const
{
return Vec4(-x, -y, -z, -w);
}
inline constexpr Vec4 Vec4::operator-(const Vec4& v2) const
{
return Vec4(x - v2.x, y - v2.y, z - v2.z, w - v2.w);
}
inline constexpr Vec4 Vec4::operator-(float d) const
{
return Vec4(x - d, y - d, z - d, w - d);
}
inline constexpr Vec4& Vec4::operator-=(const Vec4& rhs)
{
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
w -= rhs.w;
return *this;
}
inline constexpr Vec4& Vec4::operator-=(float d)
{
x -= d;
y -= d;
z -= d;
w -= d;
return *this;
}
inline constexpr Vec4 Vec4::operator*(const Vec4& v2) const
{
return Vec4(x * v2.x, y * v2.y, z * v2.z, w * v2.w);
}
inline constexpr Vec4& Vec4::operator*=(const Vec4& rhs)
{
x *= rhs.x;
y *= rhs.y;
z *= rhs.z;
w *= rhs.w;
return *this;
}
inline constexpr Vec4 Vec4::operator/(const Vec4& v2) const
{
return Vec4(x / v2.x, y / v2.y, z / v2.z, w / v2.w);
}
inline constexpr Vec4& Vec4::operator/=(const Vec4& rhs)
{
x /= rhs.x;
y /= rhs.y;
z /= rhs.z;
w /= rhs.w;
return *this;
}
inline constexpr Vec4 Vec4::operator*(float d) const
{
return Vec4(x * d, y * d, z * d, w * d);
}
constexpr Vec4 operator*(float d, const Vec4& v2)
{
return v2 * d;
}
inline constexpr Vec4& Vec4::operator*=(float d)
{
x *= d;
y *= d;
z *= d;
w *= d;
return *this;
}
inline constexpr Vec4 Vec4::operator/(float d) const
{
return Vec4(x / d, y / d, z / d, w / d);
}
inline constexpr Vec4& Vec4::operator/=(float d)
{
x /= d;
y /= d;
z /= d;
w /= d;
return *this;
}
constexpr bool Vec4::operator==(const Vec4& rhs) const
{
const Vec4 temp = *this - rhs;
const float sqmgt = temp.x * temp.x + temp.y * temp.y + temp.z * temp.z + temp.w * temp.w;
return sqmgt < Math::EPSILON * Math::EPSILON;
}
constexpr bool Vec4::operator!=(const Vec4& rhs) const
{
return !(*this == rhs);
}
static constexpr Vec4 ZERO_VEC4(0.0f, 0.0f, 0.0f, 0.0f);
#include <base/math/disable_warning_4201_footer.h>
}
BASE_END_NAMESPACE()
#endif