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