box.hh 3.93 KB
Newer Older
Philip Trettner's avatar
Philip Trettner committed
1
2
#pragma once

Philip Trettner's avatar
Philip Trettner committed
3
#include <typed-geometry/types/scalars/default.hh>
Philip Trettner's avatar
Philip Trettner committed
4
#include "../mat.hh"
Philip Trettner's avatar
Philip Trettner committed
5
6
#include "../pos.hh"
#include "../vec.hh"
7
#include "traits.hh"
Philip Trettner's avatar
Philip Trettner committed
8
9
10
11

#include "aabb.hh"

// An oriented box
Philip Trettner's avatar
Philip Trettner committed
12
13
14
// stored as:
//   center position
//   orthogonal matrix that maps the -1..1 cube to the oriented box (half-extents)
Philip Trettner's avatar
Philip Trettner committed
15
16
17

namespace tg
{
18
template <int ObjectD, class ScalarT, int DomainD = ObjectD, class TraitsT = default_object_tag>
Philip Trettner's avatar
Philip Trettner committed
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
struct box;

// Common box types

using box1 = box<1, f32>;
using box2 = box<2, f32>;
using box3 = box<3, f32>;
using box4 = box<4, f32>;

using fbox1 = box<1, f32>;
using fbox2 = box<2, f32>;
using fbox3 = box<3, f32>;
using fbox4 = box<4, f32>;

using dbox1 = box<1, f64>;
using dbox2 = box<2, f64>;
using dbox3 = box<3, f64>;
using dbox4 = box<4, f64>;

using ibox1 = box<1, i32>;
using ibox2 = box<2, i32>;
using ibox3 = box<3, i32>;
using ibox4 = box<4, i32>;

using ubox1 = box<1, u32>;
using ubox2 = box<2, u32>;
using ubox3 = box<3, u32>;
using ubox4 = box<4, u32>;

Philip Trettner's avatar
Philip Trettner committed
48
49
50
51
52
using box2in3 = box<2, f32, 3>;
using fbox2in3 = box<2, f32, 3>;
using dbox2in3 = box<2, f64, 3>;
using ibox2in3 = box<2, i32, 3>;
using ubox2in3 = box<2, u32, 3>;
Philip Trettner's avatar
Philip Trettner committed
53

54
55
56
57
template <int ObjectD, class ScalarT, int DomainD = ObjectD>
using box_boundary = box<ObjectD, ScalarT, DomainD, boundary_tag>;


Philip Trettner's avatar
Philip Trettner committed
58
59
// ======== IMPLEMENTATION ========

60
61
template <int D, class ScalarT, class TraitsT>
struct box<D, ScalarT, D, TraitsT>
Philip Trettner's avatar
Philip Trettner committed
62
{
63
    using scalar_t = ScalarT;
Philip Trettner's avatar
Philip Trettner committed
64
65
    using vec_t = vec<D, ScalarT>;
    using pos_t = pos<D, ScalarT>;
Philip Trettner's avatar
Philip Trettner committed
66
    using mat_t = mat<D, D, ScalarT>;
Philip Trettner's avatar
Philip Trettner committed
67
68
69
70
71
72

    static const box minus_one_to_one;
    static const box unit_from_zero;
    static const box unit_centered;

    pos_t center;
Philip Trettner's avatar
Philip Trettner committed
73
    mat_t half_extents;
Philip Trettner's avatar
Philip Trettner committed
74
75

    constexpr box() = default;
Philip Trettner's avatar
Philip Trettner committed
76
    constexpr box(pos_t center, mat_t const& half_extents) : center(center), half_extents(half_extents) {}
77
    constexpr box(aabb<D, ScalarT, TraitsT> const& b); // requires tg.hh
Philip Trettner's avatar
Philip Trettner committed
78

Philip Trettner's avatar
Philip Trettner committed
79
    template <class OtherT, class OtherTraitsT>
80
    explicit constexpr box(box<D, OtherT, D, OtherTraitsT> const& v) : center(v.center), half_extents(v.half_extents)
Philip Trettner's avatar
Philip Trettner committed
81
82
83
    {
    }

84
    /// Note that the box goes from -1 to 1 instead of the usual 0 to 1
85
86
    [[nodiscard]] constexpr pos_t operator[](comp<D, ScalarT> const& c) const;

87
88
    [[nodiscard]] bool operator==(box const& rhs) const { return center == rhs.center && half_extents == rhs.half_extents; }
    [[nodiscard]] bool operator!=(box const& rhs) const { return !operator==(rhs); }
Philip Trettner's avatar
Philip Trettner committed
89
};
Philip Trettner's avatar
Philip Trettner committed
90

91
92
template <class ScalarT, class TraitsT>
struct box<2, ScalarT, 3, TraitsT>
Philip Trettner's avatar
Philip Trettner committed
93
{
94
    using scalar_t = ScalarT;
Philip Trettner's avatar
Philip Trettner committed
95
96
97
98
99
100
101
102
103
    using vec_t = vec<3, ScalarT>;
    using dir_t = dir<3, ScalarT>;
    using pos_t = pos<3, ScalarT>;
    using mat_t = mat<2, 3, ScalarT>;

    pos_t center;
    mat_t half_extents;

    constexpr box() = default;
104
    constexpr box(pos_t center, mat_t const& half_extents) : center(center), half_extents(half_extents) {}
Philip Trettner's avatar
Philip Trettner committed
105
    constexpr box(pos_t center, vec_t half_extent_x, vec_t half_extent_y) : center(center), half_extents(half_extent_x, half_extent_y) {}
Philip Trettner's avatar
Philip Trettner committed
106

Philip Trettner's avatar
Philip Trettner committed
107
    template <class OtherT, class OtherTraitsT>
108
    explicit constexpr box(box<2, OtherT, 3, OtherTraitsT> const& v) : center(v.center), half_extents(v.half_extents)
Philip Trettner's avatar
Philip Trettner committed
109
110
111
    {
    }

112
    /// Note that the box goes from -1 to 1 instead of the usual 0 to 1
113
114
    [[nodiscard]] constexpr pos_t operator[](comp<2, ScalarT> const& c) const;

115
    [[nodiscard]] bool operator==(box const& rhs) const { return center == rhs.center && half_extents == rhs.half_extents; }
Philip Trettner's avatar
Philip Trettner committed
116
117
    [[nodiscard]] bool operator!=(box const& rhs) const { return !operator==(rhs); }
};
Philip Trettner's avatar
Philip Trettner committed
118
119
120
121

template <class I, int ObjectD, class ScalarT, int DomainD, class TraitsT>
constexpr void introspect(I&& i, box<ObjectD, ScalarT, DomainD, TraitsT>& v)
{
122
123
    i(v.center, "center");
    i(v.half_extents, "half_extents");
Philip Trettner's avatar
Philip Trettner committed
124
}
125
126
127
128
129

template <int ObjectD, class ScalarT, int DomainD, class TraitsT>
struct object_traits<box<ObjectD, ScalarT, DomainD, TraitsT>> : detail::finite_object_traits<ObjectD, ScalarT, DomainD, TraitsT>
{
};
Philip Trettner's avatar
Philip Trettner committed
130
} // namespace tg