blob: b1621f0147a1b62263728d471865a826d9744e83 [file] [log] [blame] [edit]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <cmath>
#include <string>
#include "impeller/geometry/color.h"
#include "impeller/geometry/point.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/size.h"
namespace impeller {
struct Vector3 {
union {
struct {
Scalar x = 0.0;
Scalar y = 0.0;
Scalar z = 0.0;
};
Scalar e[3];
};
constexpr Vector3(){};
constexpr Vector3(const Color& c) : x(c.red), y(c.green), z(c.blue) {}
constexpr Vector3(const Point& p) : x(p.x), y(p.y) {}
constexpr Vector3(const Size& s) : x(s.width), y(s.height) {}
constexpr Vector3(Scalar x, Scalar y) : x(x), y(y) {}
constexpr Vector3(Scalar x, Scalar y, Scalar z) : x(x), y(y), z(z) {}
/**
* The length (or magnitude of the vector).
*
* @return the calculated length.
*/
constexpr Scalar Length() const { return sqrt(x * x + y * y + z * z); }
constexpr Vector3 Normalize() const {
const auto len = Length();
return {x / len, y / len, z / len};
}
constexpr Scalar Dot(const Vector3& other) const {
return ((x * other.x) + (y * other.y) + (z * other.z));
}
constexpr Vector3 Cross(const Vector3& other) const {
return {
(y * other.z) - (z * other.y), //
(z * other.x) - (x * other.z), //
(x * other.y) - (y * other.x) //
};
}
constexpr bool operator==(const Vector3& v) const {
return v.x == x && v.y == y && v.z == z;
}
constexpr bool operator!=(const Vector3& v) const {
return v.x != x || v.y != y || v.z != z;
}
constexpr Vector3 operator+=(const Vector3& p) {
x += p.x;
y += p.y;
z += p.z;
return *this;
}
constexpr Vector3 operator-=(const Vector3& p) {
x -= p.x;
y -= p.y;
z -= p.z;
return *this;
}
constexpr Vector3 operator*=(const Vector3& p) {
x *= p.x;
y *= p.y;
z *= p.z;
return *this;
}
constexpr Vector3 operator/=(const Vector3& p) {
x /= p.x;
y /= p.y;
z /= p.z;
return *this;
}
constexpr Vector3 operator-() const { return Vector3(-x, -y, -z); }
constexpr Vector3 operator+(const Vector3& v) const {
return Vector3(x + v.x, y + v.y, z + v.z);
}
constexpr Vector3 operator-(const Vector3& v) const {
return Vector3(x - v.x, y - v.y, z - v.z);
}
/**
* Make a linear combination of two vectors and return the result.
*
* @param a the first vector.
* @param aScale the scale to use for the first vector.
* @param b the second vector.
* @param bScale the scale to use for the second vector.
*
* @return the combined vector.
*/
static constexpr Vector3 Combine(const Vector3& a,
Scalar aScale,
const Vector3& b,
Scalar bScale) {
return {
aScale * a.x + bScale * b.x, //
aScale * a.y + bScale * b.y, //
aScale * a.z + bScale * b.z, //
};
}
std::string ToString() const;
};
// RHS algebraic operations with arithmetic types.
template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
constexpr Vector3 operator*(U s, const Vector3& p) {
return p * s;
}
template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
constexpr Vector3 operator/(U s, const Vector3& p) {
return {static_cast<Scalar>(s) / p.x, static_cast<Scalar>(s) / p.y};
}
struct Vector4 {
union {
struct {
Scalar x = 0.0;
Scalar y = 0.0;
Scalar z = 0.0;
Scalar w = 1.0;
};
Scalar e[4];
};
constexpr Vector4() {}
constexpr Vector4(const Color& c)
: x(c.red), y(c.green), z(c.blue), w(c.alpha) {}
constexpr Vector4(Scalar x, Scalar y, Scalar z, Scalar w)
: x(x), y(y), z(z), w(w) {}
constexpr Vector4(const Vector3& v) : x(v.x), y(v.y), z(v.z) {}
constexpr Vector4(const Point& p) : x(p.x), y(p.y) {}
Vector4 Normalize() const {
const Scalar inverse = 1.0 / sqrt(x * x + y * y + z * z + w * w);
return Vector4(x * inverse, y * inverse, z * inverse, w * inverse);
}
constexpr bool operator==(const Vector4& v) const {
return (x == v.x) && (y == v.y) && (z == v.z) && (w == v.w);
}
constexpr bool operator!=(const Vector4& v) const {
return (x != v.x) || (y != v.y) || (z != v.z) || (w != v.w);
}
constexpr Vector4 operator+(const Vector4& v) const {
return Vector4(x + v.x, y + v.y, z + v.z, w + v.w);
}
constexpr Vector4 operator-(const Vector4& v) const {
return Vector4(x - v.x, y - v.y, z - v.z, w - v.w);
}
std::string ToString() const;
};
static_assert(sizeof(Vector3) == 3 * sizeof(Scalar));
static_assert(sizeof(Vector4) == 4 * sizeof(Scalar));
} // namespace impeller