removed obsolete files, make CDTestFramework compile again
This commit is contained in:
@@ -32,6 +32,8 @@ subject to the following restrictions:
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
void RenderAll();
|
||||
void Render();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
@@ -42,10 +44,12 @@ subject to the following restrictions:
|
||||
Profiler mProfiler;
|
||||
|
||||
class btBroadphaseInterface* m_broadphase;
|
||||
bool m_isdbvt;
|
||||
btAlignedObjectArray<struct btBroadphaseProxy*> m_proxies;
|
||||
|
||||
udword mNbBoxes;
|
||||
AABB* mBoxes;
|
||||
bool* mFlags;
|
||||
const char* methodname;
|
||||
const AABB** mBoxPtrs;
|
||||
Pairs mPairs;
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="./Bin/CDTestFrameworkDEBUG.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=".\AntTweakBar\lib"
|
||||
AdditionalLibraryDirectories=".\AntTweakBar\lib,../../Glut"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/CDTestFramework.pdb"
|
||||
SubSystem="1"
|
||||
@@ -142,7 +142,7 @@
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="./Bin/CDTestFramework.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=".\AntTweakBar\lib"
|
||||
AdditionalLibraryDirectories=".\AntTweakBar\lib,../../Glut"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
@@ -191,10 +191,6 @@
|
||||
RelativePath=".\BipartiteBoxPruning.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\btDbvt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BulletSAPCompleteBoxPruningTest.cpp"
|
||||
>
|
||||
@@ -239,10 +235,6 @@
|
||||
RelativePath=".\CompleteBoxPruning.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DbvtTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GLFontData.h"
|
||||
>
|
||||
@@ -325,18 +317,10 @@
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\btDbvt.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BulletSAPCompleteBoxPruningTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DbvtTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
|
||||
@@ -19,6 +19,8 @@ subject to the following restrictions:
|
||||
static const float gCamSpeed = 1.0f;
|
||||
static Point gEye(3.0616338f, 1.1985892f, 2.5769043f);
|
||||
static Point gDir(-0.66853905,-0.14004262,-0.73037237);
|
||||
//static Point gEye(140, 105, 105);
|
||||
//static Point gDir(-1,-1,-1);
|
||||
static Point gN;
|
||||
static float gFOV = 60.0f;
|
||||
|
||||
@@ -27,6 +29,11 @@ const Point& GetCameraPos()
|
||||
return gEye;
|
||||
}
|
||||
|
||||
const Point& GetCameraDir()
|
||||
{
|
||||
return gDir;
|
||||
}
|
||||
|
||||
void MoveCameraForward()
|
||||
{
|
||||
gEye += gDir * gCamSpeed;
|
||||
|
||||
@@ -18,6 +18,7 @@ subject to the following restrictions:
|
||||
#define CAMERA_H
|
||||
|
||||
const Point& GetCameraPos();
|
||||
const Point& GetCameraDir();
|
||||
void RotateCamera(int dx, int dy);
|
||||
|
||||
void MoveCameraForward();
|
||||
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
Bounding Volume Hierarchy Test
|
||||
Copyright (c) 2008 Nathanael Presson, as part of Bullet Physics Library
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DbvtTest.h"
|
||||
#include "RenderingHelpers.h"
|
||||
#include "GLFontRenderer.h"
|
||||
#include "btBulletCollisionCommon.h"
|
||||
#include "btDbvt.h"
|
||||
|
||||
namespace _0E5F0A41_1DC2_4e14_9ABC_1CBE13DF25C8_
|
||||
{
|
||||
|
||||
//
|
||||
class btDbvtProxy : public btBroadphaseProxy
|
||||
{
|
||||
public:
|
||||
AABB aabb;
|
||||
btDbvt::Node* leaf;
|
||||
bool contact;
|
||||
};
|
||||
|
||||
//
|
||||
struct btDbvtPair
|
||||
{
|
||||
btDbvtProxy* proxies[2];
|
||||
};
|
||||
|
||||
//
|
||||
class btDbvtBroadphase : public btBroadphaseInterface
|
||||
{
|
||||
public:
|
||||
btDbvtBroadphase();
|
||||
virtual ~btDbvtBroadphase() {}
|
||||
virtual btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
|
||||
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
|
||||
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
|
||||
virtual void calculateOverlappingPairs(btDispatcher* dispatcher) {}
|
||||
virtual btOverlappingPairCache* getOverlappingPairCache() { return(0); }
|
||||
virtual const btOverlappingPairCache* getOverlappingPairCache() const { return(0); }
|
||||
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const {}
|
||||
virtual void printStats() {}
|
||||
btAlignedObjectArray<btDbvtProxy*> m_proxies;
|
||||
btAlignedObjectArray<btDbvtPair> m_pairs;
|
||||
btDbvt* m_dbvt;
|
||||
};
|
||||
|
||||
//
|
||||
btDbvtBroadphase::btDbvtBroadphase()
|
||||
{
|
||||
while(m_proxies.size()) destroyProxy(m_proxies[0],0);
|
||||
}
|
||||
//
|
||||
btBroadphaseProxy* btDbvtBroadphase::createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy)
|
||||
{
|
||||
btDbvtProxy* pp=new btDbvtProxy();
|
||||
pp->aabb.SetMinMax( Point(aabbMin.x(),aabbMin.y(),aabbMin.z()),
|
||||
Point(aabbMax.x(),aabbMax.y(),aabbMax.z()));
|
||||
pp->leaf=m_dbvt->Insert((aabbMin+aabbMax)/2,(aabbMax-aabbMin)/2,pp);
|
||||
m_proxies.push_back(pp);
|
||||
return(pp);
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvtBroadphase::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
|
||||
{
|
||||
btDbvtProxy* pp=(btDbvtProxy*)proxy;
|
||||
m_proxies.remove(pp);
|
||||
m_dbvt->Remove(pp->leaf);
|
||||
delete proxy;
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvtBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)
|
||||
{
|
||||
AABB box;
|
||||
btDbvtProxy* pp=(btDbvtProxy*)proxy;
|
||||
box.SetMinMax( Point(aabbMin.x(),aabbMin.y(),aabbMin.z()),
|
||||
Point(aabbMax.x(),aabbMax.y(),aabbMax.z()));
|
||||
pp->aabb=box;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace _0E5F0A41_1DC2_4e14_9ABC_1CBE13DF25C8_;
|
||||
|
||||
DbvtTest::DbvtTest(int numBoxes)
|
||||
{
|
||||
m_bfirsttime = true;
|
||||
m_nbox = numBoxes;
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
m_margin = 0.5;
|
||||
m_bar = 0;
|
||||
m_speed = 0.005;
|
||||
m_amp = 100;
|
||||
}
|
||||
|
||||
DbvtTest::~DbvtTest()
|
||||
{
|
||||
}
|
||||
|
||||
void DbvtTest::Init()
|
||||
{
|
||||
SRand(0);
|
||||
((btDbvtBroadphase*)m_broadphase)->m_dbvt=btDbvt::Create();
|
||||
m_times.resize(m_nbox);
|
||||
for(int i=0;i<m_nbox;i++)
|
||||
{
|
||||
Point Center, Extents;
|
||||
Center.x = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Center.y = (UnitRandomFloat()-0.5f) * 10.0f;
|
||||
Center.z = (UnitRandomFloat()-0.5f) * 100.0f;
|
||||
Extents.x = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.y = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
Extents.z = 2.0f + UnitRandomFloat() * 2.0f;
|
||||
btVector3 aabbMin(Center.x-Extents.x,Center.y-Extents.y,Center.z-Extents.z);
|
||||
btVector3 aabbMax(Center.x+Extents.x,Center.y+Extents.y,Center.z+Extents.z);
|
||||
m_broadphase->createProxy(aabbMin,aabbMax,0,0,1,1,0,0);
|
||||
m_times[i]=2000.0f*UnitRandomFloat();
|
||||
}
|
||||
}
|
||||
|
||||
void DbvtTest::Release()
|
||||
{
|
||||
}
|
||||
|
||||
void DbvtTest::Select()
|
||||
{
|
||||
m_bar=TwNewBar("Dbvt");
|
||||
TwAddVarRW(m_bar,"Margin",TW_TYPE_FLOAT,&m_margin," min=0.0 max=10.0 step=0.5");
|
||||
TwAddVarRW(m_bar,"Speed", TW_TYPE_FLOAT, &m_speed, " min=0.0 max=0.01 step=0.00001");
|
||||
TwAddVarRW(m_bar,"Amplitude", TW_TYPE_FLOAT, &m_amp, " min=10.0 max=200.0 step=0.1");
|
||||
}
|
||||
|
||||
void DbvtTest::Deselect()
|
||||
{
|
||||
if(m_bar)
|
||||
{
|
||||
TwDeleteBar(m_bar);
|
||||
m_bar=0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool Intersect( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b)
|
||||
{
|
||||
return( (a.mi.x()<=b.mx.x())&&
|
||||
(a.mx.x()>=b.mi.x())&&
|
||||
(a.mi.y()<=b.mx.y())&&
|
||||
(a.mx.y()>=b.mi.y())&&
|
||||
(a.mi.z()<=b.mx.z())&&
|
||||
(a.mx.z()>=b.mi.z()));
|
||||
}
|
||||
|
||||
static void TreeTreeParse( const btDbvt::Node* a,
|
||||
const btDbvt::Node* b,
|
||||
btAlignedObjectArray<btDbvtPair>& pairs)
|
||||
{
|
||||
if(a==b)
|
||||
{
|
||||
if(a->isinternal())
|
||||
{
|
||||
TreeTreeParse(a->childs[0],a->childs[0],pairs);
|
||||
TreeTreeParse(a->childs[1],a->childs[1],pairs);
|
||||
TreeTreeParse(a->childs[0],a->childs[1],pairs);
|
||||
}
|
||||
}
|
||||
else if(Intersect(a->box,b->box))
|
||||
{
|
||||
if(a->isinternal())
|
||||
{
|
||||
if(b->isinternal())
|
||||
{
|
||||
TreeTreeParse(a->childs[0],b->childs[0],pairs);
|
||||
TreeTreeParse(a->childs[1],b->childs[0],pairs);
|
||||
TreeTreeParse(a->childs[0],b->childs[1],pairs);
|
||||
TreeTreeParse(a->childs[1],b->childs[1],pairs);
|
||||
}
|
||||
else
|
||||
{
|
||||
TreeTreeParse(a->childs[0],b,pairs);
|
||||
TreeTreeParse(a->childs[1],b,pairs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(b->isinternal())
|
||||
{
|
||||
TreeTreeParse(a,b->childs[0],pairs);
|
||||
TreeTreeParse(a,b->childs[1],pairs);
|
||||
}
|
||||
else
|
||||
{
|
||||
btDbvtPair p;
|
||||
p.proxies[0]=(btDbvtProxy*)a->data;
|
||||
p.proxies[1]=(btDbvtProxy*)b->data;
|
||||
if(p.proxies[0]->aabb.Intersect(p.proxies[1]->aabb))
|
||||
{
|
||||
pairs.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DbvtTest::PerformTest()
|
||||
{
|
||||
btDbvtBroadphase* pb=(btDbvtBroadphase*)m_broadphase;
|
||||
const btScalar speed=m_speed;
|
||||
const btScalar ampl=m_amp;
|
||||
const int nupd=m_bfirsttime? pb->m_proxies.size():
|
||||
(pb->m_proxies.size()*10)/100;
|
||||
/* Move boxes */
|
||||
m_profiler.Start();
|
||||
for(int i=0;i<nupd;i++)
|
||||
{
|
||||
const btScalar time=(m_times[i]+=speed);
|
||||
Point center( cosf(time*2.17)*ampl+sinf(time)*ampl*0.5,
|
||||
cosf(time*1.38)*ampl+sinf(time*ampl),
|
||||
sinf(time*0.777)*ampl);
|
||||
Point extent;
|
||||
pb->m_proxies[i]->aabb.GetExtents(extent);
|
||||
pb->m_proxies[i]->aabb.SetCenterExtents(center,extent);
|
||||
pb->m_dbvt->Update( pb->m_proxies[i]->leaf,
|
||||
btVector3(center.x,center.y,center.z),
|
||||
btVector3(extent.x,extent.y,extent.z),
|
||||
m_margin);
|
||||
}
|
||||
if(m_bfirsttime)
|
||||
{
|
||||
pb->m_dbvt->OptimizeTopDown();
|
||||
}
|
||||
/* Overlap */
|
||||
pb->m_pairs.resize(0);
|
||||
TreeTreeParse( pb->m_dbvt->m_root,
|
||||
pb->m_dbvt->m_root,
|
||||
pb->m_pairs);
|
||||
m_profiler.End();
|
||||
m_profiler.Accum();
|
||||
#if 0
|
||||
int check=0;
|
||||
for(int i=0,ni=pb->m_proxies.size();i<ni;++i)
|
||||
{
|
||||
AABB boxa=pb->m_proxies[i]->aabb;
|
||||
for(int j=i+1;j<ni;++j)
|
||||
{
|
||||
if(boxa.Intersect(pb->m_proxies[j]->aabb))
|
||||
{
|
||||
++check;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(check!=pb->m_pairs.size())
|
||||
{
|
||||
printf("Check failed %u => %u\r\n",check,pb->m_pairs.size());
|
||||
}
|
||||
#endif
|
||||
/* Render boxes */
|
||||
OBB CurrentBox;
|
||||
CurrentBox.mRot.Identity();
|
||||
for(int i=0,ni=pb->m_proxies.size();i<ni;i++)
|
||||
{
|
||||
pb->m_proxies[i]->contact=false;
|
||||
}
|
||||
for(int i=0,ni=pb->m_pairs.size();i<ni;i++)
|
||||
{
|
||||
pb->m_pairs[i].proxies[0]->contact=true;
|
||||
pb->m_pairs[i].proxies[1]->contact=true;
|
||||
}
|
||||
for(int i=0,ni=pb->m_proxies.size();i<ni;i++)
|
||||
{
|
||||
if(pb->m_proxies[i]->contact) glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else glColor3f(0.0f, 1.0f, 0.0f);
|
||||
pb->m_proxies[i]->aabb.GetCenter(CurrentBox.mCenter);
|
||||
pb->m_proxies[i]->aabb.GetExtents(CurrentBox.mExtents);
|
||||
DrawOBB(CurrentBox);
|
||||
}
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer,"Dbvt: %5.1f us (%d cycles) : %d pairs\n",m_profiler.mMsTime,m_profiler.mCycles,pb->m_pairs.size());
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
m_bfirsttime=false;
|
||||
}
|
||||
|
||||
void DbvtTest::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void DbvtTest::MouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void DbvtTest::MotionCallback(int x, int y)
|
||||
{
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
Bounding Volume Hierarchy Test
|
||||
Copyright (c) 2008 Nathanael Presson, as part of Bullet Physics Library
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef DBVTTEST_H
|
||||
#define DBVTTEST_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "CollisionTest.h"
|
||||
#include "Profiling.h"
|
||||
|
||||
class DbvtTest : public CollisionTest
|
||||
{
|
||||
public:
|
||||
DbvtTest(int numBoxes);
|
||||
virtual ~DbvtTest();
|
||||
|
||||
virtual void Init();
|
||||
virtual void Release();
|
||||
virtual void PerformTest();
|
||||
virtual void Select();
|
||||
virtual void Deselect();
|
||||
virtual void KeyboardCallback(unsigned char key, int x, int y);
|
||||
virtual void MouseCallback(int button, int state, int x, int y);
|
||||
virtual void MotionCallback(int x, int y);
|
||||
|
||||
TwBar* m_bar;
|
||||
btScalar m_margin;
|
||||
btScalar m_speed;
|
||||
btScalar m_amp;
|
||||
Profiler m_profiler;
|
||||
int m_nbox;
|
||||
class btBroadphaseInterface* m_broadphase;
|
||||
btAlignedObjectArray<btScalar> m_times;
|
||||
bool m_bfirsttime;
|
||||
};
|
||||
|
||||
#endif
|
||||
BIN
Extras/CDTestFramework/GLUT32.DLL
Normal file
BIN
Extras/CDTestFramework/GLUT32.DLL
Normal file
Binary file not shown.
@@ -1,424 +0,0 @@
|
||||
/*
|
||||
Bounding Volume Hierarchy, btDbvt.cpp
|
||||
Copyright (c) 2008 Nathanael Presson, as part of Bullet Physics Library
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "btDbvt.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace btdbvt_internals
|
||||
{
|
||||
|
||||
//
|
||||
typedef btAlignedObjectArray<btDbvt::Node*> tNodeArray;
|
||||
|
||||
//
|
||||
static inline int indexof(const btDbvt::Node* node)
|
||||
{
|
||||
return(node->parent->childs[1]==node);
|
||||
}
|
||||
|
||||
//
|
||||
static inline btDbvt::Aabb merge( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b)
|
||||
{
|
||||
btDbvt::Aabb res=a;
|
||||
res.mi.setMin(b.mi);
|
||||
res.mx.setMax(b.mx);
|
||||
return(res);
|
||||
}
|
||||
|
||||
// volume+edge lengths
|
||||
static inline btScalar size(const btDbvt::Aabb& a)
|
||||
{
|
||||
const btVector3 edges=a.mx-a.mi;
|
||||
return( edges.x()*edges.y()*edges.z()+
|
||||
edges.x()+edges.y()+edges.z());
|
||||
}
|
||||
|
||||
// Using manhattan distance heuristic
|
||||
static inline btScalar proximity( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b)
|
||||
{
|
||||
const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
|
||||
return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
|
||||
}
|
||||
|
||||
//
|
||||
static inline bool contain( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b)
|
||||
{
|
||||
return( (a.mi.x()<=b.mi.x())&&
|
||||
(a.mx.x()>=b.mx.x())&&
|
||||
(a.mi.y()<=b.mi.y())&&
|
||||
(a.mx.y()>=b.mx.y())&&
|
||||
(a.mi.z()<=b.mi.z())&&
|
||||
(a.mx.z()>=b.mx.z()));
|
||||
}
|
||||
|
||||
//
|
||||
static inline void deletenode( btDbvt* pdbvt,
|
||||
btDbvt::Node* node)
|
||||
{
|
||||
if(pdbvt->m_stock) delete pdbvt->m_stock;
|
||||
pdbvt->m_stock=node;
|
||||
}
|
||||
|
||||
//
|
||||
static inline void recursedeletenode( btDbvt* pdbvt,
|
||||
btDbvt::Node* node)
|
||||
{
|
||||
if(!node->isleaf())
|
||||
{
|
||||
recursedeletenode(pdbvt,node->childs[0]);
|
||||
recursedeletenode(pdbvt,node->childs[1]);
|
||||
}
|
||||
if(node==pdbvt->m_root) pdbvt->m_root=0;
|
||||
deletenode(pdbvt,node);
|
||||
}
|
||||
|
||||
//
|
||||
static inline btDbvt::Node* createnode( btDbvt* pdbvt,
|
||||
btDbvt::Node* parent,
|
||||
const btDbvt::Aabb& box,
|
||||
void* data)
|
||||
{
|
||||
btDbvt::Node* node;
|
||||
if(pdbvt->m_stock)
|
||||
{ node=pdbvt->m_stock;pdbvt->m_stock=0; }
|
||||
else
|
||||
{ node=new btDbvt::Node(); }
|
||||
node->parent = parent;
|
||||
node->box = box;
|
||||
node->data = data;
|
||||
node->childs[1] = 0;
|
||||
return(node);
|
||||
}
|
||||
|
||||
//
|
||||
static inline void insertleaf( btDbvt* pdbvt,
|
||||
btDbvt::Node* root,
|
||||
btDbvt::Node* leaf)
|
||||
{
|
||||
if(!pdbvt->m_root)
|
||||
{
|
||||
pdbvt->m_root = leaf;
|
||||
leaf->parent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!root->isleaf())
|
||||
{
|
||||
do {
|
||||
if( proximity(root->childs[0]->box,leaf->box)<
|
||||
proximity(root->childs[1]->box,leaf->box))
|
||||
root=root->childs[0];
|
||||
else
|
||||
root=root->childs[1];
|
||||
} while(!root->isleaf());
|
||||
}
|
||||
btDbvt::Node* prev=root->parent;
|
||||
btDbvt::Node* node=createnode(pdbvt,prev,merge(leaf->box,root->box),0);
|
||||
if(prev)
|
||||
{
|
||||
prev->childs[indexof(root)] = node;
|
||||
node->childs[0] = root;root->parent=node;
|
||||
node->childs[1] = leaf;leaf->parent=node;
|
||||
do {
|
||||
if(contain(prev->box,node->box))
|
||||
break;
|
||||
else
|
||||
prev->box=merge(prev->childs[0]->box,prev->childs[1]->box);
|
||||
node=prev;
|
||||
} while(0!=(prev=node->parent));
|
||||
}
|
||||
else
|
||||
{
|
||||
node->childs[0] = root;root->parent=node;
|
||||
node->childs[1] = leaf;leaf->parent=node;
|
||||
pdbvt->m_root = node;
|
||||
}
|
||||
}
|
||||
++pdbvt->m_nleafs;
|
||||
}
|
||||
|
||||
//
|
||||
static inline btDbvt::Node* removeleaf( btDbvt* pdbvt,
|
||||
btDbvt::Node* leaf)
|
||||
{
|
||||
--pdbvt->m_nleafs;
|
||||
if(leaf==pdbvt->m_root)
|
||||
{
|
||||
pdbvt->m_root=0;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
btDbvt::Node* parent=leaf->parent;
|
||||
btDbvt::Node* prev=parent->parent;
|
||||
btDbvt::Node* sibling=parent->childs[1-indexof(leaf)];
|
||||
if(prev)
|
||||
{
|
||||
prev->childs[indexof(parent)]=sibling;
|
||||
sibling->parent=prev;
|
||||
deletenode(pdbvt,parent);
|
||||
while(prev)
|
||||
{
|
||||
const btDbvt::Aabb pb=prev->box;
|
||||
prev->box = merge(prev->childs[0]->box,prev->childs[1]->box);
|
||||
if(0==memcmp(&pb,&prev->box,sizeof(pb))) break;
|
||||
sibling = prev;
|
||||
prev = prev->parent;
|
||||
}
|
||||
return(prev?prev:pdbvt->m_root);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdbvt->m_root=sibling;
|
||||
sibling->parent=0;
|
||||
deletenode(pdbvt,parent);
|
||||
return(pdbvt->m_root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void fetchleafs( btDbvt::Node* root,
|
||||
tNodeArray& leafs)
|
||||
{
|
||||
if(root->isinternal())
|
||||
{
|
||||
fetchleafs(root->childs[0],leafs);
|
||||
fetchleafs(root->childs[1],leafs);
|
||||
}
|
||||
else
|
||||
{
|
||||
leafs.push_back(root);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void split( const tNodeArray& leafs,
|
||||
tNodeArray& left,
|
||||
tNodeArray& right,
|
||||
const btVector3& org,
|
||||
const btVector3& axis)
|
||||
{
|
||||
left.resize(0);
|
||||
right.resize(0);
|
||||
for(int i=0,ni=leafs.size();i<ni;++i)
|
||||
{
|
||||
if(dot(axis,leafs[i]->box.Center()-org)<0)
|
||||
left.push_back(leafs[i]);
|
||||
else
|
||||
right.push_back(leafs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static btDbvt::Aabb bounds( const tNodeArray& leafs)
|
||||
{
|
||||
btDbvt::Aabb box=leafs[0]->box;
|
||||
for(int i=1,ni=leafs.size();i<ni;++i)
|
||||
{
|
||||
box=merge(box,leafs[i]->box);
|
||||
}
|
||||
return(box);
|
||||
}
|
||||
|
||||
//
|
||||
static void bottomup( btDbvt* pdbvt,
|
||||
tNodeArray& leafs)
|
||||
{
|
||||
while(leafs.size()>1)
|
||||
{
|
||||
btScalar minsize=SIMD_INFINITY;
|
||||
int minidx[2]={-1,-1};
|
||||
for(int i=0;i<leafs.size();++i)
|
||||
{
|
||||
for(int j=i+1;j<leafs.size();++j)
|
||||
{
|
||||
const btScalar sz=size(merge(leafs[i]->box,leafs[j]->box));
|
||||
if(sz<minsize)
|
||||
{
|
||||
minsize = sz;
|
||||
minidx[0] = i;
|
||||
minidx[1] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
btDbvt::Node* n[] = {leafs[minidx[0]],leafs[minidx[1]]};
|
||||
btDbvt::Node* p = createnode(pdbvt,0,merge(n[0]->box,n[1]->box),0);
|
||||
p->childs[0] = n[0];
|
||||
p->childs[1] = n[1];
|
||||
n[0]->parent = p;
|
||||
n[1]->parent = p;
|
||||
leafs[minidx[0]] = p;
|
||||
leafs.swap(minidx[1],leafs.size()-1);
|
||||
leafs.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static btDbvt::Node* topdown(btDbvt* pdbvt,
|
||||
tNodeArray& leafs)
|
||||
{
|
||||
static const btVector3 axis[]={btVector3(1,0,0),
|
||||
btVector3(0,1,0),
|
||||
btVector3(0,0,1)};
|
||||
if(leafs.size()>1)
|
||||
{
|
||||
const btDbvt::Aabb box=bounds(leafs);
|
||||
const btVector3 org=box.Center();
|
||||
tNodeArray sets[2];
|
||||
int bestaxis=-1;
|
||||
int bestmidp=leafs.size();
|
||||
sets[0].reserve(leafs.size());
|
||||
sets[1].reserve(leafs.size());
|
||||
for(int i=0;i<3;++i)
|
||||
{
|
||||
split(leafs,sets[0],sets[1],org,axis[i]);
|
||||
if((sets[0].size()>0)&&(sets[1].size()>0))
|
||||
{
|
||||
const int midp=abs(sets[0].size()-sets[1].size());
|
||||
if(midp<bestmidp)
|
||||
{
|
||||
bestaxis=i;
|
||||
bestmidp=midp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bestaxis>=0)
|
||||
{
|
||||
split(leafs,sets[0],sets[1],org,axis[bestaxis]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sets[0].resize(0);
|
||||
sets[1].resize(0);
|
||||
for(int i=0,ni=leafs.size();i<ni;++i)
|
||||
{
|
||||
sets[i&1].push_back(leafs[i]);
|
||||
}
|
||||
}
|
||||
btDbvt::Node* node=createnode(pdbvt,0,box,0);
|
||||
node->childs[0]=topdown(pdbvt,sets[0]);
|
||||
node->childs[1]=topdown(pdbvt,sets[1]);
|
||||
node->childs[0]->parent=node;
|
||||
node->childs[1]->parent=node;
|
||||
return(node);
|
||||
}
|
||||
return(leafs[0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
using namespace btdbvt_internals;
|
||||
|
||||
//
|
||||
// Api
|
||||
//
|
||||
|
||||
//
|
||||
btDbvt* btDbvt::Create()
|
||||
{
|
||||
btDbvt* pdbvt = new btDbvt();
|
||||
pdbvt->m_nleafs = 0;
|
||||
pdbvt->m_root = 0;
|
||||
pdbvt->m_stock = 0;
|
||||
return(pdbvt);
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::Delete()
|
||||
{
|
||||
if(m_root) recursedeletenode(this,m_root);
|
||||
if(m_stock) delete m_stock;
|
||||
delete this;
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::OptimizeBottomUp()
|
||||
{
|
||||
if(m_root)
|
||||
{
|
||||
tNodeArray leafs;
|
||||
leafs.reserve(m_nleafs);
|
||||
fetchleafs(m_root,leafs);
|
||||
for(int i=0,ni=leafs.size();i<ni;++i)
|
||||
{
|
||||
removeleaf(this,leafs[i]);
|
||||
}
|
||||
m_nleafs = leafs.size();
|
||||
bottomup(this,leafs);
|
||||
m_root = leafs[0];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::OptimizeTopDown()
|
||||
{
|
||||
if(m_root)
|
||||
{
|
||||
tNodeArray leafs;
|
||||
leafs.reserve(m_nleafs);
|
||||
fetchleafs(m_root,leafs);
|
||||
for(int i=0,ni=leafs.size();i<ni;++i)
|
||||
{
|
||||
removeleaf(this,leafs[i]);
|
||||
}
|
||||
m_nleafs = leafs.size();
|
||||
m_root = topdown(this,leafs);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
btDbvt::Node* btDbvt::Insert( const btVector3& center,
|
||||
const btVector3& extent,
|
||||
void* data)
|
||||
{
|
||||
Node* leaf=createnode(this,0,Aabb::FromCE(center,extent),data);
|
||||
insertleaf(this,m_root,leaf);
|
||||
return(leaf);
|
||||
}
|
||||
|
||||
//
|
||||
bool btDbvt::Update( Node* leaf,
|
||||
const btVector3& center,
|
||||
const btVector3& extent,
|
||||
btScalar margin)
|
||||
{
|
||||
Aabb box=Aabb::FromCE(center,extent);
|
||||
if(margin>0)
|
||||
{
|
||||
if(contain(leaf->box,box)) return(false);
|
||||
const btVector3 vm(margin,margin,margin);
|
||||
box.mi-=vm;box.mx+=vm;
|
||||
}
|
||||
Node* root=removeleaf(this,leaf);
|
||||
leaf->box=box;
|
||||
insertleaf(this,root,leaf);
|
||||
return(true);
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::Remove( Node* leaf)
|
||||
{
|
||||
removeleaf(this,leaf);
|
||||
deletenode(this,leaf);
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
Bounding Volume Hierarchy, btDbvt.h
|
||||
Copyright (c) 2008 Nathanael Presson, as part of Bullet Physics Library
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _6095FD2A_2B3C_4c47_AB85_D56C1DD1A210_
|
||||
#define _6095FD2A_2B3C_4c47_AB85_D56C1DD1A210_
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btPoint3.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
|
||||
//
|
||||
// Dynamic bounding volume tree
|
||||
//
|
||||
struct btDbvt
|
||||
{
|
||||
// Types
|
||||
|
||||
/* AabbCe */
|
||||
struct Aabb
|
||||
{
|
||||
btVector3 mi,mx;
|
||||
inline btVector3 Center() const { return((mi+mx)/2); }
|
||||
inline btVector3 Extent() const { return((mx-mi)/2); }
|
||||
static inline Aabb FromCE(const btVector3& c,const btVector3& e)
|
||||
{
|
||||
Aabb box;
|
||||
box.mi=c-e;box.mx=c+e;
|
||||
return(box);
|
||||
}
|
||||
inline friend bool operator==(const Aabb& a,const Aabb& b)
|
||||
{
|
||||
return( ((a.mi-b.mi).length2()==0)&&
|
||||
((a.mx-b.mx).length2()==0));
|
||||
}
|
||||
};
|
||||
/* Node */
|
||||
struct Node
|
||||
{
|
||||
Aabb box;
|
||||
Node* parent;
|
||||
bool isleaf() const { return(childs[1]==0); }
|
||||
bool isinternal() const { return(!isleaf()); }
|
||||
union {
|
||||
Node* childs[2];
|
||||
void* data;
|
||||
};
|
||||
};
|
||||
// Fields
|
||||
Node* m_root;
|
||||
Node* m_stock;
|
||||
int m_nleafs;
|
||||
// Methods
|
||||
static btDbvt* Create();
|
||||
void Delete();
|
||||
void OptimizeBottomUp();
|
||||
void OptimizeTopDown();
|
||||
Node* Insert( const btVector3& center,
|
||||
const btVector3& extent,
|
||||
void* data);
|
||||
bool Update( Node* leaf,
|
||||
const btVector3& center,
|
||||
const btVector3& extent,
|
||||
btScalar margin=0);
|
||||
void Remove( Node* leaf);
|
||||
// Inline's
|
||||
inline Node* Insert( const btVector3& center,
|
||||
btScalar radius,
|
||||
void* data)
|
||||
{
|
||||
return(Insert(center,btVector3(radius,radius,radius),data));
|
||||
}
|
||||
bool Update( Node* leaf,
|
||||
const btVector3& center,
|
||||
btScalar radius,
|
||||
btScalar margin=0)
|
||||
{
|
||||
return(Update(leaf,center,btVector3(radius,radius,radius),margin));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user