💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

470 lines
18 KiB

1 year ago
1 year ago
1 year ago
  1. /*
  2. * Copyright (C) 2021 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. #include "animation/ease.hpp"
  20. #include "animation/screen-transition.hpp"
  21. #include "configuration.hpp"
  22. #include "debug/logger.hpp"
  23. #include "entity/archetype.hpp"
  24. #include "game/components/cavity-component.hpp"
  25. #include "game/components/copy-transform-component.hpp"
  26. #include "game/components/copy-translation-component.hpp"
  27. #include "game/components/model-component.hpp"
  28. #include "game/components/snap-component.hpp"
  29. #include "game/components/samara-component.hpp"
  30. #include "game/components/terrain-component.hpp"
  31. #include "game/components/tool-component.hpp"
  32. #include "game/components/transform-component.hpp"
  33. #include "game/components/camera-follow-component.hpp"
  34. #include "game/components/orbit-component.hpp"
  35. #include "game/entity-commands.hpp"
  36. #include "game/game-context.hpp"
  37. #include "game/states/game-states.hpp"
  38. #include "math/math.hpp"
  39. #include "nest.hpp"
  40. #include "renderer/material.hpp"
  41. #include "rasterizer/texture-2d.hpp"
  42. #include "rasterizer/texture-filter.hpp"
  43. #include "rasterizer/texture-wrapping.hpp"
  44. #include "renderer/model.hpp"
  45. #include "renderer/passes/sky-pass.hpp"
  46. #include "resources/resource-manager.hpp"
  47. #include "scene/model-instance.hpp"
  48. #include "scene/scene.hpp"
  49. #include "scene/camera.hpp"
  50. #include "scene/ambient-light.hpp"
  51. #include "scene/directional-light.hpp"
  52. #include "scene/directional-light.hpp"
  53. #include "game/systems/control-system.hpp"
  54. #include "game/systems/camera-system.hpp"
  55. #include "game/systems/render-system.hpp"
  56. #include "game/systems/tool-system.hpp"
  57. #include "game/systems/weather-system.hpp"
  58. #include "game/systems/solar-system.hpp"
  59. #include "game/systems/astronomy-system.hpp"
  60. #include "game/biome.hpp"
  61. #include "utility/fundamental-types.hpp"
  62. #include "utility/gamma.hpp"
  63. #include "utility/bit-math.hpp"
  64. #include "genetics/genetics.hpp"
  65. #include <iostream>
  66. #include <bitset>
  67. #include <ctime>
  68. void play_state_enter(game_context* ctx)
  69. {
  70. logger* logger = ctx->logger;
  71. logger->push_task("Entering play state");
  72. // Load biome
  73. if (ctx->option_biome.has_value())
  74. {
  75. ctx->biome = ctx->resource_manager->load<biome>(ctx->option_biome.value() + ".bio");
  76. }
  77. else
  78. {
  79. ctx->biome = ctx->resource_manager->load<biome>("grassland.bio");
  80. }
  81. // Apply biome parameters to scene
  82. sky_pass* sky_pass = ctx->overworld_sky_pass;
  83. sky_pass->set_enabled(true);
  84. sky_pass->set_sky_model(ctx->resource_manager->load<model>("sky-dome.mdl"));
  85. sky_pass->set_moon_model(ctx->resource_manager->load<model>("moon.mdl"));
  86. ctx->weather_system->set_universal_time(0.0);
  87. ctx->solar_system->set_universal_time(0.0);
  88. ctx->astronomy_system->set_observer_location(double3{4.26352e-5, ctx->biome->location[0], ctx->biome->location[1]});
  89. ctx->astronomy_system->set_universal_time(0.0);
  90. ctx->astronomy_system->set_obliquity(math::radians(23.4393));
  91. ctx->astronomy_system->set_axial_rotation_at_epoch(math::radians(280.4606));
  92. ctx->astronomy_system->set_axial_rotation_speed(math::radians(360.9856));
  93. resource_manager* resource_manager = ctx->resource_manager;
  94. entt::registry& ecs_registry = *ctx->ecs_registry;
  95. ctx->sun_direct->set_intensity(1.0f);
  96. ctx->sun_direct->set_color({1, 1, 1});
  97. // Create sun
  98. {
  99. ecs::orbit_component sun_orbit;
  100. sun_orbit.elements.a = 1.0;
  101. sun_orbit.elements.ec = 0.016709;
  102. sun_orbit.elements.w = math::radians(282.9404);
  103. sun_orbit.elements.ma = math::radians(356.0470);
  104. sun_orbit.elements.i = 0.0;
  105. sun_orbit.elements.om = 0.0;
  106. sun_orbit.rate.a = 0.0;
  107. sun_orbit.rate.ec = -1.151e-9;
  108. sun_orbit.rate.w = math::radians(4.70935e-5);
  109. sun_orbit.rate.ma = math::radians(0.9856002585);
  110. sun_orbit.rate.i = 0.0;
  111. sun_orbit.rate.om = 0.0;
  112. ecs::transform_component sun_transform;
  113. sun_transform.local = math::identity_transform<float>;
  114. sun_transform.warp = true;
  115. auto sun_entity = ecs_registry.create();
  116. ecs_registry.assign<ecs::transform_component>(sun_entity, sun_transform);
  117. ecs_registry.assign<ecs::orbit_component>(sun_entity, sun_orbit);
  118. ctx->astronomy_system->set_sun(sun_entity);
  119. }
  120. // Create moon
  121. {
  122. ecs::orbit_component moon_orbit;
  123. moon_orbit.elements.a = 0.00256955529;
  124. moon_orbit.elements.ec = 0.0554;
  125. moon_orbit.elements.w = math::radians(318.15);
  126. moon_orbit.elements.ma = math::radians(135.27);
  127. moon_orbit.elements.i = math::radians(5.16);
  128. moon_orbit.elements.om = math::radians(125.08);
  129. moon_orbit.rate.a = 0.0;
  130. moon_orbit.rate.ec = 0.0;
  131. moon_orbit.rate.w = math::radians(0.1643573223); // Argument of periapsis precession period, P_w
  132. moon_orbit.rate.ma = math::radians(13.176358); // Longitude rate, n
  133. moon_orbit.rate.i = 0.0;
  134. moon_orbit.rate.om = math::radians(-18.6 / 365.2422); // Longitude of the ascending node precession period, P_node
  135. ecs::transform_component moon_transform;
  136. moon_transform.local = math::identity_transform<float>;
  137. moon_transform.warp = true;
  138. auto moon_entity = ecs_registry.create();
  139. ecs_registry.assign<ecs::transform_component>(moon_entity, moon_transform);
  140. ecs_registry.assign<ecs::orbit_component>(moon_entity, moon_orbit);
  141. ctx->astronomy_system->set_moon(moon_entity);
  142. }
  143. // Load entity archetypes
  144. ecs::archetype* ant_hill_archetype = resource_manager->load<ecs::archetype>("ant-hill.ent");
  145. ecs::archetype* maple_tree_archetype = resource_manager->load<ecs::archetype>("maple-tree.ent");
  146. ecs::archetype* nest_archetype = resource_manager->load<ecs::archetype>("harvester-nest.ent");
  147. ecs::archetype* samara_archetype = resource_manager->load<ecs::archetype>("samara.ent");
  148. ecs::archetype* forceps_archetype = resource_manager->load<ecs::archetype>("forceps.ent");
  149. ecs::archetype* lens_archetype = resource_manager->load<ecs::archetype>("lens.ent");
  150. ecs::archetype* brush_archetype = resource_manager->load<ecs::archetype>("brush.ent");
  151. ecs::archetype* marker_archetype = resource_manager->load<ecs::archetype>("marker.ent");
  152. ecs::archetype* container_archetype = resource_manager->load<ecs::archetype>("container.ent");
  153. ecs::archetype* twig_archetype = resource_manager->load<ecs::archetype>("twig.ent");
  154. ecs::archetype* larva_archetype = resource_manager->load<ecs::archetype>("larva.ent");
  155. ecs::archetype* pebble_archetype = resource_manager->load<ecs::archetype>("pebble.ent");
  156. ecs::archetype* flashlight_archetype = resource_manager->load<ecs::archetype>("flashlight.ent");
  157. ecs::archetype* flashlight_light_cone_archetype = resource_manager->load<ecs::archetype>("flashlight-light-cone.ent");
  158. ecs::archetype* lens_light_cone_archetype = resource_manager->load<ecs::archetype>("lens-light-cone.ent");
  159. ecs::archetype* ant_head_archetype = resource_manager->load<ecs::archetype>("ant-head.ent");
  160. ecs::archetype* dandelion_plant_archetype = resource_manager->load<ecs::archetype>("dandelion-plant.ent");
  161. ecs::archetype* grassland_road_archetype = resource_manager->load<ecs::archetype>("grassland-road.ent");
  162. // Create tools
  163. forceps_archetype->assign(ecs_registry, ctx->forceps_entity);
  164. lens_archetype->assign(ecs_registry, ctx->lens_entity);
  165. brush_archetype->assign(ecs_registry, ctx->brush_entity);
  166. marker_archetype->assign(ecs_registry, ctx->marker_entity);
  167. container_archetype->assign(ecs_registry, ctx->container_entity);
  168. twig_archetype->assign(ecs_registry, ctx->twig_entity);
  169. // Create flashlight and light cone, set light cone parent to flashlight, and move both to underworld scene
  170. flashlight_archetype->assign(ecs_registry, ctx->flashlight_entity);
  171. auto flashlight_light_cone = flashlight_light_cone_archetype->create(ecs_registry);
  172. ec::parent(ecs_registry, flashlight_light_cone, ctx->flashlight_entity);
  173. ec::assign_render_layers(ecs_registry, ctx->flashlight_entity, 2);
  174. // Make lens tool's model instance unculled, so its shadow is always visible.
  175. model_instance* lens_model_instance = ctx->render_system->get_model_instance(ctx->lens_entity);
  176. if (lens_model_instance)
  177. {
  178. lens_model_instance->set_culling_mask(&ctx->no_cull);
  179. }
  180. // Create lens light cone and set its parent to lens
  181. auto lens_light_cone = lens_light_cone_archetype->create(ecs_registry);
  182. //ec::bind_transform(ecs_registry, lens_light_cone, ctx->lens_entity);
  183. ec::parent(ecs_registry, lens_light_cone, ctx->lens_entity);
  184. // Hide inactive tools
  185. ec::assign_render_layers(ecs_registry, ctx->forceps_entity, 0);
  186. ec::assign_render_layers(ecs_registry, ctx->brush_entity, 0);
  187. ec::assign_render_layers(ecs_registry, ctx->lens_entity, 0);
  188. ec::assign_render_layers(ecs_registry, ctx->marker_entity, 0);
  189. ec::assign_render_layers(ecs_registry, ctx->container_entity, 0);
  190. ec::assign_render_layers(ecs_registry, ctx->twig_entity, 0);
  191. // Activate brush tool
  192. ctx->tool_system->set_active_tool(ctx->brush_entity);
  193. // Create background
  194. for (int i = 0; i < 4; ++i)
  195. {
  196. auto road_entity = grassland_road_archetype->create(ecs_registry);
  197. auto& transform = ecs_registry.get<ecs::transform_component>(road_entity);
  198. math::quaternion<float> rotation = math::angle_axis(math::half_pi<float> * static_cast<float>(i), float3{0, 1, 0});
  199. float3 translation = rotation * float3{0, 0, 1600.0f};
  200. transform.local = math::identity_transform<float>;
  201. transform.local.rotation = rotation;
  202. transform.local.translation = translation;
  203. }
  204. // Create ant-hill
  205. auto ant_hill_entity = ant_hill_archetype->create(ecs_registry);
  206. ec::place(ecs_registry, ant_hill_entity, {0, 0});
  207. // Generate pebbles
  208. float pebble_radius = 300.0f;
  209. int pebble_count = 20;
  210. for (int i = 0; i < pebble_count; ++i)
  211. {
  212. float x = math::random(-pebble_radius, pebble_radius);
  213. float z = math::random(-pebble_radius, pebble_radius);
  214. auto pebble_entity = ant_head_archetype->create(ecs_registry);
  215. auto& transform = ecs_registry.get<ecs::transform_component>(pebble_entity);
  216. transform.local = math::identity_transform<float>;
  217. transform.local.rotation = math::angle_axis(math::random(0.0f, math::two_pi<float>), {0, 1, 0});
  218. transform.local.scale = float3{1, 1, 1} * math::random(0.75f, 1.25f);
  219. ec::place(ecs_registry, pebble_entity, {x, z});
  220. }
  221. // Create maple tree
  222. //auto maple_tree_entity = maple_tree_archetype->create(ecs_registry);
  223. //ec::place(ecs_registry, maple_tree_entity, {300, 200});
  224. // Creat nest
  225. auto nest_entity = nest_archetype->create(ecs_registry);
  226. // Create terrain
  227. int terrain_radius = 6;
  228. for (int x = -terrain_radius; x <= terrain_radius; ++x)
  229. {
  230. for (int z = -terrain_radius; z <= terrain_radius; ++z)
  231. {
  232. ecs::terrain_component terrain_component;
  233. terrain_component.subdivisions = TERRAIN_PATCH_RESOLUTION;
  234. terrain_component.x = x;
  235. terrain_component.z = z;
  236. auto terrain_entity = ecs_registry.create();
  237. ecs_registry.assign<ecs::terrain_component>(terrain_entity, terrain_component);
  238. }
  239. }
  240. // Create samaras
  241. for (int i = 0; i < 15; ++i)
  242. {
  243. auto samara_entity = samara_archetype->create(ecs_registry);
  244. auto& transform = ecs_registry.get<ecs::transform_component>(samara_entity);
  245. float zone = 200.0f;
  246. transform.local = math::identity_transform<float>;
  247. transform.local.translation.x = math::random(-zone, zone);
  248. transform.local.translation.y = math::random(50.0f, 150.0f);
  249. transform.local.translation.z = math::random(-zone, zone);
  250. ecs::samara_component samara_component;
  251. samara_component.angle = math::random(0.0f, math::radians(360.0f));
  252. samara_component.direction = math::normalize(float3{math::random(-1.0f, 1.0f), math::random(-1.0f, -5.0f), math::random(-1.0f, 1.0f)});
  253. samara_component.chirality = (math::random(0.0f, 1.0f) < 0.5f) ? -1.0f : 1.0f;
  254. ecs_registry.assign_or_replace<ecs::samara_component>(samara_entity, samara_component);
  255. }
  256. // Setup camera focal point
  257. ecs::transform_component focal_point_transform;
  258. focal_point_transform.local = math::identity_transform<float>;
  259. focal_point_transform.warp = true;
  260. ecs::camera_follow_component focal_point_follow;
  261. ecs::snap_component focal_point_snap;
  262. focal_point_snap.ray = {float3{0, 10000, 0}, float3{0, -1, 0}};
  263. focal_point_snap.warp = false;
  264. focal_point_snap.relative = true;
  265. focal_point_snap.autoremove = false;
  266. ecs_registry.assign_or_replace<ecs::transform_component>(ctx->focal_point_entity, focal_point_transform);
  267. ecs_registry.assign_or_replace<ecs::camera_follow_component>(ctx->focal_point_entity, focal_point_follow);
  268. ecs_registry.assign_or_replace<ecs::snap_component>(ctx->focal_point_entity, focal_point_snap);
  269. // Setup camera
  270. ctx->overworld_camera->look_at({0, 0, 1}, {0, 0, 0}, {0, 1, 0});
  271. ctx->camera_system->set_camera(ctx->overworld_camera);
  272. auto ant_head = ant_head_archetype->create(ecs_registry);
  273. ec::place(ecs_registry, ant_head, {50, 0});
  274. ctx->overworld_scene->update_tweens();
  275. // Allocate a nest
  276. nest* nest = new ::nest();
  277. // Setup initial nest parameters
  278. float tunnel_radius = 1.15f;
  279. nest->set_tunnel_radius(tunnel_radius);
  280. nest::shaft* central_shaft = nest->get_central_shaft();
  281. central_shaft->chirality = 1.0f;
  282. central_shaft->rotation = math::radians(0.0f);
  283. central_shaft->depth = {0.0f, 200.0f};
  284. central_shaft->radius = {15.0f, 15.0f};
  285. central_shaft->pitch = {40.0f, 40.0f};
  286. central_shaft->translation = {{{0.0f, 0.0f}, {0.0f, 0.0f}}};
  287. central_shaft->current_depth = 0.0f;
  288. for (std::size_t i = 0; i < 4; ++i)
  289. {
  290. nest::chamber chamber;
  291. chamber.shaft = central_shaft;
  292. chamber.depth = (i + 1) * 50.0f;
  293. chamber.rotation = math::radians(0.0f);
  294. chamber.inner_radius = 4.0f;
  295. chamber.outer_radius = 10.0f;
  296. central_shaft->chambers.push_back(chamber);
  297. }
  298. // Dig nest shafts
  299. float shift = 0.1f;
  300. for (int i = 0; i < 800; ++i)
  301. {
  302. ecs::cavity_component cavity;
  303. cavity.position = nest->extend_shaft(*nest->get_central_shaft());
  304. cavity.position += float3{math::random(-shift, shift), math::random(-shift, shift), math::random(-shift, shift)};
  305. cavity.radius = tunnel_radius * math::random(1.0f, 1.1f);
  306. ecs_registry.assign<ecs::cavity_component>(ecs_registry.create(), cavity);
  307. }
  308. // Dig nest chambers
  309. /*
  310. for (int i = 0; i < central_shaft->chambers.size(); ++i)
  311. {
  312. for (int j = 0; j < 150; ++j)
  313. {
  314. ecs::cavity_component cavity;
  315. cavity.position = nest->expand_chamber(central_shaft->chambers[i]);
  316. cavity.position += float3{math::random(-shift, shift), math::random(-shift, shift), math::random(-shift, shift)};
  317. cavity.radius = tunnel_radius * math::random(1.0f, 1.1f);
  318. ecs_registry.assign<ecs::cavity_component>(ecs_registry.create(), cavity);
  319. }
  320. }
  321. */
  322. // Place larva in chamber
  323. {
  324. auto larva = larva_archetype->create(ecs_registry);
  325. ec::assign_render_layers(ecs_registry, larva, 1);
  326. ec::warp_to(ecs_registry, larva, {50, 0.1935f, 10});
  327. //auto& transform = ecs_registry.get<ecs::transform_component>(larva_entity);
  328. //transform.transform = math::identity_transform<float>;
  329. //transform.transform.translation = nest->get_shaft_position(*central_shaft, central_shaft->depth[1]);
  330. //transform.transform.translation.y -= 1.0f;
  331. }
  332. auto dandelion_plant = dandelion_plant_archetype->create(ecs_registry);
  333. ec::place(ecs_registry, dandelion_plant, {55, -30});
  334. control_system* control_system = ctx->control_system;
  335. control_system->update(0.0, 0.0);
  336. control_system->set_nest(nest);
  337. // Start fade in
  338. ctx->fade_transition->transition(1.0f, true, ease<float>::in_quad);
  339. logger->pop_task(EXIT_SUCCESS);
  340. std::string biome_name = (*ctx->strings)[ctx->biome->name];
  341. logger->log("Entered biome \"" + biome_name + "\"");
  342. std::srand(std::time(nullptr));
  343. //auto rng = [](){ return std::rand(); };
  344. std::random_device rd;
  345. std::mt19937 rng(rd());
  346. std::string sequence_a = "CCTTGCCCTTTGGGTCGCCCCCCTAG";
  347. std::string sequence_b = "ATGTTTCCCGAAGGGTAG";
  348. std::string sequence_c = "AAATGCCCCCCCCCCCCCCCCCCCCCCCCCCCTAGAAAAAAAAA";
  349. std::string orf_a;
  350. std::string protein_a;
  351. std::string protein_b;
  352. std::string protein_c;
  353. std::cout << "sequence a: " << sequence_a << std::endl;
  354. genetics::sequence::transcribe(sequence_a.begin(), sequence_a.end(), sequence_a.begin());
  355. std::cout << "sequence a: " << sequence_a << std::endl;
  356. std::string complement;
  357. genetics::sequence::rna::complement(sequence_a.begin(), sequence_a.end(), std::back_inserter(complement));
  358. std::cout << "complement: " << complement << std::endl;
  359. auto orf = genetics::sequence::find_orf(sequence_a.begin(), sequence_a.end(), genetics::standard_code);
  360. if (orf.start != sequence_a.end())
  361. {
  362. std::copy(orf.start, orf.stop, std::back_inserter(orf_a));
  363. std::cout << "orf a: " << orf_a << std::endl;
  364. genetics::sequence::translate(orf.start, orf.stop, std::back_inserter(protein_a), genetics::standard_code);
  365. std::cout << "protein a: " << protein_a << std::endl;
  366. }
  367. protein_b = "MFFFFP";
  368. protein_c = "MFFFYP";
  369. int score;
  370. std::cout << std::endl;
  371. std::cout << "protein_b: " << protein_b << std::endl;
  372. std::cout << "protein_c: " << protein_c << std::endl;
  373. score = genetics::protein::score(protein_b.begin(), protein_b.end(), protein_c.begin(), genetics::matrix::blosum62<int>);
  374. std::cout << "score blosum62: " << score << std::endl;
  375. score = genetics::protein::score(protein_b.begin(), protein_b.end(), protein_c.begin(), genetics::matrix::blosum80<int>);
  376. std::cout << "score blosum80: " << score << std::endl;
  377. std::cout << "identity : " << genetics::protein::identity<float>(protein_b.begin(), protein_b.end(), protein_c.begin()) << std::endl;
  378. std::cout << "similarity62: " << genetics::protein::similarity<float>(protein_b.begin(), protein_b.end(), protein_c.begin(), genetics::matrix::blosum62<int>) << std::endl;
  379. std::cout << "similarity80: " << genetics::protein::similarity<float>(protein_b.begin(), protein_b.end(), protein_c.begin(), genetics::matrix::blosum80<int>) << std::endl;
  380. }
  381. void play_state_exit(game_context* ctx)
  382. {
  383. logger* logger = ctx->logger;
  384. logger->push_task("Exiting play state");
  385. logger->pop_task(EXIT_SUCCESS);
  386. }