Files
bluflame/evoke-64k/trunk/ev10/Water.cpp
2026-04-18 22:31:51 +02:00

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);
}