From 03939299dbf4de6d6a48230a8dc17932e0d3d2d1 Mon Sep 17 00:00:00 2001 From: Klonan <11986037+Klonan@users.noreply.github.com> Date: Sat, 27 Aug 2022 17:12:19 +0200 Subject: [PATCH] Added World:getFixturesInArea() --- changes.txt | 5 ++-- src/modules/physics/box2d/World.cpp | 36 ++++++++++++++++++++++++ src/modules/physics/box2d/World.h | 20 ++++++++++++- src/modules/physics/box2d/wrap_World.cpp | 10 +++++++ 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/changes.txt b/changes.txt index 2b98cbc6e..d5a383905 100644 --- a/changes.txt +++ b/changes.txt @@ -45,6 +45,7 @@ Released: N/A * Added love.keyboard.isModifierActive. * Added love.system.getPreferredLocales. * Added love.localechanged callback. +* Added World:getFixturesInArea(). * Changed the default font from Vera size 12 to Noto Sans size 13. * Changed the Texture class and implementation to no longer have separate Canvas and Image subclasses. @@ -165,7 +166,7 @@ Released: 2019-10-27 * Fixed audio clicks immediately after playing a Source on iOS. * Fixed Source:play + Source:stop + Source:play looping the first few ms of sound for streaming Sources on iOS. * Fixed Source:play + Source:seek looping the first few ms of sound for streaming Sources on iOS. -* Fixed occasional pops in streaming sources on iOS. +* Fixed occasional pops in streaming sources on iOS. * Fixed love.audio.play(sources) to use previously set playback positions on stopped Sources. * Fixed Source:setEffect(name, true) and Source:getEffect(name) when the effect has no associated Filter. * Fixed love.audio.newSource(filename, "queue") to cause a Lua error. @@ -437,7 +438,7 @@ Released: 2016-10-31 * Improved performance of Channel methods by roughly 2x in many cases. * Improved performance of Shader:send when small numbers of arguments are given. - + * Updated love.filesystem.mount to accept a DroppedFile as the first parameter. * Updated Shader:send to do type and argument checking based on the specified uniform variable's information instead of the arguments to the function. * Updated Shader:send to accept a flat table for matrix uniforms. diff --git a/src/modules/physics/box2d/World.cpp b/src/modules/physics/box2d/World.cpp index d7ba8d11d..a5bc8c8cf 100644 --- a/src/modules/physics/box2d/World.cpp +++ b/src/modules/physics/box2d/World.cpp @@ -171,6 +171,28 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture) return true; } +World::CollectCallback::CollectCallback(World *world, lua_State *L) + : world(world) + , L(L) +{ + lua_newtable(L); +} + +World::CollectCallback::~CollectCallback() +{ +} + +bool World::CollectCallback::ReportFixture(b2Fixture *f) +{ + Fixture* fixture = (Fixture*)world->findObject(f); + if (!fixture) + throw love::Exception("A fixture has escaped Memoizer!"); + luax_pushtype(L, fixture); + lua_rawseti(L, -2, i); + i++; + return true; +} + World::RayCastCallback::RayCastCallback(World *world, lua_State *L, int idx) : world(world) , L(L) @@ -556,6 +578,20 @@ int World::queryBoundingBox(lua_State *L) return 0; } +int World::getFixturesInArea(lua_State *L) +{ + float lx = (float)luaL_checknumber(L, 1); + float ly = (float)luaL_checknumber(L, 2); + float ux = (float)luaL_checknumber(L, 3); + float uy = (float)luaL_checknumber(L, 4); + b2AABB box; + box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly)); + box.upperBound = Physics::scaleDown(b2Vec2(ux, uy)); + CollectCallback query(this, L); + world->QueryAABB(&query, box); + return 1; +} + int World::rayCast(lua_State *L) { float x1 = (float)luaL_checknumber(L, 1); diff --git a/src/modules/physics/box2d/World.h b/src/modules/physics/box2d/World.h index 39bfe0333..247bea463 100644 --- a/src/modules/physics/box2d/World.h +++ b/src/modules/physics/box2d/World.h @@ -102,6 +102,18 @@ public: int funcidx; }; + class CollectCallback : public b2QueryCallback + { + public: + CollectCallback(World *world, lua_State *L); + ~CollectCallback(); + virtual bool ReportFixture(b2Fixture *fixture); + private: + World *world; + lua_State *L; + int i = 1; + }; + class RayCastCallback : public b2RayCastCallback { public: @@ -270,10 +282,16 @@ public: b2Body *getGroundBody() const; /** - * Gets all fixtures that overlap a given bounding box. + * Calls a callback on all fixtures that overlap a given bounding box. **/ int queryBoundingBox(lua_State *L); + /** + * Gets all fixtures that overlap a given bounding box. + **/ + int getFixturesInArea(lua_State *L); + + /** * Raycasts the World for all Fixtures in the path of the ray. **/ diff --git a/src/modules/physics/box2d/wrap_World.cpp b/src/modules/physics/box2d/wrap_World.cpp index 6b3e13a48..676e6bfda 100644 --- a/src/modules/physics/box2d/wrap_World.cpp +++ b/src/modules/physics/box2d/wrap_World.cpp @@ -185,6 +185,15 @@ int w_World_queryBoundingBox(lua_State *L) return t->queryBoundingBox(L); } +int w_World_getFixturesInArea(lua_State *L) +{ + World *t = luax_checkworld(L, 1); + lua_remove(L, 1); + int ret = 0; + luax_catchexcept(L, [&](){ ret = t->getFixturesInArea(L); }); + return ret; +} + int w_World_rayCast(lua_State *L) { World *t = luax_checkworld(L, 1); @@ -228,6 +237,7 @@ static const luaL_Reg w_World_functions[] = { "getJoints", w_World_getJoints }, { "getContacts", w_World_getContacts }, { "queryBoundingBox", w_World_queryBoundingBox }, + { "getFixturesInArea", w_World_getFixturesInArea }, { "rayCast", w_World_rayCast }, { "destroy", w_World_destroy }, { "isDestroyed", w_World_isDestroyed },