From adcbef19d0c95a54817dd630dccefd49594b1dbd Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Tue, 20 Jun 2017 22:10:32 +0300 Subject: [PATCH] Allow areas to define just bounding boxes. Implement a function to add an array of points. Provide several shorter aliases. Remove some leftover commented code. --- source/Areas.cpp | 47 +++++++++++++++++++++++++++++++++++---------- source/Areas.hpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 12 deletions(-) diff --git a/source/Areas.cpp b/source/Areas.cpp index 0d972515..eb8304e3 100644 --- a/source/Areas.cpp +++ b/source/Areas.cpp @@ -14,9 +14,36 @@ SQMODE_DECL_TYPENAME(AreaTypename, _SC("SqArea")) AreaManager AreaManager::s_Inst; // ------------------------------------------------------------------------------------------------ -void Area::AddArray(const Sqrat::Array &) +void Area::AddArray(const Sqrat::Array & a) { - //todo... + float values[2]; + + a.Foreach([this, &values, n = int(0)](HSQUIRRELVM vm) mutable -> bool { + // Retrieve the type of the value + const SQObjectType type = sq_gettype(vm, -1); + // Are we dealing with a vector? + if (type == OT_INSTANCE) + { + // Next time, start again for floats + n = 0; + // Grab the instance from the stack + this->AddPoint(*ClassType< Vector2 >::GetInstance(vm, -1)); + } + else if (type & SQOBJECT_NUMERIC) + { + // Retrieve the value from the stack + values[n] = Var< float >(vm, -1).value; + // Do we have enough to form a vector? + if (++n == 2) + { + this->AddPointEx(values[0], values[1]); + // Reset the counter + n = 0; + } + } + // Ignore anything else + return true; + }); } // ------------------------------------------------------------------------------------------------ @@ -27,11 +54,6 @@ bool Area::Manage() { STHROWF("The area is already managed"); } - // Is there something to be managed? - else if (mPoints.size() < 3) - { - STHROWF("Areas need at least 3 points to be managed"); - } // We expect this to be called only from the script so that the first parameter in the vm // is the area instance LightObj obj(1, DefaultVM::Get()); @@ -271,10 +293,8 @@ void AreaManager::InsertArea(Area & a, LightObj & obj) return; // Already managed or nothing to manage } // Go through each cell and check if the area touches it - //for (AreaCell (&row)[GRIDN] : m_Grid) for (int y = 0; y < GRIDN; ++y) { - //for (AreaCell & c : row) for (int x = 0; x < GRIDN; ++x) { AreaCell & c = m_Grid[y][x]; @@ -418,7 +438,8 @@ void Register_Areas(HSQUIRRELVM vm) .Prop(_SC("Locked"), &Area::IsLocked) .Prop(_SC("IsLocked"), &Area::IsLocked) .Prop(_SC("Center"), &Area::GetCenter) - .Prop(_SC("BoundingBox"), &Area::GetBoundingBox) + .Prop(_SC("Box"), &Area::GetBoundingBox, &Area::SetBoundingBox) + .Prop(_SC("Empty"), &Area::Empty) .Prop(_SC("Empty"), &Area::Empty) .Prop(_SC("Size"), &Area::Size) .Prop(_SC("Points"), &Area::Size) @@ -428,8 +449,14 @@ void Register_Areas(HSQUIRRELVM vm) .Func(_SC("SetID"), &Area::ApplyID) .Func(_SC("Clear"), &Area::Clear) .Func(_SC("Reserve"), &Area::Reserve) + .Func(_SC("SetBox"), &Area::SetBoundingBoxEx) + .Func(_SC("SetBoundingBox"), &Area::SetBoundingBoxEx) .Func(_SC("Add"), &Area::AddPoint) .Func(_SC("AddEx"), &Area::AddPointEx) + .Func(_SC("AddVirtual"), &Area::AddVirtualPoint) + .Func(_SC("AddVirtualEx"), &Area::AddVirtualPointEx) + .Func(_SC("FakeAdd"), &Area::AddVirtualPoint) + .Func(_SC("FakeAddEx"), &Area::AddVirtualPointEx) .Func(_SC("AddArray"), &Area::AddArray) .Func(_SC("Test"), &Area::Test) .Func(_SC("TestEx"), &Area::TestEx) diff --git a/source/Areas.hpp b/source/Areas.hpp index 9bc56afa..f44d1133 100644 --- a/source/Areas.hpp +++ b/source/Areas.hpp @@ -290,6 +290,32 @@ struct Area return Vector4(mL, mB, mR, mT); } + /* -------------------------------------------------------------------------------------------- + * Modify the bounding box of this area. + */ + void SetBoundingBox(const Vector4 & b) + { + CheckLock(); + // Apply the given bounding box + mL = b.x; + mB = b.y; + mR = b.z; + mT = b.w; + } + + /* -------------------------------------------------------------------------------------------- + * Modify the bounding box of this area. + */ + void SetBoundingBoxEx(float l, float b, float r, float t) + { + CheckLock(); + // Apply the given bounding box + mL = l; + mB = b; + mR = r; + mT = t; + } + /* -------------------------------------------------------------------------------------------- * See whether the area has no points. */ @@ -360,6 +386,26 @@ struct Area Expand(x, y); } + /* -------------------------------------------------------------------------------------------- + * Add a 2D vector to the bounding box only. Not stored in the list. + */ + void AddVirtualPoint(const Vector2 & v) + { + CheckLock(); + // Update the bounding box + Expand(v.x, v.y); + } + + /* -------------------------------------------------------------------------------------------- + * Add a point to the bounding box only. Not stored in the list. + */ + void AddVirtualPointEx(float x, float y) + { + CheckLock(); + // Update the bounding box + Expand(x, y); + } + /* -------------------------------------------------------------------------------------------- * Add an array of points to the point list. */ @@ -373,7 +419,7 @@ struct Area // Is the given point in this bounding box at least? if (mL <= v.x && mR >= v.x && mB <= v.y && mT >= v.y) { - return IsInside(v.x, v.y); + return mPoints.empty() ? true : IsInside(v.x, v.y); } // Not in this area return false; @@ -387,7 +433,7 @@ struct Area // Is the given point in this bounding box at least? if (mL <= x && mR >= x && mB <= y && mT >= y) { - return IsInside(x, y); + return mPoints.empty() ? true : IsInside(x, y); } // Not in this area return false;