summaryrefslogtreecommitdiff
path: root/Runtime/Physics2D/PolygonCollider2D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Physics2D/PolygonCollider2D.cpp')
-rw-r--r--Runtime/Physics2D/PolygonCollider2D.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/Runtime/Physics2D/PolygonCollider2D.cpp b/Runtime/Physics2D/PolygonCollider2D.cpp
new file mode 100644
index 0000000..da41b0d
--- /dev/null
+++ b/Runtime/Physics2D/PolygonCollider2D.cpp
@@ -0,0 +1,134 @@
+#include "UnityPrefix.h"
+
+#if ENABLE_2D_PHYSICS
+
+#include "Runtime/Physics2D/PolygonCollider2D.h"
+#include "Runtime/Graphics/Transform.h"
+#include "Runtime/Math/FloatConversion.h"
+#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
+#include "Runtime/Filters/AABBUtility.h"
+#if ENABLE_SPRITES
+#include "Runtime/Graphics/SpriteFrame.h"
+#include "Runtime/Filters/Mesh/SpriteRenderer.h"
+#endif
+
+IMPLEMENT_CLASS (PolygonCollider2D)
+IMPLEMENT_OBJECT_SERIALIZE (PolygonCollider2D)
+
+
+// --------------------------------------------------------------------------
+
+
+PolygonCollider2D::PolygonCollider2D (MemLabelId label, ObjectCreationMode mode)
+: Super(label, mode)
+{
+}
+
+
+PolygonCollider2D::~PolygonCollider2D ()
+{
+}
+
+
+template<class TransferFunction>
+void PolygonCollider2D::Transfer (TransferFunction& transfer)
+{
+ Super::Transfer (transfer);
+
+ TRANSFER (m_Poly);
+}
+
+void PolygonCollider2D::Reset ()
+{
+ Super::Reset ();
+
+ // Create pentagon shape
+ CreateNgon (5, Vector2f(1, 1), Vector2f(0,0), m_Poly);
+}
+
+
+void PolygonCollider2D::SmartReset ()
+{
+ float radius;
+ Vector2f offset;
+
+ GameObject* go = GetGameObjectPtr();
+#if ENABLE_SPRITES
+ if (go)
+ {
+ SpriteRenderer* sr = go->QueryComponentT<SpriteRenderer>(ClassID(SpriteRenderer));
+ if (sr)
+ {
+ Sprite* sprite = sr->GetSprite();
+ if (sprite)
+ {
+ m_Poly.GenerateFrom(sprite, Vector2f(0, 0), 0.25f, 200, true);
+ if (m_Poly.GetPathCount() > 0) // We might fail if all pixels are under the threshold. No workaround in 4.3.
+ return;
+ }
+ }
+ }
+#endif
+
+ // Resolve what size collider we should have from object bounds
+ AABB aabb;
+ if (go && CalculateLocalAABB (GetGameObject (), &aabb))
+ {
+ Vector3f dist = aabb.GetExtent ();
+ radius = std::max(dist.x, dist.y);
+ if (radius <= 0.0f)
+ radius = 1.0f;
+ offset.x = aabb.GetCenter().x;
+ offset.y = aabb.GetCenter().y;
+ }
+ else
+ {
+ radius = 1.0f;
+ offset = Vector2f::zero;
+ }
+
+ // Create pentagon shape
+ CreateNgon (5, Vector2f(radius, radius), offset, m_Poly);
+}
+
+
+void PolygonCollider2D::RefreshPoly()
+{
+ Create();
+ SetDirty();
+}
+
+
+void PolygonCollider2D::CreatePrimitive (int sides, Vector2f scale, Vector2f offset)
+{
+ Assert (sides > 2);
+ Assert (scale.x > 0.0f);
+ Assert (scale.y > 0.0f);
+
+ CreateNgon (sides, scale, offset, m_Poly);
+
+ // Create polygon shape.
+ Create();
+ SetDirty();
+}
+
+
+void PolygonCollider2D::CreateNgon (const int sides, const Vector2f scale, const Vector2f offset, Polygon2D& polygon2D)
+{
+ Polygon2D::TPath path;
+
+ // Generate regular n-sided polygon.
+ const float tau = kPI * 2.0f;
+ const float chordAngle = tau / (float)sides;
+ float angle = 0.0f;
+ for (int chord = 0; chord < sides; ++chord, angle += chordAngle)
+ {
+ path.push_back (Vector2f(offset.x + scale.x * Sin(angle), offset.y + scale.y * Cos(angle)));
+ }
+
+ // Set polygon path.
+ polygon2D.SetPathCount (1);
+ polygon2D.SetPath (0, path);
+}
+
+#endif // #if ENABLE_2D_PHYSICS