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__