Variant stuff

This commit is contained in:
Joshua Ashton 2022-08-12 12:26:36 +00:00
parent 92f8669d5a
commit c70779bfff
3 changed files with 168 additions and 17 deletions

View File

@ -37,6 +37,70 @@ namespace orange
return static_cast<RemoveReference<T>&&>(arg); return static_cast<RemoveReference<T>&&>(arg);
} }
template <typename ForwardIt>
[[nodiscard]] constexpr ForwardIt MinElement(ForwardIt first, ForwardIt last)
{
if (first == last)
return last;
ForwardIt smallest = first;
++first;
for (; first != last; ++first)
{
if (*first < *smallest)
smallest = first;
}
return smallest;
}
template <typename ForwardIt, typename Compare>
[[nodiscard]] constexpr ForwardIt MinElement(ForwardIt first, ForwardIt last, Compare comp)
{
if (first == last)
return last;
ForwardIt smallest = first;
++first;
for (; first != last; ++first)
{
if (comp(*first, *smallest))
smallest = first;
}
return smallest;
}
template <typename ForwardIt>
[[nodiscard]] constexpr ForwardIt MaxElement(ForwardIt first, ForwardIt last)
{
if (first == last)
return last;
ForwardIt largest = first;
++first;
for (; first != last; ++first)
{
if (*largest < *first)
largest = first;
}
return largest;
}
template <typename ForwardIt, typename Compare>
[[nodiscard]] constexpr ForwardIt MaxElement(ForwardIt first, ForwardIt last, Compare comp)
{
if (first == last)
return last;
ForwardIt largest = first;
++first;
for (; first != last; ++first)
{
if (comp(*largest, *first))
largest = first;
}
return largest;
}
template <typename T, size_t N> template <typename T, size_t N>
[[nodiscard]] constexpr size_t Size(const T (&array)[N]) noexcept [[nodiscard]] constexpr size_t Size(const T (&array)[N]) noexcept
{ {
@ -45,17 +109,41 @@ namespace orange
} }
template <typename T> template <typename T>
[[nodiscard]] constexpr T Min( const T& valMin, const T& valMax ) [[nodiscard]] constexpr T Min(const T& valMin, const T& valMax)
{ {
return valMin < valMax ? valMin : valMax; return valMin < valMax ? valMin : valMax;
} }
template <typename T> template <typename T>
[[nodiscard]] constexpr T Max( const T& valMin, const T& valMax ) [[nodiscard]] constexpr T Min(std::initializer_list<T> ilist)
{
return *MinElement(ilist.begin(), ilist.end());
}
template <typename T, typename Compare>
[[nodiscard]] constexpr T Min(std::initializer_list<T> ilist, Compare comp)
{
return *MinElement(ilist.begin(), ilist.end(), comp);
}
template <typename T>
[[nodiscard]] constexpr T Max(const T& valMin, const T& valMax)
{ {
return valMin > valMax ? valMin : valMax; return valMin > valMax ? valMin : valMax;
} }
template <typename T>
[[nodiscard]] constexpr T Max(std::initializer_list<T> ilist)
{
return *MaxElement(ilist.begin(), ilist.end());
}
template <typename T, typename Compare>
[[nodiscard]] constexpr T Max(std::initializer_list<T> ilist, Compare comp)
{
return *MaxElement(ilist.begin(), ilist.end(), comp);
}
template <typename T> template <typename T>
[[nodiscard]] constexpr T Clamp( const T& val, const T& minVal, const T& maxVal ) [[nodiscard]] constexpr T Clamp( const T& val, const T& minVal, const T& maxVal )
{ {

View File

@ -0,0 +1,39 @@
#pragma once
#include <Orange/Core/AlignedStorage.h>
#include <Orange/Core/Traits.h>
namespace orange
{
template <typename... Types>
class Variant
{
public:
static constexpr size_t MaxElementSize = Max({sizeof(Types)...});
static constexpr size_t Alignment = Max({alignof(Types)...});
explicit Variant()
{
}
template <typename T, typename... Args>
Variant(Args&&... args)
{
Construct<T>(Forward(args)...);
}
template <typename T, typename... Args>
void Construct(Args&&... args)
{
new (Ptr<T>()) T(Forward(args)...);
}
template <typename T> T* Ptr() { return reinterpret_cast<T*>(data.data); }
template <typename T> const T* Ptr() const { return reinterpret_cast<T*>(data.data); }
template <typename T> T& Get() { return *Ptr<T>(); }
template <typename T> const T& Get() const { return *Ptr<T>(); }
private:
AlignedStorage<MaxElementSize, Alignment> data;
};
}

View File

@ -6,6 +6,7 @@
#include <Orange/Math/Vector.h> #include <Orange/Math/Vector.h>
#include <Orange/Math/Matrix.h> #include <Orange/Math/Matrix.h>
#include <Orange/Core/Parse.h> #include <Orange/Core/Parse.h>
#include <Orange/Core/Variant.h>
#include <Orange/Render/Window.h> #include <Orange/Render/Window.h>
#include <Orange/Render/RenderContext.h> #include <Orange/Render/RenderContext.h>
@ -34,14 +35,14 @@ enum class MeshVertexType
Skinned, Skinned,
}; };
struct Vertex struct StaticVertex
{ {
vec3 pos; vec3 pos;
vec2 uv; vec2 uv;
vec3 normal; vec3 normal;
vec3 tangent; vec3 tangent;
bool operator == (const Vertex& other) const bool operator == (const StaticVertex& other) const
{ {
return pos == other.pos && return pos == other.pos &&
uv == other.uv && uv == other.uv &&
@ -50,7 +51,7 @@ struct Vertex
} }
}; };
struct SkinnedVertex : public Vertex struct SkinnedVertex : public StaticVertex
{ {
static constexpr uint32_t MaxVertexWeights = 4; static constexpr uint32_t MaxVertexWeights = 4;
@ -66,24 +67,45 @@ struct SkinnedVertex : public Vertex
Array<uint8_t, MaxVertexWeights> boneIndices; Array<uint8_t, MaxVertexWeights> boneIndices;
Array<uint8_t, MaxVertexWeights> boneWeights; Array<uint8_t, MaxVertexWeights> boneWeights;
} };
struct MeshData struct MeshData
{ {
MeshVertexType vertexType; MeshData(MeshVertexType type)
union : vertexType(type)
{ {
Vector<Vertex> staticVertices; switch(type)
Vector<SkinnedVertex> skinnedVertices; {
}; case MeshVertexType::Static:
vertices.Construct<Vector<StaticVertex>>();
break;
case MeshVertexType::Skinned:
vertices.Construct<Vector<SkinnedVertex>>();
break;
}
}
Vector<StaticVertex>& GetStaticVertices()
{
Assert(vertexType == MeshVertexType::Static);
return vertices.Get<Vector<StaticVertex>>();
}
Vector<SkinnedVertex>& GetSkinnedVertices()
{
Assert(vertexType == MeshVertexType::Skinned);
return vertices.Get<Vector<SkinnedVertex>>();
}
MeshVertexType vertexType;
Variant<Vector<StaticVertex>, Vector<SkinnedVertex>> vertices;
Vector<uint16_t> indices; Vector<uint16_t> indices;
AABB bounds; AABB bounds;
}; };
Result<MeshData> ParseOBJ(StringView buffer) Result<MeshData> ParseOBJ(StringView buffer)
{ {
MeshData data; MeshData data{ MeshVertexType::Static };
data.vertexType = MeshVertexType::Static;
Vector<vec3> positions; Vector<vec3> positions;
Vector<vec2> uvs; Vector<vec2> uvs;
@ -148,18 +170,20 @@ Result<MeshData> ParseOBJ(StringView buffer)
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
Vertex vertex = StaticVertex vertex =
{ {
.pos = indices[i][0] != -1 ? positions[indices[i][0]] : vec3{}, .pos = indices[i][0] != -1 ? positions[indices[i][0]] : vec3{},
.uv = indices[i][1] != -1 ? uvs [indices[i][1]] : vec2{}, .uv = indices[i][1] != -1 ? uvs [indices[i][1]] : vec2{},
.normal = indices[i][2] != -1 ? normals [indices[i][2]] : vec3{}, .normal = indices[i][2] != -1 ? normals [indices[i][2]] : vec3{},
}; };
size_t vertexIdx = data.staticVertices.FindIdx(vertex); auto& vertices = data.GetStaticVertices();
if (vertexIdx == Vector<Vertex>::InvalidIdx)
size_t vertexIdx = vertices.FindIdx(vertex);
if (vertexIdx == vertices.InvalidIdx)
{ {
data.bounds.Extend(vertex.pos); data.bounds.Extend(vertex.pos);
vertexIdx = data.staticVertices.PushBack(vertex); vertexIdx = vertices.PushBack(vertex);
} }
Assert(vertexIdx < UINT16_MAX); Assert(vertexIdx < UINT16_MAX);