Skip to content

Commit 169a569

Browse files
GLTF Loader: enabled normalized accessors
1 parent 36fe848 commit 169a569

File tree

3 files changed

+103
-40
lines changed

3 files changed

+103
-40
lines changed

AssetLoader/interface/GLTFBuilder.hpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
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.
@@ -129,15 +129,20 @@ class ModelBuilder
129129
template <typename GltfModelType>
130130
bool LoadAnimationAndSkin(const GltfModelType& GltfModel);
131131

132-
static void WriteGltfData(const void* pSrc,
133-
VALUE_TYPE SrcType,
134-
Uint32 NumSrcComponents,
135-
Uint32 SrcElemStride,
136-
std::vector<Uint8>::iterator dst_it,
137-
VALUE_TYPE DstType,
138-
Uint32 NumDstComponents,
139-
Uint32 DstElementStride,
140-
Uint32 NumElements);
132+
struct WriteGltfDataAttribs
133+
{
134+
const void* pSrc;
135+
VALUE_TYPE SrcType;
136+
Uint32 NumSrcComponents;
137+
Uint32 SrcElemStride;
138+
std::vector<Uint8>::iterator dst_it;
139+
VALUE_TYPE DstType;
140+
Uint32 NumDstComponents;
141+
Uint32 DstElementStride;
142+
Uint32 NumElements;
143+
bool IsNormalized;
144+
};
145+
static void WriteGltfData(const WriteGltfDataAttribs& Attribs);
141146

142147
static void WriteDefaultAttibuteValue(const void* pDefaultValue,
143148
std::vector<Uint8>::iterator dst_it,
@@ -676,12 +681,22 @@ Uint32 ModelBuilder::ConvertVertexData(const GltfModelType& GltfModel,
676681
const auto ValueType = GltfVerts.Accessor.GetComponentType();
677682
const auto NumComponents = GltfVerts.Accessor.GetNumComponents();
678683
const auto SrcStride = GltfVerts.ByteStride;
684+
const bool IsNormalized = GltfVerts.Accessor.IsNormalized();
679685
VERIFY_EXPR(SrcStride > 0);
680686

681687
auto dst_it = VertexData.begin() + DataOffset + Attrib.RelativeOffset;
682688

683689
VERIFY_EXPR(static_cast<Uint32>(GltfVerts.Count) == VertexCount);
684-
WriteGltfData(GltfVerts.pData, ValueType, NumComponents, SrcStride, dst_it, Attrib.ValueType, Attrib.NumComponents, VertexStride, VertexCount);
690+
WriteGltfData({GltfVerts.pData,
691+
ValueType,
692+
static_cast<Uint32>(NumComponents),
693+
static_cast<Uint32>(SrcStride),
694+
dst_it,
695+
Attrib.ValueType,
696+
Attrib.NumComponents,
697+
VertexStride,
698+
VertexCount,
699+
IsNormalized});
685700

686701
m_Model.VertexData.EnabledAttributeFlags |= (1u << i);
687702
}

AssetLoader/src/GLTFBuilder.cpp

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
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 ============================
6667
template <>
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

7273
template <>
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>
80122
inline 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);

AssetLoader/src/GLTFLoader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2023 Diligent Graphics LLC
2+
* Copyright 2019-2024 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -174,6 +174,7 @@ struct TinyGltfAccessorWrapper
174174
auto GetByteOffset() const { return Accessor.byteOffset; }
175175
auto GetComponentType() const { return TinyGltfComponentTypeToValueType(Accessor.componentType); }
176176
auto GetNumComponents() const { return tinygltf::GetNumComponentsInType(Accessor.type); }
177+
bool IsNormalized() const { return Accessor.normalized; }
177178
// clang-format on
178179
auto GetByteStride(const TinyGltfBufferViewWrapper& View) const;
179180
};

0 commit comments

Comments
 (0)