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