11/*
2- * Copyright 2019-2023 Diligent Graphics LLC
2+ * Copyright 2019-2024 Diligent Graphics LLC
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
@@ -57,26 +57,68 @@ size_t ModelBuilder::PrimitiveKey::Hasher::operator()(const PrimitiveKey& Key) c
5757 return Key.Hash ;
5858}
5959
60- template <typename SrcType, typename DstType >
61- inline void ConvertElement (DstType& Dst, const SrcType& Src)
60+ template <typename DstType, bool Normalize, typename SrcType >
61+ inline DstType ConvertElement (SrcType Src)
6262{
63- Dst = static_cast <DstType>(Src);
63+ return static_cast <DstType>(Src);
6464}
6565
66+ // =========================== float -> Int8/Uint8 ============================
6667template <>
67- inline void ConvertElement<float , Uint8>(Uint8& Dst, const float & Src)
68+ inline Uint8 ConvertElement<Uint8, true , float >( float Src)
6869{
69- Dst = static_cast <Uint8>(clamp (Src * 255 .f + 0 .5f , 0 .f , 255 .f ));
70+ return static_cast <Uint8>(clamp (Src * 255 .f + 0 .5f , 0 .f , 255 .f ));
7071}
7172
7273template <>
73- inline void ConvertElement<float , Int8>(Int8& Dst, const float & Src)
74+ inline Uint8 ConvertElement<Uint8, false , float >(float Src)
75+ {
76+ return ConvertElement<Uint8, true >(Src);
77+ }
78+
79+ template <>
80+ inline Int8 ConvertElement<Int8, true , float >(float Src)
7481{
7582 auto r = Src > 0 .f ? +0 .5f : -0 .5f ;
76- Dst = static_cast <Int8>(clamp (Src * 127 .f + r, -127 .f , 127 .f ));
83+ return static_cast <Int8>(clamp (Src * 127 .f + r, -127 .f , 127 .f ));
84+ }
85+
86+ template <>
87+ inline Int8 ConvertElement<Int8, false , float >(float Src)
88+ {
89+ return ConvertElement<Int8, true >(Src);
90+ }
91+
92+
93+ // =========================== Int8/Uint8 -> float ============================
94+ template <>
95+ inline float ConvertElement<float , true , Int8>(Int8 Src)
96+ {
97+ return std::max (static_cast <float >(Src), -127 .f ) / 127 .f ;
98+ }
99+
100+ template <>
101+ inline float ConvertElement<float , true , Uint8>(Uint8 Src)
102+ {
103+ return static_cast <float >(Src) / 255 .f ;
104+ }
105+
106+
107+ // ========================== Int16/Uint16 -> float ===========================
108+ template <>
109+ inline float ConvertElement<float , true , Int16>(Int16 Src)
110+ {
111+ return std::max (static_cast <float >(Src), -32767 .f ) / 32767 .f ;
77112}
78113
79- template <typename SrcType, typename DstType>
114+ template <>
115+ inline float ConvertElement<float , true , Uint16>(Uint16 Src)
116+ {
117+ return static_cast <float >(Src) / 65535 .f ;
118+ }
119+
120+
121+ template <typename SrcType, typename DstType, bool IsNormalized>
80122inline void WriteGltfData (const void * pSrc,
81123 Uint32 NumComponents,
82124 Uint32 SrcElemStride,
@@ -91,33 +133,38 @@ inline void WriteGltfData(const void* pSrc,
91133 auto comp_it = dst_it + DstElementStride * elem;
92134 for (Uint32 cmp = 0 ; cmp < NumComponents; ++cmp, comp_it += sizeof (DstType))
93135 {
94- ConvertElement ( reinterpret_cast <DstType&>(*comp_it), pSrcCmp[cmp]);
136+ reinterpret_cast <DstType&>(*comp_it) = ConvertElement<DstType, IsNormalized>( pSrcCmp[cmp]);
95137 }
96138 }
97139}
98140
99- void ModelBuilder::WriteGltfData (const void * pSrc,
100- VALUE_TYPE SrcType,
101- Uint32 NumSrcComponents,
102- Uint32 SrcElemStride,
103- std::vector<Uint8>::iterator dst_it,
104- VALUE_TYPE DstType,
105- Uint32 NumDstComponents,
106- Uint32 DstElementStride,
107- Uint32 NumElements)
141+ void ModelBuilder::WriteGltfData (const WriteGltfDataAttribs& Attribs)
108142{
109- const auto NumComponentsToCopy = std::min (NumSrcComponents, NumDstComponents);
110-
111- #define INNER_CASE (SrcType, DstType ) \
112- case DstType: \
113- GLTF::WriteGltfData<typename VALUE_TYPE2CType<SrcType>::CType, \
114- typename VALUE_TYPE2CType<DstType>::CType>( \
115- pSrc, NumComponentsToCopy, SrcElemStride, dst_it, DstElementStride, NumElements); \
143+ const auto NumComponentsToCopy = std::min (Attribs.NumSrcComponents , Attribs.NumDstComponents );
144+
145+ #define INNER_CASE (SrcType, DstType ) \
146+ case DstType: \
147+ if (Attribs.IsNormalized ) \
148+ { \
149+ GLTF::WriteGltfData<typename VALUE_TYPE2CType<SrcType>::CType, \
150+ typename VALUE_TYPE2CType<DstType>::CType, \
151+ true >( \
152+ Attribs.pSrc , NumComponentsToCopy, Attribs.SrcElemStride , \
153+ Attribs.dst_it , Attribs.DstElementStride , Attribs.NumElements ); \
154+ } \
155+ else \
156+ { \
157+ GLTF::WriteGltfData<typename VALUE_TYPE2CType<SrcType>::CType, \
158+ typename VALUE_TYPE2CType<DstType>::CType, \
159+ false >( \
160+ Attribs.pSrc , NumComponentsToCopy, Attribs.SrcElemStride , \
161+ Attribs.dst_it , Attribs.DstElementStride , Attribs.NumElements ); \
162+ } \
116163 break
117164
118165#define CASE (SrcType ) \
119166 case SrcType: \
120- switch (DstType) \
167+ switch (Attribs. DstType ) \
121168 { \
122169 INNER_CASE (SrcType, VT_INT8); \
123170 INNER_CASE (SrcType, VT_INT16); \
@@ -133,7 +180,7 @@ void ModelBuilder::WriteGltfData(const void* pSrc,
133180 } \
134181 break
135182
136- switch (SrcType)
183+ switch (Attribs. SrcType )
137184 {
138185 CASE (VT_INT8);
139186 CASE (VT_INT16);
0 commit comments