85 lines
3.0 KiB
C++
85 lines
3.0 KiB
C++
#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);
|
|
}
|