diff --git a/Demos/OpenGL/DemoApplication.cpp b/Demos/OpenGL/DemoApplication.cpp index 6a805238e..a92d6143c 100644 --- a/Demos/OpenGL/DemoApplication.cpp +++ b/Demos/OpenGL/DemoApplication.cpp @@ -71,7 +71,9 @@ m_shootBoxShape(0), m_ShootBoxInitialSpeed(40.f), m_stepping(true), m_singleStep(false), - m_idle(false) + m_idle(false), + m_enableshadows(false), + m_sundirection(btVector3(1,-2,1)*1000) { #ifndef BT_NO_PROFILE m_profileIterator = CProfileManager::Get_Iterator(); @@ -289,6 +291,8 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y) case 'z' : zoomIn(); break; case 'x' : zoomOut(); break; case 'i' : toggleIdle(); break; + case 'g' : m_enableshadows=!m_enableshadows;break; + case 'u' : m_shapeDrawer.enableTexture(!m_shapeDrawer.enableTexture(false));break; case 'h': if (m_debugMode & btIDebugDraw::DBG_NoHelpText) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText); @@ -902,60 +906,115 @@ void DemoApplication::showProfileInfo(float& xOffset,float& yStart, float yIncr) } +// +void DemoApplication::renderscene(int pass) +{ +btScalar m[16]; +btMatrix3x3 rot;rot.setIdentity(); +const int numObjects=m_dynamicsWorld->getNumCollisionObjects(); +btVector3 wireColor(1,0,0); +for(int i=0;igetCollisionObjectArray()[i]; + btRigidBody* body=btRigidBody::upcast(colObj); + if(body&&body->getMotionState()) + { + btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); + myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); + rot=myMotionState->m_graphicsWorldTrans.getBasis(); + } + else + { + colObj->getWorldTransform().getOpenGLMatrix(m); + rot=colObj->getWorldTransform().getBasis(); + } + btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation + if(i&1) wireColor=btVector3(0.f,0.0f,1.f); + ///color differently for active, sleeping, wantsdeactivation states + if (colObj->getActivationState() == 1) //active + { + if (i & 1) + { + wireColor += btVector3 (1.f,0.f,0.f); + } + else + { + wireColor += btVector3 (.5f,0.f,0.f); + } + } + if(colObj->getActivationState()==2) //ISLAND_SLEEPING + { + if(i&1) + { + wireColor += btVector3 (0.f,1.f, 0.f); + } + else + { + wireColor += btVector3 (0.f,0.5f,0.f); + } + } + switch(pass) + { + case 0: m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode());break; + case 1: m_shapeDrawer.drawShadow(m,m_sundirection*rot,colObj->getCollisionShape());break; + case 2: m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor*0.3,0);break; + } + } +} + +// void DemoApplication::renderme() { updateCamera(); - btScalar m[16]; - if (m_dynamicsWorld) - { - int numObjects = m_dynamicsWorld->getNumCollisionObjects(); - btVector3 wireColor(1,0,0); - for (int i=0;igetCollisionObjectArray()[i]; - btRigidBody* body = btRigidBody::upcast(colObj); - - if (body && body->getMotionState()) + { + if(m_enableshadows) { - btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); - myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); - } else - { - colObj->getWorldTransform().getOpenGLMatrix(m); + glClear(GL_STENCIL_BUFFER_BIT); + glEnable(GL_CULL_FACE); + renderscene(0); + + glDisable(GL_LIGHTING); + glDepthMask(GL_FALSE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_STENCIL_TEST); + glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + glStencilFunc(GL_ALWAYS,1,0xFFFFFFFFL); + glFrontFace(GL_CCW); + glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); + renderscene(1); + glFrontFace(GL_CW); + glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); + renderscene(1); + glFrontFace(GL_CCW); + + glPolygonMode(GL_FRONT,GL_FILL); + glPolygonMode(GL_BACK,GL_FILL); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_LIGHTING); + glDepthMask(GL_TRUE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + + glDepthFunc(GL_LEQUAL); + glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL ); + glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + glDisable(GL_LIGHTING); + renderscene(2); + glEnable(GL_LIGHTING); + glDepthFunc(GL_LESS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); } - - btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation - if (i & 1) + else { - wireColor = btVector3(0.f,0.0f,1.f); + renderscene(0); } - ///color differently for active, sleeping, wantsdeactivation states - if (colObj->getActivationState() == 1) //active - { - if (i & 1) - { - wireColor += btVector3 (1.f,0.f,0.f); - } else - { - wireColor += btVector3 (.5f,0.f,0.f); - } - } - if (colObj->getActivationState() == 2) //ISLAND_SLEEPING - { - if (i & 1) - { - wireColor += btVector3 (0.f,1.f, 0.f); - } else - { - wireColor += btVector3 (0.f,0.5f,0.f); - } - } - - m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode()); - } - float xOffset = 10.f; float yStart = 20.f; diff --git a/Demos/OpenGL/DemoApplication.h b/Demos/OpenGL/DemoApplication.h index 04d1129f7..0dd4e15a9 100644 --- a/Demos/OpenGL/DemoApplication.h +++ b/Demos/OpenGL/DemoApplication.h @@ -80,8 +80,11 @@ class DemoApplication int m_lastKey; void showProfileInfo(float& xOffset,float& yStart, float yIncr); + void renderscene(int pass); GL_ShapeDrawer m_shapeDrawer; + bool m_enableshadows; + btVector3 m_sundirection; public: @@ -96,6 +99,9 @@ public: void setOrthographicProjection(); void resetPerspectiveProjection(); + + bool setTexturing(bool enable) { return(m_shapeDrawer.enableTexture(enable)); } + bool setShadows(bool enable) { bool p=m_enableshadows;m_enableshadows=enable;return(p); } int getDebugMode() { @@ -199,3 +205,4 @@ public: #endif //DEMO_APPLICATION_H + diff --git a/Demos/OpenGL/GL_ShapeDrawer.cpp b/Demos/OpenGL/GL_ShapeDrawer.cpp index 64fc69367..a2c028a57 100644 --- a/Demos/OpenGL/GL_ShapeDrawer.cpp +++ b/Demos/OpenGL/GL_ShapeDrawer.cpp @@ -317,7 +317,48 @@ void GL_ShapeDrawer::drawCylinder(float radius,float halfHeight, int upAxis) gluDeleteQuadric(quadObj); } - +GL_ShapeDrawer::ShapeCache* GL_ShapeDrawer::cache(btConvexShape* shape) +{ +ShapeCache* sc=(ShapeCache*)shape->getUserPointer(); +if(!sc) + { + sc=new(btAlignedAlloc(sizeof(ShapeCache),16)) ShapeCache(shape); + sc->m_shapehull.buildHull(shape->getMargin()); + m_shapecaches.push_back(sc); + shape->setUserPointer(sc); + /* Build edges */ + const int ni=sc->m_shapehull.numIndices(); + const int nv=sc->m_shapehull.numVertices(); + const unsigned int* pi=sc->m_shapehull.getIndexPointer(); + const btVector3* pv=sc->m_shapehull.getVertexPointer(); + btAlignedObjectArray edges; + sc->m_edges.reserve(ni); + edges.resize(nv*nv,0); + for(int i=0;im_edges.push_back(ShapeCache::Edge()); + e=&sc->m_edges[sc->m_edges.size()-1]; + e->n[0]=nrm;e->n[1]=-nrm; + e->v[0]=a;e->v[1]=b; + } + else + { + e->n[1]=nrm; + } + } + } + } +return(sc); +} void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode) { @@ -357,13 +398,53 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons } else { + if(m_textureenabled&&(!m_textureinitialized)) + { + GLubyte* image=new GLubyte[256*256*3]; + for(int y=0;y<256;++y) + { + const int t=y>>4; + GLubyte* pi=image+y*256*3; + for(int x=0;x<256;++x) + { + const int s=x>>4; + const GLubyte b=180; + GLubyte c=b+((s+t&1)&1)*(255-b); + pi[0]=pi[1]=pi[2]=c;pi+=3; + } + } + glGenTextures(1,&m_texturehandle); + glBindTexture(GL_TEXTURE_2D,m_texturehandle); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + gluBuild2DMipmaps(GL_TEXTURE_2D,3,256,256,GL_RGB,GL_UNSIGNED_BYTE,image); + delete[] image; + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(0.025,0.025,0.025); + + static const GLfloat planex[]={1,0,0,0}; + static const GLfloat planey[]={0,1,0,0}; + static const GLfloat planez[]={0,0,1,0}; + glTexGenfv(GL_S,GL_OBJECT_PLANE,planex); + glTexGenfv(GL_T,GL_OBJECT_PLANE,planez); + glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + m_textureinitialized=true; + } //drawCoordSystem(); //glPushMatrix(); glEnable(GL_COLOR_MATERIAL); - glColor3f(color.x(),color.y(), color.z()); - - + if(m_textureenabled) glEnable(GL_TEXTURE_2D); + glColor3f(color.x(),color.y(), color.z()); bool useWireframeFallback = true; @@ -371,7 +452,8 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons { ///you can comment out any of the specific cases, and use the default ///the benefit of 'default' is that it approximates the actual collision shape including collision margin - switch (shape->getShapeType()) + int shapetype=m_textureenabled?MAX_BROADPHASE_COLLISION_TYPES:shape->getShapeType(); + switch (shapetype) { case BOX_SHAPE_PROXYTYPE: { @@ -467,6 +549,8 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons if (shape->isConvex()) { + ShapeCache* sc=cache((btConvexShape*)shape); + #if 0 btConvexShape* convexShape = (btConvexShape*)shape; if (!shape->getUserPointer()) { @@ -488,14 +572,14 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons } - + #endif - if (shape->getUserPointer()) + //if (shape->getUserPointer()) { //glutSolidCube(1.0); - btShapeHull* hull = (btShapeHull*)shape->getUserPointer(); + btShapeHull* hull = &sc->m_shapehull/*(btShapeHull*)shape->getUserPointer()*/; if (hull->numTriangles () > 0) @@ -537,12 +621,7 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons glEnd (); } - } else - { -// printf("unhandled drawing\n"); } - - } } } @@ -656,27 +735,115 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons } glEnable(GL_DEPTH_BUFFER_BIT); - // glPopMatrix(); + // glPopMatrix(); + if(m_textureenabled) glDisable(GL_TEXTURE_2D); } glPopMatrix(); } +// +void GL_ShapeDrawer::drawShadow(btScalar* m,const btVector3& extrusion,const btCollisionShape* shape) +{ +glPushMatrix(); +btglMultMatrix(m); +if(shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE) + { + const btUniformScalingShape* scalingShape = static_cast(shape); + const btConvexShape* convexShape = scalingShape->getChildShape(); + float scalingFactor = (float)scalingShape->getUniformScalingFactor(); + btScalar tmpScaling[4][4]={ {scalingFactor,0,0,0}, + {0,scalingFactor,0,0}, + {0,0,scalingFactor,0}, + {0,0,0,1}}; + drawShadow((btScalar*)tmpScaling,extrusion,convexShape); + glPopMatrix(); + return; + } +else if(shape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) + { + const btCompoundShape* compoundShape = static_cast(shape); + for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) + { + btTransform childTrans = compoundShape->getChildTransform(i); + const btCollisionShape* colShape = compoundShape->getChildShape(i); + btScalar childMat[16]; + childTrans.getOpenGLMatrix(childMat); + drawShadow(childMat,extrusion*childTrans.getBasis(),colShape); + } + } +else + { + bool useWireframeFallback = true; + if (shape->isConvex()) + { + ShapeCache* sc=cache((btConvexShape*)shape); + btShapeHull* hull =&sc->m_shapehull; + glBegin(GL_QUADS); + for(int i=0;im_edges.size();++i) + { + const btScalar d=dot(sc->m_edges[i].n[0],extrusion); + if((d*dot(sc->m_edges[i].n[1],extrusion))<0) + { + const int q= d<0?1:0; + const btVector3& a= hull->getVertexPointer()[sc->m_edges[i].v[q]]; + const btVector3& b= hull->getVertexPointer()[sc->m_edges[i].v[1-q]]; + glVertex3f(a[0],a[1],a[2]); + glVertex3f(b[0],b[1],b[2]); + glVertex3f(b[0]+extrusion[0],b[1]+extrusion[1],b[2]+extrusion[2]); + glVertex3f(a[0]+extrusion[0],a[1]+extrusion[1],a[2]+extrusion[2]); + } + } + glEnd(); + } + } + + + + + if (shape->isConcave())//>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) +// if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btConcaveShape* concaveMesh = (btConcaveShape*) shape; + //btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + //btVector3 aabbMax(100,100,100);//btScalar(1e30),btScalar(1e30),btScalar(1e30)); + + //todo pass camera, for some culling + btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + btVector3 aabbMin(-btScalar(1e30),-btScalar(1e30),-btScalar(1e30)); + + GlDrawcallback drawCallback; + drawCallback.m_wireframe = false; + + concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); + + } + glPopMatrix(); + +} + +// GL_ShapeDrawer::GL_ShapeDrawer() { +m_texturehandle = 0; +m_textureenabled = false; +m_textureinitialized = false; } GL_ShapeDrawer::~GL_ShapeDrawer() { int i; - for (i=0;i~btShapeHull(); - btAlignedFree(hull); - m_shapeHulls[i] = 0; + m_shapecaches[i]->~ShapeCache(); + btAlignedFree(m_shapecaches[i]); } - m_shapeHulls.clear(); + m_shapecaches.clear(); + if(m_textureinitialized) + { + glDeleteTextures(1,&m_texturehandle); + } } + diff --git a/Demos/OpenGL/GL_ShapeDrawer.h b/Demos/OpenGL/GL_ShapeDrawer.h index 151e4233c..69748e013 100644 --- a/Demos/OpenGL/GL_ShapeDrawer.h +++ b/Demos/OpenGL/GL_ShapeDrawer.h @@ -20,11 +20,26 @@ class btShapeHull; #include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btVector3.h" +#include "BulletCollision/CollisionShapes/btShapeHull.h" + /// OpenGL shape drawing class GL_ShapeDrawer { + struct ShapeCache + { + struct Edge { btVector3 n[2];int v[2]; }; + ShapeCache(btConvexShape* s) : m_shapehull(s) {} + btShapeHull m_shapehull; + btAlignedObjectArray m_edges; + }; //clean-up memory of dynamically created shape hulls - btAlignedObjectArray m_shapeHulls; + btAlignedObjectArray m_shapecaches; + unsigned int m_texturehandle; + bool m_textureenabled; + bool m_textureinitialized; + + private: + ShapeCache* cache(btConvexShape*); public: GL_ShapeDrawer(); @@ -33,9 +48,13 @@ class GL_ShapeDrawer ///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode); + void drawShadow(btScalar* m, const btVector3& extrusion,const btCollisionShape* shape); + + bool enableTexture(bool enable) { bool p=m_textureenabled;m_textureenabled=enable;return(p); } static void drawCylinder(float radius,float halfHeight, int upAxis); static void drawCoordSystem(); + }; void OGL_displaylist_register_shape(btCollisionShape * shape); diff --git a/Demos/OpenGL/GlutStuff.cpp b/Demos/OpenGL/GlutStuff.cpp index e06a1dd58..4a7cb049f 100644 --- a/Demos/OpenGL/GlutStuff.cpp +++ b/Demos/OpenGL/GlutStuff.cpp @@ -71,7 +71,7 @@ int glutmain(int argc, char **argv,int width,int height,const char* title,DemoAp gDemoApplication = demoApp; glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowPosition(0, 0); glutInitWindowSize(width, height); glutCreateWindow(title); diff --git a/Demos/SoftDemo/SoftDemo.cpp b/Demos/SoftDemo/SoftDemo.cpp index fcfb86314..2536e3393 100644 --- a/Demos/SoftDemo/SoftDemo.cpp +++ b/Demos/SoftDemo/SoftDemo.cpp @@ -101,7 +101,7 @@ extern int gTotalContactPoints; void SoftDemo::clientMoveAndDisplay() { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); @@ -1030,10 +1030,15 @@ struct Functor btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices, &gIndices[0][0], NUM_TRIANGLES); - psb->generateBendingConstraints(2); + btSoftBody::Material* pm=psb->appendMaterial(); + pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2,pm); psb->m_cfg.piterations=2; + psb->m_cfg.kDF =1; psb->m_cfg.kSSHR_CL =1; psb->m_cfg.kSS_SPLT_CL =0; + psb->m_cfg.kSKHR_CL =0.1f; + psb->m_cfg.kSK_SPLT_CL =1; psb->m_cfg.collisions= btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS; psb->randomizeConstraints(); @@ -1763,3 +1768,4 @@ void SoftDemo::exitPhysics() + diff --git a/Demos/SoftDemo/SoftDemo.h b/Demos/SoftDemo/SoftDemo.h index 568d87b3f..428615103 100644 --- a/Demos/SoftDemo/SoftDemo.h +++ b/Demos/SoftDemo/SoftDemo.h @@ -88,7 +88,8 @@ public: SoftDemo() : m_drag(false) { - + setTexturing(true); + setShadows(true); } virtual ~SoftDemo() { @@ -172,3 +173,4 @@ MACRO_SOFT_DEMO(16)//Init_BunnyMatch + diff --git a/Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.cpp b/Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.cpp index ab73e8fa1..14744c7d9 100644 --- a/Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.cpp +++ b/Extras/CDTestFramework/BulletSAPCompleteBoxPruningTest.cpp @@ -492,8 +492,8 @@ void BulletSAPCompleteBoxPruningTest::Select() 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, "Dyn leafs",TW_TYPE_INT32,&((btDbvtBroadphase*)m_broadphase)->m_sets[0].m_leaves,""); + TwAddVarRO(mBar, "Fix leafs",TW_TYPE_INT32,&((btDbvtBroadphase*)m_broadphase)->m_sets[1].m_leaves,""); TwAddVarRO(mBar, "Visible",TW_TYPE_INT32,&visiblecount,""); } } @@ -669,7 +669,7 @@ void BulletSAPCompleteBoxPruningTest::PerformTest() } // -static void DrawVolume(const btDbvt::Volume& volume,const btVector3& color) +static void DrawVolume(const btDbvtVolume& volume,const btVector3& color) { const btVector3 mins=volume.Mins(); const btVector3 maxs=volume.Maxs(); @@ -789,11 +789,15 @@ if((!m_isdbvt)||(!enableCulling)) drawn=0; box.mRot.Identity(); } - bool Descent(const btDbvt::Node* node) + bool Descent(const btDbvtNode* node) { - return(ocb->queryOccluder(node->volume.Center(),node->volume.Extent())); + return(ocb->queryOccluder(node->volume.Center(),node->volume.Extents())); } - void Process(const btDbvt::Node* leaf) + void Process(const btDbvtNode* node,btScalar depth) + { + Process(node); + } + void Process(const btDbvtNode* leaf) { btBroadphaseProxy* proxy=(btBroadphaseProxy*)leaf->data; int i=((AABB*)proxy->m_clientObject)-self->mBoxes; @@ -874,20 +878,24 @@ if((!m_isdbvt)||(!enableCulling)) { OcclusionBuffer* ocb; int sid; - bool AllLeafs(const btDbvt::Node* node) + bool AllLeafs(const btDbvtNode* node) { Process(node); return(false); } - bool Descent(const btDbvt::Node* node) + bool Descent(const btDbvtNode* node) { - return(ocb->queryOccluder(node->volume.Center(),node->volume.Extent())); + return(ocb->queryOccluder(node->volume.Center(),node->volume.Extents())); } - void Process(const btDbvt::Node* node) + void Process(const btDbvtNode* node,btScalar depth) + { + Process(node); + } + void Process(const btDbvtNode* node) { if(ocb) { - ocb->appendOccluder(node->volume.Center(),node->volume.Extent()); + ocb->appendOccluder(node->volume.Center(),node->volume.Extents()); } if(sid>=0) { diff --git a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp index 0124817c0..b24935176 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp +++ b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp @@ -86,30 +86,6 @@ value=zerodummy; // Colliders // -/* Leaf collider */ -struct btDbvtLeafCollider : btDbvt::ICollide -{ -btDbvtBroadphase* pbp; -btDbvtProxy* ppx; - btDbvtLeafCollider(btDbvtBroadphase* p,btDbvtProxy* px) : pbp(p),ppx(px) {} -void Process(const btDbvtNode* na) - { - const btDbvtNode* nb=ppx->leaf; - if(nb!=na) - { - btDbvtProxy* pa=(btDbvtProxy*)na->data; - btDbvtProxy* pb=(btDbvtProxy*)nb->data; - #if DBVT_BP_DISCRETPAIRS - if(Intersect(pa->aabb,pb->aabb)) - #endif - { - if(pa>pb) btSwap(pa,pb); - pbp->m_paircache->addOverlappingPair(pa,pb); - } - } - } -}; - /* Tree collider */ struct btDbvtTreeCollider : btDbvt::ICollide { @@ -179,7 +155,7 @@ btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin, btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( userPtr, collisionFilterGroup, collisionFilterMask); -proxy->aabb = btDbvtAabbMm::FromMM(aabbMin,aabbMax); +proxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); proxy->leaf = m_sets[0].insert(proxy->aabb,proxy); proxy->stage = m_stageCurrent; proxy->m_uniqueId = ++m_gid; @@ -208,32 +184,35 @@ void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, btDispatcher* /*dispatcher*/) { btDbvtProxy* proxy=(btDbvtProxy*)absproxy; -btDbvtAabbMm aabb=btDbvtAabbMm::FromMM(aabbMin,aabbMax); -if(proxy->stage==STAGECOUNT) - {/* fixed -> dynamic set */ - m_sets[1].remove(proxy->leaf); - proxy->leaf=m_sets[0].insert(aabb,proxy); - } - else - {/* dynamic set */ - if(Intersect(proxy->leaf->volume,aabb)) - {/* Moving */ - const btVector3 delta=(aabbMin+aabbMax)/2-proxy->aabb.Center(); - #ifdef DBVT_BP_MARGIN - m_sets[0].update(proxy->leaf,aabb,delta*m_predictedframes,DBVT_BP_MARGIN); - #else - m_sets[0].update(proxy->leaf,aabb,delta*m_predictedframes); - #endif +btDbvtVolume aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); +if(NotEqual(aabb,proxy->leaf->volume)) + { + if(proxy->stage==STAGECOUNT) + {/* fixed -> dynamic set */ + m_sets[1].remove(proxy->leaf); + proxy->leaf=m_sets[0].insert(aabb,proxy); } else - {/* Teleporting */ - m_sets[0].update(proxy->leaf,aabb); - } + {/* dynamic set */ + if(Intersect(proxy->leaf->volume,aabb)) + {/* Moving */ + const btVector3 delta=(aabbMin+aabbMax)/2-proxy->aabb.Center(); + #ifdef DBVT_BP_MARGIN + m_sets[0].update(proxy->leaf,aabb,delta*m_predictedframes,DBVT_BP_MARGIN); + #else + m_sets[0].update(proxy->leaf,aabb,delta*m_predictedframes); + #endif + } + else + {/* Teleporting */ + m_sets[0].update(proxy->leaf,aabb); + } + } + listremove(proxy,m_stageRoots[proxy->stage]); + proxy->aabb = aabb; + proxy->stage = m_stageCurrent; + listappend(proxy,m_stageRoots[m_stageCurrent]); } -listremove(proxy,m_stageRoots[proxy->stage]); -proxy->aabb = aabb; -proxy->stage = m_stageCurrent; -listappend(proxy,m_stageRoots[m_stageCurrent]); } // @@ -243,9 +222,7 @@ collide(dispatcher); #if DBVT_BP_PROFILE if(0==(m_pid%DBVT_BP_PROFILING_RATE)) { - printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leafs,m_sets[0].m_leafs,m_paircache->getNumOverlappingPairs()); - printf("mode: %s\r\n",m_mode==MODE_FULL?"full":"incremental"); - printf("cleanup: %s\r\n",m_cleanupmode==CLEANUP_FULL?"full":"incremental"); + printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs()); unsigned int total=m_profiling.m_total; if(total<=0) total=1; printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE); @@ -256,7 +233,7 @@ if(0==(m_pid%DBVT_BP_PROFILING_RATE)) m_profiling.m_fdcollide+ m_profiling.m_cleanup; printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); - printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leafs+m_sets[1].m_leafs)*DBVT_BP_PROFILING_RATE)); + printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE)); clear(m_profiling); m_clock.reset(); } @@ -322,6 +299,13 @@ if(current) ++m_pid; } +// +void btDbvtBroadphase::optimize() +{ +m_sets[0].optimizeTopDown(); +m_sets[1].optimizeTopDown(); +} + // btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() { @@ -337,7 +321,7 @@ return(m_paircache); // void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const { -btDbvtAabbMm bounds; +btDbvtVolume bounds; if(!m_sets[0].empty()) if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, m_sets[1].m_root->volume,bounds); @@ -345,7 +329,7 @@ if(!m_sets[0].empty()) bounds=m_sets[0].m_root->volume; else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; else - bounds=btDbvtAabbMm::FromCR(btVector3(0,0,0),0); + bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0); aabbMin=bounds.Mins(); aabbMax=bounds.Maxs(); } diff --git a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h index 0deb75ba6..d34b82bde 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h +++ b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h @@ -88,6 +88,7 @@ struct { btDbvtBroadphase(btOverlappingPairCache* paircache=0); ~btDbvtBroadphase(); void collide(btDispatcher* dispatcher); +void optimize(); /* btBroadphaseInterface Implementation */ btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index da9ca52b1..5babfa914 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -771,7 +771,8 @@ if(k>0) /* Initialize */ btAlignedObjectArray centers; btVector3 cog(0,0,0); - for(int i=0;im_nodes.push_back(&m_nodes[i]); @@ -824,7 +825,7 @@ if(k>0) /* Merge */ btAlignedObjectArray cids; cids.resize(m_nodes.size(),-1); - for( i=0;im_nodes.size();++j) { @@ -1018,10 +1019,11 @@ if(cut) { btAlignedObjectArray cnodes; const int pcount=ncount; + int i; ncount=m_nodes.size(); cnodes.resize(ncount,0); /* Nodes */ - for(int i=0;i=pcount)||(btFabs(ifn->Eval(x))