]> git.localhorst.tv Git - blank.git/blob - src/model/bounds.cpp
store shapes in models rather than meshes
[blank.git] / src / model / bounds.cpp
1 #include "bounds.hpp"
2 #include "CollisionBounds.hpp"
3
4
5 namespace blank {
6
7 void CollisionBounds::Outline(OutlineMesh::Buffer &out) const {
8         out.vertices.insert(out.vertices.end(), out_pos.begin(), out_pos.end());
9         out.indices.insert(out.indices.end(), out_idx.begin(), out_idx.end());
10 }
11
12 void CollisionBounds::SetOutline(
13         const OutlineMesh::Positions &pos,
14         const OutlineMesh::Indices &idx
15 ) {
16         out_pos = pos;
17         out_idx = idx;
18 }
19
20
21 CuboidBounds::CuboidBounds(const AABB &b)
22 : CollisionBounds()
23 , bb(b) {
24         bb.Adjust();
25         SetOutline({
26                 { bb.min.x, bb.min.y, bb.min.z }, // back
27                 { bb.max.x, bb.min.y, bb.min.z },
28                 { bb.min.x, bb.max.y, bb.min.z },
29                 { bb.max.x, bb.max.y, bb.min.z },
30                 { bb.min.x, bb.min.y, bb.max.z }, // front
31                 { bb.max.x, bb.min.y, bb.max.z },
32                 { bb.min.x, bb.max.y, bb.max.z },
33                 { bb.max.x, bb.max.y, bb.max.z },
34         }, {
35                 0, 1, 1, 3, 3, 2, 2, 0, // back
36                 4, 5, 5, 7, 7, 6, 6, 4, // front
37                 0, 4, 1, 5, 2, 6, 3, 7, // sides
38         });
39 }
40
41 bool CuboidBounds::Intersects(
42         const Ray &ray,
43         const glm::mat4 &M,
44         float &dist, glm::vec3 &normal
45 ) const noexcept {
46         return Intersection(ray, bb, M, &dist, &normal);
47 }
48
49 bool CuboidBounds::Intersects(
50         const glm::mat4 &M,
51         const AABB &box,
52         const glm::mat4 &box_M,
53         float &depth,
54         glm::vec3 &normal
55 ) const noexcept {
56         return Intersection(bb, M, box, box_M, depth, normal);
57 }
58
59
60 StairBounds::StairBounds(const AABB &bb, const glm::vec2 &clip)
61 : CollisionBounds()
62 , top({ { bb.min.x, clip.y, bb.min.z }, { bb.max.x, bb.max.y, clip.x } })
63 , bot({ bb.min, { bb.max.x, clip.y, bb.max.z } }) {
64         SetOutline({
65                 { bot.min.x, bot.min.y, bot.min.z }, // bottom
66                 { bot.max.x, bot.min.y, bot.min.z },
67                 { bot.min.x, bot.min.y, bot.max.z },
68                 { bot.max.x, bot.min.y, bot.max.z },
69                 { bot.min.x, bot.max.y, top.max.z }, // middle
70                 { bot.max.x, bot.max.y, top.max.z },
71                 { bot.min.x, bot.max.y, bot.max.z },
72                 { bot.max.x, bot.max.y, bot.max.z },
73                 { top.min.x, top.max.y, top.min.z }, // top
74                 { top.max.x, top.max.y, top.min.z },
75                 { top.min.x, top.max.y, top.max.z },
76                 { top.max.x, top.max.y, top.max.z },
77         }, {
78                  0,  1,  1,  3,  3,  2,  2,  0, // bottom
79                  4,  5,  5,  7,  7,  6,  6,  4, // middle
80                  8,  9,  9, 11, 11, 10, 10 , 8, // top
81                  0,  8,  4, 10,  2,  6, // verticals, btf
82                  1,  9,  5, 11,  3,  7,
83         });
84 }
85
86 bool StairBounds::Intersects(
87         const Ray &ray,
88         const glm::mat4 &M,
89         float &dist,
90         glm::vec3 &norm
91 ) const noexcept {
92         float top_dist, bot_dist;
93         glm::vec3 top_norm, bot_norm;
94         bool top_hit = Intersection(ray, top, M, &top_dist, &top_norm);
95         bool bot_hit = Intersection(ray, bot, M, &bot_dist, &bot_norm);
96
97         if (top_hit) {
98                 if (bot_hit) {
99                         if (top_dist < bot_dist) {
100                                 dist = top_dist;
101                                 norm = top_norm;
102                                 return true;
103                         } else {
104                                 dist = bot_dist;
105                                 norm = bot_norm;
106                                 return true;
107                         }
108                 } else {
109                         dist = top_dist;
110                         norm = top_norm;
111                         return true;
112                 }
113         } else if (bot_hit) {
114                 dist = bot_dist;
115                 norm = bot_norm;
116                 return true;
117         } else {
118                 return false;
119         }
120 }
121
122 bool StairBounds::Intersects(
123         const glm::mat4 &M,
124         const AABB &box,
125         const glm::mat4 &box_M,
126         float &dist,
127         glm::vec3 &normal
128 ) const noexcept {
129         bool top_hit, bot_hit;
130         float top_dist, bot_dist;
131         glm::vec3 top_normal, bot_normal;
132
133         top_hit = Intersection(bot, M, box, box_M, top_dist, top_normal);
134         bot_hit = Intersection(top, M, box, box_M, bot_dist, bot_normal);
135
136         if (top_hit) {
137                 if (bot_hit && bot_dist < top_dist) {
138                         dist = bot_dist;
139                         normal = bot_normal;
140                         return true;
141                 } else {
142                         dist = top_dist;
143                         normal = top_normal;
144                         return true;
145                 }
146                 return true;
147         } else if (bot_hit) {
148                 dist = bot_dist;
149                 normal = bot_normal;
150                 return true;
151         } else {
152                 return false;
153         }
154 }
155
156 }