/* Minetest Copyright (C) 2018 nerzhul, Loic BLOT This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "test.h" #include "server/serveractiveobjectmap.h" #include "content_sao.h" class TestServerActiveObjectMap : public TestBase { public: TestServerActiveObjectMap() { TestManager::registerTestModule(this); } const char *getName() { return "TestServerActiveObjectMap"; } void runTests(IGameDef *gamedef); void testAddObject(); void testRemoveObject(); void testUpdateObject(); void testGetObject(); void testIsFreeID(); void testGetFreeID(); void testGetObjectsInsideRadius(); void testGetObjectsTouchingBox(); }; static TestServerActiveObjectMap g_test_instance; void TestServerActiveObjectMap::runTests(IGameDef *gamedef) { TEST(testAddObject); TEST(testRemoveObject); TEST(testUpdateObject); TEST(testGetObject); TEST(testIsFreeID); TEST(testGetFreeID); TEST(testGetObjectsInsideRadius); TEST(testGetObjectsTouchingBox); } void TestServerActiveObjectMap::testAddObject() { ServerActiveObjectMap saom; UASSERT(saom.getObjects().empty()); LuaEntitySAO ob1(nullptr, v3f(0, 0, 0), "", ""); ob1.setId(saom.getFreeId()); saom.addObject(&ob1); UASSERT(saom.getObjects().size() == 1); bool found = false; for (const auto &pair : saom.getObjects()) { UASSERT(pair.second.object == &ob1); found = true; } UASSERT(found); } void TestServerActiveObjectMap::testRemoveObject() { ServerActiveObjectMap saom; UASSERT(saom.getObjects().empty()); LuaEntitySAO ob1(nullptr, v3f(0, 0, 0), "", ""); ob1.setId(saom.getFreeId()); saom.addObject(&ob1); UASSERT(saom.getObjects().size() == 1); bool found = false; for (const auto &pair : saom.getObjects()) { UASSERT(pair.second.object == &ob1); found = true; } UASSERT(found); saom.removeObject(&ob1); } void TestServerActiveObjectMap::testUpdateObject() { ServerActiveObjectMap saom; LuaEntitySAO ob1(nullptr, v3f(1, 0, 0), "", ""); ob1.accessObjectProperties()->physical = true; ob1.setId(saom.getFreeId()); saom.addObject(&ob1); UASSERT(saom.getObjectsInsideRadius(v3f(0, 0, 0), 2).size() == 1); UASSERT(saom.getObjectsInsideRadius(v3f(6, 0, 0), 2).size() == 0); ob1.setBasePosition(v3f(5, 0, 0)); saom.updateObject(&ob1); UASSERT(saom.getObjectsInsideRadius(v3f(0, 0, 0), 2).size() == 0); UASSERT(saom.getObjectsInsideRadius(v3f(6, 0, 0), 2).size() == 1); } void TestServerActiveObjectMap::testGetObject() { ServerActiveObjectMap saom; LuaEntitySAO ob1(nullptr, v3f(0, 0, 0), "", ""); u16 id = saom.getFreeId(); ob1.setId(id); saom.addObject(&ob1); UASSERT(saom.getObject(0) == nullptr); UASSERT(saom.getObject(id) == &ob1); UASSERT(saom.getObject(id + 1) == nullptr); } void TestServerActiveObjectMap::testIsFreeID() { ServerActiveObjectMap saom; UASSERT(!saom.isFreeId(0)); UASSERT(saom.isFreeId(1)); UASSERT(saom.isFreeId(2)); } void TestServerActiveObjectMap::testGetFreeID() { ServerActiveObjectMap saom; u16 first_id = saom.getFreeId(); UASSERT(first_id > 0); UASSERT(saom.getFreeId() > first_id); } void TestServerActiveObjectMap::testGetObjectsInsideRadius() { ServerActiveObjectMap saom; #define ADD_OBJECT_IMPL(name, pos) \ LuaEntitySAO name(nullptr, pos, "", ""); \ name.accessObjectProperties()->physical = true; \ name.setId(saom.getFreeId()); \ saom.addObject(&name) #define ADD_OBJECT(pos) ADD_OBJECT_IMPL(NEWNAME(ob), pos) #define OBJECT_COUNT (saom.getObjectsInsideRadius(v3f(0, 0, 0), 5).size()) UASSERT(OBJECT_COUNT == 0); ADD_OBJECT(v3f(0, 0, 0)); UASSERT(OBJECT_COUNT == 1); ADD_OBJECT(v3f(-1, -1, -1)); UASSERT(OBJECT_COUNT == 2); ADD_OBJECT(v3f(4.9, 0, 0)); UASSERT(OBJECT_COUNT == 3); ADD_OBJECT(v3f(5.1, 0, 0)); UASSERT(OBJECT_COUNT == 3); ADD_OBJECT(v3f(3, 3, 3)); UASSERT(OBJECT_COUNT == 3); } void TestServerActiveObjectMap::testGetObjectsTouchingBox() { ServerActiveObjectMap saom; LuaEntitySAO ob1(nullptr, v3f(1 * BS, 0, 0), "", ""); ob1.accessObjectProperties()->physical = true; // Collision boxes are in nodes, not in world units: ob1.accessObjectProperties()->collisionbox = {-1, -1, -1, 1, 1, 1}; ob1.setId(saom.getFreeId()); saom.addObject(&ob1); LuaEntitySAO ob2(nullptr, v3f(1.5 * BS, 2.5 * BS, 0), "", ""); ob2.accessObjectProperties()->physical = true; ob2.accessObjectProperties()->collisionbox = {-0.5, -0.5, -1, 3.5, 2, 1}; ob2.setId(saom.getFreeId()); saom.addObject(&ob2); std::vector list; list = saom.getObjectsTouchingBox( {2.1 * BS, -1.0 * BS, -1.0 * BS, 2.5 * BS, 1.0 * BS, 1.0 * BS}); UASSERT(list.size() == 0); // intersecting ob1 list = saom.getObjectsTouchingBox( {1.9 * BS, -1.0 * BS, -1.0 * BS, 2.5 * BS, 1.0 * BS, 1.0 * BS}); UASSERT(list.size() == 1 && list[0] == ob1.getId()); // intersecting ob2 list = saom.getObjectsTouchingBox( {2.1 * BS, -1.0 * BS, -1.0 * BS, 2.5 * BS, 2.1 * BS, 1.0 * BS}); UASSERT(list.size() == 1 && list[0] == ob2.getId()); // contained in ob1 list = saom.getObjectsTouchingBox( {1.5 * BS, -0.1 * BS, -0.1 * BS, 1.9 * BS, 0.1 * BS, 0.1 * BS}); UASSERT(list.size() == 1 && list[0] == ob1.getId()); // contains ob2 list = saom.getObjectsTouchingBox( {0.9 * BS, 1.5 * BS, -5.0 * BS, 6.0 * BS, 20.0 * BS, 500.0 * BS}); UASSERT(list.size() == 1 && list[0] == ob2.getId()); // intersecting both list = saom.getObjectsTouchingBox( {1.9 * BS, -1.0 * BS, -1.0 * BS, 2.5 * BS, 2.1 * BS, 1.0 * BS}); UASSERT(list.size() == 2); }