Toast Engine
Loading...
Searching...
No Matches
shape.hpp
Go to the documentation of this file.
1
7
8#pragma once
9
10#include "aabb.hpp"
11#include "body.hpp"
12#include "material_defaults.hpp"
13
14#include <compare>
15#include <cstdint>
16#include <glm/glm.hpp>
17#include <limits>
18
19namespace physics {
20
22 float restitution = material_defaults::k_restitution;
23 float static_friction = material_defaults::k_static_friction;
24 float dynamic_friction = material_defaults::k_dynamic_friction;
25 float rolling_friction = material_defaults::k_rolling_friction;
26 float spin_friction = material_defaults::k_spin_friction;
27};
28
29struct ShapeID {
30 uint32_t slot = std::numeric_limits<uint32_t>::max();
31 uint32_t generation = 0;
32 auto operator<=>(const ShapeID&) const = default;
33};
34
35enum class FeatureType : uint8_t {
36 sphere_surface = 1,
37 capsule_cap_a,
38 capsule_side,
39 capsule_cap_b,
40 box_face,
41 box_edge,
42 box_vertex,
43 box_clip,
44 voxel_face,
45 voxel_edge,
46};
47
49 uint64_t value = 0;
50 auto operator<=>(const ContactFeatureID&) const = default;
51};
52
53inline constexpr uint64_t contact_feature_payload_mask = 0x00ff'ffff'ffff'ffffULL;
54
55[[nodiscard]]
56constexpr auto makeContactFeature(FeatureType type, uint64_t payload = 0) -> ContactFeatureID {
57 return ContactFeatureID {(static_cast<uint64_t>(type) << 56) | (payload & contact_feature_payload_mask)};
58}
59
60[[nodiscard]]
61constexpr auto capsuleFeature(float parameter) -> ContactFeatureID {
62 if (parameter <= 0.0f) {
63 return makeContactFeature(FeatureType::capsule_cap_a);
64 }
65 if (parameter >= 1.0f) {
66 return makeContactFeature(FeatureType::capsule_cap_b);
67 }
68 return makeContactFeature(FeatureType::capsule_side);
69}
70
71[[nodiscard]]
72constexpr auto boxFaceFeature(int axis, bool positive) -> ContactFeatureID {
73 return makeContactFeature(FeatureType::box_face, static_cast<uint64_t>(axis) | (static_cast<uint64_t>(positive) << 2));
74}
75
76[[nodiscard]]
77constexpr auto boxEdgeFeature(int direction_axis, uint8_t positive_mask) -> ContactFeatureID {
78 return makeContactFeature(
79 FeatureType::box_edge, static_cast<uint64_t>(direction_axis) | (static_cast<uint64_t>(positive_mask & 0x7u) << 2)
80 );
81}
82
83[[nodiscard]]
84constexpr auto boxVertexFeature(uint8_t positive_mask) -> ContactFeatureID {
85 return makeContactFeature(FeatureType::box_vertex, positive_mask & 0x7u);
86}
87
88[[nodiscard]]
89constexpr auto boxClipFeature(int reference_axis, bool reference_positive, int side_axis, bool side_positive)
91 uint64_t payload = static_cast<uint64_t>(reference_axis);
92 payload |= static_cast<uint64_t>(reference_positive) << 2;
93 payload |= static_cast<uint64_t>(side_axis) << 3;
94 payload |= static_cast<uint64_t>(side_positive) << 5;
95 return makeContactFeature(FeatureType::box_clip, payload);
96}
97
98[[nodiscard]]
99constexpr auto voxelFeature(FeatureType type, uint32_t brick_slot, uint16_t local_index, uint8_t normal_index)
101 uint64_t payload = static_cast<uint64_t>(local_index) & 0x1FFu;
102 payload |= (static_cast<uint64_t>(normal_index) & 0x1Fu) << 9;
103 payload |= (static_cast<uint64_t>(brick_slot) & 0xFFFF'FFFFu) << 14;
104 return makeContactFeature(type, payload);
105}
106
108 uint32_t slot = 0;
109 uint16_t local_index = 0;
110 uint8_t normal_index = 0;
111};
112
113[[nodiscard]]
114constexpr auto unpackVoxelFeature(ContactFeatureID id) -> VoxelFeaturePayload {
115 const uint64_t payload = id.value & contact_feature_payload_mask;
116 return {
117 .slot = static_cast<uint32_t>((payload >> 14) & 0xFFFF'FFFFu),
118 .local_index = static_cast<uint16_t>(payload & 0x1FFu),
119 .normal_index = static_cast<uint8_t>((payload >> 9) & 0x1Fu),
120 };
121}
122
123enum class ShapeType : uint8_t {
124 sphere,
125 box,
126 capsule,
127 voxel
128};
129
131 glm::vec3 local_center = {};
132 float radius = 0.5f;
133};
134
135struct BoxShape {
136 glm::vec3 local_center = {};
137 glm::quat local_rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
138 glm::vec3 size = {1.0f, 1.0f, 1.0f};
139};
140
142 glm::vec3 local_center = {};
143 glm::quat local_rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
144 float radius = 0.5f;
145 float height = 1.0f;
146};
147
149 uint32_t slot = std::numeric_limits<uint32_t>::max();
150 uint32_t generation = 0;
151 auto operator<=>(const VoxelDataID&) const = default;
152};
153
155 VoxelDataID data;
156 glm::vec3 local_center = {};
157 glm::quat local_rotation = {1.0f, 0.0f, 0.0f, 0.0f};
158 AABB local_bounds = {};
159};
160
161struct Shape {
162 BodyID owner;
163 ShapeType type = ShapeType::sphere;
164 bool enabled = true;
165 PhysicsMaterial material;
166
167 union {
168 SphereShape sphere;
169 BoxShape box;
170 CapsuleShape capsule;
171 VoxelShape voxel;
172 };
173
174 [[nodiscard]]
175 auto getLocalCenter() const -> glm::vec3 {
176 switch (type) {
177 case ShapeType::sphere: return sphere.local_center;
178 case ShapeType::box: return box.local_center;
179 case ShapeType::capsule: return capsule.local_center;
180 case ShapeType::voxel: return voxel.local_center;
181 }
182 return glm::vec3(0.0f);
183 }
184
185 [[nodiscard]]
186 auto getLocalRotation() const -> glm::quat {
187 switch (type) {
188 case ShapeType::sphere: return {1.0f, 0.0f, 0.0f, 0.0f};
189 case ShapeType::box: return box.local_rotation;
190 case ShapeType::capsule: return capsule.local_rotation;
191 case ShapeType::voxel: return voxel.local_rotation;
192 }
193 return {1.0f, 0.0f, 0.0f, 0.0f};
194 }
195};
196
197struct ShapeSlot {
198 Shape shape;
199 uint32_t generation = 1;
200 uint32_t revision = 1;
201 bool occupied = false;
202};
203
204inline constexpr ContactFeatureID sphere_surface_feature = makeContactFeature(FeatureType::sphere_surface);
205
206}
Axis-aligned bounds node.
Body identifiers, creation data, and copied runtime state.
The values a material has when nothing sets them.
constexpr float k_rolling_friction
A ball rolling on a hard floor loses a few percent of its speed per metre.
Definition material_defaults.hpp:22
Definition aabb.hpp:16
Definition body.hpp:20
Definition shape.hpp:135
Definition shape.hpp:141
Definition shape.hpp:48
Definition shape.hpp:21
Definition shape.hpp:29
Definition shape.hpp:197
Definition shape.hpp:161
Definition shape.hpp:130
Definition shape.hpp:148
Definition shape.hpp:107
Definition shape.hpp:154