From c70779bfff25efdedb1ee7f8a9a797e945387e27 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 12 Aug 2022 12:26:36 +0000 Subject: [PATCH] Variant stuff --- include/Orange/Core/Traits.h | 92 ++++++++++++++++++++++++++++++++++- include/Orange/Core/Variant.h | 39 +++++++++++++++ src/Apps/Tools/CubeTest.cpp | 54 ++++++++++++++------ 3 files changed, 168 insertions(+), 17 deletions(-) create mode 100644 include/Orange/Core/Variant.h diff --git a/include/Orange/Core/Traits.h b/include/Orange/Core/Traits.h index ec5019c..dea4040 100644 --- a/include/Orange/Core/Traits.h +++ b/include/Orange/Core/Traits.h @@ -37,6 +37,70 @@ namespace orange return static_cast&&>(arg); } + template + [[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 + [[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 + [[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 + [[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 [[nodiscard]] constexpr size_t Size(const T (&array)[N]) noexcept { @@ -45,17 +109,41 @@ namespace orange } template - [[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 - [[nodiscard]] constexpr T Max( const T& valMin, const T& valMax ) + [[nodiscard]] constexpr T Min(std::initializer_list ilist) + { + return *MinElement(ilist.begin(), ilist.end()); + } + + template + [[nodiscard]] constexpr T Min(std::initializer_list ilist, Compare comp) + { + return *MinElement(ilist.begin(), ilist.end(), comp); + } + + template + [[nodiscard]] constexpr T Max(const T& valMin, const T& valMax) { return valMin > valMax ? valMin : valMax; } + template + [[nodiscard]] constexpr T Max(std::initializer_list ilist) + { + return *MaxElement(ilist.begin(), ilist.end()); + } + + template + [[nodiscard]] constexpr T Max(std::initializer_list ilist, Compare comp) + { + return *MaxElement(ilist.begin(), ilist.end(), comp); + } + template [[nodiscard]] constexpr T Clamp( const T& val, const T& minVal, const T& maxVal ) { diff --git a/include/Orange/Core/Variant.h b/include/Orange/Core/Variant.h new file mode 100644 index 0000000..7ad2f31 --- /dev/null +++ b/include/Orange/Core/Variant.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +namespace orange +{ + template + class Variant + { + public: + static constexpr size_t MaxElementSize = Max({sizeof(Types)...}); + static constexpr size_t Alignment = Max({alignof(Types)...}); + + explicit Variant() + { + } + + template + Variant(Args&&... args) + { + Construct(Forward(args)...); + } + + template + void Construct(Args&&... args) + { + new (Ptr()) T(Forward(args)...); + } + + template T* Ptr() { return reinterpret_cast(data.data); } + template const T* Ptr() const { return reinterpret_cast(data.data); } + + template T& Get() { return *Ptr(); } + template const T& Get() const { return *Ptr(); } + private: + AlignedStorage data; + }; +} diff --git a/src/Apps/Tools/CubeTest.cpp b/src/Apps/Tools/CubeTest.cpp index 6ce3d90..995ce0e 100644 --- a/src/Apps/Tools/CubeTest.cpp +++ b/src/Apps/Tools/CubeTest.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -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 boneIndices; Array boneWeights; -} +}; struct MeshData { - MeshVertexType vertexType; - union + MeshData(MeshVertexType type) + : vertexType(type) { - Vector staticVertices; - Vector skinnedVertices; - }; + switch(type) + { + case MeshVertexType::Static: + vertices.Construct>(); + break; + case MeshVertexType::Skinned: + vertices.Construct>(); + break; + } + } + + Vector& GetStaticVertices() + { + Assert(vertexType == MeshVertexType::Static); + return vertices.Get>(); + } + + Vector& GetSkinnedVertices() + { + Assert(vertexType == MeshVertexType::Skinned); + return vertices.Get>(); + } + + MeshVertexType vertexType; + Variant, Vector> vertices; Vector indices; AABB bounds; }; Result ParseOBJ(StringView buffer) { - MeshData data; - data.vertexType = MeshVertexType::Static; + MeshData data{ MeshVertexType::Static }; Vector positions; Vector uvs; @@ -148,18 +170,20 @@ Result 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::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);