Antkeeper  0.0.1
ecoregion-loader.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "game/ecoregion.hpp"
23 #include <engine/utility/json.hpp>
24 #include <engine/math/angles.hpp>
25 #include <stdexcept>
26 
27 template <>
29 {
30  // Load JSON data
32 
33  // Validate ecoregion file
34  auto ecoregion_element = json_data->find("ecoregion");
35  if (ecoregion_element == json_data->end())
36  throw std::runtime_error("Invalid ecoregion file.");
37 
38  // Allocate and init ecoregion
39  std::unique_ptr<::ecoregion> ecoregion = std::make_unique<::ecoregion>();
40  ecoregion->elevation = 0.0f;
41  ecoregion->latitude = 0.0f;
42  ecoregion->longitude = 0.0f;
43  ecoregion->terrain_material = nullptr;
44  ecoregion->horizon_material = nullptr;
45 
46  if (auto element = ecoregion_element->find("name"); element != ecoregion_element->end())
47  ecoregion->name = element->get<std::string>();
48 
49  if (auto location_element = ecoregion_element->find("location"); location_element != ecoregion_element->end())
50  {
51  if (auto element = location_element->find("elevation"); element != location_element->end())
52  ecoregion->elevation = element->get<float>();
53  if (auto element = location_element->find("latitude"); element != location_element->end())
54  ecoregion->latitude = math::radians(element->get<float>());
55  if (auto element = location_element->find("longitude"); element != location_element->end())
56  ecoregion->longitude = math::radians(element->get<float>());
57  }
58 
59  if (auto terrain_element = ecoregion_element->find("terrain"); terrain_element != ecoregion_element->end())
60  {
61  if (auto element = terrain_element->find("material"); element != terrain_element->end())
63  if (auto element = terrain_element->find("albedo"); element != terrain_element->end())
64  ecoregion->terrain_albedo = {(*element)[0].get<float>(), (*element)[1].get<float>(), (*element)[2].get<float>()};
65  if (auto element = terrain_element->find("horizon_material"); element != terrain_element->end())
67  }
68 
69  // Load gene pools
70  if (auto gene_pools_element = ecoregion_element->find("gene_pools"); gene_pools_element != ecoregion_element->end())
71  {
72  // For each gene pool
73  for (auto gene_pool_element = gene_pools_element->begin(); gene_pool_element != gene_pools_element->end(); ++gene_pool_element)
74  {
75  // Allocate gene pool
76  ecoregion->gene_pools.resize(ecoregion->gene_pools.size() + 1);
77  ant_gene_pool& gene_pool = ecoregion->gene_pools.back();
78 
79  // Read gene pool name
80  if (auto name_element = gene_pool_element->find("name"); name_element != gene_pool_element->end())
81  gene_pool.name = name_element->get<std::string>();
82 
83  // Load genes
84  if (auto genes_element = gene_pool_element->find("genes"); genes_element != gene_pool_element->end())
85  {
86  // Load antennae genes
87  if (auto antennae_elements = genes_element->find("antennae"); antennae_elements != genes_element->end())
88  {
89  for (auto antennae_element = antennae_elements->begin(); antennae_element != antennae_elements->end(); ++antennae_element)
90  {
91  float weight = 0.0f;
92  std::shared_ptr<ant_antennae_gene> gene;
93 
94  if (auto weight_element = antennae_element->find("weight"); weight_element != antennae_element->end())
95  weight = weight_element->get<float>();
96  if (auto gene_element = antennae_element->find("gene"); gene_element != antennae_element->end())
97  gene = resource_manager.load<ant_antennae_gene>(gene_element->get<std::string>());
98 
99  if (gene)
100  {
101  gene_pool.antennae.weights.push_back(weight);
102  gene_pool.antennae.genes.push_back(gene);
103  }
104  }
105  }
106 
107  // Load body size genes
108  if (auto body_size_elements = genes_element->find("body_size"); body_size_elements != genes_element->end())
109  {
110  for (auto body_size_element = body_size_elements->begin(); body_size_element != body_size_elements->end(); ++body_size_element)
111  {
112  float weight = 0.0f;
113  std::shared_ptr<ant_body_size_gene> gene;
114 
115  if (auto weight_element = body_size_element->find("weight"); weight_element != body_size_element->end())
116  weight = weight_element->get<float>();
117  if (auto gene_element = body_size_element->find("gene"); gene_element != body_size_element->end())
118  gene = resource_manager.load<ant_body_size_gene>(gene_element->get<std::string>());
119 
120  if (gene)
121  {
122  gene_pool.body_size.weights.push_back(weight);
123  gene_pool.body_size.genes.push_back(gene);
124  }
125  }
126  }
127 
128  // Load pupa genes
129  if (auto pupa_elements = genes_element->find("pupa"); pupa_elements != genes_element->end())
130  {
131  for (auto pupa_element = pupa_elements->begin(); pupa_element != pupa_elements->end(); ++pupa_element)
132  {
133  float weight = 0.0f;
134  std::shared_ptr<ant_pupa_gene> gene;
135 
136  if (auto weight_element = pupa_element->find("weight"); weight_element != pupa_element->end())
137  weight = weight_element->get<float>();
138  if (auto gene_element = pupa_element->find("gene"); gene_element != pupa_element->end())
139  gene = resource_manager.load<ant_pupa_gene>(gene_element->get<std::string>());
140 
141  if (gene)
142  {
143  gene_pool.pupa.weights.push_back(weight);
144  gene_pool.pupa.genes.push_back(gene);
145  }
146  }
147  }
148 
149  // Load diet genes
150  if (auto diet_elements = genes_element->find("diet"); diet_elements != genes_element->end())
151  {
152  for (auto diet_element = diet_elements->begin(); diet_element != diet_elements->end(); ++diet_element)
153  {
154  float weight = 0.0f;
155  std::shared_ptr<ant_diet_gene> gene;
156 
157  if (auto weight_element = diet_element->find("weight"); weight_element != diet_element->end())
158  weight = weight_element->get<float>();
159  if (auto gene_element = diet_element->find("gene"); gene_element != diet_element->end())
160  gene = resource_manager.load<ant_diet_gene>(gene_element->get<std::string>());
161 
162  if (gene)
163  {
164  gene_pool.diet.weights.push_back(weight);
165  gene_pool.diet.genes.push_back(gene);
166  }
167  }
168  }
169 
170  // Load egg genes
171  if (auto egg_elements = genes_element->find("egg"); egg_elements != genes_element->end())
172  {
173  for (auto egg_element = egg_elements->begin(); egg_element != egg_elements->end(); ++egg_element)
174  {
175  float weight = 0.0f;
176  std::shared_ptr<ant_egg_gene> gene;
177 
178  if (auto weight_element = egg_element->find("weight"); weight_element != egg_element->end())
179  weight = weight_element->get<float>();
180  if (auto gene_element = egg_element->find("gene"); gene_element != egg_element->end())
181  gene = resource_manager.load<ant_egg_gene>(gene_element->get<std::string>());
182 
183  if (gene)
184  {
185  gene_pool.egg.weights.push_back(weight);
186  gene_pool.egg.genes.push_back(gene);
187  }
188  }
189  }
190 
191  // Load eyes genes
192  if (auto eyes_elements = genes_element->find("eyes"); eyes_elements != genes_element->end())
193  {
194  for (auto eyes_element = eyes_elements->begin(); eyes_element != eyes_elements->end(); ++eyes_element)
195  {
196  float weight = 0.0f;
197  std::shared_ptr<ant_eyes_gene> gene;
198 
199  if (auto weight_element = eyes_element->find("weight"); weight_element != eyes_element->end())
200  weight = weight_element->get<float>();
201  if (auto gene_element = eyes_element->find("gene"); gene_element != eyes_element->end())
202  gene = resource_manager.load<ant_eyes_gene>(gene_element->get<std::string>());
203 
204  if (gene)
205  {
206  gene_pool.eyes.weights.push_back(weight);
207  gene_pool.eyes.genes.push_back(gene);
208  }
209  }
210  }
211 
212  // Load foraging time genes
213  if (auto foraging_time_elements = genes_element->find("foraging_time"); foraging_time_elements != genes_element->end())
214  {
215  for (auto foraging_time_element = foraging_time_elements->begin(); foraging_time_element != foraging_time_elements->end(); ++foraging_time_element)
216  {
217  float weight = 0.0f;
218  std::shared_ptr<ant_foraging_time_gene> gene;
219 
220  if (auto weight_element = foraging_time_element->find("weight"); weight_element != foraging_time_element->end())
221  weight = weight_element->get<float>();
222  if (auto gene_element = foraging_time_element->find("gene"); gene_element != foraging_time_element->end())
223  gene = resource_manager.load<ant_foraging_time_gene>(gene_element->get<std::string>());
224 
225  if (gene)
226  {
227  gene_pool.foraging_time.weights.push_back(weight);
228  gene_pool.foraging_time.genes.push_back(gene);
229  }
230  }
231  }
232 
233  // Load founding mode genes
234  if (auto founding_mode_elements = genes_element->find("founding_mode"); founding_mode_elements != genes_element->end())
235  {
236  for (auto founding_mode_element = founding_mode_elements->begin(); founding_mode_element != founding_mode_elements->end(); ++founding_mode_element)
237  {
238  float weight = 0.0f;
239  std::shared_ptr<ant_founding_mode_gene> gene;
240 
241  if (auto weight_element = founding_mode_element->find("weight"); weight_element != founding_mode_element->end())
242  weight = weight_element->get<float>();
243  if (auto gene_element = founding_mode_element->find("gene"); gene_element != founding_mode_element->end())
244  gene = resource_manager.load<ant_founding_mode_gene>(gene_element->get<std::string>());
245 
246  if (gene)
247  {
248  gene_pool.founding_mode.weights.push_back(weight);
249  gene_pool.founding_mode.genes.push_back(gene);
250  }
251  }
252  }
253 
254  // Load gaster genes
255  if (auto gaster_elements = genes_element->find("gaster"); gaster_elements != genes_element->end())
256  {
257  for (auto gaster_element = gaster_elements->begin(); gaster_element != gaster_elements->end(); ++gaster_element)
258  {
259  float weight = 0.0f;
260  std::shared_ptr<ant_gaster_gene> gene;
261 
262  if (auto weight_element = gaster_element->find("weight"); weight_element != gaster_element->end())
263  weight = weight_element->get<float>();
264  if (auto gene_element = gaster_element->find("gene"); gene_element != gaster_element->end())
265  gene = resource_manager.load<ant_gaster_gene>(gene_element->get<std::string>());
266 
267  if (gene)
268  {
269  gene_pool.gaster.weights.push_back(weight);
270  gene_pool.gaster.genes.push_back(gene);
271  }
272  }
273  }
274 
275  // Load head genes
276  if (auto head_elements = genes_element->find("head"); head_elements != genes_element->end())
277  {
278  for (auto head_element = head_elements->begin(); head_element != head_elements->end(); ++head_element)
279  {
280  float weight = 0.0f;
281  std::shared_ptr<ant_head_gene> gene;
282 
283  if (auto weight_element = head_element->find("weight"); weight_element != head_element->end())
284  weight = weight_element->get<float>();
285  if (auto gene_element = head_element->find("gene"); gene_element != head_element->end())
286  gene = resource_manager.load<ant_head_gene>(gene_element->get<std::string>());
287 
288  if (gene)
289  {
290  gene_pool.head.weights.push_back(weight);
291  gene_pool.head.genes.push_back(gene);
292  }
293  }
294  }
295 
296  // Load larva genes
297  if (auto larva_elements = genes_element->find("larva"); larva_elements != genes_element->end())
298  {
299  for (auto larva_element = larva_elements->begin(); larva_element != larva_elements->end(); ++larva_element)
300  {
301  float weight = 0.0f;
302  std::shared_ptr<ant_larva_gene> gene;
303 
304  if (auto weight_element = larva_element->find("weight"); weight_element != larva_element->end())
305  weight = weight_element->get<float>();
306  if (auto gene_element = larva_element->find("gene"); gene_element != larva_element->end())
307  gene = resource_manager.load<ant_larva_gene>(gene_element->get<std::string>());
308 
309  if (gene)
310  {
311  gene_pool.larva.weights.push_back(weight);
312  gene_pool.larva.genes.push_back(gene);
313  }
314  }
315  }
316 
317  // Load legs genes
318  if (auto legs_elements = genes_element->find("legs"); legs_elements != genes_element->end())
319  {
320  for (auto legs_element = legs_elements->begin(); legs_element != legs_elements->end(); ++legs_element)
321  {
322  float weight = 0.0f;
323  std::shared_ptr<ant_legs_gene> gene;
324 
325  if (auto weight_element = legs_element->find("weight"); weight_element != legs_element->end())
326  weight = weight_element->get<float>();
327  if (auto gene_element = legs_element->find("gene"); gene_element != legs_element->end())
328  gene = resource_manager.load<ant_legs_gene>(gene_element->get<std::string>());
329 
330  if (gene)
331  {
332  gene_pool.legs.weights.push_back(weight);
333  gene_pool.legs.genes.push_back(gene);
334  }
335  }
336  }
337 
338  // Load mandibles genes
339  if (auto mandibles_elements = genes_element->find("mandibles"); mandibles_elements != genes_element->end())
340  {
341  for (auto mandibles_element = mandibles_elements->begin(); mandibles_element != mandibles_elements->end(); ++mandibles_element)
342  {
343  float weight = 0.0f;
344  std::shared_ptr<ant_mandibles_gene> gene;
345 
346  if (auto weight_element = mandibles_element->find("weight"); weight_element != mandibles_element->end())
347  weight = weight_element->get<float>();
348  if (auto gene_element = mandibles_element->find("gene"); gene_element != mandibles_element->end())
349  gene = resource_manager.load<ant_mandibles_gene>(gene_element->get<std::string>());
350 
351  if (gene)
352  {
353  gene_pool.mandibles.weights.push_back(weight);
354  gene_pool.mandibles.genes.push_back(gene);
355  }
356  }
357  }
358 
359  // Load mesosoma genes
360  if (auto mesosoma_elements = genes_element->find("mesosoma"); mesosoma_elements != genes_element->end())
361  {
362  for (auto mesosoma_element = mesosoma_elements->begin(); mesosoma_element != mesosoma_elements->end(); ++mesosoma_element)
363  {
364  float weight = 0.0f;
365  std::shared_ptr<ant_mesosoma_gene> gene;
366 
367  if (auto weight_element = mesosoma_element->find("weight"); weight_element != mesosoma_element->end())
368  weight = weight_element->get<float>();
369  if (auto gene_element = mesosoma_element->find("gene"); gene_element != mesosoma_element->end())
370  gene = resource_manager.load<ant_mesosoma_gene>(gene_element->get<std::string>());
371 
372  if (gene)
373  {
374  gene_pool.mesosoma.weights.push_back(weight);
375  gene_pool.mesosoma.genes.push_back(gene);
376  }
377  }
378  }
379 
380  // Load nest site genes
381  if (auto nest_site_elements = genes_element->find("nest_site"); nest_site_elements != genes_element->end())
382  {
383  for (auto nest_site_element = nest_site_elements->begin(); nest_site_element != nest_site_elements->end(); ++nest_site_element)
384  {
385  float weight = 0.0f;
386  std::shared_ptr<ant_nest_site_gene> gene;
387 
388  if (auto weight_element = nest_site_element->find("weight"); weight_element != nest_site_element->end())
389  weight = weight_element->get<float>();
390  if (auto gene_element = nest_site_element->find("gene"); gene_element != nest_site_element->end())
391  gene = resource_manager.load<ant_nest_site_gene>(gene_element->get<std::string>());
392 
393  if (gene)
394  {
395  gene_pool.nest_site.weights.push_back(weight);
396  gene_pool.nest_site.genes.push_back(gene);
397  }
398  }
399  }
400 
401  // Load ocelli genes
402  if (auto ocelli_elements = genes_element->find("ocelli"); ocelli_elements != genes_element->end())
403  {
404  for (auto ocelli_element = ocelli_elements->begin(); ocelli_element != ocelli_elements->end(); ++ocelli_element)
405  {
406  float weight = 0.0f;
407  std::shared_ptr<ant_ocelli_gene> gene;
408 
409  if (auto weight_element = ocelli_element->find("weight"); weight_element != ocelli_element->end())
410  weight = weight_element->get<float>();
411  if (auto gene_element = ocelli_element->find("gene"); gene_element != ocelli_element->end())
412  gene = resource_manager.load<ant_ocelli_gene>(gene_element->get<std::string>());
413 
414  if (gene)
415  {
416  gene_pool.ocelli.weights.push_back(weight);
417  gene_pool.ocelli.genes.push_back(gene);
418  }
419  }
420  }
421 
422  // Load pigmentation genes
423  if (auto pigmentation_elements = genes_element->find("pigmentation"); pigmentation_elements != genes_element->end())
424  {
425  for (auto pigmentation_element = pigmentation_elements->begin(); pigmentation_element != pigmentation_elements->end(); ++pigmentation_element)
426  {
427  float weight = 0.0f;
428  std::shared_ptr<ant_pigmentation_gene> gene;
429 
430  if (auto weight_element = pigmentation_element->find("weight"); weight_element != pigmentation_element->end())
431  weight = weight_element->get<float>();
432  if (auto gene_element = pigmentation_element->find("gene"); gene_element != pigmentation_element->end())
433  gene = resource_manager.load<ant_pigmentation_gene>(gene_element->get<std::string>());
434 
435  if (gene)
436  {
437  gene_pool.pigmentation.weights.push_back(weight);
438  gene_pool.pigmentation.genes.push_back(gene);
439  }
440  }
441  }
442 
443  // Load pilosity genes
444  if (auto pilosity_elements = genes_element->find("pilosity"); pilosity_elements != genes_element->end())
445  {
446  for (auto pilosity_element = pilosity_elements->begin(); pilosity_element != pilosity_elements->end(); ++pilosity_element)
447  {
448  float weight = 0.0f;
449  std::shared_ptr<ant_pilosity_gene> gene;
450 
451  if (auto weight_element = pilosity_element->find("weight"); weight_element != pilosity_element->end())
452  weight = weight_element->get<float>();
453  if (auto gene_element = pilosity_element->find("gene"); gene_element != pilosity_element->end())
454  gene = resource_manager.load<ant_pilosity_gene>(gene_element->get<std::string>());
455 
456  if (gene)
457  {
458  gene_pool.pilosity.weights.push_back(weight);
459  gene_pool.pilosity.genes.push_back(gene);
460  }
461  }
462  }
463 
464  // Load sculpturing genes
465  if (auto sculpturing_elements = genes_element->find("sculpturing"); sculpturing_elements != genes_element->end())
466  {
467  for (auto sculpturing_element = sculpturing_elements->begin(); sculpturing_element != sculpturing_elements->end(); ++sculpturing_element)
468  {
469  float weight = 0.0f;
470  std::shared_ptr<ant_sculpturing_gene> gene;
471 
472  if (auto weight_element = sculpturing_element->find("weight"); weight_element != sculpturing_element->end())
473  weight = weight_element->get<float>();
474  if (auto gene_element = sculpturing_element->find("gene"); gene_element != sculpturing_element->end())
475  gene = resource_manager.load<ant_sculpturing_gene>(gene_element->get<std::string>());
476 
477  if (gene)
478  {
479  gene_pool.sculpturing.weights.push_back(weight);
480  gene_pool.sculpturing.genes.push_back(gene);
481  }
482  }
483  }
484 
485  // Load sting genes
486  if (auto sting_elements = genes_element->find("sting"); sting_elements != genes_element->end())
487  {
488  for (auto sting_element = sting_elements->begin(); sting_element != sting_elements->end(); ++sting_element)
489  {
490  float weight = 0.0f;
491  std::shared_ptr<ant_sting_gene> gene;
492 
493  if (auto weight_element = sting_element->find("weight"); weight_element != sting_element->end())
494  weight = weight_element->get<float>();
495  if (auto gene_element = sting_element->find("gene"); gene_element != sting_element->end())
496  gene = resource_manager.load<ant_sting_gene>(gene_element->get<std::string>());
497 
498  if (gene)
499  {
500  gene_pool.sting.weights.push_back(weight);
501  gene_pool.sting.genes.push_back(gene);
502  }
503  }
504  }
505 
506  // Load waist genes
507  if (auto waist_elements = genes_element->find("waist"); waist_elements != genes_element->end())
508  {
509  for (auto waist_element = waist_elements->begin(); waist_element != waist_elements->end(); ++waist_element)
510  {
511  float weight = 0.0f;
512  std::shared_ptr<ant_waist_gene> gene;
513 
514  if (auto weight_element = waist_element->find("weight"); weight_element != waist_element->end())
515  weight = weight_element->get<float>();
516  if (auto gene_element = waist_element->find("gene"); gene_element != waist_element->end())
517  gene = resource_manager.load<ant_waist_gene>(gene_element->get<std::string>());
518 
519  if (gene)
520  {
521  gene_pool.waist.weights.push_back(weight);
522  gene_pool.waist.genes.push_back(gene);
523  }
524  }
525  }
526 
527  // Load wings genes
528  if (auto wings_elements = genes_element->find("wings"); wings_elements != genes_element->end())
529  {
530  for (auto wings_element = wings_elements->begin(); wings_element != wings_elements->end(); ++wings_element)
531  {
532  float weight = 0.0f;
533  std::shared_ptr<ant_wings_gene> gene;
534 
535  if (auto weight_element = wings_element->find("weight"); weight_element != wings_element->end())
536  weight = weight_element->get<float>();
537  if (auto gene_element = wings_element->find("gene"); gene_element != wings_element->end())
538  gene = resource_manager.load<ant_wings_gene>(gene_element->get<std::string>());
539 
540  if (gene)
541  {
542  gene_pool.wings.weights.push_back(weight);
543  gene_pool.wings.genes.push_back(gene);
544  }
545  }
546  }
547  }
548  }
549  }
550 
551  return ecoregion;
552 }
A material is associated with exactly one shader program and contains a set of material properties wh...
Definition: material.hpp:37
static std::unique_ptr< T > load(::resource_manager &resource_manager, deserialize_context &ctx)
Loads a resource.
Manages the loading, caching, and saving of resources.
std::shared_ptr< T > load(const std::filesystem::path &path)
Loads and caches a resource.
constexpr T radians(T degrees) noexcept
Converts an angle given in degrees to radians.
Definition: angles.hpp:48
Pool of ant genes from which ant genomes can be generated.
ant_gene_frequency_table< ant_ocelli_gene > ocelli
ant_gene_frequency_table< ant_waist_gene > waist
ant_gene_frequency_table< ant_body_size_gene > body_size
ant_gene_frequency_table< ant_legs_gene > legs
ant_gene_frequency_table< ant_sting_gene > sting
ant_gene_frequency_table< ant_foraging_time_gene > foraging_time
ant_gene_frequency_table< ant_founding_mode_gene > founding_mode
ant_gene_frequency_table< ant_pupa_gene > pupa
ant_gene_frequency_table< ant_pigmentation_gene > pigmentation
ant_gene_frequency_table< ant_mesosoma_gene > mesosoma
ant_gene_frequency_table< ant_mandibles_gene > mandibles
ant_gene_frequency_table< ant_pilosity_gene > pilosity
ant_gene_frequency_table< ant_eyes_gene > eyes
std::string name
Gene pool name.
ant_gene_frequency_table< ant_nest_site_gene > nest_site
ant_gene_frequency_table< ant_larva_gene > larva
ant_gene_frequency_table< ant_diet_gene > diet
ant_gene_frequency_table< ant_antennae_gene > antennae
ant_gene_frequency_table< ant_sculpturing_gene > sculpturing
ant_gene_frequency_table< ant_head_gene > head
ant_gene_frequency_table< ant_egg_gene > egg
ant_gene_frequency_table< ant_gaster_gene > gaster
ant_gene_frequency_table< ant_wings_gene > wings
Ant gene with caste-specific phenes.
Definition: ant-gene.hpp:50
Provides access to a deserialization state.
std::string name
Ecoregion name.
Definition: ecoregion.hpp:36
std::shared_ptr< render::material > horizon_material
Horizon material.
Definition: ecoregion.hpp:54
float latitude
Latitude, in radians.
Definition: ecoregion.hpp:42
math::fvec3 terrain_albedo
Terrain albedo.
Definition: ecoregion.hpp:51
std::shared_ptr< render::material > terrain_material
Terrain material.
Definition: ecoregion.hpp:48
float elevation
Elevation, in meters.
Definition: ecoregion.hpp:39
float longitude
Longitude, in radians.
Definition: ecoregion.hpp:45
std::vector< ant_gene_pool > gene_pools
Array of gene pools.
Definition: ecoregion.hpp:57