Cogs.Core
MeshoptDecompressor.h
1#pragma once
2
3#include "GltfLoader.h"
4
5#include "Serialization/JsonParser.h"
6
7#include <meshoptimizer/meshoptimizer.h>
8
9#include <unordered_set>
10
24namespace Cogs::Core {
26 {
27 public:
28 MeshoptDecompressor() = default;
29 ~MeshoptDecompressor() = default;
30
31 enum class Mode { UNKNOWN, ATTRIBUTES, TRIANGLES, INDICES };
32 enum class Filter { NONE, OCTAHEDRAL, QUATERNION, EXPONENTIAL };
33
35 bool registerBufferViewCompression(uint32_t bufferViewIdx, const GltfLoader::Object& properties);
36 [[nodiscard]] bool isCompressed(GltfLoader::GltfModelDefinition& loadData, int accessorIdx) const;
37
38 bool decompress(GltfLoader::GltfModelDefinition& loadData, uint32_t accessorIdx);
39
40 private:
42 int bufferIdx = -1;
43 uint32_t byteLength = 0;
44 uint32_t byteStride = 0;
45 uint32_t count = 0;
46 uint32_t byteOffset = 0;
47 Mode mode = Mode::UNKNOWN;
48 Filter filter = Filter::NONE;
49
50 uint32_t originalBufferViewIdx = 0;
51 };
52
53 bool processAttributes(BufferViewDecomp& bvd, GltfLoader::GltfModelDefinition& loadData, int accessorIdx);
54 bool processIndices(BufferViewDecomp& bvd, GltfLoader::GltfModelDefinition& loadData, int accessorIdx);
55 bool processTriangles(BufferViewDecomp& bvd, GltfLoader::GltfModelDefinition& loadData, int accessorIdx);
56
57 [[nodiscard]] int getBufferViewIdxFromAccessorIdx(GltfLoader::GltfModelDefinition& loadData, int accessorIdx) const;
58 void normalizeBBoxValue(Cogs::Core::GltfLoader::GltfAccessor& accessor, int idx) const;
59 void convertScalarAccessorBBoxToFloat(GltfLoader::GltfAccessor& accessor) const;
60
61 template <typename T>
62 void convertVecAccessorBBoxToFloat(GltfLoader::GltfAccessor& accessor) const
63 {
64 if (accessor.minCount == 0 || accessor.maxCount == 0 || accessor.componentType == GltfLoader::AccessorComponentType::Float) {
65 return;
66 }
67
68 T v;
69 constexpr int n = v.length();
70
71 if (accessor.componentType == GltfLoader::AccessorComponentType::UnsignedByte ||
72 accessor.componentType == GltfLoader::AccessorComponentType::UnsignedShort ||
73 accessor.componentType == GltfLoader::AccessorComponentType::UnsignedInt) {
74 for (int i = 0; i < n; ++i) {
75 accessor.min.s_float[i] = float(accessor.min.s_uint[i]);
76 accessor.max.s_float[i] = float(accessor.max.s_uint[i]);
77 }
78 }
79 else if (accessor.componentType == GltfLoader::AccessorComponentType::Byte ||
80 accessor.componentType == GltfLoader::AccessorComponentType::Short) {
81 for (int i = 0; i < n; ++i) {
82 accessor.min.s_float[i] = float(accessor.min.s_int[i]);
83 accessor.max.s_float[i] = float(accessor.max.s_int[i]);
84 }
85 }
86 else {
87 assert(false && "Unsupported component type");
88 }
89
90 if (accessor.normalized) {
91 for (int i = 0; i < n; ++i) {
92 normalizeBBoxValue(accessor, i);
93 }
94 }
95 }
96
97 template<typename T>
98 bool transformData(T data, int size, int stride, MeshoptDecompressor::Filter filter) const {
99 switch (filter) {
100 case Filter::EXPONENTIAL:
101 meshopt_decodeFilterExp(data, size, stride); // The API says "filter" but is it more of a transformation.
102 return true;
103 case Filter::OCTAHEDRAL:
104 meshopt_decodeFilterOct(data, size, stride);
105 return true;
106 case Filter::QUATERNION:
107 meshopt_decodeFilterQuat(data, size, stride);
108 return true;
109 case Filter::NONE:
110 break;
111 }
112
113 return false;
114 }
115
116 std::unordered_map<uint32_t, BufferViewDecomp> bufferViewDecomps; // map[bufferViewIdx]=BufferViewDecomp
117 std::vector<Memory::MemoryBuffer> memoryBuffers;
118 std::unordered_set<uint32_t> decompressedBufferViews;
119 };
120}
bool registerBufferViewCompression(uint32_t bufferViewIdx, const GltfLoader::Object &properties)
Returns false if something failed.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....