Added Height Field Fluid Demo to Bullet. All code stored in the Demos/HeightFieldFluidDemo directory for now.
Please see HfFluidDemo.cpp for examples of how to use the height field fluid along with buoyant collision shapes. The implementation is still lacking in my ways: 1) Need to complete more collision algorithms for buoyant collision shapes 2) Support compound buoyant shapes 3) The buoyancy model isn't that great 4) Fluid volume can be lost over time
This commit is contained in:
@@ -2,11 +2,11 @@ if (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
|||||||
SUBDIRS( OpenGL AllBulletDemos ConvexDecompositionDemo Benchmarks HelloWorld
|
SUBDIRS( OpenGL AllBulletDemos ConvexDecompositionDemo Benchmarks HelloWorld
|
||||||
CcdPhysicsDemo ConstraintDemo SliderConstraintDemo GenericJointDemo
|
CcdPhysicsDemo ConstraintDemo SliderConstraintDemo GenericJointDemo
|
||||||
RagdollDemo ForkLiftDemo BasicDemo BspDemo MovingConcaveDemo VehicleDemo
|
RagdollDemo ForkLiftDemo BasicDemo BspDemo MovingConcaveDemo VehicleDemo
|
||||||
ColladaDemo UserCollisionAlgorithm CharacterDemo SoftDemo TerrainDemo )
|
ColladaDemo UserCollisionAlgorithm CharacterDemo SoftDemo TerrainDemo HeightFieldFluidDemo)
|
||||||
else (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
else (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||||
SUBDIRS( OpenGL AllBulletDemos ConvexDecompositionDemo Benchmarks HelloWorld
|
SUBDIRS( OpenGL AllBulletDemos ConvexDecompositionDemo Benchmarks HelloWorld
|
||||||
MultiThreadedDemo CcdPhysicsDemo ConstraintDemo SliderConstraintDemo
|
MultiThreadedDemo CcdPhysicsDemo ConstraintDemo SliderConstraintDemo
|
||||||
GenericJointDemo RagdollDemo ForkLiftDemo BasicDemo BspDemo MovingConcaveDemo
|
GenericJointDemo RagdollDemo ForkLiftDemo BasicDemo BspDemo MovingConcaveDemo
|
||||||
VehicleDemo ColladaDemo UserCollisionAlgorithm CharacterDemo SoftDemo
|
VehicleDemo ColladaDemo UserCollisionAlgorithm CharacterDemo SoftDemo
|
||||||
TerrainDemo )
|
TerrainDemo HeightFieldFluidDemo)
|
||||||
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ void CollisionDemo::displayCallback(void) {
|
|||||||
|
|
||||||
tr[i].getOpenGLMatrix( m );
|
tr[i].getOpenGLMatrix( m );
|
||||||
|
|
||||||
m_shapeDrawer.drawOpenGL(m,shapePtr[i],btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,shapePtr[i],btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ void CollisionDemo::displayCallback(void) {
|
|||||||
btTransform ident;
|
btTransform ident;
|
||||||
ident.setIdentity();
|
ident.setIdentity();
|
||||||
ident.getOpenGLMatrix(m);
|
ident.getOpenGLMatrix(m);
|
||||||
m_shapeDrawer.drawOpenGL(m,&simplex,btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,&simplex,btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
|
|
||||||
btQuaternion orn;
|
btQuaternion orn;
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ void CollisionInterfaceDemo::displayCallback(void) {
|
|||||||
{
|
{
|
||||||
|
|
||||||
objects[i].getWorldTransform().getOpenGLMatrix( m );
|
objects[i].getWorldTransform().getOpenGLMatrix( m );
|
||||||
m_shapeDrawer.drawOpenGL(m,objects[i].getCollisionShape(),btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,objects[i].getCollisionShape(),btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ void btContinuousConvexCollisionDemo::displayCallback(void) {
|
|||||||
//m_shapeDrawer.drawOpenGL(m,shapePtr[i]);
|
//m_shapeDrawer.drawOpenGL(m,shapePtr[i]);
|
||||||
|
|
||||||
interpolatedTrans.getOpenGLMatrix( m );
|
interpolatedTrans.getOpenGLMatrix( m );
|
||||||
m_shapeDrawer.drawOpenGL(m,shapePtr[i],btVector3(1,0,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,shapePtr[i],btVector3(1,0,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,10 +231,10 @@ void btContinuousConvexCollisionDemo::displayCallback(void) {
|
|||||||
for (i=0;i<numObjects;i++)
|
for (i=0;i<numObjects;i++)
|
||||||
{
|
{
|
||||||
fromTrans[i].getOpenGLMatrix(m);
|
fromTrans[i].getOpenGLMatrix(m);
|
||||||
m_shapeDrawer.drawOpenGL(m,shapePtr[i],btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,shapePtr[i],btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
btDebugCastResult rayResult1(fromTrans[0],shapePtr[0],linVels[0],angVels[0],&m_shapeDrawer);
|
btDebugCastResult rayResult1(fromTrans[0],shapePtr[0],linVels[0],angVels[0],m_shapeDrawer);
|
||||||
|
|
||||||
|
|
||||||
for (i=1;i<numObjects;i++)
|
for (i=1;i<numObjects;i++)
|
||||||
@@ -269,12 +269,12 @@ void btContinuousConvexCollisionDemo::displayCallback(void) {
|
|||||||
btTransformUtil::integrateTransform(fromTrans[0],linVels[0],angVels[0],rayResultPtr->m_fraction,hitTrans);
|
btTransformUtil::integrateTransform(fromTrans[0],linVels[0],angVels[0],rayResultPtr->m_fraction,hitTrans);
|
||||||
|
|
||||||
hitTrans.getOpenGLMatrix(m);
|
hitTrans.getOpenGLMatrix(m);
|
||||||
m_shapeDrawer.drawOpenGL(m,shapePtr[0],btVector3(0,1,0),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,shapePtr[0],btVector3(0,1,0),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
btTransformUtil::integrateTransform(fromTrans[i],linVels[i],angVels[i],rayResultPtr->m_fraction,hitTrans);
|
btTransformUtil::integrateTransform(fromTrans[i],linVels[i],angVels[i],rayResultPtr->m_fraction,hitTrans);
|
||||||
|
|
||||||
hitTrans.getOpenGLMatrix(m);
|
hitTrans.getOpenGLMatrix(m);
|
||||||
m_shapeDrawer.drawOpenGL(m,shapePtr[i],btVector3(0,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,shapePtr[i],btVector3(0,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,278 +1,278 @@
|
|||||||
/*
|
/*
|
||||||
Bullet Continuous Collision Detection and Physics Library
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied warranty.
|
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.
|
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,
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
including commercial applications, and to alter it and redistribute it freely,
|
including commercial applications, and to alter it and redistribute it freely,
|
||||||
subject to the following restrictions:
|
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.
|
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.
|
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.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// DoublePrecisionDemo shows high level usage of the Collision Detection.
|
/// DoublePrecisionDemo shows high level usage of the Collision Detection.
|
||||||
///
|
///
|
||||||
|
|
||||||
#include "GL_Simplex1to4.h"
|
#include "GL_Simplex1to4.h"
|
||||||
|
|
||||||
//include common Bullet Collision Detection headerfiles
|
//include common Bullet Collision Detection headerfiles
|
||||||
#include "btBulletCollisionCommon.h"
|
#include "btBulletCollisionCommon.h"
|
||||||
|
|
||||||
#include "LinearMath/btIDebugDraw.h"
|
#include "LinearMath/btIDebugDraw.h"
|
||||||
#include "BMF_Api.h"
|
#include "BMF_Api.h"
|
||||||
#include "GL_ShapeDrawer.h"
|
#include "GL_ShapeDrawer.h"
|
||||||
#include "DoublePrecisionDemo.h"
|
#include "DoublePrecisionDemo.h"
|
||||||
#include "GlutStuff.h"
|
#include "GlutStuff.h"
|
||||||
#include "GLDebugDrawer.h"
|
#include "GLDebugDrawer.h"
|
||||||
|
|
||||||
btScalar yaw=btScalar(0.);
|
btScalar yaw=btScalar(0.);
|
||||||
btScalar pitch=btScalar(0.);
|
btScalar pitch=btScalar(0.);
|
||||||
btScalar roll=btScalar(0.);
|
btScalar roll=btScalar(0.);
|
||||||
const int maxNumObjects = 4;
|
const int maxNumObjects = 4;
|
||||||
const int numObjects = 2;
|
const int numObjects = 2;
|
||||||
|
|
||||||
GL_Simplex1to4 simplex;
|
GL_Simplex1to4 simplex;
|
||||||
|
|
||||||
|
|
||||||
btCollisionObject objects[maxNumObjects];
|
btCollisionObject objects[maxNumObjects];
|
||||||
btCollisionWorld* collisionWorld = 0;
|
btCollisionWorld* collisionWorld = 0;
|
||||||
|
|
||||||
// so pixel ratio is 1:1
|
// so pixel ratio is 1:1
|
||||||
int screenWidth = 640;
|
int screenWidth = 640;
|
||||||
int screenHeight = 640;
|
int screenHeight = 640;
|
||||||
GLDebugDrawer debugDrawer;
|
GLDebugDrawer debugDrawer;
|
||||||
|
|
||||||
const btScalar LARGE_DISTANCE_FROM_ORIGIN = btScalar(999999.0);
|
const btScalar LARGE_DISTANCE_FROM_ORIGIN = btScalar(999999.0);
|
||||||
const btScalar VERY_SMALL_INCREMENT = btScalar(0.000009);
|
const btScalar VERY_SMALL_INCREMENT = btScalar(0.000009);
|
||||||
|
|
||||||
int main(int argc,char** argv)
|
int main(int argc,char** argv)
|
||||||
{
|
{
|
||||||
DoublePrecisionDemo* doublePrecisionDemo = new DoublePrecisionDemo();
|
DoublePrecisionDemo* doublePrecisionDemo = new DoublePrecisionDemo();
|
||||||
|
|
||||||
doublePrecisionDemo->initPhysics();
|
doublePrecisionDemo->initPhysics();
|
||||||
doublePrecisionDemo->setCameraDistance(btScalar(2.0));
|
doublePrecisionDemo->setCameraDistance(btScalar(2.0));
|
||||||
|
|
||||||
doublePrecisionDemo->clientResetScene();
|
doublePrecisionDemo->clientResetScene();
|
||||||
|
|
||||||
return glutmain(argc, argv,screenWidth,screenHeight,"Double Precision Demo",doublePrecisionDemo);
|
return glutmain(argc, argv,screenWidth,screenHeight,"Double Precision Demo",doublePrecisionDemo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoublePrecisionDemo::initPhysics()
|
void DoublePrecisionDemo::initPhysics()
|
||||||
{
|
{
|
||||||
m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
|
m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
|
||||||
|
|
||||||
btMatrix3x3 basisA;
|
btMatrix3x3 basisA;
|
||||||
basisA.setIdentity();
|
basisA.setIdentity();
|
||||||
|
|
||||||
btMatrix3x3 basisB;
|
btMatrix3x3 basisB;
|
||||||
basisB.setIdentity();
|
basisB.setIdentity();
|
||||||
|
|
||||||
objects[0].getWorldTransform().setBasis(basisA);
|
objects[0].getWorldTransform().setBasis(basisA);
|
||||||
objects[1].getWorldTransform().setBasis(basisB);
|
objects[1].getWorldTransform().setBasis(basisB);
|
||||||
|
|
||||||
|
|
||||||
btBoxShape* boxA = new btBoxShape(btVector3(0.5,0.5,0.5));
|
btBoxShape* boxA = new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||||
btBoxShape* boxB = new btBoxShape(btVector3(0.5,0.5,0.5));
|
btBoxShape* boxB = new btBoxShape(btVector3(0.5,0.5,0.5));
|
||||||
|
|
||||||
objects[0].setCollisionShape(boxA);//&hullA;
|
objects[0].setCollisionShape(boxA);//&hullA;
|
||||||
objects[1].setCollisionShape(boxB);//&hullB;
|
objects[1].setCollisionShape(boxB);//&hullB;
|
||||||
|
|
||||||
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
|
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||||
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
|
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
|
||||||
btVector3 worldAabbMin(80000,80000,80000);
|
btVector3 worldAabbMin(80000,80000,80000);
|
||||||
btVector3 worldAabbMax(120000,120000,120000);
|
btVector3 worldAabbMax(120000,120000,120000);
|
||||||
|
|
||||||
btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax);
|
btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax);
|
||||||
|
|
||||||
collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
|
collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
|
||||||
|
|
||||||
collisionWorld->addCollisionObject(&objects[0]);
|
collisionWorld->addCollisionObject(&objects[0]);
|
||||||
collisionWorld->addCollisionObject(&objects[1]);
|
collisionWorld->addCollisionObject(&objects[1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//to be implemented by the demo
|
//to be implemented by the demo
|
||||||
|
|
||||||
void DoublePrecisionDemo::clientMoveAndDisplay()
|
void DoublePrecisionDemo::clientMoveAndDisplay()
|
||||||
{
|
{
|
||||||
|
|
||||||
displayCallback();
|
displayCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static btVoronoiSimplexSolver sGjkSimplexSolver;
|
static btVoronoiSimplexSolver sGjkSimplexSolver;
|
||||||
btSimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver;
|
btSimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver;
|
||||||
|
|
||||||
void DoublePrecisionDemo::displayCallback(void)
|
void DoublePrecisionDemo::displayCallback(void)
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
collisionWorld->getDispatchInfo().m_debugDraw = &debugDrawer;
|
collisionWorld->getDispatchInfo().m_debugDraw = &debugDrawer;
|
||||||
|
|
||||||
if (collisionWorld)
|
if (collisionWorld)
|
||||||
collisionWorld->performDiscreteCollisionDetection();
|
collisionWorld->performDiscreteCollisionDetection();
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
btVector3 worldBoundsMin,worldBoundsMax;
|
btVector3 worldBoundsMin,worldBoundsMax;
|
||||||
collisionWorld->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax);
|
collisionWorld->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
|
|
||||||
///one way to draw all the contact points is iterating over contact manifolds / points:
|
///one way to draw all the contact points is iterating over contact manifolds / points:
|
||||||
int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
|
int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
|
||||||
for (i=0;i<numManifolds;i++)
|
for (i=0;i<numManifolds;i++)
|
||||||
{
|
{
|
||||||
btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
|
btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
|
||||||
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
|
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
|
||||||
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
|
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
|
||||||
contactManifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTransform());
|
contactManifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTransform());
|
||||||
|
|
||||||
int numContacts = contactManifold->getNumContacts();
|
int numContacts = contactManifold->getNumContacts();
|
||||||
for (int j=0;j<numContacts;j++)
|
for (int j=0;j<numContacts;j++)
|
||||||
{
|
{
|
||||||
btManifoldPoint& pt = contactManifold->getContactPoint(j);
|
btManifoldPoint& pt = contactManifold->getContactPoint(j);
|
||||||
|
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glColor3f(1, 1, 1);
|
glColor3f(1, 1, 1);
|
||||||
|
|
||||||
btVector3 ptA = pt.getPositionWorldOnA() - m_cameraPosition;
|
btVector3 ptA = pt.getPositionWorldOnA() - m_cameraPosition;
|
||||||
btVector3 ptB = pt.getPositionWorldOnB() - m_cameraPosition;
|
btVector3 ptB = pt.getPositionWorldOnB() - m_cameraPosition;
|
||||||
|
|
||||||
glVertex3d(ptA.x(),ptA.y(),ptA.z());
|
glVertex3d(ptA.x(),ptA.y(),ptA.z());
|
||||||
glVertex3d(ptB.x(),ptB.y(),ptB.z());
|
glVertex3d(ptB.x(),ptB.y(),ptB.z());
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
//you can un-comment out this line, and then all points are removed
|
//you can un-comment out this line, and then all points are removed
|
||||||
//contactManifold->clearManifold();
|
//contactManifold->clearManifold();
|
||||||
}
|
}
|
||||||
|
|
||||||
btScalar m[16];
|
btScalar m[16];
|
||||||
btTransform temp;
|
btTransform temp;
|
||||||
|
|
||||||
|
|
||||||
btVector3 color;
|
btVector3 color;
|
||||||
//int i;
|
//int i;
|
||||||
for (i=0;i<numObjects;i++)
|
for (i=0;i<numObjects;i++)
|
||||||
{
|
{
|
||||||
if (i % 2)
|
if (i % 2)
|
||||||
{
|
{
|
||||||
color = btVector3(1,0,0);
|
color = btVector3(1,0,0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
color = btVector3(0,0,1);
|
color = btVector3(0,0,1);
|
||||||
}
|
}
|
||||||
temp = objects[i].getWorldTransform();
|
temp = objects[i].getWorldTransform();
|
||||||
temp.setOrigin(temp.getOrigin() - m_cameraPosition);
|
temp.setOrigin(temp.getOrigin() - m_cameraPosition);
|
||||||
temp.getOpenGLMatrix( m );
|
temp.getOpenGLMatrix( m );
|
||||||
m_shapeDrawer.drawOpenGL(m,objects[i].getCollisionShape(),color,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,objects[i].getCollisionShape(),color,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
objects[1].getWorldTransform().setOrigin(objects[1].getWorldTransform().getOrigin()+btVector3(-VERY_SMALL_INCREMENT,-VERY_SMALL_INCREMENT,0));
|
objects[1].getWorldTransform().setOrigin(objects[1].getWorldTransform().getOrigin()+btVector3(-VERY_SMALL_INCREMENT,-VERY_SMALL_INCREMENT,0));
|
||||||
objects[0].getWorldTransform().setOrigin(objects[0].getWorldTransform().getOrigin()+btVector3(VERY_SMALL_INCREMENT,VERY_SMALL_INCREMENT,0));
|
objects[0].getWorldTransform().setOrigin(objects[0].getWorldTransform().getOrigin()+btVector3(VERY_SMALL_INCREMENT,VERY_SMALL_INCREMENT,0));
|
||||||
|
|
||||||
float yStart = 20.f;
|
float yStart = 20.f;
|
||||||
float yIncr = 20.f;
|
float yIncr = 20.f;
|
||||||
char buf[124];
|
char buf[124];
|
||||||
|
|
||||||
glColor3f(0, 0, 0);
|
glColor3f(0, 0, 0);
|
||||||
|
|
||||||
setOrthographicProjection();
|
setOrthographicProjection();
|
||||||
|
|
||||||
glRasterPos3f(10.0f,yStart,0);
|
glRasterPos3f(10.0f,yStart,0);
|
||||||
#ifdef BT_USE_DOUBLE_PRECISION
|
#ifdef BT_USE_DOUBLE_PRECISION
|
||||||
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),"Double Precision Mode");
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),"Double Precision Mode");
|
||||||
#else
|
#else
|
||||||
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),"Single Precision Mode");
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),"Single Precision Mode");
|
||||||
#endif
|
#endif
|
||||||
yStart += yIncr;
|
yStart += yIncr;
|
||||||
|
|
||||||
glRasterPos3f(10.0f,yStart,0);
|
glRasterPos3f(10.0f,yStart,0);
|
||||||
sprintf(buf,"Movement distance in x and y axis = %lf", VERY_SMALL_INCREMENT);
|
sprintf(buf,"Movement distance in x and y axis = %lf", VERY_SMALL_INCREMENT);
|
||||||
|
|
||||||
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
||||||
yStart += yIncr;
|
yStart += yIncr;
|
||||||
|
|
||||||
glRasterPos3f(10.0f,yStart,0);
|
glRasterPos3f(10.0f,yStart,0);
|
||||||
btScalar xValue = objects[0].getWorldTransform().getOrigin().x();
|
btScalar xValue = objects[0].getWorldTransform().getOrigin().x();
|
||||||
btScalar yValue = objects[0].getWorldTransform().getOrigin().y();
|
btScalar yValue = objects[0].getWorldTransform().getOrigin().y();
|
||||||
btScalar zValue = objects[0].getWorldTransform().getOrigin().z();
|
btScalar zValue = objects[0].getWorldTransform().getOrigin().z();
|
||||||
sprintf(buf,"Cube 0 location = ( %lf, %lf, %lf )", xValue, yValue, zValue);
|
sprintf(buf,"Cube 0 location = ( %lf, %lf, %lf )", xValue, yValue, zValue);
|
||||||
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
||||||
yStart += yIncr;
|
yStart += yIncr;
|
||||||
|
|
||||||
xValue = objects[1].getWorldTransform().getOrigin().x();
|
xValue = objects[1].getWorldTransform().getOrigin().x();
|
||||||
yValue = objects[1].getWorldTransform().getOrigin().y();
|
yValue = objects[1].getWorldTransform().getOrigin().y();
|
||||||
zValue = objects[1].getWorldTransform().getOrigin().z();
|
zValue = objects[1].getWorldTransform().getOrigin().z();
|
||||||
glRasterPos3f(10.0f,yStart,0);
|
glRasterPos3f(10.0f,yStart,0);
|
||||||
sprintf(buf,"Cube 1 location = ( %lf, %lf, %lf )", xValue, yValue, zValue);
|
sprintf(buf,"Cube 1 location = ( %lf, %lf, %lf )", xValue, yValue, zValue);
|
||||||
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
||||||
yStart += yIncr;
|
yStart += yIncr;
|
||||||
|
|
||||||
glRasterPos3f(10.0f,yStart,0);
|
glRasterPos3f(10.0f,yStart,0);
|
||||||
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),"w=toggle wireframe/solid");
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),"w=toggle wireframe/solid");
|
||||||
|
|
||||||
resetPerspectiveProjection();
|
resetPerspectiveProjection();
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoublePrecisionDemo::clientResetScene()
|
void DoublePrecisionDemo::clientResetScene()
|
||||||
{
|
{
|
||||||
objects[0].getWorldTransform().setOrigin(btVector3(LARGE_DISTANCE_FROM_ORIGIN,LARGE_DISTANCE_FROM_ORIGIN,LARGE_DISTANCE_FROM_ORIGIN));
|
objects[0].getWorldTransform().setOrigin(btVector3(LARGE_DISTANCE_FROM_ORIGIN,LARGE_DISTANCE_FROM_ORIGIN,LARGE_DISTANCE_FROM_ORIGIN));
|
||||||
objects[1].getWorldTransform().setOrigin(btVector3(LARGE_DISTANCE_FROM_ORIGIN-VERY_SMALL_INCREMENT,LARGE_DISTANCE_FROM_ORIGIN-VERY_SMALL_INCREMENT,LARGE_DISTANCE_FROM_ORIGIN));
|
objects[1].getWorldTransform().setOrigin(btVector3(LARGE_DISTANCE_FROM_ORIGIN-VERY_SMALL_INCREMENT,LARGE_DISTANCE_FROM_ORIGIN-VERY_SMALL_INCREMENT,LARGE_DISTANCE_FROM_ORIGIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DoublePrecisionDemo::updateCamera()
|
void DoublePrecisionDemo::updateCamera()
|
||||||
{
|
{
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
// look at the stationary cube
|
// look at the stationary cube
|
||||||
m_cameraTargetPosition = objects[0].getWorldTransform().getOrigin();
|
m_cameraTargetPosition = objects[0].getWorldTransform().getOrigin();
|
||||||
|
|
||||||
m_cameraPosition = m_cameraTargetPosition;
|
m_cameraPosition = m_cameraTargetPosition;
|
||||||
m_cameraPosition[2] = m_cameraTargetPosition[2] - m_cameraDistance;
|
m_cameraPosition[2] = m_cameraTargetPosition[2] - m_cameraDistance;
|
||||||
|
|
||||||
//update OpenGL camera settings
|
//update OpenGL camera settings
|
||||||
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0);
|
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0);
|
||||||
|
|
||||||
// To not loose precision in the rendering process, we shift the object to the origin
|
// To not loose precision in the rendering process, we shift the object to the origin
|
||||||
gluLookAt(0.0, 0.0, 0.0,
|
gluLookAt(0.0, 0.0, 0.0,
|
||||||
m_cameraTargetPosition[0]-m_cameraPosition[0],m_cameraTargetPosition[1]-m_cameraPosition[1], m_cameraTargetPosition[2]-m_cameraPosition[2],
|
m_cameraTargetPosition[0]-m_cameraPosition[0],m_cameraTargetPosition[1]-m_cameraPosition[1], m_cameraTargetPosition[2]-m_cameraPosition[2],
|
||||||
m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ());
|
m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ());
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoublePrecisionDemo::keyboardCallback(unsigned char key, int x, int y)
|
void DoublePrecisionDemo::keyboardCallback(unsigned char key, int x, int y)
|
||||||
{
|
{
|
||||||
if (key == 'w')
|
if (key == 'w')
|
||||||
{
|
{
|
||||||
if (m_debugMode & btIDebugDraw::DBG_DrawWireframe)
|
if (m_debugMode & btIDebugDraw::DBG_DrawWireframe)
|
||||||
{
|
{
|
||||||
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe);
|
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe);
|
||||||
m_debugMode |= btIDebugDraw::DBG_DrawAabb;
|
m_debugMode |= btIDebugDraw::DBG_DrawAabb;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb);
|
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb);
|
||||||
m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
|
m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DemoApplication::keyboardCallback(key, x, y);
|
DemoApplication::keyboardCallback(key, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -433,7 +433,7 @@ void ForkLiftDemo::renderme()
|
|||||||
m_vehicle->updateWheelTransform(i,true);
|
m_vehicle->updateWheelTransform(i,true);
|
||||||
//draw wheels (cylinders)
|
//draw wheels (cylinders)
|
||||||
m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m);
|
m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m);
|
||||||
m_shapeDrawer.drawOpenGL(m,&wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,&wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ void GimpactConcaveDemo::renderme()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -158,11 +158,11 @@ void LinearConvexCastDemo::displayCallback(void)
|
|||||||
btTransform tmp = tr[0];
|
btTransform tmp = tr[0];
|
||||||
tmp.setOrigin(result.m_hitPoint);
|
tmp.setOrigin(result.m_hitPoint);
|
||||||
tmp.getOpenGLMatrix(m3);
|
tmp.getOpenGLMatrix(m3);
|
||||||
m_shapeDrawer.drawOpenGL( m3, &sphere, btVector3( 1, 0, 1 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL( m3, &sphere, btVector3( 1, 0, 1 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
|
|
||||||
m_shapeDrawer.drawOpenGL( m1, shapePtr[ 0 ], btVector3( 1, 0, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL( m1, shapePtr[ 0 ], btVector3( 1, 0, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
||||||
m_shapeDrawer.drawOpenGL( m2, shapePtr[ 1 ], btVector3( 1, 0, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL( m2, shapePtr[ 1 ], btVector3( 1, 0, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
btVector3 originA, originB;
|
btVector3 originA, originB;
|
||||||
originA.setInterpolate3( tr[ 0 ].getOrigin(), toA.getOrigin(), result.m_fraction );
|
originA.setInterpolate3( tr[ 0 ].getOrigin(), toA.getOrigin(), result.m_fraction );
|
||||||
@@ -177,8 +177,8 @@ void LinearConvexCastDemo::displayCallback(void)
|
|||||||
A.getOpenGLMatrix( m1 );
|
A.getOpenGLMatrix( m1 );
|
||||||
B.getOpenGLMatrix( m2 );
|
B.getOpenGLMatrix( m2 );
|
||||||
|
|
||||||
m_shapeDrawer.drawOpenGL( m1, shapePtr[ 0 ], btVector3( 1, 1, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL( m1, shapePtr[ 0 ], btVector3( 1, 1, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
||||||
m_shapeDrawer.drawOpenGL( m2, shapePtr[ 1 ], btVector3( 1, 1, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL( m2, shapePtr[ 1 ], btVector3( 1, 1, 0 ), getDebugMode() ,worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
|
|||||||
1017
Demos/HeightFieldFluidDemo/BulletHfFluid/btHfFluid.cpp
Normal file
1017
Demos/HeightFieldFluidDemo/BulletHfFluid/btHfFluid.cpp
Normal file
File diff suppressed because it is too large
Load Diff
224
Demos/HeightFieldFluidDemo/BulletHfFluid/btHfFluid.h
Normal file
224
Demos/HeightFieldFluidDemo/BulletHfFluid/btHfFluid.h
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
#ifndef __HFFLUID_H
|
||||||
|
#define __HFFLUID_H
|
||||||
|
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
|
||||||
|
|
||||||
|
class btPersistentManifold;
|
||||||
|
class btManifoldResult;
|
||||||
|
|
||||||
|
// FIX AABB calculation for whole btHfFluid shape
|
||||||
|
// Fix flags and fill ratio
|
||||||
|
// -> Figure out the constants used in flags and fill ratio code
|
||||||
|
// Fix volume removal
|
||||||
|
// add buoyant convex vs. convex / concave
|
||||||
|
// add buoyant concave support (try bunny model)
|
||||||
|
|
||||||
|
class btHfFluid : public btCollisionObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
btHfFluid (btScalar gridCellWidth, int numNodesWidth, int numNodesLength);
|
||||||
|
|
||||||
|
~btHfFluid ();
|
||||||
|
|
||||||
|
void predictMotion(btScalar dt);
|
||||||
|
|
||||||
|
/* Prep does some initial setup of the height field fluid.
|
||||||
|
* You should call this at initialization time.
|
||||||
|
*/
|
||||||
|
void prep ();
|
||||||
|
|
||||||
|
static const btHfFluid* upcast(const btCollisionObject* colObj)
|
||||||
|
{
|
||||||
|
if (colObj->getInternalType()==CO_HF_FLUID)
|
||||||
|
return (const btHfFluid*)colObj;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static btHfFluid* upcast(btCollisionObject* colObj)
|
||||||
|
{
|
||||||
|
if (colObj->getInternalType()==CO_HF_FLUID)
|
||||||
|
return (btHfFluid*)colObj;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ::btCollisionObject
|
||||||
|
//
|
||||||
|
|
||||||
|
virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
|
||||||
|
{
|
||||||
|
aabbMin = m_aabbMin;
|
||||||
|
aabbMax = m_aabbMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getNumNodesWidth () const { return m_numNodesWidth; }
|
||||||
|
int getNumNodesLength () const { return m_numNodesLength; }
|
||||||
|
|
||||||
|
btScalar getGridCellWidth () const { return m_gridCellWidth; }
|
||||||
|
btScalar widthPos (int i) const;
|
||||||
|
btScalar lengthPos (int j) const;
|
||||||
|
|
||||||
|
int arrayIndex (int i, int j) const;
|
||||||
|
int arrayIndex (btScalar i, btScalar j) const;
|
||||||
|
int arrayIndex (unsigned int i, unsigned int j) const;
|
||||||
|
const btScalar* getHeightArray () const;
|
||||||
|
const btScalar* getGroundArray () const;
|
||||||
|
const btScalar* getEtaArray () const;
|
||||||
|
const btScalar* getVelocityUArray () const;
|
||||||
|
const btScalar* getVelocityVArray () const;
|
||||||
|
const bool* getFlagsArray () const;
|
||||||
|
|
||||||
|
void setFluidHeight (int x, int y, btScalar height);
|
||||||
|
void setFluidHeight (int index, btScalar height);
|
||||||
|
|
||||||
|
void addFluidHeight (int x, int y, btScalar height);
|
||||||
|
void addDisplaced (int i, int j, btScalar r);
|
||||||
|
|
||||||
|
void getAabbForColumn (int x, int y, btVector3& aabbMin, btVector3& aabbMax);
|
||||||
|
|
||||||
|
btScalar* getHeightArray ();
|
||||||
|
btScalar* getGroundArray ();
|
||||||
|
btScalar* getEtaArray ();
|
||||||
|
btScalar* getVelocityUArray ();
|
||||||
|
btScalar* getVelocityVArray ();
|
||||||
|
bool* getFlagsArray ();
|
||||||
|
|
||||||
|
void foreachGroundTriangle(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax);
|
||||||
|
class btHfFluidColumnCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
btHfFluidColumnCallback () {}
|
||||||
|
|
||||||
|
virtual ~btHfFluidColumnCallback () {}
|
||||||
|
|
||||||
|
virtual bool processColumn (btHfFluid* fluid, int w, int l)
|
||||||
|
{
|
||||||
|
return true; // keep going
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void foreachFluidColumn (btHfFluidColumnCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax);
|
||||||
|
|
||||||
|
void foreachSurfaceTriangle (btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax);
|
||||||
|
protected:
|
||||||
|
int m_numNodesWidth;
|
||||||
|
int m_numNodesLength;
|
||||||
|
|
||||||
|
btScalar m_gridCellWidth;
|
||||||
|
btScalar m_gridWidth;
|
||||||
|
btScalar m_gridLength;
|
||||||
|
|
||||||
|
btScalar m_gridCellWidthInv;
|
||||||
|
|
||||||
|
btVector3 m_aabbMin;
|
||||||
|
btVector3 m_aabbMax;
|
||||||
|
|
||||||
|
void setGridDimensions (btScalar gridCellWidth,
|
||||||
|
int numNodesWidth, int numNodesLength);
|
||||||
|
|
||||||
|
btScalar bilinearInterpolate (const btScalar* array, btScalar i, btScalar j);
|
||||||
|
|
||||||
|
btScalar advect (const btScalar* array, btScalar i, btScalar j, btScalar di, btScalar dj, btScalar dt);
|
||||||
|
|
||||||
|
void advectEta (btScalar dt);
|
||||||
|
void updateHeight (btScalar dt);
|
||||||
|
|
||||||
|
void advectVelocityU (btScalar dt);
|
||||||
|
void advectVelocityV (btScalar dt);
|
||||||
|
void updateVelocity (btScalar dt);
|
||||||
|
|
||||||
|
void transferDisplaced (btScalar dt);
|
||||||
|
|
||||||
|
void setReflectBoundaryLeft ();
|
||||||
|
void setReflectBoundaryRight ();
|
||||||
|
void setReflectBoundaryTop ();
|
||||||
|
void setReflectBoundaryBottom ();
|
||||||
|
|
||||||
|
void setAbsorbBoundaryLeft (btScalar dt);
|
||||||
|
void setAbsorbBoundaryRight (btScalar dt);
|
||||||
|
void setAbsorbBoundaryTop (btScalar dt);
|
||||||
|
void setAbsorbBoundaryBottom (btScalar dt);
|
||||||
|
|
||||||
|
void computeFlagsAndFillRatio ();
|
||||||
|
btScalar computeHmin (int i, int j);
|
||||||
|
btScalar computeHmax (int i, int j);
|
||||||
|
btScalar computeEtaMax (int i, int j);
|
||||||
|
|
||||||
|
void allocateArrays ();
|
||||||
|
|
||||||
|
void debugTests ();
|
||||||
|
|
||||||
|
btScalar* m_temp; // temp
|
||||||
|
int m_heightIndex;
|
||||||
|
btScalar* m_height[2];
|
||||||
|
btScalar* m_ground;
|
||||||
|
btScalar* m_eta; // height - ground
|
||||||
|
btScalar* m_u[2];
|
||||||
|
btScalar* m_v[2];
|
||||||
|
int m_rIndex;
|
||||||
|
btScalar* m_r[2];
|
||||||
|
int m_velocityIndex;
|
||||||
|
bool* m_flags;
|
||||||
|
btScalar* m_fillRatio;
|
||||||
|
|
||||||
|
// tweakables
|
||||||
|
btScalar m_globalVelocityU;
|
||||||
|
btScalar m_globalVelocityV;
|
||||||
|
btScalar m_gravity;
|
||||||
|
btScalar m_volumeDisplacementScale;
|
||||||
|
btScalar m_horizontalVelocityScale;
|
||||||
|
|
||||||
|
btScalar m_epsHeight;
|
||||||
|
btScalar m_epsEta;
|
||||||
|
public:
|
||||||
|
// You can enforce a global velocity at the surface of the fluid
|
||||||
|
// default: 0.0 and 0.0
|
||||||
|
void setGlobaVelocity (btScalar globalVelocityU, btScalar globalVelocityV);
|
||||||
|
void getGlobalVelocity (btScalar& globalVelocityU, btScalar& globalVelocityV) const;
|
||||||
|
|
||||||
|
// Control force of gravity, should match physics world
|
||||||
|
// default: -10.0
|
||||||
|
void setGravity (btScalar gravity);
|
||||||
|
btScalar getGravity () const;
|
||||||
|
|
||||||
|
// When a body is submerged into the fluid, the displaced fluid
|
||||||
|
// is spread to adjacent cells. You can control the percentage of this
|
||||||
|
// by setting this value between 0.0 and 1.0
|
||||||
|
// default: 0.5
|
||||||
|
void setVolumeDisplacementScale (btScalar volumeDisplacementScale);
|
||||||
|
btScalar getVolumeDisplacementScale () const;
|
||||||
|
|
||||||
|
// The horizontal velocity of the fluid can influence bodies submerged
|
||||||
|
// in the fluid. You can control how much influence by setting this
|
||||||
|
// between 0.0 and 1.0
|
||||||
|
// default: 0.5
|
||||||
|
void setHorizontalVelocityScale (btScalar horizontalVelocityScale);
|
||||||
|
btScalar getHorizontalVelocityScale () const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class btRigidBody;
|
||||||
|
class btIDebugDraw;
|
||||||
|
class btHfFluidBuoyantConvexShape;
|
||||||
|
|
||||||
|
class btHfFluidColumnRigidBodyCallback : public btHfFluid::btHfFluidColumnCallback
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
btRigidBody* m_rigidBody;
|
||||||
|
btHfFluidBuoyantConvexShape* m_buoyantShape;
|
||||||
|
btIDebugDraw* m_debugDraw;
|
||||||
|
int m_numVoxels;
|
||||||
|
btVector3 m_voxelPositionsXformed[32*32*32];
|
||||||
|
bool m_voxelSubmerged[32*32*32];
|
||||||
|
btVector3 m_aabbMin;
|
||||||
|
btVector3 m_aabbMax;
|
||||||
|
btScalar m_volume;
|
||||||
|
btScalar m_density;
|
||||||
|
btScalar m_floatyness;
|
||||||
|
public:
|
||||||
|
btHfFluidColumnRigidBodyCallback (btRigidBody* rigidBody, btIDebugDraw* debugDraw, btScalar density, btScalar floatyness);
|
||||||
|
bool processColumn (btHfFluid* fluid, int w, int l);
|
||||||
|
btScalar getVolume () const { return m_volume; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "LinearMath/btAabbUtil2.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||||
|
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
|
||||||
|
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
|
||||||
|
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
|
||||||
|
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
|
||||||
|
|
||||||
|
#include "BulletHfFluid/btHfFluidBuoyantConvexShape.h"
|
||||||
|
|
||||||
|
btHfFluidBuoyantConvexShape::btHfFluidBuoyantConvexShape (btConvexShape* convexShape)
|
||||||
|
{
|
||||||
|
m_convexShape = convexShape;
|
||||||
|
m_shapeType = HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE;
|
||||||
|
m_radius = btScalar(0.f);
|
||||||
|
m_totalVolume = btScalar(0.0f);
|
||||||
|
m_floatyness = btScalar(1.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidBuoyantConvexShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
|
||||||
|
{
|
||||||
|
return m_convexShape->getAabb (t, aabbMin, aabbMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidBuoyantConvexShape::setMargin(btScalar margin)
|
||||||
|
{
|
||||||
|
m_convexShape->setMargin (margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidBuoyantConvexShape::setLocalScaling(const btVector3& scaling)
|
||||||
|
{
|
||||||
|
m_convexShape->setLocalScaling (scaling);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* btHfFluidBuoyantConvexShape::getName() const
|
||||||
|
{
|
||||||
|
return "HF_FLUID_BUOYANT_CONVEX_SHAPE";
|
||||||
|
}
|
||||||
|
|
||||||
|
const btVector3& btHfFluidBuoyantConvexShape::getLocalScaling() const
|
||||||
|
{
|
||||||
|
return m_convexShape->getLocalScaling();
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidBuoyantConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
|
||||||
|
{
|
||||||
|
m_convexShape->calculateLocalInertia (mass, inertia);
|
||||||
|
}
|
||||||
|
|
||||||
|
btScalar btHfFluidBuoyantConvexShape::getMargin() const
|
||||||
|
{
|
||||||
|
return m_convexShape->getMargin();
|
||||||
|
}
|
||||||
|
|
||||||
|
//must be above the machine epsilon
|
||||||
|
#define REL_ERROR2 btScalar(1.0e-6)
|
||||||
|
static bool intersect(btVoronoiSimplexSolver* simplexSolver,
|
||||||
|
const btTransform& transformA,
|
||||||
|
const btTransform& transformB,
|
||||||
|
btConvexShape* a,
|
||||||
|
btConvexShape* b)
|
||||||
|
{
|
||||||
|
|
||||||
|
btScalar squaredDistance = SIMD_INFINITY;
|
||||||
|
btTransform localTransA = transformA;
|
||||||
|
btTransform localTransB = transformB;
|
||||||
|
btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5);
|
||||||
|
localTransA.getOrigin() -= positionOffset;
|
||||||
|
localTransB.getOrigin() -= positionOffset;
|
||||||
|
btScalar delta = btScalar(0.);
|
||||||
|
btVector3 v = btVector3(1.0f, 0.0f, 0.0f);
|
||||||
|
simplexSolver->reset ();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
btVector3 seperatingAxisInA = (-v)* transformA.getBasis();
|
||||||
|
btVector3 seperatingAxisInB = v* transformB.getBasis();
|
||||||
|
|
||||||
|
btVector3 pInA = a->localGetSupportVertexNonVirtual(seperatingAxisInA);
|
||||||
|
btVector3 qInB = b->localGetSupportVertexNonVirtual(seperatingAxisInB);
|
||||||
|
|
||||||
|
btVector3 pWorld = localTransA(pInA);
|
||||||
|
btVector3 qWorld = localTransB(qInB);
|
||||||
|
|
||||||
|
btVector3 w = pWorld - qWorld;
|
||||||
|
delta = v.dot(w);
|
||||||
|
|
||||||
|
// potential exit, they don't overlap
|
||||||
|
if ((delta > btScalar(0.0)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simplexSolver->inSimplex (w))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
simplexSolver->addVertex (w, pWorld, qWorld);
|
||||||
|
|
||||||
|
if (!simplexSolver->closest(v))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
btScalar previousSquaredDistance = squaredDistance;
|
||||||
|
squaredDistance = v.length2();
|
||||||
|
|
||||||
|
if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} while (!simplexSolver->fullSimplex() && squaredDistance > REL_ERROR2 * simplexSolver->maxVertex());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidBuoyantConvexShape::generateShape (btScalar radius, btScalar gap)
|
||||||
|
{
|
||||||
|
btTransform T;
|
||||||
|
T.setIdentity ();
|
||||||
|
btVector3 aabbMin, aabbMax;
|
||||||
|
getAabb (T, aabbMin, aabbMax);
|
||||||
|
|
||||||
|
m_radius = radius;
|
||||||
|
m_numVoxels = 0;
|
||||||
|
|
||||||
|
btVoronoiSimplexSolver simplexSolver;
|
||||||
|
btSphereShape sphereShape(radius);
|
||||||
|
for (int i = 0; i < MAX_VOXEL_DIMENSION; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < MAX_VOXEL_DIMENSION; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < MAX_VOXEL_DIMENSION; k++)
|
||||||
|
{
|
||||||
|
btVector3 point;
|
||||||
|
btTransform sT;
|
||||||
|
sT.setIdentity ();
|
||||||
|
|
||||||
|
point.setX(aabbMin.getX() + (i * btScalar(2.0f) * radius) + (i * gap));
|
||||||
|
point.setY(aabbMin.getY() + (j * btScalar(2.0f) * radius) + (j * gap));
|
||||||
|
point.setZ(aabbMin.getZ() + (k * btScalar(2.0f) * radius) + (k * gap));
|
||||||
|
|
||||||
|
if (TestPointAgainstAabb2(aabbMin, aabbMax, point))
|
||||||
|
{
|
||||||
|
btTransform sT;
|
||||||
|
sT.setIdentity ();
|
||||||
|
sT.setOrigin (point);
|
||||||
|
|
||||||
|
if (intersect (&simplexSolver, T, sT, m_convexShape, &sphereShape))
|
||||||
|
{
|
||||||
|
m_voxelPositions[m_numVoxels] = point;
|
||||||
|
m_numVoxels++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_volumePerVoxel = btScalar(4.0f)/btScalar(3.0f)*SIMD_PI*radius*radius*radius;
|
||||||
|
m_totalVolume = m_numVoxels * m_volumePerVoxel;
|
||||||
|
m_radius = radius;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef __BT_HFFLUID_BUOYANT_CONVEX_SHAPE_H
|
||||||
|
#define __BT_HFFLUID_BUOYANT_CONVEX_SHAPE_H
|
||||||
|
|
||||||
|
#include "LinearMath/btVector3.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||||
|
|
||||||
|
#define MAX_VOXEL_DIMENSION 32
|
||||||
|
|
||||||
|
class btConvexShape;
|
||||||
|
|
||||||
|
class btHfFluidBuoyantConvexShape : public btCollisionShape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
btHfFluidBuoyantConvexShape (btConvexShape* convexShape);
|
||||||
|
|
||||||
|
void generateShape (btScalar radius, btScalar gap);
|
||||||
|
|
||||||
|
btConvexShape* getConvexShape () { return m_convexShape; }
|
||||||
|
|
||||||
|
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
|
||||||
|
virtual void setMargin(btScalar margin);
|
||||||
|
virtual btScalar getMargin() const;
|
||||||
|
virtual void setLocalScaling(const btVector3& scaling);
|
||||||
|
virtual const btVector3& getLocalScaling() const;
|
||||||
|
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
|
||||||
|
virtual const char* getName()const;
|
||||||
|
|
||||||
|
btScalar getVoxelRadius () const { return m_radius; }
|
||||||
|
btScalar getTotalVolume () const { return m_totalVolume; }
|
||||||
|
btScalar getVolumePerVoxel () const { return m_volumePerVoxel; }
|
||||||
|
btScalar getFloatyness () const { return m_floatyness; }
|
||||||
|
void setFloatyness (btScalar floatyness) { m_floatyness = floatyness; }
|
||||||
|
int getNumVoxels () const { return m_numVoxels; }
|
||||||
|
const btVector3* getVoxelPositionsArray() { return m_voxelPositions; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
btScalar m_floatyness;
|
||||||
|
btScalar m_radius;
|
||||||
|
btScalar m_totalVolume;
|
||||||
|
btScalar m_volumePerVoxel;
|
||||||
|
int m_numVoxels;
|
||||||
|
btVector3 m_voxelPositions[MAX_VOXEL_DIMENSION*MAX_VOXEL_DIMENSION*MAX_VOXEL_DIMENSION];
|
||||||
|
btConvexShape* m_convexShape;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "btHfFluidBuoyantShapeCollisionAlgorithm.h"
|
||||||
|
#include "btHfFluidBuoyantConvexShape.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||||
|
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||||
|
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||||
|
#include "btHfFluid.h"
|
||||||
|
|
||||||
|
btHfFluidBuoyantShapeCollisionAlgorithm::btHfFluidBuoyantShapeCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
|
||||||
|
: btCollisionAlgorithm(ci), m_convexConvexAlgorithm(NULL, ci, col0, col1, simplexSolver, pdSolver)
|
||||||
|
{
|
||||||
|
m_collisionObject0 = col0;
|
||||||
|
m_collisionObject1 = col1;
|
||||||
|
}
|
||||||
|
|
||||||
|
btHfFluidBuoyantShapeCollisionAlgorithm::~btHfFluidBuoyantShapeCollisionAlgorithm()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidBuoyantShapeCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||||
|
{
|
||||||
|
btHfFluidBuoyantConvexShape* tmpShape0 = (btHfFluidBuoyantConvexShape*)body0->getCollisionShape();
|
||||||
|
btHfFluidBuoyantConvexShape* tmpShape1 = (btHfFluidBuoyantConvexShape*)body1->getCollisionShape();
|
||||||
|
btConvexShape* convexShape0 = tmpShape0->getConvexShape();
|
||||||
|
btConvexShape* convexShape1 = tmpShape1->getConvexShape();
|
||||||
|
|
||||||
|
body0->setCollisionShape (convexShape0);
|
||||||
|
body1->setCollisionShape (convexShape1);
|
||||||
|
|
||||||
|
m_convexConvexAlgorithm.processCollision (body0, body1, dispatchInfo,resultOut);
|
||||||
|
|
||||||
|
body0->setCollisionShape (tmpShape0);
|
||||||
|
body1->setCollisionShape (tmpShape1);
|
||||||
|
}
|
||||||
|
|
||||||
|
btScalar btHfFluidBuoyantShapeCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||||
|
{
|
||||||
|
btHfFluidBuoyantConvexShape* tmpShape0 = (btHfFluidBuoyantConvexShape*)body0->getCollisionShape();
|
||||||
|
btHfFluidBuoyantConvexShape* tmpShape1 = (btHfFluidBuoyantConvexShape*)body1->getCollisionShape();
|
||||||
|
btConvexShape* convexShape0 = tmpShape0->getConvexShape();
|
||||||
|
btConvexShape* convexShape1 = tmpShape1->getConvexShape();
|
||||||
|
|
||||||
|
body0->setCollisionShape (convexShape0);
|
||||||
|
body1->setCollisionShape (convexShape1);
|
||||||
|
|
||||||
|
btScalar toi = btScalar(0.0f);
|
||||||
|
|
||||||
|
toi = m_convexConvexAlgorithm.calculateTimeOfImpact (body0, body1, dispatchInfo, resultOut);
|
||||||
|
|
||||||
|
body0->setCollisionShape (tmpShape0);
|
||||||
|
body1->setCollisionShape (tmpShape1);
|
||||||
|
|
||||||
|
return toi;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 HF_FLUID_BUOYANT_SHAPE_COLLISION_ALGORITHM_H
|
||||||
|
#define HF_FLUID_BUOYANT_SHAPE_COLLISION_ALGORITHM_H
|
||||||
|
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||||
|
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
|
||||||
|
|
||||||
|
#include "LinearMath/btVector3.h"
|
||||||
|
class btHfFluid;
|
||||||
|
|
||||||
|
class btConvexConvexAlgorithm;
|
||||||
|
class btConvexPenetrationDepthSolver;
|
||||||
|
class btSimplexSolverInterface;
|
||||||
|
/// btHfFluidBuoyantShapeCollisionAlgorithm provides collision detection between btHfFluidBuoyantConvexShape and btHfFluidBuoyantConvexShape
|
||||||
|
class btHfFluidBuoyantShapeCollisionAlgorithm : public btCollisionAlgorithm
|
||||||
|
{
|
||||||
|
btCollisionObject* m_collisionObject0;
|
||||||
|
btCollisionObject* m_collisionObject1;
|
||||||
|
|
||||||
|
btConvexConvexAlgorithm m_convexConvexAlgorithm;
|
||||||
|
public:
|
||||||
|
|
||||||
|
btHfFluidBuoyantShapeCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
|
||||||
|
|
||||||
|
virtual ~btHfFluidBuoyantShapeCollisionAlgorithm();
|
||||||
|
|
||||||
|
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||||
|
|
||||||
|
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||||
|
|
||||||
|
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||||
|
{
|
||||||
|
m_convexConvexAlgorithm.getAllContactManifolds (manifoldArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||||
|
{
|
||||||
|
btConvexPenetrationDepthSolver* m_pdSolver;
|
||||||
|
btSimplexSolverInterface* m_simplexSolver;
|
||||||
|
|
||||||
|
CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
|
||||||
|
{
|
||||||
|
m_simplexSolver = simplexSolver;
|
||||||
|
m_pdSolver = pdSolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~CreateFunc() {}
|
||||||
|
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||||
|
{
|
||||||
|
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btHfFluidBuoyantShapeCollisionAlgorithm));
|
||||||
|
if (!m_swapped)
|
||||||
|
{
|
||||||
|
return new(mem) btHfFluidBuoyantShapeCollisionAlgorithm(ci,body0,body1, m_simplexSolver, m_pdSolver);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return new(mem) btHfFluidBuoyantShapeCollisionAlgorithm(ci,body0,body1, m_simplexSolver, m_pdSolver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //HF_FLUID_BUOYANT_SHAPE_COLLISION_ALGORITHM_H
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#include "btHfFluidCollisionShape.h"
|
||||||
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#ifndef BT_HF_FLUID_COLLISION_SHAPE_H
|
||||||
|
#define BT_HF_FLUID_COLLISION_SHAPE_H
|
||||||
|
|
||||||
|
#include "BulletHfFluid/btHfFluid.h"
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btConvexInternalShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btConcaveShape.h"
|
||||||
|
|
||||||
|
class btHfFluidCollisionShape : public btConcaveShape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
btHfFluid* m_fluid;
|
||||||
|
|
||||||
|
btHfFluidCollisionShape(btHfFluid* backptr) : btConcaveShape ()
|
||||||
|
{
|
||||||
|
m_shapeType = HFFLUID_SHAPE_PROXYTYPE;
|
||||||
|
m_fluid=backptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~btHfFluidCollisionShape()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void processAllTriangles(btTriangleCallback* /*callback*/,const btVector3& /*aabbMin*/,const btVector3& /*aabbMax*/) const
|
||||||
|
{
|
||||||
|
//not yet
|
||||||
|
btAssert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
|
||||||
|
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
|
||||||
|
{
|
||||||
|
/* t should be identity, but better be safe than...fast? */
|
||||||
|
btVector3 mins;
|
||||||
|
btVector3 maxs;
|
||||||
|
|
||||||
|
m_fluid->getAabb (mins, maxs);
|
||||||
|
|
||||||
|
const btVector3 crns[]={t*btVector3(mins.x(),mins.y(),mins.z()),
|
||||||
|
t*btVector3(maxs.x(),mins.y(),mins.z()),
|
||||||
|
t*btVector3(maxs.x(),maxs.y(),mins.z()),
|
||||||
|
t*btVector3(mins.x(),maxs.y(),mins.z()),
|
||||||
|
t*btVector3(mins.x(),mins.y(),maxs.z()),
|
||||||
|
t*btVector3(maxs.x(),mins.y(),maxs.z()),
|
||||||
|
t*btVector3(maxs.x(),maxs.y(),maxs.z()),
|
||||||
|
t*btVector3(mins.x(),maxs.y(),maxs.z())};
|
||||||
|
aabbMin=aabbMax=crns[0];
|
||||||
|
for(int i=1;i<8;++i)
|
||||||
|
{
|
||||||
|
aabbMin.setMin(crns[i]);
|
||||||
|
aabbMax.setMax(crns[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setLocalScaling(const btVector3& /*scaling*/)
|
||||||
|
{
|
||||||
|
///na
|
||||||
|
btAssert(0);
|
||||||
|
}
|
||||||
|
virtual const btVector3& getLocalScaling() const
|
||||||
|
{
|
||||||
|
static const btVector3 dummy(1,1,1);
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
virtual void calculateLocalInertia(btScalar /*mass*/,btVector3& /*inertia*/) const
|
||||||
|
{
|
||||||
|
///not yet
|
||||||
|
btAssert(0);
|
||||||
|
}
|
||||||
|
virtual const char* getName()const
|
||||||
|
{
|
||||||
|
return "HfFluid";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "btHfFluidRigidCollisionAlgorithm.h"
|
||||||
|
#include "btHfFluidBuoyantConvexShape.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||||
|
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||||
|
#include "btHfFluid.h"
|
||||||
|
|
||||||
|
btHfFluidRigidCollisionAlgorithm::~btHfFluidRigidCollisionAlgorithm()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
btHfFluidRigidCollisionAlgorithm::btHfFluidRigidCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
|
||||||
|
: btCollisionAlgorithm(ci), m_isSwapped(isSwapped),
|
||||||
|
m_convexTrianglecallback(ci.m_dispatcher1, col0, col1, !isSwapped) // we flip the isSwapped because we are hf fluid vs. convex and callback expects convex vs. concave
|
||||||
|
{
|
||||||
|
m_manifoldPtr = m_convexTrianglecallback.m_manifoldPtr;
|
||||||
|
if (m_isSwapped)
|
||||||
|
{
|
||||||
|
m_hfFluid = static_cast<btHfFluid*>(col1);
|
||||||
|
m_rigidCollisionObject = static_cast<btCollisionObject*>(col0);
|
||||||
|
m_manifoldPtr->setBodies(m_hfFluid,m_rigidCollisionObject);
|
||||||
|
} else {
|
||||||
|
m_hfFluid = static_cast<btHfFluid*>(col0);
|
||||||
|
m_rigidCollisionObject = static_cast<btCollisionObject*>(col1);
|
||||||
|
m_manifoldPtr->setBodies(m_rigidCollisionObject,m_hfFluid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidCollisionAlgorithm::processGround (const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||||
|
{
|
||||||
|
btScalar triangleMargin = m_rigidCollisionObject->getCollisionShape()->getMargin();
|
||||||
|
resultOut->setPersistentManifold(m_manifoldPtr);
|
||||||
|
// to perform the convex shape vs. ground terrain:
|
||||||
|
// we pull the convex shape out of the buoyant shape and replace it temporarily
|
||||||
|
btHfFluidBuoyantConvexShape* tmpShape = (btHfFluidBuoyantConvexShape*)m_rigidCollisionObject->getCollisionShape();
|
||||||
|
btConvexShape* convexShape = ((btHfFluidBuoyantConvexShape*)tmpShape)->getConvexShape();
|
||||||
|
m_rigidCollisionObject->setCollisionShape (convexShape);
|
||||||
|
m_convexTrianglecallback.setTimeStepAndCounters (triangleMargin, dispatchInfo, resultOut);
|
||||||
|
m_hfFluid->foreachGroundTriangle (&m_convexTrianglecallback, m_convexTrianglecallback.getAabbMin(),m_convexTrianglecallback.getAabbMax());
|
||||||
|
resultOut->refreshContactPoints();
|
||||||
|
// restore the buoyant shape
|
||||||
|
m_rigidCollisionObject->setCollisionShape (tmpShape);
|
||||||
|
}
|
||||||
|
|
||||||
|
btScalar btHfFluidRigidCollisionAlgorithm::processFluid (const btDispatcherInfo& dispatchInfo, btScalar density, btScalar floatyness)
|
||||||
|
{
|
||||||
|
btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject);
|
||||||
|
btHfFluidColumnRigidBodyCallback columnCallback (rb, dispatchInfo.m_debugDraw, density, floatyness);
|
||||||
|
m_hfFluid->foreachFluidColumn (&columnCallback, m_convexTrianglecallback.getAabbMin(), m_convexTrianglecallback.getAabbMax());
|
||||||
|
return columnCallback.getVolume ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidCollisionAlgorithm::applyFluidFriction (btScalar mu, btScalar submerged_percentage)
|
||||||
|
{
|
||||||
|
btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject);
|
||||||
|
btScalar dt = btScalar(1.0f/60.0f);
|
||||||
|
|
||||||
|
//#define OLD_WAY
|
||||||
|
#ifdef OLD_WAY
|
||||||
|
btScalar radius = btScalar(0.0f);
|
||||||
|
{
|
||||||
|
btVector3 aabbMin, aabbMax;
|
||||||
|
btTransform T;
|
||||||
|
T.setIdentity();
|
||||||
|
rb->getCollisionShape()->getAabb (T, aabbMin, aabbMax);
|
||||||
|
radius = (aabbMax-aabbMin).length()*btScalar(0.5);
|
||||||
|
}
|
||||||
|
btScalar viscosity = btScalar(0.05);
|
||||||
|
btVector3 force = btScalar(6.0f) * SIMD_PI * viscosity * radius * -rb->getLinearVelocity();
|
||||||
|
|
||||||
|
btVector3 impulse = force * dt;
|
||||||
|
rb->applyCentralImpulse (impulse);
|
||||||
|
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
btVector3 av = rb->getAngularVelocity();
|
||||||
|
av *= btScalar(0.99);
|
||||||
|
rb->setAngularVelocity (av);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
btScalar scaled_mu = mu * submerged_percentage * btScalar(0.4f);
|
||||||
|
rb->applyCentralImpulse (dt * scaled_mu * -rb->getLinearVelocity());
|
||||||
|
rb->applyTorqueImpulse (dt * scaled_mu * -rb->getAngularVelocity());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||||
|
{
|
||||||
|
processGround (dispatchInfo, resultOut);
|
||||||
|
btHfFluidBuoyantConvexShape* buoyantShape = (btHfFluidBuoyantConvexShape*)m_rigidCollisionObject->getCollisionShape();
|
||||||
|
btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject);
|
||||||
|
if (rb)
|
||||||
|
{
|
||||||
|
btScalar mass = btScalar(1.0f) / rb->getInvMass ();
|
||||||
|
btScalar volume = buoyantShape->getTotalVolume ();
|
||||||
|
btScalar density = mass / volume;
|
||||||
|
btScalar floatyness = buoyantShape->getFloatyness ();
|
||||||
|
btScalar submerged_volume = processFluid (dispatchInfo, density, floatyness);
|
||||||
|
if (submerged_volume > btScalar(0.0))
|
||||||
|
{
|
||||||
|
btScalar submerged_percentage = submerged_volume/buoyantShape->getTotalVolume();
|
||||||
|
//printf("%f\n", submerged_percentage);
|
||||||
|
btScalar mu = btScalar(6.0f);
|
||||||
|
applyFluidFriction (mu, submerged_percentage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btScalar btHfFluidRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||||
|
{
|
||||||
|
return btScalar(1.0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 HF_FLUID_RIGID_COLLISION_ALGORITHM_H
|
||||||
|
#define HF_FLUID_RIGID_COLLISION_ALGORITHM_H
|
||||||
|
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||||
|
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
|
||||||
|
#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
|
||||||
|
|
||||||
|
#include "LinearMath/btVector3.h"
|
||||||
|
class btHfFluid;
|
||||||
|
|
||||||
|
/// btHfFluidRigidCollisionAlgorithm provides collision detection between btHfFluid and btRigidBody
|
||||||
|
class btHfFluidRigidCollisionAlgorithm : public btCollisionAlgorithm
|
||||||
|
{
|
||||||
|
btPersistentManifold* m_manifoldPtr;
|
||||||
|
|
||||||
|
btHfFluid* m_hfFluid;
|
||||||
|
btCollisionObject* m_rigidCollisionObject;
|
||||||
|
|
||||||
|
///for rigid versus fluid (instead of fluid versus rigid), we use this swapped boolean
|
||||||
|
bool m_isSwapped;
|
||||||
|
|
||||||
|
btConvexTriangleCallback m_convexTrianglecallback;
|
||||||
|
|
||||||
|
void processGround (const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||||
|
void applyFluidFriction (btScalar mu, btScalar submerged_percentage);
|
||||||
|
btScalar processFluid (const btDispatcherInfo& dispatchInfo, btScalar density, btScalar floatyness);
|
||||||
|
public:
|
||||||
|
|
||||||
|
btHfFluidRigidCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
|
||||||
|
|
||||||
|
virtual ~btHfFluidRigidCollisionAlgorithm();
|
||||||
|
|
||||||
|
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||||
|
|
||||||
|
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||||
|
|
||||||
|
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||||
|
{
|
||||||
|
manifoldArray.push_back (m_manifoldPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||||
|
{
|
||||||
|
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||||
|
{
|
||||||
|
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btHfFluidRigidCollisionAlgorithm));
|
||||||
|
if (!m_swapped)
|
||||||
|
{
|
||||||
|
return new(mem) btHfFluidRigidCollisionAlgorithm(ci,body0,body1,false);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return new(mem) btHfFluidRigidCollisionAlgorithm(ci,body0,body1,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //HF_FLUID_RIGID_COLLISION_ALGORITHM_H
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 "btHfFluidRigidCollisionConfiguration.h"
|
||||||
|
#include "btHfFluidRigidCollisionAlgorithm.h"
|
||||||
|
#include "btHfFluidBuoyantShapeCollisionAlgorithm.h"
|
||||||
|
#include "LinearMath/btPoolAllocator.h"
|
||||||
|
|
||||||
|
btHfFluidRigidCollisionConfiguration::btHfFluidRigidCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
|
||||||
|
:btDefaultCollisionConfiguration(constructionInfo)
|
||||||
|
{
|
||||||
|
void* mem;
|
||||||
|
|
||||||
|
mem = btAlignedAlloc(sizeof(btHfFluidRigidCollisionAlgorithm::CreateFunc),16);
|
||||||
|
m_hfFluidRigidConvexCreateFunc = new(mem) btHfFluidRigidCollisionAlgorithm::CreateFunc;
|
||||||
|
|
||||||
|
mem = btAlignedAlloc(sizeof(btHfFluidRigidCollisionAlgorithm::CreateFunc),16);
|
||||||
|
m_swappedHfFluidRigidConvexCreateFunc = new(mem) btHfFluidRigidCollisionAlgorithm::CreateFunc;
|
||||||
|
m_swappedHfFluidRigidConvexCreateFunc->m_swapped = true;
|
||||||
|
|
||||||
|
mem = btAlignedAlloc(sizeof(btHfFluidBuoyantShapeCollisionAlgorithm::CreateFunc),16);
|
||||||
|
m_hfFluidBuoyantShapeCollisionCreateFunc = new(mem) btHfFluidBuoyantShapeCollisionAlgorithm::CreateFunc(m_simplexSolver, m_pdSolver);
|
||||||
|
|
||||||
|
if (m_ownsCollisionAlgorithmPool && m_collisionAlgorithmPool)
|
||||||
|
{
|
||||||
|
int curElemSize = m_collisionAlgorithmPool->getElementSize();
|
||||||
|
///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
|
||||||
|
|
||||||
|
int maxSize0 = sizeof(btHfFluidRigidCollisionAlgorithm);
|
||||||
|
int maxSize1 = 0;
|
||||||
|
int maxSize2 = 0;
|
||||||
|
|
||||||
|
int collisionAlgorithmMaxElementSize = btMax(maxSize0,maxSize1);
|
||||||
|
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
|
||||||
|
|
||||||
|
if (collisionAlgorithmMaxElementSize > curElemSize)
|
||||||
|
{
|
||||||
|
m_collisionAlgorithmPool->~btPoolAllocator();
|
||||||
|
btAlignedFree(m_collisionAlgorithmPool);
|
||||||
|
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
|
||||||
|
m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btHfFluidRigidCollisionConfiguration::~btHfFluidRigidCollisionConfiguration()
|
||||||
|
{
|
||||||
|
m_hfFluidRigidConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||||
|
m_swappedHfFluidRigidConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||||
|
btAlignedFree(m_hfFluidRigidConvexCreateFunc);
|
||||||
|
btAlignedFree(m_swappedHfFluidRigidConvexCreateFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
btCollisionAlgorithmCreateFunc* btHfFluidRigidCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
|
||||||
|
{
|
||||||
|
if ((proxyType0 == HFFLUID_SHAPE_PROXYTYPE) && (proxyType1 == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE))
|
||||||
|
{
|
||||||
|
return m_hfFluidRigidConvexCreateFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((proxyType0 == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE) && (proxyType1 == HFFLUID_SHAPE_PROXYTYPE))
|
||||||
|
{
|
||||||
|
return m_swappedHfFluidRigidConvexCreateFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((proxyType0 == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE) && (proxyType1 == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE))
|
||||||
|
{
|
||||||
|
return m_hfFluidBuoyantShapeCollisionCreateFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
///fallback to the regular rigid collision shape
|
||||||
|
return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0,proxyType1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 BT_HFFLUID_RIGID_COLLISION_CONFIGURATION
|
||||||
|
#define BT_HFFLUID_RIGID_COLLISION_CONFIGURATION
|
||||||
|
|
||||||
|
#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h"
|
||||||
|
|
||||||
|
class btVoronoiSimplexSolver;
|
||||||
|
class btGjkEpaPenetrationDepthSolver;
|
||||||
|
|
||||||
|
|
||||||
|
///btSoftBodyRigidBodyCollisionConfiguration add softbody interaction on top of btDefaultCollisionConfiguration
|
||||||
|
class btHfFluidRigidCollisionConfiguration : public btDefaultCollisionConfiguration
|
||||||
|
{
|
||||||
|
//default CreationFunctions, filling the m_doubleDispatch table
|
||||||
|
btCollisionAlgorithmCreateFunc* m_hfFluidRigidConvexCreateFunc;
|
||||||
|
btCollisionAlgorithmCreateFunc* m_swappedHfFluidRigidConvexCreateFunc;
|
||||||
|
btCollisionAlgorithmCreateFunc* m_hfFluidBuoyantShapeCollisionCreateFunc;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
btHfFluidRigidCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo());
|
||||||
|
|
||||||
|
virtual ~btHfFluidRigidCollisionConfiguration();
|
||||||
|
|
||||||
|
///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation
|
||||||
|
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //BT_HFFLUID_RIGID_COLLISION_CONFIGURATION
|
||||||
|
|
||||||
@@ -0,0 +1,271 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 <stdio.h>
|
||||||
|
#include "LinearMath/btQuickprof.h"
|
||||||
|
#include "LinearMath/btIDebugDraw.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||||
|
|
||||||
|
// height field fluid
|
||||||
|
#include "btHfFluid.h"
|
||||||
|
#include "btHfFluidBuoyantConvexShape.h"
|
||||||
|
#include "btHfFluidRigidDynamicsWorld.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
btHfFluidRigidDynamicsWorld::btHfFluidRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
|
||||||
|
:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
|
||||||
|
{
|
||||||
|
m_drawMode = DRAWMODE_NORMAL;
|
||||||
|
m_bodyDrawMode = BODY_DRAWMODE_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
btHfFluidRigidDynamicsWorld::~btHfFluidRigidDynamicsWorld()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||||
|
{
|
||||||
|
btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep);
|
||||||
|
|
||||||
|
for ( int i=0;i<m_hfFluids.size();++i)
|
||||||
|
{
|
||||||
|
btHfFluid* phff = m_hfFluids[i];
|
||||||
|
|
||||||
|
// XXX: phff->predictMotion(timeStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
|
||||||
|
{
|
||||||
|
btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep );
|
||||||
|
|
||||||
|
updateFluids (timeStep);
|
||||||
|
|
||||||
|
solveFluidConstraints (timeStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::updateFluids(btScalar timeStep)
|
||||||
|
{
|
||||||
|
BT_PROFILE("updateFluids");
|
||||||
|
|
||||||
|
for ( int i=0;i<m_hfFluids.size();i++)
|
||||||
|
{
|
||||||
|
btHfFluid* phff=(btHfFluid*)m_hfFluids[i];
|
||||||
|
phff->predictMotion (timeStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::solveFluidConstraints(btScalar timeStep)
|
||||||
|
{
|
||||||
|
BT_PROFILE("solve Fluid Contacts");
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if(m_hfFluids.size())
|
||||||
|
{
|
||||||
|
btHfFluid::solveClusters(m_hfFluids);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0;i<m_hfFluids.size();++i)
|
||||||
|
{
|
||||||
|
btHfFluid* psb=(btHfFluid*)m_hfFluids[i];
|
||||||
|
psb->solveConstraints();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::addHfFluid(btHfFluid* body)
|
||||||
|
{
|
||||||
|
m_hfFluids.push_back(body);
|
||||||
|
|
||||||
|
btCollisionWorld::addCollisionObject(body,
|
||||||
|
btBroadphaseProxy::DefaultFilter,
|
||||||
|
btBroadphaseProxy::AllFilter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::removeHfFluid(btHfFluid* body)
|
||||||
|
{
|
||||||
|
m_hfFluids.remove(body);
|
||||||
|
|
||||||
|
btCollisionWorld::removeCollisionObject(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::drawHfFluidGround (btIDebugDraw* debugDraw, btHfFluid* fluid)
|
||||||
|
{
|
||||||
|
const btScalar* ground = fluid->getGroundArray ();
|
||||||
|
btVector3 com = fluid->getWorldTransform().getOrigin();
|
||||||
|
btVector3 color = btVector3(btScalar(0.13f), btScalar(0.13f), btScalar(0.0));
|
||||||
|
for (int i = 1; i < fluid->getNumNodesWidth()-1; i++)
|
||||||
|
{
|
||||||
|
for (int j = 1; j < fluid->getNumNodesLength()-1; j++)
|
||||||
|
{
|
||||||
|
int sw = fluid->arrayIndex (i, j);
|
||||||
|
int se = fluid->arrayIndex (i+1, j);
|
||||||
|
int nw = fluid->arrayIndex (i, j+1);
|
||||||
|
int ne = fluid->arrayIndex (i+1, j+1);
|
||||||
|
btVector3 swV = btVector3 (fluid->widthPos (i), ground[sw], fluid->lengthPos (j));
|
||||||
|
btVector3 seV = btVector3 (fluid->widthPos (i+1), ground[se], fluid->lengthPos (j));
|
||||||
|
btVector3 nwV = btVector3 (fluid->widthPos (i), ground[nw], fluid->lengthPos (j+1));
|
||||||
|
btVector3 neV = btVector3 (fluid->widthPos (i+1), ground[ne], fluid->lengthPos (j+1));
|
||||||
|
debugDraw->drawTriangle (swV+com, seV+com, nwV+com, color, btScalar(1.0f));
|
||||||
|
debugDraw->drawTriangle (seV+com, neV+com, nwV+com, color, btScalar(1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::drawHfFluidVelocity (btIDebugDraw* debugDraw, btHfFluid* fluid)
|
||||||
|
{
|
||||||
|
btScalar alpha(0.7f);
|
||||||
|
const btScalar* height = fluid->getHeightArray ();
|
||||||
|
btVector3 com = fluid->getWorldTransform().getOrigin();
|
||||||
|
btVector3 red = btVector3(btScalar(1.0f), btScalar(0.0f), btScalar(0.0));
|
||||||
|
btVector3 green = btVector3(btScalar(0.0f), btScalar(1.0f), btScalar(0.0));
|
||||||
|
const bool* flags = fluid->getFlagsArray ();
|
||||||
|
for (int i = 1; i < fluid->getNumNodesWidth()-1; i++)
|
||||||
|
{
|
||||||
|
for (int j = 1; j < fluid->getNumNodesLength()-1; j++)
|
||||||
|
{
|
||||||
|
int index = fluid->arrayIndex (i, j);
|
||||||
|
if (!flags[index])
|
||||||
|
continue;
|
||||||
|
btVector3 from = btVector3 (fluid->widthPos (i), height[index]+btScalar(0.1f), fluid->lengthPos (j));
|
||||||
|
btVector3 velocity;
|
||||||
|
velocity.setX (fluid->getVelocityUArray()[index]);
|
||||||
|
velocity.setY (btScalar(0.0f));
|
||||||
|
velocity.setZ (fluid->getVelocityVArray()[index]);
|
||||||
|
velocity.normalize();
|
||||||
|
btVector3 to = from + velocity;
|
||||||
|
|
||||||
|
debugDraw->drawLine (from+com, to+com, red, green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::drawHfFluidBuoyantConvexShape (btIDebugDraw* debugDrawer, btCollisionObject* object, btHfFluidBuoyantConvexShape* buoyantShape, int voxelDraw)
|
||||||
|
{
|
||||||
|
if (voxelDraw)
|
||||||
|
{
|
||||||
|
btTransform xform = object->getWorldTransform();
|
||||||
|
for (int i = 0; i < buoyantShape->getNumVoxels(); i++)
|
||||||
|
{
|
||||||
|
btVector3 p = buoyantShape->getVoxelPositionsArray()[i];
|
||||||
|
p = xform.getBasis() * p;
|
||||||
|
p += xform.getOrigin();
|
||||||
|
debugDrawer->drawSphere (p, buoyantShape->getVoxelRadius(), btVector3(1.0, 0.0, 0.0));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
btVector3 color(btScalar(255.),btScalar(255.),btScalar(255.));
|
||||||
|
switch(object->getActivationState())
|
||||||
|
{
|
||||||
|
case ACTIVE_TAG:
|
||||||
|
color = btVector3(btScalar(255.),btScalar(255.),btScalar(255.)); break;
|
||||||
|
case ISLAND_SLEEPING:
|
||||||
|
color = btVector3(btScalar(0.),btScalar(255.),btScalar(0.));break;
|
||||||
|
case WANTS_DEACTIVATION:
|
||||||
|
color = btVector3(btScalar(0.),btScalar(255.),btScalar(255.));break;
|
||||||
|
case DISABLE_DEACTIVATION:
|
||||||
|
color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));break;
|
||||||
|
case DISABLE_SIMULATION:
|
||||||
|
color = btVector3(btScalar(255.),btScalar(255.),btScalar(0.));break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
btConvexShape* convexShape = ((btHfFluidBuoyantConvexShape*)object->getCollisionShape())->getConvexShape();
|
||||||
|
debugDrawObject(object->getWorldTransform(),(btCollisionShape*)convexShape,color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::drawHfFluidNormal (btIDebugDraw* debugDraw, btHfFluid* fluid)
|
||||||
|
{
|
||||||
|
int colIndex = 0;
|
||||||
|
btVector3 col[2];
|
||||||
|
col[0] = btVector3(btScalar(0.0f), btScalar(0.0f), btScalar(1.0));
|
||||||
|
col[1] = btVector3(btScalar(0.0f), btScalar(0.5f), btScalar(0.5));
|
||||||
|
btScalar alpha(0.7f);
|
||||||
|
const btScalar* height = fluid->getHeightArray ();
|
||||||
|
const btScalar* eta = fluid->getEtaArray ();
|
||||||
|
const btScalar* ground = fluid->getGroundArray ();
|
||||||
|
btVector3 com = fluid->getWorldTransform().getOrigin();
|
||||||
|
const bool* flags = fluid->getFlagsArray ();
|
||||||
|
for (int i = 0; i < fluid->getNumNodesWidth()-1; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < fluid->getNumNodesLength()-1; j++)
|
||||||
|
{
|
||||||
|
int sw = fluid->arrayIndex (i, j);
|
||||||
|
int se = fluid->arrayIndex (i+1, j);
|
||||||
|
int nw = fluid->arrayIndex (i, j+1);
|
||||||
|
int ne = fluid->arrayIndex (i+1, j+1);
|
||||||
|
|
||||||
|
btScalar h = eta[sw];
|
||||||
|
btScalar g = ground[sw];
|
||||||
|
|
||||||
|
if (h < btScalar(0.05f))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (h <= btScalar(0.01f))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
btVector3 boxMin = btVector3(fluid->widthPos (i), g, fluid->lengthPos(j));
|
||||||
|
btVector3 boxMax = btVector3(fluid->widthPos(i+1), g+h, fluid->lengthPos(j+1));
|
||||||
|
boxMin += com;
|
||||||
|
boxMax += com;
|
||||||
|
|
||||||
|
debugDraw->drawBox (boxMin, boxMax, btVector3(btScalar(0.0f), btScalar(0.0f), btScalar(1.0f)), btScalar(1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btHfFluidRigidDynamicsWorld::debugDrawWorld()
|
||||||
|
{
|
||||||
|
if (getDebugDrawer())
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for ( i=0;i<this->m_hfFluids.size();i++)
|
||||||
|
{
|
||||||
|
btHfFluid* phh=(btHfFluid*)this->m_hfFluids[i];
|
||||||
|
switch (m_drawMode)
|
||||||
|
{
|
||||||
|
case DRAWMODE_NORMAL:
|
||||||
|
drawHfFluidGround (m_debugDrawer, phh);
|
||||||
|
//drawHfFluidNormal (m_debugDrawer, phh);
|
||||||
|
break;
|
||||||
|
case DRAWMODE_VELOCITY:
|
||||||
|
drawHfFluidGround (m_debugDrawer, phh);
|
||||||
|
//drawHfFluidNormal (m_debugDrawer, phh);
|
||||||
|
drawHfFluidVelocity (m_debugDrawer, phh);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
btAssert (0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < this->m_collisionObjects.size(); i++)
|
||||||
|
{
|
||||||
|
btCollisionShape* shape = m_collisionObjects[i]->getCollisionShape();
|
||||||
|
if (shape->getShapeType() == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
btHfFluidBuoyantConvexShape* buoyantShape = (btHfFluidBuoyantConvexShape*)shape;
|
||||||
|
drawHfFluidBuoyantConvexShape (m_debugDrawer, m_collisionObjects[i], buoyantShape, m_bodyDrawMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
btDiscreteDynamicsWorld::debugDrawWorld();
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
||||||
|
|
||||||
|
#ifndef BT_HFFLUID_RIGID_DYNAMICS_WORLD_H
|
||||||
|
#define BT_HFFLUID_RIGID_DYNAMICS_WORLD_H
|
||||||
|
|
||||||
|
class btHfFluid;
|
||||||
|
typedef btAlignedObjectArray<btHfFluid*> btHfFluidArray;
|
||||||
|
|
||||||
|
#define DRAWMODE_NORMAL 0
|
||||||
|
#define DRAWMODE_VELOCITY 1
|
||||||
|
#define DRAWMODE_MAX 2
|
||||||
|
|
||||||
|
#define BODY_DRAWMODE_NORMAL 0
|
||||||
|
#define BODY_DRAWMODE_VOXEL 1
|
||||||
|
#define BODY_DRAWMODE_MAX 2
|
||||||
|
|
||||||
|
class btHfFluidBuoyantConvexShape;
|
||||||
|
|
||||||
|
class btHfFluidRigidDynamicsWorld : public btDiscreteDynamicsWorld
|
||||||
|
{
|
||||||
|
|
||||||
|
btHfFluidArray m_hfFluids;
|
||||||
|
int m_drawMode;
|
||||||
|
int m_bodyDrawMode;
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void predictUnconstraintMotion(btScalar timeStep);
|
||||||
|
|
||||||
|
virtual void internalSingleStepSimulation( btScalar timeStep);
|
||||||
|
|
||||||
|
void updateFluids(btScalar timeStep);
|
||||||
|
|
||||||
|
void solveFluidConstraints(btScalar timeStep);
|
||||||
|
|
||||||
|
virtual void debugDrawWorld();
|
||||||
|
|
||||||
|
void drawHfFluidGround (btIDebugDraw* debugDraw, btHfFluid* fluid);
|
||||||
|
void drawHfFluidVelocity (btIDebugDraw* debugDraw, btHfFluid* fluid);
|
||||||
|
void drawHfFluidBuoyantConvexShape (btIDebugDraw* debugDrawer, btCollisionObject* object, btHfFluidBuoyantConvexShape* buoyantShape, int voxelDraw);
|
||||||
|
void drawHfFluidNormal (btIDebugDraw* debugDraw, btHfFluid* fluid);
|
||||||
|
public:
|
||||||
|
|
||||||
|
btHfFluidRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
|
||||||
|
|
||||||
|
virtual ~btHfFluidRigidDynamicsWorld();
|
||||||
|
|
||||||
|
|
||||||
|
void addHfFluid(btHfFluid* fluid);
|
||||||
|
|
||||||
|
void removeHfFluid(btHfFluid* fluid);
|
||||||
|
|
||||||
|
void setDrawMode (int drawMode)
|
||||||
|
{
|
||||||
|
m_drawMode = drawMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBodyDrawMode (int bodyDrawMode)
|
||||||
|
{
|
||||||
|
m_bodyDrawMode = bodyDrawMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
btHfFluidArray& getHfFluidArray()
|
||||||
|
{
|
||||||
|
return m_hfFluids;
|
||||||
|
}
|
||||||
|
|
||||||
|
const btHfFluidArray& getHfFluidArray() const
|
||||||
|
{
|
||||||
|
return m_hfFluids;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //BT_HFFLUID_RIGID_DYNAMICS_WORLD_H
|
||||||
35
Demos/HeightFieldFluidDemo/CMakeLists.txt
Normal file
35
Demos/HeightFieldFluidDemo/CMakeLists.txt
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# This is basically the overall name of the project in Visual Studio this is the name of the Solution File
|
||||||
|
|
||||||
|
|
||||||
|
# For every executable you have with a main method you should have an add_executable line below.
|
||||||
|
# For every add executable line you should list every .cpp and .h file you have associated with that executable.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# You shouldn't have to modify anything below this line
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL }
|
||||||
|
)
|
||||||
|
|
||||||
|
LINK_LIBRARIES(
|
||||||
|
LibOpenGLSupport LibBulletDynamics LibBulletCollision LibLinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(HfFluidDemo
|
||||||
|
HfFluidDemo_GL_ShapeDrawer.cpp
|
||||||
|
BulletHfFluid/btHfFluid.cpp
|
||||||
|
BulletHfFluid/btHfFluidBuoyantConvexShape.cpp
|
||||||
|
BulletHfFluid/btHfFluidBuoyantShapeCollisionAlgorithm.cpp
|
||||||
|
BulletHfFluid/btHfFluidCollisionShape.cpp
|
||||||
|
BulletHfFluid/btHfFluidRigidCollisionAlgorithm.cpp
|
||||||
|
BulletHfFluid/btHfFluidRigidCollisionConfiguration.cpp
|
||||||
|
BulletHfFluid/btHfFluidRigidDynamicsWorld.cpp
|
||||||
|
main.cpp
|
||||||
|
HfFluidDemo.cpp
|
||||||
|
)
|
||||||
|
|
||||||
1414
Demos/HeightFieldFluidDemo/HfFluidDemo.cpp
Normal file
1414
Demos/HeightFieldFluidDemo/HfFluidDemo.cpp
Normal file
File diff suppressed because it is too large
Load Diff
150
Demos/HeightFieldFluidDemo/HfFluidDemo.h
Normal file
150
Demos/HeightFieldFluidDemo/HfFluidDemo.h
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 HFFLUID_DEMO_H
|
||||||
|
#define HFFLUID_DEMO_H
|
||||||
|
|
||||||
|
#include "DemoApplication.h"
|
||||||
|
#include "LinearMath/btAlignedObjectArray.h"
|
||||||
|
#include "BulletHfFluid/btHfFluid.h"
|
||||||
|
|
||||||
|
class btBroadphaseInterface;
|
||||||
|
class btCollisionShape;
|
||||||
|
class btOverlappingPairCache;
|
||||||
|
class btCollisionDispatcher;
|
||||||
|
class btConstraintSolver;
|
||||||
|
struct btCollisionAlgorithmCreateFunc;
|
||||||
|
class btDefaultCollisionConfiguration;
|
||||||
|
|
||||||
|
class btHfFluidRigidDynamicsWorld;
|
||||||
|
///collisions between a btSoftBody and a btRigidBody
|
||||||
|
class btFluidRididCollisionAlgorithm;
|
||||||
|
|
||||||
|
|
||||||
|
///CcdPhysicsDemo shows basic stacking using Bullet physics, and allows toggle of Ccd (using key '1')
|
||||||
|
class HfFluidDemo : public DemoApplication
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
btAlignedObjectArray<btFluidRididCollisionAlgorithm*> m_FluidRigidCollisionAlgorithms;
|
||||||
|
|
||||||
|
|
||||||
|
bool m_autocam;
|
||||||
|
bool m_cutting;
|
||||||
|
bool m_raycast;
|
||||||
|
btScalar m_animtime;
|
||||||
|
btClock m_clock;
|
||||||
|
int m_lastmousepos[2];
|
||||||
|
btVector3 m_impact;
|
||||||
|
btVector3 m_goal;
|
||||||
|
bool m_drag;
|
||||||
|
|
||||||
|
|
||||||
|
//keep the collision shapes, for deletion/cleanup
|
||||||
|
btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
|
||||||
|
|
||||||
|
btBroadphaseInterface* m_broadphase;
|
||||||
|
|
||||||
|
btCollisionDispatcher* m_dispatcher;
|
||||||
|
|
||||||
|
|
||||||
|
btConstraintSolver* m_solver;
|
||||||
|
|
||||||
|
btCollisionAlgorithmCreateFunc* m_boxBoxCF;
|
||||||
|
|
||||||
|
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void initPhysics();
|
||||||
|
|
||||||
|
void exitPhysics();
|
||||||
|
|
||||||
|
HfFluidDemo ();
|
||||||
|
|
||||||
|
virtual ~HfFluidDemo()
|
||||||
|
{
|
||||||
|
exitPhysics();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setDrawClusters(bool drawClusters)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setShootBoxShape ();
|
||||||
|
|
||||||
|
virtual void clientMoveAndDisplay();
|
||||||
|
|
||||||
|
virtual void displayCallback();
|
||||||
|
|
||||||
|
void createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos );
|
||||||
|
|
||||||
|
static DemoApplication* Create()
|
||||||
|
{
|
||||||
|
HfFluidDemo* demo = new HfFluidDemo;
|
||||||
|
demo->myinit();
|
||||||
|
demo->initPhysics();
|
||||||
|
return demo;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const btHfFluidRigidDynamicsWorld* getHfFluidDynamicsWorld() const
|
||||||
|
{
|
||||||
|
///just make it a btSoftRigidDynamicsWorld please
|
||||||
|
///or we will add type checking
|
||||||
|
return (btHfFluidRigidDynamicsWorld*) m_dynamicsWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual btHfFluidRigidDynamicsWorld* getHfFluidDynamicsWorld()
|
||||||
|
{
|
||||||
|
///just make it a btSoftRigidDynamicsWorld please
|
||||||
|
///or we will add type checking
|
||||||
|
return (btHfFluidRigidDynamicsWorld*) m_dynamicsWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void clientResetScene();
|
||||||
|
void renderme();
|
||||||
|
void keyboardCallback(unsigned char key, int x, int y);
|
||||||
|
void mouseFunc(int button, int state, int x, int y);
|
||||||
|
void mouseMotionFunc(int x,int y);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MACRO_SOFT_DEMO(a) class HfFluidDemo##a : public HfFluidDemo\
|
||||||
|
{\
|
||||||
|
public:\
|
||||||
|
static DemoApplication* Create()\
|
||||||
|
{\
|
||||||
|
HfFluidDemo* demo = new HfFluidDemo##a;\
|
||||||
|
extern unsigned int current_demo;\
|
||||||
|
current_demo=a;\
|
||||||
|
demo->myinit();\
|
||||||
|
demo->initPhysics();\
|
||||||
|
return demo;\
|
||||||
|
}\
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MACRO_SOFT_DEMO(0) //Init_Drops
|
||||||
|
MACRO_SOFT_DEMO(1) //Init_Wave
|
||||||
|
MACRO_SOFT_DEMO(2) //Init_RandomDrops
|
||||||
|
MACRO_SOFT_DEMO(3)
|
||||||
|
|
||||||
|
#endif //CCD_PHYSICS_DEMO_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
604
Demos/HeightFieldFluidDemo/HfFluidDemo_GL_ShapeDrawer.cpp
Normal file
604
Demos/HeightFieldFluidDemo/HfFluidDemo_GL_ShapeDrawer.cpp
Normal file
@@ -0,0 +1,604 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WIN32 //needed for glut.h
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//think different
|
||||||
|
#if defined(__APPLE__) && !defined (VMDMESA)
|
||||||
|
#include <OpenGL/gl.h>
|
||||||
|
#include <OpenGL/glu.h>
|
||||||
|
#include <GLUT/glut.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "GlutStuff.h"
|
||||||
|
#include "HfFluidDemo_GL_ShapeDrawer.h"
|
||||||
|
|
||||||
|
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btConeShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btCylinderShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btUniformScalingShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
|
||||||
|
///
|
||||||
|
#include "BulletCollision/CollisionShapes/btShapeHull.h"
|
||||||
|
#include "BulletHfFluid/btHfFluidBuoyantConvexShape.h"
|
||||||
|
#include "BulletHfFluid/btHfFluid.h"
|
||||||
|
#include "BulletHfFluid/btHfFluidCollisionShape.h"
|
||||||
|
|
||||||
|
#include "LinearMath/btTransformUtil.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "LinearMath/btIDebugDraw.h"
|
||||||
|
//for debugmodes
|
||||||
|
#include "BMF_Api.h"
|
||||||
|
#include <stdio.h> //printf debugging
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
class GlDrawcallback : public btTriangleCallback
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool m_wireframe;
|
||||||
|
|
||||||
|
GlDrawcallback()
|
||||||
|
:m_wireframe(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
|
||||||
|
{
|
||||||
|
|
||||||
|
(void)triangleIndex;
|
||||||
|
(void)partId;
|
||||||
|
|
||||||
|
|
||||||
|
if (m_wireframe)
|
||||||
|
{
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glColor3f(1, 0, 0);
|
||||||
|
glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
|
||||||
|
glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
|
||||||
|
glColor3f(0, 1, 0);
|
||||||
|
glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
|
||||||
|
glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
|
||||||
|
glColor3f(0, 0, 1);
|
||||||
|
glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
|
||||||
|
glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
|
||||||
|
glEnd();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
//glColor3f(1, 1, 1);
|
||||||
|
|
||||||
|
|
||||||
|
glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
|
||||||
|
glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
|
||||||
|
glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
|
||||||
|
|
||||||
|
glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
|
||||||
|
glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
|
||||||
|
glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TriangleGlDrawcallback : public btInternalTriangleIndexCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
|
||||||
|
{
|
||||||
|
(void)triangleIndex;
|
||||||
|
(void)partId;
|
||||||
|
|
||||||
|
|
||||||
|
glBegin(GL_TRIANGLES);//LINES);
|
||||||
|
glColor3f(1, 0, 0);
|
||||||
|
glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
|
||||||
|
glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
|
||||||
|
glColor3f(0, 1, 0);
|
||||||
|
glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
|
||||||
|
glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ());
|
||||||
|
glColor3f(0, 0, 1);
|
||||||
|
glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ());
|
||||||
|
glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ());
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void HfFluidDemo_GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
btglMultMatrix(m);
|
||||||
|
|
||||||
|
if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
const btUniformScalingShape* scalingShape = static_cast<const btUniformScalingShape*>(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}};
|
||||||
|
|
||||||
|
drawOpenGL( (btScalar*)tmpScaling,convexShape,color,debugMode,worldBoundsMin,worldBoundsMax);
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape->getShapeType() == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
btConvexShape* convexShape = ((btHfFluidBuoyantConvexShape*)shape)->getConvexShape();
|
||||||
|
btTransform I;
|
||||||
|
I.setIdentity();
|
||||||
|
btScalar mat[16];
|
||||||
|
I.getOpenGLMatrix (&mat[0]);
|
||||||
|
drawOpenGL (mat, convexShape, color, debugMode, worldBoundsMin, worldBoundsMax);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(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);
|
||||||
|
drawOpenGL(childMat,colShape,color,debugMode,worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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,(GLuint*)&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);
|
||||||
|
if(m_textureenabled)
|
||||||
|
{
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D,m_texturehandle);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glColor3f(color.x(),color.y(), color.z());
|
||||||
|
|
||||||
|
bool useWireframeFallback = true;
|
||||||
|
|
||||||
|
if (!(debugMode & btIDebugDraw::DBG_DrawWireframe))
|
||||||
|
{
|
||||||
|
///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
|
||||||
|
int shapetype=m_textureenabled?MAX_BROADPHASE_COLLISION_TYPES:shape->getShapeType();
|
||||||
|
switch (shapetype)
|
||||||
|
{
|
||||||
|
case BOX_SHAPE_PROXYTYPE:
|
||||||
|
{
|
||||||
|
const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
|
||||||
|
btVector3 halfExtent = boxShape->getHalfExtentsWithMargin();
|
||||||
|
glScaled(2*halfExtent[0], 2*halfExtent[1], 2*halfExtent[2]);
|
||||||
|
glutSolidCube(1.0);
|
||||||
|
useWireframeFallback = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case SPHERE_SHAPE_PROXYTYPE:
|
||||||
|
{
|
||||||
|
const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
|
||||||
|
float radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
|
||||||
|
glutSolidSphere(radius,10,10);
|
||||||
|
useWireframeFallback = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CONE_SHAPE_PROXYTYPE:
|
||||||
|
{
|
||||||
|
const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
|
||||||
|
int upIndex = coneShape->getConeUpIndex();
|
||||||
|
float radius = coneShape->getRadius();//+coneShape->getMargin();
|
||||||
|
float height = coneShape->getHeight();//+coneShape->getMargin();
|
||||||
|
switch (upIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
glRotatef(90.0, 0.0, 1.0, 0.0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
glRotatef(-90.0, 1.0, 0.0, 0.0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
glTranslatef(0.0, 0.0, -0.5*height);
|
||||||
|
glutSolidCone(radius,height,10,10);
|
||||||
|
useWireframeFallback = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case STATIC_PLANE_PROXYTYPE:
|
||||||
|
{
|
||||||
|
const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
|
||||||
|
btScalar planeConst = staticPlaneShape->getPlaneConstant();
|
||||||
|
const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
|
||||||
|
btVector3 planeOrigin = planeNormal * planeConst;
|
||||||
|
btVector3 vec0,vec1;
|
||||||
|
btPlaneSpace1(planeNormal,vec0,vec1);
|
||||||
|
btScalar vecLen = 100.f;
|
||||||
|
btVector3 pt0 = planeOrigin + vec0*vecLen;
|
||||||
|
btVector3 pt1 = planeOrigin - vec0*vecLen;
|
||||||
|
btVector3 pt2 = planeOrigin + vec1*vecLen;
|
||||||
|
btVector3 pt3 = planeOrigin - vec1*vecLen;
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3f(pt0.getX(),pt0.getY(),pt0.getZ());
|
||||||
|
glVertex3f(pt1.getX(),pt1.getY(),pt1.getZ());
|
||||||
|
glVertex3f(pt2.getX(),pt2.getY(),pt2.getZ());
|
||||||
|
glVertex3f(pt3.getX(),pt3.getY(),pt3.getZ());
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case CYLINDER_SHAPE_PROXYTYPE:
|
||||||
|
{
|
||||||
|
const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
|
||||||
|
int upAxis = cylinder->getUpAxis();
|
||||||
|
|
||||||
|
|
||||||
|
float radius = cylinder->getRadius();
|
||||||
|
float halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
|
||||||
|
|
||||||
|
drawCylinder(radius,halfHeight,upAxis);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (shape->isConvex())
|
||||||
|
{
|
||||||
|
ShapeCache* sc=cache((btConvexShape*)shape);
|
||||||
|
|
||||||
|
//if (shape->getUserPointer())
|
||||||
|
{
|
||||||
|
//glutSolidCube(1.0);
|
||||||
|
btShapeHull* hull = &sc->m_shapehull/*(btShapeHull*)shape->getUserPointer()*/;
|
||||||
|
|
||||||
|
|
||||||
|
if (hull->numTriangles () > 0)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
const unsigned int* idx = hull->getIndexPointer();
|
||||||
|
const btVector3* vtx = hull->getVertexPointer();
|
||||||
|
|
||||||
|
glBegin (GL_TRIANGLES);
|
||||||
|
|
||||||
|
for (int i = 0; i < hull->numTriangles (); i++)
|
||||||
|
{
|
||||||
|
int i1 = index++;
|
||||||
|
int i2 = index++;
|
||||||
|
int i3 = index++;
|
||||||
|
btAssert(i1 < hull->numIndices () &&
|
||||||
|
i2 < hull->numIndices () &&
|
||||||
|
i3 < hull->numIndices ());
|
||||||
|
|
||||||
|
int index1 = idx[i1];
|
||||||
|
int index2 = idx[i2];
|
||||||
|
int index3 = idx[i3];
|
||||||
|
btAssert(index1 < hull->numVertices () &&
|
||||||
|
index2 < hull->numVertices () &&
|
||||||
|
index3 < hull->numVertices ());
|
||||||
|
|
||||||
|
btVector3 v1 = vtx[index1];
|
||||||
|
btVector3 v2 = vtx[index2];
|
||||||
|
btVector3 v3 = vtx[index3];
|
||||||
|
btVector3 normal = (v3-v1).cross(v2-v1);
|
||||||
|
normal.normalize ();
|
||||||
|
|
||||||
|
glNormal3f(normal.getX(),normal.getY(),normal.getZ());
|
||||||
|
glVertex3f (v1.x(), v1.y(), v1.z());
|
||||||
|
glVertex3f (v2.x(), v2.y(), v2.z());
|
||||||
|
glVertex3f (v3.x(), v3.y(), v3.z());
|
||||||
|
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// for polyhedral shapes
|
||||||
|
if (debugMode==btIDebugDraw::DBG_DrawFeaturesText && (shape->isPolyhedral()))
|
||||||
|
{
|
||||||
|
btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
|
||||||
|
|
||||||
|
{
|
||||||
|
glRasterPos3f(0.0, 0.0, 0.0);
|
||||||
|
//BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),polyshape->getExtraDebugInfo());
|
||||||
|
|
||||||
|
glColor3f(1.f, 1.f, 1.f);
|
||||||
|
int i;
|
||||||
|
for (i=0;i<polyshape->getNumVertices();i++)
|
||||||
|
{
|
||||||
|
btVector3 vtx;
|
||||||
|
polyshape->getVertex(i,vtx);
|
||||||
|
glRasterPos3f(vtx.x(), vtx.y(), vtx.z());
|
||||||
|
char buf[12];
|
||||||
|
sprintf(buf," %d",i);
|
||||||
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<polyshape->getNumPlanes();i++)
|
||||||
|
{
|
||||||
|
btVector3 normal;
|
||||||
|
btVector3 vtx;
|
||||||
|
polyshape->getPlane(normal,vtx,i);
|
||||||
|
btScalar d = vtx.dot(normal);
|
||||||
|
|
||||||
|
glRasterPos3f(normal.x()*d, normal.y()*d, normal.z()*d);
|
||||||
|
char buf[12];
|
||||||
|
sprintf(buf," plane %d",i);
|
||||||
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_DISPLAY_LISTS
|
||||||
|
|
||||||
|
if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
GLuint dlist = OGL_get_displaylist_for_shape((btCollisionShape * )shape);
|
||||||
|
if (dlist)
|
||||||
|
{
|
||||||
|
glCallList(dlist);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
if (shape->isConcave())//>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
|
||||||
|
// if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
btConcaveShape* concaveMesh = (btConcaveShape*) shape;
|
||||||
|
|
||||||
|
GlDrawcallback drawCallback;
|
||||||
|
drawCallback.m_wireframe = (debugMode & btIDebugDraw::DBG_DrawWireframe)!=0;
|
||||||
|
|
||||||
|
concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (shape->getShapeType() == HFFLUID_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
btHfFluidCollisionShape* hfFluidShape = (btHfFluidCollisionShape*)shape;
|
||||||
|
btHfFluid* fluid = hfFluidShape->m_fluid;
|
||||||
|
|
||||||
|
GlDrawcallback drawCallback;
|
||||||
|
drawCallback.m_wireframe = (debugMode & btIDebugDraw::DBG_DrawWireframe) != 0;
|
||||||
|
fluid->foreachSurfaceTriangle (&drawCallback, worldBoundsMin, worldBoundsMax);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_DISPLAY_LISTS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
|
||||||
|
|
||||||
|
//todo: pass camera for some culling
|
||||||
|
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||||
|
btVector3 aabbMin(-btScalar(1e30),-btScalar(1e30),-btScalar(1e30));
|
||||||
|
TriangleGlDrawcallback drawCallback;
|
||||||
|
convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glRasterPos3f(0,0,0);//mvtx.x(), vtx.y(), vtx.z());
|
||||||
|
if (debugMode&btIDebugDraw::DBG_DrawText)
|
||||||
|
{
|
||||||
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),shape->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debugMode& btIDebugDraw::DBG_DrawFeaturesText)
|
||||||
|
{
|
||||||
|
//BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),shape->getExtraDebugInfo());
|
||||||
|
}
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// glPopMatrix();
|
||||||
|
if(m_textureenabled) glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void HfFluidDemo_GL_ShapeDrawer::drawShadow(btScalar* m,const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax)
|
||||||
|
{
|
||||||
|
glPushMatrix();
|
||||||
|
btglMultMatrix(m);
|
||||||
|
if(shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
const btUniformScalingShape* scalingShape = static_cast<const btUniformScalingShape*>(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,worldBoundsMin,worldBoundsMax);
|
||||||
|
glPopMatrix();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(shape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
|
||||||
|
{
|
||||||
|
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(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,worldBoundsMin,worldBoundsMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool useWireframeFallback = true;
|
||||||
|
if (shape->isConvex())
|
||||||
|
{
|
||||||
|
ShapeCache* sc=cache((btConvexShape*)shape);
|
||||||
|
btShapeHull* hull =&sc->m_shapehull;
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
for(int i=0;i<sc->m_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;
|
||||||
|
|
||||||
|
GlDrawcallback drawCallback;
|
||||||
|
drawCallback.m_wireframe = false;
|
||||||
|
|
||||||
|
concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
HfFluidDemo_GL_ShapeDrawer::HfFluidDemo_GL_ShapeDrawer()
|
||||||
|
{
|
||||||
|
m_texturehandle = 0;
|
||||||
|
m_textureenabled = true;
|
||||||
|
m_textureinitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HfFluidDemo_GL_ShapeDrawer::~HfFluidDemo_GL_ShapeDrawer()
|
||||||
|
{
|
||||||
|
}
|
||||||
33
Demos/HeightFieldFluidDemo/HfFluidDemo_GL_ShapeDrawer.h
Normal file
33
Demos/HeightFieldFluidDemo/HfFluidDemo_GL_ShapeDrawer.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 HFFLUID_GL_SHAPE_DRAWER_H
|
||||||
|
#define HFFLUID_GL_SHAPE_DRAWER_H
|
||||||
|
|
||||||
|
#include "GL_ShapeDrawer.h"
|
||||||
|
|
||||||
|
/// OpenGL shape drawing
|
||||||
|
class HfFluidDemo_GL_ShapeDrawer : public GL_ShapeDrawer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HfFluidDemo_GL_ShapeDrawer();
|
||||||
|
|
||||||
|
virtual ~HfFluidDemo_GL_ShapeDrawer();
|
||||||
|
|
||||||
|
///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer
|
||||||
|
virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
|
||||||
|
virtual void drawShadow(btScalar* m, const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //HFFLUID_GL_SHAPE_DRAWER_H
|
||||||
3
Demos/HeightFieldFluidDemo/Jamfile
Normal file
3
Demos/HeightFieldFluidDemo/Jamfile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
SubDir TOP Demos HfFluidDemo ;
|
||||||
|
|
||||||
|
BulletHfFluidDemo HfFluidDemo : [ Wildcard *.h *.cpp BulletHfFluid/*.h BulletHfFluid/*.cpp ] ;
|
||||||
37
Demos/HeightFieldFluidDemo/main.cpp
Normal file
37
Demos/HeightFieldFluidDemo/main.cpp
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
|
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||||
|
|
||||||
|
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 "HfFluidDemo.h"
|
||||||
|
#include "GlutStuff.h"
|
||||||
|
#include "GLDebugDrawer.h"
|
||||||
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
|
||||||
|
GLDebugDrawer gDebugDrawer;
|
||||||
|
|
||||||
|
int main(int argc,char** argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
HfFluidDemo* fluidDemo = new HfFluidDemo();
|
||||||
|
|
||||||
|
fluidDemo->initPhysics();
|
||||||
|
fluidDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
|
||||||
|
|
||||||
|
|
||||||
|
glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bullet.sf.net",fluidDemo);
|
||||||
|
|
||||||
|
delete fluidDemo;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -102,4 +102,5 @@ SubInclude TOP Demos Raytracer ;
|
|||||||
SubInclude TOP Demos SimplexDemo ;
|
SubInclude TOP Demos SimplexDemo ;
|
||||||
SubInclude TOP Demos DoublePrecisionDemo ;
|
SubInclude TOP Demos DoublePrecisionDemo ;
|
||||||
SubInclude TOP Demos TerrainDemo ;
|
SubInclude TOP Demos TerrainDemo ;
|
||||||
|
SubInclude TOP Demos HeightFieldFluidDemo ;
|
||||||
|
|
||||||
|
|||||||
@@ -1539,7 +1539,7 @@ void ConcaveDemo::renderme()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ m_sundirection(btVector3(1,-2,1)*1000)
|
|||||||
m_profileIterator = CProfileManager::Get_Iterator();
|
m_profileIterator = CProfileManager::Get_Iterator();
|
||||||
#endif //BT_NO_PROFILE
|
#endif //BT_NO_PROFILE
|
||||||
|
|
||||||
m_shapeDrawer.enableTexture(true);
|
m_shapeDrawer = new GL_ShapeDrawer ();
|
||||||
|
m_shapeDrawer->enableTexture(true);
|
||||||
m_enableshadows = false;
|
m_enableshadows = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,9 +98,18 @@ DemoApplication::~DemoApplication()
|
|||||||
if (m_shootBoxShape)
|
if (m_shootBoxShape)
|
||||||
delete m_shootBoxShape;
|
delete m_shootBoxShape;
|
||||||
|
|
||||||
|
if (m_shapeDrawer)
|
||||||
|
delete m_shapeDrawer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DemoApplication::overrideGLShapeDrawer (GL_ShapeDrawer* shapeDrawer)
|
||||||
|
{
|
||||||
|
shapeDrawer->enableTexture (m_shapeDrawer->hasTextureEnabled());
|
||||||
|
delete m_shapeDrawer;
|
||||||
|
m_shapeDrawer = shapeDrawer;
|
||||||
|
}
|
||||||
|
|
||||||
void DemoApplication::myinit(void)
|
void DemoApplication::myinit(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -298,7 +308,7 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
|
|||||||
case 'x' : zoomOut(); break;
|
case 'x' : zoomOut(); break;
|
||||||
case 'i' : toggleIdle(); break;
|
case 'i' : toggleIdle(); break;
|
||||||
case 'g' : m_enableshadows=!m_enableshadows;break;
|
case 'g' : m_enableshadows=!m_enableshadows;break;
|
||||||
case 'u' : m_shapeDrawer.enableTexture(!m_shapeDrawer.enableTexture(false));break;
|
case 'u' : m_shapeDrawer->enableTexture(!m_shapeDrawer->enableTexture(false));break;
|
||||||
case 'h':
|
case 'h':
|
||||||
if (m_debugMode & btIDebugDraw::DBG_NoHelpText)
|
if (m_debugMode & btIDebugDraw::DBG_NoHelpText)
|
||||||
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText);
|
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText);
|
||||||
@@ -510,7 +520,19 @@ void DemoApplication::displayCallback()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DemoApplication::setShootBoxShape ()
|
||||||
|
{
|
||||||
|
if (!m_shootBoxShape)
|
||||||
|
{
|
||||||
|
//#define TEST_UNIFORM_SCALING_SHAPE 1
|
||||||
|
#ifdef TEST_UNIFORM_SCALING_SHAPE
|
||||||
|
btConvexShape* childShape = new btBoxShape(btVector3(1.f,1.f,1.f));
|
||||||
|
m_shootBoxShape = new btUniformScalingShape(childShape,0.5f);
|
||||||
|
#else
|
||||||
|
m_shootBoxShape = new btSphereShape(1.f);//BoxShape(btVector3(1.f,1.f,1.f));
|
||||||
|
#endif//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DemoApplication::shootBox(const btVector3& destination)
|
void DemoApplication::shootBox(const btVector3& destination)
|
||||||
{
|
{
|
||||||
@@ -523,16 +545,7 @@ void DemoApplication::shootBox(const btVector3& destination)
|
|||||||
btVector3 camPos = getCameraPosition();
|
btVector3 camPos = getCameraPosition();
|
||||||
startTransform.setOrigin(camPos);
|
startTransform.setOrigin(camPos);
|
||||||
|
|
||||||
if (!m_shootBoxShape)
|
setShootBoxShape ();
|
||||||
{
|
|
||||||
//#define TEST_UNIFORM_SCALING_SHAPE 1
|
|
||||||
#ifdef TEST_UNIFORM_SCALING_SHAPE
|
|
||||||
btConvexShape* childShape = new btBoxShape(btVector3(1.f,1.f,1.f));
|
|
||||||
m_shootBoxShape = new btUniformScalingShape(childShape,0.5f);
|
|
||||||
#else
|
|
||||||
m_shootBoxShape = new btSphereShape(1.f);//BoxShape(btVector3(1.f,1.f,1.f));
|
|
||||||
#endif//
|
|
||||||
}
|
|
||||||
|
|
||||||
btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape);
|
btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape);
|
||||||
|
|
||||||
@@ -981,9 +994,9 @@ void DemoApplication::renderscene(int pass)
|
|||||||
|
|
||||||
switch(pass)
|
switch(pass)
|
||||||
{
|
{
|
||||||
case 0: m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),aabbMin,aabbMax);break;
|
case 0: m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),aabbMin,aabbMax);break;
|
||||||
case 1: m_shapeDrawer.drawShadow(m,m_sundirection*rot,colObj->getCollisionShape(),aabbMin,aabbMax);break;
|
case 1: m_shapeDrawer->drawShadow(m,m_sundirection*rot,colObj->getCollisionShape(),aabbMin,aabbMax);break;
|
||||||
case 2: m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor*0.3,0,aabbMin,aabbMax);break;
|
case 2: m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor*0.3,0,aabbMin,aabbMax);break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class DemoApplication
|
|||||||
void showProfileInfo(float& xOffset,float& yStart, float yIncr);
|
void showProfileInfo(float& xOffset,float& yStart, float yIncr);
|
||||||
void renderscene(int pass);
|
void renderscene(int pass);
|
||||||
|
|
||||||
GL_ShapeDrawer m_shapeDrawer;
|
GL_ShapeDrawer* m_shapeDrawer;
|
||||||
bool m_enableshadows;
|
bool m_enableshadows;
|
||||||
btVector3 m_sundirection;
|
btVector3 m_sundirection;
|
||||||
|
|
||||||
@@ -102,15 +102,16 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void overrideGLShapeDrawer (GL_ShapeDrawer* shapeDrawer);
|
||||||
|
|
||||||
void setOrthographicProjection();
|
void setOrthographicProjection();
|
||||||
void resetPerspectiveProjection();
|
void resetPerspectiveProjection();
|
||||||
|
|
||||||
bool setTexturing(bool enable) { return(m_shapeDrawer.enableTexture(enable)); }
|
bool setTexturing(bool enable) { return(m_shapeDrawer->enableTexture(enable)); }
|
||||||
bool setShadows(bool enable) { bool p=m_enableshadows;m_enableshadows=enable;return(p); }
|
bool setShadows(bool enable) { bool p=m_enableshadows;m_enableshadows=enable;return(p); }
|
||||||
bool getTexturing() const
|
bool getTexturing() const
|
||||||
{
|
{
|
||||||
return m_shapeDrawer.hasTextureEnabled();
|
return m_shapeDrawer->hasTextureEnabled();
|
||||||
}
|
}
|
||||||
bool getShadows() const
|
bool getShadows() const
|
||||||
{
|
{
|
||||||
@@ -176,6 +177,7 @@ public:
|
|||||||
virtual void clientResetScene();
|
virtual void clientResetScene();
|
||||||
|
|
||||||
///Demo functions
|
///Demo functions
|
||||||
|
virtual void setShootBoxShape ();
|
||||||
void shootBox(const btVector3& destination);
|
void shootBox(const btVector3& destination);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,17 @@ GLDebugDrawer::GLDebugDrawer()
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btVector3& fromColor, const btVector3& toColor)
|
||||||
|
{
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glColor3f(fromColor.getX(), fromColor.getY(), fromColor.getZ());
|
||||||
|
glVertex3d(from.getX(), from.getY(), from.getZ());
|
||||||
|
glColor3f(toColor.getX(), toColor.getY(), toColor.getZ());
|
||||||
|
glVertex3d(to.getX(), to.getY(), to.getZ());
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
void GLDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
|
void GLDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
|
||||||
{
|
{
|
||||||
// if (m_debugMode > 0)
|
// if (m_debugMode > 0)
|
||||||
@@ -33,6 +44,30 @@ void GLDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLDebugDrawer::drawSphere (const btVector3& p, btScalar radius, const btVector3& color)
|
||||||
|
{
|
||||||
|
glColor4f (color.getX(), color.getY(), color.getZ(), btScalar(1.0f));
|
||||||
|
glPushMatrix ();
|
||||||
|
glTranslatef (p.getX(), p.getY(), p.getZ());
|
||||||
|
glutSolidSphere (radius, 10, 10);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLDebugDrawer::drawBox (const btVector3& boxMin, const btVector3& boxMax, const btVector3& color, btScalar alpha)
|
||||||
|
{
|
||||||
|
btVector3 halfExtent = (boxMax - boxMin) * btScalar(0.5f);
|
||||||
|
btVector3 center = (boxMax + boxMin) * btScalar(0.5f);
|
||||||
|
//glEnable(GL_BLEND); // Turn blending On
|
||||||
|
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
|
glColor4f (color.getX(), color.getY(), color.getZ(), alpha);
|
||||||
|
glPushMatrix ();
|
||||||
|
glTranslatef (center.getX(), center.getY(), center.getZ());
|
||||||
|
glScaled(2*halfExtent[0], 2*halfExtent[1], 2*halfExtent[2]);
|
||||||
|
glutSolidCube(1.0);
|
||||||
|
glPopMatrix ();
|
||||||
|
//glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
void GLDebugDrawer::drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha)
|
void GLDebugDrawer::drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha)
|
||||||
{
|
{
|
||||||
// if (m_debugMode > 0)
|
// if (m_debugMode > 0)
|
||||||
|
|||||||
@@ -14,8 +14,13 @@ public:
|
|||||||
GLDebugDrawer();
|
GLDebugDrawer();
|
||||||
|
|
||||||
|
|
||||||
|
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& fromColor, const btVector3& toColor);
|
||||||
|
|
||||||
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color);
|
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color);
|
||||||
|
|
||||||
|
virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color);
|
||||||
|
virtual void drawBox (const btVector3& boxMin, const btVector3& boxMax, const btVector3& color, btScalar alpha);
|
||||||
|
|
||||||
virtual void drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha);
|
virtual void drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha);
|
||||||
|
|
||||||
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color);
|
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class btShapeHull;
|
|||||||
/// OpenGL shape drawing
|
/// OpenGL shape drawing
|
||||||
class GL_ShapeDrawer
|
class GL_ShapeDrawer
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
struct ShapeCache
|
struct ShapeCache
|
||||||
{
|
{
|
||||||
struct Edge { btVector3 n[2];int v[2]; };
|
struct Edge { btVector3 n[2];int v[2]; };
|
||||||
@@ -38,17 +39,17 @@ class GL_ShapeDrawer
|
|||||||
bool m_textureenabled;
|
bool m_textureenabled;
|
||||||
bool m_textureinitialized;
|
bool m_textureinitialized;
|
||||||
|
|
||||||
private:
|
|
||||||
ShapeCache* cache(btConvexShape*);
|
ShapeCache* cache(btConvexShape*);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GL_ShapeDrawer();
|
GL_ShapeDrawer();
|
||||||
|
|
||||||
virtual ~GL_ShapeDrawer();
|
virtual ~GL_ShapeDrawer();
|
||||||
|
|
||||||
///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer
|
///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer
|
||||||
void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
|
virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
|
||||||
void drawShadow(btScalar* m, const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
|
virtual void drawShadow(btScalar* m, const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax);
|
||||||
|
|
||||||
bool enableTexture(bool enable) { bool p=m_textureenabled;m_textureenabled=enable;return(p); }
|
bool enableTexture(bool enable) { bool p=m_textureenabled;m_textureenabled=enable;return(p); }
|
||||||
bool hasTextureEnabled() const
|
bool hasTextureEnabled() const
|
||||||
@@ -64,4 +65,4 @@ class GL_ShapeDrawer
|
|||||||
void OGL_displaylist_register_shape(btCollisionShape * shape);
|
void OGL_displaylist_register_shape(btCollisionShape * shape);
|
||||||
void OGL_displaylist_clean();
|
void OGL_displaylist_clean();
|
||||||
|
|
||||||
#endif //GL_SHAPE_DRAWER_H
|
#endif //GL_SHAPE_DRAWER_H
|
||||||
@@ -91,7 +91,7 @@ void SimplexDemo::displayCallback()
|
|||||||
transA.getOpenGLMatrix( m );
|
transA.getOpenGLMatrix( m );
|
||||||
|
|
||||||
/// draw the simplex
|
/// draw the simplex
|
||||||
m_shapeDrawer.drawOpenGL(m,shapePtr[i],btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,shapePtr[i],btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
|
|
||||||
/// calculate closest point from simplex to the origin, and draw this vector
|
/// calculate closest point from simplex to the origin, and draw this vector
|
||||||
simplex.calcClosest(m);
|
simplex.calcClosest(m);
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ void VehicleDemo::renderme()
|
|||||||
m_vehicle->updateWheelTransform(i,true);
|
m_vehicle->updateWheelTransform(i,true);
|
||||||
//draw wheels (cylinders)
|
//draw wheels (cylinders)
|
||||||
m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m);
|
m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m);
|
||||||
m_shapeDrawer.drawOpenGL(m,&wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
m_shapeDrawer->drawOpenGL(m,&wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1803
msvc/8/wksbullet.sln
1803
msvc/8/wksbullet.sln
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,8 @@ CONCAVE_SHAPES_END_HERE,
|
|||||||
COMPOUND_SHAPE_PROXYTYPE,
|
COMPOUND_SHAPE_PROXYTYPE,
|
||||||
|
|
||||||
SOFTBODY_SHAPE_PROXYTYPE,
|
SOFTBODY_SHAPE_PROXYTYPE,
|
||||||
|
HFFLUID_SHAPE_PROXYTYPE,
|
||||||
|
HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
|
||||||
INVALID_SHAPE_PROXYTYPE,
|
INVALID_SHAPE_PROXYTYPE,
|
||||||
|
|
||||||
MAX_BROADPHASE_COLLISION_TYPES
|
MAX_BROADPHASE_COLLISION_TYPES
|
||||||
|
|||||||
@@ -114,10 +114,11 @@ public:
|
|||||||
{
|
{
|
||||||
CO_COLLISION_OBJECT =1,
|
CO_COLLISION_OBJECT =1,
|
||||||
CO_RIGID_BODY,
|
CO_RIGID_BODY,
|
||||||
CO_SOFT_BODY,
|
|
||||||
///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
|
///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
|
||||||
///It is useful for collision sensors, explosion objects, character controller etc.
|
///It is useful for collision sensors, explosion objects, character controller etc.
|
||||||
CO_GHOST_OBJECT
|
CO_GHOST_OBJECT,
|
||||||
|
CO_SOFT_BODY,
|
||||||
|
CO_HF_FLUID
|
||||||
};
|
};
|
||||||
|
|
||||||
SIMD_FORCE_INLINE bool mergesSimulationIslands() const
|
SIMD_FORCE_INLINE bool mergesSimulationIslands() const
|
||||||
|
|||||||
@@ -338,7 +338,8 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
|
|||||||
//process some debugging flags
|
//process some debugging flags
|
||||||
if (getDebugDrawer())
|
if (getDebugDrawer())
|
||||||
{
|
{
|
||||||
gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
|
btIDebugDraw* debugDrawer = getDebugDrawer ();
|
||||||
|
gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
|
||||||
}
|
}
|
||||||
if (numSimulationSubSteps)
|
if (numSimulationSubSteps)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void btAlignedFreeInternal (void* ptr,int line,char* filename);
|
|||||||
void* btAlignedAllocInternal (size_t size, int alignment);
|
void* btAlignedAllocInternal (size_t size, int alignment);
|
||||||
void btAlignedFreeInternal (void* ptr);
|
void btAlignedFreeInternal (void* ptr);
|
||||||
|
|
||||||
#define btAlignedAlloc(a,b) btAlignedAllocInternal(a,b)
|
#define btAlignedAlloc(size,alignment) btAlignedAllocInternal(size,alignment)
|
||||||
#define btAlignedFree(ptr) btAlignedFreeInternal(ptr)
|
#define btAlignedFree(ptr) btAlignedFreeInternal(ptr)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -57,6 +57,19 @@ class btIDebugDraw
|
|||||||
|
|
||||||
virtual ~btIDebugDraw() {};
|
virtual ~btIDebugDraw() {};
|
||||||
|
|
||||||
|
virtual void drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
|
||||||
|
{
|
||||||
|
drawLine (from, to, fromColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void drawBox (const btVector3& boxMin, const btVector3& boxMax, const btVector3& color, btScalar alpha)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
|
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
|
||||||
|
|
||||||
virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha)
|
virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha)
|
||||||
|
|||||||
Reference in New Issue
Block a user