From: Daniel Karbach Date: Fri, 15 Dec 2017 19:14:41 +0000 (+0100) Subject: make texture part of genome X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=e6a15aa6012cf8f034f3073c3d042f9a714da011;p=blobs.git make texture part of genome kind of --- diff --git a/src/creature/Creature.hpp b/src/creature/Creature.hpp index db0aa52..59bfcb7 100644 --- a/src/creature/Creature.hpp +++ b/src/creature/Creature.hpp @@ -103,6 +103,12 @@ public: void HighlightColor(const glm::dvec3 &c) noexcept; glm::dvec4 HighlightColor() const noexcept { return highlight_color; } + void BackSkin(double s) noexcept { skin_back = s; } + double BackSkin() const noexcept { return skin_back; } + + void SideSkin(double s) noexcept { skin_side = s; } + double SideSkin() const noexcept { return skin_side; } + void Mass(double m) noexcept { mass = m; } double Mass() const noexcept { return mass; } void Ingest(int res, double amount) noexcept; @@ -209,6 +215,8 @@ private: glm::dvec3 base_color; glm::dvec4 highlight_color; + double skin_back; + double skin_side; double mass; double size; diff --git a/src/creature/Genome.hpp b/src/creature/Genome.hpp index 1fc5c2a..96d8bf1 100644 --- a/src/creature/Genome.hpp +++ b/src/creature/Genome.hpp @@ -61,6 +61,9 @@ struct Genome { math::Distribution highlight_saturation; math::Distribution highlight_lightness; + math::Distribution skin_back; + math::Distribution skin_side; + void Configure(Creature &) const; static Properties Instantiate( diff --git a/src/creature/creature.cpp b/src/creature/creature.cpp index 0a8b460..f0f7aac 100644 --- a/src/creature/creature.cpp +++ b/src/creature/creature.cpp @@ -190,9 +190,9 @@ void Creature::Ingest(int res, double amount) noexcept { // change color to be slightly more like resource glm::dvec3 color(rgb2hsl(sim.Resources()[res].base_color)); // solids affect base color, others highlight - double p = sim.Resources()[res].state == world::Resource::SOLID ? 0 : 1; - double q = random.UInt(3); // hue, sat, or val - double r = random.UInt(2); // mean or deviation + int p = sim.Resources()[res].state == world::Resource::SOLID ? 0 : 1; + int q = random.UInt(3); // hue, sat, or val + int r = random.UInt(2); // mean or deviation math::Distribution *d = nullptr; double ref = 0.0; if (p == 0) { @@ -236,6 +236,20 @@ void Creature::Ingest(int res, double amount) noexcept { d->StandardDeviation(glm::clamp(d->StandardDeviation() * (1.0 + random.SNorm() * 0.15), 0.0001, 0.5)); } } + if (sim.Resources()[res].state == world::Resource::LIQUID && random.UNorm() < AdaptChance()) { + // change texture randomly + // TODO: make change depending on surroundings and/or resource + int p = random.UInt(2); // back or side + int q = random.UInt(2); // mean or deviation + math::Distribution &d = p ? genome.skin_side : genome.skin_back; + if (q == 0) { + // move ± one standard deviation + d.Mean(d.Mean() + (random.SNorm() * d.StandardDeviation())); + } else { + // scale by ±10%, enforce bounds + d.StandardDeviation(glm::clamp(d.StandardDeviation() * (1.0 + random.SNorm() * 0.1), 0.0001, 0.5)); + } + } } void Creature::DoWork(double amount) noexcept { @@ -631,7 +645,16 @@ void Creature::BuildVAO() { vao->ReserveAttributes(6 * 4, GL_STATIC_DRAW); { auto attrib = vao->MapAttributes(GL_WRITE_ONLY); - const float offset = 1.0f; + constexpr float offset = 1.0f; + constexpr float max_tex = 5.999f; + const float tex[6] = { + 0.0f, // face + float(std::floor(skin_side * max_tex)), // left + float(std::floor(skin_back * max_tex)), // top + float(std::floor(skin_back * max_tex)), // back + float(std::floor(skin_side * max_tex)), // right + 0.0f, // bottom + }; for (int surface = 0; surface < 6; ++surface) { const float tex_u_begin = surface < 3 ? 1.0f : 0.0f; const float tex_u_end = surface < 3 ? 0.0f : 1.0f; @@ -644,7 +667,7 @@ void Creature::BuildVAO() { attrib[4 * surface + 0].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f; attrib[4 * surface + 0].texture.x = tex_u_begin; attrib[4 * surface + 0].texture.y = 1.0f; - attrib[4 * surface + 0].texture.z = surface; + attrib[4 * surface + 0].texture.z = tex[surface]; attrib[4 * surface + 1].position[(surface + 0) % 3] = -offset; attrib[4 * surface + 1].position[(surface + 1) % 3] = offset; @@ -654,7 +677,7 @@ void Creature::BuildVAO() { attrib[4 * surface + 1].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f; attrib[4 * surface + 1].texture.x = tex_u_end; attrib[4 * surface + 1].texture.y = 1.0f; - attrib[4 * surface + 1].texture.z = surface; + attrib[4 * surface + 1].texture.z = tex[surface]; attrib[4 * surface + 2].position[(surface + 0) % 3] = offset; attrib[4 * surface + 2].position[(surface + 1) % 3] = -offset; @@ -664,7 +687,7 @@ void Creature::BuildVAO() { attrib[4 * surface + 2].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f; attrib[4 * surface + 2].texture.x = tex_u_begin; attrib[4 * surface + 2].texture.y = 0.0f; - attrib[4 * surface + 2].texture.z = surface; + attrib[4 * surface + 2].texture.z = tex[surface]; attrib[4 * surface + 3].position[(surface + 0) % 3] = offset; attrib[4 * surface + 3].position[(surface + 1) % 3] = offset; @@ -674,7 +697,7 @@ void Creature::BuildVAO() { attrib[4 * surface + 3].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f; attrib[4 * surface + 3].texture.x = tex_u_end; attrib[4 * surface + 3].texture.y = 0.0f; - attrib[4 * surface + 3].texture.z = surface; + attrib[4 * surface + 3].texture.z = tex[surface]; } } vao->BindElements(); @@ -786,6 +809,9 @@ void Spawn(Creature &c, world::Planet &p) { genome.highlight_saturation = { 1.0 - hsl.y, 0.01 }; genome.highlight_lightness = { 1.0 - hsl.z, 0.01 }; + genome.skin_side = { 0.5, 0.01 }; + genome.skin_back = { 0.5, 0.01 }; + genome.Configure(c); } @@ -817,6 +843,8 @@ void Genome::Configure(Creature &c) const { ); c.BaseColor(hsl2rgb(base_color)); c.HighlightColor(hsl2rgb(highlight_color)); + c.BackSkin(glm::clamp(skin_back.FakeNormal(random.SNorm()), 0.0, 1.0)); + c.SideSkin(glm::clamp(skin_side.FakeNormal(random.SNorm()), 0.0, 1.0)); c.SetBackgroundTask(std::unique_ptr(new BlobBackgroundTask(c))); c.AddGoal(std::unique_ptr(new IdleGoal(c))); }