Softbody improvements, thanks to Nathanael
This commit is contained in:
@@ -22,10 +22,319 @@ subject to the following restrictions:
|
||||
#include "RenderingHelpers.h"
|
||||
#include "GLFontRenderer.h"
|
||||
#include "btBulletCollisionCommon.h"
|
||||
#include "BulletSoftBody/btDbvtBroadphase.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h"
|
||||
#include "Camera.h"
|
||||
|
||||
int numParts =2;
|
||||
|
||||
bool enableCulling = true;
|
||||
bool cullFarPlane = false;
|
||||
bool showCulling = false;
|
||||
bool enableOcclusion = false;
|
||||
bool showOcclusion = true;
|
||||
int visiblecount = 0;
|
||||
|
||||
struct OcclusionBuffer
|
||||
{
|
||||
struct WriteOCL
|
||||
{
|
||||
static inline bool Process(btScalar& q,btScalar v) { if(q<v) q=v;return(false); }
|
||||
};
|
||||
struct QueryOCL
|
||||
{
|
||||
static inline bool Process(btScalar& q,btScalar v) { return(q<=v); }
|
||||
};
|
||||
bool initialized;
|
||||
btAlignedObjectArray<btScalar> buffer;
|
||||
int sizes[2];
|
||||
btScalar scales[2];
|
||||
btScalar offsets[2];
|
||||
btScalar wtrs[16];
|
||||
btVector3 eye;
|
||||
btVector3 neardist;
|
||||
btScalar ocarea;
|
||||
btScalar qrarea;
|
||||
GLuint texture;
|
||||
OcclusionBuffer()
|
||||
{
|
||||
initialized=false;
|
||||
neardist=btVector3(2,2,2);
|
||||
ocarea=(btScalar)0;
|
||||
qrarea=(btScalar)0;
|
||||
}
|
||||
void setup(int w,int h)
|
||||
{
|
||||
initialized=true;
|
||||
sizes[0]=w;
|
||||
sizes[1]=h;
|
||||
scales[0]=w/2;
|
||||
scales[1]=h/2;
|
||||
offsets[0]=scales[0]+0.5;
|
||||
offsets[1]=scales[1]+0.5;
|
||||
glGenTextures(1,&texture);
|
||||
clear();
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
buffer.resize(0);
|
||||
buffer.resize(sizes[0]*sizes[1],0);
|
||||
}
|
||||
void initialize()
|
||||
{
|
||||
if(!initialized)
|
||||
{
|
||||
setup(128,128);
|
||||
}
|
||||
GLint v[4];
|
||||
GLdouble m[16],p[16];
|
||||
glGetIntegerv(GL_VIEWPORT,v);
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX,m);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX,p);
|
||||
for(int i=0;i<16;++i) wtrs[i]=p[i];
|
||||
clear();
|
||||
}
|
||||
void drawBuffer( btScalar l,btScalar t,
|
||||
btScalar r,btScalar b)
|
||||
{
|
||||
btAlignedObjectArray<GLubyte> data;
|
||||
data.resize(buffer.size());
|
||||
for(int i=0;i<data.size();++i)
|
||||
{
|
||||
data[i]=int(32/buffer[i])%255;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,sizes[0],sizes[1],0,GL_LUMINANCE,GL_UNSIGNED_BYTE,&data[0]);
|
||||
glBegin(GL_QUADS);
|
||||
glColor4ub(255,255,255,255);
|
||||
glTexCoord2f(0,0);glVertex2f(l,t);
|
||||
glTexCoord2f(1,0);glVertex2f(r,t);
|
||||
glTexCoord2f(1,1);glVertex2f(r,b);
|
||||
glTexCoord2f(0,1);glVertex2f(l,b);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
btVector4 transform(const btVector3& x) const
|
||||
{
|
||||
btVector4 t;
|
||||
t[0] = x[0]*wtrs[0]+x[1]*wtrs[4]+x[2]*wtrs[8]+wtrs[12];
|
||||
t[1] = x[0]*wtrs[1]+x[1]*wtrs[5]+x[2]*wtrs[9]+wtrs[13];
|
||||
t[2] = x[0]*wtrs[2]+x[1]*wtrs[6]+x[2]*wtrs[10]+wtrs[14];
|
||||
t[3] = x[0]*wtrs[3]+x[1]*wtrs[7]+x[2]*wtrs[11]+wtrs[15];
|
||||
return(t);
|
||||
}
|
||||
static bool project(btVector4* p,int n)
|
||||
{
|
||||
for(int i=0;i<n;++i)
|
||||
{
|
||||
const btScalar iw=1/p[i][3];
|
||||
p[i][2]=1/p[i][3];
|
||||
p[i][0]*=p[i][2];
|
||||
p[i][1]*=p[i][2];
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
template <const int NP>
|
||||
static int clip(const btVector4* pi,btVector4* po)
|
||||
{
|
||||
btScalar s[NP];
|
||||
int m=0;
|
||||
for(int i=0;i<NP;++i)
|
||||
{
|
||||
s[i]=pi[i][2]+pi[i][3];
|
||||
if(s[i]<0) m+=1<<i;
|
||||
}
|
||||
if(m==((1<<NP)-1)) return(0);
|
||||
if(m!=0)
|
||||
{
|
||||
int n=0;
|
||||
for(int i=NP-1,j=0;j<NP;i=j++)
|
||||
{
|
||||
const btVector4& a=pi[i];
|
||||
const btVector4& b=pi[j];
|
||||
const btScalar t=s[i]/(a[3]+a[2]-b[3]-b[2]);
|
||||
if((t>0)&&(t<1))
|
||||
{
|
||||
po[n][0] = a[0]+(b[0]-a[0])*t;
|
||||
po[n][1] = a[1]+(b[1]-a[1])*t;
|
||||
po[n][2] = a[2]+(b[2]-a[2])*t;
|
||||
po[n][3] = a[3]+(b[3]-a[3])*t;
|
||||
++n;
|
||||
}
|
||||
if(s[j]>0) po[n++]=b;
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
for(int i=0;i<NP;++i) po[i]=pi[i];
|
||||
return(NP);
|
||||
}
|
||||
template <typename POLICY>
|
||||
inline bool draw( const btVector4& a,
|
||||
const btVector4& b,
|
||||
const btVector4& c,
|
||||
const btScalar minarea)
|
||||
{
|
||||
const btScalar a2=cross(b-a,c-a)[2];
|
||||
if(a2>0)
|
||||
{
|
||||
if(a2<minarea) return(true);
|
||||
const int x[]={ (int)(a.x()*scales[0]+offsets[0]),
|
||||
(int)(b.x()*scales[0]+offsets[0]),
|
||||
(int)(c.x()*scales[0]+offsets[0])};
|
||||
const int y[]={ (int)(a.y()*scales[1]+offsets[1]),
|
||||
(int)(b.y()*scales[1]+offsets[1]),
|
||||
(int)(c.y()*scales[1]+offsets[1])};
|
||||
const btScalar z[]={ a.z(),b.z(),c.z()};
|
||||
const int mix=btMax(0,btMin(x[0],btMin(x[1],x[2])));
|
||||
const int mxx=btMin(sizes[0],1+btMax(x[0],btMax(x[1],x[2])));
|
||||
const int miy=btMax(0,btMin(y[0],btMin(y[1],y[2])));
|
||||
const int mxy=btMin(sizes[1],1+btMax(y[0],btMax(y[1],y[2])));
|
||||
const int width=mxx-mix;
|
||||
const int height=mxy-miy;
|
||||
if((width*height)>0)
|
||||
{
|
||||
const int dx[]={ y[0]-y[1],
|
||||
y[1]-y[2],
|
||||
y[2]-y[0]};
|
||||
const int dy[]={ x[1]-x[0]-dx[0]*width,
|
||||
x[2]-x[1]-dx[1]*width,
|
||||
x[0]-x[2]-dx[2]*width};
|
||||
const int a=x[2]*y[0]+x[0]*y[1]-x[2]*y[1]-x[0]*y[2]+x[1]*y[2]-x[1]*y[0];
|
||||
const btScalar ia=1/(btScalar)a;
|
||||
const btScalar dzx=ia*(y[2]*(z[1]-z[0])+y[1]*(z[0]-z[2])+y[0]*(z[2]-z[1]));
|
||||
const btScalar dzy=ia*(x[2]*(z[0]-z[1])+x[0]*(z[1]-z[2])+x[1]*(z[2]-z[0]))-(dzx*width);
|
||||
int c[]={ miy*x[1]+mix*y[0]-x[1]*y[0]-mix*y[1]+x[0]*y[1]-miy*x[0],
|
||||
miy*x[2]+mix*y[1]-x[2]*y[1]-mix*y[2]+x[1]*y[2]-miy*x[1],
|
||||
miy*x[0]+mix*y[2]-x[0]*y[2]-mix*y[0]+x[2]*y[0]-miy*x[2]};
|
||||
btScalar v=ia*((z[2]*c[0])+(z[0]*c[1])+(z[1]*c[2]));
|
||||
btScalar* scan=&buffer[miy*sizes[1]];
|
||||
for(int iy=miy;iy<mxy;++iy)
|
||||
{
|
||||
for(int ix=mix;ix<mxx;++ix)
|
||||
{
|
||||
if((c[0]>=0)&&(c[1]>=0)&&(c[2]>=0))
|
||||
{
|
||||
if(POLICY::Process(scan[ix],v)) return(true);
|
||||
}
|
||||
c[0]+=dx[0];c[1]+=dx[1];c[2]+=dx[2];v+=dzx;
|
||||
}
|
||||
c[0]+=dy[0];c[1]+=dy[1];c[2]+=dy[2];v+=dzy;
|
||||
scan+=sizes[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
template <const int NP,typename POLICY>
|
||||
inline bool clipDraw( const btVector4* p,
|
||||
btScalar minarea)
|
||||
{
|
||||
btVector4 o[NP*2];
|
||||
const int n=clip<NP>(p,o);
|
||||
bool earlyexit=false;
|
||||
project(o,n);
|
||||
for(int i=2;i<n;++i)
|
||||
{
|
||||
earlyexit|=draw<POLICY>(o[0],o[i-1],o[i],minarea);
|
||||
}
|
||||
return(earlyexit);
|
||||
}
|
||||
void appendOccluder( const btVector3& a,
|
||||
const btVector3& b,
|
||||
const btVector3& c)
|
||||
{
|
||||
const btVector4 p[]={transform(a),transform(b),transform(c)};
|
||||
clipDraw<3,WriteOCL>(p,ocarea);
|
||||
}
|
||||
void appendOccluder( const btVector3& a,
|
||||
const btVector3& b,
|
||||
const btVector3& c,
|
||||
const btVector3& d)
|
||||
{
|
||||
const btVector4 p[]={transform(a),transform(b),transform(c),transform(d)};
|
||||
clipDraw<4,WriteOCL>(p,ocarea);
|
||||
}
|
||||
void appendOccluder( const btVector3& c,
|
||||
const btVector3& e)
|
||||
{
|
||||
const btVector4 x[]={ transform(btVector3(c[0]-e[0],c[1]-e[1],c[2]-e[2])),
|
||||
transform(btVector3(c[0]+e[0],c[1]-e[1],c[2]-e[2])),
|
||||
transform(btVector3(c[0]+e[0],c[1]+e[1],c[2]-e[2])),
|
||||
transform(btVector3(c[0]-e[0],c[1]+e[1],c[2]-e[2])),
|
||||
transform(btVector3(c[0]-e[0],c[1]-e[1],c[2]+e[2])),
|
||||
transform(btVector3(c[0]+e[0],c[1]-e[1],c[2]+e[2])),
|
||||
transform(btVector3(c[0]+e[0],c[1]+e[1],c[2]+e[2])),
|
||||
transform(btVector3(c[0]-e[0],c[1]+e[1],c[2]+e[2]))};
|
||||
static const int d[]={ 1,0,3,2,
|
||||
4,5,6,7,
|
||||
4,7,3,0,
|
||||
6,5,1,2,
|
||||
7,6,2,3,
|
||||
5,4,0,1};
|
||||
for(int i=0;i<(sizeof(d)/sizeof(d[0]));)
|
||||
{
|
||||
const btVector4 p[]={ x[d[i++]],
|
||||
x[d[i++]],
|
||||
x[d[i++]],
|
||||
x[d[i++]]};
|
||||
clipDraw<4,WriteOCL>(p,ocarea);
|
||||
}
|
||||
}
|
||||
inline bool queryOccluder( const btVector3& a,
|
||||
const btVector3& b,
|
||||
const btVector3& c)
|
||||
{
|
||||
const btVector4 p[]={transform(a),transform(b),transform(c)};
|
||||
return(clipDraw<3,QueryOCL>(p,qrarea));
|
||||
}
|
||||
inline bool queryOccluder( const btVector3& a,
|
||||
const btVector3& b,
|
||||
const btVector3& c,
|
||||
const btVector3& d)
|
||||
{
|
||||
const btVector4 p[]={transform(a),transform(b),transform(c),transform(d)};
|
||||
return(clipDraw<4,QueryOCL>(p,qrarea));
|
||||
}
|
||||
inline bool queryOccluder( const btVector3& c,
|
||||
const btVector3& e)
|
||||
{
|
||||
const btVector4 x[]={ transform(btVector3(c[0]-e[0],c[1]-e[1],c[2]-e[2])),
|
||||
transform(btVector3(c[0]+e[0],c[1]-e[1],c[2]-e[2])),
|
||||
transform(btVector3(c[0]+e[0],c[1]+e[1],c[2]-e[2])),
|
||||
transform(btVector3(c[0]-e[0],c[1]+e[1],c[2]-e[2])),
|
||||
transform(btVector3(c[0]-e[0],c[1]-e[1],c[2]+e[2])),
|
||||
transform(btVector3(c[0]+e[0],c[1]-e[1],c[2]+e[2])),
|
||||
transform(btVector3(c[0]+e[0],c[1]+e[1],c[2]+e[2])),
|
||||
transform(btVector3(c[0]-e[0],c[1]+e[1],c[2]+e[2]))};
|
||||
for(int i=0;i<8;++i)
|
||||
{
|
||||
if((x[i][2]+x[i][3])<=0) return(true);
|
||||
}
|
||||
static const int d[]={ 1,0,3,2,
|
||||
4,5,6,7,
|
||||
4,7,3,0,
|
||||
6,5,1,2,
|
||||
7,6,2,3,
|
||||
5,4,0,1};
|
||||
for(int i=0;i<(sizeof(d)/sizeof(d[0]));)
|
||||
{
|
||||
const btVector4 p[]={ x[d[i++]],
|
||||
x[d[i++]],
|
||||
x[d[i++]],
|
||||
x[d[i++]]};
|
||||
if(clipDraw<4,QueryOCL>(p,qrarea)) return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
};
|
||||
|
||||
OcclusionBuffer ocb;
|
||||
|
||||
BulletSAPCompleteBoxPruningTest::BulletSAPCompleteBoxPruningTest(int numBoxes,int method) :
|
||||
mBar (null),
|
||||
mNbBoxes (numBoxes),
|
||||
@@ -39,7 +348,7 @@ BulletSAPCompleteBoxPruningTest::BulletSAPCompleteBoxPruningTest(int numBoxes,in
|
||||
btVector3 aabbMax(200,200,200);
|
||||
|
||||
int maxNumBoxes = numBoxes;
|
||||
|
||||
m_isdbvt=false;
|
||||
switch (method)
|
||||
{
|
||||
case 1:
|
||||
@@ -101,8 +410,9 @@ BulletSAPCompleteBoxPruningTest::BulletSAPCompleteBoxPruningTest(int numBoxes,in
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
methodname = "btDbvtBroadphase";
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
m_isdbvt = true;
|
||||
methodname = "btDbvtBroadphase";
|
||||
break;
|
||||
default:
|
||||
{
|
||||
@@ -122,11 +432,13 @@ BulletSAPCompleteBoxPruningTest::~BulletSAPCompleteBoxPruningTest()
|
||||
|
||||
void BulletSAPCompleteBoxPruningTest::Init()
|
||||
{
|
||||
m_firstTime = true;
|
||||
btClock clock;
|
||||
m_firstTime = true;
|
||||
SRand(0);
|
||||
|
||||
|
||||
mBoxes = new AABB[mNbBoxes];
|
||||
mFlags = new bool[mNbBoxes];
|
||||
mBoxPtrs = new const AABB*[mNbBoxes];
|
||||
mBoxTime = new float[mNbBoxes];
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
@@ -146,11 +458,12 @@ void BulletSAPCompleteBoxPruningTest::Init()
|
||||
btVector3 aabbMax(Center.x+Extents.x,Center.y+Extents.y,Center.z+Extents.z);
|
||||
int shapeType =0;
|
||||
void* userPtr = 0;
|
||||
btBroadphaseProxy* proxy = m_broadphase->createProxy(aabbMin,aabbMax,shapeType,(void*)i,1,1,0,0);//m_dispatcher);
|
||||
btBroadphaseProxy* proxy = m_broadphase->createProxy(aabbMin,aabbMax,shapeType,&mBoxes[i],1,1,0,0);//m_dispatcher);
|
||||
m_proxies.push_back( proxy );
|
||||
|
||||
mBoxTime[i] = 2000.0f*UnitRandomFloat();
|
||||
}
|
||||
printf("Initialization of %s with %u boxes: %ums\r\n",methodname,mNbBoxes,clock.getTimeMilliseconds());
|
||||
}
|
||||
|
||||
void BulletSAPCompleteBoxPruningTest::Release()
|
||||
@@ -166,6 +479,23 @@ void BulletSAPCompleteBoxPruningTest::Select()
|
||||
mBar = TwNewBar("OPC_CompleteBoxPruning");
|
||||
TwAddVarRW(mBar, "Speed", TW_TYPE_FLOAT, &mSpeed, " min=0.0 max=0.01 step=0.00001");
|
||||
TwAddVarRW(mBar, "Amplitude", TW_TYPE_FLOAT, &mAmplitude, " min=10.0 max=200.0 step=0.1");
|
||||
if(m_isdbvt)
|
||||
{
|
||||
TwAddVarRW(mBar, "Enable culling",TW_TYPE_BOOLCPP,&enableCulling,"");
|
||||
TwAddVarRW(mBar, "Enable occlusion",TW_TYPE_BOOLCPP,&enableOcclusion,"");
|
||||
TwAddVarRW(mBar, "Show culling",TW_TYPE_BOOLCPP,&showCulling,"");
|
||||
TwAddVarRW(mBar, "Show occlusion",TW_TYPE_BOOLCPP,&showOcclusion,"");
|
||||
TwAddVarRW(mBar, "Cull far plane",TW_TYPE_BOOLCPP,&cullFarPlane,"");
|
||||
TwAddVarRW(mBar, "OC Min area",TW_TYPE_FLOAT,&ocb.ocarea,"min=0.0 max=1.0 step=0.001");
|
||||
TwAddVarRW(mBar, "QR Min area",TW_TYPE_FLOAT,&ocb.qrarea,"min=0.0 max=1.0 step=0.001");
|
||||
TwAddVarRW(mBar, "Dyn lkhd",TW_TYPE_INT32,&((btDbvtBroadphase*)m_broadphase)->m_sets[0].m_lkhd,"min=-1 max=32");
|
||||
TwAddVarRW(mBar, "Fix lkhd",TW_TYPE_INT32,&((btDbvtBroadphase*)m_broadphase)->m_sets[1].m_lkhd,"min=-1 max=32");
|
||||
TwAddVarRW(mBar, "Dyn opt/f(%)",TW_TYPE_INT32,&((btDbvtBroadphase*)m_broadphase)->m_dupdates,"min=0 max=100");
|
||||
TwAddVarRW(mBar, "Fix opt/f(%)",TW_TYPE_INT32,&((btDbvtBroadphase*)m_broadphase)->m_fupdates,"min=0 max=100");
|
||||
TwAddVarRO(mBar, "Dyn leafs",TW_TYPE_INT32,&((btDbvtBroadphase*)m_broadphase)->m_sets[0].m_leafs,"");
|
||||
TwAddVarRO(mBar, "Fix leafs",TW_TYPE_INT32,&((btDbvtBroadphase*)m_broadphase)->m_sets[1].m_leafs,"");
|
||||
TwAddVarRO(mBar, "Visible",TW_TYPE_INT32,&visiblecount,"");
|
||||
}
|
||||
}
|
||||
printf("SubMethod: %s\r\n",methodname);
|
||||
}
|
||||
@@ -198,8 +528,8 @@ bool BulletSAPCompleteBoxPruningTest::UpdateBoxes(int numBoxes)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
extern int doTree;
|
||||
extern int percentUpdate;
|
||||
extern int doTree;
|
||||
extern int percentUpdate;
|
||||
|
||||
void BulletSAPCompleteBoxPruningTest::PerformTest()
|
||||
{
|
||||
@@ -239,8 +569,7 @@ void BulletSAPCompleteBoxPruningTest::PerformTest()
|
||||
|
||||
// printf("%d pairs colliding\r ", mPairs.GetNbPairs());
|
||||
|
||||
bool* Flags = (bool*)_alloca(sizeof(bool)*mNbBoxes);
|
||||
ZeroMemory(Flags, sizeof(bool)*mNbBoxes);
|
||||
ZeroMemory(mFlags,sizeof(bool)*mNbBoxes);
|
||||
|
||||
btOverlappingPairCache* pairCache = m_broadphase->getOverlappingPairCache();
|
||||
const btBroadphasePair* pairPtr = pairCache->getOverlappingPairArrayPtr();
|
||||
@@ -249,8 +578,11 @@ void BulletSAPCompleteBoxPruningTest::PerformTest()
|
||||
{
|
||||
// Flags[pairPtr[i].m_pProxy0->getUid()-1] = true;
|
||||
// Flags[pairPtr[i].m_pProxy1->getUid()-1] = true;
|
||||
Flags[int(pairPtr[i].m_pProxy0->m_clientObject)] = true;
|
||||
Flags[int(pairPtr[i].m_pProxy1->m_clientObject)] = true;
|
||||
int j;
|
||||
j=((AABB*)pairPtr[i].m_pProxy0->m_clientObject)-mBoxes;
|
||||
mFlags[j] = true;
|
||||
j=((AABB*)pairPtr[i].m_pProxy1->m_clientObject)-mBoxes;
|
||||
mFlags[j] = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -304,11 +636,13 @@ void BulletSAPCompleteBoxPruningTest::PerformTest()
|
||||
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
// Render boxes
|
||||
OBB CurrentBox;
|
||||
Render();
|
||||
/*OBB CurrentBox;
|
||||
CurrentBox.mRot.Identity();
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
@@ -317,7 +651,7 @@ void BulletSAPCompleteBoxPruningTest::PerformTest()
|
||||
mBoxes[i].GetCenter(CurrentBox.mCenter);
|
||||
mBoxes[i].GetExtents(CurrentBox.mExtents);
|
||||
DrawOBB(CurrentBox);
|
||||
}
|
||||
}*/
|
||||
|
||||
char Buffer[4096];
|
||||
sprintf(Buffer, "CompleteBoxPruning: %5.1f us (%d cycles) : %d pairs\n", mProfiler.mMsTime, mProfiler.mCycles,
|
||||
@@ -328,6 +662,286 @@ void BulletSAPCompleteBoxPruningTest::PerformTest()
|
||||
GLFontRenderer::print(10.0f, 10.0f, 0.02f, Buffer);
|
||||
}
|
||||
|
||||
//
|
||||
static void DrawVolume(const btDbvt::Volume& volume,const btVector3& color)
|
||||
{
|
||||
const btVector3 mins=volume.Mins();
|
||||
const btVector3 maxs=volume.Maxs();
|
||||
glColor3f(color.x(),color.y(),color.z());
|
||||
glVertex3f(mins.x(),mins.y(),mins.z());
|
||||
glVertex3f(maxs.x(),mins.y(),mins.z());
|
||||
|
||||
glVertex3f(maxs.x(),mins.y(),mins.z());
|
||||
glVertex3f(maxs.x(),maxs.y(),mins.z());
|
||||
|
||||
glVertex3f(maxs.x(),maxs.y(),mins.z());
|
||||
glVertex3f(mins.x(),maxs.y(),mins.z());
|
||||
|
||||
glVertex3f(mins.x(),maxs.y(),mins.z());
|
||||
glVertex3f(mins.x(),mins.y(),mins.z());
|
||||
|
||||
glVertex3f(mins.x(),mins.y(),maxs.z());
|
||||
glVertex3f(maxs.x(),mins.y(),maxs.z());
|
||||
|
||||
glVertex3f(maxs.x(),mins.y(),maxs.z());
|
||||
glVertex3f(maxs.x(),maxs.y(),maxs.z());
|
||||
|
||||
glVertex3f(maxs.x(),maxs.y(),maxs.z());
|
||||
glVertex3f(mins.x(),maxs.y(),maxs.z());
|
||||
|
||||
glVertex3f(mins.x(),maxs.y(),maxs.z());
|
||||
glVertex3f(mins.x(),mins.y(),maxs.z());
|
||||
|
||||
glVertex3f(mins.x(),mins.y(),mins.z());
|
||||
glVertex3f(mins.x(),mins.y(),maxs.z());
|
||||
|
||||
glVertex3f(maxs.x(),mins.y(),mins.z());
|
||||
glVertex3f(maxs.x(),mins.y(),maxs.z());
|
||||
|
||||
glVertex3f(maxs.x(),maxs.y(),mins.z());
|
||||
glVertex3f(maxs.x(),maxs.y(),maxs.z());
|
||||
|
||||
glVertex3f(mins.x(),maxs.y(),mins.z());
|
||||
glVertex3f(mins.x(),maxs.y(),maxs.z());
|
||||
}
|
||||
|
||||
//
|
||||
void BulletSAPCompleteBoxPruningTest::RenderAll()
|
||||
{
|
||||
OBB CurrentBox;
|
||||
CurrentBox.mRot.Identity();
|
||||
for(udword i=0;i<mNbBoxes;i++)
|
||||
{
|
||||
if(mFlags[i]) glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else glColor3f(0.0f, 1.0f, 0.0f);
|
||||
mBoxes[i].GetCenter(CurrentBox.mCenter);
|
||||
mBoxes[i].GetExtents(CurrentBox.mExtents);
|
||||
DrawOBB(CurrentBox);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void BulletSAPCompleteBoxPruningTest::Render()
|
||||
{
|
||||
visiblecount=mNbBoxes;
|
||||
if((!m_isdbvt)||(!enableCulling))
|
||||
{
|
||||
RenderAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
btDbvtBroadphase* pbp=(btDbvtBroadphase*)m_broadphase;
|
||||
const int margin=0;
|
||||
const int lc=margin;
|
||||
const int rc=glutGet(GLUT_WINDOW_WIDTH)-(1+margin);
|
||||
const int tc=margin;
|
||||
const int bc=glutGet(GLUT_WINDOW_HEIGHT)-(1+margin);
|
||||
const btVector3 c00(ComputeWorldRay(lc,tc).x,
|
||||
ComputeWorldRay(lc,tc).y,
|
||||
ComputeWorldRay(lc,tc).z);
|
||||
const btVector3 c10(ComputeWorldRay(rc,tc).x,
|
||||
ComputeWorldRay(rc,tc).y,
|
||||
ComputeWorldRay(rc,tc).z);
|
||||
const btVector3 c01(ComputeWorldRay(lc,bc).x,
|
||||
ComputeWorldRay(lc,bc).y,
|
||||
ComputeWorldRay(lc,bc).z);
|
||||
const btVector3 c11(ComputeWorldRay(rc,bc).x,
|
||||
ComputeWorldRay(rc,bc).y,
|
||||
ComputeWorldRay(rc,bc).z);
|
||||
|
||||
const btVector3 eye(GetCameraPos().x,GetCameraPos().y,GetCameraPos().z);
|
||||
const btVector3 dir(GetCameraDir().x,GetCameraDir().y,GetCameraDir().z);
|
||||
const btVector3 x00=eye+c00*100;
|
||||
const btVector3 x10=eye+c10*100;
|
||||
const btVector3 x01=eye+c01*100;
|
||||
const btVector3 x11=eye+c11*100;
|
||||
|
||||
ocb.initialize();
|
||||
ocb.eye=eye;
|
||||
|
||||
btVector3 planes_n[5];
|
||||
btScalar planes_o[5];
|
||||
static const btScalar farplane=200;
|
||||
static const int nplanes=sizeof(planes_n)/sizeof(planes_n[0]);
|
||||
const int acplanes=cullFarPlane?5:4;
|
||||
planes_n[0] = cross(c01,c00).normalized();
|
||||
planes_n[1] = cross(c10,c11).normalized();
|
||||
planes_n[2] = cross(c00,c10).normalized();
|
||||
planes_n[3] = cross(c11,c01).normalized();
|
||||
planes_n[4] = -dir;
|
||||
planes_o[4] = -dot(eye+dir*farplane,planes_n[4]);
|
||||
for(int i=0;i<4;++i) planes_o[i]=-dot(eye,planes_n[i]);
|
||||
|
||||
struct SceneRenderer : btDbvt::ICollide
|
||||
{
|
||||
int drawn;
|
||||
BulletSAPCompleteBoxPruningTest* self;
|
||||
OBB box;
|
||||
OcclusionBuffer* ocb;
|
||||
SceneRenderer()
|
||||
{
|
||||
drawn=0;
|
||||
box.mRot.Identity();
|
||||
}
|
||||
bool Descent(const btDbvt::Node* node)
|
||||
{
|
||||
return(ocb->queryOccluder(node->volume.Center(),node->volume.Extent()));
|
||||
}
|
||||
void Process(const btDbvt::Node* leaf)
|
||||
{
|
||||
btBroadphaseProxy* proxy=(btBroadphaseProxy*)leaf->data;
|
||||
int i=((AABB*)proxy->m_clientObject)-self->mBoxes;
|
||||
if(self->mFlags[i]) glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else glColor3f(0.0f, 1.0f, 0.0f);
|
||||
self->mBoxes[i].GetCenter(box.mCenter);
|
||||
self->mBoxes[i].GetExtents(box.mExtents);
|
||||
DrawOBB(box);drawn++;
|
||||
if(ocb)
|
||||
{
|
||||
ocb->appendOccluder(btVector3(box.mCenter.x,box.mCenter.y,box.mCenter.z),
|
||||
btVector3(box.mExtents.x,box.mExtents.y,box.mExtents.z));
|
||||
}
|
||||
}
|
||||
} srenderer;
|
||||
srenderer.self=this;
|
||||
srenderer.ocb=0;
|
||||
if(enableOcclusion)
|
||||
{
|
||||
srenderer.ocb=&ocb;
|
||||
btDbvt::collideOCL(pbp->m_sets[1].m_root,planes_n,planes_o,dir,acplanes,srenderer);
|
||||
btDbvt::collideOCL(pbp->m_sets[0].m_root,planes_n,planes_o,dir,acplanes,srenderer);
|
||||
}
|
||||
else
|
||||
{
|
||||
btDbvt::collideKDOP(pbp->m_sets[1].m_root,planes_n,planes_o,acplanes,srenderer);
|
||||
btDbvt::collideKDOP(pbp->m_sets[0].m_root,planes_n,planes_o,acplanes,srenderer);
|
||||
}
|
||||
visiblecount=srenderer.drawn;
|
||||
if(showOcclusion&&enableOcclusion)
|
||||
{
|
||||
const btScalar ratio=((float)glutGet(GLUT_WINDOW_HEIGHT))/((float)glutGet(GLUT_WINDOW_WIDTH));
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(-1,1,-1,1,-1,1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
const float mm[]={ 1,0,0,0,
|
||||
0,1,0,0,
|
||||
0,0,0,1,
|
||||
0,0,0,1};
|
||||
glMultMatrixf(mm);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
const float size=0.6f;
|
||||
const float orgx=0.3f;
|
||||
const float orgy=0.25f;
|
||||
const float left=orgx;
|
||||
const float right=orgx+size;
|
||||
const float top=orgy+size;
|
||||
const float bottom=orgy;
|
||||
ocb.drawBuffer(left,bottom,right,top);
|
||||
}
|
||||
if(showCulling)
|
||||
{
|
||||
const btScalar ratio=((float)glutGet(GLUT_WINDOW_HEIGHT))/((float)glutGet(GLUT_WINDOW_WIDTH));
|
||||
static const float scale=0.004;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(-1,1,-1*ratio,1*ratio,-1,1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
const float mm[]={ 1,0,0,0,
|
||||
0,0,1,0,
|
||||
0,1,0,0,
|
||||
0,0,0,1};
|
||||
glMultMatrixf(mm);
|
||||
glScalef(scale,scale,scale);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glColor4f(1,1,1,1);
|
||||
|
||||
struct DebugRenderer : btDbvt::ICollide
|
||||
{
|
||||
OcclusionBuffer* ocb;
|
||||
int sid;
|
||||
bool AllLeafs(const btDbvt::Node* node)
|
||||
{
|
||||
Process(node);
|
||||
return(false);
|
||||
}
|
||||
bool Descent(const btDbvt::Node* node)
|
||||
{
|
||||
return(ocb->queryOccluder(node->volume.Center(),node->volume.Extent()));
|
||||
}
|
||||
void Process(const btDbvt::Node* node)
|
||||
{
|
||||
if(ocb)
|
||||
{
|
||||
ocb->appendOccluder(node->volume.Center(),node->volume.Extent());
|
||||
}
|
||||
if(sid>=0)
|
||||
{
|
||||
const float f=sid/1023.;
|
||||
DrawVolume(node->volume,btVector3(1,f,f));
|
||||
sid=(sid+1)%1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(node->isinternal())
|
||||
DrawVolume(node->volume,btVector3(0,1,0));
|
||||
else
|
||||
DrawVolume(node->volume,btVector3(1,0,1));
|
||||
}
|
||||
}
|
||||
} drenderer;
|
||||
if(enableOcclusion)
|
||||
{
|
||||
drenderer.ocb=&ocb;
|
||||
drenderer.sid=0;
|
||||
ocb.clear();
|
||||
btDbvt::collideOCL(pbp->m_sets[1].m_root,planes_n,planes_o,dir,acplanes,drenderer);
|
||||
btDbvt::collideOCL(pbp->m_sets[0].m_root,planes_n,planes_o,dir,acplanes,drenderer);
|
||||
}
|
||||
else
|
||||
{
|
||||
drenderer.ocb=0;
|
||||
drenderer.sid=-1;
|
||||
btDbvt::collideKDOP(pbp->m_sets[1].m_root,planes_n,planes_o,acplanes,drenderer);
|
||||
btDbvt::collideKDOP(pbp->m_sets[0].m_root,planes_n,planes_o,acplanes,drenderer);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glColor4f(1,1,1,1);
|
||||
glVertex3f(eye.x(),eye.y(),eye.z());
|
||||
glVertex3f(x00.x(),x00.y(),x00.z());
|
||||
glVertex3f(eye.x(),eye.y(),eye.z());
|
||||
glVertex3f(x10.x(),x10.y(),x10.z());
|
||||
glVertex3f(eye.x(),eye.y(),eye.z());
|
||||
glVertex3f(x01.x(),x01.y(),x01.z());
|
||||
glVertex3f(eye.x(),eye.y(),eye.z());
|
||||
glVertex3f(x11.x(),x11.y(),x11.z());
|
||||
|
||||
glVertex3f(x00.x(),x00.y(),x00.z());
|
||||
glVertex3f(x10.x(),x10.y(),x10.z());
|
||||
|
||||
glVertex3f(x10.x(),x10.y(),x10.z());
|
||||
glVertex3f(x11.x(),x11.y(),x11.z());
|
||||
|
||||
glVertex3f(x11.x(),x11.y(),x11.z());
|
||||
glVertex3f(x01.x(),x01.y(),x01.z());
|
||||
|
||||
glVertex3f(x01.x(),x01.y(),x01.z());
|
||||
glVertex3f(x00.x(),x00.y(),x00.z());
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BulletSAPCompleteBoxPruningTest::KeyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user