diff options
Diffstat (limited to 'core/math/face3.cpp')
-rw-r--r-- | core/math/face3.cpp | 79 |
1 files changed, 31 insertions, 48 deletions
diff --git a/core/math/face3.cpp b/core/math/face3.cpp index 74331b391f..db2bfaa58b 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -30,10 +30,9 @@ #include "face3.h" -#include "core/math/geometry.h" +#include "core/math/geometry_3d.h" int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_over[3]) const { - ERR_FAIL_COND_V(is_degenerate(), 0); Vector3 above[4]; @@ -43,7 +42,6 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_ int below_count = 0; for (int i = 0; i < 3; i++) { - if (p_plane.has_point(vertex[i], CMP_EPSILON)) { // point is in plane ERR_FAIL_COND_V(above_count >= 4, 0); @@ -52,7 +50,6 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_ below[below_count++] = vertex[i]; } else { - if (p_plane.is_point_over(vertex[i])) { //Point is over ERR_FAIL_COND_V(above_count >= 4, 0); @@ -67,8 +64,9 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_ /* Check for Intersection between this and the next vertex*/ Vector3 inters; - if (!p_plane.intersects_segment(vertex[i], vertex[(i + 1) % 3], &inters)) + if (!p_plane.intersects_segment(vertex[i], vertex[(i + 1) % 3], &inters)) { continue; + } /* Intersection goes to both */ ERR_FAIL_COND_V(above_count >= 4, 0); @@ -83,13 +81,11 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_ ERR_FAIL_COND_V(above_count >= 4 && below_count >= 4, 0); //bug in the algo if (above_count >= 3) { - p_res[polygons_created] = Face3(above[0], above[1], above[2]); p_is_point_over[polygons_created] = true; polygons_created++; if (above_count == 4) { - p_res[polygons_created] = Face3(above[2], above[3], above[0]); p_is_point_over[polygons_created] = true; polygons_created++; @@ -97,13 +93,11 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_ } if (below_count >= 3) { - p_res[polygons_created] = Face3(below[0], below[1], below[2]); p_is_point_over[polygons_created] = false; polygons_created++; if (below_count == 4) { - p_res[polygons_created] = Face3(below[2], below[3], below[0]); p_is_point_over[polygons_created] = false; polygons_created++; @@ -114,52 +108,49 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_ } bool Face3::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const { - - return Geometry::ray_intersects_triangle(p_from, p_dir, vertex[0], vertex[1], vertex[2], p_intersection); + return Geometry3D::ray_intersects_triangle(p_from, p_dir, vertex[0], vertex[1], vertex[2], p_intersection); } bool Face3::intersects_segment(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const { - - return Geometry::segment_intersects_triangle(p_from, p_dir, vertex[0], vertex[1], vertex[2], p_intersection); + return Geometry3D::segment_intersects_triangle(p_from, p_dir, vertex[0], vertex[1], vertex[2], p_intersection); } bool Face3::is_degenerate() const { - Vector3 normal = vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]); return (normal.length_squared() < CMP_EPSILON2); } Face3::Side Face3::get_side_of(const Face3 &p_face, ClockDirection p_clock_dir) const { - int over = 0, under = 0; Plane plane = get_plane(p_clock_dir); for (int i = 0; i < 3; i++) { - const Vector3 &v = p_face.vertex[i]; - if (plane.has_point(v)) //coplanar, don't bother + if (plane.has_point(v)) { //coplanar, don't bother continue; + } - if (plane.is_point_over(v)) + if (plane.is_point_over(v)) { over++; - else + } else { under++; + } } - if (over > 0 && under == 0) + if (over > 0 && under == 0) { return SIDE_OVER; - else if (under > 0 && over == 0) + } else if (under > 0 && over == 0) { return SIDE_UNDER; - else if (under == 0 && over == 0) + } else if (under == 0 && over == 0) { return SIDE_COPLANAR; - else + } else { return SIDE_SPANNING; + } } Vector3 Face3::get_random_point_inside() const { - real_t a = Math::random(0, 1); real_t b = Math::random(0, 1); if (a > b) { @@ -170,32 +161,28 @@ Vector3 Face3::get_random_point_inside() const { } Plane Face3::get_plane(ClockDirection p_dir) const { - return Plane(vertex[0], vertex[1], vertex[2], p_dir); } Vector3 Face3::get_median_point() const { - return (vertex[0] + vertex[1] + vertex[2]) / 3.0; } real_t Face3::get_area() const { - return vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]).length(); } ClockDirection Face3::get_clock_dir() const { - Vector3 normal = vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]); //printf("normal is %g,%g,%g x %g,%g,%g- wtfu is %g\n",tofloat(normal.x),tofloat(normal.y),tofloat(normal.z),tofloat(vertex[0].x),tofloat(vertex[0].y),tofloat(vertex[0].z),tofloat( normal.dot( vertex[0] ) ) ); return (normal.dot(vertex[0]) >= 0) ? CLOCKWISE : COUNTERCLOCKWISE; } bool Face3::intersects_aabb(const AABB &p_aabb) const { - /** TEST PLANE **/ - if (!p_aabb.intersects_plane(get_plane())) + if (!p_aabb.intersects_plane(get_plane())) { return false; + } #define TEST_AXIS(m_ax) \ /** TEST FACE AXIS */ \ @@ -228,7 +215,6 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const { }; for (int i = 0; i < 12; i++) { - Vector3 from, to; p_aabb.get_edge(i, from, to); Vector3 e1 = from - to; @@ -237,58 +223,57 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const { Vector3 axis = vec3_cross(e1, e2); - if (axis.length_squared() < 0.0001) + if (axis.length_squared() < 0.0001) { continue; // coplanar + } axis.normalize(); real_t minA, maxA, minB, maxB; p_aabb.project_range_in_plane(Plane(axis, 0), minA, maxA); project_range(axis, Transform(), minB, maxB); - if (maxA < minB || maxB < minA) + if (maxA < minB || maxB < minA) { return false; + } } } return true; } Face3::operator String() const { - return String() + vertex[0] + ", " + vertex[1] + ", " + vertex[2]; } void Face3::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - for (int i = 0; i < 3; i++) { - Vector3 v = p_transform.xform(vertex[i]); real_t d = p_normal.dot(v); - if (i == 0 || d > r_max) + if (i == 0 || d > r_max) { r_max = d; + } - if (i == 0 || d < r_min) + if (i == 0 || d < r_min) { r_min = d; + } } } void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const { - #define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.98 #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.05 - if (p_max <= 0) + if (p_max <= 0) { return; + } Vector3 n = p_transform.basis.xform_inv(p_normal); /** TEST FACE AS SUPPORT **/ if (get_plane().normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { - *p_count = MIN(3, p_max); for (int i = 0; i < *p_count; i++) { - p_vertices[i] = p_transform.xform(vertex[i]); } @@ -301,7 +286,6 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V real_t support_max = 0; for (int i = 0; i < 3; i++) { - real_t d = n.dot(vertex[i]); if (i == 0 || d > support_max) { @@ -313,19 +297,19 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V /** TEST EDGES AS SUPPORT **/ for (int i = 0; i < 3; i++) { - - if (i != vert_support_idx && i + 1 != vert_support_idx) + if (i != vert_support_idx && i + 1 != vert_support_idx) { continue; + } // check if edge is valid as a support real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n); dot = ABS(dot); if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { - *p_count = MIN(2, p_max); - for (int j = 0; j < *p_count; j++) + for (int j = 0; j < *p_count; j++) { p_vertices[j] = p_transform.xform(vertex[(j + i) % 3]); + } return; } @@ -336,7 +320,6 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V } Vector3 Face3::get_closest_point_to(const Vector3 &p_point) const { - Vector3 edge0 = vertex[1] - vertex[0]; Vector3 edge1 = vertex[2] - vertex[0]; Vector3 v0 = vertex[0] - p_point; |