| 147 | } |
| 148 | |
| 149 | bool Face3::intersects_aabb(const AABB &p_aabb) const { |
| 150 | /** TEST PLANE **/ |
| 151 | if (!p_aabb.intersects_plane(get_plane())) { |
| 152 | return false; |
| 153 | } |
| 154 | |
| 155 | #define TEST_AXIS(m_ax) \ |
| 156 | /** TEST FACE AXIS */ \ |
| 157 | { \ |
| 158 | real_t aabb_min = p_aabb.position.m_ax; \ |
| 159 | real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \ |
| 160 | real_t tri_min = vertex[0].m_ax; \ |
| 161 | real_t tri_max = vertex[0].m_ax; \ |
| 162 | for (int i = 1; i < 3; i++) { \ |
| 163 | if (vertex[i].m_ax > tri_max) \ |
| 164 | tri_max = vertex[i].m_ax; \ |
| 165 | if (vertex[i].m_ax < tri_min) \ |
| 166 | tri_min = vertex[i].m_ax; \ |
| 167 | } \ |
| 168 | \ |
| 169 | if (tri_max < aabb_min || aabb_max < tri_min) \ |
| 170 | return false; \ |
| 171 | } |
| 172 | |
| 173 | TEST_AXIS(x); |
| 174 | TEST_AXIS(y); |
| 175 | TEST_AXIS(z); |
| 176 | |
| 177 | /** TEST ALL EDGES **/ |
| 178 | |
| 179 | const Vector3 edge_norms[3] = { |
| 180 | vertex[0] - vertex[1], |
| 181 | vertex[1] - vertex[2], |
| 182 | vertex[2] - vertex[0], |
| 183 | }; |
| 184 | |
| 185 | for (int i = 0; i < 12; i++) { |
| 186 | Vector3 from, to; |
| 187 | p_aabb.get_edge(i, from, to); |
| 188 | Vector3 e1 = from - to; |
| 189 | for (int j = 0; j < 3; j++) { |
| 190 | Vector3 e2 = edge_norms[j]; |
| 191 | |
| 192 | Vector3 axis = vec3_cross(e1, e2); |
| 193 | |
| 194 | if (axis.length_squared() < 0.0001f) { |
| 195 | continue; // coplanar |
| 196 | } |
| 197 | axis.normalize(); |
| 198 | |
| 199 | real_t minA, maxA, minB, maxB; |
| 200 | p_aabb.project_range_in_plane(Plane(axis), minA, maxA); |
| 201 | project_range(axis, Transform3D(), minB, maxB); |
| 202 | |
| 203 | if (maxA < minB || maxB < minA) { |
| 204 | return false; |
| 205 | } |
| 206 | } |
no test coverage detected