-Subproject commit ce337a6b5afd87607a94f006631a390eefceeec1
+Subproject commit 7703c130c0be3b33f4f267d2662f36b999826f33
#include "../graphics/Font.hpp"
#include "../graphics/PlanetSurface.hpp"
#include "../graphics/SunSurface.hpp"
+#include "../math/GaloisLFSR.hpp"
#include "../world/Resource.hpp"
#include "../world/Set.hpp"
#include "../world/TileType.hpp"
std::string skin_path;
std::string tile_path;
+ math::GaloisLFSR random;
+
struct {
world::Set<world::Resource> resources;
world::Set<world::TileType> tile_types;
, font_path(path + "fonts/")
, skin_path(path + "skins/")
, tile_path(path + "tiles/")
+, random(0)
, fonts{
graphics::Font(font_path + "DejaVuSans.ttf", 32),
graphics::Font(font_path + "DejaVuSans.ttf", 24),
in.Skip(io::Token::EQUALS);
if (name == "label") {
in.ReadString(data.resources[id].label);
+ } else if (name == "density") {
+ data.resources[id].density = in.GetDouble();
} else if (name == "state") {
in.ReadIdentifier(name);
if (name == "solid") {
-#include "const.hpp"
#include "app/Application.hpp"
#include "app/Assets.hpp"
#include "app/init.hpp"
#include "app/MasterState.hpp"
#include "creature/Creature.hpp"
+#include "math/const.hpp"
#include "world/Planet.hpp"
#include "world/Set.hpp"
#include "world/Simulation.hpp"
// sunset
//.FirstPerson(3, glm::vec3(0.0f, 0.0f, 0.1f), glm::vec3(1.0f, -0.75f, 0.1f))
// from afar
- .MapView(0, glm::vec3(0.0f, 0.0f, 31.0f), 0.0f)
+ .MapView(0, glm::vec3(0.0f, 0.0f, 10.0f), 0.0f)
// from afar, rotating
//.Orbital(glm::vec3(-60.0f, 0.0f, 0.0f))
;
+++ /dev/null
-#ifndef BLOBS_CONST_HPP_
-#define BLOBS_CONST_HPP_
-
-
-namespace blobs {
-
-constexpr double PI = 3.141592653589793238462643383279502884;
-constexpr double PI_0p25 = PI * 0.25;
-constexpr double PI_0p5 = PI * 0.5;
-constexpr double PI_1p5 = PI * 1.5;
-constexpr double PI_2p0 = PI * 2.0;
-
-constexpr double PI_inv = 1.0 / PI;
-constexpr double PI_0p5_inv = 1.0 / PI_0p5;
-
-constexpr double G = 6.674e-11; // m³kg¯¹s¯²
-
-}
-
-#endif
#ifndef BLOBS_CREATURE_CREATURE_HPP_
#define BLOBS_CREATURE_CREATURE_HPP_
+#include "Genome.hpp"
#include "Goal.hpp"
#include "Need.hpp"
#include "Situation.hpp"
#include "Steering.hpp"
-#include "../graphics/glm.hpp"
#include "../graphics/SimpleVAO.hpp"
+#include "../math/glm.hpp"
#include <memory>
#include <string>
void Name(const std::string &n) noexcept { name = n; }
const std::string &Name() const noexcept { return name; }
+ Genome &GetGenome() noexcept { return genome; }
+ const Genome &GetGenome() const noexcept { return genome; }
+
+ void Mass(double m) noexcept { mass = m; }
+ double Mass() const noexcept { return mass; }
+
void Size(double s) noexcept { size = s; }
double Size() const noexcept { return size; }
void Velocity(const glm::dvec3 &v) noexcept { vel = v; }
const glm::dvec3 &Velocity() const noexcept { return vel; }
- bool Moving() const noexcept { return !allzero(vel); }
+ bool Moving() const noexcept { return glm::length2(vel) < 0.000001; }
glm::dmat4 LocalTransform() noexcept;
private:
world::Simulation ∼
std::string name;
+
+ Genome genome;
+
+ double mass;
double size;
double health;
--- /dev/null
+#ifndef BLOBS_CREATURE_GENOME_HPP_
+#define BLOBS_CREATURE_GENOME_HPP_
+
+#include "../math/Distribution.hpp"
+
+#include <vector>
+
+
+namespace blobs {
+namespace app {
+ struct Assets;
+}
+namespace creature {
+
+class Creature;
+
+struct Genome {
+
+ struct Composition {
+ // which resource
+ int resource;
+ // how much contained in the body
+ math::Distribution mass;
+ // how much to circulate
+ math::Distribution intake;
+ // how important for alive-being
+ math::Distribution penalty;
+ };
+ std::vector<Composition> composition;
+
+ void Configure(app::Assets &, Creature &) const;
+
+};
+
+}
+}
+
+#endif
#ifndef BLOBS_CREATURE_LOCATERESOURCEGOAL_HPP_
#define BLOBS_CREATURE_LOCATERESOURCEGOAL_HPP_
-#include "../graphics/glm.hpp"
+#include "../math/glm.hpp"
namespace blobs {
#ifndef BLOBS_CREATURE_SITUATION_HPP_
#define BLOBS_CREATURE_SITUATION_HPP_
-#include "../graphics/glm.hpp"
+#include "../math/glm.hpp"
namespace blobs {
#ifndef BLOBS_CREATURE_STEERING_HPP_
#define BLOBS_CREATURE_STEERING_HPP_
-#include "../graphics/glm.hpp"
+#include "../math/glm.hpp"
namespace blobs {
#include "Creature.hpp"
+#include "Genome.hpp"
#include "Situation.hpp"
#include "Steering.hpp"
Creature::Creature(world::Simulation &sim)
: sim(sim)
, name()
+, genome()
+, mass(1.0)
, size(1.0)
, health(1.0)
, needs()
void Spawn(Creature &c, world::Planet &p, app::Assets &assets) {
p.AddCreature(&c);
c.GetSituation().SetPlanetSurface(p, 0, p.TileCenter(0, p.SideLength() / 2, p.SideLength() / 2));
- c.Size(0.5);
// probe surrounding area for common resources
int start = p.SideLength() / 2 - 2;
}
}
+ Genome genome;
if (p.HasAtmosphere()) {
- std::cout << "require breathing " << assets.data.resources[p.Atmosphere()].label << std::endl;
- std::unique_ptr<Need> need(new InhaleNeed(p.Atmosphere(), 0.5, 0.1));
- need->name = assets.data.resources[p.Atmosphere()].label;
- need->gain = 0.2;
- need->inconvenient = 0.4;
- need->critical = 0.95;
- c.AddNeed(std::move(need));
+ genome.composition.push_back({
+ p.Atmosphere(), // resource
+ { 0.01, 0.00001 }, // mass
+ { 0.5, 0.001 }, // intake
+ { 0.1, 0.0005 } // penalty
+ });
}
if (liquid > -1) {
- std::cout << "require drinking " << assets.data.resources[liquid].label << std::endl;
- std::unique_ptr<Need> need(new IngestNeed(liquid, 0.2, 0.01));
- need->name = assets.data.resources[liquid].label;
- need->gain = 0.02;
- need->inconvenient = 0.6;
- need->critical = 0.95;
- c.AddNeed(std::move(need));
+ genome.composition.push_back({
+ liquid, // resource
+ { 0.6, 0.01 }, // mass
+ { 0.2, 0.001 }, // intake
+ { 0.01, 0.002 } // penalty
+ });
}
if (solid > -1) {
- std::cout << "require eating " << assets.data.resources[solid].label << std::endl;
- std::unique_ptr<Need> need(new IngestNeed(solid, 0.1, 0.001));
- need->name = assets.data.resources[solid].label;
- need->gain = 0.017;
- need->inconvenient = 0.6;
+ genome.composition.push_back({
+ solid, // resource
+ { 0.4, 0.01 }, // mass
+ { 0.1, 0.001 }, // intake
+ { 0.001, 0.0001 } // penalty
+ });
+ }
+
+ genome.Configure(assets, c);
+ c.GetSteering().MaxAcceleration(1.4);
+ c.GetSteering().MaxSpeed(4.4);
+}
+
+void Genome::Configure(app::Assets &assets, Creature &c) const {
+ c.GetGenome() = *this;
+ double mass = 0.0;
+ double volume = 0.0;
+ for (const auto &comp : composition) {
+ double comp_mass = comp.mass.FakeNormal(assets.random.SNorm());
+ double intake = comp.intake.FakeNormal(assets.random.SNorm());
+ double penalty = comp.intake.FakeNormal(assets.random.SNorm());
+
+ mass += comp_mass;
+ volume += comp_mass / assets.data.resources[comp.resource].density;
+
+ std::unique_ptr<Need> need;
+ if (assets.data.resources[comp.resource].state == world::Resource::SOLID) {
+ need.reset(new IngestNeed(comp.resource, intake, penalty));
+ need->gain = intake * 0.05;
+ } else if (assets.data.resources[comp.resource].state == world::Resource::LIQUID) {
+ need.reset(new IngestNeed(comp.resource, intake, penalty));
+ need->gain = intake * 0.1;
+ } else {
+ need.reset(new InhaleNeed(comp.resource, intake, penalty));
+ need->gain = intake * 0.5;
+ }
+ need->name = assets.data.resources[comp.resource].label;
+ need->inconvenient = 0.5;
need->critical = 0.95;
c.AddNeed(std::move(need));
}
+ c.Mass(mass);
+ c.Size(std::cbrt(volume));
}
Situation::Situation()
#include "Program.hpp"
#include "SimpleVAO.hpp"
-#include "glm.hpp"
-
#include <cstdint>
#ifndef BLOBS_GRAPHICS_CAMERA_HPP_
#define BLOBS_GRAPHICS_CAMERA_HPP_
-#include "glm.hpp"
+#include "../math/glm.hpp"
namespace blobs {
#ifndef BLOBS_GRAPHICS_CANVAS_HPP_
#define BLOBS_GRAPHICS_CANVAS_HPP_
-#include "glm.hpp"
#include "Program.hpp"
#include "SimpleVAO.hpp"
+#include "../math/glm.hpp"
#include <cstdint>
#include "Program.hpp"
-#include "glm.hpp"
-
namespace blobs {
namespace graphics {
#ifndef BLOBS_GRAPHICS_FONT_HPP_
#define BLOBS_GRAPHICS_FONT_HPP_
-#include "glm.hpp"
+#include "../math/glm.hpp"
#include <string>
#include <SDL_ttf.h>
#include "Program.hpp"
-#include "glm.hpp"
-
namespace blobs {
namespace graphics {
#ifndef BLOBS_GRAPHICS_PROGRAM_HPP_
#define BLOBS_GRAPHICS_PROGRAM_HPP_
-#include "glm.hpp"
+#include "../math/glm.hpp"
#include <iosfwd>
#include <list>
#include "Program.hpp"
#include "SimpleVAO.hpp"
-#include "glm.hpp"
-
#include <cstdint>
#ifndef BLOBS_GRAPHICS_GL_TRAITS_HPP_
#define BLOBS_GRAPHICS_GL_TRAITS_HPP_
-#include "glm.hpp"
+#include "../math/glm.hpp"
#include <GL/glew.h>
+++ /dev/null
-#ifndef BLOBS_GRAPHICS_GLM_HPP_
-#define BLOBS_GRAPHICS_GLM_HPP_
-
-#ifndef GLM_FORCE_RADIANS
-# define GLM_FORCE_RADIANS 1
-#endif
-
-#include <limits>
-#include <glm/glm.hpp>
-#include <glm/gtx/norm.hpp>
-#include <glm/gtx/component_wise.hpp>
-
-// GLM moved tvec[1234] from glm::detail to glm in 0.9.6
-
-#if GLM_VERSION < 96
-
-namespace glm {
- using tvec1 = detail::tvec1;
- using tvec2 = detail::tvec2;
- using tvec3 = detail::tvec3;
- using tvec4 = detail::tvec4;
-}
-
-#endif
-
-template <class T>
-inline bool allzero(const T &v) noexcept {
- return glm::length2(v) <
- std::numeric_limits<typename T::value_type>::epsilon()
- * std::numeric_limits<typename T::value_type>::epsilon();
-}
-
-template <class T>
-inline bool anynan(const T &v) noexcept {
- return glm::any(glm::isnan(v));
-}
-
-
-#endif
#include "Camera.hpp"
#include "Viewport.hpp"
-#include "../const.hpp"
+#include "../math/const.hpp"
#include "../world/Body.hpp"
#include <cmath>
#include "Token.hpp"
#include "Tokenizer.hpp"
-#include "../graphics/glm.hpp"
+#include "../math/glm.hpp"
#include <iosfwd>
#include <string>
--- /dev/null
+#ifndef BLOBS_MATH_DISTRIBUTION_HPP_
+#define BLOBS_MATH_DISTRIBUTION_HPP_
+
+#include <cmath>
+
+
+namespace blobs {
+namespace math {
+
+class Distribution {
+
+public:
+ Distribution(double mean = 0.0, double stddev = 1.0) noexcept
+ : mean(mean)
+ , stddev(stddev)
+ { }
+
+public:
+ double Mean() const noexcept { return mean; }
+ double StandardDeviation() const noexcept { return stddev; }
+ double Variance() const noexcept { return stddev * stddev; }
+
+ /// convert uniform random value in [-1,1] to fake normal distribution
+ /// in [mean - 2 stdddev,mean + 2 stddev]
+ double FakeNormal(double uniform) const noexcept {
+ return mean + (uniform * uniform * stddev) + std::abs(uniform * uniform * uniform) * stddev;
+ }
+
+private:
+ double mean;
+ double stddev;
+
+};
+
+}
+}
+
+#endif
--- /dev/null
+#ifndef BLOBS_MATH_GALOISLFSR_HPP_
+#define BLOBS_MATH_GALOISLFSR_HPP_
+
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+
+namespace blobs {
+namespace math {
+
+class GaloisLFSR {
+
+public:
+ // seed should be non-zero
+ explicit GaloisLFSR(std::uint64_t seed) noexcept
+ : state(seed) {
+ if (state == 0) {
+ state = 1;
+ }
+ }
+
+ // get the next bit
+ bool operator ()() noexcept {
+ bool result = state & 1;
+ state >>= 1;
+ if (result) {
+ state |= 0x8000000000000000;
+ state ^= mask;
+ } else {
+ state &= 0x7FFFFFFFFFFFFFFF;
+ }
+ return result;
+ }
+
+ template<class T>
+ T operator ()(T &out) noexcept {
+ constexpr int num_bits =
+ std::numeric_limits<T>::digits +
+ std::numeric_limits<T>::is_signed;
+ for (int i = 0; i < num_bits; ++i) {
+ operator ()();
+ }
+ return out = static_cast<T>(state);
+ }
+
+ /// special case for randrom(boolean), since static_cast<bool>(0b10) == true
+ bool operator ()(bool &out) noexcept {
+ return out = operator ()();
+ }
+
+ template<class T>
+ T Next() noexcept {
+ T next;
+ return (*this)(next);
+ }
+
+ double SNorm() noexcept {
+ return 2.0 * UNorm() - 1.0;
+ }
+
+ double UNorm() noexcept {
+ return double(Next<std::uint64_t>()) * (1.0 / double(std::numeric_limits<std::uint64_t>::max()));
+ }
+
+ template<class Container>
+ typename Container::reference From(Container &c) {
+ assert(c.size() > 0);
+ return c[Next<typename Container::size_type>() % c.size()];
+ }
+ template<class Container>
+ typename Container::const_reference From(const Container &c) {
+ assert(c.size() > 0);
+ return c[Next<typename Container::size_type>() % c.size()];
+ }
+
+private:
+ std::uint64_t state;
+ // bits 64, 63, 61, and 60 set to 1 (counting from 1 lo to hi)
+ static constexpr std::uint64_t mask = 0xD800000000000000;
+
+};
+
+}
+}
+
+#endif
--- /dev/null
+#ifndef BLOBS_MATH_OCTAVENOISE_HPP_
+#define BLOBS_MATH_OCTAVENOISE_HPP_
+
+#include "glm.hpp"
+
+
+namespace blobs {
+namespace math {
+
+template<class Noise>
+float OctaveNoise(
+ const Noise &noise,
+ const glm::vec3 &in,
+ int num,
+ float persistence,
+ float frequency = 1.0f,
+ float amplitude = 1.0f,
+ float growth = 2.0f
+) {
+ float total = 0.0f;
+ float max = 0.0f;
+ for (int i = 0; i < num; ++i) {
+ total += noise(in * frequency) * amplitude;
+ max += amplitude;
+ amplitude *= persistence;
+ frequency *= growth;
+ }
+
+ return total / max;
+}
+
+}
+}
+
+#endif
--- /dev/null
+#ifndef BLOBS_MATH_SIMPLEXNOISE_HPP_
+#define BLOBS_MATH_SIMPLEXNOISE_HPP_
+
+#include "glm.hpp"
+
+#include <cstdint>
+
+
+namespace blobs {
+namespace math {
+
+class SimplexNoise {
+
+public:
+ explicit SimplexNoise(std::uint64_t seed) noexcept;
+
+ float operator ()(const glm::vec3 &) const noexcept;
+
+private:
+ int Perm(int idx) const noexcept;
+ int Perm12(int idx) const noexcept;
+ const glm::vec3 &Grad(int idx) const noexcept;
+
+private:
+ int perm[512];
+ int perm12[512];
+ glm::vec3 grad[12];
+ glm::ivec3 second_ints[8];
+ glm::ivec3 third_ints[8];
+ glm::vec3 second_floats[8];
+ glm::vec3 third_floats[8];
+
+};
+
+}
+}
+
+#endif
--- /dev/null
+#ifndef BLOBS_MATH_WORLEYNOISE_HPP_
+#define BLOBS_MATH_WORLEYNOISE_HPP_
+
+#include "glm.hpp"
+
+
+namespace blobs {
+namespace math {
+
+/// implementation of Worley noise (aka Cell or Voroni noise)
+class WorleyNoise {
+
+public:
+ explicit WorleyNoise(unsigned int seed) noexcept;
+
+ float operator ()(const glm::vec3 &) const noexcept;
+
+private:
+ const unsigned int seed;
+ const int num_points;
+
+};
+
+}
+}
+
+#endif
--- /dev/null
+#ifndef BLOBS_MATH_CONST_HPP_
+#define BLOBS_MATH_CONST_HPP_
+
+
+namespace blobs {
+
+constexpr double PI = 3.141592653589793238462643383279502884;
+constexpr double PI_0p25 = PI * 0.25;
+constexpr double PI_0p5 = PI * 0.5;
+constexpr double PI_1p5 = PI * 1.5;
+constexpr double PI_2p0 = PI * 2.0;
+
+constexpr double PI_inv = 1.0 / PI;
+constexpr double PI_0p5_inv = 1.0 / PI_0p5;
+
+/// gravitational constant
+constexpr double G = 6.674e-11; // m³kg¯¹s¯²
+
+}
+
+#endif
--- /dev/null
+#ifndef BLOBS_MATH_GLM_HPP_
+#define BLOBS_MATH_GLM_HPP_
+
+#ifndef GLM_FORCE_RADIANS
+# define GLM_FORCE_RADIANS 1
+#endif
+
+#include <limits>
+#include <glm/glm.hpp>
+#include <glm/gtx/norm.hpp>
+#include <glm/gtx/component_wise.hpp>
+
+// GLM moved tvec[1234] from glm::detail to glm in 0.9.6
+
+#if GLM_VERSION < 96
+
+namespace glm {
+ using tvec1 = detail::tvec1;
+ using tvec2 = detail::tvec2;
+ using tvec3 = detail::tvec3;
+ using tvec4 = detail::tvec4;
+}
+
+#endif
+
+template <class T>
+inline bool allzero(const T &v) noexcept {
+ return glm::length2(v) <
+ std::numeric_limits<typename T::value_type>::epsilon()
+ * std::numeric_limits<typename T::value_type>::epsilon();
+}
+
+template <class T>
+inline bool anynan(const T &v) noexcept {
+ return glm::any(glm::isnan(v));
+}
+
+
+#endif
--- /dev/null
+#include "GaloisLFSR.hpp"
+#include "SimplexNoise.hpp"
+#include "WorleyNoise.hpp"
+
+#include <cmath>
+#include <glm/gtx/norm.hpp>
+
+
+namespace {
+
+constexpr float one_third = 1.0f/3.0f;
+constexpr float one_sixth = 1.0f/6.0f;
+
+}
+
+namespace blobs {
+namespace math {
+
+SimplexNoise::SimplexNoise(std::uint64_t seed) noexcept
+: grad({
+ { 1.0f, 1.0f, 0.0f },
+ { -1.0f, 1.0f, 0.0f },
+ { 1.0f, -1.0f, 0.0f },
+ { -1.0f, -1.0f, 0.0f },
+ { 1.0f, 0.0f, 1.0f },
+ { -1.0f, 0.0f, 1.0f },
+ { 1.0f, 0.0f, -1.0f },
+ { -1.0f, 0.0f, -1.0f },
+ { 0.0f, 1.0f, 1.0f },
+ { 0.0f, -1.0f, 1.0f },
+ { 0.0f, 1.0f, -1.0f },
+ { 0.0f, -1.0f, -1.0f },
+})
+, second_ints({
+ // x>y x>z y>z
+ { 0, 0, 1 }, // 0 0 0 ZYX
+ { 0, 1, 0 }, // 0 0 1 YZX
+ { 0, 0, 1 }, // 0 1 0 illogical, but ZYX
+ { 0, 1, 0 }, // 0 1 1 YXZ
+ { 0, 0, 1 }, // 1 0 0 ZXY
+ { 1, 0, 0 }, // 1 0 1 illogical, but XYZ
+ { 1, 0, 0 }, // 1 1 0 XZY
+ { 1, 0, 0 }, // 1 1 1 XYZ
+})
+, third_ints({
+ // x>y x>z y>z
+ { 0, 1, 1 }, // 0 0 0 ZYX
+ { 0, 1, 1 }, // 0 0 1 YZX
+ { 0, 1, 1 }, // 0 1 0 illogical, but ZYX
+ { 1, 1, 0 }, // 0 1 1 YXZ
+ { 1, 0, 1 }, // 1 0 0 ZXY
+ { 1, 1, 0 }, // 1 0 1 illogical, but XYZ
+ { 1, 0, 1 }, // 1 1 0 XZY
+ { 1, 1, 0 }, // 1 1 1 XYZ
+})
+, second_floats({
+ // x>y x>z y>z
+ { 0.0f, 0.0f, 1.0f }, // 0 0 0 ZYX
+ { 0.0f, 1.0f, 0.0f }, // 0 0 1 YZX
+ { 0.0f, 0.0f, 1.0f }, // 0 1 0 illogical, but ZYX
+ { 0.0f, 1.0f, 0.0f }, // 0 1 1 YXZ
+ { 0.0f, 0.0f, 1.0f }, // 1 0 0 ZXY
+ { 1.0f, 0.0f, 0.0f }, // 1 0 1 illogical, but XYZ
+ { 1.0f, 0.0f, 0.0f }, // 1 1 0 XZY
+ { 1.0f, 0.0f, 0.0f }, // 1 1 1 XYZ
+})
+, third_floats({
+ // x>y x>z y>z
+ { 0.0f, 1.0f, 1.0f }, // 0 0 0 ZYX
+ { 0.0f, 1.0f, 1.0f }, // 0 0 1 YZX
+ { 0.0f, 1.0f, 1.0f }, // 0 1 0 illogical, but ZYX
+ { 1.0f, 1.0f, 0.0f }, // 0 1 1 YXZ
+ { 1.0f, 0.0f, 1.0f }, // 1 0 0 ZXY
+ { 1.0f, 1.0f, 0.0f }, // 1 0 1 illogical, but XYZ
+ { 1.0f, 0.0f, 1.0f }, // 1 1 0 XZY
+ { 1.0f, 1.0f, 0.0f }, // 1 1 1 XYZ
+}) {
+ GaloisLFSR random(seed ^ 0x0123456789ACBDEF);
+ unsigned char value;
+ for (size_t i = 0; i < 256; ++i) {
+ perm[i] = random(value);
+ perm[i] &= 0xFF;
+ perm[i + 256] = perm[i];
+ perm12[i] = perm[i] % 12;
+ perm12[i + 256] = perm12[i];
+ }
+}
+
+
+float SimplexNoise::operator ()(const glm::vec3 &in) const noexcept {
+ float skew = (in.x + in.y + in.z) * one_third;
+
+ glm::vec3 skewed(glm::floor(in + skew));
+ float tr = (skewed.x + skewed.y + skewed.z) * one_sixth;
+
+ glm::vec3 unskewed(skewed - tr);
+ glm::vec3 relative(in - unskewed);
+
+ bool x_ge_y = relative.x >= relative.y;
+ bool x_ge_z = relative.x >= relative.z;
+ bool y_ge_z = relative.y >= relative.z;
+ unsigned int st = (x_ge_y << 2) | (x_ge_z << 1) | y_ge_z;
+
+ glm::ivec3 second_int(second_ints[st]);
+ glm::ivec3 third_int(third_ints[st]);
+ glm::vec3 second_float(second_floats[st]);
+ glm::vec3 third_float(third_floats[st]);
+
+ glm::vec3 offset[4] = {
+ in - unskewed,
+ relative - second_float + one_sixth,
+ relative - third_float + one_third,
+ relative - 0.5f,
+ };
+
+ int index[3] = {
+ (int)(skewed.x) & 0xFF,
+ (int)(skewed.y) & 0xFF,
+ (int)(skewed.z) & 0xFF,
+ };
+
+ float n = 0.0f;
+
+ // I know 0.6 is wrong, but for some reason it looks better than 0.5
+
+ // 0
+ float t = glm::clamp(0.6f - glm::length2(offset[0]), 0.0f, 1.0f);
+ t *= t;
+ int corner = Perm12(index[0] + Perm(index[1] + Perm(index[2])));
+ n += t * t * glm::dot(Grad(corner), offset[0]);
+
+ // 1
+ t = glm::clamp(0.6f - glm::length2(offset[1]), 0.0f, 1.0f);
+ t *= t;
+ corner = Perm12(index[0] + second_int.x + Perm(index[1] + second_int.y + Perm(index[2] + second_int.z)));
+ n += t * t * glm::dot(Grad(corner), offset[1]);
+
+ // 2
+ t = glm::clamp(0.6f - glm::length2(offset[2]), 0.0f, 1.0f);
+ t *= t;
+ corner = Perm12(index[0] + third_int.x + Perm(index[1] + third_int.y + Perm(index[2] + third_int.z)));
+ n += t * t * glm::dot(Grad(corner), offset[2]);
+
+ // 3
+ t = glm::clamp(0.6f - glm::length2(offset[3]), 0.0f, 1.0f);
+ t *= t;
+ corner = Perm12(index[0] + 1 + Perm(index[1] + 1 + Perm(index[2] + 1)));
+ n += t * t * glm::dot(Grad(corner), offset[3]);
+
+ return 32.0f * n;
+}
+
+
+int SimplexNoise::Perm(int idx) const noexcept {
+ return perm[idx];
+}
+
+int SimplexNoise::Perm12(int idx) const noexcept {
+ return perm12[idx];
+}
+
+const glm::vec3 &SimplexNoise::Grad(int idx) const noexcept {
+ return grad[idx];
+}
+
+
+WorleyNoise::WorleyNoise(unsigned int seed) noexcept
+: seed(seed)
+, num_points(8) {
+
+}
+
+float WorleyNoise::operator ()(const glm::vec3 &in) const noexcept {
+ glm::vec3 center = glm::floor(in);
+
+ float closest = 1.0f; // cannot be farther away than 1.0
+
+ for (int z = -1; z <= 1; ++z) {
+ for (int y = -1; y <= 1; ++y) {
+ for (int x = -1; x <= 1; ++x) {
+ glm::vec3 cube(center.x + x, center.y + y, center.z + z);
+ unsigned int cube_rand =
+ (unsigned(cube.x) * 130223) ^
+ (unsigned(cube.y) * 159899) ^
+ (unsigned(cube.z) * 190717) ^
+ seed;
+
+ for (int i = 0; i < num_points; ++i) {
+ glm::vec3 point(cube);
+ cube_rand = 190667 * cube_rand + 109807;
+ point.x += float(cube_rand % 262144) / 262144.0f;
+ cube_rand = 135899 * cube_rand + 189169;
+ point.y += float(cube_rand % 262144) / 262144.0f;
+ cube_rand = 159739 * cube_rand + 112139;
+ point.z += float(cube_rand % 262144) / 262144.0f;
+
+ float distance = glm::distance(in, point);
+ if (distance < closest) {
+ closest = distance;
+ }
+ }
+ }
+ }
+ }
+
+ // closest ranges (0, 1), so normalizing to (-1,1) is trivial
+ // though heavily biased towards lower numbers
+ return 2.0f * closest - 1.0f;
+}
+
+}
+}
+++ /dev/null
-#ifndef BLOBS_RAND_GALOISLFSR_HPP_
-#define BLOBS_RAND_GALOISLFSR_HPP_
-
-#include <cassert>
-#include <cstdint>
-#include <limits>
-
-
-namespace blobs {
-namespace rand {
-
-class GaloisLFSR {
-
-public:
- // seed should be non-zero
- explicit GaloisLFSR(std::uint64_t seed) noexcept
- : state(seed) {
- if (state == 0) {
- state = 1;
- }
- }
-
- // get the next bit
- bool operator ()() noexcept {
- bool result = state & 1;
- state >>= 1;
- if (result) {
- state |= 0x8000000000000000;
- state ^= mask;
- } else {
- state &= 0x7FFFFFFFFFFFFFFF;
- }
- return result;
- }
-
- template<class T>
- T operator ()(T &out) noexcept {
- constexpr int num_bits =
- std::numeric_limits<T>::digits +
- std::numeric_limits<T>::is_signed;
- for (int i = 0; i < num_bits; ++i) {
- operator ()();
- }
- return out = static_cast<T>(state);
- }
-
- /// special case for randrom(boolean), since static_cast<bool>(0b10) == true
- bool operator ()(bool &out) noexcept {
- return out = operator ()();
- }
-
- template<class T>
- T Next() noexcept {
- T next;
- return (*this)(next);
- }
-
- float SNorm() noexcept {
- return float(Next<std::uint32_t>()) * (1.0f / 2147483647.5f) - 1.0f;
- }
-
- float UNorm() noexcept {
- return float(Next<std::uint32_t>()) * (1.0f / 4294967295.0f);
- }
-
- template<class Container>
- typename Container::reference From(Container &c) {
- assert(c.size() > 0);
- return c[Next<typename Container::size_type>() % c.size()];
- }
- template<class Container>
- typename Container::const_reference From(const Container &c) {
- assert(c.size() > 0);
- return c[Next<typename Container::size_type>() % c.size()];
- }
-
-private:
- std::uint64_t state;
- // bits 64, 63, 61, and 60 set to 1 (counting from 1 lo to hi)
- static constexpr std::uint64_t mask = 0xD800000000000000;
-
-};
-
-}
-}
-
-#endif
+++ /dev/null
-#ifndef BLOBS_RAND_OCTAVENOISE_HPP_
-#define BLOBS_RAND_OCTAVENOISE_HPP_
-
-#include "../graphics/glm.hpp"
-
-
-namespace blobs {
-namespace rand {
-
-template<class Noise>
-float OctaveNoise(
- const Noise &noise,
- const glm::vec3 &in,
- int num,
- float persistence,
- float frequency = 1.0f,
- float amplitude = 1.0f,
- float growth = 2.0f
-) {
- float total = 0.0f;
- float max = 0.0f;
- for (int i = 0; i < num; ++i) {
- total += noise(in * frequency) * amplitude;
- max += amplitude;
- amplitude *= persistence;
- frequency *= growth;
- }
-
- return total / max;
-}
-
-}
-}
-
-#endif
+++ /dev/null
-#ifndef BLOBS_RAND_SIMPLEXNOISE_HPP_
-#define BLOBS_RAND_SIMPLEXNOISE_HPP_
-
-#include "../graphics/glm.hpp"
-
-#include <cstdint>
-
-
-namespace blobs {
-namespace rand {
-
-class SimplexNoise {
-
-public:
- explicit SimplexNoise(std::uint64_t seed) noexcept;
-
- float operator ()(const glm::vec3 &) const noexcept;
-
-private:
- int Perm(int idx) const noexcept;
- int Perm12(int idx) const noexcept;
- const glm::vec3 &Grad(int idx) const noexcept;
-
-private:
- int perm[512];
- int perm12[512];
- glm::vec3 grad[12];
- glm::ivec3 second_ints[8];
- glm::ivec3 third_ints[8];
- glm::vec3 second_floats[8];
- glm::vec3 third_floats[8];
-
-};
-
-}
-}
-
-#endif
+++ /dev/null
-#ifndef BLOBS_RAND_WORLEYNOISE_HPP_
-#define BLOBS_RAND_WORLEYNOISE_HPP_
-
-#include "../graphics/glm.hpp"
-
-
-namespace blobs {
-namespace rand {
-
-/// implementation of Worley noise (aka Cell or Voroni noise)
-class WorleyNoise {
-
-public:
- explicit WorleyNoise(unsigned int seed) noexcept;
-
- float operator ()(const glm::vec3 &) const noexcept;
-
-private:
- const unsigned int seed;
- const int num_points;
-
-};
-
-}
-}
-
-#endif
+++ /dev/null
-#include "GaloisLFSR.hpp"
-#include "SimplexNoise.hpp"
-#include "WorleyNoise.hpp"
-
-#include <cmath>
-#include <glm/gtx/norm.hpp>
-
-
-namespace {
-
-constexpr float one_third = 1.0f/3.0f;
-constexpr float one_sixth = 1.0f/6.0f;
-
-}
-
-namespace blobs {
-namespace rand {
-
-SimplexNoise::SimplexNoise(std::uint64_t seed) noexcept
-: grad({
- { 1.0f, 1.0f, 0.0f },
- { -1.0f, 1.0f, 0.0f },
- { 1.0f, -1.0f, 0.0f },
- { -1.0f, -1.0f, 0.0f },
- { 1.0f, 0.0f, 1.0f },
- { -1.0f, 0.0f, 1.0f },
- { 1.0f, 0.0f, -1.0f },
- { -1.0f, 0.0f, -1.0f },
- { 0.0f, 1.0f, 1.0f },
- { 0.0f, -1.0f, 1.0f },
- { 0.0f, 1.0f, -1.0f },
- { 0.0f, -1.0f, -1.0f },
-})
-, second_ints({
- // x>y x>z y>z
- { 0, 0, 1 }, // 0 0 0 ZYX
- { 0, 1, 0 }, // 0 0 1 YZX
- { 0, 0, 1 }, // 0 1 0 illogical, but ZYX
- { 0, 1, 0 }, // 0 1 1 YXZ
- { 0, 0, 1 }, // 1 0 0 ZXY
- { 1, 0, 0 }, // 1 0 1 illogical, but XYZ
- { 1, 0, 0 }, // 1 1 0 XZY
- { 1, 0, 0 }, // 1 1 1 XYZ
-})
-, third_ints({
- // x>y x>z y>z
- { 0, 1, 1 }, // 0 0 0 ZYX
- { 0, 1, 1 }, // 0 0 1 YZX
- { 0, 1, 1 }, // 0 1 0 illogical, but ZYX
- { 1, 1, 0 }, // 0 1 1 YXZ
- { 1, 0, 1 }, // 1 0 0 ZXY
- { 1, 1, 0 }, // 1 0 1 illogical, but XYZ
- { 1, 0, 1 }, // 1 1 0 XZY
- { 1, 1, 0 }, // 1 1 1 XYZ
-})
-, second_floats({
- // x>y x>z y>z
- { 0.0f, 0.0f, 1.0f }, // 0 0 0 ZYX
- { 0.0f, 1.0f, 0.0f }, // 0 0 1 YZX
- { 0.0f, 0.0f, 1.0f }, // 0 1 0 illogical, but ZYX
- { 0.0f, 1.0f, 0.0f }, // 0 1 1 YXZ
- { 0.0f, 0.0f, 1.0f }, // 1 0 0 ZXY
- { 1.0f, 0.0f, 0.0f }, // 1 0 1 illogical, but XYZ
- { 1.0f, 0.0f, 0.0f }, // 1 1 0 XZY
- { 1.0f, 0.0f, 0.0f }, // 1 1 1 XYZ
-})
-, third_floats({
- // x>y x>z y>z
- { 0.0f, 1.0f, 1.0f }, // 0 0 0 ZYX
- { 0.0f, 1.0f, 1.0f }, // 0 0 1 YZX
- { 0.0f, 1.0f, 1.0f }, // 0 1 0 illogical, but ZYX
- { 1.0f, 1.0f, 0.0f }, // 0 1 1 YXZ
- { 1.0f, 0.0f, 1.0f }, // 1 0 0 ZXY
- { 1.0f, 1.0f, 0.0f }, // 1 0 1 illogical, but XYZ
- { 1.0f, 0.0f, 1.0f }, // 1 1 0 XZY
- { 1.0f, 1.0f, 0.0f }, // 1 1 1 XYZ
-}) {
- GaloisLFSR random(seed ^ 0x0123456789ACBDEF);
- unsigned char value;
- for (size_t i = 0; i < 256; ++i) {
- perm[i] = random(value);
- perm[i] &= 0xFF;
- perm[i + 256] = perm[i];
- perm12[i] = perm[i] % 12;
- perm12[i + 256] = perm12[i];
- }
-}
-
-
-float SimplexNoise::operator ()(const glm::vec3 &in) const noexcept {
- float skew = (in.x + in.y + in.z) * one_third;
-
- glm::vec3 skewed(glm::floor(in + skew));
- float tr = (skewed.x + skewed.y + skewed.z) * one_sixth;
-
- glm::vec3 unskewed(skewed - tr);
- glm::vec3 relative(in - unskewed);
-
- bool x_ge_y = relative.x >= relative.y;
- bool x_ge_z = relative.x >= relative.z;
- bool y_ge_z = relative.y >= relative.z;
- unsigned int st = (x_ge_y << 2) | (x_ge_z << 1) | y_ge_z;
-
- glm::ivec3 second_int(second_ints[st]);
- glm::ivec3 third_int(third_ints[st]);
- glm::vec3 second_float(second_floats[st]);
- glm::vec3 third_float(third_floats[st]);
-
- glm::vec3 offset[4] = {
- in - unskewed,
- relative - second_float + one_sixth,
- relative - third_float + one_third,
- relative - 0.5f,
- };
-
- int index[3] = {
- (int)(skewed.x) & 0xFF,
- (int)(skewed.y) & 0xFF,
- (int)(skewed.z) & 0xFF,
- };
-
- float n = 0.0f;
-
- // I know 0.6 is wrong, but for some reason it looks better than 0.5
-
- // 0
- float t = glm::clamp(0.6f - glm::length2(offset[0]), 0.0f, 1.0f);
- t *= t;
- int corner = Perm12(index[0] + Perm(index[1] + Perm(index[2])));
- n += t * t * glm::dot(Grad(corner), offset[0]);
-
- // 1
- t = glm::clamp(0.6f - glm::length2(offset[1]), 0.0f, 1.0f);
- t *= t;
- corner = Perm12(index[0] + second_int.x + Perm(index[1] + second_int.y + Perm(index[2] + second_int.z)));
- n += t * t * glm::dot(Grad(corner), offset[1]);
-
- // 2
- t = glm::clamp(0.6f - glm::length2(offset[2]), 0.0f, 1.0f);
- t *= t;
- corner = Perm12(index[0] + third_int.x + Perm(index[1] + third_int.y + Perm(index[2] + third_int.z)));
- n += t * t * glm::dot(Grad(corner), offset[2]);
-
- // 3
- t = glm::clamp(0.6f - glm::length2(offset[3]), 0.0f, 1.0f);
- t *= t;
- corner = Perm12(index[0] + 1 + Perm(index[1] + 1 + Perm(index[2] + 1)));
- n += t * t * glm::dot(Grad(corner), offset[3]);
-
- return 32.0f * n;
-}
-
-
-int SimplexNoise::Perm(int idx) const noexcept {
- return perm[idx];
-}
-
-int SimplexNoise::Perm12(int idx) const noexcept {
- return perm12[idx];
-}
-
-const glm::vec3 &SimplexNoise::Grad(int idx) const noexcept {
- return grad[idx];
-}
-
-
-WorleyNoise::WorleyNoise(unsigned int seed) noexcept
-: seed(seed)
-, num_points(8) {
-
-}
-
-float WorleyNoise::operator ()(const glm::vec3 &in) const noexcept {
- glm::vec3 center = glm::floor(in);
-
- float closest = 1.0f; // cannot be farther away than 1.0
-
- for (int z = -1; z <= 1; ++z) {
- for (int y = -1; y <= 1; ++y) {
- for (int x = -1; x <= 1; ++x) {
- glm::vec3 cube(center.x + x, center.y + y, center.z + z);
- unsigned int cube_rand =
- (unsigned(cube.x) * 130223) ^
- (unsigned(cube.y) * 159899) ^
- (unsigned(cube.z) * 190717) ^
- seed;
-
- for (int i = 0; i < num_points; ++i) {
- glm::vec3 point(cube);
- cube_rand = 190667 * cube_rand + 109807;
- point.x += float(cube_rand % 262144) / 262144.0f;
- cube_rand = 135899 * cube_rand + 189169;
- point.y += float(cube_rand % 262144) / 262144.0f;
- cube_rand = 159739 * cube_rand + 112139;
- point.z += float(cube_rand % 262144) / 262144.0f;
-
- float distance = glm::distance(in, point);
- if (distance < closest) {
- closest = distance;
- }
- }
- }
- }
- }
-
- // closest ranges (0, 1), so normalizing to (-1,1) is trivial
- // though heavily biased towards lower numbers
- return 2.0f * closest - 1.0f;
-}
-
-}
-}
#ifndef BLOBS_UI_WIDGET_HPP_
#define BLOBS_UI_WIDGET_HPP_
-#include "../graphics/glm.hpp"
+#include "../math/glm.hpp"
namespace blobs {
#ifndef BLOBS_UI_ALIGN_HPP_
#define BLOBS_UI_ALIGN_HPP_
-#include "../graphics/glm.hpp"
+#include "../math/glm.hpp"
namespace blobs {
#define BLOBS_WORLD_BODY_HPP_
#include "Orbit.hpp"
-#include "../graphics/glm.hpp"
+#include "../math/glm.hpp"
#include <vector>
#ifndef BLOBS_WORLD_ORBIT_HPP_
#define BLOBS_WORLD_ORBIT_HPP_
-#include "../graphics/glm.hpp"
+#include "../math/glm.hpp"
namespace blobs {
#include "Set.hpp"
#include "Tile.hpp"
-#include "../graphics/glm.hpp"
#include "../graphics/SimpleVAO.hpp"
+#include "../math/glm.hpp"
#include <cassert>
#include <memory>
std::string name;
std::string label;
- int id;
+ double density = 1.0;
+
+ int id = -1;
enum State {
SOLID = 0,
};
// the resource's natural state
// TODO: something about temperature and pressure and stuff
- int state;
+ int state = SOLID;
};
#include "Tile.hpp"
#include "TileType.hpp"
-#include "../const.hpp"
#include "../app/Assets.hpp"
#include "../creature/Creature.hpp"
#include "../graphics/Viewport.hpp"
-#include "../rand/OctaveNoise.hpp"
-#include "../rand/SimplexNoise.hpp"
+#include "../math/const.hpp"
+#include "../math/OctaveNoise.hpp"
+#include "../math/SimplexNoise.hpp"
#include <algorithm>
#include <cmath>
void GenerateEarthlike(const Set<TileType> &tiles, Planet &p) noexcept {
- rand::SimplexNoise elevation_gen(0);
- rand::SimplexNoise variation_gen(45623752346);
+ math::SimplexNoise elevation_gen(0);
+ math::SimplexNoise variation_gen(45623752346);
const int ice = tiles["ice"].id;
const int ocean = tiles["ocean"].id;
p.TileAt(surface, x, y).type = ice;
continue;
}
- float elevation = rand::OctaveNoise(
+ float elevation = math::OctaveNoise(
elevation_gen,
to_tile / p.Radius(),
3, // octaves
2, // amplitude
2 // growth
);
- float variation = rand::OctaveNoise(
+ float variation = math::OctaveNoise(
variation_gen,
to_tile / p.Radius(),
3, // octaves
#ifndef BLOBS_TEST_ASSETS_HPP_
#define BLOBS_TEST_ASSETS_HPP_
-#include "graphics/glm.hpp"
+#include "math/glm.hpp"
#include <string>
#include <limits>
--- /dev/null
+#include "GaloisLFSRTest.hpp"
+
+#include "math/GaloisLFSR.hpp"
+
+#include <algorithm>
+#include <sstream>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(blobs::math::test::GaloisLFSRTest);
+
+using namespace std;
+
+
+namespace blobs {
+namespace math {
+namespace test {
+
+void GaloisLFSRTest::setUp() {
+
+}
+
+void GaloisLFSRTest::tearDown() {
+
+}
+
+void GaloisLFSRTest::testFloatNorm() {
+ GaloisLFSR random(4);
+ for (int i = 0; i < 64; ++i) {
+ float value = random.SNorm();
+ AssertBetween(
+ "random signed normal float",
+ -1.0f, 1.0f, value);
+ }
+ for (int i = 0; i < 64; ++i) {
+ float value = random.UNorm();
+ AssertBetween(
+ "random unsigned normal float",
+ 0.0f, 1.0f, value);
+ }
+}
+
+void GaloisLFSRTest::testFromContainer() {
+ GaloisLFSR random(5);
+ const vector<int> container({ 1, 2, 3, 4, 5 });
+ for (int i = 0; i < 64; ++i) {
+ int element = random.From(container);
+ AssertContains(
+ "random element from container",
+ container, element);
+ }
+}
+
+void GaloisLFSRTest::AssertBetween(
+ string message,
+ float minimum,
+ float maximum,
+ float actual
+) {
+ stringstream msg;
+ msg << message << ": " << actual << " not in ["
+ << minimum << ',' << maximum << ']';
+ CPPUNIT_ASSERT_MESSAGE(
+ msg.str(),
+ minimum <= actual && actual <= maximum);
+
+}
+
+void GaloisLFSRTest::AssertContains(
+ string message,
+ const vector<int> &container,
+ int element
+) {
+ stringstream msg;
+ msg << message << ": " << element << " not in { ";
+ for (int i : container) {
+ msg << i << ' ';
+ }
+ msg << '}';
+ CPPUNIT_ASSERT_MESSAGE(
+ msg.str(),
+ find(container.begin(), container.end(), element) != container.end());
+
+}
+
+}
+}
+}
--- /dev/null
+#ifndef BLOBS_TEST_MATH_GALOISLFSRTEST_HPP
+#define BLOBS_TEST_MATH_GALOISLFSRTEST_HPP
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <string>
+#include <vector>
+
+
+namespace blobs {
+namespace math {
+namespace test {
+
+class GaloisLFSRTest
+: public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE(GaloisLFSRTest);
+
+CPPUNIT_TEST(testFloatNorm);
+CPPUNIT_TEST(testFromContainer);
+
+CPPUNIT_TEST_SUITE_END();
+
+public:
+ void setUp();
+ void tearDown();
+
+ void testFloatNorm();
+ void testFromContainer();
+
+ /// check if value is in range [minimum,maximum]
+ static void AssertBetween(
+ std::string message,
+ float minimum,
+ float maximum,
+ float actual);
+
+ static void AssertContains(
+ std::string message,
+ const std::vector<int> &container,
+ int element);
+
+};
+
+}
+}
+}
+
+#endif
--- /dev/null
+#include "StabilityTest.hpp"
+
+#include "math/GaloisLFSR.hpp"
+#include "math/SimplexNoise.hpp"
+#include "math/WorleyNoise.hpp"
+
+#include <cstdint>
+#include <string>
+#include <sstream>
+#include <glm/gtx/io.hpp>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(blobs::math::test::StabilityTest);
+
+using namespace std;
+
+
+namespace blobs {
+namespace math {
+namespace test {
+
+void StabilityTest::setUp() {
+
+}
+
+void StabilityTest::tearDown() {
+
+}
+
+
+void StabilityTest::testRNG() {
+ GaloisLFSR random(0);
+ uint16_t value;
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #1 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #2 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #3 from RNG",
+ uint16_t(0xB000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #4 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #5 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #6 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #7 from RNG",
+ uint16_t(0x4500), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #8 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #9 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #10 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #11 from RNG",
+ uint16_t(0x2E70), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #12 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #13 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #14 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #15 from RNG",
+ uint16_t(0x1011), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #16 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #17 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #18 from RNG",
+ uint16_t(0xB000), value
+ );
+ value = random.Next<uint16_t>();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #19 from RNG (using Next())",
+ uint16_t(0x0B0B), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #20 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #21 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #22 from RNG",
+ uint16_t(0x1500), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #23 from RNG",
+ uint16_t(0x0454), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #24 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #25 from RNG",
+ uint16_t(0x0000), value
+ );
+ value = random.Next<uint16_t>();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #26 from RNG (using Next())",
+ uint16_t(0xC970), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #27 from RNG",
+ uint16_t(0x02E5), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #28 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #29 from RNG",
+ uint16_t(0x0000), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #30 from RNG",
+ uint16_t(0x0101), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #31 from RNG",
+ uint16_t(0x0100), value
+ );
+ random(value);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected value #32 from RNG",
+ uint16_t(0x0000), value
+ );
+
+ GaloisLFSR random1(1);
+ uint16_t value1;
+ for (int i = 0; i < 32; ++i) {
+ random1(value1);
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "RNG with seeds 0 and 1 differ",
+ value, value1
+ );
+
+ GaloisLFSR random_bool(0);
+ bool value_bool;
+ for (int i = 0; i < (16 * 32); ++i) {
+ random_bool(value_bool);
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected result for bool",
+ false, value_bool
+ );
+
+ GaloisLFSR random8(0);
+ uint8_t value8;
+ for (int i = 0; i < 31; ++i) {
+ random8(value8);
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected result for uint8",
+ uint8_t(0x10), value8
+ );
+
+ GaloisLFSR random32(0);
+ uint32_t value32;
+ for (int i = 0; i < 16; ++i) {
+ random32(value32);
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected result for uint32",
+ uint32_t(0xB0000000), value32
+ );
+}
+
+void StabilityTest::testSimplex() {
+ SimplexNoise noise(0);
+
+ Assert(noise, glm::vec3(0.0f, 0.0f, 0.0f), 0.0f);
+ Assert(noise, glm::vec3(0.0f, 0.0f, 1.0f), 0.652221322059631f);
+ Assert(noise, glm::vec3(0.0f, 1.0f, 0.0f), 0.867977976799011f);
+ Assert(noise, glm::vec3(0.0f, 1.0f, 1.0f), -0.107878111302853f);
+ Assert(noise, glm::vec3(1.0f, 0.0f, 0.0f), -0.107878260314465f);
+ Assert(noise, glm::vec3(1.0f, 0.0f, 1.0f), -6.31356940061778e-08f);
+ Assert(noise, glm::vec3(1.0f, 1.0f, 0.0f), -0.107878245413303f);
+ Assert(noise, glm::vec3(1.0f, 1.0f, 1.0f), 0.0f);
+
+ Assert(noise, glm::vec3( 0.0f, 0.0f, -1.0f), -0.107878483831882f);
+ Assert(noise, glm::vec3( 0.0f, -1.0f, 0.0f), -0.760099768638611f);
+ Assert(noise, glm::vec3( 0.0f, -1.0f, -1.0f), 0.0f);
+ Assert(noise, glm::vec3(-1.0f, 0.0f, 0.0f), 0.760099768638611f);
+ Assert(noise, glm::vec3(-1.0f, 0.0f, -1.0f), 0.0f);
+ Assert(noise, glm::vec3(-1.0f, -1.0f, 0.0f), -0.107878118753433f);
+ Assert(noise, glm::vec3(-1.0f, -1.0f, -1.0f), 0.0f);
+}
+
+void StabilityTest::testWorley() {
+ WorleyNoise noise(0);
+
+ Assert(noise, glm::vec3(0.0f, 0.0f, 0.0f), -0.117765009403229f);
+ Assert(noise, glm::vec3(0.0f, 0.0f, 1.0f), -0.209876894950867f);
+ Assert(noise, glm::vec3(0.0f, 1.0f, 0.0f), -0.290086328983307f);
+ Assert(noise, glm::vec3(0.0f, 1.0f, 1.0f), -0.332393705844879f);
+ Assert(noise, glm::vec3(1.0f, 0.0f, 0.0f), -0.621925830841064f);
+ Assert(noise, glm::vec3(1.0f, 0.0f, 1.0f), -0.338455379009247f);
+ Assert(noise, glm::vec3(1.0f, 1.0f, 0.0f), -0.386664032936096f);
+ Assert(noise, glm::vec3(1.0f, 1.0f, 1.0f), -0.533940434455872f);
+
+ Assert(noise, glm::vec3( 0.0f, 0.0f, -1.0f), -0.425480604171753f);
+ Assert(noise, glm::vec3( 0.0f, -1.0f, 0.0f), -0.189745843410492f);
+ Assert(noise, glm::vec3( 0.0f, -1.0f, -1.0f), -0.30408102273941f);
+ Assert(noise, glm::vec3(-1.0f, 0.0f, 0.0f), -0.618566155433655f);
+ Assert(noise, glm::vec3(-1.0f, 0.0f, -1.0f), -0.060045599937439f);
+ Assert(noise, glm::vec3(-1.0f, -1.0f, 0.0f), -0.366827547550201f);
+ Assert(noise, glm::vec3(-1.0f, -1.0f, -1.0f), -0.575981974601746f);
+}
+
+void StabilityTest::Assert(
+ const SimplexNoise &noise,
+ const glm::vec3 &position,
+ float expected
+) {
+ stringstream msg;
+ msg << "unexpected simplex noise value at " << position;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+ msg.str(),
+ expected, noise(position), numeric_limits<float>::epsilon()
+ );
+}
+
+void StabilityTest::Assert(
+ const WorleyNoise &noise,
+ const glm::vec3 &position,
+ float expected
+) {
+ stringstream msg;
+ msg << "unexpected worley noise value at " << position;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
+ msg.str(),
+ expected, noise(position), numeric_limits<float>::epsilon()
+ );
+}
+
+}
+}
+}
--- /dev/null
+#ifndef BLOBS_TEST_MATH_STABILITYTEST_HPP
+#define BLOBS_TEST_MATH_STABILITYTEST_HPP
+
+#include "math/glm.hpp"
+
+#include <cppunit/extensions/HelperMacros.h>
+
+
+
+namespace blobs {
+namespace math {
+
+class SimplexNoise;
+class WorleyNoise;
+
+namespace test {
+
+class StabilityTest
+: public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE(StabilityTest);
+
+CPPUNIT_TEST(testRNG);
+CPPUNIT_TEST(testSimplex);
+CPPUNIT_TEST(testWorley);
+
+CPPUNIT_TEST_SUITE_END();
+
+public:
+ void setUp();
+ void tearDown();
+
+ void testRNG();
+ void testSimplex();
+ void testWorley();
+
+ static void Assert(
+ const SimplexNoise &noise,
+ const glm::vec3 &position,
+ float expected);
+
+ static void Assert(
+ const WorleyNoise &noise,
+ const glm::vec3 &position,
+ float expected);
+
+};
+
+}
+}
+}
+
+#endif
+++ /dev/null
-#include "GaloisLFSRTest.hpp"
-
-#include "rand/GaloisLFSR.hpp"
-
-#include <algorithm>
-#include <sstream>
-
-CPPUNIT_TEST_SUITE_REGISTRATION(blobs::rand::test::GaloisLFSRTest);
-
-using namespace std;
-
-
-namespace blobs {
-namespace rand {
-namespace test {
-
-void GaloisLFSRTest::setUp() {
-
-}
-
-void GaloisLFSRTest::tearDown() {
-
-}
-
-void GaloisLFSRTest::testFloatNorm() {
- GaloisLFSR random(4);
- for (int i = 0; i < 64; ++i) {
- float value = random.SNorm();
- AssertBetween(
- "random signed normal float",
- -1.0f, 1.0f, value);
- }
- for (int i = 0; i < 64; ++i) {
- float value = random.UNorm();
- AssertBetween(
- "random unsigned normal float",
- 0.0f, 1.0f, value);
- }
-}
-
-void GaloisLFSRTest::testFromContainer() {
- GaloisLFSR random(5);
- const vector<int> container({ 1, 2, 3, 4, 5 });
- for (int i = 0; i < 64; ++i) {
- int element = random.From(container);
- AssertContains(
- "random element from container",
- container, element);
- }
-}
-
-void GaloisLFSRTest::AssertBetween(
- string message,
- float minimum,
- float maximum,
- float actual
-) {
- stringstream msg;
- msg << message << ": " << actual << " not in ["
- << minimum << ',' << maximum << ']';
- CPPUNIT_ASSERT_MESSAGE(
- msg.str(),
- minimum <= actual && actual <= maximum);
-
-}
-
-void GaloisLFSRTest::AssertContains(
- string message,
- const vector<int> &container,
- int element
-) {
- stringstream msg;
- msg << message << ": " << element << " not in { ";
- for (int i : container) {
- msg << i << ' ';
- }
- msg << '}';
- CPPUNIT_ASSERT_MESSAGE(
- msg.str(),
- find(container.begin(), container.end(), element) != container.end());
-
-}
-
-}
-}
-}
+++ /dev/null
-#ifndef BLOBS_TEST_RAND_GALOISLFSRTEST_HPP
-#define BLOBS_TEST_RAND_GALOISLFSRTEST_HPP
-
-#include <cppunit/extensions/HelperMacros.h>
-
-#include <string>
-#include <vector>
-
-
-namespace blobs {
-namespace rand {
-namespace test {
-
-class GaloisLFSRTest
-: public CppUnit::TestFixture {
-
-CPPUNIT_TEST_SUITE(GaloisLFSRTest);
-
-CPPUNIT_TEST(testFloatNorm);
-CPPUNIT_TEST(testFromContainer);
-
-CPPUNIT_TEST_SUITE_END();
-
-public:
- void setUp();
- void tearDown();
-
- void testFloatNorm();
- void testFromContainer();
-
- /// check if value is in range [minimum,maximum]
- static void AssertBetween(
- std::string message,
- float minimum,
- float maximum,
- float actual);
-
- static void AssertContains(
- std::string message,
- const std::vector<int> &container,
- int element);
-
-};
-
-}
-}
-}
-
-#endif
+++ /dev/null
-#include "StabilityTest.hpp"
-
-#include "rand/GaloisLFSR.hpp"
-#include "rand/SimplexNoise.hpp"
-#include "rand/WorleyNoise.hpp"
-
-#include <cstdint>
-#include <string>
-#include <sstream>
-#include <glm/gtx/io.hpp>
-
-CPPUNIT_TEST_SUITE_REGISTRATION(blobs::rand::test::StabilityTest);
-
-using namespace std;
-
-
-namespace blobs {
-namespace rand {
-namespace test {
-
-void StabilityTest::setUp() {
-
-}
-
-void StabilityTest::tearDown() {
-
-}
-
-
-void StabilityTest::testRNG() {
- GaloisLFSR random(0);
- uint16_t value;
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #1 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #2 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #3 from RNG",
- uint16_t(0xB000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #4 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #5 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #6 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #7 from RNG",
- uint16_t(0x4500), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #8 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #9 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #10 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #11 from RNG",
- uint16_t(0x2E70), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #12 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #13 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #14 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #15 from RNG",
- uint16_t(0x1011), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #16 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #17 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #18 from RNG",
- uint16_t(0xB000), value
- );
- value = random.Next<uint16_t>();
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #19 from RNG (using Next())",
- uint16_t(0x0B0B), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #20 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #21 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #22 from RNG",
- uint16_t(0x1500), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #23 from RNG",
- uint16_t(0x0454), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #24 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #25 from RNG",
- uint16_t(0x0000), value
- );
- value = random.Next<uint16_t>();
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #26 from RNG (using Next())",
- uint16_t(0xC970), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #27 from RNG",
- uint16_t(0x02E5), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #28 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #29 from RNG",
- uint16_t(0x0000), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #30 from RNG",
- uint16_t(0x0101), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #31 from RNG",
- uint16_t(0x0100), value
- );
- random(value);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected value #32 from RNG",
- uint16_t(0x0000), value
- );
-
- GaloisLFSR random1(1);
- uint16_t value1;
- for (int i = 0; i < 32; ++i) {
- random1(value1);
- }
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "RNG with seeds 0 and 1 differ",
- value, value1
- );
-
- GaloisLFSR random_bool(0);
- bool value_bool;
- for (int i = 0; i < (16 * 32); ++i) {
- random_bool(value_bool);
- }
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected result for bool",
- false, value_bool
- );
-
- GaloisLFSR random8(0);
- uint8_t value8;
- for (int i = 0; i < 31; ++i) {
- random8(value8);
- }
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected result for uint8",
- uint8_t(0x10), value8
- );
-
- GaloisLFSR random32(0);
- uint32_t value32;
- for (int i = 0; i < 16; ++i) {
- random32(value32);
- }
- CPPUNIT_ASSERT_EQUAL_MESSAGE(
- "unexpected result for uint32",
- uint32_t(0xB0000000), value32
- );
-}
-
-void StabilityTest::testSimplex() {
- SimplexNoise noise(0);
-
- Assert(noise, glm::vec3(0.0f, 0.0f, 0.0f), 0.0f);
- Assert(noise, glm::vec3(0.0f, 0.0f, 1.0f), 0.652221322059631f);
- Assert(noise, glm::vec3(0.0f, 1.0f, 0.0f), 0.867977976799011f);
- Assert(noise, glm::vec3(0.0f, 1.0f, 1.0f), -0.107878111302853f);
- Assert(noise, glm::vec3(1.0f, 0.0f, 0.0f), -0.107878260314465f);
- Assert(noise, glm::vec3(1.0f, 0.0f, 1.0f), -6.31356940061778e-08f);
- Assert(noise, glm::vec3(1.0f, 1.0f, 0.0f), -0.107878245413303f);
- Assert(noise, glm::vec3(1.0f, 1.0f, 1.0f), 0.0f);
-
- Assert(noise, glm::vec3( 0.0f, 0.0f, -1.0f), -0.107878483831882f);
- Assert(noise, glm::vec3( 0.0f, -1.0f, 0.0f), -0.760099768638611f);
- Assert(noise, glm::vec3( 0.0f, -1.0f, -1.0f), 0.0f);
- Assert(noise, glm::vec3(-1.0f, 0.0f, 0.0f), 0.760099768638611f);
- Assert(noise, glm::vec3(-1.0f, 0.0f, -1.0f), 0.0f);
- Assert(noise, glm::vec3(-1.0f, -1.0f, 0.0f), -0.107878118753433f);
- Assert(noise, glm::vec3(-1.0f, -1.0f, -1.0f), 0.0f);
-}
-
-void StabilityTest::testWorley() {
- WorleyNoise noise(0);
-
- Assert(noise, glm::vec3(0.0f, 0.0f, 0.0f), -0.117765009403229f);
- Assert(noise, glm::vec3(0.0f, 0.0f, 1.0f), -0.209876894950867f);
- Assert(noise, glm::vec3(0.0f, 1.0f, 0.0f), -0.290086328983307f);
- Assert(noise, glm::vec3(0.0f, 1.0f, 1.0f), -0.332393705844879f);
- Assert(noise, glm::vec3(1.0f, 0.0f, 0.0f), -0.621925830841064f);
- Assert(noise, glm::vec3(1.0f, 0.0f, 1.0f), -0.338455379009247f);
- Assert(noise, glm::vec3(1.0f, 1.0f, 0.0f), -0.386664032936096f);
- Assert(noise, glm::vec3(1.0f, 1.0f, 1.0f), -0.533940434455872f);
-
- Assert(noise, glm::vec3( 0.0f, 0.0f, -1.0f), -0.425480604171753f);
- Assert(noise, glm::vec3( 0.0f, -1.0f, 0.0f), -0.189745843410492f);
- Assert(noise, glm::vec3( 0.0f, -1.0f, -1.0f), -0.30408102273941f);
- Assert(noise, glm::vec3(-1.0f, 0.0f, 0.0f), -0.618566155433655f);
- Assert(noise, glm::vec3(-1.0f, 0.0f, -1.0f), -0.060045599937439f);
- Assert(noise, glm::vec3(-1.0f, -1.0f, 0.0f), -0.366827547550201f);
- Assert(noise, glm::vec3(-1.0f, -1.0f, -1.0f), -0.575981974601746f);
-}
-
-void StabilityTest::Assert(
- const SimplexNoise &noise,
- const glm::vec3 &position,
- float expected
-) {
- stringstream msg;
- msg << "unexpected simplex noise value at " << position;
- CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
- msg.str(),
- expected, noise(position), numeric_limits<float>::epsilon()
- );
-}
-
-void StabilityTest::Assert(
- const WorleyNoise &noise,
- const glm::vec3 &position,
- float expected
-) {
- stringstream msg;
- msg << "unexpected worley noise value at " << position;
- CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
- msg.str(),
- expected, noise(position), numeric_limits<float>::epsilon()
- );
-}
-
-}
-}
-}
+++ /dev/null
-#ifndef BLOBS_TEST_RAND_STABILITYTEST_HPP
-#define BLOBS_TEST_RAND_STABILITYTEST_HPP
-
-#include "graphics/glm.hpp"
-
-#include <cppunit/extensions/HelperMacros.h>
-
-
-
-namespace blobs {
-namespace rand {
-
-class SimplexNoise;
-class WorleyNoise;
-
-namespace test {
-
-class StabilityTest
-: public CppUnit::TestFixture {
-
-CPPUNIT_TEST_SUITE(StabilityTest);
-
-CPPUNIT_TEST(testRNG);
-CPPUNIT_TEST(testSimplex);
-CPPUNIT_TEST(testWorley);
-
-CPPUNIT_TEST_SUITE_END();
-
-public:
- void setUp();
- void tearDown();
-
- void testRNG();
- void testSimplex();
- void testWorley();
-
- static void Assert(
- const SimplexNoise &noise,
- const glm::vec3 &position,
- float expected);
-
- static void Assert(
- const WorleyNoise &noise,
- const glm::vec3 &position,
- float expected);
-
-};
-
-}
-}
-}
-
-#endif
#include "../assert.hpp"
-#include "const.hpp"
+#include "math/const.hpp"
#include "world/Orbit.hpp"
CPPUNIT_TEST_SUITE_REGISTRATION(blobs::world::test::OrbitTest);