35 inline std::pair<float, float>
unpoof(
const std::pair<float, float> &lhs,
const float &radii) {
36 return std::make_pair(
std::max(0.0
f, lhs.first - radii), lhs.second);
39 inline float unpoof(
const float &lhs,
const float &radii) {
44 const float abs_value = float(
fabs(new_value));
49 template <
typename VALUE_TYPE>
53 else if(value > upper)
57 template <
typename VALUE_TYPE>
58 void double_unclamp(VALUE_TYPE &min_value, VALUE_TYPE &max_value,
const VALUE_TYPE &new_value) {
59 if(min_value > new_value)
60 min_value = new_value;
61 else if(max_value < new_value)
62 max_value = new_value;
65 template <
typename LINE_TYPE>
67 const Vector3f w = rhs - lhs.get_end_point_a();
70 const float &uu = lhs.get_direction2();
71 const float uw = u *
w;
73 Vector3f closest_point = lhs.get_end_point_a() - rhs;
75 if(LINE_TYPE::has_lower_bound() && uw < 0.0
f)
76 return std::make_pair(closest_point.
magnitude(), 0.0f);
77 else if(LINE_TYPE::has_upper_bound() && uw > uu)
78 return std::make_pair((closest_point + u).magnitude(), 1.0f);
80 const float t = uw / uu;
81 return std::make_pair((closest_point + t * u).magnitude(), t);
84 template <
typename LINE_TYPE>
90 const float t = (n *
w) / (n * u);
91 if(LINE_TYPE::has_lower_bound() && t < 0.0f)
93 else if(LINE_TYPE::has_upper_bound() && t > 1.0f)
99 template <
typename LINE_TYPE1,
typename LINE_TYPE2>
100 std::pair<float, float>
nearest_point(
const LINE_TYPE1 &lhs,
const LINE_TYPE2 &rhs) {
101 const Vector3f w = lhs.get_end_point_a() - rhs.get_end_point_a();
105 const float &uu = lhs.get_direction2();
106 const float uv = u *
v;
107 const float &vv = rhs.get_direction2();
108 const float uw = u *
w;
109 const float vw = v *
w;
111 const float denom = uu * vv - uv * uv;
112 float sc_numer = uv * vw - vv * uw, sc_denom;
113 float tc_numer = uu * vw - uv * uw, tc_denom;
118 if(LINE_TYPE1::has_lower_bound() && sc_numer < 0.0
f) {
123 else if(LINE_TYPE1::has_upper_bound() && sc_numer > sc_denom) {
141 if(LINE_TYPE2::has_lower_bound() && tc_numer < 0.0
f)
143 else if(LINE_TYPE2::has_upper_bound() && tc_numer > tc_denom) {
145 final_numer = uv - uw;
148 const float t = sc_numer / sc_denom;
149 return std::make_pair((min_dist + t * u - (tc_numer / tc_denom) * v).magnitude(), t);
152 if(LINE_TYPE1::has_lower_bound() && final_numer < 0.0
f)
153 return std::make_pair(min_dist.
magnitude(), 0.0f);
154 else if(LINE_TYPE1::has_upper_bound() && final_numer > uu)
155 return std::make_pair((min_dist + u).magnitude(), 1.0f);
157 const float t = final_numer / uu;
158 return std::make_pair((min_dist + t * u).magnitude(), t);
161 template <
typename LINE_TYPE>
165 const Vector3f direction = end_point_b - end_point_a;
176 float invalid_axes_distance2 = 0.0f;
181 if(!valid_axes || real_max.
i < min_max) min_max = real_max.
i;
182 if(!valid_axes || real_min.
i > max_min) max_min = real_min.
i;
185 else if(end_point_a.i < 0.0f) {
187 invalid_axes_distance2 += diff * diff;
189 else if(end_point_a.i > 1.0f) {
191 invalid_axes_distance2 += diff * diff;
195 if(!valid_axes || real_max.
j < min_max) min_max = real_max.
j;
196 if(!valid_axes || real_min.
j > max_min) max_min = real_min.
j;
199 else if(end_point_a.j < 0.0f) {
201 invalid_axes_distance2 += diff * diff;
203 else if(end_point_a.j > 1.0f) {
205 invalid_axes_distance2 += diff * diff;
209 if(!valid_axes || real_max.
k < min_max) min_max = real_max.
k;
210 if(!valid_axes || real_min.
k > max_min) max_min = real_min.
k;
213 else if(end_point_a.k < 0.0f) {
215 invalid_axes_distance2 += diff * diff;
217 else if(end_point_a.k > 1.0f) {
219 invalid_axes_distance2 += diff * diff;
223 return std::make_pair(invalid_axes_distance2, 0.0
f);
227 if(LINE_TYPE::has_lower_bound() && min_max < 0.0
f)
229 else if(LINE_TYPE::has_upper_bound() && min_max > 1.0
f)
232 if(LINE_TYPE::has_lower_bound() && max_min < 0.0
f)
234 else if(LINE_TYPE::has_upper_bound() && max_min > 1.0
f)
237 if(min_max > max_min)
238 return std::make_pair(sqrt(invalid_axes_distance2), max_min);
240 Point3f closest_point = end_point_a + min_max * direction;
246 const Vector3f valid_axes_distance = lhs.get_end_point_a() + min_max * lhs.get_direction() - closest_point;
247 const float valid_axes_distance2 = valid_axes_distance * valid_axes_distance;
248 const float total_distance = float(sqrt(invalid_axes_distance2 + valid_axes_distance2));
250 return std::make_pair(total_distance, min_max);
263 return unpoof((center - rhs.center).magnitude(), radius + rhs.radius);
266 return unpoof((center - rhs).magnitude(), radius);
276 const Vector3f line_normal = normal % rhs.normal;
284 return float(
fabs((point - rhs) * normal));
292 : end_point_a(end_point_a_),
293 end_point_b(end_point_b_),
294 direction(end_point_b - end_point_a),
295 direction2(direction * direction)
300 : end_point_a(end_point_a_),
301 end_point_b(end_point_a_ + direction_vector_),
302 direction(direction_vector_),
303 direction2(direction * direction)
327 : end_point_a(end_point_a_),
328 end_point_b(end_point_b_),
329 direction(end_point_b - end_point_a),
330 direction2(direction * direction)
335 : end_point_a(end_point_a_),
336 end_point_b(end_point_a_ + direction_vector_),
337 direction(direction_vector_),
338 direction2(direction * direction)
365 : end_point_a(end_point_a_),
366 end_point_b(end_point_b_),
367 direction(end_point_b - end_point_a),
368 direction2(direction * direction)
395 const float &radius_)
396 : line(end_point_a_, end_point_b_),
402 const float &radius_)
403 : line(end_point_a_, direction_vector_),
431 const float &radius_)
432 : line_segment(end_point_a_, end_point_b_),
471 convert_from(edge_a, edge_b, edge_c),
472 convert_to(convert_from.inverted()),
482 center += ha + hb + hc;
498 const Vector3f *
const A = &normal_a;
501 const Point3f &Pb = rhs.center;
502 const Vector3f *
const B = &rhs.normal_a;
508 const Vector3f T(v * A[0], v * A[1], v * A[2]);
512 for(
int j = 0;
j < 3; ++
j)
513 for(
int i = 0;
i < 3; ++
i)
514 R[
j][
i] = A[
j] * B[
i];
517 const float abs_R[3][3] = {{float(
fabs(R[0][0])), float(
fabs(R[0][1])), float(
fabs(R[0][2]))},
518 {float(
fabs(R[1][0])), float(
fabs(R[1][1])), float(
fabs(R[1][2]))},
519 {float(
fabs(R[2][0])), float(
fabs(R[2][1])), float(
fabs(R[2][2]))}};
529 for(
int i = 0;
i < 3; ++
i) {
531 const float &ra = a[
i];
532 const float rb = b[0] * abs_R[
i][0] + b[1] * abs_R[
i][1] + b[2] * abs_R[
i][2];
533 const float t = float(
fabs(T[
i]));
540 const float ra = a[0] * abs_R[0][
i] + a[1] * abs_R[1][
i] + a[2] * abs_R[2][
i];
541 const float &rb = b[
i];
542 const float t = float(
fabs(T[0] * R[0][
i] + T[1] * R[1][
i] + T[2] * R[2][
i]));
558 for(
int j = 0,
u = 1, v = 2;
j < 3; ++
j) {
559 for(
int i = 0,
m = 1,
n = 2;
i < 3; ++
i) {
560 const float ra = a[
u] * abs_R[
v][
i] + a[
v] * abs_R[
u][
i];
561 const float rb = b[
m] * abs_R[
j][
n] + b[
n] * abs_R[
j][
m];
562 const float t = float(
fabs(T[
u] * R[v][
i] - T[v] * R[
u][
i]));
567 if(!i) --
m;
else --
n;
570 if(!
j) --
u;
else --
v;
577 float Parallelepiped::some_distance(
const Parallelepiped &rhs)
const {
580 const Vector3f *
const A = &normal_a;
583 const Point3f &Pb = rhs.center;
584 const Vector3f *
const B = &rhs.normal_a;
590 const Vector3f T(v * A[0], v * A[1], v * A[2]);
594 for(
int j = 0;
j < 3; ++
j)
595 for(
int i = 0;
i < 3; ++
i)
596 R[
j][
i] = A[
j] * B[
i];
599 const float abs_R[3][3] = {{float(
fabs(R[0][0])), float(
fabs(R[0][1])), float(
fabs(R[0][2]))},
600 {float(
fabs(R[1][0])), float(
fabs(R[1][1])), float(
fabs(R[1][2]))},
601 {float(
fabs(R[2][0])), float(
fabs(R[2][1])), float(
fabs(R[2][2]))}};
609 for(
int i = 0;
i < 3; ++
i) {
611 const float &ra = a[
i];
612 const float rb = b[0] * abs_R[
i][0] + b[1] * abs_R[
i][1] + b[2] * abs_R[
i][2];
613 const float t = float(
fabs(T[
i]));
616 return t - (ra + rb);
620 const float ra = a[0] * abs_R[0][
i] + a[1] * abs_R[1][
i] + a[2] * abs_R[2][
i];
621 const float &rb = b[
i];
622 const float t = float(
fabs(T[0] * R[0][
i] + T[1] * R[1][
i] + T[2] * R[2][
i]));
625 return t - (ra + rb);
638 for(
int j = 0,
u = 1, v = 2;
j < 3; ++
j) {
639 for(
int i = 0,
m = 1,
n = 2;
i < 3; ++
i) {
640 const float ra = a[
u] * abs_R[
v][
i] + a[
v] * abs_R[
u][
i];
641 const float rb = b[
m] * abs_R[
j][
n] + b[
n] * abs_R[
j][
m];
642 const float t = float(
fabs(T[
u] * R[v][
i] - T[v] * R[
u][
i]));
645 return t - (ra + rb);
647 if(!
i) --
m;
else --
n;
650 if(!
j) --
u;
else --
v;
658 const Point3f converted_point = convert_to * (rhs - point);
674 const float diff_001 = edge_c *
n;
675 const float diff_010 = edge_b *
n;
676 const float diff_011 = diff_010 + diff_001;
677 const float diff_100 = edge_a *
n;
678 const float diff_101 = diff_100 + diff_001;
679 const float diff_110 = diff_100 + diff_010;
680 const float diff_111 = diff_100 + diff_011;
682 const float t_000 = (point -
p) * n;
683 const float t_001 = t_000 + diff_001;
684 const float t_010 = t_000 + diff_010;
685 const float t_011 = t_000 + diff_011;
686 const float t_100 = t_000 + diff_100;
687 const float t_101 = t_000 + diff_101;
688 const float t_110 = t_000 + diff_110;
689 const float t_111 = t_000 + diff_111;
float shortest_distance(const Plane &rhs) const
std::pair< float, float > nearest_point(const LINE_TYPE &lhs, const Point3f &rhs)
GLint GLenum GLboolean normalized
const float & get_radius() const
#define ZENI_COLLISION_EPSILON
Vector3f divide_by(const Vector3f &rhs) const
Divide corresponding members.
GLboolean GLboolean GLboolean GLboolean a
const Vector3f & get_normal() const
void simple_clamp(VALUE_TYPE &value, const VALUE_TYPE &lower, const VALUE_TYPE &upper)
float shortest_distance(const Line &rhs) const
void double_unclamp(VALUE_TYPE &min_value, VALUE_TYPE &max_value, const VALUE_TYPE &new_value)
float shortest_distance(const Infinite_Cylinder &rhs) const
std::pair< float, float > nearest_point(const Capsule &rhs) const
Returns <distance, interpolation value [0.0f, 1.0f]>
float magnitude() const
Get the magnitude of the vector.
float shortest_distance(const Sphere &rhs) const
const float & get_radius() const
Collision Infinite Cylinder.
A 3D Point represented with floats.
const Point3f & get_center() const
std::pair< float, float > unpoof(const std::pair< float, float > &lhs, const float &radii)
A Featureful 3-Space Vector Class.
const Matrix4f & get_convert_from() const
Collision Parallelepiped.
const Point3f & get_point() const
float shortest_distance(const Parallelepiped &rhs) const
EGLSurface EGLint void ** value
const Matrix4f & get_convert_to() const
std::pair< float, float > nearest_point(const Line_Segment &rhs) const
Returns <distance, interpolation value [0.0f, 1.0f]>
GLdouble GLdouble GLdouble b
GLint GLint GLint GLint GLint w
const Point3f & get_point() const
void absolute_float_unclamp(float &value, const float &new_value)
std::pair< float, float > nearest_point(const Ray &rhs) const
Returns <distance, interpolation value [0.0f, inf)>