summaryrefslogtreecommitdiffstats
path: root/src/game/shared/coord.hh
blob: 72d2909aa7444a49e6ffdf79ded1818cc9f46fcb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef SHARED_COORD_HH
#define SHARED_COORD_HH 1
#pragma once

#include "shared/const.hh"
#include "shared/types.hh"

namespace coord
{
constexpr chunk_pos to_chunk(const voxel_pos& vpos);
} // namespace coord

namespace coord
{
constexpr local_pos to_local(const voxel_pos& vpos);
constexpr local_pos to_local(const glm::fvec3& fvec);
constexpr local_pos to_local(std::size_t index);
} // namespace coord

namespace coord
{
constexpr voxel_pos to_voxel(const chunk_pos& cpos, const local_pos& lpos);
constexpr voxel_pos to_voxel(const chunk_pos& cpos, const glm::fvec3& fvec);
} // namespace coord

namespace coord
{
constexpr std::size_t to_index(const local_pos& lpos);
} // namespace coord

namespace coord
{
constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const chunk_pos& cpos, const glm::fvec3& fvec);
constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos);
constexpr glm::fvec3 to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos, const glm::fvec3& fvec);
} // namespace coord

namespace coord
{
constexpr glm::fvec3 to_fvec3(const chunk_pos& cpos);
constexpr glm::fvec3 to_fvec3(const chunk_pos& cpos, const glm::fvec3& fpos);
} // namespace coord

inline constexpr chunk_pos coord::to_chunk(const voxel_pos& vpos)
{
    return chunk_pos {
        static_cast<chunk_pos::value_type>(vpos.x >> CHUNK_BITSHIFT),
        static_cast<chunk_pos::value_type>(vpos.y >> CHUNK_BITSHIFT),
        static_cast<chunk_pos::value_type>(vpos.z >> CHUNK_BITSHIFT),
    };
}

inline constexpr local_pos coord::to_local(const voxel_pos& vpos)
{
    return local_pos {
        static_cast<local_pos::value_type>(vx::mod_signed<voxel_pos::value_type>(vpos.x, CHUNK_SIZE)),
        static_cast<local_pos::value_type>(vx::mod_signed<voxel_pos::value_type>(vpos.y, CHUNK_SIZE)),
        static_cast<local_pos::value_type>(vx::mod_signed<voxel_pos::value_type>(vpos.z, CHUNK_SIZE)),
    };
}

inline constexpr local_pos coord::to_local(const glm::fvec3& fvec)
{
    return local_pos {
        static_cast<local_pos::value_type>(fvec.x),
        static_cast<local_pos::value_type>(fvec.y),
        static_cast<local_pos::value_type>(fvec.z),
    };
}

inline constexpr local_pos coord::to_local(std::size_t index)
{
    return local_pos {
        static_cast<local_pos::value_type>((index % CHUNK_SIZE)),
        static_cast<local_pos::value_type>((index / CHUNK_SIZE) / CHUNK_SIZE),
        static_cast<local_pos::value_type>((index / CHUNK_SIZE) % CHUNK_SIZE),
    };
}

inline constexpr voxel_pos coord::to_voxel(const chunk_pos& cpos, const local_pos& lpos)
{
    return voxel_pos {
        lpos.x + (static_cast<voxel_pos::value_type>(cpos.x) << CHUNK_BITSHIFT),
        lpos.y + (static_cast<voxel_pos::value_type>(cpos.y) << CHUNK_BITSHIFT),
        lpos.z + (static_cast<voxel_pos::value_type>(cpos.z) << CHUNK_BITSHIFT),
    };
}

inline constexpr voxel_pos coord::to_voxel(const chunk_pos& cpos, const glm::fvec3& fvec)
{
    return voxel_pos {
        static_cast<voxel_pos::value_type>(fvec.x) + (static_cast<voxel_pos::value_type>(cpos.x) << CHUNK_BITSHIFT),
        static_cast<voxel_pos::value_type>(fvec.y) + (static_cast<voxel_pos::value_type>(cpos.y) << CHUNK_BITSHIFT),
        static_cast<voxel_pos::value_type>(fvec.z) + (static_cast<voxel_pos::value_type>(cpos.z) << CHUNK_BITSHIFT),
    };
}

inline constexpr std::size_t coord::to_index(const local_pos& lpos)
{
    return static_cast<std::size_t>((lpos.y * CHUNK_SIZE + lpos.z) * CHUNK_SIZE + lpos.x);
}

inline constexpr glm::fvec3 coord::to_relative(const chunk_pos& pivot_cpos, const chunk_pos& cpos, const glm::fvec3& fvec)
{
    return glm::fvec3 {
        static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) + fvec.x,
        static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) + fvec.y,
        static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) + fvec.z,
    };
}

inline constexpr glm::fvec3 coord::to_relative(const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos)
{
    return glm::fvec3 {
        static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) - pivot_fvec.x,
        static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) - pivot_fvec.y,
        static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) - pivot_fvec.z,
    };
}

inline constexpr glm::fvec3 coord::to_relative(
    const chunk_pos& pivot_cpos, const glm::fvec3& pivot_fvec, const chunk_pos& cpos, const glm::fvec3& fvec)
{
    return glm::fvec3 {
        static_cast<float>((cpos.x - pivot_cpos.x) << CHUNK_BITSHIFT) + (fvec.x - pivot_fvec.x),
        static_cast<float>((cpos.y - pivot_cpos.y) << CHUNK_BITSHIFT) + (fvec.y - pivot_fvec.y),
        static_cast<float>((cpos.z - pivot_cpos.z) << CHUNK_BITSHIFT) + (fvec.z - pivot_fvec.z),
    };
}

inline constexpr glm::fvec3 coord::to_fvec3(const chunk_pos& cpos)
{
    return glm::fvec3 {
        static_cast<float>(cpos.x << CHUNK_BITSHIFT),
        static_cast<float>(cpos.y << CHUNK_BITSHIFT),
        static_cast<float>(cpos.z << CHUNK_BITSHIFT),
    };
}

inline constexpr glm::fvec3 coord::to_fvec3(const chunk_pos& cpos, const glm::fvec3& fpos)
{
    return glm::fvec3 {
        fpos.x + static_cast<float>(cpos.x << CHUNK_BITSHIFT),
        fpos.y + static_cast<float>(cpos.y << CHUNK_BITSHIFT),
        fpos.z + static_cast<float>(cpos.z << CHUNK_BITSHIFT),
    };
}

#endif // SHARED_COORD_HH