Line data Source code
1 :
2 : #ifndef GLTFLOADER_H_
3 : #define GLTFLOADER_H_
4 :
5 : class GLTFModelInfo final
6 : {
7 : public:
8 : /**
9 : * @brief Populates the object vectors with the data in the gltf file
10 : * throws std::ios_base::failure if unable to load file
11 : * throws std::logic_error if invalid bracketing
12 : * throws std::logic_error if invalid geometry data type (e.g. float vertex indices)
13 : *
14 : * @param path the path of the file to load
15 : * @param messages toggles enabling of debug messages
16 : */
17 : GLTFModelInfo(std::string_view path, bool messages = false);
18 : //return list of mesh names, using one of the NodeTypes
19 : std::vector<std::string> getnodenames(int type) const;
20 : //getter functions generate vectors of arrays of the appropriate type
21 : //given the node name
22 : std::vector<std::array<float, 3>> getpositions(std::string_view name) const;
23 : std::vector<std::array<float, 3>> getnormals(std::string_view name) const;
24 : std::vector<std::array<float, 2>> gettexcoords(std::string_view name) const;
25 : std::vector<std::array<uint, 4>> getjoints(std::string_view name) const;
26 : std::vector<std::array<float, 4>> getweights(std::string_view name) const;
27 : std::vector<std::array<uint, 3>> getindices(std::string_view name) const;
28 :
29 : //two models are equal if their getters return the same (slow, requires loading data pointed to by file)
30 : bool operator==(const GLTFModelInfo &m) const;
31 :
32 :
33 : //Enum for selecting node types with getnodenames
34 : //"All" selects every node name, "Mesh", "Armature", "Bone" selects only those subsets
35 : enum NodeTypes
36 : {
37 : NodeType_All,
38 : NodeType_Mesh,
39 : NodeType_Armature,
40 : NodeType_Bone
41 : };
42 : private:
43 :
44 : struct Node final
45 : {
46 : std::string name;
47 : std::optional<std::array<float, 3>> translation;
48 : std::optional<std::array<float, 4>> rotation;
49 : std::optional<size_t> mesh;
50 : std::vector<size_t> children;
51 : };
52 :
53 : struct Mesh final
54 : {
55 : std::string name;
56 : //indices of accessors
57 : std::optional<uint> positions,
58 : normals,
59 : texcoords,
60 : joints,
61 : weights,
62 : indices;
63 : };
64 :
65 : struct Accessor final
66 : {
67 : size_t index; //index of this accessor
68 : uint bufferview; //index in the binary buffer this points to
69 : uint componenttype; //type of individual elements
70 : uint count; //number of elements
71 : std::string type; //type of data structure (vec2/vec3/scalar/etc)
72 : };
73 :
74 : struct BufferView final
75 : {
76 : size_t index;
77 : uint buffer,
78 : byteoffset,
79 : bytelength;
80 : };
81 :
82 : struct Buffer final
83 : {
84 : size_t index;
85 : uint bytelength;
86 : std::string uri;
87 : std::vector<char> buf;
88 : };
89 :
90 : struct Animation final
91 : {
92 : struct Channel final
93 : {
94 : size_t index;
95 : size_t sampler;
96 : size_t targetnode;
97 : std::string targetpath;
98 : };
99 : std::vector<Channel> channels;
100 : struct Sampler final
101 : {
102 : size_t index;
103 : size_t input;
104 : std::string interpolation;
105 : size_t output;
106 : };
107 : std::vector<Sampler> samplers;
108 : std::string name;
109 : };
110 :
111 : //T: the type of the output arrays in the vector
112 : //U: the type of the vector of input data
113 : //N: the number of elements in output arrays
114 : template<class T, class U, int N>
115 31 : static std::vector<std::array<T, N>> fillvector(const std::vector<U> &block)
116 : {
117 31 : std::vector<std::array<T, N>> output;
118 1363 : for(size_t i = 0; i < block.size(); i+=N)
119 : {
120 : std::array<T, N> v;
121 5392 : for(size_t j = 0; j < N; ++j)
122 : {
123 4060 : v[j] = block[i+j];
124 : };
125 1332 : output.push_back(v);
126 : }
127 31 : return output;
128 0 : }
129 :
130 :
131 : //index and length in bytes
132 : //returns a new copy of the buffer, as a vector, in the appropriate type
133 : template<class T>
134 31 : std::vector<T> gettypeblock(size_t bufindex, uint length, uint index) const
135 : {
136 31 : if(length + index > buffers[bufindex].buf.size())
137 : {
138 0 : std::printf("indices specified out of range: %u + %u > %lu\n", length, index, buffers[bufindex].buf.size());
139 : }
140 31 : std::vector<T> outbuf;
141 4091 : for(uint i = index; i < index + length; i+=sizeof(T))
142 : {
143 : //type pun the char array to T
144 4060 : char *data = new char[sizeof(T)];
145 17204 : for(uint j = 0; j < sizeof(T); ++j)
146 : {
147 13144 : data[j] = buffers[bufindex].buf[i+j];
148 : }
149 4060 : T *outdata = reinterpret_cast<T*>(data);
150 4060 : outbuf.push_back(*outdata);
151 4060 : delete[] data; //this is safe because the vector pushes back values and not pointers
152 : }
153 31 : return outbuf;
154 0 : }
155 :
156 : /**
157 : * @brief Loads a (gltf) json file to a std::vector
158 : *
159 : * Loads a JSON file and creates a new line for each bracket level and entry.
160 : *
161 : * @param name path to the file to load
162 : *
163 : * @return vector containing contents of file line by line
164 : */
165 : std::vector<std::string> loadjsonfile(std::string_view name);
166 : std::vector<std::string> getblockbyname(std::string_view path, std::string_view blockname, size_t maxdepth = 0);
167 : static void cleanstring(std::string &s);
168 : size_t findnodes(std::string_view path);
169 : size_t findmeshes(std::string_view path);
170 : size_t findaccessors(std::string_view path);
171 : size_t findbufferviews(std::string_view path);
172 : size_t findbuffers(std::string_view path);
173 : size_t findanimations(std::string_view path);
174 : std::vector<std::string> getblock(const std::vector<std::string> &file, size_t line);
175 :
176 : const bool messages;
177 : std::vector<Node> nodes;
178 : std::vector<Mesh> meshes;
179 : std::vector<Accessor> accessors;
180 : std::vector<BufferView> bufferviews;
181 : std::vector<Buffer> buffers;
182 : std::vector<Animation> animations;
183 :
184 : };
185 :
186 : #endif
|