Browse Source

Improve ant trait definitions, trait loaders, and morphogenesis.

master
C. J. Howard 1 year ago
parent
commit
a7e5aca4a0
68 changed files with 1676 additions and 1682 deletions
  1. +0
    -1
      CMakeLists.txt
  2. +1
    -1
      src/application.cpp
  3. +1
    -1
      src/color/xyy.hpp
  4. +1
    -1
      src/color/xyz.hpp
  5. +0
    -82
      src/game/ant/breed.hpp
  6. +20
    -6
      src/game/ant/caste-type.hpp
  7. +63
    -6
      src/game/ant/caste.hpp
  8. +444
    -508
      src/game/ant/morphogenesis.cpp
  9. +3
    -4
      src/game/ant/morphogenesis.hpp
  10. +78
    -0
      src/game/ant/species.hpp
  11. +12
    -12
      src/game/ant/subcaste-type.hpp
  12. +10
    -4
      src/game/ant/trait/antennae.hpp
  13. +7
    -9
      src/game/ant/trait/body-size.hpp
  14. +4
    -4
      src/game/ant/trait/cocoon.hpp
  15. +1
    -1
      src/game/ant/trait/diet.hpp
  16. +1
    -1
      src/game/ant/trait/egg.hpp
  17. +15
    -7
      src/game/ant/trait/eyes.hpp
  18. +1
    -1
      src/game/ant/trait/foraging-time.hpp
  19. +0
    -51
      src/game/ant/trait/forewings.hpp
  20. +48
    -0
      src/game/ant/trait/founding-mode.hpp
  21. +6
    -1
      src/game/ant/trait/gaster.hpp
  22. +11
    -8
      src/game/ant/trait/head.hpp
  23. +4
    -4
      src/game/ant/trait/larva.hpp
  24. +9
    -4
      src/game/ant/trait/legs.hpp
  25. +11
    -5
      src/game/ant/trait/loader/antennae-loader.cpp
  26. +12
    -19
      src/game/ant/trait/loader/body-size-loader.cpp
  27. +3
    -6
      src/game/ant/trait/loader/cocoon-loader.cpp
  28. +2
    -1
      src/game/ant/trait/loader/egg-loader.cpp
  29. +32
    -25
      src/game/ant/trait/loader/eyes-loader.cpp
  30. +7
    -1
      src/game/ant/trait/loader/gaster-loader.cpp
  31. +15
    -14
      src/game/ant/trait/loader/head-loader.cpp
  32. +7
    -6
      src/game/ant/trait/loader/larva-loader.cpp
  33. +12
    -6
      src/game/ant/trait/loader/legs-loader.cpp
  34. +16
    -10
      src/game/ant/trait/loader/mandibles-loader.cpp
  35. +19
    -13
      src/game/ant/trait/loader/mesosoma-loader.cpp
  36. +24
    -30
      src/game/ant/trait/loader/ocelli-loader.cpp
  37. +2
    -1
      src/game/ant/trait/loader/pigmentation-loader.cpp
  38. +2
    -2
      src/game/ant/trait/loader/pilosity-loader.cpp
  39. +5
    -8
      src/game/ant/trait/loader/sting-loader.cpp
  40. +43
    -42
      src/game/ant/trait/loader/waist-loader.cpp
  41. +99
    -0
      src/game/ant/trait/loader/wings-loader.cpp
  42. +13
    -6
      src/game/ant/trait/mandibles.hpp
  43. +14
    -9
      src/game/ant/trait/mesosoma.hpp
  44. +3
    -1
      src/game/ant/trait/nest-site.hpp
  45. +9
    -9
      src/game/ant/trait/ocelli.hpp
  46. +1
    -1
      src/game/ant/trait/pigmentation.hpp
  47. +1
    -1
      src/game/ant/trait/pilosity.hpp
  48. +1
    -1
      src/game/ant/trait/sculpturing.hpp
  49. +13
    -7
      src/game/ant/trait/size-variation.hpp
  50. +19
    -11
      src/game/ant/trait/waist.hpp
  51. +28
    -13
      src/game/ant/trait/wings.hpp
  52. +32
    -81
      src/game/load.cpp
  53. +1
    -1
      src/game/state/boot.cpp
  54. +1
    -0
      src/game/state/gamepad-config-menu.hpp
  55. +53
    -82
      src/game/state/nest-selection.cpp
  56. +0
    -80
      src/game/state/nuptial-flight.cpp
  57. +0
    -1
      src/game/state/splash.cpp
  58. +34
    -96
      src/game/system/terrain.cpp
  59. +4
    -4
      src/game/system/terrain.hpp
  60. +9
    -9
      src/geom/hyperoctree.hpp
  61. +17
    -14
      src/geom/mesh.cpp
  62. +89
    -73
      src/geom/mesh.hpp
  63. +5
    -5
      src/geom/primitive/intersection.hpp
  64. +83
    -77
      src/math/matrix.hpp
  65. +48
    -48
      src/math/quaternion.hpp
  66. +137
    -137
      src/math/vector.hpp
  67. +1
    -0
      src/render/renderer.cpp
  68. +9
    -9
      src/resources/image.hpp

+ 0
- 1
CMakeLists.txt View File

@ -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)

+ 1
- 1
src/application.cpp View File

@ -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);
}

+ 1
- 1
src/color/xyy.hpp View File

@ -34,7 +34,7 @@ namespace xyy {
* @return return Luminance of @p x.
*/
template <class T>
constexpr inline T luminance(const math::vector3<T>& x)
inline constexpr T luminance(const math::vector3<T>& x)
{
return x[2];
}

+ 1
- 1
src/color/xyz.hpp View File

@ -38,7 +38,7 @@ namespace xyz {
* @return return Luminance of @p x.
*/
template <class T>
constexpr inline T luminance(const math::vector3<T>& x)
inline constexpr T luminance(const math::vector3<T>& x)
{
return x[1];
}

+ 0
- 82
src/game/ant/breed.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

src/game/ant/founding-mode.hpp → src/game/ant/caste-type.hpp View File

@ -17,19 +17,33 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#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

+ 63
- 6
src/game/ant/caste.hpp View File

@ -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 <optional>
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

+ 444
- 508
src/game/ant/morphogenesis.cpp
File diff suppressed because it is too large
View File


+ 3
- 4
src/game/ant/morphogenesis.hpp View File

@ -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

+ 78
- 0
src/game/ant/species.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <optional>
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<caste> queen_caste;
/// Worker caste description.
std::optional<caste> worker_caste;
/// Soldier caste description.
std::optional<caste> soldier_caste;
/// Male caste description.
std::optional<caste> 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

src/game/ant/subcaste.hpp → src/game/ant/subcaste-type.hpp View File

@ -17,43 +17,43 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#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

+ 10
- 4
src/game/ant/trait/antennae.hpp View File

@ -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

src/game/ant/trait/nest.hpp → src/game/ant/trait/body-size.hpp View File

@ -17,26 +17,24 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#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

+ 4
- 4
src/game/ant/trait/cocoon.hpp View File

@ -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

+ 1
- 1
src/game/ant/trait/diet.hpp View File

@ -25,7 +25,7 @@ namespace ant {
namespace trait {
/**
* Trait that describes the diet of an ant.
* Ant diet description.
*/
struct diet
{

+ 1
- 1
src/game/ant/trait/egg.hpp View File

@ -27,7 +27,7 @@ namespace ant {
namespace trait {
/**
* Trait that describes the eggs of an ant species.
* Ant egg description.
*/
struct egg
{

+ 15
- 7
src/game/ant/trait/eyes.hpp View File

@ -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

+ 1
- 1
src/game/ant/trait/foraging-time.hpp View File

@ -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
{

+ 0
- 51
src/game/ant/trait/forewings.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

+ 48
- 0
src/game/ant/trait/founding-mode.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

+ 6
- 1
src/game/ant/trait/gaster.hpp View File

@ -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

+ 11
- 8
src/game/ant/trait/head.hpp View File

@ -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

+ 4
- 4
src/game/ant/trait/larva.hpp View File

@ -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

+ 9
- 4
src/game/ant/trait/legs.hpp View File

@ -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

+ 11
- 5
src/game/ant/trait/loader/antennae-loader.cpp View File

@ -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<render::model>(model_element->get<std::string>());
// 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<float>();
// Parse total antennomere count
if (auto element = antennae_element->find("total_antennomere_count"); element != antennae_element->end())
antennae->total_antennomere_count = element->get<int>();
// Parse club antennomere count
if (auto element = antennae_element->find("club_antennomere_count"); element != antennae_element->end())
antennae->club_antennomere_count = element->get<int>();
// Free JSON data
delete data;

src/game/ant/trait/loader/nest-loader.cpp → src/game/ant/trait/loader/body-size-loader.cpp View File

@ -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 <stdexcept>
using namespace game::ant;
template <>
trait::nest* resource_loader<trait::nest>::load(resource_manager* resource_manager, PHYSFS_File* file, const std::filesystem::path& path)
trait::body_size* resource_loader<trait::body_size>::load(resource_manager* resource_manager, PHYSFS_File* file, const std::filesystem::path& path)
{
// Load JSON data
json* data = resource_loader<json>::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<std::string>();
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<float>();
// Free JSON data
delete data;
return nest;
return body_size;
}

+ 3
- 6
src/game/ant/trait/loader/cocoon-loader.cpp View File

@ -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<bool>();
@ -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<render::model>(model_element->get<std::string>());
}
else
{
cocoon->model = nullptr;
}
// Free JSON data
delete data;

+ 2
- 1
src/game/ant/trait/loader/egg-loader.cpp View File

@ -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");

+ 32
- 25
src/game/ant/trait/loader/eyes-loader.cpp View File

@ -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<bool>();
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<render::model>(model_element->get<std::string>());
// Parse length
if (auto element = eyes_element->find("length"); element != eyes_element->end())
eyes->length = element->get<float>();
// Parse width
if (auto element = eyes_element->find("width"); element != eyes_element->end())
eyes->width = element->get<float>();
// Parse height
if (auto element = eyes_element->find("height"); element != eyes_element->end())
eyes->height = element->get<float>();
// Parse ommatidia count
if (auto element = eyes_element->find("ommatidia_count"); element != eyes_element->end())
eyes->ommatidia_count = element->get<int>();
}
// 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<float>();
// 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<float>();
// Parse eyes ommatidia
eyes->ommatidia = 0;
if (auto ommatidia_element = eyes_element->find("ommatidia"); ommatidia_element != eyes_element->end())
eyes->ommatidia = ommatidia_element->get<int>();
// Free JSON data
delete data;

+ 7
- 1
src/game/ant/trait/loader/gaster-loader.cpp View File

@ -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<render::model>(model_element->get<std::string>());
// Parse phragmosis
if (auto element = gaster_element->find("phragmosis"); element != gaster_element->end())
gaster->phragmosis = element->get<float>();
// Free JSON data
delete data;

+ 15
- 14
src/game/ant/trait/loader/head-loader.cpp View File

@ -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<render::model>(model_element->get<std::string>());
// 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<float>();
// Parse length
if (auto element = head_element->find("length"); element != head_element->end())
head->length = element->get<float>();
// 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<float>();
// Parse width
if (auto element = head_element->find("width"); element != head_element->end())
head->width = element->get<float>();
// Parse head phragmotic
head->phragmotic = false;
if (auto phragmotic_element = head_element->find("phragmotic"); phragmotic_element != head_element->end())
head->phragmotic = phragmotic_element->get<bool>();
// Parse phragmosis
if (auto element = head_element->find("phragmosis"); element != head_element->end())
head->phragmosis = element->get<float>();
// Free JSON data
delete data;

+ 7
- 6
src/game/ant/trait/loader/larva-loader.cpp View File

@ -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<render::model>(model_element->get<std::string>());
// Parse larva instars
larva->instars = 0;
if (auto instars_element = larva_element->find("instars"); instars_element != larva_element->end())
larva->instars = instars_element->get<int>();
// Parse instars
if (auto element = larva_element->find("instars"); element != larva_element->end())
larva->instars = element->get<int>();
// Free JSON data
delete data;

+ 12
- 6
src/game/ant/trait/loader/legs-loader.cpp View File

@ -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<render::model>(model_element->get<std::string>());
// 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<float>();
// Parse speed
if (auto element = legs_element->find("speed"); element != legs_element->end())
legs->speed = element->get<float>();
// Parse grip
if (auto element = legs_element->find("grip"); element != legs_element->end())
legs->grip = element->get<float>();
// Free JSON data
delete data;

+ 16
- 10
src/game/ant/trait/loader/mandibles-loader.cpp View File

@ -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<render::model>(model_element->get<std::string>());
// 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<float>();
// Parse length
if (auto element = mandibles_element->find("length"); element != mandibles_element->end())
mandibles->length = element->get<float>();
// Parse apical dental count
if (auto element = mandibles_element->find("apical_dental_count"); element != mandibles_element->end())
mandibles->apical_dental_count = element->get<int>();
// Parse mandibles locking
mandibles->locking = false;
if (auto locking_element = mandibles_element->find("locking"); locking_element != mandibles_element->end())
mandibles->locking = locking_element->get<bool>();
// Parse basal dental count
if (auto element = mandibles_element->find("basal_dental_count"); element != mandibles_element->end())
mandibles->basal_dental_count = element->get<int>();
// Free JSON data
delete data;

+ 19
- 13
src/game/ant/trait/loader/mesosoma-loader.cpp View File

@ -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<render::model>(model_element->get<std::string>());
// 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<float>();
// Parse pronotum width
if (auto element = mesosoma_element->find("pronotum_width"); element != mesosoma_element->end())
mesosoma->pronotum_width = element->get<float>();
// 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<float>();
// Parse pronotum spinescence
if (auto element = mesosoma_element->find("pronotum_spinescence"); element != mesosoma_element->end())
mesosoma->pronotum_spinescence = element->get<float>();
// 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<float>();
// Parse mesonotum spinescence
if (auto element = mesosoma_element->find("mesonotum_spinescence"); element != mesosoma_element->end())
mesosoma->mesonotum_spinescence = element->get<float>();
// Parse propodeum spinescence
if (auto element = mesosoma_element->find("propodeum_spinescence"); element != mesosoma_element->end())
mesosoma->propodeum_spinescence = element->get<float>();
// Free JSON data
delete data;

+ 24
- 30
src/game/ant/trait/loader/ocelli-loader.cpp View File

@ -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<bool>();
// Parse lateral ocelli present
if (auto element = ocelli_element->find("lateral_ocelli_present"); element != ocelli_element->end())
ocelli->lateral_ocelli_present = element->get<bool>();
// 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<bool>();
// Parse median ocellus present
if (auto element = ocelli_element->find("median_ocellus_present"); element != ocelli_element->end())
ocelli->median_ocellus_present = element->get<bool>();
// 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<float>();
// 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<float>();
// Parse width
if (auto element = ocelli_element->find("width"); element != ocelli_element->end())
ocelli->width = element->get<float>();
// 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<float>();
// 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<render::model>(lateral_ocelli_model_element->get<std::string>());
}
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<render::model>(median_ocellus_model_element->get<std::string>());
}
else
{
ocelli->median_ocellus_model = nullptr;
}
// Free JSON data
delete data;

+ 2
- 1
src/game/ant/trait/loader/pigmentation-loader.cpp View File

@ -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");

+ 2
- 2
src/game/ant/trait/loader/pilosity-loader.cpp View File

@ -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<float>();

+ 5
- 8
src/game/ant/trait/loader/sting-loader.cpp View File

@ -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<bool>();
if (auto element = sting_element->find("present"); element != sting_element->end())
sting->present = element->get<bool>();
// 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<render::model>(model_element->get<std::string>());
}
else
{
sting->model = nullptr;
}
// Free JSON data
delete data;

+ 43
- 42
src/game/ant/trait/loader/waist-loader.cpp View File

@ -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<render::model>(model_element->get<std::string>());
// 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<float>();
// 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<float>();
// 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<float>();
// 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<float>();
// Parse waist postpetiole
waist->postpetiole = false;
if (auto postpetiole_element = waist_element->find("postpetiole"); postpetiole_element != waist_element->end())
waist->postpetiole = postpetiole_element->get<bool>();
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<bool>();
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<float>();
// Parse petiole properties
if (auto element = waist_element->find("petiole_length"); element != waist_element->end())
waist->petiole_length = element->get<float>();
if (auto element = waist_element->find("petiole_width"); element != waist_element->end())
waist->petiole_width = element->get<float>();
if (auto element = waist_element->find("petiole_height"); element != waist_element->end())
waist->petiole_height = element->get<float>();
if (auto element = waist_element->find("petiole_spinescence"); element != waist_element->end())
waist->petiole_spinescence = element->get<float>();
// Parse postpetiole present
if (auto element = waist_element->find("postpetiole_present"); element != waist_element->end())
waist->postpetiole_present = element->get<bool>();
if (waist->postpetiole_present)
{
// Parse postpetiole properties
if (auto element = waist_element->find("postpetiole_length"); element != waist_element->end())
waist->postpetiole_length = element->get<float>();
if (auto element = waist_element->find("postpetiole_width"); element != waist_element->end())
waist->postpetiole_width = element->get<float>();
if (auto element = waist_element->find("postpetiole_height"); element != waist_element->end())
waist->postpetiole_height = element->get<float>();
if (auto element = waist_element->find("postpetiole_spinescence"); element != waist_element->end())
waist->postpetiole_spinescence = element->get<float>();
}
// 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<float>();
// 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<float>();
// 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<render::model>(model_element->get<std::string>());
}
// Free JSON data

+ 99
- 0
src/game/ant/trait/loader/wings-loader.cpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <stdexcept>
using namespace game::ant;
template <>
trait::wings* resource_loader<trait::wings>::load(resource_manager* resource_manager, PHYSFS_File* file, const std::filesystem::path& path)
{
// Load JSON data
json* data = resource_loader<json>::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<bool>();
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<render::model>(forewings_model_element->get<std::string>());
// 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<render::model>(hindwings_model_element->get<std::string>());
// Parse forewing length
if (auto element = wings_element->find("forewing_length"); element != wings_element->end())
wings->forewing_length = element->get<float>();
// Parse forewing width
if (auto element = wings_element->find("forewing_width"); element != wings_element->end())
wings->forewing_width = element->get<float>();
// Parse forewing venation
if (auto element = wings_element->find("forewing_venation"); element != wings_element->end())
wings->forewing_venation = element->get<float>();
// Parse hindwing length
if (auto element = wings_element->find("hindwing_length"); element != wings_element->end())
wings->hindwing_length = element->get<float>();
// Parse hindwing width
if (auto element = wings_element->find("hindwing_width"); element != wings_element->end())
wings->hindwing_width = element->get<float>();
// Parse hindwing venation
if (auto element = wings_element->find("hindwing_venation"); element != wings_element->end())
wings->hindwing_venation = element->get<float>();
}
// Free JSON data
delete data;
return wings;
}

+ 13
- 6
src/game/ant/trait/mandibles.hpp View File

@ -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

+ 14
- 9
src/game/ant/trait/mesosoma.hpp View File

@ -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

src/game/ant/nest-site.hpp → src/game/ant/trait/nest-site.hpp View File

@ -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

+ 9
- 9
src/game/ant/trait/ocelli.hpp View File

@ -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

+ 1
- 1
src/game/ant/trait/pigmentation.hpp View File

@ -27,7 +27,7 @@ namespace ant {
namespace trait {
/**
* Trait that describes the pigmentation of an ant.
* Ant pigmentation description.
*/
struct pigmentation
{

+ 1
- 1
src/game/ant/trait/pilosity.hpp View File

@ -25,7 +25,7 @@ namespace ant {
namespace trait {
/**
* Trait that describes the pilosity of an ant.
* Ant pilosity description.
*/
struct pilosity
{

+ 1
- 1
src/game/ant/trait/sculpturing.hpp View File

@ -27,7 +27,7 @@ namespace ant {
namespace trait {
/**
* Trait that describes the surface sculpturing of an ant.
* Ant surface sculpturing description.
*/
struct sculpturing
{

src/game/ant/trait/size.hpp → src/game/ant/trait/size-variation.hpp View File

@ -17,24 +17,30 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#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<std::tuple<float, float>> 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

+ 19
- 11
src/game/ant/trait/waist.hpp View File

@ -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

src/game/ant/trait/hindwings.hpp → src/game/ant/trait/wings.hpp View File

@ -17,8 +17,8 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#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

+ 32
- 81
src/game/load.cpp View File

@ -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<math::vector<std::uint32_t, 2>(*)(const math::vector<float, 2>&)>(math::hash::pcg);
auto noise = static_cast<float(*)(const math::vector<float, 2>&, 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<float>(width - 1) * frequency;
float scale_y = 1.0f / static_cast<float>(height - 1) * frequency;
std::for_each
(
std::execution::par_unseq,
img.begin<unsigned char>(),
img.end<unsigned char>(),
[pixels, width, height, scale_x, scale_y, &fbm](auto& pixel)
img.begin<math::vector<unsigned char, 4>>(),
img.end<math::vector<unsigned char, 4>>(),
[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<unsigned char, 4>*)pixels;
const std::size_t y = i / width;
const std::size_t x = i % width;
float2 position =
const float2 position =
{
static_cast<float>(x) * scale_x,
static_cast<float>(y) * scale_y
};
//float n = math::noise::simplex<float, 2>(position, &math::noise::hash::pcg3d_1);
//float n = fbm(position);
// auto [sqr_center_distance, displacement, id, sqr_edge_distance] = math::noise::voronoi::f1_edge<float, std::uint32_t>(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<float, 2>(position);
f1_id
] = math::noise::voronoi::f1<float, 2>(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<unsigned char>(std::min(255.0f, f1_distance * 255.0f));
//pixel = static_cast<unsigned char>(id % 255);
const float2 uv = (position + f1_displacement) / frequency;
pixel =
{
static_cast<unsigned char>(std::min(255.0f, f1_distance * 255.0f)),
static_cast<unsigned char>(std::min(255.0f, uv[0] * 255.0f)),
static_cast<unsigned char>(std::min(255.0f, uv[1] * 255.0f)),
static_cast<unsigned char>(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;
}

+ 1
- 1
src/game/state/boot.cpp View File

@ -888,7 +888,7 @@ void boot::setup_systems()
ctx.blackbody_system->set_illuminant(color::illuminant::deg2::d55<double>);
// 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);

+ 1
- 0
src/game/state/gamepad-config-menu.hpp View File

@ -22,6 +22,7 @@
#include "game/state/base.hpp"
#include "input/control.hpp"
#include <string>
namespace game {
namespace state {

+ 53
- 82
src/game/state/nest-selection.cpp View File

@ -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 <iostream>
#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<ant::trait::antennae>("pogonomyrmex-female-antennae.dna");
worker_caste.eyes = ctx.resource_manager->load<ant::trait::eyes>("pogonomyrmex-eyes.dna");
worker_caste.gaster = ctx.resource_manager->load<ant::trait::gaster>("pogonomyrmex-worker-gaster.dna");
worker_caste.head = ctx.resource_manager->load<ant::trait::head>("pogonomyrmex-head.dna");
worker_caste.legs = ctx.resource_manager->load<ant::trait::legs>("pogonomyrmex-legs.dna");
worker_caste.mandibles = ctx.resource_manager->load<ant::trait::mandibles>("pogonomyrmex-mandibles.dna");
worker_caste.mesosoma = ctx.resource_manager->load<ant::trait::mesosoma>("pogonomyrmex-worker-mesosoma.dna");
worker_caste.ocelli = ctx.resource_manager->load<ant::trait::ocelli>("ocelli-absent.dna");
worker_caste.pigmentation = ctx.resource_manager->load<ant::trait::pigmentation>("rust-pigmentation.dna");
worker_caste.sculpturing = ctx.resource_manager->load<ant::trait::sculpturing>("politus-sculpturing.dna");
//worker_caste.size_variation = ctx.resource_manager->load<ant::trait::size_variation>(...);
worker_caste.sting = ctx.resource_manager->load<ant::trait::sting>("pogonomyrmex-sting.dna");
worker_caste.waist = ctx.resource_manager->load<ant::trait::waist>("pogonomyrmex-waist.dna");
worker_caste.wings = ctx.resource_manager->load<ant::trait::wings>("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<float>::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<component::transform>(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<component::model>(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<entity::archetype>("ruler-10cm.ent");
ruler_archetype->create(*ctx.entity_registry);
auto color_checker_archetype = ctx.resource_manager->load<entity::archetype>("color-checker.ent");
color_checker_archetype->create(*ctx.entity_registry);
// auto ruler_archetype = ctx.resource_manager->load<entity::archetype>("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<float>(ctx.loop.get_update_period()));
ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() + 0.5f * static_cast<float>(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<float>(ctx.loop.get_update_period()));
ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() - 0.5f * static_cast<float>(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

+ 0
- 80
src/game/state/nuptial-flight.cpp View File

@ -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 <iostream>
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)

+ 0
- 1
src/game/state/splash.cpp View File

@ -30,7 +30,6 @@
#include "resources/resource-manager.hpp"
#include "render/material-flags.hpp"
#include "math/linear-algebra.hpp"
#include <iostream>
namespace game {
namespace state {

+ 34
- 96
src/game/system/terrain.cpp View File

@ -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<quadtree_node_type>(std::exp2(i));
}
registry.on_construct<component::terrain>().connect<&terrain::on_terrain_construct>(this);
registry.on_update<component::terrain>().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<quadtree_node_type>((x / patch_side_length) + quadtree.resolution / 4);
quadtree_node_type node_y = static_cast<quadtree_node_type>((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<quadtree_node_type>(x / node_size + node_resolution / 2);
quadtree_node_type node_y = static_cast<quadtree_node_type>(z / node_size + node_resolution / 2);
quadtree_node_type node_location = geom::morton::encode<quadtree_node_type>(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<float>& 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<float> node_bounds;
node_bounds.min_point =
{
node_center.x() - node_size * 0.5f,
-std::numeric_limits<float>::infinity(),
node_center.z() - node_size * 0.5f
};
node_bounds.max_point =
{
node_bounds.min_point.x() + node_size,
std::numeric_limits<float>::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<quadtree_node_type> 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<quadtree_node_type>(x + 1, y + 1)));
if (y < parent_resolution - 1)
node_stack.push(quadtree.node(parent_depth, geom::morton::encode<quadtree_node_type>(x + 1, y + 1)));
if (y > 0)
nodes.insert(quadtree.node(depth, geom::morton::encode<quadtree_node_type>(x + 1, y - 1)));
node_stack.push(quadtree.node(parent_depth, geom::morton::encode<quadtree_node_type>(x + 1, y - 1)));
}
if (x > 0)
{
if (y < (quadtree.resolution / 4) - 1)
nodes.insert(quadtree.node(depth, geom::morton::encode<quadtree_node_type>(x - 1, y + 1)));
if (y < parent_resolution - 1)
node_stack.push(quadtree.node(parent_depth, geom::morton::encode<quadtree_node_type>(x - 1, y + 1)));
if (y > 0)
nodes.insert(quadtree.node(depth, geom::morton::encode<quadtree_node_type>(x - 1, y - 1)));
node_stack.push(quadtree.node(parent_depth, geom::morton::encode<quadtree_node_type>(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<float>(patch_subdivisions + 1);
const float half_cell_size = cell_size * 0.5f;
// Init patch bounds
geom::aabb<float> 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;
}

+ 4
- 4
src/game/system/terrain.hpp View File

@ -33,6 +33,7 @@
#include "scene/collection.hpp"
#include "geom/view-frustum.hpp"
#include <unordered_map>
#include <stack>
namespace game {
namespace system {
@ -103,10 +104,6 @@ private:
void rebuild_patch_base_mesh();
void visit_quadtree(const geom::bounding_volume<float>& 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<quadtree_node_type, patch*> patches;
std::stack<quadtree_node_type> node_stack;
};
} // namespace system

+ 9
- 9
src/geom/hyperoctree.hpp View File

@ -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<node_type>(max_depth + 1);
static constexpr node_type resolution = math::compile::exp2<node_type>(max_depth);
/// Number of nodes in a full hyperoctree.
static constexpr std::size_t max_node_count = (math::compile::pow<std::size_t>(resolution, N) - 1) / siblings_per_node;
static constexpr std::size_t max_node_count = (math::compile::pow<std::size_t>(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<node_type>(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;
}

+ 17
- 14
src/geom/mesh.cpp View File

@ -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;
}

+ 89
- 73
src/geom/mesh.hpp View File

@ -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<edge*> 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<mesh::vertex*>& get_vertices() const;
/// Returns the mesh edges
/// Returns the mesh edges.
const std::vector<mesh::edge*>& get_edges() const;
/// Returns the mesh faces
/// Returns the mesh faces.
const std::vector<mesh::face*>& 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;

+ 5
- 5
src/geom/primitive/intersection.hpp View File

@ -54,7 +54,7 @@ constexpr std::optional intersection(const ray& ray, const hyperplane
}
template <class T, std::size_t N>
constexpr inline std::optional<T> intersection(const hyperplane<T, N>& hyperplane, const ray<T, N>& ray) noexcept
inline constexpr std::optional<T> intersection(const hyperplane<T, N>& hyperplane, const ray<T, N>& ray) noexcept
{
return intersection<T, N>(ray, hyperplane);
}
@ -98,7 +98,7 @@ constexpr std::optional> intersection(const ray& ray, con
}
template <class T, std::size_t N>
constexpr inline std::optional<std::tuple<T, T>> intersection(const hyperrectangle<T, N>& hyperrectangle, const ray<T, N>& ray) noexcept
inline constexpr std::optional<std::tuple<T, T>> intersection(const hyperrectangle<T, N>& hyperrectangle, const ray<T, N>& ray) noexcept
{
return intersection<T, N>(ray, hyperrectangle);
}
@ -145,7 +145,7 @@ std::optional> intersection(const ray& ray, const hypersp
* @return `true` if an intersection occurred, `false` otherwise.
*/
template <class T, std::size_t N>
constexpr inline bool intersection(const hyperrectangle<T, N>& a, const hyperrectangle<T, N>& b) noexcept
inline constexpr bool intersection(const hyperrectangle<T, N>& a, const hyperrectangle<T, N>& b) noexcept
{
return a.intersects(b);
}
@ -181,7 +181,7 @@ constexpr bool intersection(const hyperrectangle& hyperrectangle, const hy
}
template <class T, std::size_t N>
constexpr inline bool intersection(const hypersphere<T, N>& hypersphere, const hyperrectangle<T, N>& hyperrectangle) noexcept
inline constexpr bool intersection(const hypersphere<T, N>& hypersphere, const hyperrectangle<T, N>& hyperrectangle) noexcept
{
return intersection<T, N>(hyperrectangle, hypersphere);
}
@ -196,7 +196,7 @@ constexpr inline bool intersection(const hypersphere& hypersphere, const h
* @return `true` if an intersection occurred, `false` otherwise.
*/
template <class T, std::size_t N>
constexpr inline bool intersection(const hypersphere<T, N>& a, const hypersphere<T, N>& b) noexcept
inline constexpr bool intersection(const hypersphere<T, N>& a, const hypersphere<T, N>& b) noexcept
{
return a.intersects(b);
}

+ 83
- 77
src/math/matrix.hpp View File

@ -42,16 +42,16 @@ namespace math {
template <typename T, std::size_t N, std::size_t M>
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 <class U, std::size_t... I>
constexpr inline matrix<U, N, M> type_cast(std::index_sequence<I...>) const noexcept
inline constexpr matrix<U, N, M> type_cast(std::index_sequence<I...>) const noexcept
{
return {vector<U, M>(columns[I])...};
}
@ -81,14 +81,14 @@ struct matrix
* @return Matrix containing the type-casted elements.
*/
template <class U>
constexpr inline explicit operator matrix<U, N, M>() const noexcept
inline constexpr explicit operator matrix<U, N, M>() const noexcept
{
return type_cast<U>(std::make_index_sequence<N>{});
}
/// @private
template <std::size_t P, std::size_t O, std::size_t... I>
constexpr inline matrix<T, P, O> size_cast(std::index_sequence<I...>) const noexcept
inline constexpr matrix<T, P, O> size_cast(std::index_sequence<I...>) const noexcept
{
if constexpr (O == M)
return {((I < N) ? columns[I] : matrix<T, P, O>::identity()[I]) ...};
@ -105,7 +105,7 @@ struct matrix
* @return *p* by *o* matrix.
*/
template <std::size_t P, std::size_t O>
constexpr inline explicit operator matrix<T, P, O>() const noexcept
inline constexpr explicit operator matrix<T, P, O>() const noexcept
{
return size_cast<P, O>(std::make_index_sequence<P>{});
}
@ -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<column_vector_type*> rbegin() noexcept
inline constexpr std::reverse_iterator<column_vector_type*> rbegin() noexcept
{
return std::reverse_iterator<column_vector_type*>(columns + column_count);
}
constexpr inline std::reverse_iterator<const column_vector_type*> rbegin() const noexcept
inline constexpr std::reverse_iterator<const column_vector_type*> rbegin() const noexcept
{
return std::reverse_iterator<const column_vector_type*>(columns + column_count);
}
constexpr inline std::reverse_iterator<const column_vector_type*> crbegin() const noexcept
inline constexpr std::reverse_iterator<const column_vector_type*> crbegin() const noexcept
{
return std::reverse_iterator<const column_vector_type*>(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<column_vector_type*> rend() noexcept
inline constexpr std::reverse_iterator<column_vector_type*> rend() noexcept
{
return std::reverse_iterator<column_vector_type*>(columns);
}
constexpr inline std::reverse_iterator<const column_vector_type*> rend() const noexcept
inline constexpr std::reverse_iterator<const column_vector_type*> rend() const noexcept
{
return std::reverse_iterator<const column_vector_type*>(columns);
}
constexpr inline std::reverse_iterator<const column_vector_type*> crend() const noexcept
inline constexpr std::reverse_iterator<const column_vector_type*> crend() const noexcept
{
return std::reverse_iterator<const column_vector_type*>(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 <std::size_t... I>
static constexpr inline matrix one(std::index_sequence<I...>) noexcept
static inline constexpr matrix one(std::index_sequence<I...>) noexcept
{
//return {column_vector_type::one() ...};
@ -331,14 +331,14 @@ struct matrix
/// @private
template <std::size_t... I>
static constexpr inline column_vector_type identity_column(std::size_t i, std::index_sequence<I...>) noexcept
static inline constexpr column_vector_type identity_column(std::size_t i, std::index_sequence<I...>) noexcept
{
return {(I == i ? T{1} : T{0}) ...};
}
/// @private
template <std::size_t... I>
static constexpr inline matrix identity(std::index_sequence<I...>) noexcept
static inline constexpr matrix identity(std::index_sequence<I...>) noexcept
{
return {identity_column(I, std::make_index_sequence<row_count>{}) ...};
}
@ -670,7 +670,7 @@ constexpr matrix transpose(const matrix& m) noexcept;
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> add(const matrix<T, N, M>& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> add(const matrix<T, N, M>& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
{
return {(a[I] + b[I]) ...};
}
@ -683,7 +683,7 @@ constexpr matrix add(const matrix& a, const matrix& b
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> add(const matrix<T, N, M>& a, T b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> add(const matrix<T, N, M>& a, T b, std::index_sequence<I...>) 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<N>{});
}
/// @private
template <class T>
constexpr T determinant(const matrix<T, 2, 2>& m) noexcept
{
@ -702,6 +703,7 @@ constexpr T determinant(const matrix& m) noexcept
m[0][1] * m[1][0];
}
/// @private
template <class T>
constexpr T determinant(const matrix<T, 3, 3>& m) noexcept
{
@ -714,6 +716,7 @@ constexpr T determinant(const matrix& m) noexcept
m[0][2] * m[1][1] * m[2][0];
}
/// @private
template <class T>
constexpr T determinant(const matrix<T, 4, 4>& m) noexcept
{
@ -734,7 +737,7 @@ constexpr T determinant(const matrix& m) noexcept
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> componentwise_mul(const matrix<T, N, M>& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> componentwise_mul(const matrix<T, N, M>& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
{
return {(a[I] * b[I]) ...};
}
@ -747,7 +750,7 @@ constexpr matrix componentwise_mul(const matrix& a, const matr
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> div(const matrix<T, N, M>& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> div(const matrix<T, N, M>& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
{
return {(a[I] / b[I]) ...};
}
@ -760,7 +763,7 @@ constexpr matrix div(const matrix& a, const matrix& b
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> div(const matrix<T, N, M>& a, T b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> div(const matrix<T, N, M>& a, T b, std::index_sequence<I...>) noexcept
{
return {(a[I] / b) ...};
}
@ -773,7 +776,7 @@ constexpr matrix div(const matrix& a, T b) noexcept
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> div(T a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> div(T a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
{
return {(a / b[I]) ...};
}
@ -785,33 +788,34 @@ constexpr matrix div(T a, const matrix& b) noexcept
}
template<std::size_t I, class T, std::size_t N, std::size_t M>
constexpr inline typename matrix<T, N, M>::column_vector_type& get(math::matrix<T, N, M>& m) noexcept
inline constexpr typename matrix<T, N, M>::column_vector_type& get(math::matrix<T, N, M>& m) noexcept
{
static_assert(I < N);
return m.columns[I];
}
template<std::size_t I, class T, std::size_t N, std::size_t M>
constexpr inline typename matrix<T, N, M>::column_vector_type&& get(math::matrix<T, N, M>&& m) noexcept
inline constexpr typename matrix<T, N, M>::column_vector_type&& get(math::matrix<T, N, M>&& m) noexcept
{
static_assert(I < N);
return std::move(m.columns[I]);
}
template<std::size_t I, class T, std::size_t N, std::size_t M>
constexpr inline const typename matrix<T, N, M>::column_vector_type& get(const math::matrix<T, N, M>& m) noexcept
inline constexpr const typename matrix<T, N, M>::column_vector_type& get(const math::matrix<T, N, M>& m) noexcept
{
static_assert(I < N);
return m.columns[I];
}
template<std::size_t I, class T, std::size_t N, std::size_t M>
constexpr inline const typename matrix<T, N, M>::column_vector_type&& get(const math::matrix<T, N, M>&& m) noexcept
inline constexpr const typename matrix<T, N, M>::column_vector_type&& get(const math::matrix<T, N, M>&& m) noexcept
{
static_assert(I < N);
return std::move(m.columns[I]);
}
/// @private
template <class T>
constexpr matrix<T, 2, 2> inverse(const matrix<T, 2, 2>& m) noexcept
{
@ -826,6 +830,7 @@ constexpr matrix inverse(const matrix& m) noexcept
};
}
/// @private
template <class T>
constexpr matrix<T, 3, 3> inverse(const matrix<T, 3, 3>& m) noexcept
{
@ -847,6 +852,7 @@ constexpr matrix inverse(const matrix& m) noexcept
};
}
/// @private
template <class T>
constexpr matrix<T, 4, 4> inverse(const matrix<T, 4, 4>& m) noexcept
{
@ -915,7 +921,7 @@ constexpr matrix mul(const matrix& a, const matrix& b
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> mul(const matrix<T, N, M>& a, T b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> mul(const matrix<T, N, M>& a, T b, std::index_sequence<I...>) noexcept
{
return {(a[I] * b) ...};
}
@ -928,7 +934,7 @@ constexpr matrix mul(const matrix& a, T b) noexcept
/// @private
template <typename T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline typename matrix<T, N, M>::column_vector_type mul(const matrix<T, N, M>& a, const typename matrix<T, N, M>::row_vector_type& b, std::index_sequence<I...>) noexcept
inline constexpr typename matrix<T, N, M>::column_vector_type mul(const matrix<T, N, M>& a, const typename matrix<T, N, M>::row_vector_type& b, std::index_sequence<I...>) noexcept
{
return ((a[I] * b[I]) + ...);
}
@ -941,7 +947,7 @@ constexpr typename matrix::column_vector_type mul(const matrix
/// @private
template <typename T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline typename matrix<T, N, M>::row_vector_type mul(const typename matrix<T, N, M>::column_vector_type& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
inline constexpr typename matrix<T, N, M>::row_vector_type mul(const typename matrix<T, N, M>::column_vector_type& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
{
return {dot(a, b[I]) ...};
}
@ -1029,7 +1035,7 @@ constexpr matrix scale(const matrix& m, const vector& v)
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> sub(const matrix<T, N, M>& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> sub(const matrix<T, N, M>& a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
{
return {(a[I] - b[I]) ...};
}
@ -1042,7 +1048,7 @@ constexpr matrix sub(const matrix& a, const matrix& b
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> sub(const matrix<T, N, M>& a, T b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> sub(const matrix<T, N, M>& a, T b, std::index_sequence<I...>) noexcept
{
return {(a[I] - b) ...};
}
@ -1055,7 +1061,7 @@ constexpr matrix sub(const matrix& a, T b) noexcept
/// @private
template <class T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, N, M> sub(T a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, N, M> sub(T a, const matrix<T, N, M>& b, std::index_sequence<I...>) noexcept
{
return {(a - b[I]) ...};
}
@ -1068,7 +1074,7 @@ constexpr matrix sub(T a, const matrix& b) noexcept
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline T trace(const matrix<T, N, N>& m, std::index_sequence<I...>) noexcept
inline constexpr T trace(const matrix<T, N, N>& m, std::index_sequence<I...>) noexcept
{
return ((m[I][I]) + ...);
}
@ -1093,14 +1099,14 @@ constexpr matrix translate(const matrix& m, const vector
/// @private
template <typename T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline typename matrix<T, M, N>::column_vector_type transpose_column(const matrix<T, N, M>& m, std::size_t i, std::index_sequence<I...>) noexcept
inline constexpr typename matrix<T, M, N>::column_vector_type transpose_column(const matrix<T, N, M>& m, std::size_t i, std::index_sequence<I...>) noexcept
{
return {m[I][i] ...};
}
/// @private
template <typename T, std::size_t N, std::size_t M, std::size_t... I>
constexpr inline matrix<T, M, N> transpose(const matrix<T, N, M>& m, std::index_sequence<I...>) noexcept
inline constexpr matrix<T, M, N> transpose(const matrix<T, N, M>& m, std::index_sequence<I...>) noexcept
{
return {transpose_column(m, I, std::make_index_sequence<N>{}) ...};
}
@ -1115,7 +1121,7 @@ namespace operators {
/// @copydoc add(const matrix<T, N, M>&, const matrix<T, N, M>&)
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator+(const matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M> operator+(const matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
{
return add(a, b);
}
@ -1123,12 +1129,12 @@ constexpr inline matrix operator+(const matrix& a, const matri
/// @copydoc add(const matrix<T, N, M>&, T)
/// @{
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator+(const matrix<T, N, M>& a, T b) noexcept
inline constexpr matrix<T, N, M> operator+(const matrix<T, N, M>& a, T b) noexcept
{
return add(a, b);
}
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator+(T a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M> operator+(T a, const matrix<T, N, M>& b) noexcept
{
return add(b, a);
}
@ -1136,28 +1142,28 @@ constexpr inline matrix operator+(T a, const matrix& b) noexce
/// @copydoc div(const matrix<T, N, M>&, const matrix<T, N, M>&)
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator/(const matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M> operator/(const matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
{
return div(a, b);
}
/// @copydoc div(const matrix<T, N, M>&, T)
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator/(const matrix<T, N, M>& a, T b) noexcept
inline constexpr matrix<T, N, M> operator/(const matrix<T, N, M>& a, T b) noexcept
{
return div(a, b);
}
/// @copydoc div(T, const matrix<T, N, M>&)
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator/(T a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M> operator/(T a, const matrix<T, N, M>& b) noexcept
{
return div(a, b);
}
/// @copydoc mul(const matrix<T, N, M>&, const matrix<T, P, N>&)
template <typename T, std::size_t N, std::size_t M, std::size_t P>
constexpr inline matrix<T, P, M> operator*(const matrix<T, N, M>& a, const matrix<T, P, N>& b) noexcept
inline constexpr matrix<T, P, M> operator*(const matrix<T, N, M>& a, const matrix<T, P, N>& b) noexcept
{
return mul(a, b);
}
@ -1165,12 +1171,12 @@ constexpr inline matrix operator*(const matrix& a, const matri
/// @copydoc mul(const matrix<T, N, M>&, T)
/// @{
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator*(const matrix<T, N, M>& a, T b) noexcept
inline constexpr matrix<T, N, M> operator*(const matrix<T, N, M>& a, T b) noexcept
{
return mul(a, b);
}
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator*(T a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M> operator*(T a, const matrix<T, N, M>& b) noexcept
{
return mul(b, a);
}
@ -1178,35 +1184,35 @@ constexpr inline matrix operator*(T a, const matrix& b) noexce
/// @copydoc mul(const matrix<T, N, M>&, const typename matrix<T, N, M>::row_vector_type&)
template <typename T, std::size_t N, std::size_t M>
constexpr inline typename matrix<T, N, M>::column_vector_type operator*(const matrix<T, N, M>& a, const typename matrix<T, N, M>::row_vector_type& b) noexcept
inline constexpr typename matrix<T, N, M>::column_vector_type operator*(const matrix<T, N, M>& a, const typename matrix<T, N, M>::row_vector_type& b) noexcept
{
return mul(a, b);
}
/// @copydoc mul(const typename matrix<T, N, M>::column_vector_type&, const matrix<T, N, M>&)
template <typename T, std::size_t N, std::size_t M>
constexpr inline typename matrix<T, N, M>::row_vector_type operator*(const typename matrix<T, N, M>::column_vector_type& a, const matrix<T, N, M>& b) noexcept
inline constexpr typename matrix<T, N, M>::row_vector_type operator*(const typename matrix<T, N, M>::column_vector_type& a, const matrix<T, N, M>& b) noexcept
{
return mul(a, b);
}
/// @copydoc sub(const matrix<T, N, M>&, const matrix<T, N, M>&)
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator-(const matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M> operator-(const matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
{
return sub(a, b);
}
/// @copydoc sub(const matrix<T, N, M>&, T)
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator-(const matrix<T, N, M>& a, T b) noexcept
inline constexpr matrix<T, N, M> operator-(const matrix<T, N, M>& a, T b) noexcept
{
return sub(a, b);
}
/// @copydoc sub(T, const matrix<T, N, M>&)
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M> operator-(T a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M> operator-(T a, const matrix<T, N, M>& b) noexcept
{
return sub(a, b);
}
@ -1221,12 +1227,12 @@ constexpr inline matrix operator-(T a, const matrix& b) noexce
*/
/// @{
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M>& operator+=(matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M>& operator+=(matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
{
return (a = a + b);
}
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M>& operator+=(matrix<T, N, M>& a, T b) noexcept
inline constexpr matrix<T, N, M>& operator+=(matrix<T, N, M>& a, T b) noexcept
{
return (a = a + b);
}
@ -1242,12 +1248,12 @@ constexpr inline matrix& operator+=(matrix& a, T b) noexcept
*/
/// @{
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M>& operator-=(matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M>& operator-=(matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
{
return (a = a - b);
}
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M>& operator-=(matrix<T, N, M>& a, T b) noexcept
inline constexpr matrix<T, N, M>& operator-=(matrix<T, N, M>& a, T b) noexcept
{
return (a = a - b);
}
@ -1263,12 +1269,12 @@ constexpr inline matrix& operator-=(matrix& a, T b) noexcept
*/
/// @{
template <class T, std::size_t N>
constexpr inline matrix<T, N, N>& operator*=(matrix<T, N, N>& a, const matrix<T, N, N>& b) noexcept
inline constexpr matrix<T, N, N>& operator*=(matrix<T, N, N>& a, const matrix<T, N, N>& b) noexcept
{
return (a = a * b);
}
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M>& operator*=(matrix<T, N, M>& a, T b) noexcept
inline constexpr matrix<T, N, M>& operator*=(matrix<T, N, M>& a, T b) noexcept
{
return (a = a * b);
}
@ -1284,12 +1290,12 @@ constexpr inline matrix& operator*=(matrix& a, T b) noexcept
*/
/// @{
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M>& operator/=(matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
inline constexpr matrix<T, N, M>& operator/=(matrix<T, N, M>& a, const matrix<T, N, M>& b) noexcept
{
return (a = a / b);
}
template <class T, std::size_t N, std::size_t M>
constexpr inline matrix<T, N, M>& operator/=(matrix<T, N, M>& a, T b) noexcept
inline constexpr matrix<T, N, M>& operator/=(matrix<T, N, M>& a, T b) noexcept
{
return (a = a / b);
}

+ 48
- 48
src/math/quaternion.hpp View File

@ -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 <class U>
constexpr inline explicit operator quaternion<U>() const noexcept
inline constexpr explicit operator quaternion<U>() const noexcept
{
return {static_cast<U>(r), vector<U, 3>(i)};
}
@ -178,7 +178,7 @@ struct quaternion
*
* @return Vector containing the real and imaginary parts of the quaternion.
*/
constexpr inline explicit operator vector<T, 4>() const noexcept
inline constexpr explicit operator vector<T, 4>() const noexcept
{
return {r, i[0], i[1], i[2]};
}
@ -479,43 +479,43 @@ template
quaternion<T> quaternion_cast(const matrix<T, 3, 3>& m);
template <class T>
constexpr inline quaternion<T> add(const quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> add(const quaternion<T>& a, const quaternion<T>& b) noexcept
{
return {a.r + b.r, a.i + b.i};
}
template <class T>
constexpr inline quaternion<T> add(const quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T> add(const quaternion<T>& a, T b) noexcept
{
return {a.r + b, a.i + b};
}
template <class T>
constexpr inline quaternion<T> conjugate(const quaternion<T>& q) noexcept
inline constexpr quaternion<T> conjugate(const quaternion<T>& q) noexcept
{
return {q.r, -q.i};
}
template <class T>
constexpr inline T dot(const quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr T dot(const quaternion<T>& a, const quaternion<T>& b) noexcept
{
return a.r * b.r + dot(a.i, b.i);
}
template <class T>
constexpr inline quaternion<T> div(const quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> div(const quaternion<T>& a, const quaternion<T>& b) noexcept
{
return {a.r / b.r, a.i / b.i};
}
template <class T>
constexpr inline quaternion<T> div(const quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T> div(const quaternion<T>& a, T b) noexcept
{
return {a.r / b, a.i / b};
}
template <class T>
constexpr inline quaternion<T> div(T a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> div(T a, const quaternion<T>& b) noexcept
{
return {a / b.r, a / b.i};
}
@ -533,7 +533,7 @@ inline T length(const quaternion& q)
}
template <class T>
constexpr inline quaternion<T> lerp(const quaternion<T>& a, const quaternion<T>& b, T t) noexcept
inline constexpr quaternion<T> lerp(const quaternion<T>& a, const quaternion<T>& b, T t) noexcept
{
return
{
@ -572,7 +572,7 @@ constexpr quaternion mul(const quaternion& a, const quaternion& b) noex
}
template <class T>
constexpr inline quaternion<T> mul(const quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T> mul(const quaternion<T>& 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 <class T>
constexpr inline vector<T, 3> mul(const vector<T, 3>& a, const quaternion<T>& b) noexcept
inline constexpr vector<T, 3> mul(const vector<T, 3>& a, const quaternion<T>& b) noexcept
{
return mul(conjugate(b), a);
}
template <class T>
constexpr inline quaternion<T> negate(const quaternion<T>& q) noexcept
inline constexpr quaternion<T> negate(const quaternion<T>& q) noexcept
{
return {-q.r, -q.i};
}
@ -639,25 +639,25 @@ quaternion slerp(const quaternion& a, const quaternion& b, T t, T error
}
template <class T>
constexpr inline T sqr_length(const quaternion<T>& q) noexcept
inline constexpr T sqr_length(const quaternion<T>& q) noexcept
{
return q.r * q.r + sqr_length(q.i);
}
template <class T>
constexpr inline quaternion<T> sub(const quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> sub(const quaternion<T>& a, const quaternion<T>& b) noexcept
{
return {a.r - b.r, a.i - b.i};
}
template <class T>
constexpr inline quaternion<T> sub(const quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T> sub(const quaternion<T>& a, T b) noexcept
{
return {a.r - b, a.i - b};
}
template <class T>
constexpr inline quaternion<T> sub(T a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> sub(T a, const quaternion<T>& b) noexcept
{
return {a - b.r, a - b.i};
}
@ -742,7 +742,7 @@ namespace operators {
/// @copydoc add(const quaternion<T>&, const quaternion<T>&)
template <class T>
constexpr inline quaternion<T> operator+(const quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> operator+(const quaternion<T>& a, const quaternion<T>& b) noexcept
{
return add(a, b);
}
@ -750,12 +750,12 @@ constexpr inline quaternion operator+(const quaternion& a, const quaternio
/// @copydoc add(const quaternion<T>&, T)
/// @{
template <class T>
constexpr inline quaternion<T> operator+(const quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T> operator+(const quaternion<T>& a, T b) noexcept
{
return add(a, b);
}
template <class T>
constexpr inline quaternion<T> operator+(T a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> operator+(T a, const quaternion<T>& b) noexcept
{
return add(b, a);
}
@ -763,28 +763,28 @@ constexpr inline quaternion operator+(T a, const quaternion& b) noexcept
/// @copydoc div(const quaternion<T>&, const quaternion<T>&)
template <class T>
constexpr inline quaternion<T> operator/(const quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> operator/(const quaternion<T>& a, const quaternion<T>& b) noexcept
{
return div(a, b);
}
/// @copydoc div(const quaternion<T>&, T)
template <class T>
constexpr inline quaternion<T> operator/(const quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T> operator/(const quaternion<T>& a, T b) noexcept
{
return div(a, b);
}
/// @copydoc div(T, const quaternion<T>&)
template <class T>
constexpr inline quaternion<T> operator/(T a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> operator/(T a, const quaternion<T>& b) noexcept
{
return div(a, b);
}
/// @copydoc mul(const quaternion<T>&, const quaternion<T>&)
template <class T>
constexpr inline quaternion<T> operator*(const quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> operator*(const quaternion<T>& a, const quaternion<T>& b) noexcept
{
return mul(a, b);
}
@ -792,12 +792,12 @@ constexpr inline quaternion operator*(const quaternion& a, const quaternio
/// @copydoc mul(const quaternion<T>&, T)
/// @{
template <class T>
constexpr inline quaternion<T> operator*(const quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T> operator*(const quaternion<T>& a, T b) noexcept
{
return mul(a, b);
}
template <class T>
constexpr inline quaternion<T> operator*(T a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> operator*(T a, const quaternion<T>& b) noexcept
{
return mul(b, a);
}
@ -805,21 +805,21 @@ constexpr inline quaternion operator*(T a, const quaternion& b) noexcept
/// @copydoc mul(const quaternion<T>&, const vector<T, 3>&)
template <class T>
constexpr inline vector<T, 3> operator*(const quaternion<T>& a, const vector<T, 3>& b) noexcept
inline constexpr vector<T, 3> operator*(const quaternion<T>& a, const vector<T, 3>& b) noexcept
{
return mul(a, b);
}
/// @copydoc mul(const vector<T, 3>&, const quaternion<T>&)
template <class T>
constexpr inline vector<T, 3> operator*(const vector<T, 3>& a, const quaternion<T>& b) noexcept
inline constexpr vector<T, 3> operator*(const vector<T, 3>& a, const quaternion<T>& b) noexcept
{
return mul(a, b);
}
/// @copydoc sub(const quaternion<T>&, const quaternion<T>&)
template <class T>
constexpr inline quaternion<T> operator-(const quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> operator-(const quaternion<T>& a, const quaternion<T>& b) noexcept
{
return sub(a, b);
}
@ -827,12 +827,12 @@ constexpr inline quaternion operator-(const quaternion& a, const quaternio
/// @copydoc sub(const quaternion<T>&, T)
/// @{
template <class T>
constexpr inline quaternion<T> operator-(const quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T> operator-(const quaternion<T>& a, T b) noexcept
{
return sub(a, b);
}
template <class T>
constexpr inline quaternion<T> operator-(T a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T> operator-(T a, const quaternion<T>& b) noexcept
{
return sub(a, b);
}
@ -840,7 +840,7 @@ constexpr inline quaternion operator-(T a, const quaternion& b) noexcept
/// @copydoc negate(const quaternion<T>&)
template <class T>
constexpr inline quaternion<T> operator-(const quaternion<T>& q) noexcept
inline constexpr quaternion<T> operator-(const quaternion<T>& q) noexcept
{
return negate(q);
}
@ -855,12 +855,12 @@ constexpr inline quaternion operator-(const quaternion& q) noexcept
*/
/// @{
template <class T>
constexpr inline quaternion<T>& operator+=(quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T>& operator+=(quaternion<T>& a, const quaternion<T>& b) noexcept
{
return (a = a + b);
}
template <class T>
constexpr inline quaternion<T>& operator+=(quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T>& operator+=(quaternion<T>& a, T b) noexcept
{
return (a = a + b);
}
@ -876,12 +876,12 @@ constexpr inline quaternion& operator+=(quaternion& a, T b) noexcept
*/
/// @{
template <class T>
constexpr inline quaternion<T>& operator-=(quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T>& operator-=(quaternion<T>& a, const quaternion<T>& b) noexcept
{
return (a = a - b);
}
template <class T>
constexpr inline quaternion<T>& operator-=(quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T>& operator-=(quaternion<T>& a, T b) noexcept
{
return (a = a - b);
}
@ -897,12 +897,12 @@ constexpr inline quaternion& operator-=(quaternion& a, T b) noexcept
*/
/// @{
template <class T>
constexpr inline quaternion<T>& operator*=(quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T>& operator*=(quaternion<T>& a, const quaternion<T>& b) noexcept
{
return (a = a * b);
}
template <class T>
constexpr inline quaternion<T>& operator*=(quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T>& operator*=(quaternion<T>& a, T b) noexcept
{
return (a = a * b);
}
@ -918,12 +918,12 @@ constexpr inline quaternion& operator*=(quaternion& a, T b) noexcept
*/
/// @{
template <class T>
constexpr inline quaternion<T>& operator/=(quaternion<T>& a, const quaternion<T>& b) noexcept
inline constexpr quaternion<T>& operator/=(quaternion<T>& a, const quaternion<T>& b) noexcept
{
return (a = a / b);
}
template <class T>
constexpr inline quaternion<T>& operator/=(quaternion<T>& a, T b) noexcept
inline constexpr quaternion<T>& operator/=(quaternion<T>& a, T b) noexcept
{
return (a = a / b);
}

+ 137
- 137
src/math/vector.hpp View File

@ -41,13 +41,13 @@ namespace math {
template <typename T, std::size_t N>
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 <class U, std::size_t... I>
constexpr inline vector<U, N> type_cast(std::index_sequence<I...>) const noexcept
inline constexpr vector<U, N> type_cast(std::index_sequence<I...>) const noexcept
{
return {static_cast<U>(elements[I])...};
}
@ -68,14 +68,14 @@ struct vector
* @return Vector containing the type-casted elements.
*/
template <class U>
constexpr inline explicit operator vector<U, N>() const noexcept
inline constexpr explicit operator vector<U, N>() const noexcept
{
return type_cast<U>(std::make_index_sequence<N>{});
}
/// @private
template <std::size_t M, std::size_t... I>
constexpr inline vector<T, M> size_cast(std::index_sequence<I...>) const noexcept
inline constexpr vector<T, M> size_cast(std::index_sequence<I...>) const noexcept
{
return {(I < N) ? elements[I] : T{0} ...};
}
@ -88,7 +88,7 @@ struct vector
* @return *m*-dimensional vector.
*/
template <std::size_t M>
constexpr inline explicit operator vector<T, M>() const noexcept
inline constexpr explicit operator vector<T, M>() const noexcept
{
return size_cast<M>(std::make_index_sequence<M>{});
}
@ -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<element_type*> rbegin() noexcept
inline constexpr std::reverse_iterator<element_type*> rbegin() noexcept
{
return std::reverse_iterator<element_type*>(elements + N);
}
constexpr inline std::reverse_iterator<const element_type*> rbegin() const noexcept
inline constexpr std::reverse_iterator<const element_type*> rbegin() const noexcept
{
return std::reverse_iterator<const element_type*>(elements + N);
}
constexpr inline std::reverse_iterator<const element_type*> crbegin() const noexcept
inline constexpr std::reverse_iterator<const element_type*> crbegin() const noexcept
{
return std::reverse_iterator<const element_type*>(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<element_type*> rend() noexcept
inline constexpr std::reverse_iterator<element_type*> rend() noexcept
{
return std::reverse_iterator<element_type*>(elements);
}
constexpr inline std::reverse_iterator<const element_type*> rend() const noexcept
inline constexpr std::reverse_iterator<const element_type*> rend() const noexcept
{
return std::reverse_iterator<const element_type*>(elements);
}
constexpr inline std::reverse_iterator<const element_type*> crend() const noexcept
inline constexpr std::reverse_iterator<const element_type*> crend() const noexcept
{
return std::reverse_iterator<const element_type*>(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 <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> abs(const vector<T, N>& x, std::index_sequence<I...>)
inline constexpr vector<T, N> abs(const vector<T, N>& x, std::index_sequence<I...>)
{
return {std::abs(x[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> abs(const vector<T, N>& x)
inline constexpr vector<T, N> abs(const vector<T, N>& x)
{
return abs(x, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] + y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return add(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> add(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> add(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
{
return {(x[I] + y)...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> add(const vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N> add(const vector<T, N>& x, T y) noexcept
{
return add(x, y, std::make_index_sequence<N>{});
}
/// @private
template <std::size_t N, std::size_t... I>
constexpr inline bool all(const vector<bool, N>& x, std::index_sequence<I...>) noexcept
inline constexpr bool all(const vector<bool, N>& x, std::index_sequence<I...>) noexcept
{
return (x[I] && ...);
}
template <std::size_t N>
constexpr inline bool all(const vector<bool, N>& x) noexcept
inline constexpr bool all(const vector<bool, N>& x) noexcept
{
return all(x, std::make_index_sequence<N>{});
}
/// @private
template <std::size_t N, std::size_t... I>
constexpr inline bool any(const vector<bool, N>& x, std::index_sequence<I...>) noexcept
inline constexpr bool any(const vector<bool, N>& x, std::index_sequence<I...>) noexcept
{
return (x[I] || ...);
}
template <std::size_t N>
constexpr inline bool any(const vector<bool, N>& x) noexcept
inline constexpr bool any(const vector<bool, N>& x) noexcept
{
return any(x, std::make_index_sequence<N>{});
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> ceil(const vector<T, N>& x, std::index_sequence<I...>)
inline constexpr vector<T, N> ceil(const vector<T, N>& x, std::index_sequence<I...>)
{
return {std::ceil(x[I])...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> ceil(const vector<T, N>& x)
inline constexpr vector<T, N> ceil(const vector<T, N>& x)
{
return ceil(x, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min_val, const vector<T, N>& max_val, std::index_sequence<I...>)
inline constexpr vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min_val, const vector<T, N>& max_val, std::index_sequence<I...>)
{
return {std::min<T>(max_val[I], std::max<T>(min_val[I], x[I]))...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min, const vector<T, N>& max)
inline constexpr vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min, const vector<T, N>& max)
{
return clamp(x, min, max, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> clamp(const vector<T, N>& x, T min, T max, std::index_sequence<I...>)
inline constexpr vector<T, N> clamp(const vector<T, N>& x, T min, T max, std::index_sequence<I...>)
{
return {std::min<T>(max, std::max<T>(min, x[I]))...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> clamp(const vector<T, N>& x, T min, T max)
inline constexpr vector<T, N> clamp(const vector<T, N>& x, T min, T max)
{
return clamp(x, min, max, std::make_index_sequence<N>{});
}
@ -944,7 +944,7 @@ vector clamp_length(const vector& x, T max_length)
}
template <class T>
constexpr inline vector<T, 3> cross(const vector<T, 3>& x, const vector<T, 3>& y) noexcept
inline constexpr vector<T, 3> cross(const vector<T, 3>& x, const vector<T, 3>& y) noexcept
{
return
{
@ -962,144 +962,144 @@ inline T distance(const vector& p0, const vector& p1)
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] / y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return div(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> div(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> div(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
{
return {(x[I] / y)...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> div(const vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N> div(const vector<T, N>& x, T y) noexcept
{
return div(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> div(T x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> div(T x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x / y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> div(T x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> div(T x, const vector<T, N>& y) noexcept
{
return div(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline T dot(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr T dot(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return ((x[I] * y[I]) + ...);
}
template <class T, std::size_t N>
constexpr inline T dot(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr T dot(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return dot(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] == y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return equal(x, y, std::make_index_sequence<N>{});
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> floor(const vector<T, N>& x, std::index_sequence<I...>)
inline constexpr vector<T, N> floor(const vector<T, N>& x, std::index_sequence<I...>)
{
return {std::floor(x[I])...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> floor(const vector<T, N>& x)
inline constexpr vector<T, N> floor(const vector<T, N>& x)
{
return floor(x, std::make_index_sequence<N>{});
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z, std::index_sequence<I...>)
inline constexpr vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z, std::index_sequence<I...>)
{
return {std::fma(x[I], y[I], z[I])...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z)
inline constexpr vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z)
{
return fma(x, y, z, std::make_index_sequence<N>{});
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> fma(const vector<T, N>& x, T y, T z, std::index_sequence<I...>)
inline constexpr vector<T, N> fma(const vector<T, N>& x, T y, T z, std::index_sequence<I...>)
{
return {std::fma(x[I], y, z)...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> fma(const vector<T, N>& x, T y, T z)
inline constexpr vector<T, N> fma(const vector<T, N>& x, T y, T z)
{
return fma(x, y, z, std::make_index_sequence<N>{});
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> fract(const vector<T, N>& x, std::index_sequence<I...>)
inline constexpr vector<T, N> fract(const vector<T, N>& x, std::index_sequence<I...>)
{
return {x[I] - std::floor(x[I])...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> fract(const vector<T, N>& x)
inline constexpr vector<T, N> fract(const vector<T, N>& x)
{
return fract(x, std::make_index_sequence<N>{});
}
template<std::size_t I, class T, std::size_t N>
constexpr inline T& get(math::vector<T, N>& v) noexcept
inline constexpr T& get(math::vector<T, N>& v) noexcept
{
static_assert(I < N);
return v.elements[I];
}
template<std::size_t I, class T, std::size_t N>
constexpr inline T&& get(math::vector<T, N>&& v) noexcept
inline constexpr T&& get(math::vector<T, N>&& v) noexcept
{
static_assert(I < N);
return std::move(v.elements[I]);
}
template<std::size_t I, class T, std::size_t N>
constexpr inline const T& get(const math::vector<T, N>& v) noexcept
inline constexpr const T& get(const math::vector<T, N>& v) noexcept
{
static_assert(I < N);
return v.elements[I];
}
template<std::size_t I, class T, std::size_t N>
constexpr inline const T&& get(const math::vector<T, N>&& v) noexcept
inline constexpr const T&& get(const math::vector<T, N>&& 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 <class T, std::size_t N, std::size_t... I>
constexpr inline vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] > y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return greater_than(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] >= y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return greater_than_equal(x, y, std::make_index_sequence<N>{});
}
@ -1145,33 +1145,33 @@ inline T length(const vector& x)
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] < y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return less_than(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] <= y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return less_than_equal(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> max(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
inline constexpr vector<T, N> max(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
{
return {std::max<T>(x[I], y[I])...};
}
@ -1183,14 +1183,14 @@ constexpr vector max(const vector& x, const vector& y)
}
template <class T, std::size_t N>
constexpr inline T max(const vector<T, N>& x)
inline constexpr T max(const vector<T, N>& x)
{
return *std::max_element(x.elements, x.elements + N);
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> min(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
inline constexpr vector<T, N> min(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
{
return {std::min<T>(x[I], y[I])...};
}
@ -1202,72 +1202,72 @@ constexpr vector min(const vector& x, const vector& y)
}
template <class T, std::size_t N>
constexpr inline T min(const vector<T, N>& x)
inline constexpr T min(const vector<T, N>& x)
{
return *std::min_element(x.elements, x.elements + N);
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
inline constexpr vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
{
return {std::fmod(x[I], y[I])...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y)
inline constexpr vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y)
{
return mod(x, y, std::make_index_sequence<N>{});
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> mod(const vector<T, N>& x, T y, std::index_sequence<I...>)
inline constexpr vector<T, N> mod(const vector<T, N>& x, T y, std::index_sequence<I...>)
{
return {std::fmod(x[I], y)...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> mod(const vector<T, N>& x, T y)
inline constexpr vector<T, N> mod(const vector<T, N>& x, T y)
{
return mod(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] * y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return mul(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> mul(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> mul(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
{
return {(x[I] * y)...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> mul(const vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N> mul(const vector<T, N>& x, T y) noexcept
{
return mul(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> negate(const vector<T, N>& x, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> negate(const vector<T, N>& x, std::index_sequence<I...>) noexcept
{
return {(-x[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> negate(const vector<T, N>& x) noexcept
inline constexpr vector<T, N> negate(const vector<T, N>& x) noexcept
{
return negate(x, std::make_index_sequence<N>{});
}
@ -1280,26 +1280,26 @@ inline vector normalize(const vector& x)
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<bool, N> logical_not(const vector<T, N>& x, std::index_sequence<I...>) noexcept
inline constexpr vector<bool, N> logical_not(const vector<T, N>& x, std::index_sequence<I...>) noexcept
{
return {!x[I]...};
}
template <class T, std::size_t N>
constexpr inline vector<bool, N> logical_not(const vector<T, N>& x) noexcept
inline constexpr vector<bool, N> logical_not(const vector<T, N>& x) noexcept
{
return logical_not(x, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] != y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return not_equal(x, y, std::make_index_sequence<N>{});
}
@ -1332,38 +1332,38 @@ inline vector pow(const vector& x, T y)
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> round(const vector<T, N>& x, std::index_sequence<I...>)
inline constexpr vector<T, N> round(const vector<T, N>& x, std::index_sequence<I...>)
{
return {std::round(x[I])...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> round(const vector<T, N>& x)
inline constexpr vector<T, N> round(const vector<T, N>& x)
{
return round(x, std::make_index_sequence<N>{});
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> sign(const vector<T, N>& x, std::index_sequence<I...>)
inline constexpr vector<T, N> sign(const vector<T, N>& x, std::index_sequence<I...>)
{
return {std::copysign(T{1}, x[I])...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> sign(const vector<T, N>& x)
inline constexpr vector<T, N> sign(const vector<T, N>& x)
{
return sign(x, std::make_index_sequence<N>{});
}
template <class T, std::size_t N>
constexpr inline T sqr_distance(const vector<T, N>& p0, const vector<T, N>& p1) noexcept
inline constexpr T sqr_distance(const vector<T, N>& p0, const vector<T, N>& p1) noexcept
{
return sqr_length(sub(p0, p1));
}
template <class T, std::size_t N>
constexpr inline T sqr_length(const vector<T, N>& x) noexcept
inline constexpr T sqr_length(const vector<T, N>& x) noexcept
{
return dot(x, x);
}
@ -1383,71 +1383,71 @@ inline vector sqrt(const vector& x, const vector& y)
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x[I] - y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return sub(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> sub(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> sub(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
{
return {(x[I] - y)...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> sub(const vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N> sub(const vector<T, N>& x, T y) noexcept
{
return sub(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> sub(T x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
inline constexpr vector<T, N> sub(T x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
{
return {(x - y[I])...};
}
template <class T, std::size_t N>
constexpr inline vector<T, N> sub(T x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> sub(T x, const vector<T, N>& y) noexcept
{
return sub(x, y, std::make_index_sequence<N>{});
}
/// @private
template <class T, std::size_t N, std::size_t... I>
constexpr inline T sum(const vector<T, N>& x, std::index_sequence<I...>) noexcept
inline constexpr T sum(const vector<T, N>& x, std::index_sequence<I...>) noexcept
{
return (x[I] + ...);
}
template <class T, std::size_t N>
constexpr inline T sum(const vector<T, N>& x) noexcept
inline constexpr T sum(const vector<T, N>& x) noexcept
{
return sum(x, std::make_index_sequence<N>{});
}
template <std::size_t... Indices, class T, std::size_t N>
constexpr inline vector<T, sizeof...(Indices)> swizzle(const vector<T, N>& x) noexcept
inline constexpr vector<T, sizeof...(Indices)> swizzle(const vector<T, N>& x) noexcept
{
return {x[Indices]...};
}
/// @private
template <std::floating_point T, std::size_t N, std::size_t... I>
constexpr inline vector<T, N> trunc(const vector<T, N>& x, std::index_sequence<I...>)
inline constexpr vector<T, N> trunc(const vector<T, N>& x, std::index_sequence<I...>)
{
return {std::trunc(x[I])...};
}
template <std::floating_point T, std::size_t N>
constexpr inline vector<T, N> trunc(const vector<T, N>& x)
inline constexpr vector<T, N> trunc(const vector<T, N>& x)
{
return trunc(x, std::make_index_sequence<N>{});
}
@ -1456,7 +1456,7 @@ namespace operators {
/// @copydoc add(const vector<T, N>&, const vector<T, N>&)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator+(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> operator+(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return add(x, y);
}
@ -1464,12 +1464,12 @@ constexpr inline vector operator+(const vector& x, const vector
/// @copydoc add(const vector<T, N>&, T)
/// @{
template <class T, std::size_t N>
constexpr inline vector<T, N> operator+(const vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N> operator+(const vector<T, N>& x, T y) noexcept
{
return add(x, y);
}
template <class T, std::size_t N>
constexpr inline vector<T, N> operator+(T x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> operator+(T x, const vector<T, N>& y) noexcept
{
return add(y, x);
}
@ -1477,28 +1477,28 @@ constexpr inline vector operator+(T x, const vector& y) noexcept
/// @copydoc div(const vector<T, N>&, const vector<T, N>&)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator/(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> operator/(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return div(x, y);
}
/// @copydoc div(const vector<T, N>&, T)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator/(const vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N> operator/(const vector<T, N>& x, T y) noexcept
{
return div(x, y);
}
/// @copydoc div(T, const vector<T, N>&)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator/(T x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> operator/(T x, const vector<T, N>& y) noexcept
{
return div(x, y);
}
/// @copydoc mul(const vector<T, N>&, const vector<T, N>&)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator*(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> operator*(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return mul(x, y);
}
@ -1506,12 +1506,12 @@ constexpr inline vector operator*(const vector& x, const vector
/// @copydoc mul(const vector<T, N>&, T)
/// @{
template <class T, std::size_t N>
constexpr inline vector<T, N> operator*(const vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N> operator*(const vector<T, N>& x, T y) noexcept
{
return mul(x, y);
}
template <class T, std::size_t N>
constexpr inline vector<T, N> operator*(T x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> operator*(T x, const vector<T, N>& y) noexcept
{
return mul(y, x);
}
@ -1519,28 +1519,28 @@ constexpr inline vector operator*(T x, const vector& y) noexcept
/// @copydoc negate(const vector<T, N>&)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator-(const vector<T, N>& x) noexcept
inline constexpr vector<T, N> operator-(const vector<T, N>& x) noexcept
{
return negate(x);
}
/// @copydoc sub(const vector<T, N>&, const vector<T, N>&)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator-(const vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> operator-(const vector<T, N>& x, const vector<T, N>& y) noexcept
{
return sub(x, y);
}
/// @copydoc sub(const vector<T, N>&, T)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator-(const vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N> operator-(const vector<T, N>& x, T y) noexcept
{
return sub(x, y);
}
/// @copydoc sub(T, const vector<T, N>&)
template <class T, std::size_t N>
constexpr inline vector<T, N> operator-(T x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N> operator-(T x, const vector<T, N>& y) noexcept
{
return sub(x, y);
}
@ -1555,12 +1555,12 @@ constexpr inline vector operator-(T x, const vector& y) noexcept
*/
/// @{
template <class T, std::size_t N>
constexpr inline vector<T, N>& operator+=(vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N>& operator+=(vector<T, N>& x, const vector<T, N>& y) noexcept
{
return (x = x + y);
}
template <class T, std::size_t N>
constexpr inline vector<T, N>& operator+=(vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N>& operator+=(vector<T, N>& x, T y) noexcept
{
return (x = x + y);
}
@ -1576,12 +1576,12 @@ constexpr inline vector& operator+=(vector& x, T y) noexcept
*/
/// @{
template <class T, std::size_t N>
constexpr inline vector<T, N>& operator-=(vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N>& operator-=(vector<T, N>& x, const vector<T, N>& y) noexcept
{
return (x = x - y);
}
template <class T, std::size_t N>
constexpr inline vector<T, N>& operator-=(vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N>& operator-=(vector<T, N>& x, T y) noexcept
{
return (x = x - y);
}
@ -1597,12 +1597,12 @@ constexpr inline vector& operator-=(vector& x, T y) noexcept
*/
/// @{
template <class T, std::size_t N>
constexpr inline vector<T, N>& operator*=(vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N>& operator*=(vector<T, N>& x, const vector<T, N>& y) noexcept
{
return (x = x * y);
}
template <class T, std::size_t N>
constexpr inline vector<T, N>& operator*=(vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N>& operator*=(vector<T, N>& x, T y) noexcept
{
return (x = x * y);
}
@ -1618,12 +1618,12 @@ constexpr inline vector& operator*=(vector& x, T y) noexcept
*/
/// @{
template <class T, std::size_t N>
constexpr inline vector<T, N>& operator/=(vector<T, N>& x, const vector<T, N>& y) noexcept
inline constexpr vector<T, N>& operator/=(vector<T, N>& x, const vector<T, N>& y) noexcept
{
return (x = x / y);
}
template <class T, std::size_t N>
constexpr inline vector<T, N>& operator/=(vector<T, N>& x, T y) noexcept
inline constexpr vector<T, N>& operator/=(vector<T, N>& x, T y) noexcept
{
return (x = x / y);
}

+ 1
- 0
src/render/renderer.cpp View File

@ -32,6 +32,7 @@
#include "geom/projection.hpp"
#include "config.hpp"
#include "math/quaternion.hpp"
#include "math/constants.hpp"
#include <functional>
#include <set>

+ 9
- 9
src/resources/image.hpp View File

@ -57,21 +57,21 @@ public:
*/
/// @{
template <class T>
constexpr inline T* begin() noexcept
inline constexpr T* begin() noexcept
{
static_assert(std::is_standard_layout<T>::value, "Pixel iterator type is not standard-layout.");
static_assert(std::is_trivial<T>::value, "Pixel iterator type is not trivial.");
return static_cast<T*>(pixels);
}
template <class T>
constexpr inline const T* begin() const noexcept
inline constexpr const T* begin() const noexcept
{
static_assert(std::is_standard_layout<T>::value, "Pixel iterator type is not standard-layout.");
static_assert(std::is_trivial<T>::value, "Pixel iterator type is not trivial.");
return static_cast<const T*>(pixels);
}
template <class T>
constexpr inline const T* cbegin() const noexcept
inline constexpr const T* cbegin() const noexcept
{
static_assert(std::is_standard_layout<T>::value, "Pixel iterator type is not standard-layout.");
static_assert(std::is_trivial<T>::value, "Pixel iterator type is not trivial.");
@ -86,25 +86,25 @@ public:
*/
/// @{
template <class T>
constexpr inline T* end() noexcept
inline constexpr T* end() noexcept
{
static_assert(std::is_standard_layout<T>::value, "Pixel iterator type is not standard-layout.");
static_assert(std::is_trivial<T>::value, "Pixel iterator type is not trivial.");
return static_cast<T*>(static_cast<unsigned char*>(pixels) + size);
return reinterpret_cast<T*>(static_cast<unsigned char*>(pixels) + size);
}
template <class T>
constexpr inline const T* end() const noexcept
inline constexpr const T* end() const noexcept
{
static_assert(std::is_standard_layout<T>::value, "Pixel iterator type is not standard-layout.");
static_assert(std::is_trivial<T>::value, "Pixel iterator type is not trivial.");
return static_cast<const T*>(static_cast<const unsigned char*>(pixels) + size);
return reinterpret_cast<const T*>(static_cast<const unsigned char*>(pixels) + size);
}
template <class T>
constexpr inline const T* cend() const noexcept
inline constexpr const T* cend() const noexcept
{
static_assert(std::is_standard_layout<T>::value, "Pixel iterator type is not standard-layout.");
static_assert(std::is_trivial<T>::value, "Pixel iterator type is not trivial.");
return static_cast<const T*>(static_cast<const unsigned char*>(pixels) + size);
return reinterpret_cast<const T*>(static_cast<const unsigned char*>(pixels) + size);
}
/// @}

Loading…
Cancel
Save