From a7e5aca4a05c9564dde7a47cf882f395967c271f Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Tue, 20 Dec 2022 23:56:09 +0800 Subject: [PATCH] Improve ant trait definitions, trait loaders, and morphogenesis. --- CMakeLists.txt | 1 - src/application.cpp | 2 +- src/color/xyy.hpp | 2 +- src/color/xyz.hpp | 2 +- src/game/ant/breed.hpp | 82 -- .../ant/{founding-mode.hpp => caste-type.hpp} | 26 +- src/game/ant/caste.hpp | 69 +- src/game/ant/morphogenesis.cpp | 952 ++++++++---------- src/game/ant/morphogenesis.hpp | 7 +- src/game/ant/species.hpp | 78 ++ .../ant/{subcaste.hpp => subcaste-type.hpp} | 24 +- src/game/ant/trait/antennae.hpp | 14 +- .../ant/trait/{nest.hpp => body-size.hpp} | 16 +- src/game/ant/trait/cocoon.hpp | 8 +- src/game/ant/trait/diet.hpp | 2 +- src/game/ant/trait/egg.hpp | 2 +- src/game/ant/trait/eyes.hpp | 22 +- src/game/ant/trait/foraging-time.hpp | 2 +- src/game/ant/trait/forewings.hpp | 51 - src/game/ant/trait/founding-mode.hpp | 48 + src/game/ant/trait/gaster.hpp | 7 +- src/game/ant/trait/head.hpp | 19 +- src/game/ant/trait/larva.hpp | 8 +- src/game/ant/trait/legs.hpp | 13 +- src/game/ant/trait/loader/antennae-loader.cpp | 16 +- .../{nest-loader.cpp => body-size-loader.cpp} | 31 +- src/game/ant/trait/loader/cocoon-loader.cpp | 9 +- src/game/ant/trait/loader/egg-loader.cpp | 3 +- src/game/ant/trait/loader/eyes-loader.cpp | 57 +- src/game/ant/trait/loader/gaster-loader.cpp | 8 +- src/game/ant/trait/loader/head-loader.cpp | 29 +- src/game/ant/trait/loader/larva-loader.cpp | 13 +- src/game/ant/trait/loader/legs-loader.cpp | 18 +- .../ant/trait/loader/mandibles-loader.cpp | 26 +- src/game/ant/trait/loader/mesosoma-loader.cpp | 32 +- src/game/ant/trait/loader/ocelli-loader.cpp | 54 +- .../ant/trait/loader/pigmentation-loader.cpp | 3 +- src/game/ant/trait/loader/pilosity-loader.cpp | 4 +- src/game/ant/trait/loader/sting-loader.cpp | 13 +- src/game/ant/trait/loader/waist-loader.cpp | 85 +- src/game/ant/trait/loader/wings-loader.cpp | 99 ++ src/game/ant/trait/mandibles.hpp | 19 +- src/game/ant/trait/mesosoma.hpp | 23 +- src/game/ant/{ => trait}/nest-site.hpp | 4 +- src/game/ant/trait/ocelli.hpp | 18 +- src/game/ant/trait/pigmentation.hpp | 2 +- src/game/ant/trait/pilosity.hpp | 2 +- src/game/ant/trait/sculpturing.hpp | 2 +- .../trait/{size.hpp => size-variation.hpp} | 20 +- src/game/ant/trait/waist.hpp | 30 +- .../ant/trait/{hindwings.hpp => wings.hpp} | 41 +- src/game/load.cpp | 113 +-- src/game/state/boot.cpp | 2 +- src/game/state/gamepad-config-menu.hpp | 1 + src/game/state/nest-selection.cpp | 135 +-- src/game/state/nuptial-flight.cpp | 80 -- src/game/state/splash.cpp | 1 - src/game/system/terrain.cpp | 130 +-- src/game/system/terrain.hpp | 8 +- src/geom/hyperoctree.hpp | 18 +- src/geom/mesh.cpp | 31 +- src/geom/mesh.hpp | 162 +-- src/geom/primitive/intersection.hpp | 10 +- src/math/matrix.hpp | 160 +-- src/math/quaternion.hpp | 96 +- src/math/vector.hpp | 274 ++--- src/render/renderer.cpp | 1 + src/resources/image.hpp | 18 +- 68 files changed, 1676 insertions(+), 1682 deletions(-) delete mode 100644 src/game/ant/breed.hpp rename src/game/ant/{founding-mode.hpp => caste-type.hpp} (69%) create mode 100644 src/game/ant/species.hpp rename src/game/ant/{subcaste.hpp => subcaste-type.hpp} (64%) rename src/game/ant/trait/{nest.hpp => body-size.hpp} (75%) delete mode 100644 src/game/ant/trait/forewings.hpp create mode 100644 src/game/ant/trait/founding-mode.hpp rename src/game/ant/trait/loader/{nest-loader.cpp => body-size-loader.cpp} (59%) create mode 100644 src/game/ant/trait/loader/wings-loader.cpp rename src/game/ant/{ => trait}/nest-site.hpp (93%) rename src/game/ant/trait/{size.hpp => size-variation.hpp} (72%) rename src/game/ant/trait/{hindwings.hpp => wings.hpp} (50%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a8b55b2..7f3572c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.7) - option(VERSION_STRING "Project version string" "0.0.0") project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX) diff --git a/src/application.cpp b/src/application.cpp index 805fc10..0a7d44a 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -297,7 +297,7 @@ void application::set_v_sync(bool v_sync) logger->pop_task(EXIT_FAILURE); logger->push_task("Enabling synchronized v-sync"); - if (SDL_GL_SetSwapInterval(-1) != 0) + if (SDL_GL_SetSwapInterval(1) != 0) { logger->pop_task(EXIT_FAILURE); } diff --git a/src/color/xyy.hpp b/src/color/xyy.hpp index c81e644..420cab2 100644 --- a/src/color/xyy.hpp +++ b/src/color/xyy.hpp @@ -34,7 +34,7 @@ namespace xyy { * @return return Luminance of @p x. */ template -constexpr inline T luminance(const math::vector3& x) +inline constexpr T luminance(const math::vector3& x) { return x[2]; } diff --git a/src/color/xyz.hpp b/src/color/xyz.hpp index ad7ff24..e138b1d 100644 --- a/src/color/xyz.hpp +++ b/src/color/xyz.hpp @@ -38,7 +38,7 @@ namespace xyz { * @return return Luminance of @p x. */ template -constexpr inline T luminance(const math::vector3& x) +inline constexpr T luminance(const math::vector3& x) { return x[1]; } diff --git a/src/game/ant/breed.hpp b/src/game/ant/breed.hpp deleted file mode 100644 index 21fe9b1..0000000 --- a/src/game/ant/breed.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2021 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_GAME_ANT_BREED_HPP -#define ANTKEEPER_GAME_ANT_BREED_HPP - -#include "game/ant/trait/antennae.hpp" -#include "game/ant/trait/cocoon.hpp" -#include "game/ant/trait/diet.hpp" -#include "game/ant/trait/egg.hpp" -#include "game/ant/trait/eyes.hpp" -#include "game/ant/trait/foraging-time.hpp" -#include "game/ant/trait/forewings.hpp" -#include "game/ant/trait/gaster.hpp" -#include "game/ant/trait/head.hpp" -#include "game/ant/trait/hindwings.hpp" -#include "game/ant/trait/larva.hpp" -#include "game/ant/trait/legs.hpp" -#include "game/ant/trait/mandibles.hpp" -#include "game/ant/trait/mesosoma.hpp" -#include "game/ant/trait/nest.hpp" -#include "game/ant/trait/ocelli.hpp" -#include "game/ant/trait/pigmentation.hpp" -#include "game/ant/trait/pilosity.hpp" -#include "game/ant/trait/sculpturing.hpp" -#include "game/ant/trait/sting.hpp" -#include "game/ant/trait/waist.hpp" - -namespace game { -namespace ant { - -/** - * Set of all traits that describes an ant breed. - */ -struct breed -{ - // Morphological traits - trait::antennae* antennae; - trait::eyes* eyes; - trait::forewings* forewings; - trait::gaster* gaster; - trait::waist* waist; - trait::head* head; - trait::hindwings* hindwings; - trait::legs* legs; - trait::mandibles* mandibles; - trait::mesosoma* mesosoma; - trait::ocelli* ocelli; - trait::sting* sting; - trait::sculpturing* sculpturing; - trait::pigmentation* pigmentation; - trait::pilosity* pilosity; - trait::egg* egg; - trait::larva* larva; - trait::cocoon* cocoon; - - // Behavioral traits - trait::diet* diet; - trait::foraging_time* foraging_time; - trait::nest* nest; -}; - -} // namespace ant -} // namespace game - -#endif // ANTKEEPER_GAME_ANT_BREED_HPP diff --git a/src/game/ant/founding-mode.hpp b/src/game/ant/caste-type.hpp similarity index 69% rename from src/game/ant/founding-mode.hpp rename to src/game/ant/caste-type.hpp index 67be08d..85128b5 100644 --- a/src/game/ant/founding-mode.hpp +++ b/src/game/ant/caste-type.hpp @@ -17,19 +17,33 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_ANT_FOUNDING_MODE_HPP -#define ANTKEEPER_GAME_ANT_FOUNDING_MODE_HPP +#ifndef ANTKEEPER_GAME_ANT_CASTE_TYPE_HPP +#define ANTKEEPER_GAME_ANT_CASTE_TYPE_HPP namespace game { namespace ant { -enum class founding_mode +/** + * Ant caste type enumerations + * + * @see https://www.antwiki.org/wiki/Caste_Terminology + */ +enum class caste_type { - semi_claustral, - claustral + /// Queen caste type. + queen, + + /// Worker caste type. + worker, + + /// Soldier caste type. + soldier, + + /// Male caste type. + male }; } // namespace ant } // namespace game -#endif // ANTKEEPER_GAME_ANT_FOUNDING_MODE_HPP +#endif // ANTKEEPER_GAME_ANT_CASTE_TYPE_HPP diff --git a/src/game/ant/caste.hpp b/src/game/ant/caste.hpp index ac1a97f..737baf8 100644 --- a/src/game/ant/caste.hpp +++ b/src/game/ant/caste.hpp @@ -20,18 +20,75 @@ #ifndef ANTKEEPER_GAME_ANT_CASTE_HPP #define ANTKEEPER_GAME_ANT_CASTE_HPP +#include "game/ant/caste-type.hpp" +#include "game/ant/trait/antennae.hpp" +#include "game/ant/trait/eyes.hpp" +#include "game/ant/trait/gaster.hpp" +#include "game/ant/trait/head.hpp" +#include "game/ant/trait/legs.hpp" +#include "game/ant/trait/mandibles.hpp" +#include "game/ant/trait/mesosoma.hpp" +#include "game/ant/trait/ocelli.hpp" +#include "game/ant/trait/pigmentation.hpp" +#include "game/ant/trait/sculpturing.hpp" +#include "game/ant/trait/size-variation.hpp" +#include "game/ant/trait/sting.hpp" +#include "game/ant/trait/waist.hpp" +#include "game/ant/trait/wings.hpp" +#include + namespace game { namespace ant { /** - * Caste type enumerations + * Ant caste description. */ -enum class caste +struct caste { - queen, - worker, - soldier, - male + /// Caste type. + caste_type type; + + /// Antennae description. + const trait::antennae* antennae; + + /// Eyes description. + const trait::eyes* eyes; + + /// Gaster description. + const trait::gaster* gaster; + + /// Head description. + const trait::head* head; + + /// Legs description. + const trait::legs* legs; + + /// Mandibles description. + const trait::mandibles* mandibles; + + /// Mesosoma description. + const trait::mesosoma* mesosoma; + + /// Ocelli description. + const trait::ocelli* ocelli; + + /// Pigmentation description. + const trait::pigmentation* pigmentation; + + /// Sculpturing description. + const trait::sculpturing* sculpturing; + + /// Size variation description. + const trait::size_variation* size_variation; + + /// Sting description. + const trait::sting* sting; + + /// Waist description. + const trait::waist* waist; + + /// Wings description. + const trait::wings* wings; }; } // namespace ant diff --git a/src/game/ant/morphogenesis.cpp b/src/game/ant/morphogenesis.cpp index 1c007e1..4ac7974 100644 --- a/src/game/ant/morphogenesis.cpp +++ b/src/game/ant/morphogenesis.cpp @@ -28,10 +28,6 @@ namespace game { namespace ant { -static render::model* generate_queen(const ant::breed& breed); -static render::model* generate_worker(const ant::breed& breed); -static render::model* generate_soldier(const ant::breed& breed); -static render::model* generate_male(const ant::breed& breed); static render::material* build_exoskeleton_material ( const ant::trait::pigmentation& pigmentation, @@ -68,79 +64,6 @@ static render::model* build_model const render::model* waist ); -render::model* morphogenesis(const ant::breed& breed, ant::caste caste) -{ - switch (caste) - { - case ant::caste::queen: - return generate_queen(breed); - case ant::caste::worker: - return generate_worker(breed); - case ant::caste::soldier: - return generate_soldier(breed); - case ant::caste::male: - return generate_male(breed); - } - - return nullptr; -} - -render::model* generate_queen(const ant::breed& breed) -{ - return nullptr; -} - -render::model* generate_worker(const ant::breed& breed) -{ - // Build exoskeleton material - render::material* exoskeleton_material = build_exoskeleton_material(*breed.pigmentation, *breed.sculpturing); - - // Get worker body part models - render::model* antennae_model = breed.antennae->model; - render::model* eyes_model = breed.eyes->model; - render::model* gaster_model = breed.gaster->model; - render::model* head_model = breed.head->model; - render::model* legs_model = breed.legs->model; - render::model* mandibles_model = breed.mandibles->model; - render::model* mesosoma_model = breed.mesosoma->model; - render::model* sting_model = breed.sting->model; - render::model* waist_model = breed.waist->model; - //render::model* lateral_ocelli_model = breed.ocelli->lateral_ocelli_model; - //render::model* median_ocellus_model = breed.ocelli->median_ocellus_model; - - // Build worker model - render::model* model = build_model - ( - exoskeleton_material, - antennae_model, - eyes_model, - nullptr, // forewings - gaster_model, - head_model, - nullptr, // hindwings - legs_model, - mandibles_model, - mesosoma_model, - nullptr, // lateral ocelli - nullptr, // median ocellus - sting_model, - waist_model - ); - - return model; -} - - -render::model* generate_soldier(const ant::breed& breed) -{ - return nullptr; -} - -render::model* generate_male(const ant::breed& breed) -{ - return nullptr; -} - render::material* build_exoskeleton_material ( const ant::trait::pigmentation& pigmentation, @@ -173,40 +96,49 @@ render::material* build_exoskeleton_material return exoskeleton_material; } -render::model* build_model -( - render::material* exoskeleton_material, - const render::model* antennae, - const render::model* eyes, - const render::model* forewings, - const render::model* gaster, - const render::model* head, - const render::model* hindwings, - const render::model* legs, - const render::model* mandibles, - const render::model* mesosoma, - const render::model* lateral_ocelli, - const render::model* median_ocellus, - const render::model* sting, - const render::model* waist -) +render::model* morphogenesis(const ant::caste& caste) { - // Get vertex buffers of required body parts - const gl::vertex_buffer* mesosoma_vbo = mesosoma->get_vertex_buffer(); - const gl::vertex_buffer* legs_vbo = legs->get_vertex_buffer(); - const gl::vertex_buffer* head_vbo = head->get_vertex_buffer(); - const gl::vertex_buffer* mandibles_vbo = mandibles->get_vertex_buffer(); - const gl::vertex_buffer* antennae_vbo = antennae->get_vertex_buffer(); - const gl::vertex_buffer* waist_vbo = waist->get_vertex_buffer(); - const gl::vertex_buffer* gaster_vbo = gaster->get_vertex_buffer(); - - // Get vertex buffers of optional body parts - const gl::vertex_buffer* sting_vbo = (sting) ? sting->get_vertex_buffer() : nullptr; - const gl::vertex_buffer* eyes_vbo = (eyes) ? eyes->get_vertex_buffer() : nullptr; - const gl::vertex_buffer* lateral_ocelli_vbo = (lateral_ocelli) ? lateral_ocelli->get_vertex_buffer() : nullptr; - const gl::vertex_buffer* median_ocellus_vbo = (median_ocellus) ? median_ocellus->get_vertex_buffer() : nullptr; - const gl::vertex_buffer* forewings_vbo = (forewings) ? forewings->get_vertex_buffer() : nullptr; - const gl::vertex_buffer* hindwings_vbo = (hindwings) ? hindwings->get_vertex_buffer() : nullptr; + // Build exoskeleton material + render::material* exoskeleton_material = build_exoskeleton_material(*caste.pigmentation, *caste.sculpturing); + + // Determine presence of optional parts + bool eyes_present = caste.eyes->present; + bool lateral_ocelli_present = caste.ocelli->lateral_ocelli_present; + bool median_ocellus_present = caste.ocelli->median_ocellus_present; + bool petiole_present = caste.waist->petiole_present; + bool postpetiole_present = caste.waist->postpetiole_present; + bool sting_present = caste.sting->present; + bool wings_present = caste.wings->present; + + // Get body part models + render::model* antennae_model = caste.antennae->model; + render::model* eyes_model = caste.eyes->model; + render::model* forewings_model = caste.wings->forewings_model; + render::model* gaster_model = caste.gaster->model; + render::model* head_model = caste.head->model; + render::model* hindwings_model = caste.wings->hindwings_model; + render::model* lateral_ocelli_model = caste.ocelli->lateral_ocelli_model; + render::model* legs_model = caste.legs->model; + render::model* mandibles_model = caste.mandibles->model; + render::model* median_ocellus_model = caste.ocelli->median_ocellus_model; + render::model* mesosoma_model = caste.mesosoma->model; + render::model* sting_model = caste.sting->model; + render::model* waist_model = caste.waist->model; + + // Get body part vertex buffers + const gl::vertex_buffer* antennae_vbo = antennae_model->get_vertex_buffer(); + const gl::vertex_buffer* eyes_vbo = (eyes_present) ? eyes_model->get_vertex_buffer() : nullptr; + const gl::vertex_buffer* forewings_vbo = (wings_present) ? forewings_model->get_vertex_buffer() : nullptr; + const gl::vertex_buffer* gaster_vbo = gaster_model->get_vertex_buffer(); + const gl::vertex_buffer* head_vbo = head_model->get_vertex_buffer(); + const gl::vertex_buffer* hindwings_vbo = (wings_present) ? hindwings_model->get_vertex_buffer() : nullptr; + const gl::vertex_buffer* lateral_ocelli_vbo = (lateral_ocelli_model) ? lateral_ocelli_model->get_vertex_buffer() : nullptr; + const gl::vertex_buffer* legs_vbo = legs_model->get_vertex_buffer(); + const gl::vertex_buffer* mandibles_vbo = mandibles_model->get_vertex_buffer(); + const gl::vertex_buffer* median_ocellus_vbo = (median_ocellus_model) ? median_ocellus_model->get_vertex_buffer() : nullptr; + const gl::vertex_buffer* mesosoma_vbo = mesosoma_model->get_vertex_buffer(); + const gl::vertex_buffer* sting_vbo = (sting_present) ? sting_model->get_vertex_buffer() : nullptr; + const gl::vertex_buffer* waist_vbo = waist_model->get_vertex_buffer(); // Determine combined size of vertex buffers and save offsets std::size_t vertex_buffer_size = 0; @@ -225,22 +157,22 @@ render::model* build_model std::size_t gaster_vbo_offset = vertex_buffer_size; vertex_buffer_size += gaster_vbo->get_size(); std::size_t sting_vbo_offset = vertex_buffer_size; - if (sting) + if (sting_present) vertex_buffer_size += sting_vbo->get_size(); std::size_t eyes_vbo_offset = vertex_buffer_size; - if (eyes) + if (eyes_present) vertex_buffer_size += eyes_vbo->get_size(); std::size_t lateral_ocelli_vbo_offset = vertex_buffer_size; - if (lateral_ocelli) + if (lateral_ocelli_present) vertex_buffer_size += lateral_ocelli_vbo->get_size(); std::size_t median_ocellus_vbo_offset = vertex_buffer_size; - if (median_ocellus) + if (median_ocellus_present) vertex_buffer_size += median_ocellus_vbo->get_size(); std::size_t forewings_vbo_offset = vertex_buffer_size; - if (forewings) + if (wings_present) vertex_buffer_size += forewings_vbo->get_size(); std::size_t hindwings_vbo_offset = vertex_buffer_size; - if (hindwings) + if (wings_present) vertex_buffer_size += hindwings_vbo->get_size(); // Allocate combined vertex buffer data @@ -254,25 +186,26 @@ render::model* build_model antennae_vbo->read(0, antennae_vbo->get_size(), vertex_buffer_data + antennae_vbo_offset); waist_vbo->read(0, waist_vbo->get_size(), vertex_buffer_data + waist_vbo_offset); gaster_vbo->read(0, gaster_vbo->get_size(), vertex_buffer_data + gaster_vbo_offset); - if (sting) + if (sting_present) sting_vbo->read(0, sting_vbo->get_size(), vertex_buffer_data + sting_vbo_offset); - if (eyes) + if (eyes_present) eyes_vbo->read(0, eyes_vbo->get_size(), vertex_buffer_data + eyes_vbo_offset); - if (lateral_ocelli) + if (lateral_ocelli_present) lateral_ocelli_vbo->read(0, lateral_ocelli_vbo->get_size(), vertex_buffer_data + lateral_ocelli_vbo_offset); - if (median_ocellus) + if (median_ocellus_present) median_ocellus_vbo->read(0, median_ocellus_vbo->get_size(), vertex_buffer_data + median_ocellus_vbo_offset); - if (forewings) + if (wings_present) + { forewings_vbo->read(0, forewings_vbo->get_size(), vertex_buffer_data + forewings_vbo_offset); - if (hindwings) hindwings_vbo->read(0, hindwings_vbo->get_size(), vertex_buffer_data + hindwings_vbo_offset); + } // Allocate model render::model* model = new render::model(); // Setup model VAO gl::vertex_array* model_vao = model->get_vertex_array(); - for (auto [location, attribute]: mesosoma->get_vertex_array()->get_attributes()) + for (auto [location, attribute]: mesosoma_model->get_vertex_array()->get_attributes()) { attribute.buffer = model->get_vertex_buffer(); model_vao->bind(location, attribute); @@ -294,146 +227,146 @@ render::model* build_model bone_index_attribute = &it->second; // Get body part skeletons - const ::skeleton& mesosoma_skeleton = mesosoma->get_skeleton(); - const ::skeleton& legs_skeleton = legs->get_skeleton(); - const ::skeleton& head_skeleton = head->get_skeleton(); - const ::skeleton& mandibles_skeleton = mandibles->get_skeleton(); - const ::skeleton& antennae_skeleton = antennae->get_skeleton(); - const ::skeleton& waist_skeleton = waist->get_skeleton(); - const ::skeleton& gaster_skeleton = gaster->get_skeleton(); - const ::skeleton* sting_skeleton = (sting) ? &sting->get_skeleton() : nullptr; - const ::skeleton* eyes_skeleton = (eyes) ? &eyes->get_skeleton() : nullptr; - const ::skeleton* lateral_ocelli_skeleton = (lateral_ocelli) ? &lateral_ocelli->get_skeleton() : nullptr; - const ::skeleton* median_ocellus_skeleton = (median_ocellus) ? &median_ocellus->get_skeleton() : nullptr; - bool postpetiole = (waist_skeleton.bone_map.find("postpetiole") != waist_skeleton.bone_map.end()); + const ::skeleton& mesosoma_skeleton = mesosoma_model->get_skeleton(); + const ::skeleton& legs_skeleton = legs_model->get_skeleton(); + const ::skeleton& head_skeleton = head_model->get_skeleton(); + const ::skeleton& mandibles_skeleton = mandibles_model->get_skeleton(); + const ::skeleton& antennae_skeleton = antennae_model->get_skeleton(); + const ::skeleton& waist_skeleton = waist_model->get_skeleton(); + const ::skeleton& gaster_skeleton = gaster_model->get_skeleton(); + const ::skeleton* sting_skeleton = (sting_present) ? &sting_model->get_skeleton() : nullptr; + const ::skeleton* eyes_skeleton = (eyes_present) ? &eyes_model->get_skeleton() : nullptr; + const ::skeleton* lateral_ocelli_skeleton = (lateral_ocelli_present) ? &lateral_ocelli_model->get_skeleton() : nullptr; + const ::skeleton* median_ocellus_skeleton = (median_ocellus_present) ? &median_ocellus_model->get_skeleton() : nullptr; // Allocate skeleton bones ::skeleton& skeleton = model->get_skeleton(); - std::size_t bone_count = 34; - if (postpetiole) + std::size_t bone_count = 33; + if (petiole_present) + bone_count += 1; + if (postpetiole_present) bone_count += 1; - if (sting) + if (sting_present) bone_count += 1; - if (forewings) - bone_count += 2; - if (hindwings) - bone_count += 2; + if (wings_present) + bone_count += 4; // Assign bone indices std::uint8_t bone_index = 0; std::uint8_t mesosoma_bone_index = bone_index++; - std::uint8_t foreleg_coxa_l_bone_index = bone_index++; - std::uint8_t foreleg_coxa_r_bone_index = bone_index++; - std::uint8_t foreleg_femur_l_bone_index = bone_index++; - std::uint8_t foreleg_femur_r_bone_index = bone_index++; - std::uint8_t foreleg_tibia_l_bone_index = bone_index++; - std::uint8_t foreleg_tibia_r_bone_index = bone_index++; - std::uint8_t foreleg_tarsus_l_bone_index = bone_index++; - std::uint8_t foreleg_tarsus_r_bone_index = bone_index++; - std::uint8_t midleg_coxa_l_bone_index = bone_index++; - std::uint8_t midleg_coxa_r_bone_index = bone_index++; - std::uint8_t midleg_femur_l_bone_index = bone_index++; - std::uint8_t midleg_femur_r_bone_index = bone_index++; - std::uint8_t midleg_tibia_l_bone_index = bone_index++; - std::uint8_t midleg_tibia_r_bone_index = bone_index++; - std::uint8_t midleg_tarsus_l_bone_index = bone_index++; - std::uint8_t midleg_tarsus_r_bone_index = bone_index++; - std::uint8_t hindleg_coxa_l_bone_index = bone_index++; - std::uint8_t hindleg_coxa_r_bone_index = bone_index++; - std::uint8_t hindleg_femur_l_bone_index = bone_index++; - std::uint8_t hindleg_femur_r_bone_index = bone_index++; - std::uint8_t hindleg_tibia_l_bone_index = bone_index++; - std::uint8_t hindleg_tibia_r_bone_index = bone_index++; - std::uint8_t hindleg_tarsus_l_bone_index = bone_index++; - std::uint8_t hindleg_tarsus_r_bone_index = bone_index++; + std::uint8_t procoxa_l_bone_index = bone_index++; + std::uint8_t procoxa_r_bone_index = bone_index++; + std::uint8_t profemur_l_bone_index = bone_index++; + std::uint8_t profemur_r_bone_index = bone_index++; + std::uint8_t protibia_l_bone_index = bone_index++; + std::uint8_t protibia_r_bone_index = bone_index++; + std::uint8_t protarsus_l_bone_index = bone_index++; + std::uint8_t protarsus_r_bone_index = bone_index++; + std::uint8_t mesocoxa_l_bone_index = bone_index++; + std::uint8_t mesocoxa_r_bone_index = bone_index++; + std::uint8_t mesofemur_l_bone_index = bone_index++; + std::uint8_t mesofemur_r_bone_index = bone_index++; + std::uint8_t mesotibia_l_bone_index = bone_index++; + std::uint8_t mesotibia_r_bone_index = bone_index++; + std::uint8_t mesotarsus_l_bone_index = bone_index++; + std::uint8_t mesotarsus_r_bone_index = bone_index++; + std::uint8_t metacoxa_l_bone_index = bone_index++; + std::uint8_t metacoxa_r_bone_index = bone_index++; + std::uint8_t metafemur_l_bone_index = bone_index++; + std::uint8_t metafemur_r_bone_index = bone_index++; + std::uint8_t metatibia_l_bone_index = bone_index++; + std::uint8_t metatibia_r_bone_index = bone_index++; + std::uint8_t metatarsus_l_bone_index = bone_index++; + std::uint8_t metatarsus_r_bone_index = bone_index++; std::uint8_t head_bone_index = bone_index++; std::uint8_t mandible_l_bone_index = bone_index++; std::uint8_t mandible_r_bone_index = bone_index++; - std::uint8_t scape_l_bone_index = bone_index++; - std::uint8_t scape_r_bone_index = bone_index++; - std::uint8_t pedicel_l_bone_index = bone_index++; - std::uint8_t pedicel_r_bone_index = bone_index++; - std::uint8_t petiole_bone_index = bone_index++; - std::uint8_t postpetiole_bone_index = (postpetiole) ? bone_index++ : static_cast(bone_count); + std::uint8_t antennomere1_l_bone_index = bone_index++; + std::uint8_t antennomere1_r_bone_index = bone_index++; + std::uint8_t antennomere2_l_bone_index = bone_index++; + std::uint8_t antennomere2_r_bone_index = bone_index++; + std::uint8_t petiole_bone_index =(petiole_present) ? bone_index++ : static_cast(bone_count); + std::uint8_t postpetiole_bone_index = (postpetiole_present) ? bone_index++ : static_cast(bone_count); std::uint8_t gaster_bone_index = bone_index++; - std::uint8_t sting_bone_index = (sting) ? bone_index++ : static_cast(bone_count); + std::uint8_t sting_bone_index = (sting_present) ? bone_index++ : static_cast(bone_count); // Construct bone identifiers ::bone mesosoma_bone = make_bone(mesosoma_bone_index); - ::bone foreleg_coxa_l_bone = make_bone(foreleg_coxa_l_bone_index, mesosoma_bone_index); - ::bone foreleg_coxa_r_bone = make_bone(foreleg_coxa_r_bone_index, mesosoma_bone_index); - ::bone foreleg_femur_l_bone = make_bone(foreleg_femur_l_bone_index, foreleg_coxa_l_bone_index); - ::bone foreleg_femur_r_bone = make_bone(foreleg_femur_r_bone_index, foreleg_coxa_r_bone_index); - ::bone foreleg_tibia_l_bone = make_bone(foreleg_tibia_l_bone_index, foreleg_femur_l_bone_index); - ::bone foreleg_tibia_r_bone = make_bone(foreleg_tibia_r_bone_index, foreleg_femur_r_bone_index); - ::bone foreleg_tarsus_l_bone = make_bone(foreleg_tarsus_l_bone_index, foreleg_tibia_l_bone_index); - ::bone foreleg_tarsus_r_bone = make_bone(foreleg_tarsus_r_bone_index, foreleg_tibia_r_bone_index); - ::bone midleg_coxa_l_bone = make_bone(midleg_coxa_l_bone_index, mesosoma_bone_index); - ::bone midleg_coxa_r_bone = make_bone(midleg_coxa_r_bone_index, mesosoma_bone_index); - ::bone midleg_femur_l_bone = make_bone(midleg_femur_l_bone_index, midleg_coxa_l_bone_index); - ::bone midleg_femur_r_bone = make_bone(midleg_femur_r_bone_index, midleg_coxa_r_bone_index); - ::bone midleg_tibia_l_bone = make_bone(midleg_tibia_l_bone_index, midleg_femur_l_bone_index); - ::bone midleg_tibia_r_bone = make_bone(midleg_tibia_r_bone_index, midleg_femur_r_bone_index); - ::bone midleg_tarsus_l_bone = make_bone(midleg_tarsus_l_bone_index, midleg_tibia_l_bone_index); - ::bone midleg_tarsus_r_bone = make_bone(midleg_tarsus_r_bone_index, midleg_tibia_r_bone_index); - ::bone hindleg_coxa_l_bone = make_bone(hindleg_coxa_l_bone_index, mesosoma_bone_index); - ::bone hindleg_coxa_r_bone = make_bone(hindleg_coxa_r_bone_index, mesosoma_bone_index); - ::bone hindleg_femur_l_bone = make_bone(hindleg_femur_l_bone_index, hindleg_coxa_l_bone_index); - ::bone hindleg_femur_r_bone = make_bone(hindleg_femur_r_bone_index, hindleg_coxa_r_bone_index); - ::bone hindleg_tibia_l_bone = make_bone(hindleg_tibia_l_bone_index, hindleg_femur_l_bone_index); - ::bone hindleg_tibia_r_bone = make_bone(hindleg_tibia_r_bone_index, hindleg_femur_r_bone_index); - ::bone hindleg_tarsus_l_bone = make_bone(hindleg_tarsus_l_bone_index, hindleg_tibia_l_bone_index); - ::bone hindleg_tarsus_r_bone = make_bone(hindleg_tarsus_r_bone_index, hindleg_tibia_r_bone_index); + ::bone procoxa_l_bone = make_bone(procoxa_l_bone_index, mesosoma_bone_index); + ::bone procoxa_r_bone = make_bone(procoxa_r_bone_index, mesosoma_bone_index); + ::bone profemur_l_bone = make_bone(profemur_l_bone_index, procoxa_l_bone_index); + ::bone profemur_r_bone = make_bone(profemur_r_bone_index, procoxa_r_bone_index); + ::bone protibia_l_bone = make_bone(protibia_l_bone_index, profemur_l_bone_index); + ::bone protibia_r_bone = make_bone(protibia_r_bone_index, profemur_r_bone_index); + ::bone protarsus_l_bone = make_bone(protarsus_l_bone_index, protibia_l_bone_index); + ::bone protarsus_r_bone = make_bone(protarsus_r_bone_index, protibia_r_bone_index); + ::bone mesocoxa_l_bone = make_bone(mesocoxa_l_bone_index, mesosoma_bone_index); + ::bone mesocoxa_r_bone = make_bone(mesocoxa_r_bone_index, mesosoma_bone_index); + ::bone mesofemur_l_bone = make_bone(mesofemur_l_bone_index, mesocoxa_l_bone_index); + ::bone mesofemur_r_bone = make_bone(mesofemur_r_bone_index, mesocoxa_r_bone_index); + ::bone mesotibia_l_bone = make_bone(mesotibia_l_bone_index, mesofemur_l_bone_index); + ::bone mesotibia_r_bone = make_bone(mesotibia_r_bone_index, mesofemur_r_bone_index); + ::bone mesotarsus_l_bone = make_bone(mesotarsus_l_bone_index, mesotibia_l_bone_index); + ::bone mesotarsus_r_bone = make_bone(mesotarsus_r_bone_index, mesotibia_r_bone_index); + ::bone metacoxa_l_bone = make_bone(metacoxa_l_bone_index, mesosoma_bone_index); + ::bone metacoxa_r_bone = make_bone(metacoxa_r_bone_index, mesosoma_bone_index); + ::bone metafemur_l_bone = make_bone(metafemur_l_bone_index, metacoxa_l_bone_index); + ::bone metafemur_r_bone = make_bone(metafemur_r_bone_index, metacoxa_r_bone_index); + ::bone metatibia_l_bone = make_bone(metatibia_l_bone_index, metafemur_l_bone_index); + ::bone metatibia_r_bone = make_bone(metatibia_r_bone_index, metafemur_r_bone_index); + ::bone metatarsus_l_bone = make_bone(metatarsus_l_bone_index, metatibia_l_bone_index); + ::bone metatarsus_r_bone = make_bone(metatarsus_r_bone_index, metatibia_r_bone_index); ::bone head_bone = make_bone(head_bone_index, mesosoma_bone_index); ::bone mandible_l_bone = make_bone(mandible_l_bone_index, head_bone_index); ::bone mandible_r_bone = make_bone(mandible_r_bone_index, head_bone_index); - ::bone scape_l_bone = make_bone(scape_l_bone_index, head_bone_index); - ::bone scape_r_bone = make_bone(scape_r_bone_index, head_bone_index); - ::bone pedicel_l_bone = make_bone(pedicel_l_bone_index, scape_l_bone_index); - ::bone pedicel_r_bone = make_bone(pedicel_r_bone_index, scape_r_bone_index); + ::bone antennomere1_l_bone = make_bone(antennomere1_l_bone_index, head_bone_index); + ::bone antennomere1_r_bone = make_bone(antennomere1_r_bone_index, head_bone_index); + ::bone antennomere2_l_bone = make_bone(antennomere2_l_bone_index, antennomere1_l_bone_index); + ::bone antennomere2_r_bone = make_bone(antennomere2_r_bone_index, antennomere1_r_bone_index); ::bone petiole_bone = make_bone(petiole_bone_index, mesosoma_bone_index); ::bone postpetiole_bone = make_bone(postpetiole_bone_index, petiole_bone_index); - ::bone gaster_bone = make_bone(gaster_bone_index, (postpetiole) ? postpetiole_bone_index : petiole_bone_index); + ::bone gaster_bone = make_bone(gaster_bone_index, (postpetiole_present) ? postpetiole_bone_index : petiole_bone_index); ::bone sting_bone = make_bone(sting_bone_index, gaster_bone_index); // Map bone names to bones skeleton.bone_map["mesosoma"] = mesosoma_bone; - skeleton.bone_map["foreleg_coxa_l"] = foreleg_coxa_l_bone; - skeleton.bone_map["foreleg_coxa_r"] = foreleg_coxa_r_bone; - skeleton.bone_map["foreleg_femur_l"] = foreleg_femur_l_bone; - skeleton.bone_map["foreleg_femur_r"] = foreleg_femur_r_bone; - skeleton.bone_map["foreleg_tibia_l"] = foreleg_tibia_l_bone; - skeleton.bone_map["foreleg_tibia_r"] = foreleg_tibia_r_bone; - skeleton.bone_map["foreleg_tarsus_l"] = foreleg_tarsus_l_bone; - skeleton.bone_map["foreleg_tarsus_r"] = foreleg_tarsus_r_bone; - skeleton.bone_map["midleg_coxa_l"] = midleg_coxa_l_bone; - skeleton.bone_map["midleg_coxa_r"] = midleg_coxa_r_bone; - skeleton.bone_map["midleg_femur_l"] = midleg_femur_l_bone; - skeleton.bone_map["midleg_femur_r"] = midleg_femur_r_bone; - skeleton.bone_map["midleg_tibia_l"] = midleg_tibia_l_bone; - skeleton.bone_map["midleg_tibia_r"] = midleg_tibia_r_bone; - skeleton.bone_map["midleg_tarsus_l"] = midleg_tarsus_l_bone; - skeleton.bone_map["midleg_tarsus_r"] = midleg_tarsus_r_bone; - skeleton.bone_map["hindleg_coxa_l"] = hindleg_coxa_l_bone; - skeleton.bone_map["hindleg_coxa_r"] = hindleg_coxa_r_bone; - skeleton.bone_map["hindleg_femur_l"] = hindleg_femur_l_bone; - skeleton.bone_map["hindleg_femur_r"] = hindleg_femur_r_bone; - skeleton.bone_map["hindleg_tibia_l"] = hindleg_tibia_l_bone; - skeleton.bone_map["hindleg_tibia_r"] = hindleg_tibia_r_bone; - skeleton.bone_map["hindleg_tarsus_l"] = hindleg_tarsus_l_bone; - skeleton.bone_map["hindleg_tarsus_r"] = hindleg_tarsus_r_bone; + skeleton.bone_map["procoxa_l"] = procoxa_l_bone; + skeleton.bone_map["procoxa_r"] = procoxa_r_bone; + skeleton.bone_map["profemur_l"] = profemur_l_bone; + skeleton.bone_map["profemur_r"] = profemur_r_bone; + skeleton.bone_map["protibia_l"] = protibia_l_bone; + skeleton.bone_map["protibia_r"] = protibia_r_bone; + skeleton.bone_map["protarsus_l"] = protarsus_l_bone; + skeleton.bone_map["protarsus_r"] = protarsus_r_bone; + skeleton.bone_map["mesocoxa_l"] = mesocoxa_l_bone; + skeleton.bone_map["mesocoxa_r"] = mesocoxa_r_bone; + skeleton.bone_map["mesofemur_l"] = mesofemur_l_bone; + skeleton.bone_map["mesofemur_r"] = mesofemur_r_bone; + skeleton.bone_map["mesotibia_l"] = mesotibia_l_bone; + skeleton.bone_map["mesotibia_r"] = mesotibia_r_bone; + skeleton.bone_map["mesotarsus_l"] = mesotarsus_l_bone; + skeleton.bone_map["mesotarsus_r"] = mesotarsus_r_bone; + skeleton.bone_map["metacoxa_l"] = metacoxa_l_bone; + skeleton.bone_map["metacoxa_r"] = metacoxa_r_bone; + skeleton.bone_map["metafemur_l"] = metafemur_l_bone; + skeleton.bone_map["metafemur_r"] = metafemur_r_bone; + skeleton.bone_map["metatibia_l"] = metatibia_l_bone; + skeleton.bone_map["metatibia_r"] = metatibia_r_bone; + skeleton.bone_map["metatarsus_l"] = metatarsus_l_bone; + skeleton.bone_map["metatarsus_r"] = metatarsus_r_bone; skeleton.bone_map["head"] = head_bone; skeleton.bone_map["mandible_l"] = mandible_l_bone; skeleton.bone_map["mandible_r"] = mandible_r_bone; - skeleton.bone_map["scape_l"] = scape_l_bone; - skeleton.bone_map["scape_r"] = scape_r_bone; - skeleton.bone_map["pedicel_l"] = pedicel_l_bone; - skeleton.bone_map["pedicel_r"] = pedicel_r_bone; - skeleton.bone_map["petiole"] = petiole_bone; - if (postpetiole) + skeleton.bone_map["antennomere1_l"] = antennomere1_l_bone; + skeleton.bone_map["antennomere1_r"] = antennomere1_r_bone; + skeleton.bone_map["antennomere2_l"] = antennomere2_l_bone; + skeleton.bone_map["antennomere2_r"] = antennomere2_r_bone; + if (petiole_present) + skeleton.bone_map["petiole"] = petiole_bone; + if (postpetiole_present) skeleton.bone_map["postpetiole"] = postpetiole_bone; skeleton.bone_map["gaster"] = gaster_bone; - if (sting) + if (sting_present) skeleton.bone_map["sting"] = sting_bone; // Get reference to skeleton bind pose @@ -444,58 +377,58 @@ render::model* build_model bind_pose[mesosoma_bone] = mesosoma_skeleton.bind_pose.at(it->second); // Skeleton forelegs pose - if (auto it = legs_skeleton.bone_map.find("foreleg_coxa_l"); it != legs_skeleton.bone_map.end()) - bind_pose[foreleg_coxa_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_coxa_r"); it != legs_skeleton.bone_map.end()) - bind_pose[foreleg_coxa_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_femur_l"); it != legs_skeleton.bone_map.end()) - bind_pose[foreleg_femur_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_femur_r"); it != legs_skeleton.bone_map.end()) - bind_pose[foreleg_femur_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tibia_l"); it != legs_skeleton.bone_map.end()) - bind_pose[foreleg_tibia_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tibia_r"); it != legs_skeleton.bone_map.end()) - bind_pose[foreleg_tibia_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus1_l"); it != legs_skeleton.bone_map.end()) - bind_pose[foreleg_tarsus_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus1_r"); it != legs_skeleton.bone_map.end()) - bind_pose[foreleg_tarsus_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("procoxa_l"); it != legs_skeleton.bone_map.end()) + bind_pose[procoxa_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("procoxa_r"); it != legs_skeleton.bone_map.end()) + bind_pose[procoxa_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("profemur_l"); it != legs_skeleton.bone_map.end()) + bind_pose[profemur_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("profemur_r"); it != legs_skeleton.bone_map.end()) + bind_pose[profemur_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("protibia_l"); it != legs_skeleton.bone_map.end()) + bind_pose[protibia_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("protibia_r"); it != legs_skeleton.bone_map.end()) + bind_pose[protibia_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus1_l"); it != legs_skeleton.bone_map.end()) + bind_pose[protarsus_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus1_r"); it != legs_skeleton.bone_map.end()) + bind_pose[protarsus_r_bone] = legs_skeleton.bind_pose.at(it->second); // Skeleton midlegs pose - if (auto it = legs_skeleton.bone_map.find("midleg_coxa_l"); it != legs_skeleton.bone_map.end()) - bind_pose[midleg_coxa_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_coxa_r"); it != legs_skeleton.bone_map.end()) - bind_pose[midleg_coxa_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_femur_l"); it != legs_skeleton.bone_map.end()) - bind_pose[midleg_femur_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_femur_r"); it != legs_skeleton.bone_map.end()) - bind_pose[midleg_femur_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tibia_l"); it != legs_skeleton.bone_map.end()) - bind_pose[midleg_tibia_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tibia_r"); it != legs_skeleton.bone_map.end()) - bind_pose[midleg_tibia_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus1_l"); it != legs_skeleton.bone_map.end()) - bind_pose[midleg_tarsus_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus1_r"); it != legs_skeleton.bone_map.end()) - bind_pose[midleg_tarsus_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("mesocoxa_l"); it != legs_skeleton.bone_map.end()) + bind_pose[mesocoxa_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("mesocoxa_r"); it != legs_skeleton.bone_map.end()) + bind_pose[mesocoxa_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("mesofemur_l"); it != legs_skeleton.bone_map.end()) + bind_pose[mesofemur_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("mesofemur_r"); it != legs_skeleton.bone_map.end()) + bind_pose[mesofemur_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotibia_l"); it != legs_skeleton.bone_map.end()) + bind_pose[mesotibia_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotibia_r"); it != legs_skeleton.bone_map.end()) + bind_pose[mesotibia_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus1_l"); it != legs_skeleton.bone_map.end()) + bind_pose[mesotarsus_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus1_r"); it != legs_skeleton.bone_map.end()) + bind_pose[mesotarsus_r_bone] = legs_skeleton.bind_pose.at(it->second); // Skeleton hindlegs pose - if (auto it = legs_skeleton.bone_map.find("hindleg_coxa_l"); it != legs_skeleton.bone_map.end()) - bind_pose[hindleg_coxa_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_coxa_r"); it != legs_skeleton.bone_map.end()) - bind_pose[hindleg_coxa_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_femur_l"); it != legs_skeleton.bone_map.end()) - bind_pose[hindleg_femur_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_femur_r"); it != legs_skeleton.bone_map.end()) - bind_pose[hindleg_femur_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tibia_l"); it != legs_skeleton.bone_map.end()) - bind_pose[hindleg_tibia_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tibia_r"); it != legs_skeleton.bone_map.end()) - bind_pose[hindleg_tibia_r_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus1_l"); it != legs_skeleton.bone_map.end()) - bind_pose[hindleg_tarsus_l_bone] = legs_skeleton.bind_pose.at(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus1_r"); it != legs_skeleton.bone_map.end()) - bind_pose[hindleg_tarsus_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("metacoxa_l"); it != legs_skeleton.bone_map.end()) + bind_pose[metacoxa_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("metacoxa_r"); it != legs_skeleton.bone_map.end()) + bind_pose[metacoxa_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("metafemur_l"); it != legs_skeleton.bone_map.end()) + bind_pose[metafemur_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("metafemur_r"); it != legs_skeleton.bone_map.end()) + bind_pose[metafemur_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("metatibia_l"); it != legs_skeleton.bone_map.end()) + bind_pose[metatibia_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("metatibia_r"); it != legs_skeleton.bone_map.end()) + bind_pose[metatibia_r_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus1_l"); it != legs_skeleton.bone_map.end()) + bind_pose[metatarsus_l_bone] = legs_skeleton.bind_pose.at(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus1_r"); it != legs_skeleton.bone_map.end()) + bind_pose[metatarsus_r_bone] = legs_skeleton.bind_pose.at(it->second); // Skeleton head pose 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")); @@ -505,30 +438,37 @@ render::model* build_model 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")); // Skeleton antennae pose - bind_pose[scape_l_bone] = head_skeleton.bind_pose.at(head_skeleton.bone_map.at("scape_l")) * antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at("scape_l")); - bind_pose[scape_r_bone] = head_skeleton.bind_pose.at(head_skeleton.bone_map.at("scape_r")) * antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at("scape_r")); - bind_pose[pedicel_l_bone] = antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at("pedicel_l")); - bind_pose[pedicel_r_bone] = antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at("pedicel_r")); + 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")); + 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")); + bind_pose[antennomere2_l_bone] = antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at("antennomere2_l")); + bind_pose[antennomere2_r_bone] = antennae_skeleton.bind_pose.at(antennae_skeleton.bone_map.at("antennomere2_r")); // Skeleton waist pose - 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")); - if (postpetiole) + if (petiole_present) + { + 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")); + } + if (postpetiole_present) { bind_pose[postpetiole_bone] = waist_skeleton.bind_pose.at(waist_skeleton.bone_map.at("postpetiole")); } // Skeleton gaster pose - if (postpetiole) + if (postpetiole_present) { 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")); } - else + else if (petiole_present) { 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")); } + else + { + 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")); + } // Skeleton sting pose - if (sting) + if (sting_present) { 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")); } @@ -541,19 +481,19 @@ render::model* build_model ::inverse(bind_pose_ss, skeleton.inverse_bind_pose); // Get number of vertex indices for each body part - std::size_t mesosoma_index_count = (*mesosoma->get_groups())[0]->get_index_count(); - std::size_t legs_index_count = (*legs->get_groups())[0]->get_index_count(); - std::size_t head_index_count = (*head->get_groups())[0]->get_index_count(); - std::size_t mandibles_index_count = (*mandibles->get_groups())[0]->get_index_count(); - std::size_t antennae_index_count = (*antennae->get_groups())[0]->get_index_count(); - std::size_t waist_index_count = (*waist->get_groups())[0]->get_index_count(); - std::size_t gaster_index_count = (*gaster->get_groups())[0]->get_index_count(); - std::size_t sting_index_count = (sting) ? (*sting->get_groups())[0]->get_index_count() : 0; - std::size_t eyes_index_count = (eyes) ? (*eyes->get_groups())[0]->get_index_count() : 0; - std::size_t lateral_ocelli_index_count = (lateral_ocelli) ? (*lateral_ocelli->get_groups())[0]->get_index_count() : 0; - std::size_t median_ocellus_index_count = (median_ocellus) ? (*median_ocellus->get_groups())[0]->get_index_count() : 0; - std::size_t forewings_index_count = (forewings) ? (*forewings->get_groups())[0]->get_index_count() : 0; - std::size_t hindwings_index_count = (hindwings) ? (*hindwings->get_groups())[0]->get_index_count() : 0; + std::size_t mesosoma_index_count = (*mesosoma_model->get_groups())[0]->get_index_count(); + std::size_t legs_index_count = (*legs_model->get_groups())[0]->get_index_count(); + std::size_t head_index_count = (*head_model->get_groups())[0]->get_index_count(); + std::size_t mandibles_index_count = (*mandibles_model->get_groups())[0]->get_index_count(); + std::size_t antennae_index_count = (*antennae_model->get_groups())[0]->get_index_count(); + std::size_t waist_index_count = (*waist_model->get_groups())[0]->get_index_count(); + std::size_t gaster_index_count = (*gaster_model->get_groups())[0]->get_index_count(); + std::size_t sting_index_count = (sting_present) ? (*sting_model->get_groups())[0]->get_index_count() : 0; + std::size_t eyes_index_count = (eyes_present) ? (*eyes_model->get_groups())[0]->get_index_count() : 0; + std::size_t lateral_ocelli_index_count = (lateral_ocelli_present) ? (*lateral_ocelli_model->get_groups())[0]->get_index_count() : 0; + std::size_t median_ocellus_index_count = (median_ocellus_present) ? (*median_ocellus_model->get_groups())[0]->get_index_count() : 0; + std::size_t forewings_index_count = (wings_present) ? (*forewings_model->get_groups())[0]->get_index_count() : 0; + std::size_t hindwings_index_count = (wings_present) ? (*hindwings_model->get_groups())[0]->get_index_count() : 0; std::size_t exoskeleton_index_count = mesosoma_index_count + legs_index_count @@ -568,155 +508,155 @@ render::model* build_model const math::transform& legs_to_body = math::transform::identity; // Reskin leg bones - std::unordered_set old_foreleg_coxa_l_indices; - if (auto it = legs_skeleton.bone_map.find("foreleg_coxa_l"); it != legs_skeleton.bone_map.end()) - old_foreleg_coxa_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_foreleg_coxa_l_indices, foreleg_coxa_l_bone_index, legs_to_body); - std::unordered_set old_foreleg_femur_l_indices; - if (auto it = legs_skeleton.bone_map.find("foreleg_femur_l"); it != legs_skeleton.bone_map.end()) - old_foreleg_femur_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_foreleg_femur_l_indices, foreleg_femur_l_bone_index, legs_to_body); - std::unordered_set old_foreleg_tibia_l_indices; - if (auto it = legs_skeleton.bone_map.find("foreleg_tibia_l"); it != legs_skeleton.bone_map.end()) - old_foreleg_tibia_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_foreleg_tibia_l_indices, foreleg_tibia_l_bone_index, legs_to_body); - std::unordered_set old_foreleg_tarsus_l_indices; - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus1_l"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus2_l"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus3_l"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus4_l"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus5_l"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_foreleg_tarsus_l_indices, foreleg_tarsus_l_bone_index, legs_to_body); - - std::unordered_set old_foreleg_coxa_r_indices; - if (auto it = legs_skeleton.bone_map.find("foreleg_coxa_r"); it != legs_skeleton.bone_map.end()) - old_foreleg_coxa_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_foreleg_coxa_r_indices, foreleg_coxa_r_bone_index, legs_to_body); - std::unordered_set old_foreleg_femur_r_indices; - if (auto it = legs_skeleton.bone_map.find("foreleg_femur_r"); it != legs_skeleton.bone_map.end()) - old_foreleg_femur_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_foreleg_femur_r_indices, foreleg_femur_r_bone_index, legs_to_body); - std::unordered_set old_foreleg_tibia_r_indices; - if (auto it = legs_skeleton.bone_map.find("foreleg_tibia_r"); it != legs_skeleton.bone_map.end()) - old_foreleg_tibia_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_foreleg_tibia_r_indices, foreleg_tibia_r_bone_index, legs_to_body); - std::unordered_set old_foreleg_tarsus_r_indices; - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus1_r"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus2_r"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus3_r"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus4_r"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("foreleg_tarsus5_r"); it != legs_skeleton.bone_map.end()) - old_foreleg_tarsus_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_foreleg_tarsus_r_indices, foreleg_tarsus_r_bone_index, legs_to_body); - - std::unordered_set old_midleg_coxa_l_indices; - if (auto it = legs_skeleton.bone_map.find("midleg_coxa_l"); it != legs_skeleton.bone_map.end()) - old_midleg_coxa_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_midleg_coxa_l_indices, midleg_coxa_l_bone_index, legs_to_body); - std::unordered_set old_midleg_femur_l_indices; - if (auto it = legs_skeleton.bone_map.find("midleg_femur_l"); it != legs_skeleton.bone_map.end()) - old_midleg_femur_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_midleg_femur_l_indices, midleg_femur_l_bone_index, legs_to_body); - std::unordered_set old_midleg_tibia_l_indices; - if (auto it = legs_skeleton.bone_map.find("midleg_tibia_l"); it != legs_skeleton.bone_map.end()) - old_midleg_tibia_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_midleg_tibia_l_indices, midleg_tibia_l_bone_index, legs_to_body); - std::unordered_set old_midleg_tarsus_l_indices; - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus1_l"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus2_l"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus3_l"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus4_l"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus5_l"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_midleg_tarsus_l_indices, midleg_tarsus_l_bone_index, legs_to_body); - - std::unordered_set old_midleg_coxa_r_indices; - if (auto it = legs_skeleton.bone_map.find("midleg_coxa_r"); it != legs_skeleton.bone_map.end()) - old_midleg_coxa_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_midleg_coxa_r_indices, midleg_coxa_r_bone_index, legs_to_body); - std::unordered_set old_midleg_femur_r_indices; - if (auto it = legs_skeleton.bone_map.find("midleg_femur_r"); it != legs_skeleton.bone_map.end()) - old_midleg_femur_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_midleg_femur_r_indices, midleg_femur_r_bone_index, legs_to_body); - std::unordered_set old_midleg_tibia_r_indices; - if (auto it = legs_skeleton.bone_map.find("midleg_tibia_r"); it != legs_skeleton.bone_map.end()) - old_midleg_tibia_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_midleg_tibia_r_indices, midleg_tibia_r_bone_index, legs_to_body); - std::unordered_set old_midleg_tarsus_r_indices; - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus1_r"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus2_r"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus3_r"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus4_r"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("midleg_tarsus5_r"); it != legs_skeleton.bone_map.end()) - old_midleg_tarsus_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_midleg_tarsus_r_indices, midleg_tarsus_r_bone_index, legs_to_body); - - std::unordered_set old_hindleg_coxa_l_indices; - if (auto it = legs_skeleton.bone_map.find("hindleg_coxa_l"); it != legs_skeleton.bone_map.end()) - old_hindleg_coxa_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_hindleg_coxa_l_indices, hindleg_coxa_l_bone_index, legs_to_body); - std::unordered_set old_hindleg_femur_l_indices; - if (auto it = legs_skeleton.bone_map.find("hindleg_femur_l"); it != legs_skeleton.bone_map.end()) - old_hindleg_femur_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_hindleg_femur_l_indices, hindleg_femur_l_bone_index, legs_to_body); - std::unordered_set old_hindleg_tibia_l_indices; - if (auto it = legs_skeleton.bone_map.find("hindleg_tibia_l"); it != legs_skeleton.bone_map.end()) - old_hindleg_tibia_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_hindleg_tibia_l_indices, hindleg_tibia_l_bone_index, legs_to_body); - std::unordered_set old_hindleg_tarsus_l_indices; - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus1_l"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus2_l"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus3_l"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus4_l"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_l_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus5_l"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_hindleg_tarsus_l_indices, hindleg_tarsus_l_bone_index, legs_to_body); - - std::unordered_set old_hindleg_coxa_r_indices; - if (auto it = legs_skeleton.bone_map.find("hindleg_coxa_r"); it != legs_skeleton.bone_map.end()) - old_hindleg_coxa_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_hindleg_coxa_r_indices, hindleg_coxa_r_bone_index, legs_to_body); - std::unordered_set old_hindleg_femur_r_indices; - if (auto it = legs_skeleton.bone_map.find("hindleg_femur_r"); it != legs_skeleton.bone_map.end()) - old_hindleg_femur_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_hindleg_femur_r_indices, hindleg_femur_r_bone_index, legs_to_body); - std::unordered_set old_hindleg_tibia_r_indices; - if (auto it = legs_skeleton.bone_map.find("hindleg_tibia_r"); it != legs_skeleton.bone_map.end()) - old_hindleg_tibia_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_hindleg_tibia_r_indices, hindleg_tibia_r_bone_index, legs_to_body); - std::unordered_set old_hindleg_tarsus_r_indices; - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus1_r"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus2_r"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus3_r"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus4_r"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_r_indices.emplace(it->second); - if (auto it = legs_skeleton.bone_map.find("hindleg_tarsus5_r"); it != legs_skeleton.bone_map.end()) - old_hindleg_tarsus_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + legs_vbo_offset, legs_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_hindleg_tarsus_r_indices, hindleg_tarsus_r_bone_index, legs_to_body); + std::unordered_set old_procoxa_l_indices; + if (auto it = legs_skeleton.bone_map.find("procoxa_l"); it != legs_skeleton.bone_map.end()) + old_procoxa_l_indices.emplace(it->second); + 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); + std::unordered_set old_profemur_l_indices; + if (auto it = legs_skeleton.bone_map.find("profemur_l"); it != legs_skeleton.bone_map.end()) + old_profemur_l_indices.emplace(it->second); + 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); + std::unordered_set old_protibia_l_indices; + if (auto it = legs_skeleton.bone_map.find("protibia_l"); it != legs_skeleton.bone_map.end()) + old_protibia_l_indices.emplace(it->second); + 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); + std::unordered_set old_protarsus_l_indices; + if (auto it = legs_skeleton.bone_map.find("protarsus1_l"); it != legs_skeleton.bone_map.end()) + old_protarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus2_l"); it != legs_skeleton.bone_map.end()) + old_protarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus3_l"); it != legs_skeleton.bone_map.end()) + old_protarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus4_l"); it != legs_skeleton.bone_map.end()) + old_protarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus5_l"); it != legs_skeleton.bone_map.end()) + old_protarsus_l_indices.emplace(it->second); + 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); + + std::unordered_set old_procoxa_r_indices; + if (auto it = legs_skeleton.bone_map.find("procoxa_r"); it != legs_skeleton.bone_map.end()) + old_procoxa_r_indices.emplace(it->second); + 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); + std::unordered_set old_profemur_r_indices; + if (auto it = legs_skeleton.bone_map.find("profemur_r"); it != legs_skeleton.bone_map.end()) + old_profemur_r_indices.emplace(it->second); + 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); + std::unordered_set old_protibia_r_indices; + if (auto it = legs_skeleton.bone_map.find("protibia_r"); it != legs_skeleton.bone_map.end()) + old_protibia_r_indices.emplace(it->second); + 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); + std::unordered_set old_protarsus_r_indices; + if (auto it = legs_skeleton.bone_map.find("protarsus1_r"); it != legs_skeleton.bone_map.end()) + old_protarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus2_r"); it != legs_skeleton.bone_map.end()) + old_protarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus3_r"); it != legs_skeleton.bone_map.end()) + old_protarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus4_r"); it != legs_skeleton.bone_map.end()) + old_protarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("protarsus5_r"); it != legs_skeleton.bone_map.end()) + old_protarsus_r_indices.emplace(it->second); + 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); + + std::unordered_set old_mesocoxa_l_indices; + if (auto it = legs_skeleton.bone_map.find("mesocoxa_l"); it != legs_skeleton.bone_map.end()) + old_mesocoxa_l_indices.emplace(it->second); + 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); + std::unordered_set old_mesofemur_l_indices; + if (auto it = legs_skeleton.bone_map.find("mesofemur_l"); it != legs_skeleton.bone_map.end()) + old_mesofemur_l_indices.emplace(it->second); + 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); + std::unordered_set old_mesotibia_l_indices; + if (auto it = legs_skeleton.bone_map.find("mesotibia_l"); it != legs_skeleton.bone_map.end()) + old_mesotibia_l_indices.emplace(it->second); + 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); + std::unordered_set old_mesotarsus_l_indices; + if (auto it = legs_skeleton.bone_map.find("mesotarsus1_l"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus2_l"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus3_l"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus4_l"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus5_l"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_l_indices.emplace(it->second); + 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); + + std::unordered_set old_mesocoxa_r_indices; + if (auto it = legs_skeleton.bone_map.find("mesocoxa_r"); it != legs_skeleton.bone_map.end()) + old_mesocoxa_r_indices.emplace(it->second); + 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); + std::unordered_set old_mesofemur_r_indices; + if (auto it = legs_skeleton.bone_map.find("mesofemur_r"); it != legs_skeleton.bone_map.end()) + old_mesofemur_r_indices.emplace(it->second); + 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); + std::unordered_set old_mesotibia_r_indices; + if (auto it = legs_skeleton.bone_map.find("mesotibia_r"); it != legs_skeleton.bone_map.end()) + old_mesotibia_r_indices.emplace(it->second); + 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); + std::unordered_set old_mesotarsus_r_indices; + if (auto it = legs_skeleton.bone_map.find("mesotarsus1_r"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus2_r"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus3_r"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus4_r"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("mesotarsus5_r"); it != legs_skeleton.bone_map.end()) + old_mesotarsus_r_indices.emplace(it->second); + 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); + + std::unordered_set old_metacoxa_l_indices; + if (auto it = legs_skeleton.bone_map.find("metacoxa_l"); it != legs_skeleton.bone_map.end()) + old_metacoxa_l_indices.emplace(it->second); + 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); + std::unordered_set old_metafemur_l_indices; + if (auto it = legs_skeleton.bone_map.find("metafemur_l"); it != legs_skeleton.bone_map.end()) + old_metafemur_l_indices.emplace(it->second); + 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); + std::unordered_set old_metatibia_l_indices; + if (auto it = legs_skeleton.bone_map.find("metatibia_l"); it != legs_skeleton.bone_map.end()) + old_metatibia_l_indices.emplace(it->second); + 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); + std::unordered_set old_metatarsus_l_indices; + if (auto it = legs_skeleton.bone_map.find("metatarsus1_l"); it != legs_skeleton.bone_map.end()) + old_metatarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus2_l"); it != legs_skeleton.bone_map.end()) + old_metatarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus3_l"); it != legs_skeleton.bone_map.end()) + old_metatarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus4_l"); it != legs_skeleton.bone_map.end()) + old_metatarsus_l_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus5_l"); it != legs_skeleton.bone_map.end()) + old_metatarsus_l_indices.emplace(it->second); + 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); + + std::unordered_set old_metacoxa_r_indices; + if (auto it = legs_skeleton.bone_map.find("metacoxa_r"); it != legs_skeleton.bone_map.end()) + old_metacoxa_r_indices.emplace(it->second); + 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); + std::unordered_set old_metafemur_r_indices; + if (auto it = legs_skeleton.bone_map.find("metafemur_r"); it != legs_skeleton.bone_map.end()) + old_metafemur_r_indices.emplace(it->second); + 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); + std::unordered_set old_metatibia_r_indices; + if (auto it = legs_skeleton.bone_map.find("metatibia_r"); it != legs_skeleton.bone_map.end()) + old_metatibia_r_indices.emplace(it->second); + 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); + std::unordered_set old_metatarsus_r_indices; + if (auto it = legs_skeleton.bone_map.find("metatarsus1_r"); it != legs_skeleton.bone_map.end()) + old_metatarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus2_r"); it != legs_skeleton.bone_map.end()) + old_metatarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus3_r"); it != legs_skeleton.bone_map.end()) + old_metatarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus4_r"); it != legs_skeleton.bone_map.end()) + old_metatarsus_r_indices.emplace(it->second); + if (auto it = legs_skeleton.bone_map.find("metatarsus5_r"); it != legs_skeleton.bone_map.end()) + old_metatarsus_r_indices.emplace(it->second); + 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); // Calculate transform from head space to body space math::transform head_to_body = bind_pose_ss.at(mesosoma_bone) * mesosoma_skeleton.bind_pose.at(mesosoma_skeleton.bone_map.at("head")); @@ -742,46 +682,45 @@ render::model* build_model 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); // Calculate transforms from antennae space to body space - math::transform antenna_l_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at("scape_l")); - math::transform antenna_r_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at("scape_r")); - - // Reskin scape bones - std::unordered_set old_scape_l_indices; - if (auto it = antennae_skeleton.bone_map.find("scape_l"); it != antennae_skeleton.bone_map.end()) - old_scape_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_scape_l_indices, scape_l_bone_index, antenna_l_to_body); - std::unordered_set old_scape_r_indices; - if (auto it = antennae_skeleton.bone_map.find("scape_r"); it != antennae_skeleton.bone_map.end()) - old_scape_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_scape_r_indices, scape_r_bone_index, antenna_r_to_body); - - // Reskin pedicel bones - const std::vector pedicel_bone_names = + math::transform antenna_l_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at("antenna_l")); + math::transform antenna_r_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at("antenna_r")); + + // Reskin antennomere1 bones + std::unordered_set old_antennomere1_l_indices; + if (auto it = antennae_skeleton.bone_map.find("antennomere1_l"); it != antennae_skeleton.bone_map.end()) + old_antennomere1_l_indices.emplace(it->second); + 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); + std::unordered_set old_antennomere1_r_indices; + if (auto it = antennae_skeleton.bone_map.find("antennomere1_r"); it != antennae_skeleton.bone_map.end()) + old_antennomere1_r_indices.emplace(it->second); + 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); + + // Reskin antennomere2+ bones + const std::vector antennomere_bone_names = { - "pedicel", - "flagellomere_1", - "flagellomere_2", - "flagellomere_3", - "flagellomere_4", - "flagellomere_5", - "flagellomere_6", - "flagellomere_7", - "flagellomere_8", - "flagellomere_9", - "flagellomere_10", - "flagellomere_11", - "flagellomere_12" + "antennomere2", + "antennomere3", + "antennomere4", + "antennomere5", + "antennomere6", + "antennomere7", + "antennomere8", + "antennomere9", + "antennomere10", + "antennomere11", + "antennomere12", + "antennomere13" }; - std::unordered_set old_pedicel_l_indices; - for (const std::string& bone_name: pedicel_bone_names) + std::unordered_set old_antennomere_l_indices; + for (const std::string& bone_name: antennomere_bone_names) if (auto it = antennae_skeleton.bone_map.find(bone_name + "_l"); it != antennae_skeleton.bone_map.end()) - old_pedicel_l_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_pedicel_l_indices, pedicel_l_bone_index, antenna_l_to_body); - std::unordered_set old_pedicel_r_indices; - for (const std::string& bone_name: pedicel_bone_names) + old_antennomere_l_indices.emplace(it->second); + 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); + std::unordered_set old_antennomere_r_indices; + for (const std::string& bone_name: antennomere_bone_names) if (auto it = antennae_skeleton.bone_map.find(bone_name + "_r"); it != antennae_skeleton.bone_map.end()) - old_pedicel_r_indices.emplace(it->second); - reskin_vertices(vertex_buffer_data + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_pedicel_r_indices, pedicel_r_bone_index, antenna_r_to_body); + old_antennomere_r_indices.emplace(it->second); + 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); // Calculate transform from waist space to body space math::transform waist_to_body = bind_pose_ss.at(mesosoma_bone) * mesosoma_skeleton.bind_pose.at(mesosoma_skeleton.bone_map.at("petiole")); @@ -791,7 +730,7 @@ render::model* build_model if (auto it = waist_skeleton.bone_map.find("petiole"); it != waist_skeleton.bone_map.end()) old_petiole_bone_indices.emplace(it->second); 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); - if (postpetiole) + if (postpetiole_present) { std::unordered_set old_postpetiole_bone_indices; if (auto it = waist_skeleton.bone_map.find("postpetiole"); it != waist_skeleton.bone_map.end()) @@ -808,7 +747,7 @@ render::model* build_model old_gaster_bone_indices.emplace(it->second); 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); - if (sting) + if (sting_present) { // Calculate transform from sting space to body space math::transform sting_to_body = bind_pose_ss.at(gaster_bone) * gaster_skeleton.bind_pose.at(gaster_skeleton.bone_map.at("sting")); @@ -820,7 +759,7 @@ render::model* build_model 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); } - if (eyes) + if (eyes_present) { // Calculate transforms from eyes space to body space math::transform eye_l_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at("eye_l")); @@ -837,7 +776,7 @@ render::model* build_model 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); } - if (lateral_ocelli) + if (lateral_ocelli_present) { // Calculate transforms from lateral ocelli space to body space math::transform ocellus_l_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at("ocellus_l")); @@ -854,7 +793,7 @@ render::model* build_model 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); } - if (median_ocellus) + if (median_ocellus_present) { // Calculate transforms from lateral ocelli space to body space math::transform ocellus_m_to_body = bind_pose_ss.at(head_bone) * head_skeleton.bind_pose.at(head_skeleton.bone_map.at("ocellus_m")); @@ -877,18 +816,18 @@ render::model* build_model exoskeleton_group->set_index_count(exoskeleton_index_count); std::size_t index_offset = exoskeleton_index_count; - if (eyes) + if (eyes_present) { // Construct eyes model group render::model_group* eyes_group = model->add_group("eyes"); - eyes_group->set_material((*eyes->get_groups())[0]->get_material()); + eyes_group->set_material((*eyes_model->get_groups())[0]->get_material()); eyes_group->set_drawing_mode(gl::drawing_mode::triangles); eyes_group->set_start_index(index_offset); eyes_group->set_index_count(eyes_index_count); index_offset += eyes_index_count; } - if (lateral_ocelli || median_ocellus) + if (lateral_ocelli_present || median_ocellus_present) { // Construct ocelli model group render::model_group* ocelli_group = model->add_group("ocelli"); @@ -896,39 +835,36 @@ render::model* build_model ocelli_group->set_start_index(index_offset); std::size_t index_count = 0; - if (lateral_ocelli) + if (lateral_ocelli_present) { index_count += lateral_ocelli_index_count; index_offset += lateral_ocelli_index_count; - ocelli_group->set_material((*lateral_ocelli->get_groups())[0]->get_material()); + ocelli_group->set_material((*lateral_ocelli_model->get_groups())[0]->get_material()); } - if (median_ocellus) + if (median_ocellus_present) { index_count += median_ocellus_index_count; index_offset += median_ocellus_index_count; - if (!lateral_ocelli) - ocelli_group->set_material((*median_ocellus->get_groups())[0]->get_material()); + if (!lateral_ocelli_present) + ocelli_group->set_material((*median_ocellus_model->get_groups())[0]->get_material()); } ocelli_group->set_index_count(index_count); } - if (forewings) + if (wings_present) { // Construct forewings model group render::model_group* forewings_group = model->add_group("forewings"); - forewings_group->set_material((*forewings->get_groups())[0]->get_material()); + forewings_group->set_material((*forewings_model->get_groups())[0]->get_material()); forewings_group->set_drawing_mode(gl::drawing_mode::triangles); forewings_group->set_start_index(index_offset); forewings_group->set_index_count(forewings_index_count); index_offset += forewings_index_count; - } - - if (hindwings) - { + // Construct hindwings model group render::model_group* hindwings_group = model->add_group("hindwings"); - hindwings_group->set_material((*hindwings->get_groups())[0]->get_material()); + hindwings_group->set_material((*hindwings_model->get_groups())[0]->get_material()); hindwings_group->set_drawing_mode(gl::drawing_mode::triangles); hindwings_group->set_start_index(index_offset); hindwings_group->set_index_count(hindwings_index_count); diff --git a/src/game/ant/morphogenesis.hpp b/src/game/ant/morphogenesis.hpp index b10540e..1c30051 100644 --- a/src/game/ant/morphogenesis.hpp +++ b/src/game/ant/morphogenesis.hpp @@ -20,7 +20,6 @@ #ifndef ANTKEEPER_GAME_ANT_MORPHOGENESIS_HPP #define ANTKEEPER_GAME_ANT_MORPHOGENESIS_HPP -#include "game/ant/breed.hpp" #include "game/ant/caste.hpp" #include "render/model.hpp" @@ -30,11 +29,11 @@ namespace ant { /** * Generates a 3D model of an ant. * - * @param breed Breed of the ant. - * @param caste Caste to which the ant belongs. + * @param caste Caste description. + * * @return 3D model of an ant. */ -render::model* morphogenesis(const ant::breed& breed, ant::caste caste); +render::model* morphogenesis(const ant::caste& caste); } // namespace ant } // namespace game diff --git a/src/game/ant/species.hpp b/src/game/ant/species.hpp new file mode 100644 index 0000000..0ebcc1a --- /dev/null +++ b/src/game/ant/species.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GAME_ANT_SPECIES_HPP +#define ANTKEEPER_GAME_ANT_SPECIES_HPP + +#include "game/ant/caste.hpp" +#include "game/ant/trait/body-size.hpp" +#include "game/ant/trait/cocoon.hpp" +#include "game/ant/trait/diet.hpp" +#include "game/ant/trait/egg.hpp" +#include "game/ant/trait/foraging-time.hpp" +#include "game/ant/trait/larva.hpp" +#include "game/ant/trait/nest-site.hpp" +#include + +namespace game { +namespace ant { + +/** + * Ant species description. + */ +struct species +{ + /// Body size description. + const trait::body_size* body_size; + + /// Egg description. + const trait::egg* egg; + + /// Larva description. + const trait::larva* larva; + + /// Cocoon description. + const trait::cocoon* cocoon; + + /// Queen caste description. + std::optional queen_caste; + + /// Worker caste description. + std::optional worker_caste; + + /// Soldier caste description. + std::optional soldier_caste; + + /// Male caste description. + std::optional male_caste; + + /// Diet description. + const trait::diet* diet; + + /// Foraging time description. + const trait::foraging_time* foraging_time; + + /// Nest site description. + const trait::nest_site* nest_site; +}; + +} // namespace ant +} // namespace game + +#endif // ANTKEEPER_GAME_ANT_SPECIES_HPP diff --git a/src/game/ant/subcaste.hpp b/src/game/ant/subcaste-type.hpp similarity index 64% rename from src/game/ant/subcaste.hpp rename to src/game/ant/subcaste-type.hpp index 82e360b..0c3f8fd 100644 --- a/src/game/ant/subcaste.hpp +++ b/src/game/ant/subcaste-type.hpp @@ -17,43 +17,43 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_ANT_SUBCASTE_HPP -#define ANTKEEPER_GAME_ANT_SUBCASTE_HPP +#ifndef ANTKEEPER_GAME_ANT_SUBCASTE_TYPE_HPP +#define ANTKEEPER_GAME_ANT_SUBCASTE_TYPE_HPP namespace game { namespace ant { /** - * Ant subcaste types. + * Ant subcaste type enumerations. */ enum class subcaste { - /// A worker from the queen's first batch of eggs, smaller than normal workers. + /// Worker from the queen's first batch of eggs, smaller than normal workers. nanitic, - /// A small worker or soldier. + /// Small worker or soldier. minor, - /// A normal-sized worker or soldier + /// Normal-sized worker or soldier media, - /// A large worker or soldier. + /// Large worker or soldier. major, - /// A queen or male which still has its wings. + /// Winged queen or male. alate, - /// A queen or male which has shed its wings. + /// Dewinged queen or male. dealate, - /// A queen or male which does not develop wings. + /// Queen or male which does not develop wings. ergatoid, - /// A queen or male with short, nonfunctional wings. + /// Queen or male with short, nonfunctional wings. brachypterous }; } // namespace ant } // namespace game -#endif // ANTKEEPER_GAME_ANT_SUBCASTE_HPP +#endif // ANTKEEPER_GAME_ANT_SUBCASTE_TYPE_HPP diff --git a/src/game/ant/trait/antennae.hpp b/src/game/ant/trait/antennae.hpp index bda1b9b..2e57cb0 100644 --- a/src/game/ant/trait/antennae.hpp +++ b/src/game/ant/trait/antennae.hpp @@ -27,15 +27,21 @@ namespace ant { namespace trait { /** - * Trait that describes the antennae of an ant. + * Ant antennae description. + * + * @see https://www.antwiki.org/wiki/Character_States_for_Extant_Ant_Genera_of_the_Formicidae + * @see https://www.antwiki.org/wiki/Morphological_Measurements */ struct antennae { - /// Scape length (SL), measured in mesosomal lengths. - float scape_length; - /// 3D model of the antennae. render::model* model; + + /// Total number of antennal segments. + int total_antennomere_count; + + /// Number of antennal segments that constitute a club. + int club_antennomere_count; }; } // namespace trait diff --git a/src/game/ant/trait/nest.hpp b/src/game/ant/trait/body-size.hpp similarity index 75% rename from src/game/ant/trait/nest.hpp rename to src/game/ant/trait/body-size.hpp index 3349b13..7ba7d74 100644 --- a/src/game/ant/trait/nest.hpp +++ b/src/game/ant/trait/body-size.hpp @@ -17,26 +17,24 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_ANT_TRAIT_NEST_HPP -#define ANTKEEPER_GAME_ANT_TRAIT_NEST_HPP - -#include "game/ant/nest-site.hpp" +#ifndef ANTKEEPER_GAME_ANT_TRAIT_BODY_SIZE_HPP +#define ANTKEEPER_GAME_ANT_TRAIT_BODY_SIZE_HPP namespace game { namespace ant { namespace trait { /** - * Trait that describes the nest site of an ant. + * Ant body size description. */ -struct nest +struct body_size { - /// Site of the nest. - game::ant::nest_site site; + /// Mesosoma length (Weber's length) of a media worker, in centimeters. + float mesosoma_length; }; } // namespace trait } // namespace ant } // namespace game -#endif // ANTKEEPER_GAME_ANT_TRAIT_NEST_HPP +#endif // ANTKEEPER_GAME_ANT_TRAIT_BODY_SIZE_HPP diff --git a/src/game/ant/trait/cocoon.hpp b/src/game/ant/trait/cocoon.hpp index ea34f17..6898732 100644 --- a/src/game/ant/trait/cocoon.hpp +++ b/src/game/ant/trait/cocoon.hpp @@ -27,15 +27,15 @@ namespace ant { namespace trait { /** - * Trait that describes the cocoon of an ant species. + * Ant cocoon description. */ struct cocoon { - /// Indicates whether a cocoon is formed by the larvae or not. - bool present; - /// 3D model of the cocoon, if present. render::model* model; + + /// Indicates whether a cocoon is formed by the larvae or not. + bool present; }; } // namespace trait diff --git a/src/game/ant/trait/diet.hpp b/src/game/ant/trait/diet.hpp index a1ec448..a691a23 100644 --- a/src/game/ant/trait/diet.hpp +++ b/src/game/ant/trait/diet.hpp @@ -25,7 +25,7 @@ namespace ant { namespace trait { /** - * Trait that describes the diet of an ant. + * Ant diet description. */ struct diet { diff --git a/src/game/ant/trait/egg.hpp b/src/game/ant/trait/egg.hpp index b5a2502..a34cd2a 100644 --- a/src/game/ant/trait/egg.hpp +++ b/src/game/ant/trait/egg.hpp @@ -27,7 +27,7 @@ namespace ant { namespace trait { /** - * Trait that describes the eggs of an ant species. + * Ant egg description. */ struct egg { diff --git a/src/game/ant/trait/eyes.hpp b/src/game/ant/trait/eyes.hpp index 3018f65..378e4a9 100644 --- a/src/game/ant/trait/eyes.hpp +++ b/src/game/ant/trait/eyes.hpp @@ -27,21 +27,29 @@ namespace ant { namespace trait { /** - * Trait that describes the eyes of an ant. + * Ant eyes description. + * + * @see https://www.antwiki.org/wiki/Morphological_Measurements */ struct eyes { - /// Eye length (EL), measured in mesosomal lengths. + /// 3D model of the eyes, if present. + render::model* model; + + /// Indicates whether eyes are present. + bool present; + + /// Eye length, in mesosomal lengths. float length; - /// Eye width (EW), measured in mesosomal lengths. + /// Eye width, in mesosomal lengths. float width; - /// Number of ommatidia. - int ommatidia; + /// Eye height, in mesosomal lengths. + float height; - /// 3D model of the eyes. - render::model* model; + /// Number of ommatidia. + int ommatidia_count; }; } // namespace trait diff --git a/src/game/ant/trait/foraging-time.hpp b/src/game/ant/trait/foraging-time.hpp index 90df4a8..7abb08f 100644 --- a/src/game/ant/trait/foraging-time.hpp +++ b/src/game/ant/trait/foraging-time.hpp @@ -27,7 +27,7 @@ namespace ant { namespace trait { /** - * Trait that describes the surface foraging time of an ant. + * Ant foraging time description. */ struct foraging_time { diff --git a/src/game/ant/trait/forewings.hpp b/src/game/ant/trait/forewings.hpp deleted file mode 100644 index fc604a5..0000000 --- a/src/game/ant/trait/forewings.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2021 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_GAME_ANT_TRAIT_FOREWINGS_HPP -#define ANTKEEPER_GAME_ANT_TRAIT_FOREWINGS_HPP - -#include "render/model.hpp" - -namespace game { -namespace ant { -namespace trait { - -/** - * Trait that describes the forewings of an ant. - */ -struct forewings -{ - /// Wing length, measured in mesosomal lengths. - float length; - - /// Wing width, measured in mesosomal lengths. - float width; - - /// Degree of venation. A value of `1.0` indicates a highly-developed venation pattern, while `0.0` indicates a complete absence of visible venation. - float venation; - - /// 3D model of the forewings. - render::model* model; -}; - -} // namespace trait -} // namespace ant -} // namespace game - -#endif // ANTKEEPER_GAME_ANT_TRAIT_FOREWINGS_HPP diff --git a/src/game/ant/trait/founding-mode.hpp b/src/game/ant/trait/founding-mode.hpp new file mode 100644 index 0000000..7a86dcc --- /dev/null +++ b/src/game/ant/trait/founding-mode.hpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GAME_ANT_TRAIT_FOUNDING_MODE_HPP +#define ANTKEEPER_GAME_ANT_TRAIT_FOUNDING_MODE_HPP + +namespace game { +namespace ant { +namespace trait { + +/** + * Colony founding mode. + * + * @see https://www.antwiki.org/wiki/Colony_Foundation + */ +enum class founding_mode +{ + /// Foraging outside the claustral chamber is required. + semi_claustral, + + /// Foraging outside the claustral chamber is unnecessary. + claustral, + + /// Parent colony splits, with a queen taking a portion of the workforce with her. + fission +}; + +} // namespace trait +} // namespace ant +} // namespace game + +#endif // ANTKEEPER_GAME_ANT_TRAIT_FOUNDING_MODE_HPP diff --git a/src/game/ant/trait/gaster.hpp b/src/game/ant/trait/gaster.hpp index dec4005..66426d3 100644 --- a/src/game/ant/trait/gaster.hpp +++ b/src/game/ant/trait/gaster.hpp @@ -27,12 +27,17 @@ namespace ant { namespace trait { /** - * Trait that describes the gaster of an ant. + * Ant gaster description. + * + * @see https://antwiki.org/wiki/Phragmosis */ struct gaster { /// 3D model of the gaster. render::model* model; + + /// Degree of phragmosis. + float phragmosis; }; } // namespace trait diff --git a/src/game/ant/trait/head.hpp b/src/game/ant/trait/head.hpp index 6d6db88..b8a3bf6 100644 --- a/src/game/ant/trait/head.hpp +++ b/src/game/ant/trait/head.hpp @@ -27,21 +27,24 @@ namespace ant { namespace trait { /** - * Trait that describes the head of an ant. + * Ant head description. + * + * @see https://www.antwiki.org/wiki/Morphological_Measurements + * @see https://antwiki.org/wiki/Phragmosis */ struct head { - /// Head length in full face view (HL), measured in mesosomal lengths. + /// 3D model of the head. + render::model* model; + + /// Head length, in mesosomal lengths. float length; - /// Head width in full face view (HW), measured in mesosomal lengths. + /// Head width, in mesosomal lengths. float width; - /// Indicates whether the head can be used to plug nest entrances. - bool phragmotic; - - /// 3D model of the head. - render::model* model; + /// Degree of phragmosis. + float phragmosis; }; } // namespace trait diff --git a/src/game/ant/trait/larva.hpp b/src/game/ant/trait/larva.hpp index a3f5123..c011d41 100644 --- a/src/game/ant/trait/larva.hpp +++ b/src/game/ant/trait/larva.hpp @@ -27,15 +27,15 @@ namespace ant { namespace trait { /** - * Trait that describes the larvae of an ant species. + * Ant larva description. */ struct larva { - /// Number of larval instars before pupation. - int instars; - /// 3D model of the larva. render::model* model; + + /// Number of larval instars before pupation. + int instars; }; } // namespace trait diff --git a/src/game/ant/trait/legs.hpp b/src/game/ant/trait/legs.hpp index d3d005e..c8370bb 100644 --- a/src/game/ant/trait/legs.hpp +++ b/src/game/ant/trait/legs.hpp @@ -27,15 +27,20 @@ namespace ant { namespace trait { /** - * Trait that describes the legs of an ant. + * Ant legs description. + * + * @see https://www.antwiki.org/wiki/Morphological_Measurements */ struct legs { - /// Running speed, measured in mesosomal lengths per second (ML/s). - float speed; - /// 3D model of the legs. render::model* model; + + /// Running speed, in mesosomal lengths per second. + float speed; + + /// Grip factor. + float grip; }; } // namespace trait diff --git a/src/game/ant/trait/loader/antennae-loader.cpp b/src/game/ant/trait/loader/antennae-loader.cpp index 61bca5d..bcd15d1 100644 --- a/src/game/ant/trait/loader/antennae-loader.cpp +++ b/src/game/ant/trait/loader/antennae-loader.cpp @@ -37,8 +37,11 @@ trait::antennae* resource_loader::load(resource_manager* resour if (antennae_element == data->end()) throw std::runtime_error("Invalid antennae trait."); - // Allocate antennae trait + // Allocate and init antennae trait trait::antennae* antennae = new trait::antennae(); + antennae->model = nullptr; + antennae->total_antennomere_count = 0; + antennae->club_antennomere_count = 0; // Load antennae model auto model_element = antennae_element->find("model"); @@ -46,10 +49,13 @@ trait::antennae* resource_loader::load(resource_manager* resour throw std::runtime_error("Antennae trait doesn't specify antennae model."); antennae->model = resource_manager->load(model_element->get()); - // Parse antennae scape length - antennae->scape_length = 0.0f; - if (auto scape_length_element = antennae_element->find("scape_length"); scape_length_element != antennae_element->end()) - antennae->scape_length = scape_length_element->get(); + // Parse total antennomere count + if (auto element = antennae_element->find("total_antennomere_count"); element != antennae_element->end()) + antennae->total_antennomere_count = element->get(); + + // Parse club antennomere count + if (auto element = antennae_element->find("club_antennomere_count"); element != antennae_element->end()) + antennae->club_antennomere_count = element->get(); // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/nest-loader.cpp b/src/game/ant/trait/loader/body-size-loader.cpp similarity index 59% rename from src/game/ant/trait/loader/nest-loader.cpp rename to src/game/ant/trait/loader/body-size-loader.cpp index c9feb77..6cdb5c0 100644 --- a/src/game/ant/trait/loader/nest-loader.cpp +++ b/src/game/ant/trait/loader/body-size-loader.cpp @@ -20,39 +20,32 @@ #include "resources/resource-loader.hpp" #include "resources/resource-manager.hpp" #include "resources/json.hpp" -#include "game/ant/trait/nest.hpp" -#include "game/ant/nest-site.hpp" +#include "game/ant/trait/body-size.hpp" #include using namespace game::ant; template <> -trait::nest* resource_loader::load(resource_manager* resource_manager, PHYSFS_File* file, const std::filesystem::path& path) +trait::body_size* resource_loader::load(resource_manager* resource_manager, PHYSFS_File* file, const std::filesystem::path& path) { // Load JSON data json* data = resource_loader::load(resource_manager, file, path); // Validate trait file - auto nest_element = data->find("nest"); - if (nest_element == data->end()) - throw std::runtime_error("Invalid nest trait."); + auto body_size_element = data->find("body_size"); + if (body_size_element == data->end()) + throw std::runtime_error("Invalid body size trait."); - // Allocate nest trait - trait::nest* nest = new trait::nest(); + // Allocate and init body size trait + trait::body_size* body_size = new trait::body_size(); + body_size->mesosoma_length = 1.0f; - // Parse nest site - nest->site = nest_site::hypogeic; - if (auto site_element = nest_element->find("site"); site_element != nest_element->end()) - { - std::string site = site_element->get(); - if (site == "hypogeic") - nest->site = nest_site::hypogeic; - else if (site == "arboreal") - nest->site = nest_site::arboreal; - } + // Parse mesosoma length + if (auto element = body_size_element->find("mesosoma_length"); element != body_size_element->end()) + body_size->mesosoma_length = element->get(); // Free JSON data delete data; - return nest; + return body_size; } diff --git a/src/game/ant/trait/loader/cocoon-loader.cpp b/src/game/ant/trait/loader/cocoon-loader.cpp index a5b1d5d..7a532db 100644 --- a/src/game/ant/trait/loader/cocoon-loader.cpp +++ b/src/game/ant/trait/loader/cocoon-loader.cpp @@ -37,11 +37,12 @@ trait::cocoon* resource_loader::load(resource_manager* resource_m if (cocoon_element == data->end()) throw std::runtime_error("Invalid cocoon trait."); - // Allocate cocoon trait + // Allocate and init cocoon trait trait::cocoon* cocoon = new trait::cocoon(); + cocoon->present = false; + cocoon->model = nullptr; // Parse cocoon present - cocoon->present = false; if (auto present_element = cocoon_element->find("present"); present_element != cocoon_element->end()) cocoon->present = present_element->get(); @@ -53,10 +54,6 @@ trait::cocoon* resource_loader::load(resource_manager* resource_m throw std::runtime_error("Cocoon trait doesn't specify cocoon model."); cocoon->model = resource_manager->load(model_element->get()); } - else - { - cocoon->model = nullptr; - } // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/egg-loader.cpp b/src/game/ant/trait/loader/egg-loader.cpp index e4de136..005e82f 100644 --- a/src/game/ant/trait/loader/egg-loader.cpp +++ b/src/game/ant/trait/loader/egg-loader.cpp @@ -37,8 +37,9 @@ trait::egg* resource_loader::load(resource_manager* resource_manager if (egg_element == data->end()) throw std::runtime_error("Invalid egg trait."); - // Allocate egg trait + // Allocate and init egg trait trait::egg* egg = new trait::egg(); + egg->model = nullptr; // Load egg model auto model_element = egg_element->find("model"); diff --git a/src/game/ant/trait/loader/eyes-loader.cpp b/src/game/ant/trait/loader/eyes-loader.cpp index f923c4a..d89f0f1 100644 --- a/src/game/ant/trait/loader/eyes-loader.cpp +++ b/src/game/ant/trait/loader/eyes-loader.cpp @@ -37,37 +37,44 @@ trait::eyes* resource_loader::load(resource_manager* resource_manag if (eyes_element == data->end()) throw std::runtime_error("Invalid eyes trait."); - // Allocate eyes trait + // Allocate and init eyes trait trait::eyes* eyes = new trait::eyes(); + eyes->present = false; + eyes->model = nullptr; + eyes->length = 0.0f; + eyes->width = 0.0f; + eyes->height = 0.0f; + eyes->ommatidia_count = 0; - // Load eyes model (if not null) - auto model_element = eyes_element->find("model"); - if (model_element == eyes_element->end()) - throw std::runtime_error("Eyes trait doesn't specify eyes model."); - if (model_element->is_null()) - { - eyes->model = nullptr; - } - else + // Parse eyes present + if (auto present_element = eyes_element->find("present"); present_element != eyes_element->end()) + eyes->present = present_element->get(); + + if (eyes->present) { + // Load eyes model + auto model_element = eyes_element->find("model"); + if (model_element == eyes_element->end()) + throw std::runtime_error("Eyes trait doesn't specify eyes model."); eyes->model = resource_manager->load(model_element->get()); + + // Parse length + if (auto element = eyes_element->find("length"); element != eyes_element->end()) + eyes->length = element->get(); + + // Parse width + if (auto element = eyes_element->find("width"); element != eyes_element->end()) + eyes->width = element->get(); + + // Parse height + if (auto element = eyes_element->find("height"); element != eyes_element->end()) + eyes->height = element->get(); + + // Parse ommatidia count + if (auto element = eyes_element->find("ommatidia_count"); element != eyes_element->end()) + eyes->ommatidia_count = element->get(); } - // Parse eyes length - eyes->length = 0.0f; - if (auto length_element = eyes_element->find("length"); length_element != eyes_element->end()) - eyes->length = length_element->get(); - - // Parse eyes width - eyes->width = 0.0f; - if (auto width_element = eyes_element->find("width"); width_element != eyes_element->end()) - eyes->width = width_element->get(); - - // Parse eyes ommatidia - eyes->ommatidia = 0; - if (auto ommatidia_element = eyes_element->find("ommatidia"); ommatidia_element != eyes_element->end()) - eyes->ommatidia = ommatidia_element->get(); - // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/gaster-loader.cpp b/src/game/ant/trait/loader/gaster-loader.cpp index dfaed7f..3e1968e 100644 --- a/src/game/ant/trait/loader/gaster-loader.cpp +++ b/src/game/ant/trait/loader/gaster-loader.cpp @@ -37,8 +37,10 @@ trait::gaster* resource_loader::load(resource_manager* resource_m if (gaster_element == data->end()) throw std::runtime_error("Invalid gaster trait."); - // Allocate gaster trait + // Allocate and init gaster trait trait::gaster* gaster = new trait::gaster(); + gaster->model = nullptr; + gaster->phragmosis = 0.0; // Load gaster model auto model_element = gaster_element->find("model"); @@ -46,6 +48,10 @@ trait::gaster* resource_loader::load(resource_manager* resource_m throw std::runtime_error("Gaster trait doesn't specify gaster model."); gaster->model = resource_manager->load(model_element->get()); + // Parse phragmosis + if (auto element = gaster_element->find("phragmosis"); element != gaster_element->end()) + gaster->phragmosis = element->get(); + // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/head-loader.cpp b/src/game/ant/trait/loader/head-loader.cpp index a00fc42..5c3f274 100644 --- a/src/game/ant/trait/loader/head-loader.cpp +++ b/src/game/ant/trait/loader/head-loader.cpp @@ -37,29 +37,30 @@ trait::head* resource_loader::load(resource_manager* resource_manag if (head_element == data->end()) throw std::runtime_error("Invalid head trait."); - // Allocate head trait + // Allocate and init head trait trait::head* head = new trait::head(); + head->model = nullptr; + head->length = 0.0f; + head->width = 0.0f; + head->phragmosis = false; - // Load head model + // Load model auto model_element = head_element->find("model"); if (model_element == head_element->end()) throw std::runtime_error("Head trait doesn't specify head model."); head->model = resource_manager->load(model_element->get()); - // Parse head length - head->length = 0.0f; - if (auto length_element = head_element->find("length"); length_element != head_element->end()) - head->length = length_element->get(); + // Parse length + if (auto element = head_element->find("length"); element != head_element->end()) + head->length = element->get(); - // Parse head width - head->width = 0.0f; - if (auto width_element = head_element->find("width"); width_element != head_element->end()) - head->width = width_element->get(); + // Parse width + if (auto element = head_element->find("width"); element != head_element->end()) + head->width = element->get(); - // Parse head phragmotic - head->phragmotic = false; - if (auto phragmotic_element = head_element->find("phragmotic"); phragmotic_element != head_element->end()) - head->phragmotic = phragmotic_element->get(); + // Parse phragmosis + if (auto element = head_element->find("phragmosis"); element != head_element->end()) + head->phragmosis = element->get(); // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/larva-loader.cpp b/src/game/ant/trait/loader/larva-loader.cpp index 7eb19b2..490c76a 100644 --- a/src/game/ant/trait/loader/larva-loader.cpp +++ b/src/game/ant/trait/loader/larva-loader.cpp @@ -37,19 +37,20 @@ trait::larva* resource_loader::load(resource_manager* resource_man if (larva_element == data->end()) throw std::runtime_error("Invalid larva trait."); - // Allocate larva trait + // Allocate and init larva trait trait::larva* larva = new trait::larva(); + larva->model = nullptr; + larva->instars = 0; - // Load larva model + // Load model auto model_element = larva_element->find("model"); if (model_element == larva_element->end()) throw std::runtime_error("Larva trait doesn't specify larva model."); larva->model = resource_manager->load(model_element->get()); - // Parse larva instars - larva->instars = 0; - if (auto instars_element = larva_element->find("instars"); instars_element != larva_element->end()) - larva->instars = instars_element->get(); + // Parse instars + if (auto element = larva_element->find("instars"); element != larva_element->end()) + larva->instars = element->get(); // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/legs-loader.cpp b/src/game/ant/trait/loader/legs-loader.cpp index aebff06..6a53019 100644 --- a/src/game/ant/trait/loader/legs-loader.cpp +++ b/src/game/ant/trait/loader/legs-loader.cpp @@ -37,19 +37,25 @@ trait::legs* resource_loader::load(resource_manager* resource_manag if (legs_element == data->end()) throw std::runtime_error("Invalid legs trait."); - // Allocate legs trait + // Allocate and init legs trait trait::legs* legs = new trait::legs(); + legs->model = nullptr; + legs->speed = 1.0f; + legs->grip = 1.0f; - // Load legs model + // Load model auto model_element = legs_element->find("model"); if (model_element == legs_element->end()) throw std::runtime_error("Legs trait doesn't specify legs model."); legs->model = resource_manager->load(model_element->get()); - // Parse legs speed - legs->speed = 0.0f; - if (auto speed_element = legs_element->find("speed"); speed_element != legs_element->end()) - legs->speed = speed_element->get(); + // Parse speed + if (auto element = legs_element->find("speed"); element != legs_element->end()) + legs->speed = element->get(); + + // Parse grip + if (auto element = legs_element->find("grip"); element != legs_element->end()) + legs->grip = element->get(); // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/mandibles-loader.cpp b/src/game/ant/trait/loader/mandibles-loader.cpp index 495d823..cecf43b 100644 --- a/src/game/ant/trait/loader/mandibles-loader.cpp +++ b/src/game/ant/trait/loader/mandibles-loader.cpp @@ -37,24 +37,30 @@ trait::mandibles* resource_loader::load(resource_manager* reso if (mandibles_element == data->end()) throw std::runtime_error("Invalid mandibles trait."); - // Allocate mandibles trait + // Allocate and init mandibles trait trait::mandibles* mandibles = new trait::mandibles(); + mandibles->model = nullptr; + mandibles->length = 0.0f; + mandibles->apical_dental_count = 0; + mandibles->basal_dental_count = 0; - // Load mandibles model + // Load model auto model_element = mandibles_element->find("model"); if (model_element == mandibles_element->end()) throw std::runtime_error("Mandibles trait doesn't specify mandibles model."); mandibles->model = resource_manager->load(model_element->get()); - // Parse mandibles length - mandibles->length = 0.0f; - if (auto length_element = mandibles_element->find("length"); length_element != mandibles_element->end()) - mandibles->length = length_element->get(); + // Parse length + if (auto element = mandibles_element->find("length"); element != mandibles_element->end()) + mandibles->length = element->get(); + + // Parse apical dental count + if (auto element = mandibles_element->find("apical_dental_count"); element != mandibles_element->end()) + mandibles->apical_dental_count = element->get(); - // Parse mandibles locking - mandibles->locking = false; - if (auto locking_element = mandibles_element->find("locking"); locking_element != mandibles_element->end()) - mandibles->locking = locking_element->get(); + // Parse basal dental count + if (auto element = mandibles_element->find("basal_dental_count"); element != mandibles_element->end()) + mandibles->basal_dental_count = element->get(); // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/mesosoma-loader.cpp b/src/game/ant/trait/loader/mesosoma-loader.cpp index 0256a65..c4a7fba 100644 --- a/src/game/ant/trait/loader/mesosoma-loader.cpp +++ b/src/game/ant/trait/loader/mesosoma-loader.cpp @@ -37,8 +37,13 @@ trait::mesosoma* resource_loader::load(resource_manager* resour if (mesosoma_element == data->end()) throw std::runtime_error("Invalid mesosoma trait."); - // Allocate mesosoma trait + // Allocate and init mesosoma trait trait::mesosoma* mesosoma = new trait::mesosoma(); + mesosoma->model = nullptr; + mesosoma->pronotum_width = 0.0f; + mesosoma->pronotum_spinescence = 0.0f; + mesosoma->mesonotum_spinescence = 0.0f; + mesosoma->propodeum_spinescence = 0.0f; // Load mesosoma model auto model_element = mesosoma_element->find("model"); @@ -46,20 +51,21 @@ trait::mesosoma* resource_loader::load(resource_manager* resour throw std::runtime_error("Mesosoma trait doesn't specify mesosoma model."); mesosoma->model = resource_manager->load(model_element->get()); - // Parse mesosoma length - mesosoma->length = 0.0f; - if (auto length_element = mesosoma_element->find("length"); length_element != mesosoma_element->end()) - mesosoma->length = length_element->get(); + // Parse pronotum width + if (auto element = mesosoma_element->find("pronotum_width"); element != mesosoma_element->end()) + mesosoma->pronotum_width = element->get(); - // Parse mesosoma width - mesosoma->width = 0.0f; - if (auto width_element = mesosoma_element->find("width"); width_element != mesosoma_element->end()) - mesosoma->width = width_element->get(); + // Parse pronotum spinescence + if (auto element = mesosoma_element->find("pronotum_spinescence"); element != mesosoma_element->end()) + mesosoma->pronotum_spinescence = element->get(); - // Parse mesosoma spinescence - mesosoma->spinescence = 0.0f; - if (auto spinescence_element = mesosoma_element->find("spinescence"); spinescence_element != mesosoma_element->end()) - mesosoma->spinescence = spinescence_element->get(); + // Parse mesonotum spinescence + if (auto element = mesosoma_element->find("mesonotum_spinescence"); element != mesosoma_element->end()) + mesosoma->mesonotum_spinescence = element->get(); + + // Parse propodeum spinescence + if (auto element = mesosoma_element->find("propodeum_spinescence"); element != mesosoma_element->end()) + mesosoma->propodeum_spinescence = element->get(); // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/ocelli-loader.cpp b/src/game/ant/trait/loader/ocelli-loader.cpp index fccef69..6b1b96d 100644 --- a/src/game/ant/trait/loader/ocelli-loader.cpp +++ b/src/game/ant/trait/loader/ocelli-loader.cpp @@ -37,31 +37,33 @@ trait::ocelli* resource_loader::load(resource_manager* resource_m if (ocelli_element == data->end()) throw std::runtime_error("Invalid ocelli trait."); - // Allocate ocelli trait + // Allocate and init ocelli trait trait::ocelli* ocelli = new trait::ocelli(); + ocelli->lateral_ocelli_model = nullptr; + ocelli->median_ocellus_model = nullptr; + ocelli->lateral_ocelli_present = false; + ocelli->median_ocellus_present = false; + ocelli->width = 0.0f; + ocelli->height = 0.0f; - // Parse lateral ocelli - ocelli->lateral_ocelli = false; - if (auto lateral_ocelli_element = ocelli_element->find("lateral_ocelli"); lateral_ocelli_element != ocelli_element->end()) - ocelli->lateral_ocelli = lateral_ocelli_element->get(); + // Parse lateral ocelli present + if (auto element = ocelli_element->find("lateral_ocelli_present"); element != ocelli_element->end()) + ocelli->lateral_ocelli_present = element->get(); - // Parse median ocellus - ocelli->median_ocellus = false; - if (auto median_ocellus_element = ocelli_element->find("median_ocellus"); median_ocellus_element != ocelli_element->end()) - ocelli->median_ocellus = median_ocellus_element->get(); + // Parse median ocellus present + if (auto element = ocelli_element->find("median_ocellus_present"); element != ocelli_element->end()) + ocelli->median_ocellus_present = element->get(); - // Parse ocelli width - ocelli->width = 0.0f; - if (auto width_element = ocelli_element->find("width"); width_element != ocelli_element->end()) - ocelli->width = width_element->get(); - - // Parse ocelli height - ocelli->height = 0.0f; - if (auto height_element = ocelli_element->find("height"); height_element != ocelli_element->end()) - ocelli->height = height_element->get(); + // Parse width + if (auto element = ocelli_element->find("width"); element != ocelli_element->end()) + ocelli->width = element->get(); - // Load lateral ocelli model (if not null) - if (ocelli->lateral_ocelli) + // Parse height + if (auto element = ocelli_element->find("height"); element != ocelli_element->end()) + ocelli->height = element->get(); + + // Load lateral ocelli model, if present + if (ocelli->lateral_ocelli_present) { auto lateral_ocelli_model_element = ocelli_element->find("lateral_ocelli_model"); if (lateral_ocelli_model_element == ocelli_element->end() || lateral_ocelli_model_element->is_null()) @@ -69,13 +71,9 @@ trait::ocelli* resource_loader::load(resource_manager* resource_m ocelli->lateral_ocelli_model = resource_manager->load(lateral_ocelli_model_element->get()); } - else - { - ocelli->lateral_ocelli_model = nullptr; - } - // Load median ocellus model (if not null) - if (ocelli->median_ocellus) + // Load median ocellus model, if present + if (ocelli->median_ocellus_present) { auto median_ocellus_model_element = ocelli_element->find("median_ocellus_model"); if (median_ocellus_model_element == ocelli_element->end() || median_ocellus_model_element->is_null()) @@ -83,10 +81,6 @@ trait::ocelli* resource_loader::load(resource_manager* resource_m ocelli->median_ocellus_model = resource_manager->load(median_ocellus_model_element->get()); } - else - { - ocelli->median_ocellus_model = nullptr; - } // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/pigmentation-loader.cpp b/src/game/ant/trait/loader/pigmentation-loader.cpp index d18621b..829e3de 100644 --- a/src/game/ant/trait/loader/pigmentation-loader.cpp +++ b/src/game/ant/trait/loader/pigmentation-loader.cpp @@ -36,8 +36,9 @@ trait::pigmentation* resource_loader::load(resource_manager if (pigmentation_element == data->end()) throw std::runtime_error("Invalid pigmentation trait."); - // Allocate pigmentation trait + // Allocate and init pigmentation trait trait::pigmentation* pigmentation = new trait::pigmentation(); + pigmentation->material = nullptr; // Load pigmentation material auto material_element = pigmentation_element->find("material"); diff --git a/src/game/ant/trait/loader/pilosity-loader.cpp b/src/game/ant/trait/loader/pilosity-loader.cpp index 910dc70..38604a8 100644 --- a/src/game/ant/trait/loader/pilosity-loader.cpp +++ b/src/game/ant/trait/loader/pilosity-loader.cpp @@ -36,11 +36,11 @@ trait::pilosity* resource_loader::load(resource_manager* resour if (pilosity_element == data->end()) throw std::runtime_error("Invalid pilosity trait."); - // Allocate pilosity trait + // Allocate and init pilosity trait trait::pilosity* pilosity = new trait::pilosity(); + pilosity->density = 0.0f; // Parse pilosity density - pilosity->density = 0.0f; if (auto density_element = pilosity_element->find("density"); density_element != pilosity_element->end()) pilosity->density = density_element->get(); diff --git a/src/game/ant/trait/loader/sting-loader.cpp b/src/game/ant/trait/loader/sting-loader.cpp index cfa51df..93d8da8 100644 --- a/src/game/ant/trait/loader/sting-loader.cpp +++ b/src/game/ant/trait/loader/sting-loader.cpp @@ -37,13 +37,14 @@ trait::sting* resource_loader::load(resource_manager* resource_man if (sting_element == data->end()) throw std::runtime_error("Invalid sting trait."); - // Allocate sting trait + // Allocate and init sting trait trait::sting* sting = new trait::sting(); + sting->present = false; + sting->model = nullptr; // Parse sting present - sting->present = false; - if (auto present_element = sting_element->find("present"); present_element != sting_element->end()) - sting->present = present_element->get(); + if (auto element = sting_element->find("present"); element != sting_element->end()) + sting->present = element->get(); // Load sting model (if present) if (sting->present) @@ -53,10 +54,6 @@ trait::sting* resource_loader::load(resource_manager* resource_man throw std::runtime_error("Sting trait doesn't specify sting model."); sting->model = resource_manager->load(model_element->get()); } - else - { - sting->model = nullptr; - } // Free JSON data delete data; diff --git a/src/game/ant/trait/loader/waist-loader.cpp b/src/game/ant/trait/loader/waist-loader.cpp index 3856709..8f00d58 100644 --- a/src/game/ant/trait/loader/waist-loader.cpp +++ b/src/game/ant/trait/loader/waist-loader.cpp @@ -37,57 +37,58 @@ trait::waist* resource_loader::load(resource_manager* resource_man if (waist_element == data->end()) throw std::runtime_error("Invalid waist trait."); - // Allocate waist trait + // Allocate and init waist trait trait::waist* waist = new trait::waist(); - - // Load waist model - auto model_element = waist_element->find("model"); - if (model_element == waist_element->end()) - throw std::runtime_error("Waist trait doesn't specify waist model."); - waist->model = resource_manager->load(model_element->get()); - - // Parse waist spinescence - waist->spinescence = 0.0f; - if (auto spinescence_element = waist_element->find("spinescence"); spinescence_element != waist_element->end()) - waist->spinescence = spinescence_element->get(); - - // Parse waist petiole length + waist->model = nullptr; + waist->petiole_present = false; waist->petiole_length = 0.0f; - if (auto petiole_length_element = waist_element->find("petiole_length"); petiole_length_element != waist_element->end()) - waist->petiole_length = petiole_length_element->get(); - - // Parse waist petiole width waist->petiole_width = 0.0f; - if (auto petiole_width_element = waist_element->find("petiole_width"); petiole_width_element != waist_element->end()) - waist->petiole_width = petiole_width_element->get(); - - // Parse waist petiole height waist->petiole_height = 0.0f; - if (auto petiole_height_element = waist_element->find("petiole_height"); petiole_height_element != waist_element->end()) - waist->petiole_height = petiole_height_element->get(); - - // Parse waist postpetiole - waist->postpetiole = false; - if (auto postpetiole_element = waist_element->find("postpetiole"); postpetiole_element != waist_element->end()) - waist->postpetiole = postpetiole_element->get(); - + waist->petiole_spinescence = 0.0f; + waist->postpetiole_present = false; waist->postpetiole_length = 0.0f; waist->postpetiole_width = 0.0f; waist->postpetiole_height = 0.0f; - - if (waist->postpetiole) + waist->postpetiole_spinescence = 0.0f; + + // Parse petiole present + if (auto element = waist_element->find("petiole_present"); element != waist_element->end()) + waist->petiole_present = element->get(); + + if (waist->petiole_present) { - // Parse waist postpetiole length - if (auto postpetiole_length_element = waist_element->find("postpetiole_length"); postpetiole_length_element != waist_element->end()) - waist->postpetiole_length = postpetiole_length_element->get(); + // Parse petiole properties + if (auto element = waist_element->find("petiole_length"); element != waist_element->end()) + waist->petiole_length = element->get(); + if (auto element = waist_element->find("petiole_width"); element != waist_element->end()) + waist->petiole_width = element->get(); + if (auto element = waist_element->find("petiole_height"); element != waist_element->end()) + waist->petiole_height = element->get(); + if (auto element = waist_element->find("petiole_spinescence"); element != waist_element->end()) + waist->petiole_spinescence = element->get(); + + // Parse postpetiole present + if (auto element = waist_element->find("postpetiole_present"); element != waist_element->end()) + waist->postpetiole_present = element->get(); + + if (waist->postpetiole_present) + { + // Parse postpetiole properties + if (auto element = waist_element->find("postpetiole_length"); element != waist_element->end()) + waist->postpetiole_length = element->get(); + if (auto element = waist_element->find("postpetiole_width"); element != waist_element->end()) + waist->postpetiole_width = element->get(); + if (auto element = waist_element->find("postpetiole_height"); element != waist_element->end()) + waist->postpetiole_height = element->get(); + if (auto element = waist_element->find("postpetiole_spinescence"); element != waist_element->end()) + waist->postpetiole_spinescence = element->get(); + } - // Parse waist postpetiole width - if (auto postpetiole_width_element = waist_element->find("postpetiole_width"); postpetiole_width_element != waist_element->end()) - waist->postpetiole_width = postpetiole_width_element->get(); - - // Parse waist postpetiole height - if (auto postpetiole_height_element = waist_element->find("postpetiole_height"); postpetiole_height_element != waist_element->end()) - waist->postpetiole_height = postpetiole_height_element->get(); + // Load waist model + auto model_element = waist_element->find("model"); + if (model_element == waist_element->end()) + throw std::runtime_error("Waist trait doesn't specify waist model."); + waist->model = resource_manager->load(model_element->get()); } // Free JSON data diff --git a/src/game/ant/trait/loader/wings-loader.cpp b/src/game/ant/trait/loader/wings-loader.cpp new file mode 100644 index 0000000..1b3f1b0 --- /dev/null +++ b/src/game/ant/trait/loader/wings-loader.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include "resources/resource-loader.hpp" +#include "resources/resource-manager.hpp" +#include "resources/json.hpp" +#include "game/ant/trait/wings.hpp" +#include "render/model.hpp" +#include + +using namespace game::ant; + +template <> +trait::wings* resource_loader::load(resource_manager* resource_manager, PHYSFS_File* file, const std::filesystem::path& path) +{ + // Load JSON data + json* data = resource_loader::load(resource_manager, file, path); + + // Validate trait file + auto wings_element = data->find("wings"); + if (wings_element == data->end()) + throw std::runtime_error("Invalid wings trait."); + + // Allocate and init wings trait + trait::wings* wings = new trait::wings(); + wings->forewings_model = nullptr; + wings->hindwings_model = nullptr; + wings->present = false; + wings->forewing_length = 0.0f; + wings->forewing_width = 0.0f; + wings->forewing_venation = 0.0f; + wings->hindwing_length = 0.0f; + wings->hindwing_width = 0.0f; + wings->hindwing_venation = 0.0f; + + // Parse wings present + if (auto present_element = wings_element->find("present"); present_element != wings_element->end()) + wings->present = present_element->get(); + + if (wings->present) + { + // Load forewings model + auto forewings_model_element = wings_element->find("forewings_model"); + if (forewings_model_element == wings_element->end()) + throw std::runtime_error("Wings trait doesn't specify forewings model."); + wings->forewings_model = resource_manager->load(forewings_model_element->get()); + + // Load hindwings model + auto hindwings_model_element = wings_element->find("hindwings_model"); + if (hindwings_model_element == wings_element->end()) + throw std::runtime_error("Wings trait doesn't specify hindwings model."); + wings->hindwings_model = resource_manager->load(hindwings_model_element->get()); + + // Parse forewing length + if (auto element = wings_element->find("forewing_length"); element != wings_element->end()) + wings->forewing_length = element->get(); + + // Parse forewing width + if (auto element = wings_element->find("forewing_width"); element != wings_element->end()) + wings->forewing_width = element->get(); + + // Parse forewing venation + if (auto element = wings_element->find("forewing_venation"); element != wings_element->end()) + wings->forewing_venation = element->get(); + + // Parse hindwing length + if (auto element = wings_element->find("hindwing_length"); element != wings_element->end()) + wings->hindwing_length = element->get(); + + // Parse hindwing width + if (auto element = wings_element->find("hindwing_width"); element != wings_element->end()) + wings->hindwing_width = element->get(); + + // Parse hindwing venation + if (auto element = wings_element->find("hindwing_venation"); element != wings_element->end()) + wings->hindwing_venation = element->get(); + } + + // Free JSON data + delete data; + + return wings; +} diff --git a/src/game/ant/trait/mandibles.hpp b/src/game/ant/trait/mandibles.hpp index 4b58c8d..2af2600 100644 --- a/src/game/ant/trait/mandibles.hpp +++ b/src/game/ant/trait/mandibles.hpp @@ -27,18 +27,25 @@ namespace ant { namespace trait { /** - * Trait that describes the mandibles of an ant. + * Ant mandibles description. + * + * @see https://www.antwiki.org/wiki/Character_States_for_Extant_Ant_Genera_of_the_Formicidae + * @see https://www.antwiki.org/wiki/Morphological_and_Functional_Diversity_of_Ant_Mandibles + * @see https://www.antwiki.org/wiki/Morphological_Measurements */ struct mandibles { - /// Length of the closed mandibles in full face view (MandL), measured in mesosomal lengths. + /// 3D model of the mandibles. + render::model* model; + + /// Mandible length at closure, in mesosomal lengths. float length; - /// Indicates the mandibles are able to lock open, such as in trap-jaw ants. - bool locking; + /// Number of teeth and denticles on the masticatory (apical) margin of the mandible. + int apical_dental_count; - /// 3D model of the mandibles. - render::model* model; + /// Number of teeth and denticles on the basal margin of the mandible. + int basal_dental_count; }; } // namespace trait diff --git a/src/game/ant/trait/mesosoma.hpp b/src/game/ant/trait/mesosoma.hpp index 5f96394..77efe14 100644 --- a/src/game/ant/trait/mesosoma.hpp +++ b/src/game/ant/trait/mesosoma.hpp @@ -27,21 +27,26 @@ namespace ant { namespace trait { /** - * Trait that describes the mesosoma of an ant. + * Ant mesosoma description. + * + * @see https://www.antwiki.org/wiki/Morphological_Measurements */ struct mesosoma { - /// Mesosoma length (ML), also known as the Weber's length (WL). - float length; + /// 3D model of the mesosoma. + render::model* model; - /// Pronotum width in dorsal view (PrW). - float width; + /// Pronotum width, in mesosomal lengths. + float pronotum_width; - /// Degree of spinescence. - float spinescence; + /// Degree of spinescence on the pronotum. + float pronotum_spinescence; - /// 3D model of the mesosoma. - render::model* model; + /// Degree of spinescence on the mesonotum. + float mesonotum_spinescence; + + /// Degree of spinescence on the propodeum. + float propodeum_spinescence; }; } // namespace trait diff --git a/src/game/ant/nest-site.hpp b/src/game/ant/trait/nest-site.hpp similarity index 93% rename from src/game/ant/nest-site.hpp rename to src/game/ant/trait/nest-site.hpp index 7dd159e..009fbd9 100644 --- a/src/game/ant/nest-site.hpp +++ b/src/game/ant/trait/nest-site.hpp @@ -22,9 +22,10 @@ namespace game { namespace ant { +namespace trait { /** - * Nest site enumerations. + * Colony nest site description. */ enum class nest_site { @@ -32,6 +33,7 @@ enum class nest_site arboreal }; +} // namespace trait } // namespace ant } // namespace game diff --git a/src/game/ant/trait/ocelli.hpp b/src/game/ant/trait/ocelli.hpp index 27e3f3b..1f4d51f 100644 --- a/src/game/ant/trait/ocelli.hpp +++ b/src/game/ant/trait/ocelli.hpp @@ -27,27 +27,27 @@ namespace ant { namespace trait { /** - * Trait that describes the ocelli of an ant. + * Ant ocelli description. */ struct ocelli { + /// 3D model of the lateral ocelli, if present. + render::model* lateral_ocelli_model; + + /// 3D model of the median ocellus, if present. + render::model* median_ocellus_model; + /// Lateral ocelli present. - bool lateral_ocelli; + bool lateral_ocelli_present; /// Median ocellus present. - bool median_ocellus; + bool median_ocellus_present; /// Ocellus width, in mesosomal lengths. float width; /// Ocellus height, in mesosomal lengths. float height; - - /// 3D model of the lateral ocelli. - render::model* lateral_ocelli_model; - - /// 3D model of the median ocellus. - render::model* median_ocellus_model; }; } // namespace trait diff --git a/src/game/ant/trait/pigmentation.hpp b/src/game/ant/trait/pigmentation.hpp index 58603d7..374fe93 100644 --- a/src/game/ant/trait/pigmentation.hpp +++ b/src/game/ant/trait/pigmentation.hpp @@ -27,7 +27,7 @@ namespace ant { namespace trait { /** - * Trait that describes the pigmentation of an ant. + * Ant pigmentation description. */ struct pigmentation { diff --git a/src/game/ant/trait/pilosity.hpp b/src/game/ant/trait/pilosity.hpp index 4139e83..8365b53 100644 --- a/src/game/ant/trait/pilosity.hpp +++ b/src/game/ant/trait/pilosity.hpp @@ -25,7 +25,7 @@ namespace ant { namespace trait { /** - * Trait that describes the pilosity of an ant. + * Ant pilosity description. */ struct pilosity { diff --git a/src/game/ant/trait/sculpturing.hpp b/src/game/ant/trait/sculpturing.hpp index bc2b130..c5b2102 100644 --- a/src/game/ant/trait/sculpturing.hpp +++ b/src/game/ant/trait/sculpturing.hpp @@ -27,7 +27,7 @@ namespace ant { namespace trait { /** - * Trait that describes the surface sculpturing of an ant. + * Ant surface sculpturing description. */ struct sculpturing { diff --git a/src/game/ant/trait/size.hpp b/src/game/ant/trait/size-variation.hpp similarity index 72% rename from src/game/ant/trait/size.hpp rename to src/game/ant/trait/size-variation.hpp index a333c23..21bc2a6 100644 --- a/src/game/ant/trait/size.hpp +++ b/src/game/ant/trait/size-variation.hpp @@ -17,24 +17,30 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_ANT_TRAIT_SIZE_HPP -#define ANTKEEPER_GAME_ANT_TRAIT_SIZE_HPP +#ifndef ANTKEEPER_GAME_ANT_TRAIT_SIZE_VARIATION_HPP +#define ANTKEEPER_GAME_ANT_TRAIT_SIZE_VARIATION_HPP namespace game { namespace ant { namespace trait { /** - * Trait that describes the sizes of an ant caste. + * Caste size variation description. */ -struct size +struct size_variation { - /// Size-frequency distribution, with sizes measured in mesosomal lengths. - std::vector> distribution; + /// Minimum size factor. + float min_size; + + /// Maximum size factor. + float max_size; + + /// Mean size factor. + float mean_size; }; } // namespace trait } // namespace ant } // namespace game -#endif // ANTKEEPER_GAME_ANT_TRAIT_SIZE_HPP +#endif // ANTKEEPER_GAME_ANT_TRAIT_SIZE_VARIATION_HPP diff --git a/src/game/ant/trait/waist.hpp b/src/game/ant/trait/waist.hpp index 39ed15b..3abce31 100644 --- a/src/game/ant/trait/waist.hpp +++ b/src/game/ant/trait/waist.hpp @@ -28,35 +28,43 @@ namespace trait { /** * Trait that describes the waist (petiole plus postpetiole) of an ant. + * + * @see https://www.antwiki.org/wiki/Morphological_Measurements */ struct waist { /// 3D model of the waist. render::model* model; - /// Degree of spinescence. - float spinescence; - - /// Postpetiole presence. - bool postpetiole; + //// Petiole presence. + bool petiole_present; - /// Petiole length in dorsal view (PetL). + /// Petiole length, in mesosomal lengths. float petiole_length; - /// Petiole width in dorsal view (PetW). + /// Petiole width, in mesosomal lengths. float petiole_width; - /// Petiole height in in lateral profile (PetH). + /// Petiole height, in mesosomal lengths. float petiole_height; - /// Postpetiole length in dorsal view (PPL). + /// Degree of petiole spinescence. + float petiole_spinescence; + + /// Postpetiole presence. + bool postpetiole_present; + + /// Postpetiole length, in mesosomal lengths. float postpetiole_length; - /// Postpetiole width in dorsal view (PPW). + /// Postpetiole width, in mesosomal lengths. float postpetiole_width; - /// Postpetiole height in in lateral profile (PPH). + /// Postpetiole height, in mesosomal lengths. float postpetiole_height; + + /// Degree of postpetiole spinescence + float postpetiole_spinescence; }; } // namespace trait diff --git a/src/game/ant/trait/hindwings.hpp b/src/game/ant/trait/wings.hpp similarity index 50% rename from src/game/ant/trait/hindwings.hpp rename to src/game/ant/trait/wings.hpp index 312503b..7879a20 100644 --- a/src/game/ant/trait/hindwings.hpp +++ b/src/game/ant/trait/wings.hpp @@ -17,8 +17,8 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_ANT_TRAIT_HINDWINGS_HPP -#define ANTKEEPER_GAME_ANT_TRAIT_HINDWINGS_HPP +#ifndef ANTKEEPER_GAME_ANT_TRAIT_WINGS_HPP +#define ANTKEEPER_GAME_ANT_TRAIT_WINGS_HPP #include "render/model.hpp" @@ -27,25 +27,40 @@ namespace ant { namespace trait { /** - * Trait that describes the hindwings of an ant. + * Ant wings description. */ -struct hindwings +struct wings { - /// Wing length, measured in mesosomal lengths. - float length; + /// 3D model of the forewings. + render::model* forewings_model; - /// Wing width, measured in mesosomal lengths. - float width; + /// 3D model of the hindwings. + render::model* hindwings_model; - /// Degree of venation. A value of `1.0` indicates a highly-developed venation pattern, while `0.0` indicates a complete absence of visible venation. - float venation; + /// Wings presence. + bool present; - /// 3D model of the hindwings. - render::model* model; + /// Forewing length, in mesosomal lengths. + float forewing_length; + + /// Forewing width, in mesosomal lengths. + float forewing_width; + + /// Degree of forewing venation. A value of `1.0` indicates a highly-developed venation pattern, while `0.0` indicates a complete absence of visible venation. + float forewing_venation; + + /// Forewing length, in mesosomal lengths. + float hindwing_length; + + /// Forewing width, in mesosomal lengths. + float hindwing_width; + + /// Degree of hindwing venation. A value of `1.0` indicates a highly-developed venation pattern, while `0.0` indicates a complete absence of visible venation. + float hindwing_venation; }; } // namespace trait } // namespace ant } // namespace game -#endif // ANTKEEPER_GAME_ANT_TRAIT_HINDWINGS_HPP +#endif // ANTKEEPER_GAME_ANT_TRAIT_WINGS_HPP diff --git a/src/game/load.cpp b/src/game/load.cpp index 15d7eba..052f90a 100644 --- a/src/game/load.cpp +++ b/src/game/load.cpp @@ -50,83 +50,57 @@ void biome(game::context& ctx, const std::filesystem::path& path) /* image img; - img.format(1, 1); - img.resize(1024, 1024); - - float frequency = 10.0f; - std::size_t octaves = 4; - float lacunarity = 2.0f; - float gain = 0.5f; - auto hash = static_cast(*)(const math::vector&)>(math::hash::pcg); - auto noise = static_cast&, decltype(hash))>(math::noise::simplex); - - auto fbm = [&](const float2& x) - { - return math::noise::fbm - ( - x, - octaves, - lacunarity, - gain, - noise, - hash - ); - }; + img.format(1, 4); + img.resize(2048, 2048); auto width = img.get_width(); auto height = img.get_height(); unsigned char* pixels = (unsigned char*)img.data(); + const float frequency = 400.0f; float scale_x = 1.0f / static_cast(width - 1) * frequency; float scale_y = 1.0f / static_cast(height - 1) * frequency; - - std::for_each ( std::execution::par_unseq, - img.begin(), - img.end(), - [pixels, width, height, scale_x, scale_y, &fbm](auto& pixel) + img.begin>(), + img.end>(), + [pixels, width, height, scale_x, scale_y, frequency](auto& pixel) { - std::size_t i = &pixel - pixels; - std::size_t y = i / width; - std::size_t x = i % width; + const std::size_t i = &pixel - (math::vector*)pixels; + const std::size_t y = i / width; + const std::size_t x = i % width; - float2 position = + const float2 position = { static_cast(x) * scale_x, static_cast(y) * scale_y }; - //float n = math::noise::simplex(position, &math::noise::hash::pcg3d_1); - //float n = fbm(position); - // auto [sqr_center_distance, displacement, id, sqr_edge_distance] = math::noise::voronoi::f1_edge(position, 1.0f, &math::noise::hash::pcg3d_3); - // float center_distance = std::sqrt(sqr_center_distance); - // float edge_distance = std::sqrt(sqr_edge_distance); - - auto + const auto [ f1_sqr_distance, f1_displacement, - f1_id, - // f2_sqr_distance, - // f2_displacement, - // f2_id - edge_sqr_distance( - ] = math::noise::voronoi::f1_edge(position); + f1_id + ] = math::noise::voronoi::f1(position, 1.0f, {frequency, frequency}); - float f1_distance = std::sqrt(f1_sqr_distance(); - //float f2_distance = std::sqrt(f2_sqr_distance(); - float edge_distance = std::sqrt(edge_sqr_distance(); + const float f1_distance = std::sqrt(f1_sqr_distance); - pixel = static_cast(std::min(255.0f, f1_distance * 255.0f)); - //pixel = static_cast(id % 255); + const float2 uv = (position + f1_displacement) / frequency; + + pixel = + { + static_cast(std::min(255.0f, f1_distance * 255.0f)), + static_cast(std::min(255.0f, uv[0] * 255.0f)), + static_cast(std::min(255.0f, uv[1] * 255.0f)), + static_cast(f1_id % 256) + }; } ); stbi_flip_vertically_on_write(1); - stbi_write_png((ctx.config_path / "gallery" / "noise.png").string().c_str(), img.get_width(), img.get_height(), img.get_channel_count(), img.data(), img.get_width() * img.get_channel_count()); + stbi_write_tga((ctx.config_path / "gallery" / "voronoi-f1-400-nc8-2k.tga").string().c_str(), img.get_width(), img.get_height(), img.get_channel_count(), img.data()); */ try @@ -195,44 +169,21 @@ void biome(game::context& ctx, const std::filesystem::path& path) ( [](float x, float z) -> float { - /* - float frequency = 0.01f; - std::size_t octaves = 4; - float lacunarity = 3.0f; - float gain = 0.5f; - - float2 position = float2{x, z} * frequency; + const float2 position = float2{x, z}; + + const std::size_t octaves = 3; + const float lacunarity = 1.5f; + const float gain = 0.5f; - float fbm = math::noise::fbm + const float fbm = math::noise::fbm ( - position, + position * 0.005f, octaves, lacunarity, gain ); - auto - [ - f1_sqr_distance, - f1_displacement, - f1_id - ] = math::noise::voronoi::f1(position); - float f1_distance = std::sqrt(f1_sqr_distance(); - - float y = f1_distance * 5.0f + fbm * 0.5f; - */ - - float2 position = float2{x, z} * 0.05f; - - auto - [ - f1_sqr_distance, - f1_displacement, - f1_id - ] = math::noise::voronoi::f1(position); - float f1_distance = std::sqrt(f1_sqr_distance); - float y = f1_distance * 3.0f; - + float y = fbm * 4.0f; return y; } diff --git a/src/game/state/boot.cpp b/src/game/state/boot.cpp index 1834669..aa3203b 100644 --- a/src/game/state/boot.cpp +++ b/src/game/state/boot.cpp @@ -888,7 +888,7 @@ void boot::setup_systems() ctx.blackbody_system->set_illuminant(color::illuminant::deg2::d55); // RGB wavelengths for atmospheric scatteering - ctx.rgb_wavelengths = {640, 575, 440}; + ctx.rgb_wavelengths = {680, 550, 440}; // Setup atmosphere system ctx.atmosphere_system = new game::system::atmosphere(*ctx.entity_registry); diff --git a/src/game/state/gamepad-config-menu.hpp b/src/game/state/gamepad-config-menu.hpp index f7e337f..0c4d632 100644 --- a/src/game/state/gamepad-config-menu.hpp +++ b/src/game/state/gamepad-config-menu.hpp @@ -22,6 +22,7 @@ #include "game/state/base.hpp" #include "input/control.hpp" +#include namespace game { namespace state { diff --git a/src/game/state/nest-selection.cpp b/src/game/state/nest-selection.cpp index 147b9e3..7c4163e 100644 --- a/src/game/state/nest-selection.cpp +++ b/src/game/state/nest-selection.cpp @@ -46,8 +46,6 @@ #include "state-machine.hpp" #include "config.hpp" #include "game/load.hpp" -#include "game/ant/breed.hpp" -#include "game/ant/morphogenesis.hpp" #include "math/interpolation.hpp" #include "physics/light/exposure.hpp" #include "application.hpp" @@ -55,6 +53,9 @@ #include "math/projection.hpp" #include +#include "game/ant/morphogenesis.hpp" +#include "game/ant/species.hpp" + using namespace game::ant; namespace game { @@ -65,6 +66,49 @@ nest_selection::nest_selection(game::context& ctx): { ctx.logger->push_task("Entering nest selection state"); + + ctx.logger->push_task("Loading worker caste"); + + ant::species species; + ant::caste& worker_caste = *species.worker_caste; + worker_caste.type = ant::caste_type::worker; + + worker_caste.antennae = ctx.resource_manager->load("pogonomyrmex-female-antennae.dna"); + worker_caste.eyes = ctx.resource_manager->load("pogonomyrmex-eyes.dna"); + worker_caste.gaster = ctx.resource_manager->load("pogonomyrmex-worker-gaster.dna"); + worker_caste.head = ctx.resource_manager->load("pogonomyrmex-head.dna"); + worker_caste.legs = ctx.resource_manager->load("pogonomyrmex-legs.dna"); + worker_caste.mandibles = ctx.resource_manager->load("pogonomyrmex-mandibles.dna"); + worker_caste.mesosoma = ctx.resource_manager->load("pogonomyrmex-worker-mesosoma.dna"); + worker_caste.ocelli = ctx.resource_manager->load("ocelli-absent.dna"); + worker_caste.pigmentation = ctx.resource_manager->load("rust-pigmentation.dna"); + worker_caste.sculpturing = ctx.resource_manager->load("politus-sculpturing.dna"); + //worker_caste.size_variation = ctx.resource_manager->load(...); + worker_caste.sting = ctx.resource_manager->load("pogonomyrmex-sting.dna"); + worker_caste.waist = ctx.resource_manager->load("pogonomyrmex-waist.dna"); + worker_caste.wings = ctx.resource_manager->load("wings-absent.dna"); + + render::model* worker_model = ant::morphogenesis(worker_caste); + + ctx.logger->pop_task(EXIT_SUCCESS); + + + // Create worker entity(s) + entity::id worker_eid = ctx.entity_registry->create(); + component::transform worker_transform_component; + worker_transform_component.local = math::transform::identity; + worker_transform_component.local.translation = {0, 0, -20}; + worker_transform_component.world = worker_transform_component.local; + worker_transform_component.warp = true; + ctx.entity_registry->emplace(worker_eid, worker_transform_component); + + component::model worker_model_component; + worker_model_component.render_model = worker_model; + worker_model_component.instance_count = 0; + worker_model_component.layers = ~0; + ctx.entity_registry->emplace(worker_eid, worker_model_component); + + // Disable UI color clear ctx.ui_clear_pass->set_cleared_buffers(false, true, false); @@ -132,8 +176,11 @@ nest_selection::nest_selection(game::context& ctx): // Satisfy first person camera rig constraints satisfy_first_person_camera_rig_constraints(); - auto ruler_archetype = ctx.resource_manager->load("ruler-10cm.ent"); - ruler_archetype->create(*ctx.entity_registry); + auto color_checker_archetype = ctx.resource_manager->load("color-checker.ent"); + color_checker_archetype->create(*ctx.entity_registry); + + // auto ruler_archetype = ctx.resource_manager->load("ruler-10cm.ent"); + // ruler_archetype->create(*ctx.entity_registry); // Queue control setup ctx.function_queue.push(std::bind(&nest_selection::enable_controls, this)); @@ -653,7 +700,7 @@ void nest_selection::enable_controls() [&ctx = this->ctx](float) { //ctx.astronomy_system->set_exposure_offset(ctx.astronomy_system->get_exposure_offset() - 1.0f); - ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() + 3.0f * static_cast(ctx.loop.get_update_period())); + ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() + 0.5f * static_cast(ctx.loop.get_update_period())); ctx.logger->log("EV100: " + std::to_string(ctx.surface_camera->get_exposure())); } ); @@ -663,80 +710,10 @@ void nest_selection::enable_controls() [&ctx = this->ctx](float) { //ctx.astronomy_system->set_exposure_offset(ctx.astronomy_system->get_exposure_offset() + 1.0f); - ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() - 3.0f * static_cast(ctx.loop.get_update_period())); + ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() - 0.5f * static_cast(ctx.loop.get_update_period())); ctx.logger->log("EV100: " + std::to_string(ctx.surface_camera->get_exposure())); } ); - - const float wavelength_speed = 20.0; - ctx.controls["dec_red"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.x() -= wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - ctx.controls["inc_red"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.x() += wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - - ctx.controls["dec_green"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.y() -= wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - ctx.controls["inc_green"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.y() += wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - - ctx.controls["dec_blue"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.z() -= wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - ctx.controls["inc_blue"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.z() += wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); } void nest_selection::disable_controls() @@ -772,12 +749,6 @@ void nest_selection::disable_controls() ctx.controls["pause"]->set_activated_callback(nullptr); ctx.controls["increase_exposure"]->set_active_callback(nullptr); ctx.controls["decrease_exposure"]->set_active_callback(nullptr); - ctx.controls["dec_red"]->set_active_callback(nullptr); - ctx.controls["inc_red"]->set_active_callback(nullptr); - ctx.controls["dec_green"]->set_active_callback(nullptr); - ctx.controls["inc_green"]->set_active_callback(nullptr); - ctx.controls["dec_blue"]->set_active_callback(nullptr); - ctx.controls["inc_blue"]->set_active_callback(nullptr); } } // namespace state diff --git a/src/game/state/nuptial-flight.cpp b/src/game/state/nuptial-flight.cpp index c6d73dd..234e94e 100644 --- a/src/game/state/nuptial-flight.cpp +++ b/src/game/state/nuptial-flight.cpp @@ -49,8 +49,6 @@ #include "state-machine.hpp" #include "config.hpp" #include "game/load.hpp" -#include "game/ant/breed.hpp" -#include "game/ant/morphogenesis.hpp" #include "math/interpolation.hpp" #include "physics/light/exposure.hpp" #include "color/color.hpp" @@ -61,8 +59,6 @@ #include "geom/primitive/hyperplane.hpp" #include -using namespace game::ant; - namespace game { namespace state { @@ -775,76 +771,6 @@ void nuptial_flight::enable_controls() ctx.logger->log("EV100: " + std::to_string(ctx.surface_camera->get_exposure())); } ); - - const float wavelength_speed = 20.0; - ctx.controls["dec_red"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.x() -= wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - ctx.controls["inc_red"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.x() += wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - - ctx.controls["dec_green"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.y() -= wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - ctx.controls["inc_green"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.y() += wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - - ctx.controls["dec_blue"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.z() -= wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); - ctx.controls["inc_blue"]->set_active_callback - ( - [&ctx = this->ctx, wavelength_speed](float) - { - ctx.rgb_wavelengths.z() += wavelength_speed * ctx.loop.get_update_period(); - ctx.atmosphere_system->set_rgb_wavelengths(ctx.rgb_wavelengths * 1e-9); - std::stringstream stream; - stream << ctx.rgb_wavelengths; - ctx.logger->log("wavelengths: " + stream.str()); - } - ); } void nuptial_flight::disable_controls() @@ -880,12 +806,6 @@ void nuptial_flight::disable_controls() ctx.controls["pause"]->set_activated_callback(nullptr); ctx.controls["increase_exposure"]->set_active_callback(nullptr); ctx.controls["decrease_exposure"]->set_active_callback(nullptr); - ctx.controls["dec_red"]->set_active_callback(nullptr); - ctx.controls["inc_red"]->set_active_callback(nullptr); - ctx.controls["dec_green"]->set_active_callback(nullptr); - ctx.controls["inc_green"]->set_active_callback(nullptr); - ctx.controls["dec_blue"]->set_active_callback(nullptr); - ctx.controls["inc_blue"]->set_active_callback(nullptr); } void nuptial_flight::select_entity(entity::id entity_id) diff --git a/src/game/state/splash.cpp b/src/game/state/splash.cpp index 6729405..ba1bc8f 100644 --- a/src/game/state/splash.cpp +++ b/src/game/state/splash.cpp @@ -30,7 +30,6 @@ #include "resources/resource-manager.hpp" #include "render/material-flags.hpp" #include "math/linear-algebra.hpp" -#include namespace game { namespace state { diff --git a/src/game/system/terrain.cpp b/src/game/system/terrain.cpp index 46003d3..82d5934 100644 --- a/src/game/system/terrain.cpp +++ b/src/game/system/terrain.cpp @@ -55,7 +55,10 @@ terrain::terrain(entity::registry& registry): // Init quadtee node sizes at each depth for (std::size_t i = 0; i <= quadtree_type::max_depth; ++i) + { quadtree_node_size[i] = 0.0f; + quadtree_node_resolution[i] = static_cast(std::exp2(i)); + } registry.on_construct().connect<&terrain::on_terrain_construct>(this); registry.on_update().connect<&terrain::on_terrain_update>(this); @@ -87,11 +90,16 @@ void terrain::update(double t, double dt) // Determine camera node location const auto [x, y, z] = cam.get_translation(); - quadtree_node_type node_x = static_cast((x / patch_side_length) + quadtree.resolution / 4); - quadtree_node_type node_y = static_cast((z / patch_side_length) + quadtree.resolution / 4); + quadtree_node_type node_depth = quadtree.max_depth; + const float node_size = quadtree_node_size[node_depth]; + quadtree_node_type node_resolution = quadtree_node_resolution[node_depth]; + + quadtree_node_type node_x = static_cast(x / node_size + node_resolution / 2); + quadtree_node_type node_y = static_cast(z / node_size + node_resolution / 2); quadtree_node_type node_location = geom::morton::encode(node_x, node_y); - quadtree.insert(quadtree.node(quadtree.max_depth, node_location)); + //quadtree.insert(quadtree.node(node_depth, node_location)); + node_stack.push(quadtree.node(node_depth, node_location)); balance_quadtree(); for (const quadtree_node_type& node: quadtree) @@ -111,21 +119,12 @@ void terrain::update(double t, double dt) - //std::cout << "qsize: " << quadtree.size() << std::endl; - std::size_t qvis = 0; - - /// Toggle visibility of terrain scene objects for (auto it = patches.begin(); it != patches.end(); ++it) { bool active = (quadtree.contains(it->first) && quadtree.is_leaf(it->first)); it->second->model_instance->set_active(active); - - if (active) - ++qvis; } - - //std::cout << "qvis: " << qvis << std::endl; } void terrain::set_patch_side_length(float length) @@ -136,7 +135,6 @@ void terrain::set_patch_side_length(float length) for (std::size_t i = 0; i <= quadtree_type::max_depth; ++i) { quadtree_node_size[i] = std::exp2(quadtree_type::max_depth - i) * patch_side_length; - //std::cout << quadtree_node_size[i] << std::endl; } } @@ -245,105 +243,48 @@ void terrain::rebuild_patch_base_mesh() } } -void terrain::visit_quadtree(const geom::bounding_volume& volume, quadtree_node_type node) -{ - const float root_offset = quadtree_node_size[0] * -0.5f; - - // Extract node depth - quadtree_type::node_type node_depth = quadtree_type::depth(node); - - const float node_size = get_patch_size(node); - const float3 node_center = get_patch_center(node); - - // Build node bounds AABB - geom::aabb node_bounds; - node_bounds.min_point = - { - node_center.x() - node_size * 0.5f, - -std::numeric_limits::infinity(), - node_center.z() - node_size * 0.5f - }; - node_bounds.max_point = - { - node_bounds.min_point.x() + node_size, - std::numeric_limits::infinity(), - node_bounds.min_point.z() + node_size - }; - - // If volume intersects node - if (volume.intersects(node_bounds)) - { - // Subdivide leaf nodes - if (quadtree.is_leaf(node)) - { - quadtree.insert(quadtree_type::child(node, 0)); - - for (quadtree_node_type i = 0; i < quadtree_type::children_per_node; ++i) - { - quadtree_node_type child = quadtree_type::child(node, i); - - if (patches.find(child) == patches.end()) - { - patch* child_patch = generate_patch(child); - patches[child] = child_patch; - scene_collection->add_object(child_patch->model_instance); - } - } - } - - // Visit children - if (node_depth < quadtree_type::max_depth - 1) - { - for (quadtree_node_type i = 0; i < quadtree_type::children_per_node; ++i) - visit_quadtree(volume, quadtree_type::child(node, i)); - } - } -} - void terrain::balance_quadtree() { - std::unordered_set nodes; - - for (const auto& node: quadtree) + while (!node_stack.empty()) { - auto [depth, location] = quadtree.split(node); + quadtree_node_type node = node_stack.top(); + node_stack.pop(); - // Skip root node - if (depth < 2) + if (quadtree.contains(node)) continue; - quadtree_node_type x, y; - geom::morton::decode(location, x, y); - + quadtree.insert(node); - // TODO!!!! + const auto depth = quadtree.depth(node); + if (depth < 2) + continue; - // DONT USE quadtree.resolution, use a depth-specific resolution + const quadtree_node_type parent = quadtree.parent(node); + const quadtree_node_type parent_depth = depth - 1; + const quadtree_node_type parent_resolution = quadtree_node_resolution[parent_depth]; - if (!quadtree.is_leaf(node)) + for (quadtree_node_type i = 0; i < quadtree.children_per_node; ++i) { - if (x < (quadtree.resolution / 4) - 1) + const auto location = quadtree.location(quadtree.sibling(parent, i)); + quadtree_node_type x, y; + geom::morton::decode(location, x, y); + + if (x < parent_resolution - 1) { - if (y < (quadtree.resolution / 4) - 1) - nodes.insert(quadtree.node(depth, geom::morton::encode(x + 1, y + 1))); + if (y < parent_resolution - 1) + node_stack.push(quadtree.node(parent_depth, geom::morton::encode(x + 1, y + 1))); if (y > 0) - nodes.insert(quadtree.node(depth, geom::morton::encode(x + 1, y - 1))); + node_stack.push(quadtree.node(parent_depth, geom::morton::encode(x + 1, y - 1))); } if (x > 0) { - if (y < (quadtree.resolution / 4) - 1) - nodes.insert(quadtree.node(depth, geom::morton::encode(x - 1, y + 1))); + if (y < parent_resolution - 1) + node_stack.push(quadtree.node(parent_depth, geom::morton::encode(x - 1, y + 1))); if (y > 0) - nodes.insert(quadtree.node(depth, geom::morton::encode(x - 1, y - 1))); + node_stack.push(quadtree.node(parent_depth, geom::morton::encode(x - 1, y - 1))); } } - - } - - for (const auto& node: nodes) - { - quadtree.insert(node); } } @@ -392,7 +333,6 @@ geom::mesh* terrain::generate_patch_mesh(quadtree_node_type node) const // Calculate size of a patch cell const float cell_size = patch_size / static_cast(patch_subdivisions + 1); - const float half_cell_size = cell_size * 0.5f; // Init patch bounds geom::aabb patch_bounds; @@ -696,8 +636,6 @@ geom::mesh* terrain::generate_patch_mesh(quadtree_node_type node) const // Set patch model bounds patch_model->set_bounds(patch_bounds); - //std::cout << "depth: " << quadtree_type::depth(node) << "; size: " << (patch_bounds.max_point + patch_bounds.min_point) * 0.5f << std::endl; - return patch_model; } diff --git a/src/game/system/terrain.hpp b/src/game/system/terrain.hpp index 3714565..01314fc 100644 --- a/src/game/system/terrain.hpp +++ b/src/game/system/terrain.hpp @@ -33,6 +33,7 @@ #include "scene/collection.hpp" #include "geom/view-frustum.hpp" #include +#include namespace game { namespace system { @@ -103,10 +104,6 @@ private: void rebuild_patch_base_mesh(); - - - void visit_quadtree(const geom::bounding_volume& volume, quadtree_node_type node); - /** * Generates a mesh for a terrain patch given the patch's quadtree node */ @@ -149,9 +146,12 @@ private: /// Quadtree describing level of detail quadtree_type quadtree; float quadtree_node_size[quadtree_type::max_depth + 1]; + quadtree_node_type quadtree_node_resolution[quadtree_type::max_depth + 1]; /// Map linking quadtree nodes to terrain patches std::unordered_map patches; + + std::stack node_stack; }; } // namespace system diff --git a/src/geom/hyperoctree.hpp b/src/geom/hyperoctree.hpp index eee2262..ff02f8f 100644 --- a/src/geom/hyperoctree.hpp +++ b/src/geom/hyperoctree.hpp @@ -172,10 +172,10 @@ public: static constexpr node_type siblings_per_node = children_per_node - 1; /// Resolution in each dimension. - static constexpr node_type resolution = math::compile::exp2(max_depth + 1); + static constexpr node_type resolution = math::compile::exp2(max_depth); /// Number of nodes in a full hyperoctree. - static constexpr std::size_t max_node_count = (math::compile::pow(resolution, N) - 1) / siblings_per_node; + static constexpr std::size_t max_node_count = (math::compile::pow(resolution * 2, N) - 1) / siblings_per_node; /// Node identifier of the persistent root node. static constexpr node_type root = 0; @@ -204,7 +204,7 @@ public: * * @return Depth of the node. */ - static constexpr inline node_type depth(node_type node) noexcept + static inline constexpr node_type depth(node_type node) noexcept { constexpr node_type mask = math::compile::exp2(depth_bits) - 1; return node & mask; @@ -217,7 +217,7 @@ public: * * @return Morton location code of the node. */ - static constexpr inline node_type location(node_type node) noexcept + static inline constexpr node_type location(node_type node) noexcept { return node >> ((node_bits - 1) - depth(node) * N); } @@ -246,7 +246,7 @@ public: * * @warning If @p depth exceeds `max_depth`, the returned node identifier is not valid. */ - static constexpr inline node_type node(node_type depth, node_type location) noexcept + static inline constexpr node_type node(node_type depth, node_type location) noexcept { return (location << ((node_bits - 1) - depth * N)) | depth; } @@ -261,7 +261,7 @@ public: * * @warning If @p depth exceeds the depth of @p node, the returned node identifier is not valid. */ - static constexpr inline node_type ancestor(node_type node, node_type depth) noexcept + static inline constexpr node_type ancestor(node_type node, node_type depth) noexcept { const node_type mask = (~node_type(0)) << ((node_bits - 1) - depth * N); return (node & mask) | depth; @@ -274,7 +274,7 @@ public: * * @return Identifier of the parent node. */ - static constexpr inline node_type parent(node_type node) noexcept + static inline constexpr node_type parent(node_type node) noexcept { return ancestor(node, depth(node) - 1); } @@ -303,7 +303,7 @@ public: * * @return Identifier of the nth child node. */ - static constexpr inline node_type child(node_type node, T n) noexcept + static inline constexpr node_type child(node_type node, T n) noexcept { return sibling(node + 1, n); } @@ -470,7 +470,7 @@ public: } /// Returns the total number of nodes the hyperoctree is capable of containing. - consteval std::size_t max_size() const noexcept + constexpr std::size_t max_size() const noexcept { return max_node_count; } diff --git a/src/geom/mesh.cpp b/src/geom/mesh.cpp index a4ac37e..22403ea 100644 --- a/src/geom/mesh.cpp +++ b/src/geom/mesh.cpp @@ -120,19 +120,19 @@ mesh& mesh::operator=(const mesh& other) return *this; } -void mesh::clear() +void mesh::clear() noexcept { // Deallocate vertices for (mesh::vertex* vertex: vertices) delete vertex; - + // Deallocate edges for (mesh::edge* edge: edges) { delete edge->symmetric; delete edge; } - + // Deallocate faces for (mesh::face* face: faces) delete face; @@ -144,12 +144,15 @@ void mesh::clear() mesh::vertex* mesh::add_vertex(const float3& position) { - mesh::vertex* vertex = new mesh::vertex(); - vertex->edge = nullptr; - vertex->position = position; - vertex->index = vertices.size(); + mesh::vertex* vertex = new mesh::vertex + { + vertices.size(), + nullptr, + position + }; + vertices.push_back(vertex); - + return vertex; } @@ -158,19 +161,19 @@ mesh::edge* mesh::add_edge(mesh::vertex* a, mesh::vertex* b) mesh::edge* ab = new mesh::edge(); mesh::edge* ba = new mesh::edge(); + ab->index = edges.size(); ab->vertex = a; ab->face = nullptr; ab->previous = ba; ab->next = ba; ab->symmetric = ba; - ab->index = edges.size(); + ba->index = edges.size(); ba->vertex = b; ba->face = nullptr; ba->previous = ab; ba->next = ab; ba->symmetric = ab; - ba->index = edges.size(); if (!a->edge) { @@ -240,21 +243,21 @@ mesh::face* mesh::add_face(const loop& loop) throw std::runtime_error("Non-manifold mesh 2"); } } - + // Create face mesh::face* face = new mesh::face(); face->edge = loop[0]; face->index = faces.size(); - + // Add face faces.push_back(face); - + // Connect edges to the face for (mesh::edge* edge: loop) { edge->face = face; } - + return face; } diff --git a/src/geom/mesh.hpp b/src/geom/mesh.hpp index 4953759..2eb578b 100644 --- a/src/geom/mesh.hpp +++ b/src/geom/mesh.hpp @@ -37,45 +37,112 @@ public: struct edge; struct face; - /// List of edges which form a face. + /** + * Half-edge mesh vertex, containing its index, a pointer to its parent edge, and its position vector. + */ + struct vertex + { + /// Index of this vertex. + std::size_t index; + + /// Pointer to the edge to which this vertex belongs. + mesh::edge* edge; + + /// Vertex position. + float3 position; + }; + + /** + * Half-edge mesh edge, containing its index and pointers to its starting vertex, parent face, and related edges. + */ + struct edge + { + /// Index of this edge. + std::size_t index; + + /// Pointer to the vertex at which the edge starts. + mesh::vertex* vertex; + + /// Pointer to the face on the left of this edge. + mesh::face* face; + + /// Pointer to the previous edge in the parent face. + mesh::edge* previous; + + /// Pointer to the next edge in the parent face. + mesh::edge* next; + + /// Pointer to the symmetric edge. + mesh::edge* symmetric; + }; + + /** + * Half-edge mesh face, containing its index and a pointer to its first edge. + */ + struct face + { + /// Index of this face. + std::size_t index; + + /// Pointer to the first edge in this face. + mesh::edge* edge; + }; + + /** + * List of edges which form a face. + */ typedef std::vector loop; /** * Constructs a mesh. */ - mesh() = default; + constexpr mesh() noexcept = default; - /// Copy-constructs a mesh. + /** + * Copy-constructs a mesh. + */ mesh(const mesh& other); /** - * Destroys a mesh. + * Destructs a mesh. */ - ~mesh(); + ~mesh() noexcept; - /// Copies another mesh into this mesh. + /** + * Copies another mesh into this mesh. + * + * @param other Mesh to copy. + * + * @return Reference to this mesh. + */ mesh& operator=(const mesh& other); - /// Removes all vertices, edges, and faces from the mesh. - void clear(); - /** - * Adds a vertex to the mesh. This vertex initially has a null edge. + * Removes all vertices, edges, and faces from the mesh. + */ + void clear() noexcept; + + /** + * Adds a vertex to the mesh. * * @param position Position of the vertex. + * * @return Pointer to the added vertex. + * + * @warning The added vertex will initially have a null edge. */ mesh::vertex* add_vertex(const float3& position); - + /** - * Adds an edge to the mesh. + * Adds two half edges to the mesh. + * + * @param a Vertex from which the edge originates. + * @param b Vertex at which the edge ends. * - * @param a The vertex from which the edge originates. - * @param b The vertex at which the edge ends. - * @return Pointer to the added edge. + * @return Pointer to the half edge `ab`. The symmetric half edge `ba` can be accessed through `ab->symmetric`. */ mesh::edge* add_edge(mesh::vertex* a, mesh::vertex* b); - + /** * Adds a face to the mesh. * @@ -88,21 +155,21 @@ public: * @exception std::runtime_error Non-manifold mesh 2. */ mesh::face* add_face(const loop& loop); - + /** * Removes a face from the mesh. * * @param face Face to be removed. This face will be deallocated after removal. */ void remove_face(mesh::face* face); - + /** * Removes an edge and all dependent faces from the mesh. * * @param edge Edge to be removed. This edge will be deallocated after removal. */ void remove_edge(mesh::edge* edge); - + /** * Removes a vertex, all dependent edges, and all dependent faces from the mesh. * @@ -110,66 +177,15 @@ public: */ void remove_vertex(mesh::vertex* vertex); - /// Returns the mesh vertices + /// Returns the mesh vertices. const std::vector& get_vertices() const; - /// Returns the mesh edges + /// Returns the mesh edges. const std::vector& get_edges() const; - /// Returns the mesh faces + /// Returns the mesh faces. const std::vector& get_faces() const; - - /** - * Half-edge vertex which contains its index, a pointer to its parent edge, and its position vector. - */ - struct vertex - { - /// Index of this vertex. - std::size_t index; - - /// Pointer to the edge to which this vertex belongs. - mesh::edge* edge; - - /// Vertex position. - float3 position; - }; - - /** - * Half-edge edge which contains its index and pointers to its starting vertex, parent face, and related edges. - */ - struct edge - { - /// Index of this edge. - std::size_t index; - - /// Pointer to the vertex at which the edge starts. - mesh::vertex* vertex; - - /// Pointer to the face on the left of this edge. - mesh::face* face; - - /// Pointer to the previous edge in the parent face. - mesh::edge* previous; - - /// Pointer to the next edge in the parent face. - mesh::edge* next; - - /// Pointer to the symmetric edge. - mesh::edge* symmetric; - }; - /** - * Half-edge face which contains its index and a pointer to its first edge. - */ - struct face - { - /// Index of this face. - std::size_t index; - - /// Pointer to the first edge in this face. - mesh::edge* edge; - }; - private: mesh::edge* find_free_incident(mesh::vertex* vertex) const; mesh::edge* find_free_incident(mesh::edge* start_edge, mesh::edge* end_edge) const; diff --git a/src/geom/primitive/intersection.hpp b/src/geom/primitive/intersection.hpp index a34dc5c..5d18dc8 100644 --- a/src/geom/primitive/intersection.hpp +++ b/src/geom/primitive/intersection.hpp @@ -54,7 +54,7 @@ constexpr std::optional intersection(const ray& ray, const hyperplane -constexpr inline std::optional intersection(const hyperplane& hyperplane, const ray& ray) noexcept +inline constexpr std::optional intersection(const hyperplane& hyperplane, const ray& ray) noexcept { return intersection(ray, hyperplane); } @@ -98,7 +98,7 @@ constexpr std::optional> intersection(const ray& ray, con } template -constexpr inline std::optional> intersection(const hyperrectangle& hyperrectangle, const ray& ray) noexcept +inline constexpr std::optional> intersection(const hyperrectangle& hyperrectangle, const ray& ray) noexcept { return intersection(ray, hyperrectangle); } @@ -145,7 +145,7 @@ std::optional> intersection(const ray& ray, const hypersp * @return `true` if an intersection occurred, `false` otherwise. */ template -constexpr inline bool intersection(const hyperrectangle& a, const hyperrectangle& b) noexcept +inline constexpr bool intersection(const hyperrectangle& a, const hyperrectangle& b) noexcept { return a.intersects(b); } @@ -181,7 +181,7 @@ constexpr bool intersection(const hyperrectangle& hyperrectangle, const hy } template -constexpr inline bool intersection(const hypersphere& hypersphere, const hyperrectangle& hyperrectangle) noexcept +inline constexpr bool intersection(const hypersphere& hypersphere, const hyperrectangle& hyperrectangle) noexcept { return intersection(hyperrectangle, hypersphere); } @@ -196,7 +196,7 @@ constexpr inline bool intersection(const hypersphere& hypersphere, const h * @return `true` if an intersection occurred, `false` otherwise. */ template -constexpr inline bool intersection(const hypersphere& a, const hypersphere& b) noexcept +inline constexpr bool intersection(const hypersphere& a, const hypersphere& b) noexcept { return a.intersects(b); } diff --git a/src/math/matrix.hpp b/src/math/matrix.hpp index 8cbcf76..67e2e04 100644 --- a/src/math/matrix.hpp +++ b/src/math/matrix.hpp @@ -42,16 +42,16 @@ namespace math { template struct matrix { - /// Matrix element data type. + /// Element type. typedef T element_type; - /// Number of matrix columns. + /// Number of columns. static constexpr std::size_t column_count = N; - /// Number of matrix rows. + /// Number of rows. static constexpr std::size_t row_count = M; - /// Number of matrix elements. + /// Number of elements. static constexpr std::size_t element_count = column_count * row_count; /// Matrix column vector data type. @@ -68,7 +68,7 @@ struct matrix /// @private template - constexpr inline matrix type_cast(std::index_sequence) const noexcept + inline constexpr matrix type_cast(std::index_sequence) const noexcept { return {vector(columns[I])...}; } @@ -81,14 +81,14 @@ struct matrix * @return Matrix containing the type-casted elements. */ template - constexpr inline explicit operator matrix() const noexcept + inline constexpr explicit operator matrix() const noexcept { return type_cast(std::make_index_sequence{}); } /// @private template - constexpr inline matrix size_cast(std::index_sequence) const noexcept + inline constexpr matrix size_cast(std::index_sequence) const noexcept { if constexpr (O == M) return {((I < N) ? columns[I] : matrix::identity()[I]) ...}; @@ -105,7 +105,7 @@ struct matrix * @return *p* by *o* matrix. */ template - constexpr inline explicit operator matrix() const noexcept + inline constexpr explicit operator matrix() const noexcept { return size_cast(std::make_index_sequence

{}); } @@ -123,19 +123,19 @@ struct matrix * @return Reference to the column vector at index @p i. */ /// @{ - constexpr inline column_vector_type& operator[](std::size_t i) noexcept + inline constexpr column_vector_type& operator[](std::size_t i) noexcept { return columns[i]; } - constexpr inline const column_vector_type& operator[](std::size_t i) const noexcept + inline constexpr const column_vector_type& operator[](std::size_t i) const noexcept { return columns[i]; } - constexpr inline column_vector_type& column(std::size_t i) noexcept + inline constexpr column_vector_type& column(std::size_t i) noexcept { return columns[i]; } - constexpr inline const column_vector_type& column(std::size_t i) const noexcept + inline constexpr const column_vector_type& column(std::size_t i) const noexcept { return columns[i]; } @@ -145,11 +145,11 @@ struct matrix * Returns a reference to the first column vector. */ /// @{ - constexpr inline column_vector_type& front() noexcept + inline constexpr column_vector_type& front() noexcept { return columns[0]; } - constexpr inline const column_vector_type& front() const noexcept + inline constexpr const column_vector_type& front() const noexcept { return columns[0]; } @@ -159,11 +159,11 @@ struct matrix * Returns a reference to the last column vector. */ /// @{ - constexpr inline column_vector_type& back() noexcept + inline constexpr column_vector_type& back() noexcept { return columns[column_count - 1]; } - constexpr inline const column_vector_type& back() const noexcept + inline constexpr const column_vector_type& back() const noexcept { return columns[column_count - 1]; } @@ -182,11 +182,11 @@ struct matrix * @return Reference to the element at column-major index @p i. */ /// @{ - constexpr inline T& element(std::size_t i) noexcept + inline constexpr T& element(std::size_t i) noexcept { return columns[i / row_count][i % row_count]; } - constexpr inline const T& element(std::size_t i) const noexcept + inline constexpr const T& element(std::size_t i) const noexcept { return columns[i / row_count][i % row_count]; } @@ -198,11 +198,11 @@ struct matrix * @warning If matrix::element_type is not a POD type, elements may not be stored contiguously. */ /// @{ - constexpr inline element_type* data() noexcept + inline constexpr element_type* data() noexcept { return &columns[0][0]; }; - constexpr inline const element_type* data() const noexcept + inline constexpr const element_type* data() const noexcept { return &columns[0][0]; }; @@ -217,15 +217,15 @@ struct matrix * Returns an iterator to the first column vector. */ /// @{ - constexpr inline column_vector_type* begin() noexcept + inline constexpr column_vector_type* begin() noexcept { return columns; } - constexpr inline const column_vector_type* begin() const noexcept + inline constexpr const column_vector_type* begin() const noexcept { return columns; } - constexpr inline const column_vector_type* cbegin() const noexcept + inline constexpr const column_vector_type* cbegin() const noexcept { return columns; } @@ -235,15 +235,15 @@ struct matrix * Returns an iterator to the column vector following the last column vector. */ /// @{ - constexpr inline column_vector_type* end() noexcept + inline constexpr column_vector_type* end() noexcept { return columns + column_count; } - constexpr inline const column_vector_type* end() const noexcept + inline constexpr const column_vector_type* end() const noexcept { return columns + column_count; } - constexpr inline const column_vector_type* cend() const noexcept + inline constexpr const column_vector_type* cend() const noexcept { return columns + column_count; } @@ -253,15 +253,15 @@ struct matrix * Returns a reverse iterator to the first column vector of the reversed matrix. */ /// @{ - constexpr inline std::reverse_iterator rbegin() noexcept + inline constexpr std::reverse_iterator rbegin() noexcept { return std::reverse_iterator(columns + column_count); } - constexpr inline std::reverse_iterator rbegin() const noexcept + inline constexpr std::reverse_iterator rbegin() const noexcept { return std::reverse_iterator(columns + column_count); } - constexpr inline std::reverse_iterator crbegin() const noexcept + inline constexpr std::reverse_iterator crbegin() const noexcept { return std::reverse_iterator(columns + column_count); } @@ -271,15 +271,15 @@ struct matrix * Returns a reverse iterator to the column vector following the last column vector of the reversed matrix. */ /// @{ - constexpr inline std::reverse_iterator rend() noexcept + inline constexpr std::reverse_iterator rend() noexcept { return std::reverse_iterator(columns); } - constexpr inline std::reverse_iterator rend() const noexcept + inline constexpr std::reverse_iterator rend() const noexcept { return std::reverse_iterator(columns); } - constexpr inline std::reverse_iterator crend() const noexcept + inline constexpr std::reverse_iterator crend() const noexcept { return std::reverse_iterator(columns); } @@ -293,7 +293,7 @@ struct matrix /** * Returns the number of elements in the matrix. */ - constexpr inline std::size_t size() const noexcept + inline constexpr std::size_t size() const noexcept { return element_count; }; @@ -313,7 +313,7 @@ struct matrix /// @private template - static constexpr inline matrix one(std::index_sequence) noexcept + static inline constexpr matrix one(std::index_sequence) noexcept { //return {column_vector_type::one() ...}; @@ -331,14 +331,14 @@ struct matrix /// @private template - static constexpr inline column_vector_type identity_column(std::size_t i, std::index_sequence) noexcept + static inline constexpr column_vector_type identity_column(std::size_t i, std::index_sequence) noexcept { return {(I == i ? T{1} : T{0}) ...}; } /// @private template - static constexpr inline matrix identity(std::index_sequence) noexcept + static inline constexpr matrix identity(std::index_sequence) noexcept { return {identity_column(I, std::make_index_sequence{}) ...}; } @@ -670,7 +670,7 @@ constexpr matrix transpose(const matrix& m) noexcept; /// @private template -constexpr inline matrix add(const matrix& a, const matrix& b, std::index_sequence) noexcept +inline constexpr matrix add(const matrix& a, const matrix& b, std::index_sequence) noexcept { return {(a[I] + b[I]) ...}; } @@ -683,7 +683,7 @@ constexpr matrix add(const matrix& a, const matrix& b /// @private template -constexpr inline matrix add(const matrix& a, T b, std::index_sequence) noexcept +inline constexpr matrix add(const matrix& a, T b, std::index_sequence) noexcept { return {(a[I] + b) ...}; } @@ -694,6 +694,7 @@ constexpr matrix add(const matrix& a, T b) noexcept return add(a, b, std::make_index_sequence{}); } +/// @private template constexpr T determinant(const matrix& m) noexcept { @@ -702,6 +703,7 @@ constexpr T determinant(const matrix& m) noexcept m[0][1] * m[1][0]; } +/// @private template constexpr T determinant(const matrix& m) noexcept { @@ -714,6 +716,7 @@ constexpr T determinant(const matrix& m) noexcept m[0][2] * m[1][1] * m[2][0]; } +/// @private template constexpr T determinant(const matrix& m) noexcept { @@ -734,7 +737,7 @@ constexpr T determinant(const matrix& m) noexcept /// @private template -constexpr inline matrix componentwise_mul(const matrix& a, const matrix& b, std::index_sequence) noexcept +inline constexpr matrix componentwise_mul(const matrix& a, const matrix& b, std::index_sequence) noexcept { return {(a[I] * b[I]) ...}; } @@ -747,7 +750,7 @@ constexpr matrix componentwise_mul(const matrix& a, const matr /// @private template -constexpr inline matrix div(const matrix& a, const matrix& b, std::index_sequence) noexcept +inline constexpr matrix div(const matrix& a, const matrix& b, std::index_sequence) noexcept { return {(a[I] / b[I]) ...}; } @@ -760,7 +763,7 @@ constexpr matrix div(const matrix& a, const matrix& b /// @private template -constexpr inline matrix div(const matrix& a, T b, std::index_sequence) noexcept +inline constexpr matrix div(const matrix& a, T b, std::index_sequence) noexcept { return {(a[I] / b) ...}; } @@ -773,7 +776,7 @@ constexpr matrix div(const matrix& a, T b) noexcept /// @private template -constexpr inline matrix div(T a, const matrix& b, std::index_sequence) noexcept +inline constexpr matrix div(T a, const matrix& b, std::index_sequence) noexcept { return {(a / b[I]) ...}; } @@ -785,33 +788,34 @@ constexpr matrix div(T a, const matrix& b) noexcept } template -constexpr inline typename matrix::column_vector_type& get(math::matrix& m) noexcept +inline constexpr typename matrix::column_vector_type& get(math::matrix& m) noexcept { static_assert(I < N); return m.columns[I]; } template -constexpr inline typename matrix::column_vector_type&& get(math::matrix&& m) noexcept +inline constexpr typename matrix::column_vector_type&& get(math::matrix&& m) noexcept { static_assert(I < N); return std::move(m.columns[I]); } template -constexpr inline const typename matrix::column_vector_type& get(const math::matrix& m) noexcept +inline constexpr const typename matrix::column_vector_type& get(const math::matrix& m) noexcept { static_assert(I < N); return m.columns[I]; } template -constexpr inline const typename matrix::column_vector_type&& get(const math::matrix&& m) noexcept +inline constexpr const typename matrix::column_vector_type&& get(const math::matrix&& m) noexcept { static_assert(I < N); return std::move(m.columns[I]); } +/// @private template constexpr matrix inverse(const matrix& m) noexcept { @@ -826,6 +830,7 @@ constexpr matrix inverse(const matrix& m) noexcept }; } +/// @private template constexpr matrix inverse(const matrix& m) noexcept { @@ -847,6 +852,7 @@ constexpr matrix inverse(const matrix& m) noexcept }; } +/// @private template constexpr matrix inverse(const matrix& m) noexcept { @@ -915,7 +921,7 @@ constexpr matrix mul(const matrix& a, const matrix& b /// @private template -constexpr inline matrix mul(const matrix& a, T b, std::index_sequence) noexcept +inline constexpr matrix mul(const matrix& a, T b, std::index_sequence) noexcept { return {(a[I] * b) ...}; } @@ -928,7 +934,7 @@ constexpr matrix mul(const matrix& a, T b) noexcept /// @private template -constexpr inline typename matrix::column_vector_type mul(const matrix& a, const typename matrix::row_vector_type& b, std::index_sequence) noexcept +inline constexpr typename matrix::column_vector_type mul(const matrix& a, const typename matrix::row_vector_type& b, std::index_sequence) noexcept { return ((a[I] * b[I]) + ...); } @@ -941,7 +947,7 @@ constexpr typename matrix::column_vector_type mul(const matrix /// @private template -constexpr inline typename matrix::row_vector_type mul(const typename matrix::column_vector_type& a, const matrix& b, std::index_sequence) noexcept +inline constexpr typename matrix::row_vector_type mul(const typename matrix::column_vector_type& a, const matrix& b, std::index_sequence) noexcept { return {dot(a, b[I]) ...}; } @@ -1029,7 +1035,7 @@ constexpr matrix scale(const matrix& m, const vector& v) /// @private template -constexpr inline matrix sub(const matrix& a, const matrix& b, std::index_sequence) noexcept +inline constexpr matrix sub(const matrix& a, const matrix& b, std::index_sequence) noexcept { return {(a[I] - b[I]) ...}; } @@ -1042,7 +1048,7 @@ constexpr matrix sub(const matrix& a, const matrix& b /// @private template -constexpr inline matrix sub(const matrix& a, T b, std::index_sequence) noexcept +inline constexpr matrix sub(const matrix& a, T b, std::index_sequence) noexcept { return {(a[I] - b) ...}; } @@ -1055,7 +1061,7 @@ constexpr matrix sub(const matrix& a, T b) noexcept /// @private template -constexpr inline matrix sub(T a, const matrix& b, std::index_sequence) noexcept +inline constexpr matrix sub(T a, const matrix& b, std::index_sequence) noexcept { return {(a - b[I]) ...}; } @@ -1068,7 +1074,7 @@ constexpr matrix sub(T a, const matrix& b) noexcept /// @private template -constexpr inline T trace(const matrix& m, std::index_sequence) noexcept +inline constexpr T trace(const matrix& m, std::index_sequence) noexcept { return ((m[I][I]) + ...); } @@ -1093,14 +1099,14 @@ constexpr matrix translate(const matrix& m, const vector /// @private template -constexpr inline typename matrix::column_vector_type transpose_column(const matrix& m, std::size_t i, std::index_sequence) noexcept +inline constexpr typename matrix::column_vector_type transpose_column(const matrix& m, std::size_t i, std::index_sequence) noexcept { return {m[I][i] ...}; } /// @private template -constexpr inline matrix transpose(const matrix& m, std::index_sequence) noexcept +inline constexpr matrix transpose(const matrix& m, std::index_sequence) noexcept { return {transpose_column(m, I, std::make_index_sequence{}) ...}; } @@ -1115,7 +1121,7 @@ namespace operators { /// @copydoc add(const matrix&, const matrix&) template -constexpr inline matrix operator+(const matrix& a, const matrix& b) noexcept +inline constexpr matrix operator+(const matrix& a, const matrix& b) noexcept { return add(a, b); } @@ -1123,12 +1129,12 @@ constexpr inline matrix operator+(const matrix& a, const matri /// @copydoc add(const matrix&, T) /// @{ template -constexpr inline matrix operator+(const matrix& a, T b) noexcept +inline constexpr matrix operator+(const matrix& a, T b) noexcept { return add(a, b); } template -constexpr inline matrix operator+(T a, const matrix& b) noexcept +inline constexpr matrix operator+(T a, const matrix& b) noexcept { return add(b, a); } @@ -1136,28 +1142,28 @@ constexpr inline matrix operator+(T a, const matrix& b) noexce /// @copydoc div(const matrix&, const matrix&) template -constexpr inline matrix operator/(const matrix& a, const matrix& b) noexcept +inline constexpr matrix operator/(const matrix& a, const matrix& b) noexcept { return div(a, b); } /// @copydoc div(const matrix&, T) template -constexpr inline matrix operator/(const matrix& a, T b) noexcept +inline constexpr matrix operator/(const matrix& a, T b) noexcept { return div(a, b); } /// @copydoc div(T, const matrix&) template -constexpr inline matrix operator/(T a, const matrix& b) noexcept +inline constexpr matrix operator/(T a, const matrix& b) noexcept { return div(a, b); } /// @copydoc mul(const matrix&, const matrix&) template -constexpr inline matrix operator*(const matrix& a, const matrix& b) noexcept +inline constexpr matrix operator*(const matrix& a, const matrix& b) noexcept { return mul(a, b); } @@ -1165,12 +1171,12 @@ constexpr inline matrix operator*(const matrix& a, const matri /// @copydoc mul(const matrix&, T) /// @{ template -constexpr inline matrix operator*(const matrix& a, T b) noexcept +inline constexpr matrix operator*(const matrix& a, T b) noexcept { return mul(a, b); } template -constexpr inline matrix operator*(T a, const matrix& b) noexcept +inline constexpr matrix operator*(T a, const matrix& b) noexcept { return mul(b, a); } @@ -1178,35 +1184,35 @@ constexpr inline matrix operator*(T a, const matrix& b) noexce /// @copydoc mul(const matrix&, const typename matrix::row_vector_type&) template -constexpr inline typename matrix::column_vector_type operator*(const matrix& a, const typename matrix::row_vector_type& b) noexcept +inline constexpr typename matrix::column_vector_type operator*(const matrix& a, const typename matrix::row_vector_type& b) noexcept { return mul(a, b); } /// @copydoc mul(const typename matrix::column_vector_type&, const matrix&) template -constexpr inline typename matrix::row_vector_type operator*(const typename matrix::column_vector_type& a, const matrix& b) noexcept +inline constexpr typename matrix::row_vector_type operator*(const typename matrix::column_vector_type& a, const matrix& b) noexcept { return mul(a, b); } /// @copydoc sub(const matrix&, const matrix&) template -constexpr inline matrix operator-(const matrix& a, const matrix& b) noexcept +inline constexpr matrix operator-(const matrix& a, const matrix& b) noexcept { return sub(a, b); } /// @copydoc sub(const matrix&, T) template -constexpr inline matrix operator-(const matrix& a, T b) noexcept +inline constexpr matrix operator-(const matrix& a, T b) noexcept { return sub(a, b); } /// @copydoc sub(T, const matrix&) template -constexpr inline matrix operator-(T a, const matrix& b) noexcept +inline constexpr matrix operator-(T a, const matrix& b) noexcept { return sub(a, b); } @@ -1221,12 +1227,12 @@ constexpr inline matrix operator-(T a, const matrix& b) noexce */ /// @{ template -constexpr inline matrix& operator+=(matrix& a, const matrix& b) noexcept +inline constexpr matrix& operator+=(matrix& a, const matrix& b) noexcept { return (a = a + b); } template -constexpr inline matrix& operator+=(matrix& a, T b) noexcept +inline constexpr matrix& operator+=(matrix& a, T b) noexcept { return (a = a + b); } @@ -1242,12 +1248,12 @@ constexpr inline matrix& operator+=(matrix& a, T b) noexcept */ /// @{ template -constexpr inline matrix& operator-=(matrix& a, const matrix& b) noexcept +inline constexpr matrix& operator-=(matrix& a, const matrix& b) noexcept { return (a = a - b); } template -constexpr inline matrix& operator-=(matrix& a, T b) noexcept +inline constexpr matrix& operator-=(matrix& a, T b) noexcept { return (a = a - b); } @@ -1263,12 +1269,12 @@ constexpr inline matrix& operator-=(matrix& a, T b) noexcept */ /// @{ template -constexpr inline matrix& operator*=(matrix& a, const matrix& b) noexcept +inline constexpr matrix& operator*=(matrix& a, const matrix& b) noexcept { return (a = a * b); } template -constexpr inline matrix& operator*=(matrix& a, T b) noexcept +inline constexpr matrix& operator*=(matrix& a, T b) noexcept { return (a = a * b); } @@ -1284,12 +1290,12 @@ constexpr inline matrix& operator*=(matrix& a, T b) noexcept */ /// @{ template -constexpr inline matrix& operator/=(matrix& a, const matrix& b) noexcept +inline constexpr matrix& operator/=(matrix& a, const matrix& b) noexcept { return (a = a / b); } template -constexpr inline matrix& operator/=(matrix& a, T b) noexcept +inline constexpr matrix& operator/=(matrix& a, T b) noexcept { return (a = a / b); } diff --git a/src/math/quaternion.hpp b/src/math/quaternion.hpp index fdfc58a..e1460b7 100644 --- a/src/math/quaternion.hpp +++ b/src/math/quaternion.hpp @@ -54,11 +54,11 @@ struct quaternion /// Returns a reference to the quaternion real part. /// @{ - constexpr inline scalar_type& w() noexcept + inline constexpr scalar_type& w() noexcept { return r; } - constexpr inline const scalar_type& w() const noexcept + inline constexpr const scalar_type& w() const noexcept { return r; } @@ -66,11 +66,11 @@ struct quaternion /// Returns a reference to the first element of the quaternion imaginary part. /// @{ - constexpr inline scalar_type& x() noexcept + inline constexpr scalar_type& x() noexcept { return i.x(); } - constexpr inline const scalar_type& x() const noexcept + inline constexpr const scalar_type& x() const noexcept { return i.x(); } @@ -78,11 +78,11 @@ struct quaternion /// Returns a reference to the second element of the quaternion imaginary part. /// @{ - constexpr inline scalar_type& y() noexcept + inline constexpr scalar_type& y() noexcept { return i.y(); } - constexpr inline const scalar_type& y() const noexcept + inline constexpr const scalar_type& y() const noexcept { return i.y(); } @@ -90,11 +90,11 @@ struct quaternion /// Returns a reference to the third element of the quaternion imaginary part. /// @{ - constexpr inline scalar_type& z() noexcept + inline constexpr scalar_type& z() noexcept { return i.z(); } - constexpr inline const scalar_type& z() const noexcept + inline constexpr const scalar_type& z() const noexcept { return i.z(); } @@ -143,7 +143,7 @@ struct quaternion * @return Type-casted quaternion. */ template - constexpr inline explicit operator quaternion() const noexcept + inline constexpr explicit operator quaternion() const noexcept { return {static_cast(r), vector(i)}; } @@ -178,7 +178,7 @@ struct quaternion * * @return Vector containing the real and imaginary parts of the quaternion. */ - constexpr inline explicit operator vector() const noexcept + inline constexpr explicit operator vector() const noexcept { return {r, i[0], i[1], i[2]}; } @@ -479,43 +479,43 @@ template quaternion quaternion_cast(const matrix& m); template -constexpr inline quaternion add(const quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion add(const quaternion& a, const quaternion& b) noexcept { return {a.r + b.r, a.i + b.i}; } template -constexpr inline quaternion add(const quaternion& a, T b) noexcept +inline constexpr quaternion add(const quaternion& a, T b) noexcept { return {a.r + b, a.i + b}; } template -constexpr inline quaternion conjugate(const quaternion& q) noexcept +inline constexpr quaternion conjugate(const quaternion& q) noexcept { return {q.r, -q.i}; } template -constexpr inline T dot(const quaternion& a, const quaternion& b) noexcept +inline constexpr T dot(const quaternion& a, const quaternion& b) noexcept { return a.r * b.r + dot(a.i, b.i); } template -constexpr inline quaternion div(const quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion div(const quaternion& a, const quaternion& b) noexcept { return {a.r / b.r, a.i / b.i}; } template -constexpr inline quaternion div(const quaternion& a, T b) noexcept +inline constexpr quaternion div(const quaternion& a, T b) noexcept { return {a.r / b, a.i / b}; } template -constexpr inline quaternion div(T a, const quaternion& b) noexcept +inline constexpr quaternion div(T a, const quaternion& b) noexcept { return {a / b.r, a / b.i}; } @@ -533,7 +533,7 @@ inline T length(const quaternion& q) } template -constexpr inline quaternion lerp(const quaternion& a, const quaternion& b, T t) noexcept +inline constexpr quaternion lerp(const quaternion& a, const quaternion& b, T t) noexcept { return { @@ -572,7 +572,7 @@ constexpr quaternion mul(const quaternion& a, const quaternion& b) noex } template -constexpr inline quaternion mul(const quaternion& a, T b) noexcept +inline constexpr quaternion mul(const quaternion& a, T b) noexcept { return {a.r * b, a.i * b}; } @@ -584,13 +584,13 @@ constexpr vector mul(const quaternion& a, const vector& b) noexce } template -constexpr inline vector mul(const vector& a, const quaternion& b) noexcept +inline constexpr vector mul(const vector& a, const quaternion& b) noexcept { return mul(conjugate(b), a); } template -constexpr inline quaternion negate(const quaternion& q) noexcept +inline constexpr quaternion negate(const quaternion& q) noexcept { return {-q.r, -q.i}; } @@ -639,25 +639,25 @@ quaternion slerp(const quaternion& a, const quaternion& b, T t, T error } template -constexpr inline T sqr_length(const quaternion& q) noexcept +inline constexpr T sqr_length(const quaternion& q) noexcept { return q.r * q.r + sqr_length(q.i); } template -constexpr inline quaternion sub(const quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion sub(const quaternion& a, const quaternion& b) noexcept { return {a.r - b.r, a.i - b.i}; } template -constexpr inline quaternion sub(const quaternion& a, T b) noexcept +inline constexpr quaternion sub(const quaternion& a, T b) noexcept { return {a.r - b, a.i - b}; } template -constexpr inline quaternion sub(T a, const quaternion& b) noexcept +inline constexpr quaternion sub(T a, const quaternion& b) noexcept { return {a - b.r, a - b.i}; } @@ -742,7 +742,7 @@ namespace operators { /// @copydoc add(const quaternion&, const quaternion&) template -constexpr inline quaternion operator+(const quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion operator+(const quaternion& a, const quaternion& b) noexcept { return add(a, b); } @@ -750,12 +750,12 @@ constexpr inline quaternion operator+(const quaternion& a, const quaternio /// @copydoc add(const quaternion&, T) /// @{ template -constexpr inline quaternion operator+(const quaternion& a, T b) noexcept +inline constexpr quaternion operator+(const quaternion& a, T b) noexcept { return add(a, b); } template -constexpr inline quaternion operator+(T a, const quaternion& b) noexcept +inline constexpr quaternion operator+(T a, const quaternion& b) noexcept { return add(b, a); } @@ -763,28 +763,28 @@ constexpr inline quaternion operator+(T a, const quaternion& b) noexcept /// @copydoc div(const quaternion&, const quaternion&) template -constexpr inline quaternion operator/(const quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion operator/(const quaternion& a, const quaternion& b) noexcept { return div(a, b); } /// @copydoc div(const quaternion&, T) template -constexpr inline quaternion operator/(const quaternion& a, T b) noexcept +inline constexpr quaternion operator/(const quaternion& a, T b) noexcept { return div(a, b); } /// @copydoc div(T, const quaternion&) template -constexpr inline quaternion operator/(T a, const quaternion& b) noexcept +inline constexpr quaternion operator/(T a, const quaternion& b) noexcept { return div(a, b); } /// @copydoc mul(const quaternion&, const quaternion&) template -constexpr inline quaternion operator*(const quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion operator*(const quaternion& a, const quaternion& b) noexcept { return mul(a, b); } @@ -792,12 +792,12 @@ constexpr inline quaternion operator*(const quaternion& a, const quaternio /// @copydoc mul(const quaternion&, T) /// @{ template -constexpr inline quaternion operator*(const quaternion& a, T b) noexcept +inline constexpr quaternion operator*(const quaternion& a, T b) noexcept { return mul(a, b); } template -constexpr inline quaternion operator*(T a, const quaternion& b) noexcept +inline constexpr quaternion operator*(T a, const quaternion& b) noexcept { return mul(b, a); } @@ -805,21 +805,21 @@ constexpr inline quaternion operator*(T a, const quaternion& b) noexcept /// @copydoc mul(const quaternion&, const vector&) template -constexpr inline vector operator*(const quaternion& a, const vector& b) noexcept +inline constexpr vector operator*(const quaternion& a, const vector& b) noexcept { return mul(a, b); } /// @copydoc mul(const vector&, const quaternion&) template -constexpr inline vector operator*(const vector& a, const quaternion& b) noexcept +inline constexpr vector operator*(const vector& a, const quaternion& b) noexcept { return mul(a, b); } /// @copydoc sub(const quaternion&, const quaternion&) template -constexpr inline quaternion operator-(const quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion operator-(const quaternion& a, const quaternion& b) noexcept { return sub(a, b); } @@ -827,12 +827,12 @@ constexpr inline quaternion operator-(const quaternion& a, const quaternio /// @copydoc sub(const quaternion&, T) /// @{ template -constexpr inline quaternion operator-(const quaternion& a, T b) noexcept +inline constexpr quaternion operator-(const quaternion& a, T b) noexcept { return sub(a, b); } template -constexpr inline quaternion operator-(T a, const quaternion& b) noexcept +inline constexpr quaternion operator-(T a, const quaternion& b) noexcept { return sub(a, b); } @@ -840,7 +840,7 @@ constexpr inline quaternion operator-(T a, const quaternion& b) noexcept /// @copydoc negate(const quaternion&) template -constexpr inline quaternion operator-(const quaternion& q) noexcept +inline constexpr quaternion operator-(const quaternion& q) noexcept { return negate(q); } @@ -855,12 +855,12 @@ constexpr inline quaternion operator-(const quaternion& q) noexcept */ /// @{ template -constexpr inline quaternion& operator+=(quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion& operator+=(quaternion& a, const quaternion& b) noexcept { return (a = a + b); } template -constexpr inline quaternion& operator+=(quaternion& a, T b) noexcept +inline constexpr quaternion& operator+=(quaternion& a, T b) noexcept { return (a = a + b); } @@ -876,12 +876,12 @@ constexpr inline quaternion& operator+=(quaternion& a, T b) noexcept */ /// @{ template -constexpr inline quaternion& operator-=(quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion& operator-=(quaternion& a, const quaternion& b) noexcept { return (a = a - b); } template -constexpr inline quaternion& operator-=(quaternion& a, T b) noexcept +inline constexpr quaternion& operator-=(quaternion& a, T b) noexcept { return (a = a - b); } @@ -897,12 +897,12 @@ constexpr inline quaternion& operator-=(quaternion& a, T b) noexcept */ /// @{ template -constexpr inline quaternion& operator*=(quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion& operator*=(quaternion& a, const quaternion& b) noexcept { return (a = a * b); } template -constexpr inline quaternion& operator*=(quaternion& a, T b) noexcept +inline constexpr quaternion& operator*=(quaternion& a, T b) noexcept { return (a = a * b); } @@ -918,12 +918,12 @@ constexpr inline quaternion& operator*=(quaternion& a, T b) noexcept */ /// @{ template -constexpr inline quaternion& operator/=(quaternion& a, const quaternion& b) noexcept +inline constexpr quaternion& operator/=(quaternion& a, const quaternion& b) noexcept { return (a = a / b); } template -constexpr inline quaternion& operator/=(quaternion& a, T b) noexcept +inline constexpr quaternion& operator/=(quaternion& a, T b) noexcept { return (a = a / b); } diff --git a/src/math/vector.hpp b/src/math/vector.hpp index d5e930b..d107948 100644 --- a/src/math/vector.hpp +++ b/src/math/vector.hpp @@ -41,13 +41,13 @@ namespace math { template struct vector { - /// Vector element data type. + /// Element type. typedef T element_type; - /// Number of vector elements. + /// Number of elements. static constexpr std::size_t element_count = N; - /// Array of vector elements. + /// Array of elements. element_type elements[N]; /// @name Conversion @@ -55,7 +55,7 @@ struct vector /// @private template - constexpr inline vector type_cast(std::index_sequence) const noexcept + inline constexpr vector type_cast(std::index_sequence) const noexcept { return {static_cast(elements[I])...}; } @@ -68,14 +68,14 @@ struct vector * @return Vector containing the type-casted elements. */ template - constexpr inline explicit operator vector() const noexcept + inline constexpr explicit operator vector() const noexcept { return type_cast(std::make_index_sequence{}); } /// @private template - constexpr inline vector size_cast(std::index_sequence) const noexcept + inline constexpr vector size_cast(std::index_sequence) const noexcept { return {(I < N) ? elements[I] : T{0} ...}; } @@ -88,7 +88,7 @@ struct vector * @return *m*-dimensional vector. */ template - constexpr inline explicit operator vector() const noexcept + inline constexpr explicit operator vector() const noexcept { return size_cast(std::make_index_sequence{}); } @@ -106,11 +106,11 @@ struct vector * @return Reference to the element at index @p i. */ /// @{ - constexpr inline element_type& operator[](std::size_t i) noexcept + inline constexpr element_type& operator[](std::size_t i) noexcept { return elements[i]; } - constexpr inline const element_type& operator[](std::size_t i) const noexcept + inline constexpr const element_type& operator[](std::size_t i) const noexcept { return elements[i]; } @@ -120,11 +120,11 @@ struct vector * Returns a reference to the first element. */ /// @{ - constexpr inline element_type& front() noexcept + inline constexpr element_type& front() noexcept { return elements[0]; } - constexpr inline const element_type& front() const noexcept + inline constexpr const element_type& front() const noexcept { return elements[0]; } @@ -134,11 +134,11 @@ struct vector * Returns a reference to the last element. */ /// @{ - constexpr inline element_type& back() noexcept + inline constexpr element_type& back() noexcept { return elements[N - 1]; } - constexpr inline const element_type& back() const noexcept + inline constexpr const element_type& back() const noexcept { return elements[N - 1]; } @@ -148,11 +148,11 @@ struct vector * Returns a pointer to the element array. */ /// @{ - constexpr inline element_type* data() noexcept + inline constexpr element_type* data() noexcept { return elements; }; - constexpr inline const element_type* data() const noexcept + inline constexpr const element_type* data() const noexcept { return elements; }; @@ -160,12 +160,12 @@ struct vector /// Returns a reference to the first element. /// @{ - constexpr inline element_type& x() noexcept + inline constexpr element_type& x() noexcept { static_assert(N > 0, "Vector does not contain an x element."); return elements[0]; } - constexpr inline const element_type& x() const noexcept + inline constexpr const element_type& x() const noexcept { static_assert(N > 0, "Vector does not contain an x element."); return elements[0]; @@ -176,12 +176,12 @@ struct vector * Returns a reference to the second element. */ /// @{ - constexpr inline element_type& y() noexcept + inline constexpr element_type& y() noexcept { static_assert(N > 1, "Vector does not contain a y element."); return elements[1]; } - constexpr inline const element_type& y() const noexcept + inline constexpr const element_type& y() const noexcept { static_assert(N > 1, "Vector does not contain a y element."); return elements[1]; @@ -192,12 +192,12 @@ struct vector * Returns a reference to the third element. */ /// @{ - constexpr inline element_type& z() noexcept + inline constexpr element_type& z() noexcept { static_assert(N > 2, "Vector does not contain a z element."); return elements[2]; } - constexpr inline const element_type& z() const noexcept + inline constexpr const element_type& z() const noexcept { static_assert(N > 2, "Vector does not contain a z element."); return elements[2]; @@ -213,15 +213,15 @@ struct vector * Returns an iterator to the first element. */ /// @{ - constexpr inline element_type* begin() noexcept + inline constexpr element_type* begin() noexcept { return elements; } - constexpr inline const element_type* begin() const noexcept + inline constexpr const element_type* begin() const noexcept { return elements; } - constexpr inline const element_type* cbegin() const noexcept + inline constexpr const element_type* cbegin() const noexcept { return elements; } @@ -231,15 +231,15 @@ struct vector * Returns an iterator to the element following the last element. */ /// @{ - constexpr inline element_type* end() noexcept + inline constexpr element_type* end() noexcept { return elements + N; } - constexpr inline const element_type* end() const noexcept + inline constexpr const element_type* end() const noexcept { return elements + N; } - constexpr inline const element_type* cend() const noexcept + inline constexpr const element_type* cend() const noexcept { return elements + N; } @@ -249,15 +249,15 @@ struct vector * Returns a reverse iterator to the first element of the reversed vector. */ /// @{ - constexpr inline std::reverse_iterator rbegin() noexcept + inline constexpr std::reverse_iterator rbegin() noexcept { return std::reverse_iterator(elements + N); } - constexpr inline std::reverse_iterator rbegin() const noexcept + inline constexpr std::reverse_iterator rbegin() const noexcept { return std::reverse_iterator(elements + N); } - constexpr inline std::reverse_iterator crbegin() const noexcept + inline constexpr std::reverse_iterator crbegin() const noexcept { return std::reverse_iterator(elements + N); } @@ -267,15 +267,15 @@ struct vector * Returns a reverse iterator to the element following the last element of the reversed vector. */ /// @{ - constexpr inline std::reverse_iterator rend() noexcept + inline constexpr std::reverse_iterator rend() noexcept { return std::reverse_iterator(elements); } - constexpr inline std::reverse_iterator rend() const noexcept + inline constexpr std::reverse_iterator rend() const noexcept { return std::reverse_iterator(elements); } - constexpr inline std::reverse_iterator crend() const noexcept + inline constexpr std::reverse_iterator crend() const noexcept { return std::reverse_iterator(elements); } @@ -289,7 +289,7 @@ struct vector /** * Returns the number of elements in the vector. */ - constexpr inline std::size_t size() const noexcept + inline constexpr std::size_t size() const noexcept { return N; }; @@ -834,104 +834,104 @@ constexpr vector trunc(const vector& x); /// @private template -constexpr inline vector abs(const vector& x, std::index_sequence) +inline constexpr vector abs(const vector& x, std::index_sequence) { return {std::abs(x[I])...}; } template -constexpr inline vector abs(const vector& x) +inline constexpr vector abs(const vector& x) { return abs(x, std::make_index_sequence{}); } /// @private template -constexpr inline vector add(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector add(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] + y[I])...}; } template -constexpr inline vector add(const vector& x, const vector& y) noexcept +inline constexpr vector add(const vector& x, const vector& y) noexcept { return add(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector add(const vector& x, T y, std::index_sequence) noexcept +inline constexpr vector add(const vector& x, T y, std::index_sequence) noexcept { return {(x[I] + y)...}; } template -constexpr inline vector add(const vector& x, T y) noexcept +inline constexpr vector add(const vector& x, T y) noexcept { return add(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline bool all(const vector& x, std::index_sequence) noexcept +inline constexpr bool all(const vector& x, std::index_sequence) noexcept { return (x[I] && ...); } template -constexpr inline bool all(const vector& x) noexcept +inline constexpr bool all(const vector& x) noexcept { return all(x, std::make_index_sequence{}); } /// @private template -constexpr inline bool any(const vector& x, std::index_sequence) noexcept +inline constexpr bool any(const vector& x, std::index_sequence) noexcept { return (x[I] || ...); } template -constexpr inline bool any(const vector& x) noexcept +inline constexpr bool any(const vector& x) noexcept { return any(x, std::make_index_sequence{}); } /// @private template -constexpr inline vector ceil(const vector& x, std::index_sequence) +inline constexpr vector ceil(const vector& x, std::index_sequence) { return {std::ceil(x[I])...}; } template -constexpr inline vector ceil(const vector& x) +inline constexpr vector ceil(const vector& x) { return ceil(x, std::make_index_sequence{}); } /// @private template -constexpr inline vector clamp(const vector& x, const vector& min_val, const vector& max_val, std::index_sequence) +inline constexpr vector clamp(const vector& x, const vector& min_val, const vector& max_val, std::index_sequence) { return {std::min(max_val[I], std::max(min_val[I], x[I]))...}; } template -constexpr inline vector clamp(const vector& x, const vector& min, const vector& max) +inline constexpr vector clamp(const vector& x, const vector& min, const vector& max) { return clamp(x, min, max, std::make_index_sequence{}); } /// @private template -constexpr inline vector clamp(const vector& x, T min, T max, std::index_sequence) +inline constexpr vector clamp(const vector& x, T min, T max, std::index_sequence) { return {std::min(max, std::max(min, x[I]))...}; } template -constexpr inline vector clamp(const vector& x, T min, T max) +inline constexpr vector clamp(const vector& x, T min, T max) { return clamp(x, min, max, std::make_index_sequence{}); } @@ -944,7 +944,7 @@ vector clamp_length(const vector& x, T max_length) } template -constexpr inline vector cross(const vector& x, const vector& y) noexcept +inline constexpr vector cross(const vector& x, const vector& y) noexcept { return { @@ -962,144 +962,144 @@ inline T distance(const vector& p0, const vector& p1) /// @private template -constexpr inline vector div(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector div(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] / y[I])...}; } template -constexpr inline vector div(const vector& x, const vector& y) noexcept +inline constexpr vector div(const vector& x, const vector& y) noexcept { return div(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector div(const vector& x, T y, std::index_sequence) noexcept +inline constexpr vector div(const vector& x, T y, std::index_sequence) noexcept { return {(x[I] / y)...}; } template -constexpr inline vector div(const vector& x, T y) noexcept +inline constexpr vector div(const vector& x, T y) noexcept { return div(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector div(T x, const vector& y, std::index_sequence) noexcept +inline constexpr vector div(T x, const vector& y, std::index_sequence) noexcept { return {(x / y[I])...}; } template -constexpr inline vector div(T x, const vector& y) noexcept +inline constexpr vector div(T x, const vector& y) noexcept { return div(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline T dot(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr T dot(const vector& x, const vector& y, std::index_sequence) noexcept { return ((x[I] * y[I]) + ...); } template -constexpr inline T dot(const vector& x, const vector& y) noexcept +inline constexpr T dot(const vector& x, const vector& y) noexcept { return dot(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector equal(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector equal(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] == y[I])...}; } template -constexpr inline vector equal(const vector& x, const vector& y) noexcept +inline constexpr vector equal(const vector& x, const vector& y) noexcept { return equal(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector floor(const vector& x, std::index_sequence) +inline constexpr vector floor(const vector& x, std::index_sequence) { return {std::floor(x[I])...}; } template -constexpr inline vector floor(const vector& x) +inline constexpr vector floor(const vector& x) { return floor(x, std::make_index_sequence{}); } /// @private template -constexpr inline vector fma(const vector& x, const vector& y, const vector& z, std::index_sequence) +inline constexpr vector fma(const vector& x, const vector& y, const vector& z, std::index_sequence) { return {std::fma(x[I], y[I], z[I])...}; } template -constexpr inline vector fma(const vector& x, const vector& y, const vector& z) +inline constexpr vector fma(const vector& x, const vector& y, const vector& z) { return fma(x, y, z, std::make_index_sequence{}); } /// @private template -constexpr inline vector fma(const vector& x, T y, T z, std::index_sequence) +inline constexpr vector fma(const vector& x, T y, T z, std::index_sequence) { return {std::fma(x[I], y, z)...}; } template -constexpr inline vector fma(const vector& x, T y, T z) +inline constexpr vector fma(const vector& x, T y, T z) { return fma(x, y, z, std::make_index_sequence{}); } /// @private template -constexpr inline vector fract(const vector& x, std::index_sequence) +inline constexpr vector fract(const vector& x, std::index_sequence) { return {x[I] - std::floor(x[I])...}; } template -constexpr inline vector fract(const vector& x) +inline constexpr vector fract(const vector& x) { return fract(x, std::make_index_sequence{}); } template -constexpr inline T& get(math::vector& v) noexcept +inline constexpr T& get(math::vector& v) noexcept { static_assert(I < N); return v.elements[I]; } template -constexpr inline T&& get(math::vector&& v) noexcept +inline constexpr T&& get(math::vector&& v) noexcept { static_assert(I < N); return std::move(v.elements[I]); } template -constexpr inline const T& get(const math::vector& v) noexcept +inline constexpr const T& get(const math::vector& v) noexcept { static_assert(I < N); return v.elements[I]; } template -constexpr inline const T&& get(const math::vector&& v) noexcept +inline constexpr const T&& get(const math::vector&& v) noexcept { static_assert(I < N); return std::move(v.elements[I]); @@ -1107,26 +1107,26 @@ constexpr inline const T&& get(const math::vector&& v) noexcept /// @private template -constexpr inline vector greater_than(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector greater_than(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] > y[I])...}; } template -constexpr inline vector greater_than(const vector& x, const vector& y) noexcept +inline constexpr vector greater_than(const vector& x, const vector& y) noexcept { return greater_than(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector greater_than_equal(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector greater_than_equal(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] >= y[I])...}; } template -constexpr inline vector greater_than_equal(const vector& x, const vector& y) noexcept +inline constexpr vector greater_than_equal(const vector& x, const vector& y) noexcept { return greater_than_equal(x, y, std::make_index_sequence{}); } @@ -1145,33 +1145,33 @@ inline T length(const vector& x) /// @private template -constexpr inline vector less_than(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector less_than(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] < y[I])...}; } template -constexpr inline vector less_than(const vector& x, const vector& y) noexcept +inline constexpr vector less_than(const vector& x, const vector& y) noexcept { return less_than(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector less_than_equal(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector less_than_equal(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] <= y[I])...}; } template -constexpr inline vector less_than_equal(const vector& x, const vector& y) noexcept +inline constexpr vector less_than_equal(const vector& x, const vector& y) noexcept { return less_than_equal(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector max(const vector& x, const vector& y, std::index_sequence) +inline constexpr vector max(const vector& x, const vector& y, std::index_sequence) { return {std::max(x[I], y[I])...}; } @@ -1183,14 +1183,14 @@ constexpr vector max(const vector& x, const vector& y) } template -constexpr inline T max(const vector& x) +inline constexpr T max(const vector& x) { return *std::max_element(x.elements, x.elements + N); } /// @private template -constexpr inline vector min(const vector& x, const vector& y, std::index_sequence) +inline constexpr vector min(const vector& x, const vector& y, std::index_sequence) { return {std::min(x[I], y[I])...}; } @@ -1202,72 +1202,72 @@ constexpr vector min(const vector& x, const vector& y) } template -constexpr inline T min(const vector& x) +inline constexpr T min(const vector& x) { return *std::min_element(x.elements, x.elements + N); } /// @private template -constexpr inline vector mod(const vector& x, const vector& y, std::index_sequence) +inline constexpr vector mod(const vector& x, const vector& y, std::index_sequence) { return {std::fmod(x[I], y[I])...}; } template -constexpr inline vector mod(const vector& x, const vector& y) +inline constexpr vector mod(const vector& x, const vector& y) { return mod(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector mod(const vector& x, T y, std::index_sequence) +inline constexpr vector mod(const vector& x, T y, std::index_sequence) { return {std::fmod(x[I], y)...}; } template -constexpr inline vector mod(const vector& x, T y) +inline constexpr vector mod(const vector& x, T y) { return mod(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector mul(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector mul(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] * y[I])...}; } template -constexpr inline vector mul(const vector& x, const vector& y) noexcept +inline constexpr vector mul(const vector& x, const vector& y) noexcept { return mul(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector mul(const vector& x, T y, std::index_sequence) noexcept +inline constexpr vector mul(const vector& x, T y, std::index_sequence) noexcept { return {(x[I] * y)...}; } template -constexpr inline vector mul(const vector& x, T y) noexcept +inline constexpr vector mul(const vector& x, T y) noexcept { return mul(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector negate(const vector& x, std::index_sequence) noexcept +inline constexpr vector negate(const vector& x, std::index_sequence) noexcept { return {(-x[I])...}; } template -constexpr inline vector negate(const vector& x) noexcept +inline constexpr vector negate(const vector& x) noexcept { return negate(x, std::make_index_sequence{}); } @@ -1280,26 +1280,26 @@ inline vector normalize(const vector& x) /// @private template -constexpr inline vector logical_not(const vector& x, std::index_sequence) noexcept +inline constexpr vector logical_not(const vector& x, std::index_sequence) noexcept { return {!x[I]...}; } template -constexpr inline vector logical_not(const vector& x) noexcept +inline constexpr vector logical_not(const vector& x) noexcept { return logical_not(x, std::make_index_sequence{}); } /// @private template -constexpr inline vector not_equal(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector not_equal(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] != y[I])...}; } template -constexpr inline vector not_equal(const vector& x, const vector& y) noexcept +inline constexpr vector not_equal(const vector& x, const vector& y) noexcept { return not_equal(x, y, std::make_index_sequence{}); } @@ -1332,38 +1332,38 @@ inline vector pow(const vector& x, T y) /// @private template -constexpr inline vector round(const vector& x, std::index_sequence) +inline constexpr vector round(const vector& x, std::index_sequence) { return {std::round(x[I])...}; } template -constexpr inline vector round(const vector& x) +inline constexpr vector round(const vector& x) { return round(x, std::make_index_sequence{}); } /// @private template -constexpr inline vector sign(const vector& x, std::index_sequence) +inline constexpr vector sign(const vector& x, std::index_sequence) { return {std::copysign(T{1}, x[I])...}; } template -constexpr inline vector sign(const vector& x) +inline constexpr vector sign(const vector& x) { return sign(x, std::make_index_sequence{}); } template -constexpr inline T sqr_distance(const vector& p0, const vector& p1) noexcept +inline constexpr T sqr_distance(const vector& p0, const vector& p1) noexcept { return sqr_length(sub(p0, p1)); } template -constexpr inline T sqr_length(const vector& x) noexcept +inline constexpr T sqr_length(const vector& x) noexcept { return dot(x, x); } @@ -1383,71 +1383,71 @@ inline vector sqrt(const vector& x, const vector& y) /// @private template -constexpr inline vector sub(const vector& x, const vector& y, std::index_sequence) noexcept +inline constexpr vector sub(const vector& x, const vector& y, std::index_sequence) noexcept { return {(x[I] - y[I])...}; } template -constexpr inline vector sub(const vector& x, const vector& y) noexcept +inline constexpr vector sub(const vector& x, const vector& y) noexcept { return sub(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector sub(const vector& x, T y, std::index_sequence) noexcept +inline constexpr vector sub(const vector& x, T y, std::index_sequence) noexcept { return {(x[I] - y)...}; } template -constexpr inline vector sub(const vector& x, T y) noexcept +inline constexpr vector sub(const vector& x, T y) noexcept { return sub(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline vector sub(T x, const vector& y, std::index_sequence) noexcept +inline constexpr vector sub(T x, const vector& y, std::index_sequence) noexcept { return {(x - y[I])...}; } template -constexpr inline vector sub(T x, const vector& y) noexcept +inline constexpr vector sub(T x, const vector& y) noexcept { return sub(x, y, std::make_index_sequence{}); } /// @private template -constexpr inline T sum(const vector& x, std::index_sequence) noexcept +inline constexpr T sum(const vector& x, std::index_sequence) noexcept { return (x[I] + ...); } template -constexpr inline T sum(const vector& x) noexcept +inline constexpr T sum(const vector& x) noexcept { return sum(x, std::make_index_sequence{}); } template -constexpr inline vector swizzle(const vector& x) noexcept +inline constexpr vector swizzle(const vector& x) noexcept { return {x[Indices]...}; } /// @private template -constexpr inline vector trunc(const vector& x, std::index_sequence) +inline constexpr vector trunc(const vector& x, std::index_sequence) { return {std::trunc(x[I])...}; } template -constexpr inline vector trunc(const vector& x) +inline constexpr vector trunc(const vector& x) { return trunc(x, std::make_index_sequence{}); } @@ -1456,7 +1456,7 @@ namespace operators { /// @copydoc add(const vector&, const vector&) template -constexpr inline vector operator+(const vector& x, const vector& y) noexcept +inline constexpr vector operator+(const vector& x, const vector& y) noexcept { return add(x, y); } @@ -1464,12 +1464,12 @@ constexpr inline vector operator+(const vector& x, const vector&, T) /// @{ template -constexpr inline vector operator+(const vector& x, T y) noexcept +inline constexpr vector operator+(const vector& x, T y) noexcept { return add(x, y); } template -constexpr inline vector operator+(T x, const vector& y) noexcept +inline constexpr vector operator+(T x, const vector& y) noexcept { return add(y, x); } @@ -1477,28 +1477,28 @@ constexpr inline vector operator+(T x, const vector& y) noexcept /// @copydoc div(const vector&, const vector&) template -constexpr inline vector operator/(const vector& x, const vector& y) noexcept +inline constexpr vector operator/(const vector& x, const vector& y) noexcept { return div(x, y); } /// @copydoc div(const vector&, T) template -constexpr inline vector operator/(const vector& x, T y) noexcept +inline constexpr vector operator/(const vector& x, T y) noexcept { return div(x, y); } /// @copydoc div(T, const vector&) template -constexpr inline vector operator/(T x, const vector& y) noexcept +inline constexpr vector operator/(T x, const vector& y) noexcept { return div(x, y); } /// @copydoc mul(const vector&, const vector&) template -constexpr inline vector operator*(const vector& x, const vector& y) noexcept +inline constexpr vector operator*(const vector& x, const vector& y) noexcept { return mul(x, y); } @@ -1506,12 +1506,12 @@ constexpr inline vector operator*(const vector& x, const vector&, T) /// @{ template -constexpr inline vector operator*(const vector& x, T y) noexcept +inline constexpr vector operator*(const vector& x, T y) noexcept { return mul(x, y); } template -constexpr inline vector operator*(T x, const vector& y) noexcept +inline constexpr vector operator*(T x, const vector& y) noexcept { return mul(y, x); } @@ -1519,28 +1519,28 @@ constexpr inline vector operator*(T x, const vector& y) noexcept /// @copydoc negate(const vector&) template -constexpr inline vector operator-(const vector& x) noexcept +inline constexpr vector operator-(const vector& x) noexcept { return negate(x); } /// @copydoc sub(const vector&, const vector&) template -constexpr inline vector operator-(const vector& x, const vector& y) noexcept +inline constexpr vector operator-(const vector& x, const vector& y) noexcept { return sub(x, y); } /// @copydoc sub(const vector&, T) template -constexpr inline vector operator-(const vector& x, T y) noexcept +inline constexpr vector operator-(const vector& x, T y) noexcept { return sub(x, y); } /// @copydoc sub(T, const vector&) template -constexpr inline vector operator-(T x, const vector& y) noexcept +inline constexpr vector operator-(T x, const vector& y) noexcept { return sub(x, y); } @@ -1555,12 +1555,12 @@ constexpr inline vector operator-(T x, const vector& y) noexcept */ /// @{ template -constexpr inline vector& operator+=(vector& x, const vector& y) noexcept +inline constexpr vector& operator+=(vector& x, const vector& y) noexcept { return (x = x + y); } template -constexpr inline vector& operator+=(vector& x, T y) noexcept +inline constexpr vector& operator+=(vector& x, T y) noexcept { return (x = x + y); } @@ -1576,12 +1576,12 @@ constexpr inline vector& operator+=(vector& x, T y) noexcept */ /// @{ template -constexpr inline vector& operator-=(vector& x, const vector& y) noexcept +inline constexpr vector& operator-=(vector& x, const vector& y) noexcept { return (x = x - y); } template -constexpr inline vector& operator-=(vector& x, T y) noexcept +inline constexpr vector& operator-=(vector& x, T y) noexcept { return (x = x - y); } @@ -1597,12 +1597,12 @@ constexpr inline vector& operator-=(vector& x, T y) noexcept */ /// @{ template -constexpr inline vector& operator*=(vector& x, const vector& y) noexcept +inline constexpr vector& operator*=(vector& x, const vector& y) noexcept { return (x = x * y); } template -constexpr inline vector& operator*=(vector& x, T y) noexcept +inline constexpr vector& operator*=(vector& x, T y) noexcept { return (x = x * y); } @@ -1618,12 +1618,12 @@ constexpr inline vector& operator*=(vector& x, T y) noexcept */ /// @{ template -constexpr inline vector& operator/=(vector& x, const vector& y) noexcept +inline constexpr vector& operator/=(vector& x, const vector& y) noexcept { return (x = x / y); } template -constexpr inline vector& operator/=(vector& x, T y) noexcept +inline constexpr vector& operator/=(vector& x, T y) noexcept { return (x = x / y); } diff --git a/src/render/renderer.cpp b/src/render/renderer.cpp index 13e4b47..79ceb31 100644 --- a/src/render/renderer.cpp +++ b/src/render/renderer.cpp @@ -32,6 +32,7 @@ #include "geom/projection.hpp" #include "config.hpp" #include "math/quaternion.hpp" +#include "math/constants.hpp" #include #include diff --git a/src/resources/image.hpp b/src/resources/image.hpp index 4dce95c..2c3af27 100644 --- a/src/resources/image.hpp +++ b/src/resources/image.hpp @@ -57,21 +57,21 @@ public: */ /// @{ template - constexpr inline T* begin() noexcept + inline constexpr T* begin() noexcept { static_assert(std::is_standard_layout::value, "Pixel iterator type is not standard-layout."); static_assert(std::is_trivial::value, "Pixel iterator type is not trivial."); return static_cast(pixels); } template - constexpr inline const T* begin() const noexcept + inline constexpr const T* begin() const noexcept { static_assert(std::is_standard_layout::value, "Pixel iterator type is not standard-layout."); static_assert(std::is_trivial::value, "Pixel iterator type is not trivial."); return static_cast(pixels); } template - constexpr inline const T* cbegin() const noexcept + inline constexpr const T* cbegin() const noexcept { static_assert(std::is_standard_layout::value, "Pixel iterator type is not standard-layout."); static_assert(std::is_trivial::value, "Pixel iterator type is not trivial."); @@ -86,25 +86,25 @@ public: */ /// @{ template - constexpr inline T* end() noexcept + inline constexpr T* end() noexcept { static_assert(std::is_standard_layout::value, "Pixel iterator type is not standard-layout."); static_assert(std::is_trivial::value, "Pixel iterator type is not trivial."); - return static_cast(static_cast(pixels) + size); + return reinterpret_cast(static_cast(pixels) + size); } template - constexpr inline const T* end() const noexcept + inline constexpr const T* end() const noexcept { static_assert(std::is_standard_layout::value, "Pixel iterator type is not standard-layout."); static_assert(std::is_trivial::value, "Pixel iterator type is not trivial."); - return static_cast(static_cast(pixels) + size); + return reinterpret_cast(static_cast(pixels) + size); } template - constexpr inline const T* cend() const noexcept + inline constexpr const T* cend() const noexcept { static_assert(std::is_standard_layout::value, "Pixel iterator type is not standard-layout."); static_assert(std::is_trivial::value, "Pixel iterator type is not trivial."); - return static_cast(static_cast(pixels) + size); + return reinterpret_cast(static_cast(pixels) + size); } /// @}