#include "defines.h" #include "Water.h" #include "shader.h" #include "globals.h" #include "intrin.h" void Water::Init() { } void Water::Update(const D3DXMATRIX &mView, const D3DXMATRIX &mProj) { // Mirror reflection D3DXMATRIX mMirror; D3DXMatrixIdentity(&mMirror); mMirror._22 = -1.0f; mMirror._42 = 2.0f * m_fWaterLevel; m_ViewMatrix = mMirror * mView; // Extract new view position m_ViewPos.x = -(m_ViewMatrix._41 * m_ViewMatrix._11 + m_ViewMatrix._42 * m_ViewMatrix._12 + m_ViewMatrix._43 * m_ViewMatrix._13); m_ViewPos.y = -(m_ViewMatrix._41 * m_ViewMatrix._21 + m_ViewMatrix._42 * m_ViewMatrix._22 + m_ViewMatrix._43 * m_ViewMatrix._23); m_ViewPos.z = -(m_ViewMatrix._41 * m_ViewMatrix._31 + m_ViewMatrix._42 * m_ViewMatrix._32 + m_ViewMatrix._43 * m_ViewMatrix._33); // Extract camera direction m_ViewDir.x = m_ViewMatrix._13; m_ViewDir.y = m_ViewMatrix._23; m_ViewDir.z = m_ViewMatrix._33; float fEyeHeight = -(mView._41 * mView._21 + mView._42 * mView._22 + mView._43 * mView._23); float fReflectionClipHeight = m_fWaterLevel - min(max(fEyeHeight - m_fWaterLevel, 0.0f), 64.0f) / 32.0f; // Clip reflection m_ProjMatrix = ObliqueProjectionMatrix(m_ViewMatrix, mProj, D3DXPLANE(0.0f, -1.0f, 0.0f, fReflectionClipHeight)); } /// Returns the sign of the given value inline float Sign0(float v) { return (v > 0.0f) ? 1.0f : ((v < 0.0f) ? -1.0f : 0.0f); } // Computes a projection matrix that contains the given plane as near plane D3DXMATRIX Water::ObliqueProjectionMatrix(const D3DXMATRIX &mView, const D3DXMATRIX &mProjection, const D3DXPLANE &clipPlane) { // Compute inverse transpose (orthogonal matrix) D3DXMATRIX mViewInverseTranspose = mView; mViewInverseTranspose._14 = -(mView._41 * mView._11 + mView._42 * mView._12 + mView._43 * mView._13); mViewInverseTranspose._24 = -(mView._41 * mView._21 + mView._42 * mView._22 + mView._43 * mView._23); mViewInverseTranspose._34 = -(mView._41 * mView._31 + mView._42 * mView._32 + mView._43 * mView._33); mViewInverseTranspose._41 = mView._14; mViewInverseTranspose._42 = mView._24; mViewInverseTranspose._43 = mView._34; // Transform plane to view space D3DXPLANE viewClipPlane = -clipPlane; D3DXPlaneTransform(&viewClipPlane, &viewClipPlane, &mViewInverseTranspose); // Check clip plane orientation if(viewClipPlane.d > -0.001f) return mProjection; // Compute view-space corner point D3DXVECTOR4 vFarCorner = D3DXVECTOR4( Sign0(viewClipPlane.a + mProjection._31) / mProjection._11, Sign0(viewClipPlane.b + mProjection._32) / mProjection._22, -1.0f, (1.0f + mProjection._33) / mProjection._43 ); // Scale clip plane D3DXPLANE projClipPlane = viewClipPlane * (1.0f / D3DXPlaneDot(&viewClipPlane, &vFarCorner)); // Modify projection matrix return D3DXMATRIX(mProjection._11, mProjection._12, projClipPlane.a, mProjection._14, mProjection._21, mProjection._22, projClipPlane.b, mProjection._24, mProjection._31, mProjection._32, projClipPlane.c, mProjection._34, mProjection._41, mProjection._42, projClipPlane.d, mProjection._44); }