Antkeeper  0.0.1
collision-system.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
26 #include <limits>
27 
28 
31 {
32 }
33 
35 {
36 }
37 
38 void collision_system::update(float t, float dt)
39 {
40 
41 }
42 
43 entity::id collision_system::pick_nearest(const geom::ray<float, 3>& ray, std::uint32_t flags) const
44 {
45  entity::id nearest_eid = entt::null;
46  float nearest_distance = std::numeric_limits<float>::infinity();
47 
48  // For each entity with picking and transform components
50  (
51  [&](entity::id entity_id, const auto& picking, const auto& transform)
52  {
53  // Skip entity if picking flags don't match
54  if (!~(flags | picking.flags))
55  return;
56 
57  // Transform picking sphere
59  {
60  transform.world * picking.sphere.center,
61  picking.sphere.radius * math::max(transform.world.scale)
62  };
63 
64  // Test for intersection between ray and sphere
65  auto result = geom::intersection(ray, sphere);
66  if (result)
67  {
68  float t0 = std::get<0>(*result);
69  float t1 = std::get<1>(*result);
70 
71  if (t0 < nearest_distance)
72  {
73  nearest_eid = entity_id;
74  nearest_distance = t0;
75  }
76  }
77  }
78  );
79 
80  return nearest_eid;
81 }
82 
83 entity::id collision_system::pick_nearest(const math::fvec3& origin, const math::fvec3& normal, std::uint32_t flags) const
84 {
85  entity::id nearest_eid = entt::null;
86  float nearest_sqr_distance = std::numeric_limits<float>::infinity();
87 
88  // Construct picking plane
89  const geom::plane<float> picking_plane = geom::plane<float>(origin, normal);
90 
91  // For each entity with picking and transform components
93  (
94  [&](entity::id entity_id, const auto& picking, const auto& transform)
95  {
96  // Skip entity if picking flags don't match
97  if (!~(flags | picking.flags))
98  return;
99 
100  // Transform picking sphere center
101  math::fvec3 picking_sphere_center = transform.world * picking.sphere.center;
102 
103  // Skip entity if picking sphere center has negative distance from picking plane
104  if (picking_plane.distance(picking_sphere_center) < 0.0f)
105  return;
106 
107  // Measure distance from picking plane origin to picking sphere center
108  const float sqr_distance = math::sqr_distance(picking_sphere_center, origin);
109 
110  // Check if entity is nearer than the current nearest entity
111  if (sqr_distance < nearest_sqr_distance)
112  {
113  nearest_eid = entity_id;
114  nearest_sqr_distance = sqr_distance;
115  }
116  }
117  );
118 
119  return nearest_eid;
120 }
121 
collision_system(entity::registry &registry)
virtual void update(float t, float dt)
Perform's a system's update() function.
entity::id pick_nearest(const geom::ray< float, 3 > &ray, std::uint32_t flags) const
Picks the nearest entity with the specified picking flags that intersects a ray.
Abstract base class for updatable systems.
entity::registry & registry
Registry on which the system operate.
entt::registry registry
Component registry type.
Definition: registry.hpp:28
entt::entity id
Entity ID type.
Definition: id.hpp:28
hypersphere< T, 3 > sphere
3-dimensional hypersphere.
Definition: sphere.hpp:34
constexpr std::optional< T > intersection(const ray< T, N > &ray, const hyperplane< T, N > &hyperplane) noexcept
Ray-hyperplane intersection test.
constexpr T sqr_distance(const vector< T, N > &p0, const vector< T, N > &p1) noexcept
Calculates the square distance between two points.
Definition: vector.hpp:1514
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
Definition: vector.hpp:1328
n-dimensional plane.
Definition: hyperplane.hpp:36
constexpr T distance(const vector_type &point) const noexcept
Calculates the signed distance from the hyperplane to a point.
Definition: hyperplane.hpp:78
n-dimensional sphere.
Definition: hypersphere.hpp:37
Half of a line proceeding from an initial point.
Definition: ray.hpp:38
n-dimensional vector.
Definition: vector.hpp:44