3#include "Serialization/JsonParser.h"
5#include "Services/TaskManager.h"
6#include "Resources/TextureManager.h"
7#include "Resources/ModelManager.h"
8#include "Resources/MeshManager.h"
10#include "Foundation/Platform/Timer.h"
12#include "Rendering/DataFormat.h"
19typedef unsigned char stbi_uc;
21#include <glm/gtx/matrix_decompose.hpp>
31 using namespace rapidjson;
39 static const char* optimizeVariableName =
"gltf.import.optimize";
41 typedef GenericMember<UTF8<>, RAPIDJSON_DEFAULT_ALLOCATOR> Member;
42 typedef GenericArray<true, Value> Array;
43 typedef GenericObject<true, Value> Object;
45 constexpr int GLTF_BYTE = 5120;
46 constexpr int GLTF_UNSIGNED_BYTE = 5121;
47 constexpr int GLTF_SHORT = 5122;
48 constexpr int GLTF_UNSIGNED_SHORT = 5123;
49 constexpr int GLTF_UNSIGNED_INT = 5125;
50 constexpr int GLTF_FLOAT = 5126;
52 constexpr unsigned GLTF_NEAREST = 9728;
53 constexpr unsigned GLTF_LINEAR = 9729;
54 constexpr unsigned GLTF_NEAREST_MIPMAP_NEAREST = 9984;
55 constexpr unsigned GLTF_LINEAR_MIPMAP_NEAREST = 9985;
56 constexpr unsigned GLTF_NEAREST_MIPMAP_LINEAR = 9986;
57 constexpr unsigned GLTF_LINEAR_MIPMAP_LINEAR = 9987;
62 constexpr unsigned GLTF_CLAMP_TO_EDGE = 33071;
63 constexpr unsigned GLTF_MIRRORED_REPEAT = 33648;
64 constexpr unsigned GLTF_REPEAT = 10497;
66 enum struct AccessorComponentType
78 static const char* accessorComponentTypeName[] = {
87 static_assert(
sizeof(accessorComponentTypeName) ==
sizeof(accessorComponentTypeName[0]) * size_t(AccessorComponentType::Count));
89 static uint32_t accessorComponentTypeSize[] = {
91 uint32_t(
sizeof(int8_t)),
92 uint32_t(
sizeof(uint8_t)),
93 uint32_t(
sizeof(int16_t)),
94 uint32_t(
sizeof(uint16_t)),
95 uint32_t(
sizeof(uint32_t)),
96 uint32_t(
sizeof(
float))
98 static_assert(
sizeof(accessorComponentTypeSize) ==
sizeof(accessorComponentTypeSize[0]) * size_t(AccessorComponentType::Count));
100 enum struct AccessorType {
108 static const char* accessorTypeName[] = {
111 "Vec2",
"Vec3",
"Vec4",
112 "Mat2",
"Mat3",
"Mat4"
114 static_assert(
sizeof(accessorTypeName) ==
sizeof(accessorTypeName[0]) * size_t(AccessorType::Count));
116 static uint32_t accessorTypeSize[] = {
122 static_assert(
sizeof(accessorTypeSize) ==
sizeof(accessorTypeSize[0]) * size_t(AccessorType::Count));
128 uint32_t byteLength = 0;
129 uint32_t byteOffset = 0;
130 uint32_t byteStride = 0;
136 uint32_t bufferView = 0;
137 uint32_t byteOffset = 0;
140 AccessorComponentType componentType = AccessorComponentType::None;
141 AccessorType type = AccessorType::None;
144 int32_t s_int[4 * 4] = { 0 };
145 uint32_t s_uint[4 * 4];
146 float s_float[4 * 4];
149 uint32_t minCount = 0;
150 uint32_t maxCount = 0;
152 bool normalized =
false;
161 bool mipmapped =
true;
175 uint32_t bufferViewIndex =0;
176 std::string mimeType;
181 stbi_uc* data =
nullptr;
190 std::unique_ptr<Cogs::Core::TextureManager::ResourceProxy> proxy;
196 int32_t sampler = -1;
203 std::vector<uint32_t> children;
205 glm::quat rot = glm::quat();
206 glm::vec3 pos = glm::vec3(0);
207 glm::vec3 scale = glm::vec3(1);
210 uint32_t mesh = (uint32_t) -1;
211 uint32_t skin = (uint32_t) -1;
213 uint32_t node_index = (uint32_t) -1;
214 uint32_t parent_node = (uint32_t) -1;
216 uint32_t part_index = (uint32_t) -1;
217 uint32_t bone_index = (uint32_t) -1;
223 std::vector<uint32_t> nodes;
228 uint32_t inverseBindMatrices = 0;
229 std::vector<uint32_t> joints;
230 uint32_t skeleton = 0;
237 std::string interpolation;
243 uint32_t sampler = 0;
251 std::vector<GltfSampler> samplers;
252 std::vector<GltfChannel> channels;
257 int32_t modelMaterialIx = -1;
259 uint32_t texCoordSets = 0;
260 bool needsTangents =
false;
261 bool needsNormals =
false;
268 uint32_t vertexCount = (uint32_t) -1;
277 glm::vec2 offset = glm::vec2(0, 0);
278 glm::vec2 scale = glm::vec2(1.0, 1.0);
279 float rotation = 0.0;
292 int32_t version = -1;
293 int32_t min_version = -1;
294 int32_t load_scene = -1;
296 unsigned optimizationLevel = 1;
298 std::map<std::string, uint32_t> debugMessages;
300 std::vector<ResourceBuffer> buffer_data_store;
301 std::vector<std::span<const uint8_t>> buffer_data;
302 std::vector<GltfBufferView> buffer_views;
303 std::vector<GltfAccessor> accessors;
305 std::vector<GltfImage> images;
306 std::vector<GltfTextureSampler> texture_samplers;
307 std::vector<GltfTexture> textures;
309 std::vector<GltfScene> scenes;
310 std::vector<GltfNode> nodes;
312 std::vector<GltfSkin> skins;
313 std::vector<GltfAnimation> animations;
315 std::vector<Object> materialsArray;
316 std::vector<Object> meshesArray;
317 std::vector<TextureTransform> textureTransforms;
319 std::vector<CachedModelMaterial> modelMaterialsCache;
320 std::unordered_map<size_t, CachedModelMesh> modelMeshCache;
322 int32_t default_material = -1;
323 std::vector<int32_t> materials_skinned;
325 std::vector<Cogs::Memory::MemoryBuffer> normalsScratch;
326 std::vector<Cogs::Memory::MemoryBuffer> tangentsScratch;
327 std::vector<Cogs::Memory::MemoryBuffer> positionsScratch;
328 std::vector<Cogs::Memory::MemoryBuffer> texCoordsScratch;
333 const uint8_t* data =
nullptr;
338 static_assert(
sizeof(
BufferDataView) == (
sizeof(BufferDataView::data) +
339 sizeof(BufferDataView::stride) +
340 sizeof(BufferDataView::count)),
"Struct is not tightly packed");
345 size_t formatSize = 0;
347 Cogs::DataFormat format = Cogs::DataFormat::Unknown;
349 uint32_t semanticIndex = 0;
352 static_assert(
sizeof(
VertexStream) == (
sizeof(VertexStream::dataView) +
353 sizeof(VertexStream::formatSize) +
354 sizeof(VertexStream::offset) +
355 sizeof(VertexStream::format) +
356 sizeof(VertexStream::semantic) +
357 sizeof(VertexStream::semanticIndex)),
"Struct is not tightly packed");
360 return Cogs::hash(&stream,
sizeof(stream), hashValue);
365 Cogs::Geometry::BoundingBox bbox = Cogs::Geometry::makeEmptyBoundingBox<Cogs::Geometry::BoundingBox>();
370 AccessorComponentType indexType = AccessorComponentType::None;
371 bool positionPresent =
false;
372 bool normalPresent =
false;
373 bool tangentPresent =
false;
374 uint32_t indexSize = 0;
375 uint32_t texcoordStreamCount = 0;
376 uint32_t colorStreamCount = 0;
377 uint32_t jointsStreamCount = 0;
378 uint32_t weightsStreamCount = 0;
379 uint32_t positionCount = 0;
387 assert(workspace->size() == 0 &&
"Cannot reuse MemoryBuffer");
388 assert(srcType != AccessorComponentType::Float &&
"Buffer is already of type float!");
390 size_t stride =
sizeof(T);
391 workspace->resize(stride * srcBuf.count);
393 T* buf =
static_cast<T*
>(workspace->data());
394 const uint8_t* src = srcBuf.data;
397 for (uint32_t i = 0; i < srcBuf.count; ++i) {
399 constexpr int n = v.length();
400 for (
int j = 0; j < n; ++j) {
401 const uint8_t* ptr = src + c;
403 case AccessorComponentType::Byte:
404 v[j] = float(normalize ? std::fmax(
float(
reinterpret_cast<const int8_t*
>(ptr)[j]) / 127.0, -1.0) :
float(
reinterpret_cast<const int8_t*
>(ptr)[j]));
406 case AccessorComponentType::UnsignedByte:
407 v[j] = float(normalize ? (
float(
reinterpret_cast<const uint8_t*
>(ptr)[j])) / 255.0f :
float(
reinterpret_cast<const int8_t*
>(ptr)[j]));
409 case AccessorComponentType::Short:
410 v[j] = float(normalize ? std::fmax(
float(
reinterpret_cast<const int16_t*
>(ptr)[j]) / 32767.0f, -1.0) :
float(
reinterpret_cast<const int16_t*
>(ptr)[j]));
412 case AccessorComponentType::UnsignedShort:
413 v[j] = float(normalize ?
float(
reinterpret_cast<const uint16_t*
>(ptr)[j]) / 65535.0f :
float(
reinterpret_cast<const uint16_t*
>(ptr)[j]));
416 assert(
false &&
"Unhandled component type");
424 BufferDataView target{
425 .data =
reinterpret_cast<uint8_t*
>(buf),
426 .stride = (uint32_t) stride,
427 .count = srcBuf.count
438 bool load(
Context* context,
const ModelLoadInfo& loadInfo, std::unique_ptr<Cogs::FileContents> contents);
A Context instance contains all the services, systems and runtime components needed to use Cogs.
size_t getPotentialB3DMOffset(uint8_t *content, size_t size)
Provides a weakly referenced view over the contents of a string.
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
ElementSemantic
Element semantics used to map data to the shader stage.
@ Position
Position semantic.
Task id struct used to identify unique Task instances.
AddressMode
Addressing modes to use when sampling textures.
@ Wrap
Texture coordinates automatically wrap around to [0, 1] range.
FilterMode
Filter modes to specify how texture data is treated when sampled.
@ MinMagMipLinear
Linear sampling for both minification and magnification.