|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmecamera.h"
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "mathlib/vector.h"
#include "movieobjects/dmetransform.h"
#include "materialsystem/imaterialsystem.h"
#include "movieobjects_interfaces.h"
#include "tier2/tier2.h"
// FIXME: REMOVE
#include "istudiorender.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeCamera, CDmeCamera );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeCamera::OnConstruction() { m_fieldOfView.InitAndSet( this, "fieldOfView", 30.0f );
// FIXME: This currently matches the client DLL for HL2
// but we probably need a way of getting this state from the client DLL
m_zNear.InitAndSet( this, "znear", 3.0f ); m_zFar.InitAndSet( this, "zfar", 16384.0f * 1.73205080757f );
m_fFocalDistance.InitAndSet( this, "focalDistance", 72.0f); m_fAperture.InitAndSet( this, "aperture", 0.2f); m_fShutterSpeed.InitAndSet( this, "shutterSpeed", 1.0f / 48.0f ); m_fToneMapScale.InitAndSet( this, "toneMapScale", 1.0f ); m_fBloomScale.InitAndSet( this, "bloomScale", 0.28f ); m_nDoFQuality.InitAndSet( this, "depthOfFieldQuality", 0 ); m_nMotionBlurQuality.InitAndSet( this, "motionBlurQuality", 0 ); }
void CDmeCamera::OnDestruction() { } //-----------------------------------------------------------------------------
// Loads the material system view matrix based on the transform
//-----------------------------------------------------------------------------
void CDmeCamera::LoadViewMatrix( bool bUseEngineCoordinateSystem ) { if ( !g_pMaterialSystem ) return;
CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); VMatrix view; GetViewMatrix( view, bUseEngineCoordinateSystem ); pRenderContext->MatrixMode( MATERIAL_VIEW ); pRenderContext->LoadMatrix( view ); }
//-----------------------------------------------------------------------------
// Loads the material system projection matrix based on the fov, etc.
//-----------------------------------------------------------------------------
void CDmeCamera::LoadProjectionMatrix( int nDisplayWidth, int nDisplayHeight ) { if ( !g_pMaterialSystem ) return;
CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); pRenderContext->MatrixMode( MATERIAL_PROJECTION );
VMatrix proj; GetProjectionMatrix( proj, nDisplayWidth, nDisplayHeight ); pRenderContext->LoadMatrix( proj ); }
//-----------------------------------------------------------------------------
// Sets up studiorender camera state
//-----------------------------------------------------------------------------
void CDmeCamera::LoadStudioRenderCameraState() { // FIXME: Remove this! This should automatically happen in DrawModel
// in studiorender.
if ( !g_pStudioRender ) return;
matrix3x4_t transform; GetTransform()->GetTransform( transform );
Vector vecOrigin, vecRight, vecUp, vecForward; MatrixGetColumn( transform, 0, vecRight ); MatrixGetColumn( transform, 1, vecUp ); MatrixGetColumn( transform, 2, vecForward ); MatrixGetColumn( transform, 3, vecOrigin ); g_pStudioRender->SetViewState( vecOrigin, vecRight, vecUp, vecForward ); }
//-----------------------------------------------------------------------------
// Returns the x FOV (the full angle)
//-----------------------------------------------------------------------------
float CDmeCamera::GetFOVx() const { return m_fieldOfView; }
void CDmeCamera::SetFOVx( float fov ) { m_fieldOfView = fov; }
//-----------------------------------------------------------------------------
// Returns the focal distance in inches
//-----------------------------------------------------------------------------
float CDmeCamera::GetFocalDistance() const { return m_fFocalDistance; }
//-----------------------------------------------------------------------------
// Sets the focal distance in inches
//-----------------------------------------------------------------------------
void CDmeCamera::SetFocalDistance( const float &fFocalDistance ) { m_fFocalDistance = fFocalDistance; }
//-----------------------------------------------------------------------------
// Returns the camera aperture in inches
//-----------------------------------------------------------------------------
float CDmeCamera::GetAperture() const { return m_fAperture; }
//-----------------------------------------------------------------------------
// Returns the camera aperture in inches
//-----------------------------------------------------------------------------
float CDmeCamera::GetShutterSpeed() const { return m_fShutterSpeed; }
//-----------------------------------------------------------------------------
// Returns the tone map scale
//-----------------------------------------------------------------------------
float CDmeCamera::GetToneMapScale() const { return m_fToneMapScale; }
//-----------------------------------------------------------------------------
// Returns the bloom scale
//-----------------------------------------------------------------------------
float CDmeCamera::GetBloomScale() const { return m_fBloomScale; }
//-----------------------------------------------------------------------------
// Returns the number of Depth of Field samples
//-----------------------------------------------------------------------------
int CDmeCamera::GetDepthOfFieldQuality() const { return m_nDoFQuality; }
//-----------------------------------------------------------------------------
// Returns the number of Motion Blur samples
//-----------------------------------------------------------------------------
int CDmeCamera::GetMotionBlurQuality() const { return m_nMotionBlurQuality; }
//-----------------------------------------------------------------------------
// Returns the view direction
//-----------------------------------------------------------------------------
void CDmeCamera::GetViewDirection( Vector *pDirection ) { matrix3x4_t transform; GetTransform()->GetTransform( transform ); MatrixGetColumn( transform, 2, *pDirection );
// We look down the -z axis
*pDirection *= -1.0f; }
//-----------------------------------------------------------------------------
// Sets up render state in the material system for rendering
//-----------------------------------------------------------------------------
void CDmeCamera::SetupRenderState( int nDisplayWidth, int nDisplayHeight, bool bUseEngineCoordinateSystem /* = false */ ) { LoadViewMatrix( bUseEngineCoordinateSystem ); LoadProjectionMatrix( nDisplayWidth, nDisplayHeight ); LoadStudioRenderCameraState( ); }
//-----------------------------------------------------------------------------
// accessors for generated matrices
//-----------------------------------------------------------------------------
void CDmeCamera::GetViewMatrix( VMatrix &view, bool bUseEngineCoordinateSystem /* = false */ ) { matrix3x4_t transform, invTransform; CDmeTransform *pTransform = GetTransform(); pTransform->GetTransform( transform );
if ( bUseEngineCoordinateSystem ) { VMatrix matRotate( transform ); VMatrix matRotateZ; MatrixBuildRotationAboutAxis( matRotateZ, Vector(0,0,1), -90 ); MatrixMultiply( matRotate, matRotateZ, matRotate );
VMatrix matRotateX; MatrixBuildRotationAboutAxis( matRotateX, Vector(1,0,0), 90 ); MatrixMultiply( matRotate, matRotateX, matRotate ); transform = matRotate.As3x4(); }
MatrixInvert( transform, invTransform ); view = invTransform; }
void CDmeCamera::GetProjectionMatrix( VMatrix &proj, int width, int height ) { float flFOV = m_fieldOfView.Get(); float flZNear = m_zNear.Get(); float flZFar = m_zFar.Get(); float flApsectRatio = (float)width / (float)height;
// MatrixBuildPerspective( proj, flFOV, flFOV * flApsectRatio, flZNear, flZFar );
#if 1
float halfWidth = tan( flFOV * M_PI / 360.0 ); float halfHeight = halfWidth / flApsectRatio; #else
float halfHeight = tan( flFOV * M_PI / 360.0 ); float halfWidth = flApsectRatio * halfHeight; #endif
memset( proj.Base(), 0, sizeof( proj ) ); proj[0][0] = 1.0f / halfWidth; proj[1][1] = 1.0f / halfHeight; proj[2][2] = flZFar / ( flZNear - flZFar ); proj[3][2] = -1.0f; proj[2][3] = flZNear * flZFar / ( flZNear - flZFar ); }
void CDmeCamera::GetViewProjectionInverse( VMatrix &viewprojinv, int width, int height ) { VMatrix view, proj; GetViewMatrix( view ); GetProjectionMatrix( proj, width, height );
VMatrix viewproj; MatrixMultiply( proj, view, viewproj ); bool success = MatrixInverseGeneral( viewproj, viewprojinv ); if ( !success ) { Assert( 0 ); MatrixInverseTR( viewproj, viewprojinv ); } }
//-----------------------------------------------------------------------------
// Computes the screen space position given a screen size
//-----------------------------------------------------------------------------
void CDmeCamera::ComputeScreenSpacePosition( const Vector &vecWorldPosition, int width, int height, Vector2D *pScreenPosition ) { VMatrix view, proj, viewproj; GetViewMatrix( view ); GetProjectionMatrix( proj, width, height ); MatrixMultiply( proj, view, viewproj );
Vector vecScreenPos; Vector3DMultiplyPositionProjective( viewproj, vecWorldPosition, vecScreenPos );
pScreenPosition->x = ( vecScreenPos.x + 1.0f ) * width / 2.0f; pScreenPosition->y = ( -vecScreenPos.y + 1.0f ) * height / 2.0f; }
|