Variant stuff
This commit is contained in:
parent
92f8669d5a
commit
c70779bfff
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue