Merge pull request #146 from mapbase-source/feature/real-fake-worldportals

func_fake_worldportal overhaul
This commit is contained in:
Blixibon 2021-09-25 11:26:15 -05:00 committed by GitHub
commit 416912d61b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 83 deletions

View File

@ -1,6 +1,6 @@
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// //========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
// //
// Purpose: Recreates Portal 2 linked_portal_door functionality using SDK code only. // Purpose: Recreates Portal 2 linked_portal_door visual functionality using SDK code only.
// (basically a combination of point_camera and func_reflective_glass) // (basically a combination of point_camera and func_reflective_glass)
// //
// $NoKeywords: $ // $NoKeywords: $
@ -120,8 +120,8 @@ C_FuncFakeWorldPortal *IsFakeWorldPortalInView( const CViewSetup& view, cplane_t
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Iterates through fake world portals instead of just picking one // Iterates through fake world portals instead of just picking one
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view, cplane_t &plane, C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view,
const Frustum_t &frustum ) cplane_t &plane, Vector &vecPlaneOrigin, const Frustum_t &frustum )
{ {
// Early out if no cameras // Early out if no cameras
C_FuncFakeWorldPortal *pReflectiveGlass = NULL; C_FuncFakeWorldPortal *pReflectiveGlass = NULL;
@ -167,6 +167,7 @@ C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const
if ( !pReflectiveGlass->m_hTargetPlane ) if ( !pReflectiveGlass->m_hTargetPlane )
continue; continue;
vecPlaneOrigin = vecOrigin;
return pReflectiveGlass; return pReflectiveGlass;
} }
} }

View File

@ -55,8 +55,8 @@ public:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
C_FuncFakeWorldPortal *IsFakeWorldPortalInView( const CViewSetup& view, cplane_t &plane ); C_FuncFakeWorldPortal *IsFakeWorldPortalInView( const CViewSetup& view, cplane_t &plane );
C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view, cplane_t &plane, C_FuncFakeWorldPortal *NextFakeWorldPortal( C_FuncFakeWorldPortal *pStart, const CViewSetup& view,
const Frustum_t &frustum ); cplane_t &plane, Vector &vecPlaneOrigin, const Frustum_t &frustum );
#endif // C_FUNC_FAKE_WORLDPORTAL #endif // C_FUNC_FAKE_WORLDPORTAL

View File

@ -2110,18 +2110,19 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum ); GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum );
cplane_t portalPlane; cplane_t portalPlane;
Vector vecPlaneOrigin;
//C_FuncFakeWorldPortal *pPortalEnt = IsFakeWorldPortalInView( view, portalPlane ); //C_FuncFakeWorldPortal *pPortalEnt = IsFakeWorldPortalInView( view, portalPlane );
//if ( pPortalEnt ) //if ( pPortalEnt )
C_FuncFakeWorldPortal *pPortalEnt = NextFakeWorldPortal( NULL, view, portalPlane, frustum ); C_FuncFakeWorldPortal *pPortalEnt = NextFakeWorldPortal( NULL, view, portalPlane, vecPlaneOrigin, frustum );
while ( pPortalEnt != NULL ) while ( pPortalEnt != NULL )
{ {
ITexture *pCameraTarget = pPortalEnt->RenderTarget(); ITexture *pCameraTarget = pPortalEnt->RenderTarget();
int width = pCameraTarget->GetActualWidth(); int width = pCameraTarget->GetActualWidth();
int height = pCameraTarget->GetActualHeight(); int height = pCameraTarget->GetActualHeight();
DrawFakeWorldPortal( pCameraTarget, pPortalEnt, viewMiddle, C_BasePlayer::GetLocalPlayer(), 0, 0, width, height, view, portalPlane ); DrawFakeWorldPortal( pCameraTarget, pPortalEnt, viewMiddle, C_BasePlayer::GetLocalPlayer(), 0, 0, width, height, view, portalPlane, vecPlaneOrigin );
pPortalEnt = NextFakeWorldPortal( pPortalEnt, view, portalPlane, frustum ); pPortalEnt = NextFakeWorldPortal( pPortalEnt, view, portalPlane, vecPlaneOrigin, frustum );
} }
#endif #endif
} }
@ -3539,8 +3540,7 @@ ConVar r_fakeworldportal_debug("r_fakeworldportal_debug", "0");
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: Sets up scene and renders WIP fake world portal view. // Purpose: Sets up scene and renders WIP fake world portal view.
// Based on code from monitors, mirrors, and 3D skyboxes. // Based on code from monitors, mirrors, and logic_measure_movement.
// It's also terrible right now.
// //
// Input : cameraNum - // Input : cameraNum -
// &cameraView // &cameraView
@ -3554,7 +3554,7 @@ ConVar r_fakeworldportal_debug("r_fakeworldportal_debug", "0");
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer,
int x, int y, int width, int height, int x, int y, int width, int height,
const CViewSetup &mainView, cplane_t &ourPlane ) const CViewSetup &mainView, cplane_t &ourPlane, const Vector &vecPlaneOrigin )
{ {
#ifdef USE_MONITORS #ifdef USE_MONITORS
VPROF_INCREMENT_COUNTER( "cameras rendered", 1 ); VPROF_INCREMENT_COUNTER( "cameras rendered", 1 );
@ -3593,97 +3593,89 @@ bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldP
monitorView.origin = mainView.origin; monitorView.origin = mainView.origin;
monitorView.angles = mainView.angles; monitorView.angles = mainView.angles;
// Temporary debug stuff // Debug stuff
static float flLastDebugTime = 0.0f; static float flLastDebugTime = 0.0f;
bool bDebug = r_fakeworldportal_debug.GetBool() && gpGlobals->curtime > flLastDebugTime; bool bDebug = r_fakeworldportal_debug.GetBool() && gpGlobals->curtime > flLastDebugTime;
QAngle angTargetAngles = pCameraEnt->m_hTargetPlane->GetAbsAngles() + pCameraEnt->m_PlaneAngles; //
// Calculate the angles for the fake portal plane
// RED - First origin //
if (bDebug) QAngle angTargetAngles = pCameraEnt->m_hTargetPlane->GetAbsAngles() - pCameraEnt->m_PlaneAngles;
debugoverlay->AddBoxOverlay( monitorView.origin, Vector(-32,-32,-32), Vector(32,32,32), monitorView.angles, 255, 0, 0, 128, 10.0f ); QAngle angFakePortalAngles;
// Make sure the origin and angles are relative to the target plane
monitorView.origin -= pCameraEnt->GetAbsOrigin();
// scale origin by sky scale
if ( pCameraEnt->m_flScale > 0 )
{
float scale = 1.0f / pCameraEnt->m_flScale;
VectorScale( monitorView.origin, scale, monitorView.origin );
}
// YELLOW - Main origin
if (bDebug)
debugoverlay->AddBoxOverlay( pCameraEnt->GetAbsOrigin(), Vector(-32,-32,-32), Vector(32,32,32), monitorView.angles, 255, 224, 0, 128, 10.0f );
// Make sure our angles are relative to the main plane, just like the origin
QAngle angOurAngles;
VectorAngles( ourPlane.normal * -1, angOurAngles );
//angles -= angOurAngles;
// First, create a matrix for the sky's angles.
matrix3x4_t matSkyAngles;
AngleMatrix( angTargetAngles - angOurAngles, matSkyAngles );
Vector vecSkyForward, vecSkyRight, vecSkyUp;
// Get vectors from our original angles. // Get vectors from our original angles.
Vector vPlayerForward, vPlayerRight, vPlayerUp; Vector vOurForward, vOurRight, vOurUp;
AngleVectors( monitorView.angles, &vPlayerForward, &vPlayerRight, &vPlayerUp ); AngleVectors( pCameraEnt->GetAbsAngles(), &vOurForward, &vOurRight, &vOurUp );
VectorTransform( vPlayerForward, matSkyAngles, vecSkyForward );
VectorTransform( vPlayerRight, matSkyAngles, vecSkyRight );
VectorTransform( vPlayerUp, matSkyAngles, vecSkyUp );
// Normalize them.
VectorNormalize( vecSkyForward );
VectorNormalize( vecSkyRight );
VectorNormalize( vecSkyUp );
Quaternion quat; Quaternion quat;
BasisToQuaternion( vecSkyForward, vecSkyRight, vecSkyUp, quat ); BasisToQuaternion( ourPlane.normal, vOurRight, vOurUp, quat );
QuaternionAngles( quat, monitorView.angles ); QuaternionAngles( quat, angFakePortalAngles );
// End of code mostly lifted from projected texture screenspace stuff
// ----------------------------------------------------------------------
// Now just rotate our origin with that matrix.
// We create a copy of the origin since VectorRotate doesn't want in1 to be the same variable as the destination.
VectorRotate(Vector(monitorView.origin), matSkyAngles, monitorView.origin);
// BLUE - Target origin
if (bDebug)
debugoverlay->AddBoxOverlay( pCameraEnt->m_hTargetPlane->GetAbsOrigin(), Vector(-32,-32,-32), Vector(32,32,32), monitorView.angles, 0, 0, 255, 128, 10.0f );
monitorView.origin += pCameraEnt->m_hTargetPlane->GetAbsOrigin();
// GREEN - Final origin
if (bDebug) 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 ); 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; flLastDebugTime = gpGlobals->curtime + 5.0f;
} }
monitorView.fov = mainView.fov; monitorView.fov = mainView.fov;
monitorView.m_bOrtho = false; monitorView.m_bOrtho = mainView.m_bOrtho;
monitorView.m_flAspectRatio = 0.0f; monitorView.m_flAspectRatio = mainView.m_flAspectRatio;
monitorView.m_bViewToProjectionOverride = false; monitorView.m_bViewToProjectionOverride = false;
// @MULTICORE (toml 8/11/2006): this should be a renderer.... // @MULTICORE (toml 8/11/2006): this should be a renderer....
int nClearFlags = (VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR | VIEW_CLEAR_OBEY_STENCIL); int nClearFlags = (VIEW_CLEAR_DEPTH | VIEW_CLEAR_COLOR | VIEW_CLEAR_OBEY_STENCIL);
bool bDrew3dSkybox = false; bool bDrew3dSkybox = false;
SkyboxVisibility_t nSkyMode = pCameraEnt->SkyMode();
Frustum frustum; Frustum frustum;
render->Push3DView( monitorView, nClearFlags, pRenderTarget, (VPlane *)frustum ); render->Push3DView( monitorView, nClearFlags, pRenderTarget, (VPlane *)frustum );
// //
// Monitor sky handling // Sky handling
// //
if ( pCameraEnt->SkyMode() == SKYBOX_3DSKYBOX_VISIBLE ) SkyboxVisibility_t nSkyMode = pCameraEnt->SkyMode();
if ( nSkyMode == SKYBOX_3DSKYBOX_VISIBLE )
{ {
// if the 3d skybox world is drawn, then don't draw the normal skybox // if the 3d skybox world is drawn, then don't draw the normal skybox
CSkyboxView *pSkyView = new CSkyboxView( this ); CSkyboxView *pSkyView = new CSkyboxView( this );
@ -3694,16 +3686,21 @@ bool CViewRender::DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldP
SafeRelease( pSkyView ); SafeRelease( pSkyView );
} }
//
// Make a clipping plane for the target view
//
Vector4D plane; Vector4D plane;
// Combine the target angles and the plane angles Vector vecAnglesNormal;
Vector vecAnglesNormal( angTargetAngles.x, angTargetAngles.y, angTargetAngles.z ); AngleVectors( angTargetAngles, &vecAnglesNormal );
VectorNormalize( vecAnglesNormal ); VectorNormalize( vecAnglesNormal );
VectorCopy( vecAnglesNormal, plane.AsVector3D() ); VectorCopy( -vecAnglesNormal, plane.AsVector3D() );
// TODO: How do we get a good value for this!?!? // The portal plane's distance from the actual brush's origin
//plane.w = m_OurPlane.dist + 0.1f; float flPlaneDist = vecPlaneOrigin.Length();
plane.w = -32.0f + 0.1f;
// The target's distance from world origin
plane.w = -((pCameraEnt->m_hTargetPlane->GetAbsOrigin() * vecAnglesNormal).Length() + flPlaneDist) + 0.1f;
CMatRenderContextPtr pRenderContext( materials ); CMatRenderContextPtr pRenderContext( materials );
pRenderContext->PushCustomClipPlane( plane.Base() ); pRenderContext->PushCustomClipPlane( plane.Base() );

View File

@ -454,7 +454,7 @@ private:
#ifdef MAPBASE #ifdef MAPBASE
bool DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer, bool DrawFakeWorldPortal( ITexture *pRenderTarget, C_FuncFakeWorldPortal *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer,
int x, int y, int width, int height, int x, int y, int width, int height,
const CViewSetup &mainView, cplane_t &ourPlane ); const CViewSetup &mainView, cplane_t &ourPlane, const Vector &vecPlaneOrigin );
#endif #endif
// Drawing primitives // Drawing primitives

View File

@ -1,6 +1,6 @@
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// //========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
// //
// Purpose: Recreates Portal 2 linked_portal_door functionality using SDK code only. // Purpose: Recreates Portal 2 linked_portal_door visual functionality using SDK code only.
// (basically a combination of point_camera and func_reflective_glass) // (basically a combination of point_camera and func_reflective_glass)
// //
//===========================================================================// //===========================================================================//