#ifndef EXAMPLE_GLTF_LOADER_H_ #define EXAMPLE_GLTF_LOADER_H_ #include #include #include #include "material.h" #include "mesh.h" namespace example { /// Adapts an array of bytes to an array of T. Will advace of byte_stride each /// elements. template struct arrayAdapter { /// Pointer to the bytes const unsigned char *dataPtr; /// Number of elements in the array const size_t elemCount; /// Stride in bytes between two elements const size_t stride; /// Construct an array adapter. /// \param ptr Pointer to the start of the data, with offset applied /// \param count Number of elements in the array /// \param byte_stride Stride betweens elements in the array arrayAdapter(const unsigned char *ptr, size_t count, size_t byte_stride) : dataPtr(ptr), elemCount(count), stride(byte_stride) {} /// Returns a *copy* of a single element. Can't be used to modify it. T operator[](size_t pos) const { if (pos >= elemCount) throw std::out_of_range( "Tried to access beyond the last element of an array adapter with " "count " + std::to_string(elemCount) + " while getting elemnet number " + std::to_string(pos)); return *(reinterpret_cast(dataPtr + pos * stride)); } }; /// Interface of any adapted array that returns ingeger data struct intArrayBase { virtual ~intArrayBase() = default; virtual unsigned int operator[](size_t) const = 0; virtual size_t size() const = 0; }; /// Interface of any adapted array that returns float data struct floatArrayBase { virtual ~floatArrayBase() = default; virtual float operator[](size_t) const = 0; virtual size_t size() const = 0; }; /// An array that loads interger types, returns them as int template struct intArray : public intArrayBase { arrayAdapter adapter; intArray(const arrayAdapter &a) : adapter(a) {} unsigned int operator[](size_t position) const override { return static_cast(adapter[position]); } size_t size() const override { return adapter.elemCount; } }; template struct floatArray : public floatArrayBase { arrayAdapter adapter; floatArray(const arrayAdapter &a) : adapter(a) {} float operator[](size_t position) const override { return static_cast(adapter[position]); } size_t size() const override { return adapter.elemCount; } }; #pragma pack(push, 1) template struct v2 { T x, y; }; /// 3D vector of floats without padding template struct v3 { T x, y, z; }; /// 4D vector of floats without padding template struct v4 { T x, y, z, w; }; #pragma pack(pop) using v2f = v2; using v3f = v3; using v4f = v4; using v2d = v2; using v3d = v3; using v4d = v4; struct v2fArray { arrayAdapter adapter; v2fArray(const arrayAdapter &a) : adapter(a) {} v2f operator[](size_t position) const { return adapter[position]; } size_t size() const { return adapter.elemCount; } }; struct v3fArray { arrayAdapter adapter; v3fArray(const arrayAdapter &a) : adapter(a) {} v3f operator[](size_t position) const { return adapter[position]; } size_t size() const { return adapter.elemCount; } }; struct v4fArray { arrayAdapter adapter; v4fArray(const arrayAdapter &a) : adapter(a) {} v4f operator[](size_t position) const { return adapter[position]; } size_t size() const { return adapter.elemCount; } }; struct v2dArray { arrayAdapter adapter; v2dArray(const arrayAdapter &a) : adapter(a) {} v2d operator[](size_t position) const { return adapter[position]; } size_t size() const { return adapter.elemCount; } }; struct v3dArray { arrayAdapter adapter; v3dArray(const arrayAdapter &a) : adapter(a) {} v3d operator[](size_t position) const { return adapter[position]; } size_t size() const { return adapter.elemCount; } }; struct v4dArray { arrayAdapter adapter; v4dArray(const arrayAdapter &a) : adapter(a) {} v4d operator[](size_t position) const { return adapter[position]; } size_t size() const { return adapter.elemCount; } }; /// /// Loads glTF 2.0 mesh /// bool LoadGLTF(const std::string &filename, float scale, std::vector > *meshes, std::vector *materials, std::vector *textures); } // namespace example #endif // EXAMPLE_GLTF_LOADER_H_