1 #include "Creature.hpp"
5 #include "TileType.hpp"
6 #include "../app/Assets.hpp"
8 #include <glm/gtx/transform.hpp>
26 Creature::~Creature() {
30 glm::dmat4 Creature::LocalTransform() noexcept {
31 // TODO: surface transform
32 constexpr double half_height = 0.25;
33 return glm::translate(glm::dvec3(position.x, position.y, position.z + body->Radius() + half_height))
34 * glm::scale(glm::dvec3(half_height, half_height, half_height));
37 void Creature::BuildVAO() {
40 vao.EnableAttribute(0);
41 vao.EnableAttribute(1);
42 vao.EnableAttribute(2);
43 vao.AttributePointer<glm::vec3>(0, false, offsetof(Attributes, position));
44 vao.AttributePointer<glm::vec3>(1, false, offsetof(Attributes, normal));
45 vao.AttributePointer<glm::vec3>(2, false, offsetof(Attributes, texture));
46 vao.ReserveAttributes(6 * 4, GL_STATIC_DRAW);
48 auto attrib = vao.MapAttributes(GL_WRITE_ONLY);
49 const float offset = 1.0f;
50 for (int surface = 0; surface < 6; ++surface) {
51 const float tex_u_begin = surface < 3 ? 1.0f : 0.0f;
52 const float tex_u_end = surface < 3 ? 0.0f : 1.0f;
54 attrib[4 * surface + 0].position[(surface + 0) % 3] = -offset;
55 attrib[4 * surface + 0].position[(surface + 1) % 3] = -offset;
56 attrib[4 * surface + 0].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
57 attrib[4 * surface + 0].normal[(surface + 0) % 3] = 0.0f;
58 attrib[4 * surface + 0].normal[(surface + 1) % 3] = 0.0f;
59 attrib[4 * surface + 0].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
60 attrib[4 * surface + 0].texture.x = tex_u_begin;
61 attrib[4 * surface + 0].texture.y = 1.0f;
62 attrib[4 * surface + 0].texture.z = surface;
64 attrib[4 * surface + 1].position[(surface + 0) % 3] = -offset;
65 attrib[4 * surface + 1].position[(surface + 1) % 3] = offset;
66 attrib[4 * surface + 1].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
67 attrib[4 * surface + 1].normal[(surface + 0) % 3] = 0.0f;
68 attrib[4 * surface + 1].normal[(surface + 1) % 3] = 0.0f;
69 attrib[4 * surface + 1].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
70 attrib[4 * surface + 1].texture.x = tex_u_end;
71 attrib[4 * surface + 1].texture.y = 1.0f;
72 attrib[4 * surface + 1].texture.z = surface;
74 attrib[4 * surface + 2].position[(surface + 0) % 3] = offset;
75 attrib[4 * surface + 2].position[(surface + 1) % 3] = -offset;
76 attrib[4 * surface + 2].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
77 attrib[4 * surface + 2].normal[(surface + 0) % 3] = 0.0f;
78 attrib[4 * surface + 2].normal[(surface + 1) % 3] = 0.0f;
79 attrib[4 * surface + 2].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
80 attrib[4 * surface + 2].texture.x = tex_u_begin;
81 attrib[4 * surface + 2].texture.y = 0.0f;
82 attrib[4 * surface + 2].texture.z = surface;
84 attrib[4 * surface + 3].position[(surface + 0) % 3] = offset;
85 attrib[4 * surface + 3].position[(surface + 1) % 3] = offset;
86 attrib[4 * surface + 3].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
87 attrib[4 * surface + 3].normal[(surface + 0) % 3] = 0.0f;
88 attrib[4 * surface + 3].normal[(surface + 1) % 3] = 0.0f;
89 attrib[4 * surface + 3].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f;
90 attrib[4 * surface + 3].texture.x = tex_u_end;
91 attrib[4 * surface + 3].texture.y = 0.0f;
92 attrib[4 * surface + 3].texture.z = surface;
96 vao.ReserveElements(6 * 6, GL_STATIC_DRAW);
98 auto element = vao.MapElements(GL_WRITE_ONLY);
99 for (int surface = 0; surface < 3; ++surface) {
100 element[6 * surface + 0] = 4 * surface + 0;
101 element[6 * surface + 1] = 4 * surface + 2;
102 element[6 * surface + 2] = 4 * surface + 1;
103 element[6 * surface + 3] = 4 * surface + 1;
104 element[6 * surface + 4] = 4 * surface + 2;
105 element[6 * surface + 5] = 4 * surface + 3;
107 for (int surface = 3; surface < 6; ++surface) {
108 element[6 * surface + 0] = 4 * surface + 0;
109 element[6 * surface + 1] = 4 * surface + 1;
110 element[6 * surface + 2] = 4 * surface + 2;
111 element[6 * surface + 3] = 4 * surface + 2;
112 element[6 * surface + 4] = 4 * surface + 1;
113 element[6 * surface + 5] = 4 * surface + 3;
119 void Creature::Draw(app::Assets &assets, graphics::Viewport &viewport) {
121 vao.DrawTriangles(6 * 6);
125 void Spawn(Creature &c, Planet &p, app::Assets &assets) {
128 c.Position(glm::dvec3(0.0, 0.0, 0.0));
130 // probe surrounding area for common resources
131 int start = p.SideLength() / 2 - 2;
133 std::map<int, double> yields;
134 for (int y = start; y < end; ++y) {
135 for (int x = start; x < end; ++x) {
136 const TileType &t = assets.data.tiles[p.TileAt(0, x, y).type];
137 for (auto yield : t.resources) {
138 yields[yield.resource] += yield.ubiquity;
144 for (auto e : yields) {
145 if (assets.data.resources[e.first].state == Resource::LIQUID) {
146 if (liquid < 0 || e.second > yields[liquid]) {
149 } else if (assets.data.resources[e.first].state == Resource::SOLID) {
150 if (solid < 0 || e.second > yields[solid]) {
156 if (p.HasAtmosphere()) {
157 std::cout << "require breathing " << assets.data.resources[p.Atmosphere()].label << std::endl;
158 c.RequireBreathing(p.Atmosphere());
161 std::cout << "require drinking " << assets.data.resources[liquid].label << std::endl;
162 c.RequireDrinking(liquid);
165 std::cout << "require eating " << assets.data.resources[solid].label << std::endl;
166 c.RequireEating(solid);