#include "precompile.h" #include #include #include #include void TestGlm() { glm::vec3 orig(0.0, 0.0, 0.0); glm::vec3 dir(1.0, 1.0, 0); glm::vec3 v0(0.0, 1.0, 0); glm::vec3 v1(1.3, 1.0, 0); glm::vec3 v2(0.0, 2.0, 0); glm::vec3 baryPosition; bool ret = glm::intersectRayTriangle(orig, dir, v0, v1, v2, baryPosition); int i = 0; } bool IntersectSegmentCircle(Vector2D p0, Vector2D p1, Vector2D pos, float rad) { Vector2D t = p1 - p0; float d = std::max(t.Norm(), 0.0001f); Vector2D n = p0 - pos; float v = n.Dot(t); float z = n.Dot(n) - rad*rad; if (z > 0 && v > 0) { return false; } float u = v*v - z; if (u < 0) { return false; } float i = sqrt(u); float x = -v - i; if (x < 0 && (x = -v + i), x <= d) { return true; } return false; } bool IntersectSegmentAabb(Vector2D p0, Vector2D p1, Vector2D _min, Vector2D _max) { float t = 0.0f; float d = FLT_MAX; Vector2D n = p0; Vector2D v = p1 - p0; float z = v.Norm(); v = z > (float)1e-5 ? v / z : Vector2D(1, 0); if (std::abs(v.x) < (float)1e-5) { v.x = float(2e-5); } if (std::abs(v.y) < (float)1e-5) { v.y = (float)2e-5; } if (std::abs(v.x) > (float)1e-5) { float u = (_min.x - n.x) / v.x; float i = (_max.x - n.x) / v.x; t = std::max(t, std::min(u, i)); d = std::min(d, std::max(u, i)); if (t > d) { return false; } } if (std::abs(v.y) > (float)1e-5) { float x = (_min.y - n.y) / v.y; float l = (_max.y - n.y) / v.y; t = std::max(t, std::min(x, l)); d = std::min(d, std::max(x, l)); if (t > d) { return false; } } if (t > z) { return false; } return true; } bool IntersectAabbCircle(Vector2D a_min, Vector2D a_max, Vector2D b_pos, float b_rad) { if (b_pos.x >= a_min.x && b_pos.x <= a_max.x && b_pos.y >= a_min.y && b_pos.y <= a_max.y) { return true; } Vector2D nearest_point(a8::Clamp(b_pos.x, a_min.x, a_max.x), a8::Clamp(b_pos.y, a_min.y, a_max.y)); Vector2D i = b_pos - nearest_point; float n = a8::LengthSqr(i); return n < b_rad*b_rad; } bool IntersectAabbAabb(Vector2D a_min, Vector2D a_max, Vector2D b_min, Vector2D b_max) { Vector2D a_v = (a_max - a_min) * 0.5f; Vector2D a_center = a_min + a_v; Vector2D b_v = (b_max - b_min) * 0.5f; Vector2D b_center = b_min + b_v; Vector2D z = b_center - a_center; float u = a_v.x + b_v.x - std::abs(z.x); return u > 0; } bool IntersectCircleCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad) { float t = a_rad + b_rad; Vector2D d = b_pos - a_pos; float n = a8::LengthSqr(d); return n < t*t; } bool CircleContainCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad) { float distance = (a_pos - b_pos).Norm(); return distance < a_rad - b_rad; } bool CalcCircleAabbSafePoint(Vector2D a_min, Vector2D a_max, Vector2D b_pos, float b_rad, Vector2D& new_pos) { new_pos = b_pos; bool at_left = std::abs(b_pos.x - a_min.x) < std::abs(b_pos.x - a_max.x); bool at_down = std::abs(b_pos.y - a_min.y) < std::abs(b_pos.y - a_max.y); float x_len = at_left ? std::abs(b_pos.x - a_min.x) : std::abs(b_pos.x - a_max.x); float y_len = at_down ? std::abs(b_pos.y - a_min.y) : std::abs(b_pos.y - a_max.y); if (at_left) { if (x_len < y_len) { //左 new_pos.x = a_min.x - b_rad - 1; } else { if (at_down) { new_pos.y = a_min.y - b_rad - 1; } else { new_pos.y = a_max.y + b_rad + 1; } } } else { if (x_len < y_len) { //右 new_pos.x = a_max.x + b_rad + 1; } else { if (at_down) { new_pos.y = a_min.y - b_rad - 1; } else { new_pos.y = a_max.y + b_rad + 1; } } } return true; }