tess 1.0.0
Performance-first tile and path simulation substrate
Loading...
Searching...
No Matches
step_policy.h
1#pragma once
2
3#include <tess/core/lattice.h>
4#include <tess/core/shape.h>
5
6#include <concepts>
7#include <cstdint>
8#include <type_traits>
9
10namespace tess::movement {
11
13enum class CornerRule : std::uint8_t {
14 RequireBothClear,
15 RequireOneClear,
16};
17
19enum class StepPolicyIdentity : std::uint32_t {
20 Default = 0x44454654,
21 DiagonalRequireBothClear = 0x44474243,
22 DiagonalRequireOneClear = 0x44474f43,
23};
24
27 static constexpr StepPolicyIdentity identity = StepPolicyIdentity::Default;
28 static constexpr std::uint32_t cost_scale = 1;
29 static constexpr std::uint32_t maximum_step_multiplier = 1;
30};
31
33template <CornerRule Rule = CornerRule::RequireBothClear>
35 static constexpr CornerRule corner_rule = Rule;
36 static constexpr StepPolicyIdentity identity =
37 Rule == CornerRule::RequireBothClear
38 ? StepPolicyIdentity::DiagonalRequireBothClear
39 : StepPolicyIdentity::DiagonalRequireOneClear;
40 // 181 / 128 is the nearest scale-128 integer approximation to sqrt(2).
41 // Naming both factors here keeps enumeration, heuristics, and static range
42 // assessment on one exact fixed-point contract.
43 static constexpr std::uint32_t cost_scale = 128;
44 static constexpr std::uint32_t diagonal_step_multiplier = 181;
45 static constexpr std::uint32_t maximum_step_multiplier =
46 diagonal_step_multiplier;
47};
48
50template <CornerRule Rule>
52 Rule == CornerRule::RequireBothClear || Rule == CornerRule::RequireOneClear;
53
54namespace detail {
55
56template <typename Policy>
57struct is_diagonal_steps : std::false_type {};
58
59template <CornerRule Rule>
60struct is_diagonal_steps<DiagonalSteps<Rule>> : std::true_type {
61 static constexpr CornerRule corner_rule = Rule;
62};
63
64template <typename Shape>
65inline constexpr auto effective_axis_count =
66 static_cast<unsigned>(ShapeTraits<Shape>::size.x != 1) +
67 static_cast<unsigned>(ShapeTraits<Shape>::size.y != 1) +
68 static_cast<unsigned>(ShapeTraits<Shape>::size.z != 1);
69
70template <typename Class, typename = void>
71struct step_policy_of_impl {
72 using type = DefaultSteps;
73};
74
75template <typename Class>
76struct step_policy_of_impl<Class, std::void_t<typename Class::step_policy>> {
77 using type = typename Class::step_policy;
78};
79
80} // namespace detail
81
83template <typename Policy>
84concept StepPolicy = requires {
85 { Policy::identity } -> std::convertible_to<StepPolicyIdentity>;
86 { Policy::cost_scale } -> std::convertible_to<std::uint32_t>;
87} && Policy::cost_scale > 0;
88
90template <typename Policy, typename Shape>
93 (std::is_same_v<Policy, DefaultSteps> ||
94 (detail::is_diagonal_steps<Policy>::value &&
96 std::is_same_v<typename ShapeTraits<Shape>::lattice_type,
98 detail::effective_axis_count<Shape> == 2));
99
101template <typename Class>
102using step_policy_of = typename detail::step_policy_of_impl<Class>::type;
103
105template <typename Policy>
106inline constexpr StepPolicyIdentity step_policy_identity = Policy::identity;
107
109template <typename Class>
110inline constexpr StepPolicyIdentity step_policy_identity_of =
111 step_policy_identity<step_policy_of<Class>>;
112
113} // namespace tess::movement
Definition step_policy.h:91
Definition step_policy.h:84
Definition step_policy.h:51
Definition lattice.h:15
Definition step_policy.h:26
Definition step_policy.h:34