summaryrefslogtreecommitdiff
path: root/movieobjects/dmecamera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'movieobjects/dmecamera.cpp')
-rw-r--r--movieobjects/dmecamera.cpp288
1 files changed, 288 insertions, 0 deletions
diff --git a/movieobjects/dmecamera.cpp b/movieobjects/dmecamera.cpp
new file mode 100644
index 0000000..f593602
--- /dev/null
+++ b/movieobjects/dmecamera.cpp
@@ -0,0 +1,288 @@
+//========= 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;
+}
+
+