Math types
This commit is contained in:
parent
26f4deca12
commit
f6f4ee884a
|
@ -1,182 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Core/Types.h>
|
||||
#include <Orange/Core/Traits.h>
|
||||
#include <Orange/Core/AlignedStorage.h>
|
||||
#include <Orange/Core/Span.h>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
template <typename T, size_t N>
|
||||
class SmallArray
|
||||
template <typename T, size_t Size>
|
||||
struct Array
|
||||
{
|
||||
public:
|
||||
constexpr Array()
|
||||
: m_data{ } {}
|
||||
|
||||
SmallArray() {}
|
||||
SmallArray(size_t size) { Resize(size); }
|
||||
SmallArray(Span<T> span)
|
||||
constexpr Array(const T components[Size])
|
||||
{
|
||||
Reserve(span.size);
|
||||
for (const auto& val : span)
|
||||
PushBack(val);
|
||||
Copy(&components[0], &components[Size], m_data.begin());
|
||||
}
|
||||
|
||||
SmallArray (const SmallArray&) = delete;
|
||||
SmallArray& operator = (const SmallArray&) = delete;
|
||||
|
||||
~SmallArray()
|
||||
template <typename... Args>
|
||||
constexpr Array(const Args&... args)
|
||||
: m_data {{ args... }}
|
||||
{
|
||||
for (size_t i = 0; i < m_size; i++)
|
||||
Ptr(i)->~T();
|
||||
|
||||
if (m_capacity > N)
|
||||
delete[] u.m_ptr;
|
||||
static_assert(sizeof...(Args) == Size);
|
||||
}
|
||||
|
||||
template <typename J>
|
||||
bool operator == (const Span<J>& x)
|
||||
constexpr Array(const Array& other) = default;
|
||||
|
||||
constexpr T& operator[](size_t index) { return m_data[index]; }
|
||||
constexpr const T& operator[](size_t index) const { return m_data[index]; }
|
||||
|
||||
|
||||
constexpr const T* begin() const { return &m_data[0]; }
|
||||
constexpr T* begin() { return &m_data[0]; }
|
||||
constexpr const T* end() const { return &m_data[Size]; }
|
||||
constexpr T* end() { return &m_data[Size]; }
|
||||
|
||||
|
||||
constexpr bool operator==(const Array& other) const
|
||||
{
|
||||
return Span<T>(*this) == x;
|
||||
return Equal(begin(), end(), other.begin());
|
||||
}
|
||||
|
||||
bool operator == (const char *x)
|
||||
constexpr bool operator!=(const Array& other) const
|
||||
{
|
||||
return Span<T>(*this) == StringView(x);
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
void Reserve(size_t n)
|
||||
{
|
||||
n = PickCapacity(n);
|
||||
|
||||
if (n <= m_capacity)
|
||||
return;
|
||||
|
||||
Storage* data = new Storage[n];
|
||||
|
||||
for (size_t i = 0; i < m_size; i++)
|
||||
{
|
||||
new (&data[i]) T(Move(*Ptr(i)));
|
||||
Ptr(i)->~T();
|
||||
}
|
||||
|
||||
if (m_capacity > N)
|
||||
delete[] u.m_ptr;
|
||||
|
||||
m_capacity = n;
|
||||
u.m_ptr = data;
|
||||
}
|
||||
|
||||
size_t Size() const { return m_size; }
|
||||
|
||||
const T* Data() const { return Ptr(0); }
|
||||
T* Data() { return Ptr(0); }
|
||||
|
||||
void Resize(size_t n)
|
||||
{
|
||||
Reserve(n);
|
||||
|
||||
for (size_t i = n; i < m_size; i++)
|
||||
Ptr(i)->~T();
|
||||
|
||||
for (size_t i = m_size; i < n; i++)
|
||||
new (Ptr(i)) T();
|
||||
|
||||
m_size = n;
|
||||
}
|
||||
|
||||
void PushBack(const T& object)
|
||||
{
|
||||
Reserve(m_size + 1);
|
||||
new (Ptr(m_size++)) T(object);
|
||||
}
|
||||
|
||||
void PushBack(T&& object)
|
||||
{
|
||||
Reserve(m_size + 1);
|
||||
new (Ptr(m_size++)) T(Move(object));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void EmplaceBack(Args... args)
|
||||
{
|
||||
Reserve(m_size + 1);
|
||||
new (Ptr(m_size++)) T(Forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void Erase(size_t idx)
|
||||
{
|
||||
Ptr(idx)->~T();
|
||||
|
||||
for (size_t i = idx; i < m_size - 1; i++)
|
||||
{
|
||||
new (Ptr(i)) T(Move(*Ptr(i + 1)));
|
||||
Ptr(i + 1)->~T();
|
||||
}
|
||||
}
|
||||
|
||||
void PopBack()
|
||||
{
|
||||
Ptr(--m_size)->~T();
|
||||
}
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
return Size() == 0;
|
||||
}
|
||||
|
||||
T& operator [] (size_t idx) { return *Ptr(idx); }
|
||||
const T& operator [] (size_t idx) const { return *Ptr(idx); }
|
||||
|
||||
T* begin() { return Ptr(0); }
|
||||
const T* begin() const { return Ptr(0); }
|
||||
|
||||
T* end() { return Ptr(m_size); }
|
||||
const T* end() const { return Ptr(m_size); }
|
||||
|
||||
T& front() { return *Ptr(0); }
|
||||
const T& front() const { return *Ptr(0); }
|
||||
|
||||
T& back() { return *Ptr(m_size - 1); }
|
||||
const T& back() const { return *Ptr(m_size - 1); }
|
||||
|
||||
operator Span<T>() { return Span<T>(*this); }
|
||||
|
||||
private:
|
||||
using Storage = AlignedStorage<sizeof(T), alignof(T)>;
|
||||
|
||||
size_t m_capacity = N;
|
||||
size_t m_size = 0;
|
||||
|
||||
union
|
||||
{
|
||||
Storage* m_ptr;
|
||||
Storage m_data[sizeof(T) * N];
|
||||
} u;
|
||||
|
||||
size_t PickCapacity(size_t n) {
|
||||
size_t capacity = m_capacity;
|
||||
|
||||
while (capacity < n)
|
||||
capacity = (capacity * 2) + 2;
|
||||
|
||||
return capacity;
|
||||
}
|
||||
|
||||
T* Ptr(size_t idx) {
|
||||
return m_capacity == N
|
||||
? reinterpret_cast<T*>(&u.m_data[idx])
|
||||
: reinterpret_cast<T*>(&u.m_ptr[idx]);
|
||||
}
|
||||
|
||||
const T* Ptr(size_t idx) const
|
||||
{
|
||||
return m_capacity == N
|
||||
? reinterpret_cast<const T*>(&u.m_data[idx])
|
||||
: reinterpret_cast<const T*>(&u.m_ptr[idx]);
|
||||
}
|
||||
T m_data[Size];
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using Array = SmallArray<T, sizeof(T) / sizeof(void*)>;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Orange/Core/Array.h"
|
||||
#include "Orange/Core/Vector.h"
|
||||
#include <Orange/Core/Result.h>
|
||||
#include <Orange/Core/Span.h>
|
||||
|
||||
|
@ -68,7 +68,7 @@ namespace orange::stream
|
|||
return Consume(first, end, " \t");
|
||||
}
|
||||
|
||||
template <typename OutArray = SmallArray<char, 1>>
|
||||
template <typename OutArray = SmallVector<char, 1>>
|
||||
size_t ReadOrAdvance(const char*& first, const char* end, StringView delims, size_t advancement = 0, OutArray* array = nullptr)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
@ -88,7 +88,7 @@ namespace orange::stream
|
|||
return count;
|
||||
}
|
||||
|
||||
template <typename OutArray = SmallArray<char, 1>>
|
||||
template <typename OutArray = SmallVector<char, 1>>
|
||||
size_t ReadString(const char*& first, const char* end, StringView delims, OutArray& array)
|
||||
{
|
||||
return ReadOrAdvance(first, end, delims, 0, &array);
|
||||
|
|
|
@ -60,4 +60,120 @@ namespace orange
|
|||
{
|
||||
return Min( Max( val, minVal ), maxVal );
|
||||
}
|
||||
|
||||
// Transformations
|
||||
|
||||
template <typename InputIt, typename OutputIt, typename UnaryOperation>
|
||||
OutputIt Transform(InputIt inFirst, InputIt inLast,
|
||||
OutputIt outFirst, UnaryOperation unaryOp)
|
||||
{
|
||||
while (inFirst != inLast)
|
||||
*outFirst++ = unaryOp(*inFirst++);
|
||||
return outFirst;
|
||||
}
|
||||
|
||||
template<typename InputIt1, typename InputIt2, typename OutputIt, typename BinaryOperation>
|
||||
OutputIt Transform(InputIt1 first1, InputIt1 last1, InputIt2 first2,
|
||||
OutputIt outFirst, BinaryOperation binOp)
|
||||
{
|
||||
while (first1 != last1)
|
||||
*outFirst++ = binOp(*first1++, *first2++);
|
||||
return outFirst;
|
||||
}
|
||||
|
||||
template <typename T, typename InputIt, typename UnaryOperation>
|
||||
T TransformResult(InputIt first, InputIt last, UnaryOperation op)
|
||||
{
|
||||
T result;
|
||||
Transform(first, last, result.begin(), op);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename InputIt1, typename InputIt2, typename BinaryOperation>
|
||||
T TransformResult(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryOperation op)
|
||||
{
|
||||
T result;
|
||||
Transform(first1, last1, first2, result.begin(), op);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename InputIt, typename T>
|
||||
constexpr T Accumulate(InputIt first, InputIt last, T init)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
init = Move(init) + *first;
|
||||
return init;
|
||||
}
|
||||
|
||||
template <typename InputIt, typename T, typename BinaryOperation>
|
||||
constexpr T Accumulate(InputIt first, InputIt last, T init, BinaryOperation op)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
init = op(Move(init), *first);
|
||||
return init;
|
||||
}
|
||||
|
||||
template <typename InputIt1, typename InputIt2>
|
||||
bool Equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
|
||||
{
|
||||
for (; first1 != last1; ++first1, ++first2)
|
||||
{
|
||||
if (!(*first1 == *first2))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename InputIt1, typename InputIt2, typename BinaryPredicate>
|
||||
bool Equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p)
|
||||
{
|
||||
for (; first1 != last1; ++first1, ++first2)
|
||||
{
|
||||
if (!p(*first1, *first2))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename InputIt, typename OutputIt>
|
||||
OutputIt Copy(InputIt first, InputIt last, OutputIt d_first)
|
||||
{
|
||||
for (; first != last; (void)++first, (void)++d_first)
|
||||
*d_first = *first;
|
||||
return d_first;
|
||||
}
|
||||
|
||||
template <typename InputIt, typename OutputIt, typename UnaryPredicate>
|
||||
OutputIt CopyIf(InputIt first, InputIt last,
|
||||
OutputIt d_first, UnaryPredicate pred)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
{
|
||||
if (pred(*first))
|
||||
{
|
||||
*d_first = *first;
|
||||
++d_first;
|
||||
}
|
||||
}
|
||||
return d_first;
|
||||
}
|
||||
|
||||
template <typename ForwardIt, typename T>
|
||||
void Fill(ForwardIt first, ForwardIt last, const T& value)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
*first = value;
|
||||
}
|
||||
|
||||
// Math ops
|
||||
namespace math
|
||||
{
|
||||
template <typename T> T Negate(const T& x) { return -x; }
|
||||
|
||||
template <typename T> T Add (const T& x, const T& y) { return x + y; }
|
||||
template <typename T> T Subtract (const T& x, const T& y) { return x - y; }
|
||||
template <typename T> T Multiply (const T& x, const T& y) { return x * y; }
|
||||
template <typename T> T Divide (const T& x, const T& y) { return x / y; }
|
||||
template <typename T> T Modulo (const T& x, const T& y) { return x % y; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Core/Traits.h>
|
||||
#include <Orange/Core/AlignedStorage.h>
|
||||
#include <Orange/Core/Span.h>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
template <typename T, size_t N>
|
||||
class SmallVector
|
||||
{
|
||||
public:
|
||||
|
||||
SmallVector() {}
|
||||
SmallVector(size_t size) { Resize(size); }
|
||||
SmallVector(Span<T> span)
|
||||
{
|
||||
Reserve(span.size);
|
||||
for (const auto& val : span)
|
||||
PushBack(val);
|
||||
}
|
||||
|
||||
SmallVector (const SmallVector&) = delete;
|
||||
SmallVector& operator = (const SmallVector&) = delete;
|
||||
|
||||
~SmallVector()
|
||||
{
|
||||
for (size_t i = 0; i < m_size; i++)
|
||||
Ptr(i)->~T();
|
||||
|
||||
if (m_capacity > N)
|
||||
delete[] u.m_ptr;
|
||||
}
|
||||
|
||||
template <typename J>
|
||||
bool operator == (const Span<J>& x)
|
||||
{
|
||||
return Span<T>(*this) == x;
|
||||
}
|
||||
|
||||
bool operator == (const char *x)
|
||||
{
|
||||
return Span<T>(*this) == StringView(x);
|
||||
}
|
||||
|
||||
void Reserve(size_t n)
|
||||
{
|
||||
n = PickCapacity(n);
|
||||
|
||||
if (n <= m_capacity)
|
||||
return;
|
||||
|
||||
Storage* data = new Storage[n];
|
||||
|
||||
for (size_t i = 0; i < m_size; i++)
|
||||
{
|
||||
new (&data[i]) T(Move(*Ptr(i)));
|
||||
Ptr(i)->~T();
|
||||
}
|
||||
|
||||
if (m_capacity > N)
|
||||
delete[] u.m_ptr;
|
||||
|
||||
m_capacity = n;
|
||||
u.m_ptr = data;
|
||||
}
|
||||
|
||||
size_t Size() const { return m_size; }
|
||||
|
||||
const T* Data() const { return Ptr(0); }
|
||||
T* Data() { return Ptr(0); }
|
||||
|
||||
void Resize(size_t n)
|
||||
{
|
||||
Reserve(n);
|
||||
|
||||
for (size_t i = n; i < m_size; i++)
|
||||
Ptr(i)->~T();
|
||||
|
||||
for (size_t i = m_size; i < n; i++)
|
||||
new (Ptr(i)) T();
|
||||
|
||||
m_size = n;
|
||||
}
|
||||
|
||||
void PushBack(const T& object)
|
||||
{
|
||||
Reserve(m_size + 1);
|
||||
new (Ptr(m_size++)) T(object);
|
||||
}
|
||||
|
||||
void PushBack(T&& object)
|
||||
{
|
||||
Reserve(m_size + 1);
|
||||
new (Ptr(m_size++)) T(Move(object));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void EmplaceBack(Args... args)
|
||||
{
|
||||
Reserve(m_size + 1);
|
||||
new (Ptr(m_size++)) T(Forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void Erase(size_t idx)
|
||||
{
|
||||
Ptr(idx)->~T();
|
||||
|
||||
for (size_t i = idx; i < m_size - 1; i++)
|
||||
{
|
||||
new (Ptr(i)) T(Move(*Ptr(i + 1)));
|
||||
Ptr(i + 1)->~T();
|
||||
}
|
||||
}
|
||||
|
||||
void PopBack()
|
||||
{
|
||||
Ptr(--m_size)->~T();
|
||||
}
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
return Size() == 0;
|
||||
}
|
||||
|
||||
T& operator [] (size_t idx) { return *Ptr(idx); }
|
||||
const T& operator [] (size_t idx) const { return *Ptr(idx); }
|
||||
|
||||
T* begin() { return Ptr(0); }
|
||||
const T* begin() const { return Ptr(0); }
|
||||
|
||||
T* end() { return Ptr(m_size); }
|
||||
const T* end() const { return Ptr(m_size); }
|
||||
|
||||
T& front() { return *Ptr(0); }
|
||||
const T& front() const { return *Ptr(0); }
|
||||
|
||||
T& back() { return *Ptr(m_size - 1); }
|
||||
const T& back() const { return *Ptr(m_size - 1); }
|
||||
|
||||
operator Span<T>() { return Span<T>(*this); }
|
||||
|
||||
private:
|
||||
using Storage = AlignedStorage<sizeof(T), alignof(T)>;
|
||||
|
||||
size_t m_capacity = N;
|
||||
size_t m_size = 0;
|
||||
|
||||
union
|
||||
{
|
||||
Storage* m_ptr;
|
||||
Storage m_data[sizeof(T) * N];
|
||||
} u;
|
||||
|
||||
size_t PickCapacity(size_t n) {
|
||||
size_t capacity = m_capacity;
|
||||
|
||||
while (capacity < n)
|
||||
capacity = (capacity * 2) + 2;
|
||||
|
||||
return capacity;
|
||||
}
|
||||
|
||||
T* Ptr(size_t idx) {
|
||||
return m_capacity == N
|
||||
? reinterpret_cast<T*>(&u.m_data[idx])
|
||||
: reinterpret_cast<T*>(&u.m_ptr[idx]);
|
||||
}
|
||||
|
||||
const T* Ptr(size_t idx) const
|
||||
{
|
||||
return m_capacity == N
|
||||
? reinterpret_cast<const T*>(&u.m_data[idx])
|
||||
: reinterpret_cast<const T*>(&u.m_ptr[idx]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using Vector = SmallVector<T, sizeof(T) / sizeof(void*)>;
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
template <typename T>
|
||||
struct DefaultLengthTypeResolver
|
||||
{
|
||||
using LengthType = float;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DefaultLengthTypeResolver<double>
|
||||
{
|
||||
using LengthType = double;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DefaultLengthTypeResolver<long double>
|
||||
{
|
||||
using LengthType = long double;
|
||||
};
|
||||
|
||||
template <typename T, typename J = DefaultLengthTypeResolver<T>::LengthType>
|
||||
constexpr J rcp(const T& a)
|
||||
{
|
||||
return static_cast<J>(1) / static_cast<J>(a);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Core/Types.h>
|
||||
#include <Orange/Core/Traits.h>
|
||||
#include <Orange/Core/Array.h>
|
||||
|
||||
#include <Orange/Math/Basic.h>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
template <typename T, size_t Size>
|
||||
struct Vec
|
||||
{
|
||||
using DefaultLengthType = DefaultLengthTypeResolver<T>::LengthType;
|
||||
using DefaultLengthVec = Vec<DefaultLengthType, Size>;
|
||||
|
||||
constexpr Vec()
|
||||
: data{ } {}
|
||||
|
||||
constexpr explicit Vec(T splat)
|
||||
{
|
||||
Fill(data.begin(), data.end(), splat);
|
||||
}
|
||||
|
||||
constexpr Vec(const T components[Size])
|
||||
{
|
||||
Copy(&components[0], &components[Size], data.begin());
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
constexpr Vec(const Args&... args)
|
||||
: data {{ args... }}
|
||||
{
|
||||
static_assert(sizeof...(Args) == Size);
|
||||
}
|
||||
|
||||
constexpr Vec(const Vec& other) = default;
|
||||
|
||||
|
||||
constexpr T& operator[](size_t index) { return data[index]; }
|
||||
constexpr const T& operator[](size_t index) const { return data[index]; }
|
||||
|
||||
|
||||
constexpr const T* begin() const { return data.begin(); }
|
||||
constexpr T* begin() { return data.begin(); }
|
||||
constexpr const T* end() const { return data.end(); }
|
||||
constexpr T* end() { return data.end(); }
|
||||
|
||||
|
||||
constexpr bool operator==(const Vec& other) const
|
||||
{
|
||||
return Equal(begin(), end(), other.begin());
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const Vec& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
|
||||
template <typename UnaryOperation>
|
||||
constexpr Vec TransformResult(UnaryOperation op) const
|
||||
{
|
||||
return TransformResult<Vec>(begin(), end(), op);
|
||||
}
|
||||
|
||||
template <typename BinaryOperation>
|
||||
constexpr Vec TransformResult(const T *other, BinaryOperation op) const
|
||||
{
|
||||
return TransformResult<Vec>(begin(), end(), other, op);
|
||||
}
|
||||
|
||||
template <typename BinaryOperation>
|
||||
constexpr Vec TransformResult(const Vec& other, BinaryOperation op) const
|
||||
{
|
||||
return TransformResult(other.begin(), op);
|
||||
}
|
||||
|
||||
template <typename UnaryOperation>
|
||||
constexpr Vec& TransformInPlace(UnaryOperation op)
|
||||
{
|
||||
Transform(begin(), end(), begin(), op);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename BinaryOperation>
|
||||
constexpr Vec& TransformInPlace(const T *other, BinaryOperation op)
|
||||
{
|
||||
Transform(begin(), end(), other, begin(), op);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename BinaryOperation>
|
||||
constexpr Vec& TransformInPlace(const Vec& other, BinaryOperation op)
|
||||
{
|
||||
return TransformInPlace(other.begin(), op);
|
||||
}
|
||||
|
||||
|
||||
constexpr Vec operator-() const
|
||||
{
|
||||
return TransformResult(math::Negate);
|
||||
}
|
||||
|
||||
|
||||
constexpr Vec operator+(const Vec& other) const
|
||||
{
|
||||
return TransformResult(other, math::Add);
|
||||
}
|
||||
|
||||
constexpr Vec operator-(const Vec& other) const
|
||||
{
|
||||
return TransformResult(other, math::Subtract);
|
||||
}
|
||||
|
||||
constexpr Vec operator*(const Vec& other) const
|
||||
{
|
||||
return TransformResult(other, math::Multiply);
|
||||
}
|
||||
|
||||
constexpr Vec operator*(const T& scalar) const
|
||||
{
|
||||
return TransformResult([scalar](T value) { return value * scalar; });
|
||||
}
|
||||
|
||||
constexpr Vec operator/(const Vec& other) const
|
||||
{
|
||||
return TransformResult(other, math::Divide);
|
||||
}
|
||||
|
||||
constexpr Vec operator/(const T& scalar) const
|
||||
{
|
||||
return TransformResult([scalar](T value) { return value / scalar; });
|
||||
}
|
||||
|
||||
constexpr Vec operator%(const Vec& other) const
|
||||
{
|
||||
return TransformResult(other, math::Modulo);
|
||||
}
|
||||
|
||||
constexpr Vec operator%(const T& scalar) const
|
||||
{
|
||||
return TransformResult([scalar](T value) { return value % scalar; });
|
||||
}
|
||||
|
||||
|
||||
constexpr Vec& operator+=(const Vec& other)
|
||||
{
|
||||
return TransformInPlace(math::Add);
|
||||
}
|
||||
|
||||
constexpr Vec& operator-=(const Vec& other)
|
||||
{
|
||||
return TransformInPlace(math::Subtract);
|
||||
}
|
||||
|
||||
constexpr Vec& operator*=(const Vec& other)
|
||||
{
|
||||
return TransformInPlace(math::Multiply);
|
||||
}
|
||||
|
||||
constexpr Vec& operator*=(const T& scalar)
|
||||
{
|
||||
return TransformInPlace([scalar](T value) { return value * scalar; });
|
||||
}
|
||||
|
||||
constexpr Vec& operator/=(const Vec& other)
|
||||
{
|
||||
return TransformInPlace(math::Divide);
|
||||
}
|
||||
|
||||
constexpr Vec& operator/=(const T& scalar)
|
||||
{
|
||||
return TransformInPlace([scalar](T value) { return value / scalar; });
|
||||
}
|
||||
|
||||
constexpr Vec& operator%=(const Vec& other)
|
||||
{
|
||||
return TransformInPlace(math::Modulo);
|
||||
}
|
||||
|
||||
constexpr Vec& operator%=(const T& scalar)
|
||||
{
|
||||
return TransformInPlace([scalar](T value) { return value % scalar; });
|
||||
}
|
||||
|
||||
|
||||
static constexpr Vec Zero = Vec{ T{ 0 } };
|
||||
static constexpr Vec Identity = Vec{ T{ 1 } };
|
||||
|
||||
|
||||
// Align to 16 if the size is a multiple of 4 and T is 4 bytes in size.
|
||||
// to take advantage of aligned load/stores.
|
||||
static constexpr size_t Alignment =
|
||||
(Size % 4zu == 0 && sizeof(T) == 4zu)
|
||||
? Max<size_t>(16zu, alignof(T))
|
||||
: alignof(T);
|
||||
|
||||
alignas(Alignment) Array<T, Size> data;
|
||||
|
||||
};
|
||||
|
||||
template <typename T, size_t Size>
|
||||
constexpr Vec<T, Size> operator*(T scalar, const Vec<T, Size>& Vec)
|
||||
{
|
||||
return Vec.TransformResult([scalar](T value) { return scalar * value; });
|
||||
}
|
||||
|
||||
template <typename T, size_t Size>
|
||||
constexpr Vec<T, Size> operator/(T scalar, const Vec<T, Size>& Vec)
|
||||
{
|
||||
return Vec.TransformResult([scalar](T value) { return scalar / value; });
|
||||
}
|
||||
|
||||
template <typename T, size_t Size>
|
||||
constexpr Vec<T, Size> operator%(T scalar, const Vec<T, Size>& Vec)
|
||||
{
|
||||
return Vec.TransformResult([scalar](T value) { return scalar % value; });
|
||||
}
|
||||
|
||||
|
||||
template <typename T, size_t Size>
|
||||
constexpr T accumulate(const Vec<T, Size>& a, T init = T{})
|
||||
{
|
||||
return Accumulate(a.begin(), a.end(), init);
|
||||
}
|
||||
|
||||
template <typename T, size_t Size>
|
||||
constexpr T dot(const Vec<T, Size>& a, const Vec<T, Size>& b)
|
||||
{
|
||||
return accumulate(a * b);
|
||||
}
|
||||
|
||||
template <typename T, size_t Size>
|
||||
constexpr T lengthSqr(const Vec<T, Size>& a)
|
||||
{
|
||||
return dot(a, a);
|
||||
}
|
||||
|
||||
template <typename T, size_t Size, typename J = Vec<T, Size>::DefaultLengthType>
|
||||
constexpr J length(const Vec<T, Size>& a)
|
||||
{
|
||||
sqrtf(J{ lengthSqr(a) });
|
||||
}
|
||||
|
||||
template <typename T, size_t Size, typename J = Vec<T, Size>::DefaultLengthType>
|
||||
constexpr Vec<J, Size> normalize(const Vec<T, Size>& a)
|
||||
{
|
||||
return a * J{ rcp( length<T, Size>(a) ) };
|
||||
}
|
||||
|
||||
template <typename T, size_t Size, typename J = Vec<T, Size>::DefaultLengthType>
|
||||
constexpr Vec<J, Size> rcp(const Vec<T, Size>& a)
|
||||
{
|
||||
return TransformResult<Vec<J, Size>>(a.begin(), a.end(), [](T value){ return rcp<T, J>(value); });
|
||||
}
|
||||
|
||||
template <typename T, size_t Size>
|
||||
constexpr bool empty(const Vec<T, Size>& a)
|
||||
{
|
||||
return a == Vec<T, Size>::Zero;
|
||||
}
|
||||
|
||||
template <typename T, size_t Size>
|
||||
constexpr bool identity(const Vec<T, Size>& a)
|
||||
{
|
||||
return a == Vec<T, Size>::Identity;
|
||||
}
|
||||
|
||||
using Vec1 = Vec<float, 1>;
|
||||
using Vec2 = Vec<float, 2>;
|
||||
using Vec3 = Vec<float, 3>;
|
||||
using Vec4 = Vec<float, 4>;
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <Orange/Core/Span.h>
|
||||
#include <Orange/Core/Result.h>
|
||||
#include <Orange/Core/Array.h>
|
||||
#include <Orange/Core/Vector.h>
|
||||
|
||||
#include <Orange/Render/RenderContext.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
@ -51,13 +51,13 @@ namespace orange
|
|||
VkExtent2D m_extent;
|
||||
VkSwapchainKHR m_swapchain;
|
||||
|
||||
SmallArray<VkImage, 6> m_images;
|
||||
SmallArray<VkImageView, 6> m_imageViews;
|
||||
SmallVector<VkImage, 6> m_images;
|
||||
SmallVector<VkImageView, 6> m_imageViews;
|
||||
|
||||
SmallArray<VkCommandBuffer, MaxFramesInFlight> m_commandBuffers;
|
||||
SmallArray<VkSemaphore, MaxFramesInFlight> m_imageAvailableSemaphores;
|
||||
SmallArray<VkSemaphore, MaxFramesInFlight> m_renderFinishedSemaphores;
|
||||
SmallArray<VkFence, MaxFramesInFlight> m_inFlightFences;
|
||||
SmallVector<VkCommandBuffer, MaxFramesInFlight> m_commandBuffers;
|
||||
SmallVector<VkSemaphore, MaxFramesInFlight> m_imageAvailableSemaphores;
|
||||
SmallVector<VkSemaphore, MaxFramesInFlight> m_renderFinishedSemaphores;
|
||||
SmallVector<VkFence, MaxFramesInFlight> m_inFlightFences;
|
||||
|
||||
uint32_t m_currentFrame = 0;
|
||||
uint32_t m_currentImage = 0;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "Orange/Core/Array.h"
|
||||
#include <Orange/Core/Array.h>
|
||||
#include <Orange/Core/Vector.h>
|
||||
#include "Orange/Core/Span.h"
|
||||
#include <Orange/Core/Result.h>
|
||||
#include <Orange/Core/FileSystem.h>
|
||||
#include <Orange/Math/Vector.h>
|
||||
#include <Orange/Core/Parse.h>
|
||||
|
||||
#include <Orange/Render/Window.h>
|
||||
|
@ -16,7 +18,7 @@ Result<VoidResult> ParseOBJ(StringView buffer)
|
|||
const char* end = buffer.data + buffer.size;
|
||||
while (obj != end)
|
||||
{
|
||||
SmallArray<char, 8> element;
|
||||
SmallVector<char, 8> element;
|
||||
stream::ReadString(obj, end, " #\n", element);
|
||||
|
||||
if (element == "v" || element == "vn" || element == "vt")
|
||||
|
@ -37,7 +39,7 @@ Result<VoidResult> ParseOBJ(StringView buffer)
|
|||
else if (element == "g" || element == "o")
|
||||
{
|
||||
stream::ConsumeSpace(obj, end);
|
||||
SmallArray<char, 32> name;
|
||||
SmallVector<char, 32> name;
|
||||
stream::ReadString(obj, end, " #\n", name);
|
||||
|
||||
name.PushBack('\0');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <Orange/Core/Log.h>
|
||||
#include <Orange/Core/Array.h>
|
||||
#include <Orange/Core/Vector.h>
|
||||
|
||||
#include <Orange/Render/VulkanHelpers.h>
|
||||
#include <Orange/Render/RenderContext.h>
|
||||
|
@ -9,7 +9,7 @@ namespace orange
|
|||
{
|
||||
static VulkanResult<VkInstance> CreateVkInstance(const char* appName)
|
||||
{
|
||||
SmallArray<const char *, 32> instanceExtensions;
|
||||
SmallVector<const char *, 32> instanceExtensions;
|
||||
{
|
||||
auto r_tempWindow = Window::Create();
|
||||
if (!r_tempWindow)
|
||||
|
@ -49,7 +49,7 @@ namespace orange
|
|||
|
||||
static Result<uint32_t> PickQueueFamilyIndex(VkPhysicalDevice physicalDevice)
|
||||
{
|
||||
SmallArray<VkQueueFamilyProperties, 32> queueFamilyProperties;
|
||||
SmallVector<VkQueueFamilyProperties, 32> queueFamilyProperties;
|
||||
VkEnumerate(vkGetPhysicalDeviceQueueFamilyProperties, queueFamilyProperties, physicalDevice);
|
||||
|
||||
for (uint32_t i = 0; i < queueFamilyProperties.Size(); i++)
|
||||
|
@ -80,7 +80,7 @@ namespace orange
|
|||
|
||||
static Result<VkPhysicalDevice> PickPhysicalDevice(VkInstance instance)
|
||||
{
|
||||
SmallArray<VkPhysicalDevice, 32> physicalDevices;
|
||||
SmallVector<VkPhysicalDevice, 32> physicalDevices;
|
||||
VkEnumerate(vkEnumeratePhysicalDevices, physicalDevices, instance);
|
||||
|
||||
VkPhysicalDevice bestPhysicalDevice = VK_NULL_HANDLE;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace orange
|
|||
|
||||
static Result<VkSurfaceFormatKHR> ChooseSwapChainFormat(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
|
||||
{
|
||||
SmallArray<VkSurfaceFormatKHR, 32> surfaceFormats;
|
||||
SmallVector<VkSurfaceFormatKHR, 32> surfaceFormats;
|
||||
if (!VkEnumerate(vkGetPhysicalDeviceSurfaceFormatsKHR, surfaceFormats, physicalDevice, surface))
|
||||
{
|
||||
log::err("Surface supports no formats");
|
||||
|
@ -29,7 +29,7 @@ namespace orange
|
|||
|
||||
static VkPresentModeKHR ChoosePresentMode(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
|
||||
{
|
||||
SmallArray<VkPresentModeKHR, 32> presentModes;
|
||||
SmallVector<VkPresentModeKHR, 32> presentModes;
|
||||
VkEnumerate(vkGetPhysicalDeviceSurfacePresentModesKHR, presentModes, physicalDevice, surface);
|
||||
|
||||
for (auto& presentMode : presentModes) { if (presentMode == VK_PRESENT_MODE_MAILBOX_KHR) return presentMode; }
|
||||
|
@ -99,11 +99,11 @@ namespace orange
|
|||
if (vkCreateSwapchainKHR(context.Device(), &swapchainInfo, nullptr, &swapchain) != VK_SUCCESS)
|
||||
return Result<Swapchain>::PrintError("Failed to create swapchain");
|
||||
|
||||
SmallArray<VkImage, 6> swapchainImages;
|
||||
SmallVector<VkImage, 6> swapchainImages;
|
||||
if (!VkEnumerate(vkGetSwapchainImagesKHR, swapchainImages, context.Device(), swapchain))
|
||||
return Result<Swapchain>::PrintError("Failed to get swapchain images");
|
||||
|
||||
SmallArray<VkImageView, 6> swapchainImageViews{ swapchainImages.Size() };
|
||||
SmallVector<VkImageView, 6> swapchainImageViews{ swapchainImages.Size() };
|
||||
for (size_t i = 0; i < swapchainImages.Size(); i++)
|
||||
{
|
||||
VkImageViewCreateInfo imageViewInfo =
|
||||
|
@ -119,7 +119,7 @@ namespace orange
|
|||
return Result<Swapchain>::PrintError("Failed to get swapchain image view");
|
||||
}
|
||||
|
||||
SmallArray<VkCommandBuffer, 6> commandBuffers{ DefaultFramesInFlight };
|
||||
SmallVector<VkCommandBuffer, 6> commandBuffers{ DefaultFramesInFlight };
|
||||
{
|
||||
VkCommandBufferAllocateInfo commandBufferInfo =
|
||||
{
|
||||
|
@ -133,9 +133,9 @@ namespace orange
|
|||
return Result<Swapchain>::PrintError("Failed to get swapchain image view");
|
||||
}
|
||||
|
||||
SmallArray<VkSemaphore, MaxFramesInFlight> imageAvailableSemaphores{ DefaultFramesInFlight };
|
||||
SmallArray<VkSemaphore, MaxFramesInFlight> renderFinishedSemaphores{ DefaultFramesInFlight };
|
||||
SmallArray<VkFence, MaxFramesInFlight> inFlightFences { DefaultFramesInFlight };
|
||||
SmallVector<VkSemaphore, MaxFramesInFlight> imageAvailableSemaphores{ DefaultFramesInFlight };
|
||||
SmallVector<VkSemaphore, MaxFramesInFlight> renderFinishedSemaphores{ DefaultFramesInFlight };
|
||||
SmallVector<VkFence, MaxFramesInFlight> inFlightFences { DefaultFramesInFlight };
|
||||
for (uint32_t i = 0; i < DefaultFramesInFlight; i++)
|
||||
{
|
||||
auto r_fence = context.CreateFence(true);
|
||||
|
|
Loading…
Reference in New Issue