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