00001 #include "ODEFluid.h"
00002 #include "MercuryLog.h"
00003
00004 REGISTER_ODE_OBJECT_CLASS( ODEFluid )
00005
00006 ODEFluid::~ODEFluid()
00007 {
00008
00009 }
00010
00011 bool ODEFluid::LoadFromINI( MercuryINI & pINI, const MString & sShapeName, const dWorldID & oWorld )
00012 {
00013 MercuryODEObjectLoadable::LoadFromINI( pINI, sShapeName, oWorld );
00014
00015 m_fViscosity = GetParameter( "Viscosity" ).GetValueF();
00016 m_pDirection = MercuryPoint(
00017 GetParameter( "DirectionX" ).GetValueF(),
00018 GetParameter( "DirectionY" ).GetValueF(),
00019 GetParameter( "DirectionZ" ).GetValueF() );
00020
00021 m_pForce = MercuryPoint(
00022 GetParameter( "ForceX" ).GetValueF(),
00023 GetParameter( "ForceY" ).GetValueF(),
00024 GetParameter( "ForceZ" ).GetValueF() );
00025
00026 SetDrawOrder(40000);
00027 SetDiffuse( MercuryColor(1,1,1,0.5) );
00028 return true;
00029 }
00030
00031 void ODEFluid::Update( const float dTime )
00032 {
00033
00034 }
00035
00036 void ODEFluid::PreCycleUpdate( const float dTime )
00037 {
00038 float fRelForce = 10.0f;
00039
00040 for( std::map< dBodyID, HitObject >::iterator i = m_pHitObjects.begin(); i != m_pHitObjects.end(); ++i )
00041 {
00042 HitObject * pHit = &i->second;
00043 float fHitForcePart = fRelForce/(float(pHit->m_pDirectionForce.size()));
00044
00045 for( unsigned j = 0; j < pHit->m_pDirectionForce.size(); j++ )
00046 {
00047 float fForceAmount = fHitForcePart * ( pHit->m_pDirectionForce[j] * pHit->m_pDirectionForce[j] * pHit->m_pDirectionForce[j] / 40 );
00048 fForceAmount = Clamp(fForceAmount,0.0f,7.0f);
00049 dBodyAddForceAtPos( (i->first),
00050 m_pForce.x * fForceAmount, m_pForce.y * fForceAmount, m_pForce.z * fForceAmount,
00051 pHit->m_pAtForces[j].x, pHit->m_pAtForces[j].y, pHit->m_pAtForces[j].z );
00052 }
00053
00054 const float * fCurLinearVel = dBodyGetLinearVel( i->first );
00055 const float * fCurAngularVel = dBodyGetAngularVel( i->first );
00056
00057 float fViscAmount = m_fViscosity*dTime*i->second.fFric;
00058 fViscAmount=Clamp(fViscAmount,0.0f,1.0f);
00059
00060 dBodySetLinearVel( i->first, fCurLinearVel[0] * (1-fViscAmount) + m_pDirection.x * fViscAmount,
00061 fCurLinearVel[1] * (1-fViscAmount) + m_pDirection.y * fViscAmount,
00062 fCurLinearVel[2] * (1-fViscAmount) + m_pDirection.z * fViscAmount );
00063 dBodySetAngularVel( i->first, fCurAngularVel[0] * (1-fViscAmount) * (1-fViscAmount),
00064 fCurAngularVel[1] * (1-fViscAmount) * (1-fViscAmount),
00065 fCurAngularVel[2] * (1-fViscAmount) * (1-fViscAmount) );
00066 }
00067 m_pHitObjects.clear();
00068 }
00069
00070 bool ODEFluid::Collide( MercuryODEObject * pHit, dContact & pContact, MercuryODEWorld * pWorld )
00071 {
00072 if ( pHit->m_oBody )
00073 {
00074
00075 if( !dBodyIsEnabled( pHit->m_oBody ) )
00076 return false;
00077
00078 m_pHitObjects[pHit->m_oBody].m_pDirectionForce.push_back( pContact.geom.depth );
00079 m_pHitObjects[pHit->m_oBody].m_pAtForces.push_back( MercuryPoint(
00080 pContact.geom.pos[0], pContact.geom.pos[1], pContact.geom.pos[2] ) );
00081
00082 if( pHit->GetParameter("FluidFriction").GetType() == PSElement::NIL )
00083 m_pHitObjects[pHit->m_oBody].fFric = 1;
00084 else
00085 m_pHitObjects[pHit->m_oBody].fFric = pHit->GetParameter("FluidFriction").GetValueF();
00086 }
00087 return false;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116