Skip to content

Commit

Permalink
Optimise func_fake_worldportal render code
Browse files Browse the repository at this point in the history
Consistent and self explanatory variable names, simplified calculations.
  • Loading branch information
samisalreadytaken committed Nov 17, 2022
1 parent a1c8dba commit 55b8c8d
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 159 deletions.
90 changes: 17 additions & 73 deletions sp/src/game/client/mapbase/c_func_fake_worldportal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() )
Expand All @@ -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;
Expand All @@ -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 )
continue;
VectorTransform( vecLocalOrigin, mat, vecAbsOrigin );
VectorSubtract( vecAbsOrigin, view.origin, vecDelta );

// Must have valid plane
if ( !pReflectiveGlass->m_hTargetPlane )
if ( vecDelta.Dot( worldPlane.normal ) >= 0 ) // Backface cull
continue;

vecPlaneOrigin = vecOrigin;
vecPlaneLocalOrigin = vecLocalOrigin;
vecAbsPlaneNormal = worldPlane.normal;

return pReflectiveGlass;
}
}
Expand Down
4 changes: 1 addition & 3 deletions sp/src/game/client/mapbase/c_func_fake_worldportal.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,8 @@ class C_FuncFakeWorldPortal : public C_BaseEntity
//-----------------------------------------------------------------------------
// 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
Expand Down
123 changes: 41 additions & 82 deletions sp/src/game/client/viewrender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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.
Expand All @@ -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 );
Expand Down Expand Up @@ -3586,84 +3582,51 @@ bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldP
}
}

monitorView.width = width;
monitorView.height = height;
monitorView.x = x;
monitorView.y = y;
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;

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 );
matrix3x4_t worldToView;
AngleIMatrix( mainView.angles, mainView.origin, worldToView );

if (bDebug)
matrix3x4_t targetToWorld;
{
// 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 );
// NOTE: m_PlaneAngles is angle offset
QAngle targetAngles = pCameraEnt->m_hTargetPlane->GetAbsAngles() - pCameraEnt->m_PlaneAngles;
AngleMatrix( targetAngles, pCameraEnt->m_hTargetPlane->GetAbsOrigin(), targetToWorld );
}

//
// 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 )
matrix3x4_t portalToWorld;
{
Vector vecTranslation;
MatrixGetColumn( matPlayerToPortal, 3, vecTranslation );
vecTranslation /= pCameraEnt->m_flScale;
MatrixSetColumn( vecTranslation, 3, matPlayerToPortal );
Vector left, up;
VectorVectors( vecAbsPlaneNormal, left, up );
VectorNegate( left );
portalToWorld.Init( vecAbsPlaneNormal, left, up, pCameraEnt->GetAbsOrigin() );
}

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 );
matrix3x4_t portalToView;
ConcatTransforms( worldToView, portalToWorld, portalToView );

ConcatTransforms( matTarget, matPortalToPlayer, matNewPlayerPosition );

MatrixAngles( matNewPlayerPosition, monitorView.angles, monitorView.origin );

if (bDebug)
if ( pCameraEnt->m_flScale > 0.0f )
{
// BLUE - Target origin
debugoverlay->AddBoxOverlay( pCameraEnt->m_hTargetPlane->GetAbsOrigin(), Vector(-32,-32,-32), Vector(32,32,32), angTargetAngles, 0, 0, 255, 128, 10.0f );
portalToView[0][3] /= pCameraEnt->m_flScale;
portalToView[1][3] /= pCameraEnt->m_flScale;
portalToView[2][3] /= pCameraEnt->m_flScale;
}

// GREEN - Final origin
debugoverlay->AddBoxOverlay( monitorView.origin, Vector(-32,-32,-32), Vector(32,32,32), monitorView.angles, 0, 255, 0, 128, 10.0f );
matrix3x4_t viewToPortal;
MatrixInvert( portalToView, viewToPortal );

flLastDebugTime = gpGlobals->curtime + 5.0f;
}
matrix3x4_t newViewToWorld;
ConcatTransforms( targetToWorld, viewToPortal, newViewToWorld );

MatrixAngles( newViewToWorld, monitorView.angles, monitorView.origin );

monitorView.fov = mainView.fov;
monitorView.m_bOrtho = mainView.m_bOrtho;
monitorView.m_flAspectRatio = mainView.m_flAspectRatio;
monitorView.m_bViewToProjectionOverride = false;

// @MULTICORE (toml 8/11/2006): this should be a renderer....
int nClearFlags = (VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR | VIEW_CLEAR_OBEY_STENCIL);
Expand All @@ -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() );
Expand Down
2 changes: 1 addition & 1 deletion sp/src/game/client/viewrender.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ class CViewRender : public IViewRender,
#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
Expand Down

0 comments on commit 55b8c8d

Please sign in to comment.