Initialize libbullet git in 2.0_beta.
[platform/upstream/libbullet.git] / Demos / HeightFieldFluidDemo / BulletHfFluid / btHfFluid.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.com
4
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:
10
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.
14
15 Experimental Buoyancy fluid demo written by John McCutchan
16 */
17
18 #ifndef __HFFLUID_H
19 #define __HFFLUID_H
20
21 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
22 #include "BulletCollision/CollisionShapes/btTriangleCallback.h"
23
24 class btPersistentManifold;
25 class btManifoldResult;
26
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
30 // Fix volume removal
31 // add buoyant convex vs. convex / concave
32 // add buoyant concave support (try bunny model)
33
34 ///experimental buyancy fluid demo
35 class btHfFluid : public btCollisionObject
36 {
37 public:
38         btHfFluid (btScalar gridCellWidth, int numNodesWidth, int numNodesLength);
39
40         ~btHfFluid ();
41
42         void predictMotion(btScalar dt);
43
44         /* Prep does some initial setup of the height field fluid.
45          * You should call this at initialization time.
46          */
47         void prep ();
48                 
49         static const btHfFluid* upcast(const btCollisionObject* colObj)
50         {
51                 if (colObj->getInternalType()==CO_HF_FLUID)
52                         return (const btHfFluid*)colObj;
53                 return 0;
54         }
55         static btHfFluid*                       upcast(btCollisionObject* colObj)
56         {
57                 if (colObj->getInternalType()==CO_HF_FLUID)
58                         return (btHfFluid*)colObj;
59                 return 0;
60         }
61
62         //
63         // ::btCollisionObject
64         //
65
66         virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
67         {
68                 aabbMin = m_aabbMin;
69                 aabbMax = m_aabbMax;
70         }
71
72         int getNumNodesWidth () const { return m_numNodesWidth; }
73         int getNumNodesLength () const { return m_numNodesLength; }
74
75         btScalar getGridCellWidth () const { return m_gridCellWidth; }
76         btScalar widthPos (int i) const;
77         btScalar lengthPos (int j) const;
78
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;
88
89         void setFluidHeight (int x, int y, btScalar height);
90         void setFluidHeight (int index, btScalar height);
91
92         void addFluidHeight (int x, int y, btScalar height);
93         void addDisplaced (int i, int j, btScalar r);
94
95         void getAabbForColumn (int x, int y, btVector3& aabbMin, btVector3& aabbMax);
96
97         btScalar* getHeightArray ();
98         btScalar* getGroundArray ();
99         btScalar* getEtaArray ();
100         btScalar* getVelocityUArray ();
101         btScalar* getVelocityVArray ();
102         bool* getFlagsArray ();
103
104         void foreachGroundTriangle(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax);
105         class btHfFluidColumnCallback 
106         {
107         public:
108                 btHfFluidColumnCallback () {}
109
110                 virtual ~btHfFluidColumnCallback () {}
111
112                 virtual bool processColumn (btHfFluid* fluid, int w, int l)
113                 {
114                         return true; // keep going
115                 }
116         };
117
118         void foreachFluidColumn (btHfFluidColumnCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax);
119
120         void foreachSurfaceTriangle (btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax);
121 protected:
122         int m_numNodesWidth;
123         int m_numNodesLength;
124
125         btScalar m_gridCellWidth;
126         btScalar m_gridWidth;
127         btScalar m_gridLength;
128
129         btScalar m_gridCellWidthInv;
130         
131         btVector3 m_aabbMin;
132         btVector3 m_aabbMax;
133
134         void setGridDimensions (btScalar gridCellWidth,
135                                                         int numNodesWidth, int numNodesLength);
136
137         btScalar bilinearInterpolate (const btScalar* array, btScalar i, btScalar j);
138
139         btScalar advect (const btScalar* array, btScalar i, btScalar j, btScalar di, btScalar dj, btScalar dt);
140
141         void advectEta (btScalar dt);
142         void updateHeight (btScalar dt);
143
144         void advectVelocityU (btScalar dt);
145         void advectVelocityV (btScalar dt);
146         void updateVelocity (btScalar dt);
147
148         void transferDisplaced (btScalar dt);
149
150         void setReflectBoundaryLeft ();
151         void setReflectBoundaryRight ();
152         void setReflectBoundaryTop ();
153         void setReflectBoundaryBottom ();
154
155         void setAbsorbBoundaryLeft (btScalar dt);
156         void setAbsorbBoundaryRight (btScalar dt);
157         void setAbsorbBoundaryTop (btScalar dt);
158         void setAbsorbBoundaryBottom (btScalar dt);
159
160         void computeFlagsAndFillRatio ();
161         btScalar computeHmin (int i, int j);
162         btScalar computeHmax (int i, int j);
163         btScalar computeEtaMax (int i, int j);
164
165         void allocateArrays ();
166
167         void debugTests ();
168
169         btScalar* m_temp; // temp
170         int m_heightIndex;
171         btScalar* m_height[2];
172         btScalar* m_ground;
173         btScalar* m_eta; // height - ground
174         btScalar* m_u[2];
175         btScalar* m_v[2];
176         int m_rIndex;
177         btScalar* m_r[2];
178         int m_velocityIndex;
179         bool* m_flags;
180         btScalar* m_fillRatio;
181
182         // tweakables
183         btScalar m_globalVelocityU;
184         btScalar m_globalVelocityV;
185         btScalar m_gravity;
186         btScalar m_volumeDisplacementScale;
187         btScalar m_horizontalVelocityScale;
188
189         btScalar m_epsHeight;
190         btScalar m_epsEta;
191 public:
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;
196
197         // Control force of gravity, should match physics world
198         // default: -10.0
199         void setGravity (btScalar gravity);
200         btScalar getGravity () const;
201
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
205         // default: 0.5
206         void setVolumeDisplacementScale (btScalar volumeDisplacementScale);
207         btScalar getVolumeDisplacementScale () const;
208
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
212         // default: 0.5
213         void setHorizontalVelocityScale (btScalar horizontalVelocityScale);
214         btScalar getHorizontalVelocityScale () const;
215 };
216
217 class btRigidBody;
218 class btIDebugDraw;
219 class btHfFluidBuoyantConvexShape;
220
221 class btHfFluidColumnRigidBodyCallback : public btHfFluid::btHfFluidColumnCallback
222 {
223 protected:
224         btRigidBody* m_rigidBody;
225         btHfFluidBuoyantConvexShape* m_buoyantShape;
226         btIDebugDraw* m_debugDraw;
227         int m_numVoxels;
228         btVector3* m_voxelPositionsXformed;
229         bool* m_voxelSubmerged;
230         btVector3 m_aabbMin;
231         btVector3 m_aabbMax;
232         btScalar m_volume;
233         btScalar m_density;
234         btScalar m_floatyness;
235 public:
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; }
240 };
241
242 #endif
243