25 #include <unordered_set>
35 static void reskin_vertices
37 std::uint8_t* vertex_data,
38 std::size_t index_count,
43 const std::unordered_set<std::uint8_t>& old_bone_indices,
44 std::uint8_t new_bone_index,
95 return exoskeleton_material;
143 std::size_t vertex_buffer_size = 0;
144 std::size_t mesosoma_vbo_offset = vertex_buffer_size;
145 vertex_buffer_size += mesosoma_vbo->
get_size();
146 std::size_t legs_vbo_offset = vertex_buffer_size;
147 vertex_buffer_size += legs_vbo->
get_size();
148 std::size_t head_vbo_offset = vertex_buffer_size;
149 vertex_buffer_size += head_vbo->
get_size();
150 std::size_t mandibles_vbo_offset = vertex_buffer_size;
151 vertex_buffer_size += mandibles_vbo->
get_size();
152 std::size_t antennae_vbo_offset = vertex_buffer_size;
153 vertex_buffer_size += antennae_vbo->
get_size();
154 std::size_t waist_vbo_offset = vertex_buffer_size;
155 vertex_buffer_size += waist_vbo->
get_size();
156 std::size_t gaster_vbo_offset = vertex_buffer_size;
157 vertex_buffer_size += gaster_vbo->
get_size();
158 std::size_t sting_vbo_offset = vertex_buffer_size;
160 vertex_buffer_size += sting_vbo->
get_size();
161 std::size_t eyes_vbo_offset = vertex_buffer_size;
163 vertex_buffer_size += eyes_vbo->
get_size();
164 std::size_t lateral_ocelli_vbo_offset = vertex_buffer_size;
165 if (lateral_ocelli_present)
166 vertex_buffer_size += lateral_ocelli_vbo->
get_size();
167 std::size_t median_ocellus_vbo_offset = vertex_buffer_size;
168 if (median_ocellus_present)
169 vertex_buffer_size += median_ocellus_vbo->
get_size();
170 std::size_t forewings_vbo_offset = vertex_buffer_size;
172 vertex_buffer_size += forewings_vbo->
get_size();
173 std::size_t hindwings_vbo_offset = vertex_buffer_size;
175 vertex_buffer_size += hindwings_vbo->
get_size();
178 std::uint8_t* vertex_buffer_data =
new std::uint8_t[vertex_buffer_size];
181 mesosoma_vbo->
read(0, mesosoma_vbo->
get_size(), vertex_buffer_data + mesosoma_vbo_offset);
182 legs_vbo->
read(0, legs_vbo->
get_size(), vertex_buffer_data + legs_vbo_offset);
183 head_vbo->
read(0, head_vbo->
get_size(), vertex_buffer_data + head_vbo_offset);
184 mandibles_vbo->
read(0, mandibles_vbo->
get_size(), vertex_buffer_data + mandibles_vbo_offset);
185 antennae_vbo->
read(0, antennae_vbo->
get_size(), vertex_buffer_data + antennae_vbo_offset);
186 waist_vbo->
read(0, waist_vbo->
get_size(), vertex_buffer_data + waist_vbo_offset);
187 gaster_vbo->
read(0, gaster_vbo->
get_size(), vertex_buffer_data + gaster_vbo_offset);
189 sting_vbo->
read(0, sting_vbo->
get_size(), vertex_buffer_data + sting_vbo_offset);
191 eyes_vbo->
read(0, eyes_vbo->
get_size(), vertex_buffer_data + eyes_vbo_offset);
192 if (lateral_ocelli_present)
193 lateral_ocelli_vbo->
read(0, lateral_ocelli_vbo->
get_size(), vertex_buffer_data + lateral_ocelli_vbo_offset);
194 if (median_ocellus_present)
195 median_ocellus_vbo->
read(0, median_ocellus_vbo->
get_size(), vertex_buffer_data + median_ocellus_vbo_offset);
198 forewings_vbo->
read(0, forewings_vbo->
get_size(), vertex_buffer_data + forewings_vbo_offset);
199 hindwings_vbo->
read(0, hindwings_vbo->
get_size(), vertex_buffer_data + hindwings_vbo_offset);
210 model_vao->
bind(location, attribute);
220 position_attribute = &it->second;
222 normal_attribute = &it->second;
224 tangent_attribute = &it->second;
226 bone_index_attribute = &it->second;
229 const ::skeleton& mesosoma_skeleton = mesosoma_model->
get_skeleton();
230 const ::skeleton& legs_skeleton = legs_model->
get_skeleton();
231 const ::skeleton& head_skeleton = head_model->
get_skeleton();
232 const ::skeleton& mandibles_skeleton = mandibles_model->
get_skeleton();
233 const ::skeleton& antennae_skeleton = antennae_model->
get_skeleton();
234 const ::skeleton& waist_skeleton = waist_model->
get_skeleton();
235 const ::skeleton& gaster_skeleton = gaster_model->
get_skeleton();
236 const ::skeleton* sting_skeleton = (sting_present) ? &sting_model->
get_skeleton() :
nullptr;
237 const ::skeleton* eyes_skeleton = (eyes_present) ? &eyes_model->
get_skeleton() :
nullptr;
238 const ::skeleton* lateral_ocelli_skeleton = (lateral_ocelli_present) ? &lateral_ocelli_model->
get_skeleton() :
nullptr;
239 const ::skeleton* median_ocellus_skeleton = (median_ocellus_present) ? &median_ocellus_model->
get_skeleton() :
nullptr;
243 std::size_t bone_count = 33;
246 if (postpetiole_present)
255 std::uint8_t mesosoma_bone_index =
bone_index++;
256 std::uint8_t procoxa_l_bone_index =
bone_index++;
257 std::uint8_t procoxa_r_bone_index =
bone_index++;
258 std::uint8_t profemur_l_bone_index =
bone_index++;
259 std::uint8_t profemur_r_bone_index =
bone_index++;
260 std::uint8_t protibia_l_bone_index =
bone_index++;
261 std::uint8_t protibia_r_bone_index =
bone_index++;
262 std::uint8_t protarsus_l_bone_index =
bone_index++;
263 std::uint8_t protarsus_r_bone_index =
bone_index++;
264 std::uint8_t mesocoxa_l_bone_index =
bone_index++;
265 std::uint8_t mesocoxa_r_bone_index =
bone_index++;
266 std::uint8_t mesofemur_l_bone_index =
bone_index++;
267 std::uint8_t mesofemur_r_bone_index =
bone_index++;
268 std::uint8_t mesotibia_l_bone_index =
bone_index++;
269 std::uint8_t mesotibia_r_bone_index =
bone_index++;
270 std::uint8_t mesotarsus_l_bone_index =
bone_index++;
271 std::uint8_t mesotarsus_r_bone_index =
bone_index++;
272 std::uint8_t metacoxa_l_bone_index =
bone_index++;
273 std::uint8_t metacoxa_r_bone_index =
bone_index++;
274 std::uint8_t metafemur_l_bone_index =
bone_index++;
275 std::uint8_t metafemur_r_bone_index =
bone_index++;
276 std::uint8_t metatibia_l_bone_index =
bone_index++;
277 std::uint8_t metatibia_r_bone_index =
bone_index++;
278 std::uint8_t metatarsus_l_bone_index =
bone_index++;
279 std::uint8_t metatarsus_r_bone_index =
bone_index++;
281 std::uint8_t mandible_l_bone_index =
bone_index++;
282 std::uint8_t mandible_r_bone_index =
bone_index++;
283 std::uint8_t antennomere1_l_bone_index =
bone_index++;
284 std::uint8_t antennomere1_r_bone_index =
bone_index++;
285 std::uint8_t antennomere2_l_bone_index =
bone_index++;
286 std::uint8_t antennomere2_r_bone_index =
bone_index++;
287 std::uint8_t petiole_bone_index =(petiole_present) ?
bone_index++ :
static_cast<std::uint8_t
>(bone_count);
288 std::uint8_t postpetiole_bone_index = (postpetiole_present) ?
bone_index++ :
static_cast<std::uint8_t
>(bone_count);
289 std::uint8_t gaster_bone_index =
bone_index++;
290 std::uint8_t sting_bone_index = (sting_present) ?
bone_index++ :
static_cast<std::uint8_t
>(bone_count);
294 ::bone procoxa_l_bone =
make_bone(procoxa_l_bone_index, mesosoma_bone_index);
295 ::bone procoxa_r_bone =
make_bone(procoxa_r_bone_index, mesosoma_bone_index);
296 ::bone profemur_l_bone =
make_bone(profemur_l_bone_index, procoxa_l_bone_index);
297 ::bone profemur_r_bone =
make_bone(profemur_r_bone_index, procoxa_r_bone_index);
298 ::bone protibia_l_bone =
make_bone(protibia_l_bone_index, profemur_l_bone_index);
299 ::bone protibia_r_bone =
make_bone(protibia_r_bone_index, profemur_r_bone_index);
300 ::bone protarsus_l_bone =
make_bone(protarsus_l_bone_index, protibia_l_bone_index);
301 ::bone protarsus_r_bone =
make_bone(protarsus_r_bone_index, protibia_r_bone_index);
302 ::bone mesocoxa_l_bone =
make_bone(mesocoxa_l_bone_index, mesosoma_bone_index);
303 ::bone mesocoxa_r_bone =
make_bone(mesocoxa_r_bone_index, mesosoma_bone_index);
304 ::bone mesofemur_l_bone =
make_bone(mesofemur_l_bone_index, mesocoxa_l_bone_index);
305 ::bone mesofemur_r_bone =
make_bone(mesofemur_r_bone_index, mesocoxa_r_bone_index);
306 ::bone mesotibia_l_bone =
make_bone(mesotibia_l_bone_index, mesofemur_l_bone_index);
307 ::bone mesotibia_r_bone =
make_bone(mesotibia_r_bone_index, mesofemur_r_bone_index);
308 ::bone mesotarsus_l_bone =
make_bone(mesotarsus_l_bone_index, mesotibia_l_bone_index);
309 ::bone mesotarsus_r_bone =
make_bone(mesotarsus_r_bone_index, mesotibia_r_bone_index);
310 ::bone metacoxa_l_bone =
make_bone(metacoxa_l_bone_index, mesosoma_bone_index);
311 ::bone metacoxa_r_bone =
make_bone(metacoxa_r_bone_index, mesosoma_bone_index);
312 ::bone metafemur_l_bone =
make_bone(metafemur_l_bone_index, metacoxa_l_bone_index);
313 ::bone metafemur_r_bone =
make_bone(metafemur_r_bone_index, metacoxa_r_bone_index);
314 ::bone metatibia_l_bone =
make_bone(metatibia_l_bone_index, metafemur_l_bone_index);
315 ::bone metatibia_r_bone =
make_bone(metatibia_r_bone_index, metafemur_r_bone_index);
316 ::bone metatarsus_l_bone =
make_bone(metatarsus_l_bone_index, metatibia_l_bone_index);
317 ::bone metatarsus_r_bone =
make_bone(metatarsus_r_bone_index, metatibia_r_bone_index);
319 ::bone mandible_l_bone =
make_bone(mandible_l_bone_index, head_bone_index);
320 ::bone mandible_r_bone =
make_bone(mandible_r_bone_index, head_bone_index);
321 ::bone antennomere1_l_bone =
make_bone(antennomere1_l_bone_index, head_bone_index);
322 ::bone antennomere1_r_bone =
make_bone(antennomere1_r_bone_index, head_bone_index);
323 ::bone antennomere2_l_bone =
make_bone(antennomere2_l_bone_index, antennomere1_l_bone_index);
324 ::bone antennomere2_r_bone =
make_bone(antennomere2_r_bone_index, antennomere1_r_bone_index);
325 ::bone petiole_bone =
make_bone(petiole_bone_index, mesosoma_bone_index);
326 ::bone postpetiole_bone =
make_bone(postpetiole_bone_index, petiole_bone_index);
327 ::bone gaster_bone =
make_bone(gaster_bone_index, (postpetiole_present) ? postpetiole_bone_index : petiole_bone_index);
365 if (postpetiole_present)
375 if (
auto it = mesosoma_skeleton.bone_map.find(
"mesosoma"); it != mesosoma_skeleton.bone_map.end())
376 bind_pose[mesosoma_bone] = mesosoma_skeleton.bind_pose.at(it->second);
379 if (
auto it = legs_skeleton.bone_map.find(
"procoxa_l"); it != legs_skeleton.bone_map.end())
380 bind_pose[procoxa_l_bone] = legs_skeleton.bind_pose.at(it->second);
381 if (
auto it = legs_skeleton.bone_map.find(
"procoxa_r"); it != legs_skeleton.bone_map.end())
382 bind_pose[procoxa_r_bone] = legs_skeleton.bind_pose.at(it->second);
383 if (
auto it = legs_skeleton.bone_map.find(
"profemur_l"); it != legs_skeleton.bone_map.end())
384 bind_pose[profemur_l_bone] = legs_skeleton.bind_pose.at(it->second);
385 if (
auto it = legs_skeleton.bone_map.find(
"profemur_r"); it != legs_skeleton.bone_map.end())
386 bind_pose[profemur_r_bone] = legs_skeleton.bind_pose.at(it->second);
387 if (
auto it = legs_skeleton.bone_map.find(
"protibia_l"); it != legs_skeleton.bone_map.end())
388 bind_pose[protibia_l_bone] = legs_skeleton.bind_pose.at(it->second);
389 if (
auto it = legs_skeleton.bone_map.find(
"protibia_r"); it != legs_skeleton.bone_map.end())
390 bind_pose[protibia_r_bone] = legs_skeleton.bind_pose.at(it->second);
391 if (
auto it = legs_skeleton.bone_map.find(
"protarsus1_l"); it != legs_skeleton.bone_map.end())
392 bind_pose[protarsus_l_bone] = legs_skeleton.bind_pose.at(it->second);
393 if (
auto it = legs_skeleton.bone_map.find(
"protarsus1_r"); it != legs_skeleton.bone_map.end())
394 bind_pose[protarsus_r_bone] = legs_skeleton.bind_pose.at(it->second);
397 if (
auto it = legs_skeleton.bone_map.find(
"mesocoxa_l"); it != legs_skeleton.bone_map.end())
398 bind_pose[mesocoxa_l_bone] = legs_skeleton.bind_pose.at(it->second);
399 if (
auto it = legs_skeleton.bone_map.find(
"mesocoxa_r"); it != legs_skeleton.bone_map.end())
400 bind_pose[mesocoxa_r_bone] = legs_skeleton.bind_pose.at(it->second);
401 if (
auto it = legs_skeleton.bone_map.find(
"mesofemur_l"); it != legs_skeleton.bone_map.end())
402 bind_pose[mesofemur_l_bone] = legs_skeleton.bind_pose.at(it->second);
403 if (
auto it = legs_skeleton.bone_map.find(
"mesofemur_r"); it != legs_skeleton.bone_map.end())
404 bind_pose[mesofemur_r_bone] = legs_skeleton.bind_pose.at(it->second);
405 if (
auto it = legs_skeleton.bone_map.find(
"mesotibia_l"); it != legs_skeleton.bone_map.end())
406 bind_pose[mesotibia_l_bone] = legs_skeleton.bind_pose.at(it->second);
407 if (
auto it = legs_skeleton.bone_map.find(
"mesotibia_r"); it != legs_skeleton.bone_map.end())
408 bind_pose[mesotibia_r_bone] = legs_skeleton.bind_pose.at(it->second);
409 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus1_l"); it != legs_skeleton.bone_map.end())
410 bind_pose[mesotarsus_l_bone] = legs_skeleton.bind_pose.at(it->second);
411 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus1_r"); it != legs_skeleton.bone_map.end())
412 bind_pose[mesotarsus_r_bone] = legs_skeleton.bind_pose.at(it->second);
415 if (
auto it = legs_skeleton.bone_map.find(
"metacoxa_l"); it != legs_skeleton.bone_map.end())
416 bind_pose[metacoxa_l_bone] = legs_skeleton.bind_pose.at(it->second);
417 if (
auto it = legs_skeleton.bone_map.find(
"metacoxa_r"); it != legs_skeleton.bone_map.end())
418 bind_pose[metacoxa_r_bone] = legs_skeleton.bind_pose.at(it->second);
419 if (
auto it = legs_skeleton.bone_map.find(
"metafemur_l"); it != legs_skeleton.bone_map.end())
420 bind_pose[metafemur_l_bone] = legs_skeleton.bind_pose.at(it->second);
421 if (
auto it = legs_skeleton.bone_map.find(
"metafemur_r"); it != legs_skeleton.bone_map.end())
422 bind_pose[metafemur_r_bone] = legs_skeleton.bind_pose.at(it->second);
423 if (
auto it = legs_skeleton.bone_map.find(
"metatibia_l"); it != legs_skeleton.bone_map.end())
424 bind_pose[metatibia_l_bone] = legs_skeleton.bind_pose.at(it->second);
425 if (
auto it = legs_skeleton.bone_map.find(
"metatibia_r"); it != legs_skeleton.bone_map.end())
426 bind_pose[metatibia_r_bone] = legs_skeleton.bind_pose.at(it->second);
427 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus1_l"); it != legs_skeleton.bone_map.end())
428 bind_pose[metatarsus_l_bone] = legs_skeleton.bind_pose.at(it->second);
429 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus1_r"); it != legs_skeleton.bone_map.end())
430 bind_pose[metatarsus_r_bone] = legs_skeleton.bind_pose.at(it->second);
433 bind_pose[head_bone] = mesosoma_skeleton.bind_pose.at(mesosoma_skeleton.bone_map.at(
"head")) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"head"));
436 bind_pose[mandible_l_bone] = head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"mandible_l")) * mandibles_skeleton.bind_pose.at(mandibles_skeleton.bone_map.at(
"mandible_l"));
437 bind_pose[mandible_r_bone] = head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"mandible_r")) * mandibles_skeleton.bind_pose.at(mandibles_skeleton.bone_map.at(
"mandible_r"));
440 bind_pose[antennomere1_l_bone] = head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"antenna_l")) * antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at(
"antennomere1_l"));
441 bind_pose[antennomere1_r_bone] = head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"antenna_r")) * antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at(
"antennomere1_r"));
442 bind_pose[antennomere2_l_bone] = antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at(
"antennomere2_l"));
443 bind_pose[antennomere2_r_bone] = antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at(
"antennomere2_r"));
448 bind_pose[petiole_bone] = mesosoma_skeleton.bind_pose.at(mesosoma_skeleton.bone_map.at(
"petiole")) * waist_skeleton.bind_pose.at(waist_skeleton.bone_map.at(
"petiole"));
450 if (postpetiole_present)
452 bind_pose[postpetiole_bone] = waist_skeleton.bind_pose.at(waist_skeleton.bone_map.at(
"postpetiole"));
456 if (postpetiole_present)
458 bind_pose[gaster_bone] = waist_skeleton.bind_pose.at(waist_skeleton.bone_map.at(
"postpetiole")) * gaster_skeleton.bind_pose.at(gaster_skeleton.bone_map.at(
"gaster"));
460 else if (petiole_present)
462 bind_pose[gaster_bone] = waist_skeleton.bind_pose.at(waist_skeleton.bone_map.at(
"petiole")) * gaster_skeleton.bind_pose.at(gaster_skeleton.bone_map.at(
"gaster"));
466 bind_pose[gaster_bone] = mesosoma_skeleton.bind_pose.at(mesosoma_skeleton.bone_map.at(
"petiole")) * gaster_skeleton.bind_pose.at(gaster_skeleton.bone_map.at(
"gaster"));
472 bind_pose[sting_bone] = gaster_skeleton.bind_pose.at(gaster_skeleton.bone_map.at(
"sting")) * sting_skeleton->bind_pose.at(sting_skeleton->bone_map.at(
"sting"));
483 std::size_t mesosoma_index_count = (*mesosoma_model->
get_groups())[0]->get_index_count();
484 std::size_t legs_index_count = (*legs_model->
get_groups())[0]->get_index_count();
485 std::size_t head_index_count = (*head_model->
get_groups())[0]->get_index_count();
486 std::size_t mandibles_index_count = (*mandibles_model->
get_groups())[0]->get_index_count();
487 std::size_t antennae_index_count = (*antennae_model->
get_groups())[0]->get_index_count();
488 std::size_t waist_index_count = (*waist_model->
get_groups())[0]->get_index_count();
489 std::size_t gaster_index_count = (*gaster_model->
get_groups())[0]->get_index_count();
490 std::size_t sting_index_count = (sting_present) ? (*sting_model->
get_groups())[0]->get_index_count() : 0;
491 std::size_t eyes_index_count = (eyes_present) ? (*eyes_model->
get_groups())[0]->get_index_count() : 0;
492 std::size_t lateral_ocelli_index_count = (lateral_ocelli_present) ? (*lateral_ocelli_model->
get_groups())[0]->get_index_count() : 0;
493 std::size_t median_ocellus_index_count = (median_ocellus_present) ? (*median_ocellus_model->
get_groups())[0]->get_index_count() : 0;
494 std::size_t forewings_index_count = (wings_present) ? (*forewings_model->
get_groups())[0]->get_index_count() : 0;
495 std::size_t hindwings_index_count = (wings_present) ? (*hindwings_model->
get_groups())[0]->get_index_count() : 0;
496 std::size_t exoskeleton_index_count =
500 + mandibles_index_count
501 + antennae_index_count
510 std::unordered_set<std::uint8_t> old_procoxa_l_indices;
511 if (
auto it = legs_skeleton.bone_map.find(
"procoxa_l"); it != legs_skeleton.bone_map.end())
512 old_procoxa_l_indices.emplace(it->second);
513 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_procoxa_l_indices, procoxa_l_bone_index, legs_to_body);
514 std::unordered_set<std::uint8_t> old_profemur_l_indices;
515 if (
auto it = legs_skeleton.bone_map.find(
"profemur_l"); it != legs_skeleton.bone_map.end())
516 old_profemur_l_indices.emplace(it->second);
517 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_profemur_l_indices, profemur_l_bone_index, legs_to_body);
518 std::unordered_set<std::uint8_t> old_protibia_l_indices;
519 if (
auto it = legs_skeleton.bone_map.find(
"protibia_l"); it != legs_skeleton.bone_map.end())
520 old_protibia_l_indices.emplace(it->second);
521 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_protibia_l_indices, protibia_l_bone_index, legs_to_body);
522 std::unordered_set<std::uint8_t> old_protarsus_l_indices;
523 if (
auto it = legs_skeleton.bone_map.find(
"protarsus1_l"); it != legs_skeleton.bone_map.end())
524 old_protarsus_l_indices.emplace(it->second);
525 if (
auto it = legs_skeleton.bone_map.find(
"protarsus2_l"); it != legs_skeleton.bone_map.end())
526 old_protarsus_l_indices.emplace(it->second);
527 if (
auto it = legs_skeleton.bone_map.find(
"protarsus3_l"); it != legs_skeleton.bone_map.end())
528 old_protarsus_l_indices.emplace(it->second);
529 if (
auto it = legs_skeleton.bone_map.find(
"protarsus4_l"); it != legs_skeleton.bone_map.end())
530 old_protarsus_l_indices.emplace(it->second);
531 if (
auto it = legs_skeleton.bone_map.find(
"protarsus5_l"); it != legs_skeleton.bone_map.end())
532 old_protarsus_l_indices.emplace(it->second);
533 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_protarsus_l_indices, protarsus_l_bone_index, legs_to_body);
535 std::unordered_set<std::uint8_t> old_procoxa_r_indices;
536 if (
auto it = legs_skeleton.bone_map.find(
"procoxa_r"); it != legs_skeleton.bone_map.end())
537 old_procoxa_r_indices.emplace(it->second);
538 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_procoxa_r_indices, procoxa_r_bone_index, legs_to_body);
539 std::unordered_set<std::uint8_t> old_profemur_r_indices;
540 if (
auto it = legs_skeleton.bone_map.find(
"profemur_r"); it != legs_skeleton.bone_map.end())
541 old_profemur_r_indices.emplace(it->second);
542 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_profemur_r_indices, profemur_r_bone_index, legs_to_body);
543 std::unordered_set<std::uint8_t> old_protibia_r_indices;
544 if (
auto it = legs_skeleton.bone_map.find(
"protibia_r"); it != legs_skeleton.bone_map.end())
545 old_protibia_r_indices.emplace(it->second);
546 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_protibia_r_indices, protibia_r_bone_index, legs_to_body);
547 std::unordered_set<std::uint8_t> old_protarsus_r_indices;
548 if (
auto it = legs_skeleton.bone_map.find(
"protarsus1_r"); it != legs_skeleton.bone_map.end())
549 old_protarsus_r_indices.emplace(it->second);
550 if (
auto it = legs_skeleton.bone_map.find(
"protarsus2_r"); it != legs_skeleton.bone_map.end())
551 old_protarsus_r_indices.emplace(it->second);
552 if (
auto it = legs_skeleton.bone_map.find(
"protarsus3_r"); it != legs_skeleton.bone_map.end())
553 old_protarsus_r_indices.emplace(it->second);
554 if (
auto it = legs_skeleton.bone_map.find(
"protarsus4_r"); it != legs_skeleton.bone_map.end())
555 old_protarsus_r_indices.emplace(it->second);
556 if (
auto it = legs_skeleton.bone_map.find(
"protarsus5_r"); it != legs_skeleton.bone_map.end())
557 old_protarsus_r_indices.emplace(it->second);
558 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_protarsus_r_indices, protarsus_r_bone_index, legs_to_body);
560 std::unordered_set<std::uint8_t> old_mesocoxa_l_indices;
561 if (
auto it = legs_skeleton.bone_map.find(
"mesocoxa_l"); it != legs_skeleton.bone_map.end())
562 old_mesocoxa_l_indices.emplace(it->second);
563 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_mesocoxa_l_indices, mesocoxa_l_bone_index, legs_to_body);
564 std::unordered_set<std::uint8_t> old_mesofemur_l_indices;
565 if (
auto it = legs_skeleton.bone_map.find(
"mesofemur_l"); it != legs_skeleton.bone_map.end())
566 old_mesofemur_l_indices.emplace(it->second);
567 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_mesofemur_l_indices, mesofemur_l_bone_index, legs_to_body);
568 std::unordered_set<std::uint8_t> old_mesotibia_l_indices;
569 if (
auto it = legs_skeleton.bone_map.find(
"mesotibia_l"); it != legs_skeleton.bone_map.end())
570 old_mesotibia_l_indices.emplace(it->second);
571 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_mesotibia_l_indices, mesotibia_l_bone_index, legs_to_body);
572 std::unordered_set<std::uint8_t> old_mesotarsus_l_indices;
573 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus1_l"); it != legs_skeleton.bone_map.end())
574 old_mesotarsus_l_indices.emplace(it->second);
575 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus2_l"); it != legs_skeleton.bone_map.end())
576 old_mesotarsus_l_indices.emplace(it->second);
577 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus3_l"); it != legs_skeleton.bone_map.end())
578 old_mesotarsus_l_indices.emplace(it->second);
579 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus4_l"); it != legs_skeleton.bone_map.end())
580 old_mesotarsus_l_indices.emplace(it->second);
581 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus5_l"); it != legs_skeleton.bone_map.end())
582 old_mesotarsus_l_indices.emplace(it->second);
583 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_mesotarsus_l_indices, mesotarsus_l_bone_index, legs_to_body);
585 std::unordered_set<std::uint8_t> old_mesocoxa_r_indices;
586 if (
auto it = legs_skeleton.bone_map.find(
"mesocoxa_r"); it != legs_skeleton.bone_map.end())
587 old_mesocoxa_r_indices.emplace(it->second);
588 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_mesocoxa_r_indices, mesocoxa_r_bone_index, legs_to_body);
589 std::unordered_set<std::uint8_t> old_mesofemur_r_indices;
590 if (
auto it = legs_skeleton.bone_map.find(
"mesofemur_r"); it != legs_skeleton.bone_map.end())
591 old_mesofemur_r_indices.emplace(it->second);
592 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_mesofemur_r_indices, mesofemur_r_bone_index, legs_to_body);
593 std::unordered_set<std::uint8_t> old_mesotibia_r_indices;
594 if (
auto it = legs_skeleton.bone_map.find(
"mesotibia_r"); it != legs_skeleton.bone_map.end())
595 old_mesotibia_r_indices.emplace(it->second);
596 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_mesotibia_r_indices, mesotibia_r_bone_index, legs_to_body);
597 std::unordered_set<std::uint8_t> old_mesotarsus_r_indices;
598 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus1_r"); it != legs_skeleton.bone_map.end())
599 old_mesotarsus_r_indices.emplace(it->second);
600 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus2_r"); it != legs_skeleton.bone_map.end())
601 old_mesotarsus_r_indices.emplace(it->second);
602 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus3_r"); it != legs_skeleton.bone_map.end())
603 old_mesotarsus_r_indices.emplace(it->second);
604 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus4_r"); it != legs_skeleton.bone_map.end())
605 old_mesotarsus_r_indices.emplace(it->second);
606 if (
auto it = legs_skeleton.bone_map.find(
"mesotarsus5_r"); it != legs_skeleton.bone_map.end())
607 old_mesotarsus_r_indices.emplace(it->second);
608 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_mesotarsus_r_indices, mesotarsus_r_bone_index, legs_to_body);
610 std::unordered_set<std::uint8_t> old_metacoxa_l_indices;
611 if (
auto it = legs_skeleton.bone_map.find(
"metacoxa_l"); it != legs_skeleton.bone_map.end())
612 old_metacoxa_l_indices.emplace(it->second);
613 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_metacoxa_l_indices, metacoxa_l_bone_index, legs_to_body);
614 std::unordered_set<std::uint8_t> old_metafemur_l_indices;
615 if (
auto it = legs_skeleton.bone_map.find(
"metafemur_l"); it != legs_skeleton.bone_map.end())
616 old_metafemur_l_indices.emplace(it->second);
617 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_metafemur_l_indices, metafemur_l_bone_index, legs_to_body);
618 std::unordered_set<std::uint8_t> old_metatibia_l_indices;
619 if (
auto it = legs_skeleton.bone_map.find(
"metatibia_l"); it != legs_skeleton.bone_map.end())
620 old_metatibia_l_indices.emplace(it->second);
621 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_metatibia_l_indices, metatibia_l_bone_index, legs_to_body);
622 std::unordered_set<std::uint8_t> old_metatarsus_l_indices;
623 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus1_l"); it != legs_skeleton.bone_map.end())
624 old_metatarsus_l_indices.emplace(it->second);
625 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus2_l"); it != legs_skeleton.bone_map.end())
626 old_metatarsus_l_indices.emplace(it->second);
627 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus3_l"); it != legs_skeleton.bone_map.end())
628 old_metatarsus_l_indices.emplace(it->second);
629 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus4_l"); it != legs_skeleton.bone_map.end())
630 old_metatarsus_l_indices.emplace(it->second);
631 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus5_l"); it != legs_skeleton.bone_map.end())
632 old_metatarsus_l_indices.emplace(it->second);
633 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_metatarsus_l_indices, metatarsus_l_bone_index, legs_to_body);
635 std::unordered_set<std::uint8_t> old_metacoxa_r_indices;
636 if (
auto it = legs_skeleton.bone_map.find(
"metacoxa_r"); it != legs_skeleton.bone_map.end())
637 old_metacoxa_r_indices.emplace(it->second);
638 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_metacoxa_r_indices, metacoxa_r_bone_index, legs_to_body);
639 std::unordered_set<std::uint8_t> old_metafemur_r_indices;
640 if (
auto it = legs_skeleton.bone_map.find(
"metafemur_r"); it != legs_skeleton.bone_map.end())
641 old_metafemur_r_indices.emplace(it->second);
642 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_metafemur_r_indices, metafemur_r_bone_index, legs_to_body);
643 std::unordered_set<std::uint8_t> old_metatibia_r_indices;
644 if (
auto it = legs_skeleton.bone_map.find(
"metatibia_r"); it != legs_skeleton.bone_map.end())
645 old_metatibia_r_indices.emplace(it->second);
646 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_metatibia_r_indices, metatibia_r_bone_index, legs_to_body);
647 std::unordered_set<std::uint8_t> old_metatarsus_r_indices;
648 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus1_r"); it != legs_skeleton.bone_map.end())
649 old_metatarsus_r_indices.emplace(it->second);
650 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus2_r"); it != legs_skeleton.bone_map.end())
651 old_metatarsus_r_indices.emplace(it->second);
652 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus3_r"); it != legs_skeleton.bone_map.end())
653 old_metatarsus_r_indices.emplace(it->second);
654 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus4_r"); it != legs_skeleton.bone_map.end())
655 old_metatarsus_r_indices.emplace(it->second);
656 if (
auto it = legs_skeleton.bone_map.find(
"metatarsus5_r"); it != legs_skeleton.bone_map.end())
657 old_metatarsus_r_indices.emplace(it->second);
658 reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_metatarsus_r_indices, metatarsus_r_bone_index, legs_to_body);
661 math::transform<float> head_to_body = bind_pose_ss.at(mesosoma_bone) * mesosoma_skeleton.bind_pose.at(mesosoma_skeleton.bone_map.at(
"head"));
664 std::unordered_set<std::uint8_t> old_head_bone_indices;
665 if (
auto it = head_skeleton.bone_map.find(
"head"); it != head_skeleton.bone_map.end())
666 old_head_bone_indices.emplace(it->second);
667 reskin_vertices(vertex_buffer_data + head_vbo_offset, head_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_head_bone_indices, head_bone_index, head_to_body);
670 math::transform<float> mandible_l_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"mandible_l"));
671 math::transform<float> mandible_r_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"mandible_r"));
674 std::unordered_set<std::uint8_t> old_head_mandible_l_bone_indices;
675 if (
auto it = mandibles_skeleton.bone_map.find(
"mandible_l"); it != mandibles_skeleton.bone_map.end())
676 old_head_mandible_l_bone_indices.emplace(it->second);
677 reskin_vertices(vertex_buffer_data + mandibles_vbo_offset, mandibles_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_head_mandible_l_bone_indices, mandible_l_bone_index, mandible_l_to_body);
678 std::unordered_set<std::uint8_t> old_head_mandible_r_bone_indices;
679 if (
auto it = mandibles_skeleton.bone_map.find(
"mandible_r"); it != mandibles_skeleton.bone_map.end())
680 old_head_mandible_r_bone_indices.emplace(it->second);
681 reskin_vertices(vertex_buffer_data + mandibles_vbo_offset, mandibles_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_head_mandible_r_bone_indices, mandible_r_bone_index, mandible_r_to_body);
684 math::transform<float> antenna_l_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"antenna_l"));
685 math::transform<float> antenna_r_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"antenna_r"));
688 std::unordered_set<std::uint8_t> old_antennomere1_l_indices;
689 if (
auto it = antennae_skeleton.bone_map.find(
"antennomere1_l"); it != antennae_skeleton.bone_map.end())
690 old_antennomere1_l_indices.emplace(it->second);
691 reskin_vertices(vertex_buffer_data + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_antennomere1_l_indices, antennomere1_l_bone_index, antenna_l_to_body);
692 std::unordered_set<std::uint8_t> old_antennomere1_r_indices;
693 if (
auto it = antennae_skeleton.bone_map.find(
"antennomere1_r"); it != antennae_skeleton.bone_map.end())
694 old_antennomere1_r_indices.emplace(it->second);
695 reskin_vertices(vertex_buffer_data + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_antennomere1_r_indices, antennomere1_r_bone_index, antenna_r_to_body);
698 const std::vector<std::string> antennomere_bone_names =
713 std::unordered_set<std::uint8_t> old_antennomere_l_indices;
714 for (
const std::string& bone_name: antennomere_bone_names)
715 if (
auto it = antennae_skeleton.bone_map.find(bone_name +
"_l"); it != antennae_skeleton.bone_map.end())
716 old_antennomere_l_indices.emplace(it->second);
717 reskin_vertices(vertex_buffer_data + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_antennomere_l_indices, antennomere2_l_bone_index, antenna_l_to_body);
718 std::unordered_set<std::uint8_t> old_antennomere_r_indices;
719 for (
const std::string& bone_name: antennomere_bone_names)
720 if (
auto it = antennae_skeleton.bone_map.find(bone_name +
"_r"); it != antennae_skeleton.bone_map.end())
721 old_antennomere_r_indices.emplace(it->second);
722 reskin_vertices(vertex_buffer_data + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_antennomere_r_indices, antennomere2_r_bone_index, antenna_r_to_body);
725 math::transform<float> waist_to_body = bind_pose_ss.at(mesosoma_bone) * mesosoma_skeleton.bind_pose.at(mesosoma_skeleton.bone_map.at(
"petiole"));
728 std::unordered_set<std::uint8_t> old_petiole_bone_indices;
729 if (
auto it = waist_skeleton.bone_map.find(
"petiole"); it != waist_skeleton.bone_map.end())
730 old_petiole_bone_indices.emplace(it->second);
731 reskin_vertices(vertex_buffer_data + waist_vbo_offset, waist_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_petiole_bone_indices, petiole_bone_index, waist_to_body);
732 if (postpetiole_present)
734 std::unordered_set<std::uint8_t> old_postpetiole_bone_indices;
735 if (
auto it = waist_skeleton.bone_map.find(
"postpetiole"); it != waist_skeleton.bone_map.end())
736 old_postpetiole_bone_indices.emplace(it->second);
737 reskin_vertices(vertex_buffer_data + waist_vbo_offset, waist_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_postpetiole_bone_indices, postpetiole_bone_index, waist_to_body);
744 std::unordered_set<std::uint8_t> old_gaster_bone_indices;
745 if (
auto it = gaster_skeleton.bone_map.find(
"gaster"); it != gaster_skeleton.bone_map.end())
746 old_gaster_bone_indices.emplace(it->second);
747 reskin_vertices(vertex_buffer_data + gaster_vbo_offset, gaster_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_gaster_bone_indices, gaster_bone_index, gaster_to_body);
752 math::transform<float> sting_to_body = gaster_to_body * gaster_skeleton.bind_pose.at(gaster_skeleton.bone_map.at(
"sting"));
755 std::unordered_set<std::uint8_t> old_sting_bone_indices;
756 if (
auto it = sting_skeleton->bone_map.find(
"sting"); it != sting_skeleton->bone_map.end())
757 old_sting_bone_indices.emplace(it->second);
758 reskin_vertices(vertex_buffer_data + sting_vbo_offset, sting_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_sting_bone_indices, sting_bone_index, sting_to_body);
764 math::transform<float> eye_l_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"eye_l"));
765 math::transform<float> eye_r_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"eye_r"));
768 std::unordered_set<std::uint8_t> old_eye_l_bone_indices;
769 if (
auto it = eyes_skeleton->bone_map.find(
"eye_l"); it != eyes_skeleton->bone_map.end())
770 old_eye_l_bone_indices.emplace(it->second);
771 reskin_vertices(vertex_buffer_data + eyes_vbo_offset, eyes_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_eye_l_bone_indices, head_bone_index, eye_l_to_body);
772 std::unordered_set<std::uint8_t> old_eye_r_bone_indices;
773 if (
auto it = eyes_skeleton->bone_map.find(
"eye_r"); it != eyes_skeleton->bone_map.end())
774 old_eye_r_bone_indices.emplace(it->second);
775 reskin_vertices(vertex_buffer_data + eyes_vbo_offset, eyes_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_eye_r_bone_indices, head_bone_index, eye_r_to_body);
778 if (lateral_ocelli_present)
781 math::transform<float> ocellus_l_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"ocellus_l"));
782 math::transform<float> ocellus_r_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"ocellus_r"));
785 std::unordered_set<std::uint8_t> old_ocellus_l_bone_indices;
786 if (
auto it = lateral_ocelli_skeleton->bone_map.find(
"ocellus_l"); it != lateral_ocelli_skeleton->bone_map.end())
787 old_ocellus_l_bone_indices.emplace(it->second);
788 reskin_vertices(vertex_buffer_data + lateral_ocelli_vbo_offset, lateral_ocelli_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_ocellus_l_bone_indices, head_bone_index, ocellus_l_to_body);
789 std::unordered_set<std::uint8_t> old_ocellus_r_bone_indices;
790 if (
auto it = lateral_ocelli_skeleton->bone_map.find(
"ocellus_r"); it != lateral_ocelli_skeleton->bone_map.end())
791 old_ocellus_r_bone_indices.emplace(it->second);
792 reskin_vertices(vertex_buffer_data + lateral_ocelli_vbo_offset, lateral_ocelli_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_ocellus_r_bone_indices, head_bone_index, ocellus_r_to_body);
795 if (median_ocellus_present)
798 math::transform<float> ocellus_m_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at(
"ocellus_m"));
801 std::unordered_set<std::uint8_t> old_ocellus_m_bone_indices;
802 if (
auto it = median_ocellus_skeleton->bone_map.find(
"ocellus_m"); it != median_ocellus_skeleton->bone_map.end())
803 old_ocellus_m_bone_indices.emplace(it->second);
804 reskin_vertices(vertex_buffer_data + median_ocellus_vbo_offset, median_ocellus_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_ocellus_m_bone_indices, head_bone_index, ocellus_m_to_body);
817 std::size_t index_offset = exoskeleton_index_count;
826 index_offset += eyes_index_count;
829 if (lateral_ocelli_present || median_ocellus_present)
836 std::size_t index_count = 0;
837 if (lateral_ocelli_present)
839 index_count += lateral_ocelli_index_count;
840 index_offset += lateral_ocelli_index_count;
843 if (median_ocellus_present)
845 index_count += median_ocellus_index_count;
846 index_offset += median_ocellus_index_count;
847 if (!lateral_ocelli_present)
862 index_offset += forewings_index_count;
870 index_offset += hindwings_index_count;
874 geom::aabb<float> bounds = calculate_bounds(vertex_buffer_data, index_offset, *position_attribute);
878 delete[] vertex_buffer_data;
885 std::uint8_t* vertex_data,
886 std::size_t index_count,
891 const std::unordered_set<std::uint8_t>& old_bone_indices,
892 std::uint8_t new_bone_index,
896 std::uint8_t* position_data = vertex_data + position_attribute.
offset;
897 std::uint8_t* normal_data = vertex_data + normal_attribute.
offset;
898 std::uint8_t* tangent_data = vertex_data + tangent_attribute.
offset;
899 std::uint8_t* bone_index_data = vertex_data + bone_index_attribute.
offset;
901 for (std::size_t i = 0; i < index_count; ++i)
904 float*
bone_index =
reinterpret_cast<float*
>(bone_index_data + bone_index_attribute.
stride * i);
907 if (!old_bone_indices.count(
static_cast<std::uint8_t
>(*
bone_index + 0.5f)))
911 float* x =
reinterpret_cast<float*
>(position_data + position_attribute.
stride * i);
916 float* nx =
reinterpret_cast<float*
>(normal_data + normal_attribute.
stride * i);
921 float* tx =
reinterpret_cast<float*
>(tangent_data + tangent_attribute.
stride * i);
942 *
bone_index =
static_cast<float>(new_bone_index);
948 std::uint8_t* position_data = vertex_data + position_attribute.
offset;
951 bounds.
min_point.
x() = std::numeric_limits<float>::infinity();
952 bounds.
min_point.
y() = std::numeric_limits<float>::infinity();
953 bounds.
min_point.
z() = std::numeric_limits<float>::infinity();
954 bounds.
max_point.
x() = -std::numeric_limits<float>::infinity();
955 bounds.
max_point.
y() = -std::numeric_limits<float>::infinity();
956 bounds.
max_point.
z() = -std::numeric_limits<float>::infinity();
958 for (std::size_t i = 0;
i < index_count; ++
i)
961 float*
x =
reinterpret_cast<float*
>(position_data + position_attribute.
stride *
i);
std::uint32_t bone
Skeletal animation bone identifier, consisting of a bone index in the lower half, and a parent bone i...
std::uint16_t bone_index(bone x)
Returns the index of a bone.
bone make_bone(std::uint16_t index, std::uint16_t parent_index)
Constructs a bone identifier.
std::uint16_t bone_parent_index(bone x)
Returns the parent index of a bone.
A 2D texture which can be uploaded to shaders via shader inputs.
Vertex array object (VAO), which describes how vertex attributes are stored in vertex buffer objects ...
const attribute_map_type & get_attributes() const
Returns a const reference to the map of vertex attributes bound to this vertex array.
void bind(attribute_location_type location, const vertex_attribute &attribute)
Binds a vertex attribute to the vertex array.
Vertex buffer object (VBO).
std::size_t get_size() const
Returns the size of the buffer's data, in bytes.
void repurpose(buffer_usage usage, std::size_t size, const void *data=nullptr)
Repurposes a vertex buffer, changing its usage hint, its size, and replacing its data.
void read(std::size_t offset, std::size_t size, void *data) const
Reads a subset of the buffer's data from the GL and returns it to the application.
Abstract base class for material properties.
A material is associated with exactly one shader program and contains a set of material properties wh...
material_property< T > * add_property(const std::string &name, std::size_t element_count=1)
Adds a material array property to the material.
material_property_base * get_property(const std::string &name) const
Returns the material property with the specified name, or nullptr if the material could not be found.
Part of a model which is associated with exactly one material.
void set_drawing_mode(gl::drawing_mode mode)
void set_material(material *material)
void set_start_index(std::size_t index)
void set_index_count(std::size_t count)
const gl::vertex_array * get_vertex_array() const
const skeleton & get_skeleton() const
const std::vector< model_group * > * get_groups() const
model_group * add_group(const std::string &name=std::string())
const gl::vertex_buffer * get_vertex_buffer() const
void set_bounds(const aabb_type &bounds)
polyphenic_gene< phene::pigmentation > pigmentation
Polyphenic pigmentation gene.
polyphenic_gene< phene::head > head
Polyphenic head gene.
polyphenic_gene< phene::mandibles > mandibles
Polyphenic mandibles gene.
polyphenic_gene< phene::gaster > gaster
Polyphenic gaster gene.
polyphenic_gene< phene::eyes > eyes
Polyphenic eyes gene.
polyphenic_gene< phene::mesosoma > mesosoma
Polyphenic mesosoma gene.
polyphenic_gene< phene::sting > sting
Polyphenic sting gene.
polyphenic_gene< phene::legs > legs
Polyphenic legs gene.
polyphenic_gene< phene::sculpturing > sculpturing
Polyphenic sculpturing gene.
polyphenic_gene< phene::antennae > antennae
Polyphenic antennae gene.
polyphenic_gene< phene::waist > waist
Polyphenic waist gene.
render::model * morphogenesis(const phenome &phenome)
Generates a 3D model of an ant given its phenome.
aabb< float > calculate_bounds(const mesh &mesh)
Calculates the AABB bounds of a mesh.
@ static_draw
Data will be modified once, by the application, and used many times, for drawing commands.
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
@ normal
Vertex normal (vec3)
@ position
Vertex position (vec3)
@ bone_index
Vertex bone indices (vec4)
@ tangent
Vertex tangent (vec4)
void inverse(const pose &x, pose &y)
Inverses each transform in a pose.
void concatenate(const pose &bone_space, pose &skeleton_space)
Transforms a pose from bone-space into skeleton-space.
std::map< bone, math::transform< float >, bone_index_compare > pose
Skeletal animation pose.
render::model * model
3D model of the antennae.
render::model * model
3D model of the eyes, if present.
bool present
Indicates whether eyes are present.
render::model * model
3D model of the gaster.
render::model * model
3D model of the head.
render::model * model
3D model of the legs.
render::model * model
3D model of the mandibles.
render::model * model
3D model of the mesosoma.
bool median_ocellus_present
Median ocellus present.
render::model * median_ocellus_model
3D model of the median ocellus, if present.
bool lateral_ocelli_present
Lateral ocelli present.
render::model * lateral_ocelli_model
3D model of the lateral ocelli, if present.
render::model * model
3D model of the sting.
bool present
Indicates whether a sting present or not.
bool postpetiole_present
Postpetiole presence.
render::model * model
3D model of the waist.
render::model * hindwings_model
3D model of the hindwings.
bool present
Wings presence.
render::model * forewings_model
3D model of the forewings.
Complete set of ant phenes.
const phene::mandibles * mandibles
const phene::pigmentation * pigmentation
const phene::sting * sting
const phene::mesosoma * mesosoma
const phene::antennae * antennae
const phene::ocelli * ocelli
const phene::sculpturing * sculpturing
const phene::waist * waist
const phene::gaster * gaster
const phene::wings * wings
Describes a vertex attribute within a vertex buffer.
std::size_t stride
Number of bytes between consecutive instances of this attribute in the vertex buffer....
std::size_t offset
Offset to the first component of the first instance of this attribute in the vertex buffer,...
constexpr element_type & x() noexcept
Returns a reference to the first element.
constexpr element_type & y() noexcept
Returns a reference to the second element.
constexpr element_type & z() noexcept
Returns a reference to the third element.
Skeletal animation skeleton.
pose inverse_bind_pose
Inverse skeleton-space bind pose of the skeleton.
pose bind_pose
Bone-space bind pose of the skeleton.
std::unordered_map< std::string, bone > bone_map
Maps bone names to bone identifiers.