www.pudn.com > fluid.rar > FluidAnimator2D.h, change:2006-10-27,size:6893b
#ifndef __Fluid_Animator_2D__
#define __Fluid_Animator_2D__
#include "DTKDeviceListener.h"
#include "DTKColorValue.h"
namespace DTK
{
enum TexturePrecision
{
TP_16BIT = 0,
TP_32BIT
};
class FluidAnimator2D : public DeviceListener
{
public:
struct ExternalForce
{
ExternalForce(float r=1.0f, const Vector2& p_rt=Vector2::ZERO, const Vector2& f_rp=Vector2::ZERO)
:m_r(r),m_p_rt(p_rt),m_f_rp(f_rp){}
float m_r; //force radius
Vector2 m_p_rt; //force center
Vector2 m_f_rp; //force vector
};
public:
FluidAnimator2D(uint uWidth =64,uint uHeight = 64,TexturePrecision = TP_32BIT);
void onCreateDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc = NULL, void* pUserContext=NULL );
void onResetDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc = NULL, void* pUserContext=NULL );
void onLostDevice( void* pUserContext=NULL );
void onDestroyDevice( void* pUserContext=NULL );
void reset();
void addExternalForce(const ExternalForce& force);
void enableDiffuse(bool bEnable);
void enableAdvection(bool bEnable);
void enableProject(bool bEnable);
void enableVelocityBoundary(bool bEnable);
void enablePressureBoundary(bool bEnable);
void enableVorticityConfinement(bool bEnable);
void setParticleDistance(float fD);
float getParticleDistance();
void setDissipation(float dis);
float getDissipation();
void setViscous(float fV);
float getViscous();
void setVorticityConfinementCoefficient(float vorCoe);
float getVorticityConfinementCoefficient();
void setIterateNumber(uint uNum);
uint getIterateNumber();
Vector2 getSize();
IDirect3DTexture9* getForceField();
IDirect3DTexture9* getVelocityField();
IDirect3DTexture9* getPressureField();
IDirect3DTexture9* getVorticityField();
/*!
\param dt
delta time,in seconds
*/
void timeStep(float dt);
private:
IDirect3DDevice9* m_pD3DDevice;
TexturePrecision m_texPrec;
uint m_uWidth; //grid width
uint m_uHeight; //grid height
float m_d; //grid distance
float m_dis; //dissipation
float m_v; //fluid viscous
float m_vorCoe; //vorticity confinement coefficient
bool m_bDiffuse;
bool m_bAdvection;
bool m_bProject;
bool m_bVelocityBoundary;
bool m_bPressureBoundary;
bool m_bVorticityConfinement;
static const int BUFFER_NUM = 3;
IDirect3DTexture9* m_apVelFieldTex[BUFFER_NUM];
IDirect3DSurface9* m_apVelFieldSurf[BUFFER_NUM];
uint m_uSrcVelField; //velocity field u0 for current frame. 0-3
uint m_uActiveVelField; //0-2
IDirect3DTexture9* m_apScalarFieldTex[BUFFER_NUM];
IDirect3DSurface9* m_apScalarFieldSurf[BUFFER_NUM];
uint m_uSrcScalarField;
uint m_uActiveScalarField;
uint m_uNumItr;//number of Jacobi iteration
//uint m_uNumItrDiffuse;//number of Jacobi iteration for diffuse term
//uint m_uNumItrPressure;//number of Jacobi iteration for pressure term
IDirect3DTexture9* m_pForceTex;
IDirect3DSurface9* m_pForceSurf;
ExternalForce m_extForce;
IDirect3DTexture9* m_pVorticityTex;
IDirect3DSurface9* m_pVorticitySurf;
ID3DXEffect* m_pShader;
D3DXHANDLE m_hTexSize;
D3DXHANDLE m_hDx;
D3DXHANDLE m_hDy;
D3DXHANDLE m_hD;
D3DXHANDLE m_hV;
D3DXHANDLE m_hDis;
D3DXHANDLE m_hVorCoe;
D3DXHANDLE m_hDt;
D3DXHANDLE m_hRf_rt;
D3DXHANDLE m_hPosf_rt;
D3DXHANDLE m_hForce_rp;
D3DXHANDLE m_hForceFieldTex;
D3DXHANDLE m_hVelFieldTex;
D3DXHANDLE m_hActiveVelFieldTex;
D3DXHANDLE m_hScalarFieldTex;
D3DXHANDLE m_hActiveScalarFieldTex;
D3DXHANDLE m_hTimeStepTech;
enum TimeStepPass
{
TSP_ADD_FORCE = 0,
TSP_ADVECTION,
TSP_DIFFUSE,
TSP_COMPUTE_DIVERGENCE,
TSP_COMPUTE_PRESSURE,
TSP_PROJECT,
TSP_VELOCITY_BOUNDARY,
TSP_PRESSURE_BOUNDARY,
TSP_COMPUTE_VORTICITY,
TSP_VORTICITY_CONFINEMENT
};
private:
void clearRenderTarget(IDirect3DSurface9* pSurf);
/*! \brief add force term to velocity field(render target 0)
use u0 as source velocity field
use u1 as temp velocity field
\return
u0 will keep the result
*/
void addForceTerm(float dt);
/* add advection term
use u0 as source velocity field
use u1 as temp velocity field
\return
u0 will keep the result
*/
void advection(float dt);
/*
use u0 as source velocity field
use u00 and u01 as temp velocity field for iteration
\return
u0 will keep the result
*/
void diffuse(float dt);
uint u0() {return m_uSrcVelField;}
uint u1() {return (m_uSrcVelField+1)%BUFFER_NUM;}
uint _u00(){return m_uActiveVelField;}
uint _u01(){return (m_uActiveVelField+1)%(BUFFER_NUM-1);}
uint u00() {return (m_uSrcVelField+1+_u00())%BUFFER_NUM;}
uint u01() {return (m_uSrcVelField+1+_u01())%BUFFER_NUM;}
void loop_u0(uint uSrcVelField){assert (uSrcVelField/BUFFER_NUM == 0); m_uSrcVelField = uSrcVelField;}
void loop_u00(uint uActiveVelField){assert (uActiveVelField/(BUFFER_NUM-1) == 0);
m_uActiveVelField = uActiveVelField;}
/*! project velocity field to zero divergence
use u0 as source velocity field
use u1 as temp velocity field
\return
u0 will keep the result
*/
void project();
/*
use s0 as initial pressure field for Jacobi iterate
use s00 as divergence of source velocity field
use s01 as temp pressure field
\return
result will be kept in s0
*/
void computePressure();
/*
after each time step
s0 is pressure field
*/
uint s0() {return m_uSrcScalarField;}
uint s1() {return (m_uSrcScalarField+1)%BUFFER_NUM;}
uint _s00(){return m_uActiveScalarField;}
uint _s01(){return (m_uActiveScalarField+1)%(BUFFER_NUM-1);}
uint s00() {return (m_uSrcScalarField+1+_s00())%BUFFER_NUM;}
uint s01() {return (m_uSrcScalarField+1+_s01())%BUFFER_NUM;}
void loop_s0(uint uSrcScalarField){assert (uSrcScalarField/BUFFER_NUM == 0);
m_uSrcScalarField = uSrcScalarField;}
void loop_s00(uint uActiveScalarField){assert (uActiveScalarField/(BUFFER_NUM-1) == 0);
m_uActiveScalarField = uActiveScalarField;}
void set_s00(uint s00){((((s00 + BUFFER_NUM - s0())%3)+1)%2);}
/*apply boundary condition
use u0 as source velocity field
use u1 as temp velocity field
u0 will keep the result
use s0 as source pressure field
use s1 as temp pressure field
s0 will keep the result
*/
void boundary();
/*
use u0 as source pressure field
*/
void computeVorticity();
void computeVorticityConfinement();
void createShader();
void updateSharedParam(float dt);
void clearup();
};
}
#endif //end ifndef __Fluid_Animator_2D__