1 #ifndef EXAMPLE_GLTF_LOADER_H_
2 #define EXAMPLE_GLTF_LOADER_H_
3 
4 #include <stdexcept>
5 #include <string>
6 #include <vector>
7 
8 #include "material.h"
9 #include "mesh.h"
10 #include "texture.h"
11 
12 namespace example {
13 
14 /// Adapts an array of bytes to an array of T. Will advace of byte_stride each
15 /// elements.
16 template <typename T>
17 struct arrayAdapter {
18   /// Pointer to the bytes
19   const unsigned char *dataPtr;
20   /// Number of elements in the array
21   const size_t elemCount;
22   /// Stride in bytes between two elements
23   const size_t stride;
24 
25   /// Construct an array adapter.
26   /// \param ptr Pointer to the start of the data, with offset applied
27   /// \param count Number of elements in the array
28   /// \param byte_stride Stride betweens elements in the array
arrayAdapterarrayAdapter29   arrayAdapter(const unsigned char *ptr, size_t count, size_t byte_stride)
30       : dataPtr(ptr), elemCount(count), stride(byte_stride) {}
31 
32   /// Returns a *copy* of a single element. Can't be used to modify it.
33   T operator[](size_t pos) const {
34     if (pos >= elemCount)
35       throw std::out_of_range(
36           "Tried to access beyond the last element of an array adapter with "
37           "count " +
38           std::to_string(elemCount) + " while getting elemnet number " +
39           std::to_string(pos));
40     return *(reinterpret_cast<const T *>(dataPtr + pos * stride));
41   }
42 };
43 
44 /// Interface of any adapted array that returns ingeger data
45 struct intArrayBase {
46   virtual ~intArrayBase() = default;
47   virtual unsigned int operator[](size_t) const = 0;
48   virtual size_t size() const = 0;
49 };
50 
51 /// Interface of any adapted array that returns float data
52 struct floatArrayBase {
53   virtual ~floatArrayBase() = default;
54   virtual float operator[](size_t) const = 0;
55   virtual size_t size() const = 0;
56 };
57 
58 /// An array that loads interger types, returns them as int
59 template <class T>
60 struct intArray : public intArrayBase {
61   arrayAdapter<T> adapter;
62 
intArrayintArray63   intArray(const arrayAdapter<T> &a) : adapter(a) {}
64   unsigned int operator[](size_t position) const override {
65     return static_cast<unsigned int>(adapter[position]);
66   }
67 
sizeintArray68   size_t size() const override { return adapter.elemCount; }
69 };
70 
71 template <class T>
72 struct floatArray : public floatArrayBase {
73   arrayAdapter<T> adapter;
74 
floatArrayfloatArray75   floatArray(const arrayAdapter<T> &a) : adapter(a) {}
76   float operator[](size_t position) const override {
77     return static_cast<float>(adapter[position]);
78   }
79 
sizefloatArray80   size_t size() const override { return adapter.elemCount; }
81 };
82 
83 #pragma pack(push, 1)
84 
85 template <typename T>
86 struct v2 {
87   T x, y;
88 };
89 /// 3D vector of floats without padding
90 template <typename T>
91 struct v3 {
92   T x, y, z;
93 };
94 
95 /// 4D vector of floats without padding
96 template <typename T>
97 struct v4 {
98   T x, y, z, w;
99 };
100 
101 #pragma pack(pop)
102 
103 using v2f = v2<float>;
104 using v3f = v3<float>;
105 using v4f = v4<float>;
106 using v2d = v2<double>;
107 using v3d = v3<double>;
108 using v4d = v4<double>;
109 
110 struct v2fArray {
111   arrayAdapter<v2f> adapter;
v2fArrayv2fArray112   v2fArray(const arrayAdapter<v2f> &a) : adapter(a) {}
113 
114   v2f operator[](size_t position) const { return adapter[position]; }
sizev2fArray115   size_t size() const { return adapter.elemCount; }
116 };
117 
118 struct v3fArray {
119   arrayAdapter<v3f> adapter;
v3fArrayv3fArray120   v3fArray(const arrayAdapter<v3f> &a) : adapter(a) {}
121 
122   v3f operator[](size_t position) const { return adapter[position]; }
sizev3fArray123   size_t size() const { return adapter.elemCount; }
124 };
125 
126 struct v4fArray {
127   arrayAdapter<v4f> adapter;
v4fArrayv4fArray128   v4fArray(const arrayAdapter<v4f> &a) : adapter(a) {}
129 
130   v4f operator[](size_t position) const { return adapter[position]; }
sizev4fArray131   size_t size() const { return adapter.elemCount; }
132 };
133 
134 struct v2dArray {
135   arrayAdapter<v2d> adapter;
v2dArrayv2dArray136   v2dArray(const arrayAdapter<v2d> &a) : adapter(a) {}
137 
138   v2d operator[](size_t position) const { return adapter[position]; }
sizev2dArray139   size_t size() const { return adapter.elemCount; }
140 };
141 
142 struct v3dArray {
143   arrayAdapter<v3d> adapter;
v3dArrayv3dArray144   v3dArray(const arrayAdapter<v3d> &a) : adapter(a) {}
145 
146   v3d operator[](size_t position) const { return adapter[position]; }
sizev3dArray147   size_t size() const { return adapter.elemCount; }
148 };
149 
150 struct v4dArray {
151   arrayAdapter<v4d> adapter;
v4dArrayv4dArray152   v4dArray(const arrayAdapter<v4d> &a) : adapter(a) {}
153 
154   v4d operator[](size_t position) const { return adapter[position]; }
sizev4dArray155   size_t size() const { return adapter.elemCount; }
156 };
157 
158 ///
159 /// Loads glTF 2.0 mesh
160 ///
161 bool LoadGLTF(
162     const std::string &filename, float scale, Mesh<float> &mesh,
163     /*,std::vector<Material> *materials,*/ std::vector<Texture> &textures);
164 
165 }  // namespace example
166 
167 #endif  // EXAMPLE_GLTF_LOADER_H_
168