From cc0c90693d123174d31bc81a5816c634ecb41311 Mon Sep 17 00:00:00 2001 From: samisalreadytaken <46823719+samisalreadytaken@users.noreply.github.com> Date: Thu, 17 Nov 2022 08:48:10 +0300 Subject: [PATCH] Optimise func_fake_worldportal render code Consistent and descriptive variable names, simplified calculations. --- .../mapbase/c_func_fake_worldportal.cpp | 90 +++-------- .../client/mapbase/c_func_fake_worldportal.h | 4 +- sp/src/game/client/viewrender.cpp | 143 +++++++----------- sp/src/game/client/viewrender.h | 2 +- 4 files changed, 70 insertions(+), 169 deletions(-) diff --git a/sp/src/game/client/mapbase/c_func_fake_worldportal.cpp b/sp/src/game/client/mapbase/c_func_fake_worldportal.cpp index 1cae8ebe..3a5751d1 100644 --- a/sp/src/game/client/mapbase/c_func_fake_worldportal.cpp +++ b/sp/src/game/client/mapbase/c_func_fake_worldportal.cpp @@ -58,70 +58,11 @@ bool C_FuncFakeWorldPortal::ShouldDraw() } -//----------------------------------------------------------------------------- -// Do we have a fake world portal in view? -//----------------------------------------------------------------------------- -C_FuncFakeWorldPortal *IsFakeWorldPortalInView( const CViewSetup& view, cplane_t &plane ) -{ - // Early out if no cameras - C_FuncFakeWorldPortal *pReflectiveGlass = GetFakeWorldPortalList(); - if ( !pReflectiveGlass ) - return NULL; - - Frustum_t frustum; - GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum ); - - cplane_t localPlane; - Vector vecOrigin, vecWorld, vecDelta, vecForward; - AngleVectors( view.angles, &vecForward, NULL, NULL ); - - for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext ) - { - if ( pReflectiveGlass->IsDormant() ) - continue; - - if ( pReflectiveGlass->m_iViewHideFlags & (1 << CurrentViewID()) ) - continue; - - Vector vecMins, vecMaxs; - pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs ); - if ( R_CullBox( vecMins, vecMaxs, frustum ) ) - continue; - - const model_t *pModel = pReflectiveGlass->GetModel(); - const matrix3x4_t& mat = pReflectiveGlass->EntityToWorldTransform(); - - int nCount = modelinfo->GetBrushModelPlaneCount( pModel ); - for ( int i = 0; i < nCount; ++i ) - { - modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecOrigin ); - - MatrixTransformPlane( mat, localPlane, plane ); // Transform to world space - VectorTransform( vecOrigin, mat, vecWorld ); - - if ( view.origin.Dot( plane.normal ) <= plane.dist ) // Check for view behind plane - continue; - - VectorSubtract( vecWorld, view.origin, vecDelta ); // Backface cull - if ( vecDelta.Dot( plane.normal ) >= 0 ) - continue; - - // Must have valid plane - if ( !pReflectiveGlass->m_hTargetPlane ) - continue; - - return pReflectiveGlass; - } - } - - return NULL; -} - //----------------------------------------------------------------------------- // Iterates through fake world portals instead of just picking one //----------------------------------------------------------------------------- C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view, - cplane_t &plane, Vector &vecPlaneOrigin, const Frustum_t &frustum ) + Vector &vecAbsPlaneNormal, Vector &vecPlaneLocalOrigin, const Frustum_t &frustum ) { // Early out if no cameras C_FuncFakeWorldPortal *pReflectiveGlass = NULL; @@ -130,8 +71,9 @@ C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const else pReflectiveGlass = pStart->m_pNext; - cplane_t localPlane; - Vector vecOrigin, vecWorld, vecDelta; + cplane_t localPlane, worldPlane; + Vector vecMins, vecMaxs, vecLocalOrigin, vecAbsOrigin, vecDelta; + for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext ) { if ( pReflectiveGlass->IsDormant() ) @@ -140,7 +82,10 @@ C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const if ( pReflectiveGlass->m_iViewHideFlags & (1 << CurrentViewID()) ) continue; - Vector vecMins, vecMaxs; + // Must have valid plane + if ( !pReflectiveGlass->m_hTargetPlane ) + continue; + pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs ); if ( R_CullBox( vecMins, vecMaxs, frustum ) ) continue; @@ -151,23 +96,22 @@ C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const int nCount = modelinfo->GetBrushModelPlaneCount( pModel ); for ( int i = 0; i < nCount; ++i ) { - modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecOrigin ); + modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecLocalOrigin ); - MatrixTransformPlane( mat, localPlane, plane ); // Transform to world space - VectorTransform( vecOrigin, mat, vecWorld ); + MatrixTransformPlane( mat, localPlane, worldPlane ); // Transform to world space - if ( view.origin.Dot( plane.normal ) <= plane.dist ) // Check for view behind plane + if ( view.origin.Dot( worldPlane.normal ) <= worldPlane.dist ) // Check for view behind plane continue; - VectorSubtract( vecWorld, view.origin, vecDelta ); // Backface cull - if ( vecDelta.Dot( plane.normal ) >= 0 ) + VectorTransform( vecLocalOrigin, mat, vecAbsOrigin ); + VectorSubtract( vecAbsOrigin, view.origin, vecDelta ); + + if ( vecDelta.Dot( worldPlane.normal ) >= 0 ) // Backface cull continue; - // Must have valid plane - if ( !pReflectiveGlass->m_hTargetPlane ) - continue; + vecPlaneLocalOrigin = vecLocalOrigin; + vecAbsPlaneNormal = worldPlane.normal; - vecPlaneOrigin = vecOrigin; return pReflectiveGlass; } } diff --git a/sp/src/game/client/mapbase/c_func_fake_worldportal.h b/sp/src/game/client/mapbase/c_func_fake_worldportal.h index 1bae2de0..7912e2cb 100644 --- a/sp/src/game/client/mapbase/c_func_fake_worldportal.h +++ b/sp/src/game/client/mapbase/c_func_fake_worldportal.h @@ -53,10 +53,8 @@ public: //----------------------------------------------------------------------------- // Do we have reflective glass in view? If so, what's the reflection plane? //----------------------------------------------------------------------------- -C_FuncFakeWorldPortal *IsFakeWorldPortalInView( const CViewSetup& view, cplane_t &plane ); - C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view, - cplane_t &plane, Vector &vecPlaneOrigin, const Frustum_t &frustum ); + Vector &vecAbsPlaneNormal, Vector &vecPlaneOrigin, const Frustum_t &frustum ); #endif // C_FUNC_FAKE_WORLDPORTAL diff --git a/sp/src/game/client/viewrender.cpp b/sp/src/game/client/viewrender.cpp index 2acc9d91..e77bb1ea 100644 --- a/sp/src/game/client/viewrender.cpp +++ b/sp/src/game/client/viewrender.cpp @@ -2106,20 +2106,18 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT Frustum_t frustum; GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum ); - cplane_t portalPlane; - Vector vecPlaneOrigin; - //C_FuncFakeWorldPortal *pPortalEnt = IsFakeWorldPortalInView( view, portalPlane ); - //if ( pPortalEnt ) - C_FuncFakeWorldPortal *pPortalEnt = NextFakeWorldPortal( NULL, view, portalPlane, vecPlaneOrigin, frustum ); + Vector vecAbsPlaneNormal; + Vector vecPlaneLocalOrigin; + C_FuncFakeWorldPortal *pPortalEnt = NextFakeWorldPortal( NULL, view, vecAbsPlaneNormal, vecPlaneLocalOrigin, frustum ); while ( pPortalEnt != NULL ) { ITexture *pCameraTarget = pPortalEnt->RenderTarget(); int width = pCameraTarget->GetActualWidth(); int height = pCameraTarget->GetActualHeight(); - DrawFakeWorldPortal( pCameraTarget, pPortalEnt, viewMiddle, C_BasePlayer::GetLocalPlayer(), 0, 0, width, height, view, portalPlane, vecPlaneOrigin ); + DrawFakeWorldPortal( pCameraTarget, pPortalEnt, viewMiddle, C_BasePlayer::GetLocalPlayer(), 0, 0, width, height, view, vecAbsPlaneNormal, vecPlaneLocalOrigin ); - pPortalEnt = NextFakeWorldPortal( pPortalEnt, view, portalPlane, vecPlaneOrigin, frustum ); + pPortalEnt = NextFakeWorldPortal( pPortalEnt, view, vecAbsPlaneNormal, vecPlaneLocalOrigin, frustum ); } #endif } @@ -3537,8 +3535,6 @@ bool CViewRender::DrawOneMonitor( ITexture *pRenderTarget, int cameraNum, C_Poin } #ifdef MAPBASE -ConVar r_fakeworldportal_debug("r_fakeworldportal_debug", "0"); - //----------------------------------------------------------------------------- // Purpose: Sets up scene and renders WIP fake world portal view. // Based on code from monitors, mirrors, and logic_measure_movement. @@ -3555,7 +3551,7 @@ ConVar r_fakeworldportal_debug("r_fakeworldportal_debug", "0"); //----------------------------------------------------------------------------- bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, int x, int y, int width, int height, - const CViewSetup &mainView, cplane_t &ourPlane, const Vector &vecPlaneOrigin ) + const CViewSetup &mainView, const Vector &vecAbsPlaneNormal, const Vector &vecPlaneLocalOrigin ) { #ifdef USE_MONITORS VPROF_INCREMENT_COUNTER( "cameras rendered", 1 ); @@ -3586,85 +3582,52 @@ bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldP } } - monitorView.width = width; - monitorView.height = height; monitorView.x = x; monitorView.y = y; - - monitorView.origin = mainView.origin; - monitorView.angles = mainView.angles; - - // Debug stuff - static float flLastDebugTime = 0.0f; - bool bDebug = r_fakeworldportal_debug.GetBool() && gpGlobals->curtime > flLastDebugTime; - - // - // Calculate the angles for the fake portal plane - // - QAngle angTargetAngles = pCameraEnt->m_hTargetPlane->GetAbsAngles() - pCameraEnt->m_PlaneAngles; - QAngle angFakePortalAngles; - - // Get vectors from our original angles. - Vector vOurForward, vOurRight, vOurUp; - AngleVectors( pCameraEnt->GetAbsAngles(), &vOurForward, &vOurRight, &vOurUp ); - - Quaternion quat; - BasisToQuaternion( ourPlane.normal, vOurRight, vOurUp, quat ); - QuaternionAngles( quat, angFakePortalAngles ); - - if (bDebug) - { - // RED - Initial player origin - debugoverlay->AddBoxOverlay( monitorView.origin, Vector(-32,-32,-32), Vector(32,32,32), monitorView.angles, 255, 0, 0, 128, 10.0f ); - - // YELLOW - Portal origin - debugoverlay->AddBoxOverlay( pCameraEnt->GetAbsOrigin(), Vector(-32,-32,-32), Vector(32,32,32), angFakePortalAngles, 255, 224, 0, 128, 10.0f ); - } - - // - // Translate the actual portal view position to be relative to the target - // - matrix3x4_t matPlayer, matPortal, matPlayerToPortal; - AngleIMatrix( monitorView.angles, monitorView.origin, matPlayer ); - AngleMatrix( angFakePortalAngles, pCameraEnt->GetAbsOrigin(), matPortal ); - ConcatTransforms( matPlayer, matPortal, matPlayerToPortal ); - - // Apply the scale factor - if ( pCameraEnt->m_flScale > 0 ) - { - Vector vecTranslation; - MatrixGetColumn( matPlayerToPortal, 3, vecTranslation ); - vecTranslation /= pCameraEnt->m_flScale; - MatrixSetColumn( vecTranslation, 3, matPlayerToPortal ); - } - - matrix3x4_t matTarget; - AngleMatrix( angTargetAngles, pCameraEnt->m_hTargetPlane->GetAbsOrigin(), matTarget ); - - // Now apply the new matrix to the new reference point - matrix3x4_t matPortalToPlayer, matNewPlayerPosition; - MatrixInvert( matPlayerToPortal, matPortalToPlayer ); - - ConcatTransforms( matTarget, matPortalToPlayer, matNewPlayerPosition ); - - MatrixAngles( matNewPlayerPosition, monitorView.angles, monitorView.origin ); - - if (bDebug) - { - // BLUE - Target origin - debugoverlay->AddBoxOverlay( pCameraEnt->m_hTargetPlane->GetAbsOrigin(), Vector(-32,-32,-32), Vector(32,32,32), angTargetAngles, 0, 0, 255, 128, 10.0f ); - - // GREEN - Final origin - debugoverlay->AddBoxOverlay( monitorView.origin, Vector(-32,-32,-32), Vector(32,32,32), monitorView.angles, 0, 255, 0, 128, 10.0f ); - - flLastDebugTime = gpGlobals->curtime + 5.0f; - } - - monitorView.fov = mainView.fov; + monitorView.width = width; + monitorView.height = height; monitorView.m_bOrtho = mainView.m_bOrtho; + monitorView.fov = mainView.fov; monitorView.m_flAspectRatio = mainView.m_flAspectRatio; monitorView.m_bViewToProjectionOverride = false; + matrix3x4_t worldToView; + AngleIMatrix( mainView.angles, mainView.origin, worldToView ); + + matrix3x4_t targetToWorld; + { + // NOTE: m_PlaneAngles is angle offset + QAngle targetAngles = pCameraEnt->m_hTargetPlane->GetAbsAngles() - pCameraEnt->m_PlaneAngles; + AngleMatrix( targetAngles, pCameraEnt->m_hTargetPlane->GetAbsOrigin(), targetToWorld ); + } + + matrix3x4_t portalToWorld; + { + Vector left, up; + VectorVectors( vecAbsPlaneNormal, left, up ); + VectorNegate( left ); + portalToWorld.Init( vecAbsPlaneNormal, left, up, pCameraEnt->GetAbsOrigin() ); + } + + matrix3x4_t portalToView; + ConcatTransforms( worldToView, portalToWorld, portalToView ); + + if ( pCameraEnt->m_flScale > 0.0f ) + { + portalToView[0][3] /= pCameraEnt->m_flScale; + portalToView[1][3] /= pCameraEnt->m_flScale; + portalToView[2][3] /= pCameraEnt->m_flScale; + } + + matrix3x4_t viewToPortal; + MatrixInvert( portalToView, viewToPortal ); + + matrix3x4_t newViewToWorld; + ConcatTransforms( targetToWorld, viewToPortal, newViewToWorld ); + + MatrixAngles( newViewToWorld, monitorView.angles, monitorView.origin ); + + // @MULTICORE (toml 8/11/2006): this should be a renderer.... int nClearFlags = (VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR | VIEW_CLEAR_OBEY_STENCIL); bool bDrew3dSkybox = false; @@ -3687,21 +3650,17 @@ bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldP SafeRelease( pSkyView ); } - // - // Make a clipping plane for the target view - // Vector4D plane; - Vector vecAnglesNormal; - AngleVectors( angTargetAngles, &vecAnglesNormal ); - VectorNormalize( vecAnglesNormal ); - VectorCopy( -vecAnglesNormal, plane.AsVector3D() ); + MatrixGetColumn( targetToWorld, 0, plane.AsVector3D() ); + VectorNormalize( plane.AsVector3D() ); + VectorNegate( plane.AsVector3D() ); // The portal plane's distance from the actual brush's origin - float flPlaneDist = vecPlaneOrigin.Length(); + float flPlaneDist = vecPlaneLocalOrigin.Length(); // The target's distance from world origin - plane.w = -((pCameraEnt->m_hTargetPlane->GetAbsOrigin() * vecAnglesNormal).Length() + flPlaneDist) + 0.1f; + plane.w = -((pCameraEnt->m_hTargetPlane->GetAbsOrigin() * plane.AsVector3D()).Length() + flPlaneDist) + 0.1f; CMatRenderContextPtr pRenderContext( materials ); pRenderContext->PushCustomClipPlane( plane.Base() ); diff --git a/sp/src/game/client/viewrender.h b/sp/src/game/client/viewrender.h index 936a282b..0aa24db6 100644 --- a/sp/src/game/client/viewrender.h +++ b/sp/src/game/client/viewrender.h @@ -454,7 +454,7 @@ private: #ifdef MAPBASE bool DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, int x, int y, int width, int height, - const CViewSetup &mainView, cplane_t &ourPlane, const Vector &vecPlaneOrigin ); + const CViewSetup &mainView, const Vector &vecAbsPlaneNormal, const Vector &vecPlaneOrigin ); #endif // Drawing primitives