Implemented collisions.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#define UTILS_QTREE_H_
|
||||
|
||||
#include <utils/Assert.h>
|
||||
#include <utils/Exceptions.h>
|
||||
#include <utils/INonAssignable.h>
|
||||
#include <utils/Rect.h>
|
||||
|
||||
@@ -58,7 +59,7 @@ namespace utils {
|
||||
/**
|
||||
* Quad tree
|
||||
*/
|
||||
template <typename T, size_t Capacity>
|
||||
template <typename T, size_t Capacity = 16>
|
||||
class QTree : public INonAssignable
|
||||
{
|
||||
public:
|
||||
@@ -74,11 +75,13 @@ namespace utils {
|
||||
bool empty() const;
|
||||
size_t size() const;
|
||||
|
||||
void insert(T element, float x, float y);
|
||||
void insert(const T& element, float x, float y);
|
||||
void move(iterator it, float newX, float newY);
|
||||
void erase(iterator it);
|
||||
void clear();
|
||||
|
||||
iterator find(T element);
|
||||
iterator find(const T& element);
|
||||
iterator find(const T& element, float x, float y);
|
||||
iterator lower_bound(const RectF& area);
|
||||
iterator upper_bound(const RectF& area);
|
||||
|
||||
@@ -312,7 +315,7 @@ namespace utils {
|
||||
}
|
||||
|
||||
template<typename T, size_t Capacity>
|
||||
void QTree<T, Capacity>::insert(T element, float x, float y)
|
||||
void QTree<T, Capacity>::insert(const T& element, float x, float y)
|
||||
{
|
||||
Assert(m_bounds.contains(x, y), "Can't add element outside bounds.");
|
||||
|
||||
@@ -344,6 +347,54 @@ namespace utils {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, size_t Capacity>
|
||||
void QTree<T, Capacity>::move(iterator it, float newX, float newY)
|
||||
{
|
||||
Assert(!it.m_tree->m_isSplit, "Container modified.");
|
||||
Assert(it.m_item < it.m_tree->m_itemsCount, "Container modified.");
|
||||
|
||||
// Find destination tree
|
||||
QTree<T, Capacity>* destTree = this;
|
||||
bool found = false;
|
||||
do
|
||||
{
|
||||
// Go to parent
|
||||
if (!destTree->m_bounds.contains(newX, newY))
|
||||
destTree = destTree->m_parent;
|
||||
|
||||
// Go to child
|
||||
else if (destTree->m_isSplit)
|
||||
{
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
if (destTree->m_children[i]->m_bounds.contains(newX, newY))
|
||||
{
|
||||
destTree = destTree->m_children[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
|
||||
} while (!found && destTree != nullptr);
|
||||
|
||||
if (destTree == nullptr)
|
||||
THROW(InvalidArgumentException, "Iterator doesn't belong to this tree.");
|
||||
|
||||
// No need to move
|
||||
if (destTree == it.m_tree)
|
||||
{
|
||||
it->x = newX;
|
||||
it->y = newY;
|
||||
}
|
||||
|
||||
// Need to move. Preform an 'erase' and an 'insert'
|
||||
T dataTemp = it->data;
|
||||
it.m_tree->erase(it);
|
||||
destTree->insert(dataTemp, newX, newY);
|
||||
}
|
||||
|
||||
template<typename T, size_t Capacity>
|
||||
void QTree<T, Capacity>::erase(iterator it)
|
||||
{
|
||||
@@ -385,7 +436,7 @@ namespace utils {
|
||||
}
|
||||
|
||||
template<typename T, size_t Capacity>
|
||||
typename QTree<T, Capacity>::iterator QTree<T, Capacity>::find(T element)
|
||||
typename QTree<T, Capacity>::iterator QTree<T, Capacity>::find(const T& element)
|
||||
{
|
||||
for (auto it = begin(); it != end(); it++)
|
||||
if (it->data == element)
|
||||
@@ -394,6 +445,31 @@ namespace utils {
|
||||
return end();
|
||||
}
|
||||
|
||||
template<typename T, size_t Capacity>
|
||||
typename QTree<T, Capacity>::iterator QTree<T, Capacity>::find(const T& element, float x, float y)
|
||||
{
|
||||
if (!m_bounds.contains(x, y))
|
||||
{
|
||||
if (m_parent)
|
||||
return m_parent->find(element, x, y);
|
||||
return end();
|
||||
}
|
||||
if (m_isSplit)
|
||||
{
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
if (m_children[i]->m_bounds.contains(x, y))
|
||||
return m_children[i]->find(element, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < m_itemsCount; i++)
|
||||
if (m_items[i].data == element && m_items[i].x == x && m_items[i].y == y)
|
||||
return iterator(this, RectF(x, y, 0, 0), i);
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
template<typename T, size_t Capacity>
|
||||
typename QTree<T, Capacity>::iterator QTree<T, Capacity>::lower_bound(const RectF& area)
|
||||
{
|
||||
|
Reference in New Issue
Block a user