Browse Source

Add spring system. Improve orbit cam and first person cam

master
C. J. Howard 2 years ago
parent
commit
8bc2811081
19 changed files with 1148 additions and 1001 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +15
    -0
      src/animation/spring.hpp
  3. +81
    -0
      src/game/component/spring.hpp
  4. +2
    -0
      src/game/context.hpp
  5. +6
    -1
      src/game/state/boot.cpp
  6. +7
    -4
      src/game/state/main-menu.cpp
  7. +411
    -658
      src/game/state/nest-selection.cpp
  8. +26
    -6
      src/game/state/nest-selection.hpp
  9. +111
    -38
      src/game/state/nuptial-flight.cpp
  10. +13
    -1
      src/game/state/nuptial-flight.hpp
  11. +0
    -3
      src/game/state/splash.cpp
  12. +1
    -1
      src/game/system/constraint.cpp
  13. +80
    -0
      src/game/system/spring.cpp
  14. +44
    -0
      src/game/system/spring.hpp
  15. +287
    -287
      src/geom/marching-cubes.cpp
  16. +0
    -1
      src/geom/marching-cubes.hpp
  17. +1
    -1
      src/geom/mesh-accelerator.hpp
  18. +1
    -0
      src/math/math.hpp
  19. +61
    -0
      src/math/projection.hpp

+ 1
- 0
CMakeLists.txt View File

@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.7) cmake_minimum_required(VERSION 3.7)
option(VERSION_STRING "Project version string" "0.0.0") option(VERSION_STRING "Project version string" "0.0.0")
project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX) project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX)

+ 15
- 0
src/animation/spring.hpp View File

@ -84,6 +84,15 @@ T hz_to_rads(T hz);
template <typename T> template <typename T>
T rads_to_hz(T rads); T rads_to_hz(T rads);
/**
* Converts a period from seconds to radians per second.
*
* @param t Period, in seconds.
* @return Angular frequency, in radians per second.
*/
template <typename T>
T period_to_rads(T t);
template <typename T, typename S> template <typename T, typename S>
void spring(T& x0, T& v, const T& x1, S z, S w, S dt) void spring(T& x0, T& v, const T& x1, S z, S w, S dt)
{ {
@ -116,4 +125,10 @@ inline T rads_to_hz(T rads)
return rads / math::two_pi<T>; return rads / math::two_pi<T>;
} }
template <typename T>
inline T period_to_rads(T t)
{
return math::two_pi<T> / t;
}
#endif // ANTKEEPER_SPRING_HPP #endif // ANTKEEPER_SPRING_HPP

+ 81
- 0
src/game/component/spring.hpp View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_GAME_COMPONENT_SPRING_HPP
#define ANTKEEPER_GAME_COMPONENT_SPRING_HPP
#include "animation/spring.hpp"
#include "utility/fundamental-types.hpp"
#include <functional>
namespace game {
namespace component {
/**
* Numeric spring with one component.
*/
struct spring1
{
/// Numeric spring with one component.
numeric_spring<float, float> spring;
/// Spring solved callback.
std::function<void(float)> callback;
};
/**
* Numeric spring with two components.
*/
struct spring2
{
/// Numeric spring with two components.
numeric_spring<float2, float> spring;
/// Spring solved callback.
std::function<void(const float2&)> callback;
};
/**
* Numeric spring with three components.
*/
struct spring3
{
/// Numeric spring with three components.
numeric_spring<float3, float> spring;
/// Spring solved callback.
std::function<void(const float3&)> callback;
};
/**
* Numeric spring with four components.
*/
struct spring4
{
/// Numeric spring with four components.
numeric_spring<float4, float> spring;
/// Spring solved callback.
std::function<void(const float4&)> callback;
};
} // namespace component
} // namespace game
#endif // ANTKEEPER_GAME_COMPONENT_SPRING_HPP

+ 2
- 0
src/game/context.hpp View File

@ -98,6 +98,7 @@ namespace game
class samara; class samara;
class proteome; class proteome;
class steering; class steering;
class spring;
} }
} }
@ -286,6 +287,7 @@ struct context
game::system::subterrain* subterrain_system; game::system::subterrain* subterrain_system;
game::system::terrain* terrain_system; game::system::terrain* terrain_system;
game::system::vegetation* vegetation_system; game::system::vegetation* vegetation_system;
game::system::spring* spring_system;
game::system::spatial* spatial_system; game::system::spatial* spatial_system;
game::system::painting* painting_system; game::system::painting* painting_system;
game::system::blackbody* blackbody_system; game::system::blackbody* blackbody_system;

+ 6
- 1
src/game/state/boot.cpp View File

@ -75,6 +75,7 @@
#include "game/system/orbit.hpp" #include "game/system/orbit.hpp"
#include "game/system/proteome.hpp" #include "game/system/proteome.hpp"
#include "game/system/steering.hpp" #include "game/system/steering.hpp"
#include "game/system/spring.hpp"
#include "entity/commands.hpp" #include "entity/commands.hpp"
#include "utility/paths.hpp" #include "utility/paths.hpp"
#include "event/event-dispatcher.hpp" #include "event/event-dispatcher.hpp"
@ -874,6 +875,9 @@ void boot::setup_systems()
// Setup steering system // Setup steering system
ctx.steering_system = new game::system::steering(*ctx.entity_registry); ctx.steering_system = new game::system::steering(*ctx.entity_registry);
// Setup spring system
ctx.spring_system = new game::system::spring(*ctx.entity_registry);
// Setup spatial system // Setup spatial system
ctx.spatial_system = new game::system::spatial(*ctx.entity_registry); ctx.spatial_system = new game::system::spatial(*ctx.entity_registry);
@ -892,7 +896,7 @@ void boot::setup_systems()
ctx.blackbody_system->set_illuminant(color::illuminant::deg2::d55<double>); ctx.blackbody_system->set_illuminant(color::illuminant::deg2::d55<double>);
// RGB wavelengths for atmospheric scatteering // RGB wavelengths for atmospheric scatteering
ctx.rgb_wavelengths = {645, 575, 440};
ctx.rgb_wavelengths = {640, 575, 440};
// Setup atmosphere system // Setup atmosphere system
ctx.atmosphere_system = new game::system::atmosphere(*ctx.entity_registry); ctx.atmosphere_system = new game::system::atmosphere(*ctx.entity_registry);
@ -1139,6 +1143,7 @@ void boot::setup_loop()
ctx.blackbody_system->update(t, dt); ctx.blackbody_system->update(t, dt);
ctx.atmosphere_system->update(t, dt); ctx.atmosphere_system->update(t, dt);
ctx.astronomy_system->update(t, dt); ctx.astronomy_system->update(t, dt);
ctx.spring_system->update(t, dt);
ctx.spatial_system->update(t, dt); ctx.spatial_system->update(t, dt);
ctx.constraint_system->update(t, dt); ctx.constraint_system->update(t, dt);
ctx.painting_system->update(t, dt); ctx.painting_system->update(t, dt);

+ 7
- 4
src/game/state/main-menu.cpp View File

@ -246,7 +246,7 @@ main_menu::main_menu(game::context& ctx, bool fade_in):
{ {
game::world::cosmogenesis(ctx); game::world::cosmogenesis(ctx);
game::world::create_observer(ctx); game::world::create_observer(ctx);
game::load::biome(ctx, "debug.bio");
game::load::biome(ctx, "desert-scrub.bio");
} }
// Set world time // Set world time
@ -257,9 +257,13 @@ main_menu::main_menu(game::context& ctx, bool fade_in):
ctx.surface_camera->set_active(true); ctx.surface_camera->set_active(true);
const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f); const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f);
ctx.surface_camera->set_exposure(15.5f);
ctx.surface_camera->set_exposure(ev100_sunny16);
ctx.surface_camera->look_at({0, 10, 0}, {0, 0, 0}, {0, 0, 1});
const auto& viewport_dimensions = ctx.app->get_viewport_dimensions();
const float aspect_ratio = static_cast<float>(viewport_dimensions[0]) / static_cast<float>(viewport_dimensions[1]);
ctx.surface_camera->look_at({0, 3.0f, 0}, {0, 0, 0}, {0, 0, 1});
ctx.surface_camera->set_perspective(math::vertical_fov(math::radians(100.0f), aspect_ratio), ctx.surface_camera->get_aspect_ratio(), ctx.surface_camera->get_clip_near(), ctx.surface_camera->get_clip_far());
ctx.surface_camera->update_tweens(); ctx.surface_camera->update_tweens();
// Setup and enable sky and ground passes // Setup and enable sky and ground passes
@ -271,7 +275,6 @@ main_menu::main_menu(game::context& ctx, bool fade_in):
//if (!ctx.menu_bg_billboard->is_active()) //if (!ctx.menu_bg_billboard->is_active())
// game::menu::fade_in_bg(ctx); // game::menu::fade_in_bg(ctx);
ctx.logger->pop_task(EXIT_SUCCESS); ctx.logger->pop_task(EXIT_SUCCESS);
} }

+ 411
- 658
src/game/state/nest-selection.cpp
File diff suppressed because it is too large
View File


+ 26
- 6
src/game/state/nest-selection.hpp View File

@ -21,6 +21,8 @@
#define ANTKEEPER_GAME_STATE_NEST_SELECTION_HPP #define ANTKEEPER_GAME_STATE_NEST_SELECTION_HPP
#include "game/state/base.hpp" #include "game/state/base.hpp"
#include "entity/id.hpp"
#include "utility/fundamental-types.hpp"
namespace game { namespace game {
namespace state { namespace state {
@ -32,15 +34,33 @@ public:
virtual ~nest_selection(); virtual ~nest_selection();
private: private:
void setup_camera();
void create_first_person_camera_rig();
void destroy_first_person_camera_rig();
void set_first_person_camera_rig_pedestal(float pedestal);
void move_first_person_camera_rig(const float2& direction, float factor);
void satisfy_first_person_camera_rig_constraints();
bool is_keeper;
void enable_keeper_controls();
void disable_keeper_controls();
void enable_ant_controls();
void disable_ant_controls();
void enable_controls(); void enable_controls();
void disable_controls(); void disable_controls();
entity::id first_person_camera_rig_eid;
entity::id first_person_camera_rig_spring_translation_eid;
entity::id first_person_camera_rig_spring_rotation_eid;
entity::id first_person_camera_rig_fov_spring_eid;
float first_person_camera_rig_translation_spring_angular_frequency;
float first_person_camera_rig_rotation_spring_angular_frequency;
float first_person_camera_rig_fov_spring_angular_frequency;
float first_person_camera_rig_min_elevation;
float first_person_camera_rig_max_elevation;
float first_person_camera_near_fov;
float first_person_camera_far_fov;
float first_person_camera_near_speed;
float first_person_camera_far_speed;
float first_person_camera_rig_pedestal_speed;
float first_person_camera_rig_pedestal;
bool mouse_look;
}; };
} // namespace state } // namespace state

+ 111
- 38
src/game/state/nuptial-flight.cpp View File

@ -19,6 +19,7 @@
#include "game/state/nuptial-flight.hpp" #include "game/state/nuptial-flight.hpp"
#include "game/state/pause-menu.hpp" #include "game/state/pause-menu.hpp"
#include "game/state/nest-selection.hpp"
#include "game/ant/swarm.hpp" #include "game/ant/swarm.hpp"
#include "entity/archetype.hpp" #include "entity/archetype.hpp"
#include "game/system/camera.hpp" #include "game/system/camera.hpp"
@ -34,6 +35,8 @@
#include "game/component/constraint-stack.hpp" #include "game/component/constraint-stack.hpp"
#include "game/component/steering.hpp" #include "game/component/steering.hpp"
#include "game/component/picking.hpp" #include "game/component/picking.hpp"
#include "game/component/spring.hpp"
#include "math/projection.hpp"
#include "game/controls.hpp" #include "game/controls.hpp"
#include "entity/commands.hpp" #include "entity/commands.hpp"
#include "animation/screen-transition.hpp" #include "animation/screen-transition.hpp"
@ -83,7 +86,7 @@ nuptial_flight::nuptial_flight(game::context& ctx):
} }
// Load biome // Load biome
game::load::biome(ctx, "desert-scrub.bio");
//game::load::biome(ctx, "desert-scrub.bio");
// Set world time // Set world time
game::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0); game::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0);
@ -106,6 +109,26 @@ nuptial_flight::nuptial_flight(game::context& ctx):
const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f); const float ev100_sunny16 = physics::light::ev::from_settings(16.0f, 1.0f / 100.0f, 100.0f);
ctx.surface_camera->set_exposure(ev100_sunny16); ctx.surface_camera->set_exposure(ev100_sunny16);
const auto& viewport_dimensions = ctx.app->get_viewport_dimensions();
const float aspect_ratio = static_cast<float>(viewport_dimensions[0]) / static_cast<float>(viewport_dimensions[1]);
// Init camera rig params
camera_rig_near_distance = 1.0f;
camera_rig_far_distance = 150.0f;
camera_rig_near_fov = math::vertical_fov(math::radians(100.0f), aspect_ratio);
camera_rig_far_fov = math::vertical_fov(math::radians(60.0f), aspect_ratio);
camera_rig_zoom_speed = 4.0f;
camera_rig_translation_spring_angular_frequency = period_to_rads(0.125f);
camera_rig_rotation_spring_angular_frequency = period_to_rads(0.125f);
camera_rig_fov_spring_angular_frequency = period_to_rads(0.125f);
camera_rig_focus_ease_to_duration = 1.0f;
// Read camera rig settingss
if (ctx.config->contains("near_fov"))
camera_rig_near_fov = math::vertical_fov(math::radians((*ctx.config)["near_fov"].get<float>()), aspect_ratio);
if (ctx.config->contains("far_fov"))
camera_rig_far_fov = math::vertical_fov(math::radians((*ctx.config)["far_fov"].get<float>()), aspect_ratio);
// Create camera rig // Create camera rig
create_camera_rig(); create_camera_rig();
@ -150,7 +173,7 @@ void nuptial_flight::create_camera_rig()
component::constraint::ease_to camera_rig_focus_ease_to; component::constraint::ease_to camera_rig_focus_ease_to;
camera_rig_focus_ease_to.target = selected_eid; camera_rig_focus_ease_to.target = selected_eid;
camera_rig_focus_ease_to.start = {0, 0, 0}; camera_rig_focus_ease_to.start = {0, 0, 0};
camera_rig_focus_ease_to.duration = 1.0f;
camera_rig_focus_ease_to.duration = camera_rig_focus_ease_to_duration;
camera_rig_focus_ease_to.t = camera_rig_focus_ease_to.duration; camera_rig_focus_ease_to.t = camera_rig_focus_ease_to.duration;
camera_rig_focus_ease_to.function = &ease<float3, float>::out_expo; camera_rig_focus_ease_to.function = &ease<float3, float>::out_expo;
component::constraint_stack_node camera_rig_focus_ease_to_node; component::constraint_stack_node camera_rig_focus_ease_to_node;
@ -215,7 +238,7 @@ void nuptial_flight::create_camera_rig()
{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f},
1.0f, 1.0f,
hz_to_rads(8.0f)
camera_rig_rotation_spring_angular_frequency
}; };
component::constraint_stack_node camera_rig_spring_rotation_node; component::constraint_stack_node camera_rig_spring_rotation_node;
camera_rig_spring_rotation_node.active = true; camera_rig_spring_rotation_node.active = true;
@ -233,7 +256,7 @@ void nuptial_flight::create_camera_rig()
{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f},
1.0f, 1.0f,
hz_to_rads(8.0f)
camera_rig_translation_spring_angular_frequency
}; };
component::constraint_stack_node camera_rig_spring_translation_node; component::constraint_stack_node camera_rig_spring_translation_node;
camera_rig_spring_translation_node.active = true; camera_rig_spring_translation_node.active = true;
@ -264,6 +287,25 @@ void nuptial_flight::create_camera_rig()
ctx.entity_registry->emplace<component::transform>(camera_rig_eid, camera_rig_transform); ctx.entity_registry->emplace<component::transform>(camera_rig_eid, camera_rig_transform);
ctx.entity_registry->emplace<component::constraint_stack>(camera_rig_eid, camera_rig_constraint_stack); ctx.entity_registry->emplace<component::constraint_stack>(camera_rig_eid, camera_rig_constraint_stack);
// Construct camera rig fov spring
component::spring1 camera_rig_fov_spring;
camera_rig_fov_spring.spring =
{
0.0f,
0.0f,
0.0f,
1.0f,
camera_rig_fov_spring_angular_frequency
};
camera_rig_fov_spring.callback = [&](float fov)
{
ctx.surface_camera->set_perspective(fov, ctx.surface_camera->get_aspect_ratio(), ctx.surface_camera->get_clip_near(), ctx.surface_camera->get_clip_far());
};
// Construct camera rig fov spring entity
camera_rig_fov_spring_eid = ctx.entity_registry->create();
ctx.entity_registry->emplace<component::spring1>(camera_rig_fov_spring_eid, camera_rig_fov_spring);
set_camera_rig_zoom(0.25f); set_camera_rig_zoom(0.25f);
} }
@ -277,16 +319,15 @@ void nuptial_flight::destroy_camera_rig()
ctx.entity_registry->destroy(camera_rig_focus_eid); ctx.entity_registry->destroy(camera_rig_focus_eid);
ctx.entity_registry->destroy(camera_rig_focus_ease_to_eid); ctx.entity_registry->destroy(camera_rig_focus_ease_to_eid);
ctx.entity_registry->destroy(camera_rig_fov_spring_eid);
} }
void nuptial_flight::set_camera_rig_zoom(float zoom) void nuptial_flight::set_camera_rig_zoom(float zoom)
{ {
const float near_distance = 1.0f;
const float far_distance = 50.0f;
camera_rig_zoom = zoom; camera_rig_zoom = zoom;
const float distance = math::log_lerp(far_distance, near_distance, camera_rig_zoom);
const float distance = math::log_lerp(camera_rig_far_distance, camera_rig_near_distance, camera_rig_zoom);
ctx.entity_registry->patch<component::constraint::spring_translation> ctx.entity_registry->patch<component::constraint::spring_translation>
( (
camera_rig_spring_translation_eid, camera_rig_spring_translation_eid,
@ -295,11 +336,21 @@ void nuptial_flight::set_camera_rig_zoom(float zoom)
component.spring.x1[2] = distance; component.spring.x1[2] = distance;
} }
); );
const float fov = math::log_lerp(camera_rig_far_fov, camera_rig_near_fov, camera_rig_zoom);
ctx.entity_registry->patch<component::spring1>
(
camera_rig_fov_spring_eid,
[&](auto& component)
{
component.spring.x1 = fov;
}
);
} }
void nuptial_flight::satisfy_camera_rig_constraints() void nuptial_flight::satisfy_camera_rig_constraints()
{ {
// Warp camera rig focus ease to
// Satisfy camera rig focus ease to constraint
ctx.entity_registry->patch<component::constraint::ease_to> ctx.entity_registry->patch<component::constraint::ease_to>
( (
camera_rig_focus_ease_to_eid, camera_rig_focus_ease_to_eid,
@ -309,7 +360,7 @@ void nuptial_flight::satisfy_camera_rig_constraints()
} }
); );
// Warp camera rig spring translation
// Satisfy camera rig spring translation constraint
ctx.entity_registry->patch<component::constraint::spring_translation> ctx.entity_registry->patch<component::constraint::spring_translation>
( (
camera_rig_spring_translation_eid, camera_rig_spring_translation_eid,
@ -320,7 +371,7 @@ void nuptial_flight::satisfy_camera_rig_constraints()
} }
); );
// Warp camera rig spring rotation
// Satisfy camera rig spring rotation constraint
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
@ -330,6 +381,17 @@ void nuptial_flight::satisfy_camera_rig_constraints()
component.spring.v *= 0.0f; component.spring.v *= 0.0f;
} }
); );
// Satisfycamera rig fov spring
ctx.entity_registry->patch<component::spring1>
(
camera_rig_fov_spring_eid,
[&](auto& component)
{
component.spring.x0 = component.spring.x1;
component.spring.v *= 0.0f;
}
);
} }
void nuptial_flight::enable_controls() void nuptial_flight::enable_controls()
@ -339,7 +401,6 @@ void nuptial_flight::enable_controls()
double time_scale = 0.0; double time_scale = 0.0;
double ff_time_scale = 60.0 * 200.0; double ff_time_scale = 60.0 * 200.0;
const float dolly_zoom_speed = 4.0f;
// Init control settings // Init control settings
float mouse_tilt_sensitivity = 1.0f; float mouse_tilt_sensitivity = 1.0f;
@ -414,7 +475,7 @@ void nuptial_flight::enable_controls()
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
[&](auto& component)
[&, mouse_pan_factor](auto& component)
{ {
component.spring.x1[0] -= mouse_pan_factor * value; component.spring.x1[0] -= mouse_pan_factor * value;
} }
@ -428,7 +489,7 @@ void nuptial_flight::enable_controls()
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
[&](auto& component)
[&, gamepad_pan_factor](auto& component)
{ {
component.spring.x1[0] -= gamepad_pan_factor * value * static_cast<float>(ctx.loop.get_update_period()); component.spring.x1[0] -= gamepad_pan_factor * value * static_cast<float>(ctx.loop.get_update_period());
} }
@ -447,7 +508,7 @@ void nuptial_flight::enable_controls()
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
[&](auto& component)
[&, mouse_pan_factor](auto& component)
{ {
component.spring.x1[0] += mouse_pan_factor * value; component.spring.x1[0] += mouse_pan_factor * value;
} }
@ -461,7 +522,7 @@ void nuptial_flight::enable_controls()
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
[&](auto& component)
[&, gamepad_pan_factor](auto& component)
{ {
component.spring.x1[0] += gamepad_pan_factor * value * static_cast<float>(ctx.loop.get_update_period()); component.spring.x1[0] += gamepad_pan_factor * value * static_cast<float>(ctx.loop.get_update_period());
} }
@ -480,7 +541,7 @@ void nuptial_flight::enable_controls()
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
[&](auto& component)
[&, mouse_tilt_factor](auto& component)
{ {
component.spring.x1[1] -= mouse_tilt_factor * value; component.spring.x1[1] -= mouse_tilt_factor * value;
component.spring.x1[1] = std::max(-math::half_pi<float>, component.spring.x1[1]); component.spring.x1[1] = std::max(-math::half_pi<float>, component.spring.x1[1]);
@ -495,7 +556,7 @@ void nuptial_flight::enable_controls()
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
[&](auto& component)
[&, gamepad_tilt_factor](auto& component)
{ {
component.spring.x1[1] -= gamepad_tilt_factor * value * static_cast<float>(ctx.loop.get_update_period()); component.spring.x1[1] -= gamepad_tilt_factor * value * static_cast<float>(ctx.loop.get_update_period());
component.spring.x1[1] = std::max(-math::half_pi<float>, component.spring.x1[1]); component.spring.x1[1] = std::max(-math::half_pi<float>, component.spring.x1[1]);
@ -515,7 +576,7 @@ void nuptial_flight::enable_controls()
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
[&](auto& component)
[&, mouse_tilt_factor](auto& component)
{ {
component.spring.x1[1] += mouse_tilt_factor * value; component.spring.x1[1] += mouse_tilt_factor * value;
component.spring.x1[1] = std::min(math::half_pi<float>, component.spring.x1[1]); component.spring.x1[1] = std::min(math::half_pi<float>, component.spring.x1[1]);
@ -530,7 +591,7 @@ void nuptial_flight::enable_controls()
ctx.entity_registry->patch<component::constraint::spring_rotation> ctx.entity_registry->patch<component::constraint::spring_rotation>
( (
camera_rig_spring_rotation_eid, camera_rig_spring_rotation_eid,
[&](auto& component)
[&, gamepad_tilt_factor](auto& component)
{ {
component.spring.x1[1] += gamepad_tilt_factor * value * static_cast<float>(ctx.loop.get_update_period()); component.spring.x1[1] += gamepad_tilt_factor * value * static_cast<float>(ctx.loop.get_update_period());
component.spring.x1[1] = std::min(math::half_pi<float>, component.spring.x1[1]); component.spring.x1[1] = std::min(math::half_pi<float>, component.spring.x1[1]);
@ -542,18 +603,18 @@ void nuptial_flight::enable_controls()
// Dolly in control // Dolly in control
ctx.controls["move_up"]->set_active_callback ctx.controls["move_up"]->set_active_callback
( (
[&, dolly_zoom_speed](float value)
[&](float value)
{ {
set_camera_rig_zoom(std::min(1.0f, camera_rig_zoom + dolly_zoom_speed * static_cast<float>(ctx.loop.get_update_period())));
set_camera_rig_zoom(std::min(1.0f, camera_rig_zoom + camera_rig_zoom_speed * static_cast<float>(ctx.loop.get_update_period())));
} }
); );
// Dolly out control // Dolly out control
ctx.controls["move_down"]->set_active_callback ctx.controls["move_down"]->set_active_callback
( (
[&, dolly_zoom_speed](float value)
[&](float value)
{ {
set_camera_rig_zoom(std::max(0.0f, camera_rig_zoom - dolly_zoom_speed * static_cast<float>(ctx.loop.get_update_period())));
set_camera_rig_zoom(std::max(0.0f, camera_rig_zoom - camera_rig_zoom_speed * static_cast<float>(ctx.loop.get_update_period())));
} }
); );
@ -628,7 +689,12 @@ void nuptial_flight::enable_controls()
( (
[&]() [&]()
{ {
// Disable controls
disable_controls();
// Change to nest selection state
ctx.state_machine.pop();
ctx.state_machine.emplace(new game::state::nest_selection(ctx));
} }
); );
@ -781,30 +847,37 @@ void nuptial_flight::disable_controls()
ctx.app->set_relative_mouse_mode(false); ctx.app->set_relative_mouse_mode(false);
} }
ctx.controls["move_forward"]->set_activated_callback(nullptr);
ctx.controls["move_back"]->set_activated_callback(nullptr);
ctx.controls["move_right"]->set_activated_callback(nullptr);
ctx.controls["move_left"]->set_activated_callback(nullptr);
ctx.controls["move_up"]->set_active_callback(nullptr);
ctx.controls["move_down"]->set_active_callback(nullptr);
ctx.controls["mouse_look"]->set_activated_callback(nullptr); ctx.controls["mouse_look"]->set_activated_callback(nullptr);
ctx.controls["mouse_look"]->set_deactivated_callback(nullptr); ctx.controls["mouse_look"]->set_deactivated_callback(nullptr);
ctx.controls["look_left_gamepad"]->set_active_callback(nullptr);
ctx.controls["look_left_mouse"]->set_active_callback(nullptr);
ctx.controls["look_right_gamepad"]->set_active_callback(nullptr);
ctx.controls["look_right_mouse"]->set_active_callback(nullptr); ctx.controls["look_right_mouse"]->set_active_callback(nullptr);
ctx.controls["look_up_gamepad"]->set_active_callback(nullptr);
ctx.controls["look_right_gamepad"]->set_active_callback(nullptr);
ctx.controls["look_left_mouse"]->set_active_callback(nullptr);
ctx.controls["look_left_gamepad"]->set_active_callback(nullptr);
ctx.controls["look_up_mouse"]->set_active_callback(nullptr); ctx.controls["look_up_mouse"]->set_active_callback(nullptr);
ctx.controls["look_down_gamepad"]->set_active_callback(nullptr);
ctx.controls["look_up_gamepad"]->set_active_callback(nullptr);
ctx.controls["look_down_mouse"]->set_active_callback(nullptr); ctx.controls["look_down_mouse"]->set_active_callback(nullptr);
ctx.controls["look_down_gamepad"]->set_active_callback(nullptr);
ctx.controls["move_up"]->set_active_callback(nullptr);
ctx.controls["move_down"]->set_active_callback(nullptr);
ctx.controls["select_mouse"]->set_activated_callback(nullptr); ctx.controls["select_mouse"]->set_activated_callback(nullptr);
ctx.controls["move_forward"]->set_activated_callback(nullptr);
ctx.controls["move_back"]->set_activated_callback(nullptr);
ctx.controls["move_right"]->set_activated_callback(nullptr);
ctx.controls["move_left"]->set_activated_callback(nullptr);
ctx.controls["action"]->set_activated_callback(nullptr); ctx.controls["action"]->set_activated_callback(nullptr);
ctx.controls["switch_pov"]->set_activated_callback(nullptr);
ctx.controls["fast_forward"]->set_activated_callback(nullptr); ctx.controls["fast_forward"]->set_activated_callback(nullptr);
ctx.controls["fast_forward"]->set_deactivated_callback(nullptr);
ctx.controls["rewind"]->set_activated_callback(nullptr); ctx.controls["rewind"]->set_activated_callback(nullptr);
ctx.controls["rewind"]->set_deactivated_callback(nullptr);
ctx.controls["pause"]->set_activated_callback(nullptr); ctx.controls["pause"]->set_activated_callback(nullptr);
ctx.controls["increase_exposure"]->set_activated_callback(nullptr);
ctx.controls["decrease_exposure"]->set_activated_callback(nullptr);
ctx.controls["increase_exposure"]->set_active_callback(nullptr);
ctx.controls["decrease_exposure"]->set_active_callback(nullptr);
ctx.controls["dec_red"]->set_active_callback(nullptr);
ctx.controls["inc_red"]->set_active_callback(nullptr);
ctx.controls["dec_green"]->set_active_callback(nullptr);
ctx.controls["inc_green"]->set_active_callback(nullptr);
ctx.controls["dec_blue"]->set_active_callback(nullptr);
ctx.controls["inc_blue"]->set_active_callback(nullptr);
} }
void nuptial_flight::select_entity(entity::id entity_id) void nuptial_flight::select_entity(entity::id entity_id)

+ 13
- 1
src/game/state/nuptial-flight.hpp View File

@ -54,9 +54,21 @@ private:
entity::id camera_rig_spring_rotation_eid; entity::id camera_rig_spring_rotation_eid;
entity::id camera_rig_copy_translation_eid; entity::id camera_rig_copy_translation_eid;
entity::id camera_rig_pivot_eid; entity::id camera_rig_pivot_eid;
float camera_rig_near_distance;
float camera_rig_far_distance;
float camera_rig_near_fov;
float camera_rig_far_fov;
float camera_rig_zoom_speed;
float camera_rig_zoom; float camera_rig_zoom;
entity::id camera_rig_fov_spring_eid;
float camera_rig_translation_spring_angular_frequency;
float camera_rig_rotation_spring_angular_frequency;
float camera_rig_fov_spring_angular_frequency;
float camera_rig_focus_ease_to_duration;
entity::id swarm_eid; entity::id swarm_eid;
std::uint32_t selected_picking_flag; std::uint32_t selected_picking_flag;

+ 0
- 3
src/game/state/splash.cpp View File

@ -19,7 +19,6 @@
#include "game/state/splash.hpp" #include "game/state/splash.hpp"
#include "game/state/main-menu.hpp" #include "game/state/main-menu.hpp"
#include "game/state/nuptial-flight.hpp"
#include "animation/screen-transition.hpp" #include "animation/screen-transition.hpp"
#include "animation/animation.hpp" #include "animation/animation.hpp"
#include "animation/animator.hpp" #include "animation/animator.hpp"
@ -118,7 +117,6 @@ splash::splash(game::context& ctx):
{ {
ctx.state_machine.pop(); ctx.state_machine.pop();
ctx.state_machine.emplace(new game::state::main_menu(ctx, true)); ctx.state_machine.emplace(new game::state::main_menu(ctx, true));
//ctx.state_machine.emplace(new game::state::nuptial_flight(ctx));
} }
); );
} }
@ -147,7 +145,6 @@ splash::splash(game::context& ctx):
// Change to main menu state // Change to main menu state
ctx.state_machine.pop(); ctx.state_machine.pop();
ctx.state_machine.emplace(new game::state::main_menu(ctx, true)); ctx.state_machine.emplace(new game::state::main_menu(ctx, true));
//ctx.state_machine.emplace(new game::state::nuptial_flight(ctx));
} }
} }
); );

+ 1
- 1
src/game/system/constraint.cpp View File

@ -17,7 +17,7 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "constraint.hpp"
#include "game/system/constraint.hpp"
#include "game/component/constraint-stack.hpp" #include "game/component/constraint-stack.hpp"
namespace game { namespace game {

+ 80
- 0
src/game/system/spring.cpp View File

@ -0,0 +1,80 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "game/system/spring.hpp"
#include "game/component/spring.hpp"
#include "entity/id.hpp"
namespace game {
namespace system {
spring::spring(entity::registry& registry):
updatable(registry)
{}
spring::~spring()
{}
void spring::update(double t, double dt)
{
const float dtf = static_cast<float>(dt);
registry.view<component::spring1>().each
(
[&](entity::id spring_eid, auto& component)
{
solve_numeric_spring<float, float>(component.spring, dtf);
if (component.callback)
component.callback(component.spring.x0);
}
);
registry.view<component::spring2>().each
(
[&](entity::id spring_eid, auto& component)
{
solve_numeric_spring<float2, float>(component.spring, dtf);
if (component.callback)
component.callback(component.spring.x0);
}
);
registry.view<component::spring3>().each
(
[&](entity::id spring_eid, auto& component)
{
solve_numeric_spring<float3, float>(component.spring, dtf);
if (component.callback)
component.callback(component.spring.x0);
}
);
registry.view<component::spring4>().each
(
[&](entity::id spring_eid, auto& component)
{
solve_numeric_spring<float4, float>(component.spring, dtf);
if (component.callback)
component.callback(component.spring.x0);
}
);
}
} // namespace system
} // namespace game

+ 44
- 0
src/game/system/spring.hpp View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_GAME_SYSTEM_SPRING_HPP
#define ANTKEEPER_GAME_SYSTEM_SPRING_HPP
#include "game/system/updatable.hpp"
namespace game {
namespace system {
/**
* Solves numeric springs.
*/
class spring:
public updatable
{
public:
spring(entity::registry& registry);
~spring();
virtual void update(double t, double dt);
};
} // namespace system
} // namespace game
#endif // ANTKEEPER_GAME_SYSTEM_SPRING_HPP

+ 287
- 287
src/geom/marching-cubes.cpp View File

@ -41,297 +41,297 @@ static constexpr std::uint_fast8_t vertex_table[12][2] =
static constexpr std::uint_fast16_t edge_table[256] = static constexpr std::uint_fast16_t edge_table[256] =
{ {
0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c,
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac,
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
0x460, 0x569, 0x663, 0x76a, 0x066, 0x16f, 0x265, 0x36c,
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc,
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c,
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc,
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
0x15c, 0x055, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000
0x000, 0x109, 0x203, 0x30A, 0x406, 0x50F, 0x605, 0x70C,
0x80C, 0x905, 0xA0F, 0xB06, 0xC0A, 0xD03, 0xE09, 0xF00,
0x190, 0x099, 0x393, 0x29A, 0x596, 0x49F, 0x795, 0x69C,
0x99C, 0x895, 0xB9F, 0xA96, 0xD9A, 0xC93, 0xF99, 0xE90,
0x230, 0x339, 0x033, 0x13A, 0x636, 0x73F, 0x435, 0x53C,
0xA3C, 0xB35, 0x83F, 0x936, 0xE3A, 0xF33, 0xC39, 0xD30,
0x3A0, 0x2A9, 0x1A3, 0x0AA, 0x7A6, 0x6AF, 0x5A5, 0x4AC,
0xBAC, 0xAA5, 0x9AF, 0x8A6, 0xFAA, 0xEA3, 0xDA9, 0xCA0,
0x460, 0x569, 0x663, 0x76A, 0x066, 0x16F, 0x265, 0x36C,
0xC6C, 0xD65, 0xE6F, 0xF66, 0x86A, 0x963, 0xA69, 0xB60,
0x5F0, 0x4F9, 0x7F3, 0x6FA, 0x1F6, 0x0FF, 0x3F5, 0x2FC,
0xDFC, 0xCF5, 0xFFF, 0xEF6, 0x9FA, 0x8F3, 0xBF9, 0xAF0,
0x650, 0x759, 0x453, 0x55A, 0x256, 0x35F, 0x055, 0x15C,
0xE5C, 0xF55, 0xC5F, 0xD56, 0xA5A, 0xB53, 0x859, 0x950,
0x7C0, 0x6C9, 0x5C3, 0x4CA, 0x3C6, 0x2CF, 0x1C5, 0x0CC,
0xFCC, 0xEC5, 0xDCF, 0xCC6, 0xBCA, 0xAC3, 0x9C9, 0x8C0,
0x8C0, 0x9C9, 0xAC3, 0xBCA, 0xCC6, 0xDCF, 0xEC5, 0xFCC,
0x0CC, 0x1C5, 0x2CF, 0x3C6, 0x4CA, 0x5C3, 0x6C9, 0x7C0,
0x950, 0x859, 0xB53, 0xA5A, 0xD56, 0xC5F, 0xF55, 0xE5C,
0x15C, 0x055, 0x35F, 0x256, 0x55A, 0x453, 0x759, 0x650,
0xAF0, 0xBF9, 0x8F3, 0x9FA, 0xEF6, 0xFFF, 0xCF5, 0xDFC,
0x2FC, 0x3F5, 0x0FF, 0x1F6, 0x6FA, 0x7F3, 0x4F9, 0x5F0,
0xB60, 0xA69, 0x963, 0x86A, 0xF66, 0xE6F, 0xD65, 0xC6C,
0x36C, 0x265, 0x16F, 0x066, 0x76A, 0x663, 0x569, 0x460,
0xCA0, 0xDA9, 0xEA3, 0xFAA, 0x8A6, 0x9AF, 0xAA5, 0xBAC,
0x4AC, 0x5A5, 0x6AF, 0x7A6, 0x0AA, 0x1A3, 0x2A9, 0x3A0,
0xD30, 0xC39, 0xF33, 0xE3A, 0x936, 0x83F, 0xB35, 0xA3C,
0x53C, 0x435, 0x73F, 0x636, 0x13A, 0x033, 0x339, 0x230,
0xE90, 0xF99, 0xC93, 0xD9A, 0xA96, 0xB9F, 0x895, 0x99C,
0x69C, 0x795, 0x49F, 0x596, 0x29A, 0x393, 0x099, 0x190,
0xF00, 0xE09, 0xD03, 0xC0A, 0xB06, 0xA0F, 0x905, 0x80C,
0x70C, 0x605, 0x50F, 0x406, 0x30A, 0x203, 0x109, 0x000
}; };
static constexpr std::int_fast8_t triangle_table[256][16] = static constexpr std::int_fast8_t triangle_table[256][16] =
{
{
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
{ 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
{ 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
{ 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
{ 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
{ 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
{ 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
{ 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
{ 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
{ 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
{ 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
{ 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
{ 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
{ 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
{ 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
{ 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
{ 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
{ 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
{ 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
{ 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
{ 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
{ 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
{ 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
{ 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
{ 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
{ 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
{ 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
{ 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
{ 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
{ 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
{ 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
{ 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
{ 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
{ 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
{ 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
{ 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
{ 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
{ 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
{ 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
{ 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
{ 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
{ 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
{ 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
{ 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
{ 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
{ 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
{ 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
{ 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
{ 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
{ 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
{ 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
{ 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
{ 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
{ 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
{ 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
{ 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
{ 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
{ 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
{ 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
{ 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
{ 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
{ 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
{ 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
{ 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
{ 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
{ 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
{ 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
{ 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
{ 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
{ 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
{ 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
{ 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
{ 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
{ 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
{ 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
{ 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
{ 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
{ 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
{ 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
{ 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
{ 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
{ 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
{ 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
{ 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
{ 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
{ 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
{ 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
{ 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
{ 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
{ 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
{ 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
{ 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
{ 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
{ 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
{ 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
{ 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
{ 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
{ 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
{ 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
{ 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
{ 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
{ 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
{ 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
{ 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
{ 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
{ 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
{ 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
{ 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
{ 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
{ 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
{ 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
{ 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
{ 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
{ 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
{ 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
{ 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
{ 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
{ 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
{ 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
{ 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
{ 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
{ 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
{ 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
{ 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
{ 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
{ 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
{ 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
{ 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
{ 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
{ 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
{ 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
{ 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
{ 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
{ 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
{ 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
{ 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
{ 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
{ 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
{ 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
{ 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
{ 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
{ 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
{ 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
{ 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
{ 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
{ 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
{ 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
{ 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
{ 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
{ 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
{ 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
{ 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{ 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
}; };

+ 0
- 1
src/geom/marching-cubes.hpp View File

@ -56,4 +56,3 @@ constexpr float unit_cube[8][3] =
} // namespace geom } // namespace geom
#endif // ANTKEEPER_GEOM_MARCHING_CUBES_HPP #endif // ANTKEEPER_GEOM_MARCHING_CUBES_HPP

+ 1
- 1
src/geom/mesh-accelerator.hpp View File

@ -54,7 +54,7 @@ public:
* Finds the first intersection between a ray and a triangle in the mesh. * Finds the first intersection between a ray and a triangle in the mesh.
* *
* @param ray Ray to test for intersection. * @param ray Ray to test for intersection.
* @return Ray query result on intersection, and `std::nullopt` if no intersection occurreda.
* @return Ray query result on intersection, and `std::nullopt` if no intersection occurred.
*/ */
std::optional<ray_query_result> query_nearest(const ray<float>& ray) const; std::optional<ray_query_result> query_nearest(const ray<float>& ray) const;

+ 1
- 0
src/math/math.hpp View File

@ -48,5 +48,6 @@ namespace math {}
#include "math/interpolation.hpp" #include "math/interpolation.hpp"
#include "math/random.hpp" #include "math/random.hpp"
#include "math/map.hpp" #include "math/map.hpp"
#include "math/projection.hpp"
#endif // ANTKEEPER_MATH_HPP #endif // ANTKEEPER_MATH_HPP

+ 61
- 0
src/math/projection.hpp View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_MATH_PROJECTION_HPP
#define ANTKEEPER_MATH_PROJECTION_HPP
#include <cmath>
namespace math {
/**
* Calculates a horizontal FoV given a vertical FoV and aspect ratio.
*
* @param v Vertical FoV, in radians.
* @param r Ratio of width to height.
*
* @return Horizontal FoV, in radians.
*
* @see https://en.wikipedia.org/wiki/Field_of_view_in_video_games
*/
template <class T>
T horizontal_fov(T v, T r)
{
return T{2} * std::atan(std::tan(v * T{0.5}) * r);
}
/**
* Calculates a vertical FoV given a horizontal FoV and aspect ratio.
*
* @param h Horizontal FoV, in radians.
* @param r Ratio of width to height.
*
* @return Vertical FoV, in radians.
*
* @see https://en.wikipedia.org/wiki/Field_of_view_in_video_games
*/
template <class T>
T vertical_fov(T h, T r)
{
return T{2} * std::atan(std::tan(h * T{0.5}) / r);
}
} // namespace math
#endif // ANTKEEPER_MATH_PROJECTION_HPP

Loading…
Cancel
Save