00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <LinearMath/btQuickprof.h>
00020 #include <LinearMath/btIDebugDraw.h>
00021 #include <BulletCollision/CollisionShapes/btCollisionShape.h>
00022
00023
00024 #include <uwsim/BulletHfFluid/btHfFluid.h>
00025 #include <uwsim/BulletHfFluid/btHfFluidBuoyantConvexShape.h>
00026 #include <uwsim/BulletHfFluid/btHfFluidRigidDynamicsWorld.h>
00027
00028 btHfFluidRigidDynamicsWorld::btHfFluidRigidDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache,
00029 btConstraintSolver* constraintSolver,
00030 btCollisionConfiguration* collisionConfiguration) :
00031 btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration)
00032 {
00033 m_drawMode = DRAWMODE_NORMAL;
00034 m_bodyDrawMode = BODY_DRAWMODE_NORMAL;
00035 }
00036
00037 btHfFluidRigidDynamicsWorld::~btHfFluidRigidDynamicsWorld()
00038 {
00039
00040 }
00041
00042 void btHfFluidRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
00043 {
00044 btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep);
00045
00046 for (int i = 0; i < m_hfFluids.size(); ++i)
00047 {
00048 btHfFluid* phff = m_hfFluids[i];
00049
00050
00051 }
00052 }
00053
00054 void btHfFluidRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
00055 {
00056 btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep);
00057
00058 updateFluids(timeStep);
00059
00060 solveFluidConstraints(timeStep);
00061 }
00062
00063 void btHfFluidRigidDynamicsWorld::updateFluids(btScalar timeStep)
00064 {
00065 BT_PROFILE("updateFluids");
00066
00067 for (int i = 0; i < m_hfFluids.size(); i++)
00068 {
00069 btHfFluid* phff = (btHfFluid*)m_hfFluids[i];
00070 phff->predictMotion(timeStep);
00071 }
00072 }
00073
00074 void btHfFluidRigidDynamicsWorld::solveFluidConstraints(btScalar timeStep)
00075 {
00076 BT_PROFILE("solve Fluid Contacts");
00077
00078 #if 0
00079 if(m_hfFluids.size())
00080 {
00081 btHfFluid::solveClusters(m_hfFluids);
00082 }
00083
00084 for(int i=0;i<m_hfFluids.size();++i)
00085 {
00086 btHfFluid* psb=(btHfFluid*)m_hfFluids[i];
00087 psb->solveConstraints();
00088 }
00089 #endif
00090 }
00091
00092 void btHfFluidRigidDynamicsWorld::addHfFluid(btHfFluid* body)
00093 {
00094 m_hfFluids.push_back(body);
00095
00096 btCollisionWorld::addCollisionObject(body, btBroadphaseProxy::DefaultFilter, btBroadphaseProxy::AllFilter);
00097
00098 }
00099
00100 void btHfFluidRigidDynamicsWorld::removeHfFluid(btHfFluid* body)
00101 {
00102 m_hfFluids.remove(body);
00103
00104 btCollisionWorld::removeCollisionObject(body);
00105 }
00106
00107 void btHfFluidRigidDynamicsWorld::drawHfFluidGround(btIDebugDraw* debugDraw, btHfFluid* fluid)
00108 {
00109 const btScalar* ground = fluid->getGroundArray();
00110 btVector3 com = fluid->getWorldTransform().getOrigin();
00111 btVector3 color = btVector3(btScalar(0.13f), btScalar(0.13f), btScalar(0.0));
00112 for (int i = 1; i < fluid->getNumNodesWidth() - 1; i++)
00113 {
00114 for (int j = 1; j < fluid->getNumNodesLength() - 1; j++)
00115 {
00116 int sw = fluid->arrayIndex(i, j);
00117 int se = fluid->arrayIndex(i + 1, j);
00118 int nw = fluid->arrayIndex(i, j + 1);
00119 int ne = fluid->arrayIndex(i + 1, j + 1);
00120 btVector3 swV = btVector3(fluid->widthPos(i), ground[sw], fluid->lengthPos(j));
00121 btVector3 seV = btVector3(fluid->widthPos(i + 1), ground[se], fluid->lengthPos(j));
00122 btVector3 nwV = btVector3(fluid->widthPos(i), ground[nw], fluid->lengthPos(j + 1));
00123 btVector3 neV = btVector3(fluid->widthPos(i + 1), ground[ne], fluid->lengthPos(j + 1));
00124 debugDraw->drawTriangle(swV + com, seV + com, nwV + com, color, btScalar(1.0f));
00125 debugDraw->drawTriangle(seV + com, neV + com, nwV + com, color, btScalar(1.0f));
00126 }
00127 }
00128 }
00129
00130 void btHfFluidRigidDynamicsWorld::drawHfFluidVelocity(btIDebugDraw* debugDraw, btHfFluid* fluid)
00131 {
00132 btScalar alpha(0.7f);
00133 const btScalar* height = fluid->getHeightArray();
00134 btVector3 com = fluid->getWorldTransform().getOrigin();
00135 btVector3 red = btVector3(btScalar(1.0f), btScalar(0.0f), btScalar(0.0));
00136 btVector3 green = btVector3(btScalar(0.0f), btScalar(1.0f), btScalar(0.0));
00137 const bool* flags = fluid->getFlagsArray();
00138 for (int i = 1; i < fluid->getNumNodesWidth() - 1; i++)
00139 {
00140 for (int j = 1; j < fluid->getNumNodesLength() - 1; j++)
00141 {
00142 int index = fluid->arrayIndex(i, j);
00143 if (!flags[index])
00144 continue;
00145 btVector3 from = btVector3(fluid->widthPos(i), height[index] + btScalar(0.1f), fluid->lengthPos(j));
00146 btVector3 velocity;
00147 velocity.setX(fluid->getVelocityUArray()[index]);
00148 velocity.setY(btScalar(0.0f));
00149 velocity.setZ(fluid->getVelocityVArray()[index]);
00150 velocity.normalize();
00151 btVector3 to = from + velocity;
00152
00153 debugDraw->drawLine(from + com, to + com, red, green);
00154 }
00155 }
00156 }
00157
00158 void btHfFluidRigidDynamicsWorld::drawHfFluidBuoyantConvexShape(btIDebugDraw* debugDrawer, btCollisionObject* object,
00159 btHfFluidBuoyantConvexShape* buoyantShape,
00160 int voxelDraw)
00161 {
00162 if (voxelDraw)
00163 {
00164 btTransform xform = object->getWorldTransform();
00165 for (int i = 0; i < buoyantShape->getNumVoxels(); i++)
00166 {
00167 btVector3 p = buoyantShape->getVoxelPositionsArray()[i];
00168 p = xform.getBasis() * p;
00169 p += xform.getOrigin();
00170 debugDrawer->drawSphere(p, buoyantShape->getVoxelRadius(), btVector3(1.0, 0.0, 0.0));
00171 }
00172 }
00173 else
00174 {
00175 btVector3 color(btScalar(255.), btScalar(255.), btScalar(255.));
00176 switch (object->getActivationState())
00177 {
00178 case ACTIVE_TAG:
00179 color = btVector3(btScalar(255.), btScalar(255.), btScalar(255.));
00180 break;
00181 case ISLAND_SLEEPING:
00182 color = btVector3(btScalar(0.), btScalar(255.), btScalar(0.));
00183 break;
00184 case WANTS_DEACTIVATION:
00185 color = btVector3(btScalar(0.), btScalar(255.), btScalar(255.));
00186 break;
00187 case DISABLE_DEACTIVATION:
00188 color = btVector3(btScalar(255.), btScalar(0.), btScalar(0.));
00189 break;
00190 case DISABLE_SIMULATION:
00191 color = btVector3(btScalar(255.), btScalar(255.), btScalar(0.));
00192 break;
00193 default:
00194 {
00195 color = btVector3(btScalar(255.), btScalar(0.), btScalar(0.));
00196 }
00197 };
00198
00199 btConvexShape* convexShape = ((btHfFluidBuoyantConvexShape*)object->getCollisionShape())->getConvexShape();
00200 debugDrawObject(object->getWorldTransform(), (btCollisionShape*)convexShape, color);
00201 }
00202 }
00203
00204 void btHfFluidRigidDynamicsWorld::drawHfFluidNormal(btIDebugDraw* debugDraw, btHfFluid* fluid)
00205 {
00206 int colIndex = 0;
00207 btVector3 col[2];
00208 col[0] = btVector3(btScalar(0.0f), btScalar(0.0f), btScalar(1.0));
00209 col[1] = btVector3(btScalar(0.0f), btScalar(0.5f), btScalar(0.5));
00210 btScalar alpha(0.7f);
00211 const btScalar* height = fluid->getHeightArray();
00212 const btScalar* eta = fluid->getEtaArray();
00213 const btScalar* ground = fluid->getGroundArray();
00214 btVector3 com = fluid->getWorldTransform().getOrigin();
00215 const bool* flags = fluid->getFlagsArray();
00216 for (int i = 0; i < fluid->getNumNodesWidth() - 1; i++)
00217 {
00218 for (int j = 0; j < fluid->getNumNodesLength() - 1; j++)
00219 {
00220 int sw = fluid->arrayIndex(i, j);
00221 int se = fluid->arrayIndex(i + 1, j);
00222 int nw = fluid->arrayIndex(i, j + 1);
00223 int ne = fluid->arrayIndex(i + 1, j + 1);
00224
00225 btScalar h = eta[sw];
00226 btScalar g = ground[sw];
00227
00228 if (h < btScalar(0.05f))
00229 continue;
00230
00231 if (h <= btScalar(0.01f))
00232 continue;
00233
00234 btVector3 boxMin = btVector3(fluid->widthPos(i), g, fluid->lengthPos(j));
00235 btVector3 boxMax = btVector3(fluid->widthPos(i + 1), g + h, fluid->lengthPos(j + 1));
00236 boxMin += com;
00237 boxMax += com;
00238
00239 debugDraw->drawBox(boxMin, boxMax, btVector3(btScalar(0.0f), btScalar(0.0f), btScalar(1.0f)));
00240 }
00241 }
00242 }
00243
00244 void btHfFluidRigidDynamicsWorld::debugDrawWorld()
00245 {
00246 if (getDebugDrawer())
00247 {
00248 int i;
00249 for (i = 0; i < this->m_hfFluids.size(); i++)
00250 {
00251 btHfFluid* phh = (btHfFluid*)this->m_hfFluids[i];
00252 switch (m_drawMode)
00253 {
00254 case DRAWMODE_NORMAL:
00255 drawHfFluidGround(m_debugDrawer, phh);
00256
00257 break;
00258 case DRAWMODE_VELOCITY:
00259 drawHfFluidGround(m_debugDrawer, phh);
00260
00261 drawHfFluidVelocity(m_debugDrawer, phh);
00262 break;
00263 default:
00264 btAssert(0);
00265 break;
00266 }
00267 }
00268 for (i = 0; i < this->m_collisionObjects.size(); i++)
00269 {
00270 btCollisionShape* shape = m_collisionObjects[i]->getCollisionShape();
00271 if (shape->getShapeType() == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE)
00272 {
00273 btHfFluidBuoyantConvexShape* buoyantShape = (btHfFluidBuoyantConvexShape*)shape;
00274 drawHfFluidBuoyantConvexShape(m_debugDrawer, m_collisionObjects[i], buoyantShape, m_bodyDrawMode);
00275 }
00276 }
00277 }
00278 btDiscreteDynamicsWorld::debugDrawWorld();
00279 }