|
@@ -0,0 +1,1273 @@
|
|
|
+// Copyright 2016 Chris Conway (Koderz). All Rights Reserved.
|
|
|
+
|
|
|
+#pragma once
|
|
|
+
|
|
|
+#include "RuntimeMeshCore.h"
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+//
|
|
|
+// This file contains a generic vertex structure capable of efficiently representing a vertex
|
|
|
+// with any combination of position, normal, tangent, color, and 0-8 uv channels.
|
|
|
+//
|
|
|
+// To get around an issue with MSVC and potentially other compilers not performing
|
|
|
+// empty base class optimizations (EBO) to children in multiple inheritance,
|
|
|
+// this vertex is built via a tree of inheritance using partial specializations.
|
|
|
+//
|
|
|
+// At each tier of this tree partial specialization will choose which components
|
|
|
+// we need to add in, thereby removing entire inherited classes when we don't need them.
|
|
|
+//
|
|
|
+// Structure:
|
|
|
+// FRuntimeMeshVertex
|
|
|
+// / \
|
|
|
+// FRuntimeMeshPositionNormalTangentComponentCombiner FRuntimeMeshColorUVComponentCombiner
|
|
|
+// / \ / \
|
|
|
+// FRuntimeMeshPositionComponent \ FRuntimeMeshColorComponent \
|
|
|
+// \ \
|
|
|
+// FRuntimeMeshNormalTangentComponents FRuntimeMeshUVComponents
|
|
|
+//
|
|
|
+//
|
|
|
+//
|
|
|
+//
|
|
|
+//
|
|
|
+// Example use: (This defines a vertex with all components and 1 UV with default precision for normal/tangent and UV)
|
|
|
+//
|
|
|
+// using MyVertex = FRuntimeMeshVertex<true, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::Default>;
|
|
|
+//
|
|
|
+// MyVertex Vertex;
|
|
|
+// Vertex.Position = FVector(0,0,0);
|
|
|
+// Vertex.Normal = FVector(0,0,0);
|
|
|
+// Vertex.UV0 = FVector2D(0,0);
|
|
|
+//
|
|
|
+//
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+
|
|
|
+template<int32 TextureChannels, bool HalfPrecisionUVs, bool HasPositionComponent>
|
|
|
+RuntimeMeshVertexStructure CreateVertexStructure(const FVertexBuffer& VertexBuffer);
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Texture Component Type Selector
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+enum class ERuntimeMeshVertexUVType
|
|
|
+{
|
|
|
+ Default = 1,
|
|
|
+ HighPrecision = 2,
|
|
|
+};
|
|
|
+
|
|
|
+template<ERuntimeMeshVertexUVType UVType>
|
|
|
+struct FRuntimeMeshVertexUVsTypeSelector;
|
|
|
+
|
|
|
+template<>
|
|
|
+struct FRuntimeMeshVertexUVsTypeSelector<ERuntimeMeshVertexUVType::Default>
|
|
|
+{
|
|
|
+ typedef FVector2DHalf UVsType;
|
|
|
+ static const EVertexElementType VertexElementType1Channel = VET_Half2;
|
|
|
+ static const EVertexElementType VertexElementType2Channel = VET_Half4;
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+template<>
|
|
|
+struct FRuntimeMeshVertexUVsTypeSelector<ERuntimeMeshVertexUVType::HighPrecision>
|
|
|
+{
|
|
|
+ typedef FVector2D UVsType;
|
|
|
+ static const EVertexElementType VertexElementType1Channel = VET_Float2;
|
|
|
+ static const EVertexElementType VertexElementType2Channel = VET_Float4;
|
|
|
+};
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Texture Component
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Defaulted to 0 channels) */
|
|
|
+template<int32 TextureChannels, typename UVType> struct FRuntimeMeshUVComponents
|
|
|
+{
|
|
|
+ static_assert(TextureChannels >= 0 && TextureChannels <= 8, "You must have between 0 and 8 (inclusive) UV channels");
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 0 channels) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<0, UVType>
|
|
|
+{
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) { }
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 1 channels) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<1, UVType>
|
|
|
+{
|
|
|
+ UVType UV0;
|
|
|
+
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) : UV0(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0) : UV0(InUV0) { }
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 2 channels) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<2, UVType>
|
|
|
+{
|
|
|
+ UVType UV0;
|
|
|
+ UVType UV1;
|
|
|
+
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) : UV0(0, 0), UV1(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0) : UV0(InUV0), UV1(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) : UV0(InUV0), UV1(InUV1) { }
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 3 channels) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<3, UVType>
|
|
|
+{
|
|
|
+ UVType UV0;
|
|
|
+ UVType UV1;
|
|
|
+ UVType UV2;
|
|
|
+
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) :
|
|
|
+ UV0(0, 0), UV1(0, 0), UV2(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0) :
|
|
|
+ UV0(InUV0), UV1(0, 0), UV2(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2) { }
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 4 channels) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<4, UVType>
|
|
|
+{
|
|
|
+ UVType UV0;
|
|
|
+ UVType UV1;
|
|
|
+ UVType UV2;
|
|
|
+ UVType UV3;
|
|
|
+
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) :
|
|
|
+ UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0) :
|
|
|
+ UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3) { }
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 5 channels) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<5, UVType>
|
|
|
+{
|
|
|
+ UVType UV0;
|
|
|
+ UVType UV1;
|
|
|
+ UVType UV2;
|
|
|
+ UVType UV3;
|
|
|
+ UVType UV4;
|
|
|
+
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) :
|
|
|
+ UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0) :
|
|
|
+ UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0), UV4(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0), UV4(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4) : UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4) { }
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 6 channels, Half Precision) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<6, UVType>
|
|
|
+{
|
|
|
+ UVType UV0;
|
|
|
+ UVType UV1;
|
|
|
+ UVType UV2;
|
|
|
+ UVType UV3;
|
|
|
+ UVType UV4;
|
|
|
+ UVType UV5;
|
|
|
+
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) :
|
|
|
+ UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0) :
|
|
|
+ UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0), UV4(0, 0), UV5(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(0, 0), UV5(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4, const FVector2D& InUV5) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5) { }
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 7 channels) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<7, UVType>
|
|
|
+{
|
|
|
+ UVType UV0;
|
|
|
+ UVType UV1;
|
|
|
+ UVType UV2;
|
|
|
+ UVType UV3;
|
|
|
+ UVType UV4;
|
|
|
+ UVType UV5;
|
|
|
+ UVType UV6;
|
|
|
+
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) :
|
|
|
+ UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0) :
|
|
|
+ UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(0, 0), UV6(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4, const FVector2D& InUV5) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4, const FVector2D& InUV5, const FVector2D& InUV6) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(InUV6) { }
|
|
|
+};
|
|
|
+
|
|
|
+/* Defines the UV coordinates for a vertex (Specialized to 8 channels) */
|
|
|
+template<typename UVType> struct FRuntimeMeshUVComponents<8, UVType>
|
|
|
+{
|
|
|
+ UVType UV0;
|
|
|
+ UVType UV1;
|
|
|
+ UVType UV2;
|
|
|
+ UVType UV3;
|
|
|
+ UVType UV4;
|
|
|
+ UVType UV5;
|
|
|
+ UVType UV6;
|
|
|
+ UVType UV7;
|
|
|
+
|
|
|
+ FRuntimeMeshUVComponents() { }
|
|
|
+ FRuntimeMeshUVComponents(EForceInit) :
|
|
|
+ UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0) :
|
|
|
+ UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4, const FVector2D& InUV5) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(0, 0), UV7(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4, const FVector2D& InUV5, const FVector2D& InUV6) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(InUV6), UV7(0, 0) { }
|
|
|
+ FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
|
|
|
+ const FVector2D& InUV4, const FVector2D& InUV5, const FVector2D& InUV6, const FVector2D& InUV7) :
|
|
|
+ UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(InUV6), UV7(InUV7) { }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Tangent Basis Component Type Selector
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+enum class ERuntimeMeshVertexTangentBasisType
|
|
|
+{
|
|
|
+ Default = 1,
|
|
|
+ HighPrecision = 2,
|
|
|
+};
|
|
|
+
|
|
|
+template<ERuntimeMeshVertexTangentBasisType TangentBasisType>
|
|
|
+struct FRuntimeMeshVertexTangentTypeSelector;
|
|
|
+
|
|
|
+template<>
|
|
|
+struct FRuntimeMeshVertexTangentTypeSelector<ERuntimeMeshVertexTangentBasisType::Default>
|
|
|
+{
|
|
|
+ typedef FPackedNormal TangentType;
|
|
|
+ static const EVertexElementType VertexElementType = VET_PackedNormal;
|
|
|
+};
|
|
|
+
|
|
|
+template<>
|
|
|
+struct FRuntimeMeshVertexTangentTypeSelector<ERuntimeMeshVertexTangentBasisType::HighPrecision>
|
|
|
+{
|
|
|
+ typedef FPackedRGBA16N TangentType;
|
|
|
+ static const EVertexElementType VertexElementType = VET_UShort4N;
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Tangent Basis Components
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+template<bool WantsNormal, bool WantsTangent, typename TangentType>
|
|
|
+struct FRuntimeMeshNormalTangentComponents;
|
|
|
+
|
|
|
+struct RuntimeMeshNormalUtil
|
|
|
+{
|
|
|
+ static void SetNormalW(FPackedNormal& Target, float Determinant)
|
|
|
+ {
|
|
|
+ Target.Vector.W = Determinant < 0.0f ? 0 : 255;
|
|
|
+ }
|
|
|
+
|
|
|
+ static void SetNormalW(FPackedRGBA16N& Target, float Determinant)
|
|
|
+ {
|
|
|
+ Target.W = Determinant < 0.0f ? 0 : 65535;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+template<typename TangentType>
|
|
|
+struct FRuntimeMeshNormalTangentComponents<true, false, TangentType>
|
|
|
+{
|
|
|
+ TangentType Normal;
|
|
|
+
|
|
|
+ FRuntimeMeshNormalTangentComponents() { }
|
|
|
+ FRuntimeMeshNormalTangentComponents(EForceInit) : Normal(FVector4(0.0f, 0.0f, 1.0f, 1.0f)) { }
|
|
|
+
|
|
|
+ void SetNormalAndTangent(const FVector& InNormal, const FRuntimeMeshTangent& InTangent)
|
|
|
+ {
|
|
|
+ Normal = InNormal;
|
|
|
+
|
|
|
+ InTangent.AdjustNormal(Normal);
|
|
|
+ }
|
|
|
+
|
|
|
+ void SetNormalAndTangent(const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ)
|
|
|
+ {
|
|
|
+ Normal = InTangentZ;
|
|
|
+
|
|
|
+ // store determinant of basis in w component of normal vector
|
|
|
+ RuntimeMeshNormalUtil::SetNormalW(Normal, GetBasisDeterminantSign(InTangentX, InTangentY, InTangentZ));
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+template<typename TangentType>
|
|
|
+struct FRuntimeMeshNormalTangentComponents<false, true, TangentType>
|
|
|
+{
|
|
|
+ TangentType Tangent;
|
|
|
+
|
|
|
+ FRuntimeMeshNormalTangentComponents() { }
|
|
|
+ FRuntimeMeshNormalTangentComponents(EForceInit) : Tangent(FVector(1.0f, 0.0f, 0.0f)) { }
|
|
|
+
|
|
|
+ void SetNormalAndTangent(const FVector& InNormal, const FRuntimeMeshTangent& InTangent)
|
|
|
+ {
|
|
|
+ Tangent = InTangent.TangentX;
|
|
|
+ }
|
|
|
+
|
|
|
+ void SetNormalAndTangent(const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ)
|
|
|
+ {
|
|
|
+ Tangent = InTangentX;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+template<typename TangentType>
|
|
|
+struct FRuntimeMeshNormalTangentComponents<true, true, TangentType>
|
|
|
+{
|
|
|
+ TangentType Normal;
|
|
|
+ TangentType Tangent;
|
|
|
+
|
|
|
+ FRuntimeMeshNormalTangentComponents() { }
|
|
|
+ FRuntimeMeshNormalTangentComponents(EForceInit) : Normal(FVector4(0.0f, 0.0f, 1.0f, 1.0f)), Tangent(FVector(1.0f, 0.0f, 0.0f)) { }
|
|
|
+
|
|
|
+ void SetNormalAndTangent(const FVector& InNormal, const FRuntimeMeshTangent& InTangent)
|
|
|
+ {
|
|
|
+ Normal = InNormal;
|
|
|
+ Tangent = InTangent.TangentX;
|
|
|
+
|
|
|
+ InTangent.AdjustNormal(Normal);
|
|
|
+ }
|
|
|
+
|
|
|
+ void SetNormalAndTangent(const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ)
|
|
|
+ {
|
|
|
+ Normal = InTangentZ;
|
|
|
+ Tangent = InTangentX;
|
|
|
+
|
|
|
+ // store determinant of basis in w component of normal vector
|
|
|
+ RuntimeMeshNormalUtil::SetNormalW(Normal, GetBasisDeterminantSign(InTangentX, InTangentY, InTangentZ));
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Position Component
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+template<bool WantsPosition>
|
|
|
+struct FRuntimeMeshPositionComponent;
|
|
|
+
|
|
|
+template<>
|
|
|
+struct FRuntimeMeshPositionComponent<true>
|
|
|
+{
|
|
|
+ FVector Position;
|
|
|
+
|
|
|
+ FRuntimeMeshPositionComponent() { }
|
|
|
+ FRuntimeMeshPositionComponent(EForceInit) : Position(0.0f, 0.0f, 0.0f) { }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Color Component
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+template<bool WantsColor>
|
|
|
+struct FRuntimeMeshColorComponent;
|
|
|
+
|
|
|
+template<>
|
|
|
+struct FRuntimeMeshColorComponent<true>
|
|
|
+{
|
|
|
+ FColor Color;
|
|
|
+
|
|
|
+ FRuntimeMeshColorComponent() { }
|
|
|
+ FRuntimeMeshColorComponent(EForceInit) : Color(FColor::White) { }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Position Normal Tangent Combiner
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+template<bool WantsPosition, bool WantsNormal, bool WantsTangent, typename TangentBasisType>
|
|
|
+struct FRuntimeMeshPositionNormalTangentComponentCombiner :
|
|
|
+ public FRuntimeMeshPositionComponent<WantsPosition>,
|
|
|
+ public FRuntimeMeshNormalTangentComponents<WantsNormal, WantsTangent, TangentBasisType>
|
|
|
+{
|
|
|
+ FRuntimeMeshPositionNormalTangentComponentCombiner() { }
|
|
|
+ FRuntimeMeshPositionNormalTangentComponentCombiner(EForceInit)
|
|
|
+ : FRuntimeMeshPositionComponent<WantsPosition>(EForceInit::ForceInit)
|
|
|
+ , FRuntimeMeshNormalTangentComponents<WantsNormal, WantsTangent, TangentBasisType>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+template<bool WantsPosition, typename TangentBasisType>
|
|
|
+struct FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, false, false, TangentBasisType> :
|
|
|
+ public FRuntimeMeshPositionComponent<WantsPosition>
|
|
|
+{
|
|
|
+ FRuntimeMeshPositionNormalTangentComponentCombiner() { }
|
|
|
+ FRuntimeMeshPositionNormalTangentComponentCombiner(EForceInit)
|
|
|
+ : FRuntimeMeshPositionComponent<WantsPosition>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+template<bool WantsNormal, bool WantsTangent, typename TangentBasisType>
|
|
|
+struct FRuntimeMeshPositionNormalTangentComponentCombiner<false, WantsNormal, WantsTangent, TangentBasisType> :
|
|
|
+ public FRuntimeMeshNormalTangentComponents<WantsNormal, WantsTangent, TangentBasisType>
|
|
|
+{
|
|
|
+ FRuntimeMeshPositionNormalTangentComponentCombiner() { }
|
|
|
+ FRuntimeMeshPositionNormalTangentComponentCombiner(EForceInit)
|
|
|
+ : FRuntimeMeshNormalTangentComponents<WantsNormal, WantsTangent, TangentBasisType>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+template<typename TangentBasisType>
|
|
|
+struct FRuntimeMeshPositionNormalTangentComponentCombiner<false, false, false, TangentBasisType>;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Color UV Combiner
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+template<bool WantsColor, int32 NumWantedUVChannels, typename UVType>
|
|
|
+struct FRuntimeMeshColorUVComponentCombiner :
|
|
|
+ public FRuntimeMeshColorComponent<WantsColor>,
|
|
|
+ public FRuntimeMeshUVComponents<NumWantedUVChannels, UVType>
|
|
|
+{
|
|
|
+ FRuntimeMeshColorUVComponentCombiner() { }
|
|
|
+ FRuntimeMeshColorUVComponentCombiner(EForceInit)
|
|
|
+ : FRuntimeMeshColorComponent<WantsColor>(EForceInit::ForceInit)
|
|
|
+ , FRuntimeMeshUVComponents<NumWantedUVChannels, UVType>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+template<int32 NumWantedUVChannels, typename UVType>
|
|
|
+struct FRuntimeMeshColorUVComponentCombiner<false, NumWantedUVChannels, UVType> :
|
|
|
+ public FRuntimeMeshUVComponents<NumWantedUVChannels, UVType>
|
|
|
+{
|
|
|
+ FRuntimeMeshColorUVComponentCombiner() { }
|
|
|
+ FRuntimeMeshColorUVComponentCombiner(EForceInit)
|
|
|
+ : FRuntimeMeshUVComponents<NumWantedUVChannels, UVType>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+template<bool WantsColor, typename UVType>
|
|
|
+struct FRuntimeMeshColorUVComponentCombiner<WantsColor, 0, UVType> :
|
|
|
+ public FRuntimeMeshColorComponent<WantsColor>
|
|
|
+{
|
|
|
+ FRuntimeMeshColorUVComponentCombiner() { }
|
|
|
+ FRuntimeMeshColorUVComponentCombiner(EForceInit)
|
|
|
+ : FRuntimeMeshColorComponent<WantsColor>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+template<typename UVType>
|
|
|
+struct FRuntimeMeshColorUVComponentCombiner<false, 0, UVType>;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Template Vertex Type Info Structure
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+template<bool WantsPosition, bool WantsNormal, bool WantsTangent, bool WantsColor, int32 NumWantedUVChannels,
|
|
|
+ ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
|
|
|
+struct FRuntimeMeshVertexTypeInfo_GenericVertex : public FRuntimeMeshVertexTypeInfo
|
|
|
+{
|
|
|
+ FRuntimeMeshVertexTypeInfo_GenericVertex(FString VertexName) :
|
|
|
+ FRuntimeMeshVertexTypeInfo(
|
|
|
+ FString::Printf(TEXT("RuntimeMeshVertex<%d, %d, %d, %d, %d, %d, %d>"), WantsPosition, WantsNormal, WantsTangent, WantsColor, NumWantedUVChannels, (int32)NormalTangentType, (int32)UVType),
|
|
|
+ GetVertexGuid(VertexName)) { }
|
|
|
+
|
|
|
+ static FGuid GetVertexGuid(FString VertexName)
|
|
|
+ {
|
|
|
+ uint32 TypeID = 0;
|
|
|
+ TypeID = (TypeID << 1) | (WantsPosition ? 1 : 0);
|
|
|
+ TypeID = (TypeID << 1) | (WantsNormal ? 1 : 0);
|
|
|
+ TypeID = (TypeID << 1) | (WantsTangent ? 1 : 0);
|
|
|
+ TypeID = (TypeID << 3) | (uint32)NormalTangentType;
|
|
|
+ TypeID = (TypeID << 1) | (WantsColor ? 1 : 0);
|
|
|
+ TypeID = (TypeID << 6) | (NumWantedUVChannels & 0xFF);
|
|
|
+ TypeID = (TypeID << 3) | (uint32)UVType;
|
|
|
+
|
|
|
+ FGuid Guid = FGuid(0x00FFEB44, 0x31094597, /*0x93918032*/ GetTypeHash(VertexName), (0x78C3 << 16) | TypeID);
|
|
|
+ return Guid;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Macros to create a custom vertex type based on the generic vertex and implement some common constructors
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_POSITION_true Position = FVector(0.0f, 0.0f, 0.0f);
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_POSITION_false
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_POSITION(HasPosition) RUNTIMEMESH_VERTEX_DEFAULTINIT_POSITION_##HasPosition
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL_true Normal = FVector4(0.0f, 0.0f, 1.0f, 1.0f);
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL_false
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL(HasNormal) RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL_##HasNormal
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT_true Tangent = FVector(1.0f, 0.0f, 0.0f);
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT_false
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT(HasTangent) RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT_##HasTangent
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR_true Color = FColor::White;
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR_false
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(HasColor) RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR_##HasColor
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_0
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_1 \
|
|
|
+ UV0 = FVector2D(0.0f, 0.0f);
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_2 \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_1 \
|
|
|
+ UV1 = FVector2D(0.0f, 0.0f);
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_3 \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_2 \
|
|
|
+ UV2 = FVector2D(0.0f, 0.0f);
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_4 \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_3 \
|
|
|
+ UV3 = FVector2D(0.0f, 0.0f);
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_5 \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_4 \
|
|
|
+ UV4 = FVector2D(0.0f, 0.0f);
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_6 \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_5 \
|
|
|
+ UV5 = FVector2D(0.0f, 0.0f);
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_7 \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_6 \
|
|
|
+ UV6 = FVector2D(0.0f, 0.0f);
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_8 \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_7 \
|
|
|
+ UV7 = FVector2D(0.0f, 0.0f);
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNELS(NumChannels) RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_##NumChannels
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_0
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_1 , const FVector2D& InUV0 = FVector2D::ZeroVector
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_2 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_1 , const FVector2D& InUV1 = FVector2D::ZeroVector
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_3 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_2 , const FVector2D& InUV2 = FVector2D::ZeroVector
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_4 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_3 , const FVector2D& InUV3 = FVector2D::ZeroVector
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_5 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_4 , const FVector2D& InUV4 = FVector2D::ZeroVector
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_6 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_5 , const FVector2D& InUV5 = FVector2D::ZeroVector
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_7 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_6 , const FVector2D& InUV6 = FVector2D::ZeroVector
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_8 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_7 , const FVector2D& InUV7 = FVector2D::ZeroVector
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(NumChannels) RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_##NumChannels
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_0
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_1 \
|
|
|
+ UV0 = InUV0;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_2 \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_1 \
|
|
|
+ UV1 = InUV1;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_3 \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_2 \
|
|
|
+ UV2 = InUV2;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_4 \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_3 \
|
|
|
+ UV3 = InUV3;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_5 \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_4 \
|
|
|
+ UV4 = InUV4;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_6 \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_5 \
|
|
|
+ UV5 = InUV5;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_7 \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_6 \
|
|
|
+ UV6 = InUV6;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_8 \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_7 \
|
|
|
+ UV7 = InUV7;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(NumChannels) RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_##NumChannels
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_POSITION_true const FVector& InPosition,
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_POSITION_false
|
|
|
+#define RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) RUNTIMEMESH_VERTEX_PARAMETER_POSITION_##NeedsPosition
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_POSITION_true Position = InPosition;
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_POSITION_false
|
|
|
+#define RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) RUNTIMEMESH_VERTEX_INIT_POSITION_##NeedsPosition
|
|
|
+
|
|
|
+
|
|
|
+// PreProcessor IF with pass through for all the constructor arguments
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, Condition, IfTrue) \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF_##Condition(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, IfTrue)
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF_false(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, IfTrue)
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF_true(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, IfTrue) IfTrue
|
|
|
+
|
|
|
+
|
|
|
+// Implementation of Position only Constructor
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ VertexName(const FVector& InPosition) \
|
|
|
+ { \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL(NeedsNormal) \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT(NeedsTangent) \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(NeedsColor) \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNELS(UVChannelCount) \
|
|
|
+ }
|
|
|
+
|
|
|
+// Defines the Position Constuctor if it's wanted
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsPosition, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ )
|
|
|
+
|
|
|
+// Implementation of Position/Normal Constructor
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InNormal) \
|
|
|
+ { \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
|
|
|
+ Normal = InNormal; \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT(NeedsTangent) \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(NeedsColor) \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNELS(UVChannelCount) \
|
|
|
+ }
|
|
|
+
|
|
|
+// Defines the Position/Normal Constuctor if it's wanted
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ )
|
|
|
+
|
|
|
+// Implementation of Position/Color Constructor
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FColor& InColor) \
|
|
|
+ { \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL(NeedsNormal) \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT(NeedsTangent) \
|
|
|
+ Color = InColor; \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNELS(UVChannelCount) \
|
|
|
+ }
|
|
|
+
|
|
|
+// Defines the Position/Color Constructor if it's wanted
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsColor, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// Implementation of Position/Normal/Tangent Constructor
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InNormal, const FRuntimeMeshTangent& InTangent RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(UVChannelCount)) \
|
|
|
+ { \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
|
|
|
+ Normal = InNormal; \
|
|
|
+ Tangent = InTangent.TangentX; \
|
|
|
+ InTangent.AdjustNormal(Normal); \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(NeedsColor) \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(UVChannelCount) \
|
|
|
+ }
|
|
|
+
|
|
|
+// Defines the Position/Normal/Tangent Constructor if it's wanted
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsTangent, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ ) \
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+// Implementation of Position/TangentX/TangentY/TangentZ Constructor
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(UVChannelCount)) \
|
|
|
+ { \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
|
|
|
+ SetNormalAndTangent(InTangentX, InTangentY, InTangentZ); \
|
|
|
+ RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(NeedsColor) \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(UVChannelCount) \
|
|
|
+ }
|
|
|
+
|
|
|
+// Defines the Position/TangentX/TangentY/TangentZ Constructor if it's wanted
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsTangent, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ ) \
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// Implementation of Position/Normal/Tangent Constructor
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InNormal, const FRuntimeMeshTangent& InTangent, const FColor& InColor RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(UVChannelCount)) \
|
|
|
+ { \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
|
|
|
+ Normal = InNormal; \
|
|
|
+ Tangent = InTangent.TangentX; \
|
|
|
+ InTangent.AdjustNormal(Normal); \
|
|
|
+ Color = InColor; \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(UVChannelCount) \
|
|
|
+ }
|
|
|
+
|
|
|
+// Defines the Position/Normal/Tangent Constructor if it's wanted
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsTangent, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsColor, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ ) \
|
|
|
+ ) \
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+// Implementation of Position/TangentX/TangentY/TangentZ Constructor
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ, const FColor& InColor RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(UVChannelCount)) \
|
|
|
+ { \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
|
|
|
+ SetNormalAndTangent(InTangentX, InTangentY, InTangentZ); \
|
|
|
+ Color = InColor; \
|
|
|
+ RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(UVChannelCount) \
|
|
|
+ }
|
|
|
+
|
|
|
+// Defines the Position/TangentX/TangentY/TangentZ Constructor if it's wanted
|
|
|
+#define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsTangent, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsColor, \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ ) \
|
|
|
+ ) \
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION_true Ar << V.Position;
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION_false
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION(NeedsPosition) RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION_##NeedsPosition
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL_true Ar << V.Normal;
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL_false
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL(NeedsNormal) RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL_##NeedsNormal
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT_true Ar << V.Tangent;
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT_false
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT(NeedsTangent) RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT_##NeedsTangent
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR_true Ar << V.Color;
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR_false
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR(NeedsColor) RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR_##NeedsColor
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_0
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_1 \
|
|
|
+ Ar << V.UV0;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_2 \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_1 \
|
|
|
+ Ar << V.UV1;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_3 \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_2 \
|
|
|
+ Ar << V.UV2;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_4 \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_3 \
|
|
|
+ Ar << V.UV3;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_5 \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_4 \
|
|
|
+ Ar << V.UV4;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_6 \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_5 \
|
|
|
+ Ar << V.UV5;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_7 \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_6 \
|
|
|
+ Ar << V.UV6;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_8 \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_7 \
|
|
|
+ Ar << V.UV7;
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNELS(NumChannels) RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_##NumChannels
|
|
|
+
|
|
|
+#define RUNTIMEMESH_VERTEX_SERIALIZER(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount) \
|
|
|
+ friend FArchive& operator<<(FArchive& Ar, VertexName & V) \
|
|
|
+ { \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION(NeedsPosition) \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL(NeedsNormal) \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT(NeedsTangent) \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR(NeedsColor) \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNELS(UVChannelCount) \
|
|
|
+ return Ar; \
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#define DECLARE_RUNTIME_MESH_VERTEXINTERNAL(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, APIQUALIFIER) \
|
|
|
+ struct APIQUALIFIER FRuntimeMeshVertexTypeInfo_##VertexName \
|
|
|
+ : public FRuntimeMeshVertexTypeInfo_GenericVertex<NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType> \
|
|
|
+ { \
|
|
|
+ FRuntimeMeshVertexTypeInfo_##VertexName() \
|
|
|
+ : FRuntimeMeshVertexTypeInfo_GenericVertex<NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType>(TEXT("")) { } \
|
|
|
+ \
|
|
|
+ virtual class FRuntimeMeshSectionInterface* CreateSection(bool bInNeedsPositionOnlyBuffer) const override; \
|
|
|
+ }; \
|
|
|
+ struct APIQUALIFIER VertexName : public FRuntimeMeshVertex<NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType> \
|
|
|
+ { \
|
|
|
+ static const FRuntimeMeshVertexTypeInfo_##VertexName TypeInfo; \
|
|
|
+ \
|
|
|
+ typedef FRuntimeMeshVertex<NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType> Super; \
|
|
|
+ \
|
|
|
+ VertexName() { } \
|
|
|
+ \
|
|
|
+ VertexName(EForceInit) : Super(EForceInit::ForceInit) { } \
|
|
|
+ \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ \
|
|
|
+ RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ \
|
|
|
+ RUNTIMEMESH_VERTEX_SERIALIZER(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount) \
|
|
|
+ };
|
|
|
+
|
|
|
+#define DECLARE_RUNTIME_MESH_VERTEX(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
|
|
|
+ DECLARE_RUNTIME_MESH_VERTEXINTERNAL(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, /**/)
|
|
|
+
|
|
|
+/* Used only for the generic vertex to create the type registration */
|
|
|
+#define DEFINE_RUNTIME_MESH_VERTEX(VertexName) \
|
|
|
+ const FRuntimeMeshVertexTypeInfo_##VertexName VertexName::TypeInfo; \
|
|
|
+ FRuntimeMeshVertexTypeRegistration< VertexName > FRuntimeMeshVertexTypeInfoRegistration_##VertexName; \
|
|
|
+ FRuntimeMeshSectionInterface* FRuntimeMeshVertexTypeInfo_##VertexName::CreateSection(bool bInNeedsPositionOnlyBuffer) const \
|
|
|
+ { \
|
|
|
+ return new FRuntimeMeshSection< VertexName >(bInNeedsPositionOnlyBuffer); \
|
|
|
+ }
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Template Vertex
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+// This version uses both sub combiners since there's at least 1 thing we need from both.
|
|
|
+template<bool WantsPosition, bool WantsNormal, bool WantsTangent, bool WantsColor, int32 NumWantedUVChannels,
|
|
|
+ERuntimeMeshVertexTangentBasisType NormalTangentType = ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType UVType = ERuntimeMeshVertexUVType::Default>
|
|
|
+struct FRuntimeMeshVertex :
|
|
|
+ public FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, WantsNormal, WantsTangent, typename FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::TangentType>,
|
|
|
+ public FRuntimeMeshColorUVComponentCombiner<WantsColor, NumWantedUVChannels, typename FRuntimeMeshVertexUVsTypeSelector<UVType>::UVsType>
|
|
|
+{
|
|
|
+ // Make sure something is enabled
|
|
|
+ static_assert((WantsPosition || WantsNormal || WantsTangent || WantsColor || NumWantedUVChannels > 0), "Invalid configuration... You must have at least 1 component enabled.");
|
|
|
+
|
|
|
+ // Get vertex structure
|
|
|
+ static RuntimeMeshVertexStructure GetVertexStructure(const FVertexBuffer& VertexBuffer);
|
|
|
+
|
|
|
+ FRuntimeMeshVertex() { }
|
|
|
+ FRuntimeMeshVertex(EForceInit)
|
|
|
+ : FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, WantsNormal, WantsTangent, typename FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::TangentType>(EForceInit::ForceInit)
|
|
|
+ , FRuntimeMeshColorUVComponentCombiner<WantsColor, NumWantedUVChannels, typename FRuntimeMeshVertexUVsTypeSelector<UVType>::UVsType>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+// This version only uses the position/normal/tangent combiner as we don't need anything from the other
|
|
|
+template<bool WantsPosition, bool WantsNormal, bool WantsTangent, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
|
|
|
+struct FRuntimeMeshVertex<WantsPosition, WantsNormal, WantsTangent, false, 0, NormalTangentType, UVType> :
|
|
|
+ public FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, WantsNormal, WantsTangent, typename FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::TangentType>
|
|
|
+{
|
|
|
+ // Get vertex structure
|
|
|
+ static RuntimeMeshVertexStructure GetVertexStructure(const FVertexBuffer& VertexBuffer);
|
|
|
+
|
|
|
+ FRuntimeMeshVertex() { }
|
|
|
+ FRuntimeMeshVertex(EForceInit)
|
|
|
+ : FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, WantsNormal, WantsTangent, typename FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::TangentType>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+// This version only uses the color/uv combiner as we don't need anything from the other
|
|
|
+template<bool WantsColor, int32 NumWantedUVChannels, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
|
|
|
+struct FRuntimeMeshVertex<false, false, false, WantsColor, NumWantedUVChannels, NormalTangentType, UVType> :
|
|
|
+ public FRuntimeMeshColorUVComponentCombiner<WantsColor, NumWantedUVChannels, typename FRuntimeMeshVertexUVsTypeSelector<UVType>::UVsType>
|
|
|
+{
|
|
|
+ // Get vertex structure
|
|
|
+ static RuntimeMeshVertexStructure GetVertexStructure(const FVertexBuffer& VertexBuffer);
|
|
|
+
|
|
|
+ FRuntimeMeshVertex() { }
|
|
|
+ FRuntimeMeshVertex(EForceInit)
|
|
|
+ : FRuntimeMeshColorUVComponentCombiner<WantsColor, NumWantedUVChannels, typename FRuntimeMeshVertexUVsTypeSelector<UVType>::UVsType>(EForceInit::ForceInit)
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Vertex Structure Generator
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+struct FRuntimeMeshVertexUtilities
|
|
|
+{
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ // Position Component
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ template<typename RuntimeVertexType, bool WantsPosition>
|
|
|
+ struct FRuntimeMeshPositionComponentUtilities
|
|
|
+ {
|
|
|
+ static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.PositionComponent = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Position, VET_Float3);
|
|
|
+ }
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType>
|
|
|
+ struct FRuntimeMeshPositionComponentUtilities<RuntimeVertexType, false>
|
|
|
+ {
|
|
|
+ static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ // Normal/Tangent Components
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ template<typename RuntimeVertexType, bool WantsNormal, bool WantsTangent, ERuntimeMeshVertexTangentBasisType NormalTangentType>
|
|
|
+ struct FRuntimeMeshNormalTangentComponentVertexStructure
|
|
|
+ {
|
|
|
+ static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TangentBasisComponents[1] = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Normal,
|
|
|
+ FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::VertexElementType);
|
|
|
+ VertexStructure.TangentBasisComponents[0] = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Tangent,
|
|
|
+ FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::VertexElementType);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexTangentBasisType NormalTangentType>
|
|
|
+ struct FRuntimeMeshNormalTangentComponentVertexStructure<RuntimeVertexType, true, false, NormalTangentType>
|
|
|
+ {
|
|
|
+ static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TangentBasisComponents[1] = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Normal,
|
|
|
+ FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::VertexElementType);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexTangentBasisType NormalTangentType>
|
|
|
+ struct FRuntimeMeshNormalTangentComponentVertexStructure<RuntimeVertexType, false, true, NormalTangentType>
|
|
|
+ {
|
|
|
+ static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TangentBasisComponents[0] = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Tangent,
|
|
|
+ FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::VertexElementType);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexTangentBasisType NormalTangentType>
|
|
|
+ struct FRuntimeMeshNormalTangentComponentVertexStructure<RuntimeVertexType, false, false, NormalTangentType>
|
|
|
+ {
|
|
|
+ static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ // Color Component
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ template<typename RuntimeVertexType, bool WantsColor>
|
|
|
+ struct FRuntimeMeshColorComponentVertexStructure
|
|
|
+ {
|
|
|
+ static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.ColorComponent = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Color, VET_Color);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType>
|
|
|
+ struct FRuntimeMeshColorComponentVertexStructure<RuntimeVertexType, false>
|
|
|
+ {
|
|
|
+ static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ // UV Components
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ template<typename RuntimeVertexType, int32 NumWantedUVChannels, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 1, UVType>
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType1Channel));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 2, UVType>
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 3, UVType>
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType1Channel));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 4, UVType>
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 5, UVType>
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV4, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType1Channel));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 6, UVType>
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV4, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 7, UVType>
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV4, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV6, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType1Channel));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 8, UVType>
|
|
|
+ {
|
|
|
+ static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
|
|
|
+ {
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV4, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV6, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ // Vertex Structure Helper
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ template<bool WantsPosition, bool WantsNormal, bool WantsTangent, bool WantsColor, int32 NumWantedUVChannels,
|
|
|
+ ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
|
|
|
+ static RuntimeMeshVertexStructure CreateVertexStructure(const FVertexBuffer& VertexBuffer)
|
|
|
+ {
|
|
|
+ typedef FRuntimeMeshVertex<WantsPosition, WantsNormal, WantsTangent, WantsColor, NumWantedUVChannels, NormalTangentType, UVType> RuntimeVertexType;
|
|
|
+
|
|
|
+ RuntimeMeshVertexStructure VertexStructure;
|
|
|
+
|
|
|
+ // Add Position component if necessary
|
|
|
+ FRuntimeMeshPositionComponentUtilities<RuntimeVertexType, WantsPosition>::AddComponent(VertexBuffer, VertexStructure);
|
|
|
+
|
|
|
+ // Add normal and tangent components if necessary
|
|
|
+ FRuntimeMeshNormalTangentComponentVertexStructure<RuntimeVertexType, WantsNormal, WantsTangent, NormalTangentType>::AddComponent(VertexBuffer, VertexStructure);
|
|
|
+
|
|
|
+ // Add color component if necessary
|
|
|
+ FRuntimeMeshColorComponentVertexStructure<RuntimeVertexType, WantsColor>::AddComponent(VertexBuffer, VertexStructure);
|
|
|
+
|
|
|
+ // Add all texture channels
|
|
|
+ FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, NumWantedUVChannels, UVType>::AddChannels(VertexBuffer, VertexStructure);
|
|
|
+
|
|
|
+ return VertexStructure;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// These need to be declared after FRuntimemeshVertexStructureHelper and RuntimeMeshVertexStructure to fix circular dependencies between the two
|
|
|
+template<bool WantsPosition, bool WantsNormal, bool WantsTangent, bool WantsColor, int32 NumWantedUVChannels, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
|
|
|
+RuntimeMeshVertexStructure FRuntimeMeshVertex<WantsPosition, WantsNormal, WantsTangent, WantsColor, NumWantedUVChannels, NormalTangentType, UVType>::GetVertexStructure(const FVertexBuffer& VertexBuffer)
|
|
|
+{
|
|
|
+ return FRuntimeMeshVertexUtilities::CreateVertexStructure<WantsPosition, WantsNormal, WantsTangent, WantsColor, NumWantedUVChannels, NormalTangentType, UVType>(VertexBuffer);
|
|
|
+}
|
|
|
+
|
|
|
+template<bool WantsPosition, bool WantsNormal, bool WantsTangent, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
|
|
|
+RuntimeMeshVertexStructure FRuntimeMeshVertex<WantsPosition, WantsNormal, WantsTangent, false, 0, NormalTangentType, UVType>::GetVertexStructure(const FVertexBuffer& VertexBuffer)
|
|
|
+{
|
|
|
+ return FRuntimeMeshVertexUtilities::CreateVertexStructure<WantsPosition, WantsNormal, WantsTangent, false, 0, NormalTangentType, UVType>(VertexBuffer);
|
|
|
+}
|
|
|
+
|
|
|
+template<bool WantsColor, int32 NumWantedUVChannels, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
|
|
|
+RuntimeMeshVertexStructure FRuntimeMeshVertex<false, false, false, WantsColor, NumWantedUVChannels, NormalTangentType, UVType>::GetVertexStructure(const FVertexBuffer& VertexBuffer)
|
|
|
+{
|
|
|
+ return FRuntimeMeshVertexUtilities::CreateVertexStructure<false, false, false, WantsColor, NumWantedUVChannels, NormalTangentType, UVType>(VertexBuffer);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+// Name Vertex Configurations
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+/** Simple vertex with 1 UV channel */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexSimple, true, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+/** Simple vertex with 2 UV channels */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexDualUV, true, true, true, true, 2, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+/** Simple vertex with 3 UV channels */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexTripleUV, true, true, true, true, 3, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+/** Simple vertex with 1 UV channel and NO position component (Meant to be used with separate position buffer) */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexNoPosition, false, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+/** Simple vertex with 2 UV channels and NO position component (Meant to be used with separate position buffer) */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexNoPositionDualUV, false, true, true, true, 2, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+/** Simple vertex with 1 UV channel */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexHiPrecisionNormals, true, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::HighPrecision, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+/** Simple vertex with 2 UV channels */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexDualUVHiPrecisionNormals, true, true, true, true, 2, ERuntimeMeshVertexTangentBasisType::HighPrecision, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+/** Simple vertex with 1 UV channel and NO position component (Meant to be used with separate position buffer) */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexNoPositionHiPrecisionNormals, false, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::HighPrecision, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+/** Simple vertex with 2 UV channels and NO position component (Meant to be used with separate position buffer) */
|
|
|
+DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexNoPositionDualUVHiPrecisionNormals, false, true, true, true, 2, ERuntimeMeshVertexTangentBasisType::HighPrecision, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
|
|
|
+
|
|
|
+
|