ODEFluid.cpp

Go to the documentation of this file.
00001 #include "ODEFluid.h"
00002 #include "MercuryLog.h"
00003 
00004 REGISTER_ODE_OBJECT_CLASS( ODEFluid )
00005 
00006 ODEFluid::~ODEFluid()
00007 {
00008     //Do nothing?
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     //Do nothing?
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         //If the body isn't enabled; don't don't start piling on forces to it
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;   //Don't make a contact joint for this object.
00088 }
00089 
00090 /* 
00091  * Copyright (c) 2006, Charles Lohr
00092  * All rights reserved.
00093  *
00094  * Redistribution and use in source and binary forms, with or
00095  * without modification, are permitted provided that the following
00096  * conditions are met:
00097  *  -   Redistributions of source code must retain the above
00098  *      copyright notice, this list of conditions and the following disclaimer.
00099  *  -   Redistributions in binary form must reproduce the above copyright
00100  *      notice, this list of conditions and the following disclaimer in
00101  *      the documentation and/or other materials provided with the distribution.
00102  *  -   Neither the name of the Mercury Engine nor the names of its
00103  *      contributors may be used to endorse or promote products derived from
00104  *      this software without specific prior written permission.
00105  *
00106  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00107  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00108  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00109  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00110  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00111  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00112  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00113  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00114  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00115  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00116  */

Hosted by SourceForge.net Logo