2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.com
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
15 Experimental Buoyancy fluid demo written by John McCutchan
21 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
22 #include "BulletCollision/CollisionShapes/btTriangleCallback.h"
24 class btPersistentManifold;
25 class btManifoldResult;
27 // FIX AABB calculation for whole btHfFluid shape
28 // Fix flags and fill ratio
29 // -> Figure out the constants used in flags and fill ratio code
31 // add buoyant convex vs. convex / concave
32 // add buoyant concave support (try bunny model)
34 ///experimental buyancy fluid demo
35 class btHfFluid : public btCollisionObject
38 btHfFluid (btScalar gridCellWidth, int numNodesWidth, int numNodesLength);
42 void predictMotion(btScalar dt);
44 /* Prep does some initial setup of the height field fluid.
45 * You should call this at initialization time.
49 static const btHfFluid* upcast(const btCollisionObject* colObj)
51 if (colObj->getInternalType()==CO_HF_FLUID)
52 return (const btHfFluid*)colObj;
55 static btHfFluid* upcast(btCollisionObject* colObj)
57 if (colObj->getInternalType()==CO_HF_FLUID)
58 return (btHfFluid*)colObj;
63 // ::btCollisionObject
66 virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
72 int getNumNodesWidth () const { return m_numNodesWidth; }
73 int getNumNodesLength () const { return m_numNodesLength; }
75 btScalar getGridCellWidth () const { return m_gridCellWidth; }
76 btScalar widthPos (int i) const;
77 btScalar lengthPos (int j) const;
79 int arrayIndex (int i, int j) const;
80 int arrayIndex (btScalar i, btScalar j) const;
81 int arrayIndex (unsigned int i, unsigned int j) const;
82 const btScalar* getHeightArray () const;
83 const btScalar* getGroundArray () const;
84 const btScalar* getEtaArray () const;
85 const btScalar* getVelocityUArray () const;
86 const btScalar* getVelocityVArray () const;
87 const bool* getFlagsArray () const;
89 void setFluidHeight (int x, int y, btScalar height);
90 void setFluidHeight (int index, btScalar height);
92 void addFluidHeight (int x, int y, btScalar height);
93 void addDisplaced (int i, int j, btScalar r);
95 void getAabbForColumn (int x, int y, btVector3& aabbMin, btVector3& aabbMax);
97 btScalar* getHeightArray ();
98 btScalar* getGroundArray ();
99 btScalar* getEtaArray ();
100 btScalar* getVelocityUArray ();
101 btScalar* getVelocityVArray ();
102 bool* getFlagsArray ();
104 void foreachGroundTriangle(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax);
105 class btHfFluidColumnCallback
108 btHfFluidColumnCallback () {}
110 virtual ~btHfFluidColumnCallback () {}
112 virtual bool processColumn (btHfFluid* fluid, int w, int l)
114 return true; // keep going
118 void foreachFluidColumn (btHfFluidColumnCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax);
120 void foreachSurfaceTriangle (btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax);
123 int m_numNodesLength;
125 btScalar m_gridCellWidth;
126 btScalar m_gridWidth;
127 btScalar m_gridLength;
129 btScalar m_gridCellWidthInv;
134 void setGridDimensions (btScalar gridCellWidth,
135 int numNodesWidth, int numNodesLength);
137 btScalar bilinearInterpolate (const btScalar* array, btScalar i, btScalar j);
139 btScalar advect (const btScalar* array, btScalar i, btScalar j, btScalar di, btScalar dj, btScalar dt);
141 void advectEta (btScalar dt);
142 void updateHeight (btScalar dt);
144 void advectVelocityU (btScalar dt);
145 void advectVelocityV (btScalar dt);
146 void updateVelocity (btScalar dt);
148 void transferDisplaced (btScalar dt);
150 void setReflectBoundaryLeft ();
151 void setReflectBoundaryRight ();
152 void setReflectBoundaryTop ();
153 void setReflectBoundaryBottom ();
155 void setAbsorbBoundaryLeft (btScalar dt);
156 void setAbsorbBoundaryRight (btScalar dt);
157 void setAbsorbBoundaryTop (btScalar dt);
158 void setAbsorbBoundaryBottom (btScalar dt);
160 void computeFlagsAndFillRatio ();
161 btScalar computeHmin (int i, int j);
162 btScalar computeHmax (int i, int j);
163 btScalar computeEtaMax (int i, int j);
165 void allocateArrays ();
169 btScalar* m_temp; // temp
171 btScalar* m_height[2];
173 btScalar* m_eta; // height - ground
180 btScalar* m_fillRatio;
183 btScalar m_globalVelocityU;
184 btScalar m_globalVelocityV;
186 btScalar m_volumeDisplacementScale;
187 btScalar m_horizontalVelocityScale;
189 btScalar m_epsHeight;
192 // You can enforce a global velocity at the surface of the fluid
193 // default: 0.0 and 0.0
194 void setGlobaVelocity (btScalar globalVelocityU, btScalar globalVelocityV);
195 void getGlobalVelocity (btScalar& globalVelocityU, btScalar& globalVelocityV) const;
197 // Control force of gravity, should match physics world
199 void setGravity (btScalar gravity);
200 btScalar getGravity () const;
202 // When a body is submerged into the fluid, the displaced fluid
203 // is spread to adjacent cells. You can control the percentage of this
204 // by setting this value between 0.0 and 1.0
206 void setVolumeDisplacementScale (btScalar volumeDisplacementScale);
207 btScalar getVolumeDisplacementScale () const;
209 // The horizontal velocity of the fluid can influence bodies submerged
210 // in the fluid. You can control how much influence by setting this
211 // between 0.0 and 1.0
213 void setHorizontalVelocityScale (btScalar horizontalVelocityScale);
214 btScalar getHorizontalVelocityScale () const;
219 class btHfFluidBuoyantConvexShape;
221 class btHfFluidColumnRigidBodyCallback : public btHfFluid::btHfFluidColumnCallback
224 btRigidBody* m_rigidBody;
225 btHfFluidBuoyantConvexShape* m_buoyantShape;
226 btIDebugDraw* m_debugDraw;
228 btVector3* m_voxelPositionsXformed;
229 bool* m_voxelSubmerged;
234 btScalar m_floatyness;
236 btHfFluidColumnRigidBodyCallback (btRigidBody* rigidBody, btIDebugDraw* debugDraw, btScalar density, btScalar floatyness);
237 ~btHfFluidColumnRigidBodyCallback ();
238 bool processColumn (btHfFluid* fluid, int w, int l);
239 btScalar getVolume () const { return m_volume; }