From 28b391af48c1d7200c60004d4c5f87872fbbdb49 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 19 Mar 2019 14:38:09 +0800 Subject: [PATCH] remove obb box --- server/gameserver/collider.cc | 195 ++++++++++++++++++++++++++-------- server/gameserver/collider.h | 90 ---------------- server/gameserver/types.cc | 11 ++ server/gameserver/types.h | 2 + 4 files changed, 162 insertions(+), 136 deletions(-) diff --git a/server/gameserver/collider.cc b/server/gameserver/collider.cc index 14ce0b5..904b647 100644 --- a/server/gameserver/collider.cc +++ b/server/gameserver/collider.cc @@ -1,11 +1,94 @@ #include "precompile.h" #include +#include #include "entity.h" #include "collider.h" #if 0 + +struct Segment +{ + Vector2D p0; + Vector2D p1; + Vector2D dir; + + Segment(const Vector2D& p0_, const Vector2D& p1_) + { + p0 = p0_; + p1 = p1_; + dir = p1 - p0; + } +}; + +struct Polygon +{ + std::vector vertices; + std::vector edges; + + std::tuple Project(Vector2D axis) + { + axis = axis.Normalize(); + float min_v = vertices[0].Dot(axis); + float max_v = min_v; + for (size_t i = 0; i < vertices.size(); ++i) { + float proj = vertices[i].Dot(axis); + if (proj < min_v) { + min_v = proj; + } + if (proj > max_v) { + max_v = proj; + } + } + return std::make_tuple(min_v, max_v); + } + + bool Contains(float n, std::tuple& range) + { + float a = std::get<0>(range); + float b = std::get<1>(range); + if (b < a) { + a = b; + b = std::get<0>(range); + } + return n >= a && n <= b; + } + + bool Overlap(std::tuple& a, std::tuple& b) + { + return + Contains(std::get<0>(a), b) || + Contains(std::get<1>(a), b) || + Contains(std::get<0>(b), a) || + Contains(std::get<1>(b), a); + } + + bool Sat(Polygon& b) + { + for (size_t i = 0; i < vertices.size(); ++i) { + Vector2D axis = edges[i].dir; + axis = axis.Perp(); + auto a_ = Project(axis); + auto b_ = b.Project(axis); + if (!Overlap(a_, b_)) { + return false; + } + } + for (size_t i = 0; i < b.vertices.size(); ++i) { + Vector2D axis = b.edges[i].dir; + axis = axis.Perp(); + auto a_ = Project(axis); + auto b_ = b.Project(axis); + if (!Overlap(a_, b_)) { + return false; + } + } + return true; + } + +}; + static Polygon newPolygon(std::vector& vertices) { Polygon shape; @@ -18,6 +101,66 @@ static Polygon newPolygon(std::vector& vertices) } #endif +static 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; +} + +static 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; +} + static bool IntersectAabbCircle(AabbCollider* a, CircleCollider* b) { if (b->pos.x >= a->_min.x && b->pos.x <= a->_max.x && @@ -42,21 +185,6 @@ static bool IntersectAabbAabb(AabbCollider* a, AabbCollider* b) return u > 0; } -static bool IntersectAabbObb(AabbCollider* a, ObbCollider* b) -{ - return false; -} - -static bool IntersectObbObb(ObbCollider* a, ObbCollider* b) -{ - return false; -} - -static bool IntersectObbCircle(ObbCollider* a, CircleCollider* b) -{ - return false; -} - static bool IntersectCircleCircle(CircleCollider* a, CircleCollider* b) { float t = a->rad + b->rad; @@ -68,19 +196,18 @@ static bool IntersectCircleCircle(CircleCollider* a, CircleCollider* b) bool ColliderComponent::Intersect(ColliderComponent* b) { switch (type) { + case CT_None: + break; case CT_Aabb: { switch (b->type) { + case CT_None: + break; case CT_Aabb: { return IntersectAabbAabb((AabbCollider*)this, (AabbCollider*)b); } break; - case CT_Obb: - { - return IntersectAabbObb((AabbCollider*)this, (ObbCollider*)b); - } - break; case CT_Circle: { return IntersectAabbCircle((AabbCollider*)this, (CircleCollider*)b); @@ -89,40 +216,16 @@ bool ColliderComponent::Intersect(ColliderComponent* b) } }; break; - case CT_Obb: - { - switch (b->type) { - case CT_Aabb: - { - return IntersectAabbObb((AabbCollider*)b, (ObbCollider*)this); - } - break; - case CT_Obb: - { - return IntersectObbObb((ObbCollider*)this, (ObbCollider*)b); - } - break; - case CT_Circle: - { - return IntersectObbCircle((ObbCollider*)this, (CircleCollider*)b); - } - break; - } - } - break; case CT_Circle: { switch (b->type) { + case CT_None: + break; case CT_Aabb: { return IntersectAabbCircle((AabbCollider*)b, (CircleCollider*)this); } break; - case CT_Obb: - { - return IntersectObbCircle((ObbCollider*)b, (CircleCollider*)this); - } - break; case CT_Circle: { return IntersectCircleCircle((CircleCollider*)this, (CircleCollider*)b); diff --git a/server/gameserver/collider.h b/server/gameserver/collider.h index 0ee123d..0fdf3d1 100644 --- a/server/gameserver/collider.h +++ b/server/gameserver/collider.h @@ -4,91 +4,9 @@ enum ColliderType_e { CT_None, CT_Aabb, - CT_Obb, CT_Circle }; -struct Segment -{ - Vector2D p0; - Vector2D p1; - Vector2D dir; - - Segment(const Vector2D& p0_, const Vector2D& p1_) - { - p0 = p0_; - p1 = p1_; - dir = p1 - p0; - } -}; - -struct Polygon -{ - std::vector vertices; - std::vector edges; - - std::tuple Project(Vector2D axis) - { - axis = axis.Normalize(); - float min_v = vertices[0].Dot(axis); - float max_v = min_v; - for (size_t i = 0; i < vertices.size(); ++i) { - float proj = vertices[i].Dot(axis); - if (proj < min_v) { - min_v = proj; - } - if (proj > max_v) { - max_v = proj; - } - } - return std::make_tuple(min_v, max_v); - } - - bool Contains(float n, std::tuple& range) - { - float a = std::get<0>(range); - float b = std::get<1>(range); - if (b < a) { - a = b; - b = std::get<0>(range); - } - return n >= a && n <= b; - } - - bool Overlap(std::tuple& a, std::tuple& b) - { - return - Contains(std::get<0>(a), b) || - Contains(std::get<1>(a), b) || - Contains(std::get<0>(b), a) || - Contains(std::get<1>(b), a); - } - - bool Sat(Polygon& b) - { - for (size_t i = 0; i < vertices.size(); ++i) { - Vector2D axis = edges[i].dir; - axis = axis.Perp(); - auto a_ = Project(axis); - auto b_ = b.Project(axis); - if (!Overlap(a_, b_)) { - return false; - } - } - for (size_t i = 0; i < b.vertices.size(); ++i) { - Vector2D axis = b.edges[i].dir; - axis = axis.Perp(); - auto a_ = Project(axis); - auto b_ = b.Project(axis); - if (!Overlap(a_, b_)) { - return false; - } - } - return true; - } - -}; - class Entity; class ColliderComponent { @@ -107,14 +25,6 @@ public: Vector2D _max; }; -class ObbCollider : public ColliderComponent -{ -public: - Vector2D _min; - Vector2D _max; - Vector2D dir; -}; - class CircleCollider : public ColliderComponent { public: diff --git a/server/gameserver/types.cc b/server/gameserver/types.cc index e6ea1e8..c4d7e83 100644 --- a/server/gameserver/types.cc +++ b/server/gameserver/types.cc @@ -43,6 +43,12 @@ Vector2D Vector2D::operator * (float scale) return Vector2D(v[0], v[1]); } +Vector2D Vector2D::operator / (float scale) +{ + Eigen::Vector2f v = Eigen::Vector2f(x, y) * (1.0 / scale); + return Vector2D(v[0], v[1]); +} + Vector2D Vector2D::Rotate(float angle) { Eigen::Vector3f v(x, y, 0); @@ -59,3 +65,8 @@ float Vector2D::Dot(const Vector2D& v) { return x*v.x + y*v.y; } + +float Vector2D::Norm() +{ + return fabs(sqrt(x*x + y*y)); +} diff --git a/server/gameserver/types.h b/server/gameserver/types.h index f6999d7..8ddf7b7 100755 --- a/server/gameserver/types.h +++ b/server/gameserver/types.h @@ -28,8 +28,10 @@ struct Vector2D Vector2D operator + (const Vector2D& b); Vector2D operator - (const Vector2D& b); Vector2D operator * (float scale); + Vector2D operator / (float scale); Vector2D Rotate(float angle); Vector2D Perp(); float Dot(const Vector2D& v); + float Norm(); };