2013-11-28 11:14:24 +01:00
|
|
|
#include "Octree.h"
|
|
|
|
|
|
|
|
using namespace Oyster;
|
|
|
|
using namespace Physics;
|
2013-11-28 17:59:12 +01:00
|
|
|
using namespace ::Utility::DynamicMemory;
|
|
|
|
|
|
|
|
const unsigned int Octree::invalid_ref = ::Utility::Value::numeric_limits<unsigned int>::max();
|
2013-11-28 11:14:24 +01:00
|
|
|
|
|
|
|
Octree::Octree(unsigned int bufferSize, unsigned char numLayers, Math::Float3 worldSize)
|
|
|
|
{
|
|
|
|
this->worldNode.dataPtr = NULL;
|
|
|
|
|
|
|
|
this->worldNode.container.maxVertex = worldSize*0.5f;
|
|
|
|
this->worldNode.container.minVertex = -worldSize*0.5f;
|
|
|
|
}
|
|
|
|
|
|
|
|
Octree::~Octree()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-11-28 14:18:44 +01:00
|
|
|
Octree& Octree::operator=(const Octree& orig)
|
|
|
|
{
|
|
|
|
this->leafData = orig.leafData;
|
|
|
|
this->updateQueue = orig.updateQueue;
|
|
|
|
this->worldNode = orig.worldNode;
|
|
|
|
this->mapReferences = orig.mapReferences;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2013-11-28 17:59:12 +01:00
|
|
|
void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
|
2013-11-28 11:14:24 +01:00
|
|
|
{
|
2013-12-19 10:53:55 +01:00
|
|
|
customBodyRef->SetScene( this );
|
2013-11-28 11:14:24 +01:00
|
|
|
Data data;
|
|
|
|
//Data* tempPtr = this->worldNode.dataPtr;
|
|
|
|
|
|
|
|
data.container = customBodyRef->GetBoundingSphere();
|
|
|
|
data.queueRef = -1;
|
|
|
|
data.next = NULL;
|
|
|
|
data.prev = NULL;
|
|
|
|
data.customBodyRef = customBodyRef;
|
2014-02-03 15:15:47 +01:00
|
|
|
data.limbo = false;
|
2013-12-04 09:51:48 +01:00
|
|
|
this->mapReferences.insert(std::pair <ICustomBody*, unsigned int> (data.customBodyRef, this->leafData.size()));
|
2013-11-28 11:14:24 +01:00
|
|
|
this->leafData.push_back(data);
|
|
|
|
|
|
|
|
/*if(tempPtr != NULL)
|
|
|
|
{
|
|
|
|
tempPtr->prev->next = &this->leafData[this->leafData.size() - 1];
|
|
|
|
this->leafData[this->leafData.size() - 1].prev = tempPtr->prev;
|
|
|
|
tempPtr->prev = &this->leafData[this->leafData.size() - 1];
|
|
|
|
this->leafData[this->leafData.size() - 1].next = tempPtr;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->worldNode.dataPtr = &this->leafData[this->leafData.size() - 1];
|
|
|
|
this->worldNode.dataPtr->next = this->worldNode.dataPtr;
|
|
|
|
this->worldNode.dataPtr->prev = this->worldNode.dataPtr;
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
2013-11-28 17:59:12 +01:00
|
|
|
void Octree::MoveToUpdateQueue(UniquePointer< ICustomBody > customBodyRef)
|
2013-11-28 11:14:24 +01:00
|
|
|
{
|
|
|
|
/*this->leafData[this->mapReferences[customBodyRef]].queueRef = this->updateQueue.size();
|
|
|
|
this->updateQueue.push_back(&this->leafData[this->mapReferences[customBodyRef]]);*/
|
|
|
|
}
|
|
|
|
|
2014-02-03 15:15:47 +01:00
|
|
|
void Octree::MoveToLimbo(const ICustomBody* customBodyRef)
|
|
|
|
{
|
|
|
|
auto object = this->mapReferences.find(customBodyRef);
|
|
|
|
|
|
|
|
unsigned int tempRef = object->second;
|
|
|
|
|
|
|
|
this->leafData[tempRef].limbo = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Octree::IsInLimbo(const ICustomBody* customBodyRef)
|
|
|
|
{
|
|
|
|
auto object = this->mapReferences.find(customBodyRef);
|
|
|
|
|
|
|
|
unsigned int tempRef = object->second;
|
|
|
|
|
|
|
|
return this->leafData[tempRef].limbo;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Octree::ReleaseFromLimbo(const ICustomBody* customBodyRef)
|
|
|
|
{
|
|
|
|
auto object = this->mapReferences.find(customBodyRef);
|
|
|
|
|
|
|
|
unsigned int tempRef = object->second;
|
|
|
|
|
|
|
|
this->leafData[tempRef].limbo = false;
|
|
|
|
}
|
|
|
|
|
2013-11-28 17:59:12 +01:00
|
|
|
void Octree::DestroyObject(UniquePointer< ICustomBody > customBodyRef)
|
2013-11-28 11:14:24 +01:00
|
|
|
{
|
2013-11-28 17:59:12 +01:00
|
|
|
std::map<const ICustomBody*, unsigned int>::iterator it = this->mapReferences.find(customBodyRef);
|
2013-11-28 11:14:24 +01:00
|
|
|
|
|
|
|
this->mapReferences.erase(it);
|
|
|
|
|
|
|
|
this->leafData.erase(this->leafData.begin() + this->leafData[this->mapReferences[customBodyRef]].queueRef);
|
|
|
|
}
|
|
|
|
|
2013-11-29 09:03:37 +01:00
|
|
|
std::vector<ICustomBody*>& Octree::Sample(ICustomBody* customBodyRef, std::vector<ICustomBody*>& updateList)
|
2013-11-28 11:14:24 +01:00
|
|
|
{
|
2013-11-28 14:18:44 +01:00
|
|
|
auto object = this->mapReferences.find(customBodyRef);
|
|
|
|
|
|
|
|
if(object == this->mapReferences.end())
|
|
|
|
{
|
2013-11-29 09:03:37 +01:00
|
|
|
return updateList;
|
2013-11-28 14:18:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int tempRef = object->second;
|
|
|
|
|
2013-11-28 11:14:24 +01:00
|
|
|
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
|
|
|
{
|
2014-02-03 15:15:47 +01:00
|
|
|
if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
|
2013-11-28 11:14:24 +01:00
|
|
|
{
|
2013-11-29 09:03:37 +01:00
|
|
|
updateList.push_back(this->leafData[i].customBodyRef);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return updateList;
|
|
|
|
}
|
|
|
|
|
2013-11-29 09:07:52 +01:00
|
|
|
std::vector<ICustomBody*>& Octree::Sample(const Oyster::Collision3D::ICollideable& collideable, std::vector<ICustomBody*>& updateList)
|
2013-11-29 09:03:37 +01:00
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
|
|
|
{
|
2014-02-03 15:15:47 +01:00
|
|
|
if(!this->leafData[i].limbo && this->leafData[i].container.Intersects(collideable))
|
2013-11-29 09:03:37 +01:00
|
|
|
{
|
|
|
|
updateList.push_back(this->leafData[i].customBodyRef);
|
2013-11-28 11:14:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-29 09:03:37 +01:00
|
|
|
return updateList;
|
2013-11-28 11:14:24 +01:00
|
|
|
}
|
2013-11-28 14:18:44 +01:00
|
|
|
|
2014-01-21 14:10:31 +01:00
|
|
|
void Octree::Visit(ICustomBody* customBodyRef, VisitorAction hitAction )
|
2013-11-28 14:18:44 +01:00
|
|
|
{
|
|
|
|
auto object = this->mapReferences.find(customBodyRef);
|
|
|
|
|
|
|
|
if(object == this->mapReferences.end())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int tempRef = object->second;
|
|
|
|
|
|
|
|
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
|
|
|
{
|
2014-02-03 15:15:47 +01:00
|
|
|
if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
|
2013-11-28 14:18:44 +01:00
|
|
|
{
|
|
|
|
hitAction(*this, tempRef, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-28 10:18:26 +01:00
|
|
|
void Octree::Visit(const Oyster::Collision3D::ICollideable& collideable, void* args, VisitorActionCollideable hitAction)
|
2013-11-29 09:03:37 +01:00
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
|
|
|
{
|
2014-02-03 15:15:47 +01:00
|
|
|
if(!this->leafData[i].limbo && collideable.Intersects(this->leafData[i].container))
|
2013-11-29 09:03:37 +01:00
|
|
|
{
|
2014-01-28 10:18:26 +01:00
|
|
|
hitAction( this->GetCustomBody(i), args );
|
2013-11-29 09:03:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-28 14:18:44 +01:00
|
|
|
ICustomBody* Octree::GetCustomBody(const unsigned int tempRef)
|
|
|
|
{
|
|
|
|
return this->leafData[tempRef].customBodyRef;
|
2013-11-28 17:59:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
UniquePointer<ICustomBody> Octree::Extract( const ICustomBody* objRef )
|
|
|
|
{ // Dan Andersson
|
|
|
|
auto iter = this->mapReferences.find( objRef );
|
|
|
|
if( iter != this->mapReferences.end() )
|
|
|
|
{
|
|
|
|
return this->Extract( iter->second );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
UniquePointer<ICustomBody> Octree::Extract( unsigned int tempRef )
|
|
|
|
{
|
|
|
|
if( tempRef != Octree::invalid_ref )
|
|
|
|
{
|
|
|
|
//! @todo TODO: implement stub
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int Octree::GetTemporaryReferenceOf( const ICustomBody* objRef ) const
|
|
|
|
{ // Dan Andersson
|
|
|
|
auto iter = this->mapReferences.find( objRef );
|
|
|
|
if( iter != this->mapReferences.end() )
|
|
|
|
{
|
|
|
|
return iter->second;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return Octree::invalid_ref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Octree::SetAsAltered( unsigned int tempRef )
|
|
|
|
{
|
2013-12-04 11:49:33 +01:00
|
|
|
this->leafData[tempRef].container = this->leafData[tempRef].customBodyRef->GetBoundingSphere();
|
2013-11-28 17:59:12 +01:00
|
|
|
//! @todo TODO: implement stub
|
|
|
|
}
|
|
|
|
|
|
|
|
void Octree::EvaluatePosition( unsigned int tempRef )
|
|
|
|
{
|
|
|
|
//! @todo TODO: implement stub
|
2013-11-28 14:18:44 +01:00
|
|
|
}
|