68 #include <engine/config.hpp>
114 std::shared_ptr<render::model> worker_model =
ant_morphogenesis(*worker_phenome);
125 auto nest_exterior_rigid_body = std::make_unique<physics::rigid_body>();
126 nest_exterior_rigid_body->set_mass(0.0f);
127 nest_exterior_rigid_body->set_collider(std::make_shared<physics::mesh_collider>(std::move(nest_exterior_mesh)));
128 nest_exterior_rigid_body->set_position({10, -20, -5});
130 nest_exterior_rigid_body->set_scale({0.5f, 1.0f, 0.75f});
141 nest_interior_scene_component.
object->set_layer_mask(0b10);
146 auto nest_interior_rigid_body = std::make_unique<physics::rigid_body>();
147 nest_interior_rigid_body->set_mass(0.0f);
148 nest_interior_rigid_body->set_collider(std::make_shared<physics::mesh_collider>(std::move(nest_interior_mesh)));
149 nest_interior_rigid_body->get_collider()->set_layer_mask(0b10);
162 transform.scale.x() = 2000.0f;
163 transform.scale.y() = 400.0f;
164 transform.scale.z() = transform.scale.x();
166 transform.translation.y() = -transform.scale.y() * 0.5f;
178 scene.layer_mask = 1;
183 const auto hit_distance = std::get<1>(*
trace);
184 const auto& hit_normal = std::get<3>(*
trace);
196 area_light = std::make_unique<scene::rectangle_light>();
197 area_light->set_luminous_flux(12.57f * 100.0f);
198 area_light->set_color_temperature(20000.0f);
199 area_light->set_translation({0.0f, 0.0f, 0.0f});
201 area_light->set_size({1.0f, 2.0f});
202 area_light->set_layer_mask(0b10);
207 auto light_rectangle_material = std::make_shared<render::material>(*light_rectangle_model->get_groups().front().material);
208 light_rectangle_emissive = std::static_pointer_cast<render::matvar_fvec3>(light_rectangle_material->get_variable(
"emissive"));
209 light_rectangle_emissive->set(area_light->get_colored_luminance());
210 auto light_rectangle_static_mesh = std::make_shared<scene::static_mesh>(light_rectangle_model);
211 light_rectangle_static_mesh->set_material(0, light_rectangle_material);
212 light_rectangle_static_mesh->set_transform(area_light->get_transform());
213 light_rectangle_static_mesh->set_layer_mask(area_light->get_layer_mask());
219 auto worker_skeletal_mesh = std::make_unique<scene::skeletal_mesh>(worker_model);
220 worker_skeletal_mesh->set_layer_mask(0b11);
223 const auto& worker_skeleton = worker_model->get_skeleton();
224 worker_ik_rig = std::make_shared<ik_rig>(*worker_skeletal_mesh);
225 auto mesocoxa_ik_constraint = std::make_shared<euler_ik_constraint>();
226 mesocoxa_ik_constraint->set_min_angles({-math::pi<float>, -math::pi<float>, -math::pi<float>});
227 mesocoxa_ik_constraint->set_max_angles({ math::pi<float>, math::pi<float>, math::pi<float>});
228 worker_ik_rig->set_constraint(*worker_skeleton.get_bone_index(
"mesocoxa_l"), std::move(mesocoxa_ik_constraint));
231 worker_skeletal_mesh->get_pose() = *worker_model->get_skeleton().get_pose(
"midswing");
244 worker_caste_component.
phenome = worker_phenome;
247 worker_rigid_body_component.
body = std::make_unique<physics::rigid_body>();
248 worker_rigid_body_component.
body->set_mass(0.0f);
249 auto rigid_body_transform = worker_rigid_body_component.
body->get_transform();
250 rigid_body_transform.scale =
math::fvec3::one() * worker_phenome->body_size->mean_mesosoma_length;
251 worker_rigid_body_component.
body->set_transform(rigid_body_transform);
258 worker_locomotion_component.
body_bone = *worker_skeleton.get_bone_index(
"mesosoma");
261 *worker_skeleton.get_bone_index(
"protarsomere1_l"),
262 *worker_skeleton.get_bone_index(
"mesotarsomere1_l"),
263 *worker_skeleton.get_bone_index(
"metatarsomere1_l"),
264 *worker_skeleton.get_bone_index(
"protarsomere1_r"),
265 *worker_skeleton.get_bone_index(
"mesotarsomere1_r"),
266 *worker_skeleton.get_bone_index(
"metatarsomere1_r")
269 worker_locomotion_component.
gait = std::make_shared<::gait>();
270 worker_locomotion_component.
gait->frequency = 4.0f;
271 worker_locomotion_component.
gait->steps.resize(6);
272 for (std::size_t i = 0; i < 6; ++i)
274 const float duty_factors[3] = {0.52f, 0.62f, 0.54f};
275 auto&
step = worker_locomotion_component.
gait->steps[i];
279 worker_locomotion_component.
standing_height = worker_phenome->legs->standing_height;
280 worker_locomotion_component.
stride_length = worker_phenome->legs->stride_length * worker_rigid_body_component.
body->get_transform().scale.x();
289 worker_ovary_component.
ovipositor_bone = *worker_skeleton.get_bone_index(
"gaster");
290 worker_ovary_component.
oviposition_path = {{0.0f, -0.141708f, -0.799793f}, {0.0f, -0.187388f, -1.02008f}};
308 color_checker_scene_component.
object->set_translation({0, 0, 4});
316 double time_scale = 0.0;
324 sky_probe = std::make_shared<scene::light_probe>();
325 const std::uint32_t sky_probe_face_size = 128;
326 const auto sky_probe_mip_levels =
static_cast<std::uint32_t
>(std::bit_width(sky_probe_face_size));
327 sky_probe->set_luminance_texture
329 std::make_shared<gl::texture_cube>
331 std::make_shared<gl::image_view_cube>
333 std::make_shared<gl::image_cube>
343 std::make_shared<gl::sampler>
361 const auto& viewport_size =
ctx.
window->get_viewport_size();
362 const float aspect_ratio =
static_cast<float>(viewport_size[0]) /
static_cast<float>(viewport_size[1]);
365 create_third_person_camera_rig();
402 destroy_third_person_camera_rig();
407 void treadmill_experiment_state::create_third_person_camera_rig()
410 const auto subject_scale =
static_cast<double>(subject_rigid_body.get_transform().scale.x());
419 spring_arm.
zoom = 0.25;
420 spring_arm.
focal_point_offset = {0,
static_cast<double>(worker_phenome->legs->standing_height) * subject_scale, 0};
428 spring_arm.
min_angles.
x() = -math::half_pi<double>;
437 void treadmill_experiment_state::destroy_third_person_camera_rig()
442 void treadmill_experiment_state::set_third_person_camera_zoom(
double zoom)
446 void treadmill_experiment_state::set_third_person_camera_rotation(
double yaw,
double pitch)
450 void treadmill_experiment_state::zoom_third_person_camera(
double zoom)
454 void treadmill_experiment_state::translate_third_person_camera(
const math::dvec3& direction,
double magnitude)
466 if (!mouse_look && !mouse_grip && !mouse_zoom)
477 third_person_camera_focal_plane_width * (
static_cast<double>(-
event.difference.x()) / (viewport_size.
x() - 1.0)),
479 third_person_camera_focal_plane_height * (
static_cast<double>(-
event.difference.y()) / (viewport_size.
y() - 1.0)),
482 if (third_person_camera_pitch < 0.0)
484 translation.z() *= -1.0;
487 third_person_camera_focal_point += third_person_camera_yaw_rotation * translation;
492 rotate_third_person_camera(
event);
497 const double zoom_speed = -1.0 /
static_cast<double>(
ctx.
window->get_viewport_size().y());
498 zoom_third_person_camera(
static_cast<double>(
event.difference.y()) * zoom_speed);
501 update_third_person_camera();
504 void treadmill_experiment_state::update_third_person_camera()
508 void treadmill_experiment_state::load_camera_preset(std::uint8_t index)
513 void treadmill_experiment_state::save_camera_preset(std::uint8_t index)
518 void treadmill_experiment_state::load_or_save_camera_preset(std::uint8_t index)
526 const auto& viewport_size =
ctx.
window->get_viewport_size();
531 static_cast<float>(mouse_position.
x()) /
static_cast<float>(viewport_size.
x() - 1) * 2.0f - 1.0f,
532 (1.0f -
static_cast<float>(mouse_position.
y()) /
static_cast<float>(viewport_size.
y() - 1)) * 2.0f - 1.0f
538 return camera.pick(mouse_ndc);
541 void treadmill_experiment_state::setup_controls()
544 action_subscriptions.emplace_back
548 [&](
const auto&
event)
550 mouse_grip = ctx.toggle_mouse_grip ? !mouse_grip : true;
554 const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position();
557 const auto mouse_ray = get_mouse_ray(mouse_position);
558 const auto intersection = geom::intersection(mouse_ray, mouse_grip_plane);
561 mouse_grip_point = mouse_ray.origin + mouse_ray.direction * (*intersection);
566 const auto& mouse_position = (*
ctx.
input_manager->get_mice().begin())->get_position();
567 const auto mouse_ray = get_mouse_ray(mouse_position);
575 const auto& hit_rigid_body = *ctx.entity_registry->get<rigid_body_component>(std::get<0>(*trace)).body;
576 const auto& hit_collider = *hit_rigid_body.get_collider();
577 const auto hit_distance = std::get<1>(*trace);
578 const auto& hit_normal = std::get<3>(*trace);
580 geom::brep_mesh* hit_mesh = nullptr;
581 geom::brep_face* hit_face = nullptr;
582 if (hit_collider.type() == physics::collider_type::mesh)
584 hit_mesh = static_cast<const physics::mesh_collider&>(hit_collider).get_mesh().get();
585 hit_face = hit_mesh->faces()[std::get<2>(*trace)];
590 auto agent_transform = agent_rigid_body.get_transform();
591 agent_transform.translation = mouse_ray.extrapolate(hit_distance);
593 agent_rigid_body.set_transform(agent_transform);
594 agent_rigid_body.set_previous_transform(agent_transform);
602 component.navmesh_eid = std::get<0>(*trace);
603 component.mesh = hit_mesh;
604 component.face = hit_face;
605 component.surface_normal = hit_normal;
std::unique_ptr< ant_genome > ant_cladogenesis(const ant_gene_pool &pool, URBG &urbg)
Generates an ant genome from a gene pool.
void disable_ant_controls(::game &ctx)
void enable_ant_controls(::game &ctx)
std::unique_ptr< render::model > ant_morphogenesis(const ant_phenome &phenome)
Generates a 3D model of an ant given its phenome.
void disable_camera_controls(::game &ctx)
void enable_camera_controls(::game &ctx)
void refresh() noexcept
Resets the accumulated time (at) and frame timer, but not the elapsed fixed-rate update time.
Abstract base class for game states.
std::unique_ptr<::terrain_system > terrain_system
std::unique_ptr< render::material_pass > surface_material_pass
std::unique_ptr< scene::collection > surface_scene
::frame_scheduler frame_scheduler
entity::id active_camera_eid
std::unique_ptr< screen_transition > fade_transition
std::shared_ptr< scene::camera > surface_camera
scene::collection * active_scene
std::shared_ptr< ecoregion > active_ecoregion
std::unique_ptr< resource_manager > resource_manager
std::unique_ptr< render::sky_pass > sky_pass
std::shared_ptr< app::window > window
std::queue< std::function< void()> > function_queue
std::shared_ptr< render::matvar_fvec3 > fade_transition_color
input::action camera_mouse_pick_action
std::unique_ptr<::physics_system > physics_system
entity::id controlled_ant_eid
std::unique_ptr< entity::registry > entity_registry
std::unique_ptr< app::input_manager > input_manager
Boundary representation (B-rep) of a mesh.
const skeleton * get_skeleton() const noexcept
Returns the skeleton with which the pose is associated.
A material is associated with exactly one shader program and contains a set of material properties wh...
void set_rotation(const quaternion_type &rotation)
Sets the rotation of the object.
void set_translation(const vector_type &translation)
Sets the translation of the object.
Abstract base class for lights, cameras, model instances, and other scene objects.
void transition(float duration, bool reverse, animation< float >::interpolator_type interpolator, bool hide=true, const std::function< void()> &callback=nullptr)
const animation_pose * get_pose(hash::fnv1a32_t name) const
Finds a pose from the poses's name.
const rest_pose & get_rest_pose() const noexcept
Returns the skeleton's rest pose.
treadmill_experiment_state(::game &ctx)
~treadmill_experiment_state() override
void enable_game_controls(::game &ctx)
void disable_game_controls(::game &ctx)
log_message< log_message_severity::trace, Args... > log_trace
Formats and logs a trace message.
Publish-subscribe messaging.
@ clamp_to_edge
Clamp to edge wrap mode.
@ linear
Linear filtering.
@ linear
Linear filtering.
dvec< 2 > dvec2
n-dimensional vector of double-precision floating-point numbers.
constexpr T trace(const matrix< T, N, N > &m) noexcept
Calculates the trace of a square matrix.
quaternion< T > angle_axis(T angle, const vec3< T > &axis)
Creates a rotation from an angle and axis.
constexpr T radians(T degrees) noexcept
Converts an angle given in degrees to radians.
quaternion< T > rotation(const vec3< T > &from, const vec3< T > &to, T tolerance=T{1e-6})
Constructs a quaternion representing the minimum rotation from one direction to another direction.
T from_settings(T n, T t, T s)
Exposure value from exposure settings.
void enter_ecoregion(::game &ctx, const ecoregion &ecoregion)
Enters a ecoregion.
void set_time_scale(::game &ctx, double scale)
Sets rate at which time passes.
void set_time(::game &ctx, double t)
Sets the current time.
std::shared_ptr< ant_phenome > phenome
Subcaste type.
ant_caste_type type
Caste type.
Container for templated easing functions.
Half of a line proceeding from an initial point.
Legged terrestrial locomotion.
const pose * midswing_pose
float max_angular_frequency
Maximum angular frequency when turning, in radians per second.
const pose * liftoff_pose
std::shared_ptr<::gait > gait
std::uint8_t leg_bone_count
Number of bones per leg.
bone_index_type body_bone
float stride_length
Distance covered in a single gait cycle.
const pose * midstance_pose
std::vector< bone_index_type > tip_bones
Indices of the the final bones in the legs.
const pose * touchdown_pose
static quaternion rotate_x(scalar_type angle)
Returns a quaternion representing a rotation about the x-axis.
constexpr element_type & x() noexcept
Returns a reference to the first element.
constexpr element_type & y() noexcept
Returns a reference to the second element.
static constexpr vector one() noexcept
Returns a vector of ones, where every element is equal to one.
geom::line_segment< float, 3 > oviposition_path
Path along which eggs travel while being oviposited, relative to the ovipositor bone.
bone_index_type ovipositor_bone
Bone of the ovipositor.
std::uint16_t egg_capacity
Maximum number of concurrent eggs.
float oviposition_duration
Duration required to lay an egg, in seconds.
float egg_production_duration
Duration required to produce an egg, in seconds.
pose current_pose
Pose of the current state.
pose previous_pose
Pose of the previous state.
std::unique_ptr< physics::rigid_body > body
std::shared_ptr< scene::object_base > object
Attaches a camera to an entity using springs.
double near_hfov
Horizontal FoV at maximum zoom.
double far_hfov
Horizontal FoV at minimum zoom.
physics::numeric_spring< math::dvec3, double > focal_point_spring
double zoom
Zoom factor, on [0, 1].
math::dvec3 min_angles
Minimum pitch, yaw, and roll angles, in radians.
double far_focal_plane_height
Arm length spring.
math::dvec3 max_angles
Maximum pitch, yaw, and roll angles, in radians.
physics::numeric_spring< math::dvec3, double > angles_spring
Pitch, yaw, and roll angles spring.
entity::id parent_eid
ID of the entity to which the spring arm is attached.
math::dvec3 focal_point_offset
Position of the focal point, relative to the subject.
double near_focal_plane_height
Height of the view frustum at the near clipping distance.
Describes the timing of a single step in a gait.
float delay
Fraction of the gait cycle, on [0, 1], at which the limb enters the swing phase.
float duty_factor
Fraction of the gait cycle, on [0, 1], in which the limb is in the stance phase.