mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-07-16 14:25:01 +00:00
feat(Portal Simulation): Portals now work with displacements.
Taken from Portal2 code. feat(sv_allow_mobile_portals): Added `sv_allow_mobile_portals` doesn't really work, most of it is not implemented yet. feat(sv_autojump_): Added `sv_autojump_` does what it says - auto jumps. fix(d1_canals_01): Fix crash when vortigaunt charges your suit. fix(CRagdollPropAttached): Check if `pRefObject` is nullptr so we can feed a combine apc to a barnacle.
This commit is contained in:
parent
881d4a91c9
commit
4bebd92781
@ -261,8 +261,11 @@ void C_VortigauntChargeToken::NotifyShouldTransmit( ShouldTransmitState_t state
|
||||
// Turn on
|
||||
if ( state == SHOULDTRANSMIT_START )
|
||||
{
|
||||
m_hEffect = ParticleProp()->Create( "vortigaunt_charge_token", PATTACH_ABSORIGIN_FOLLOW );
|
||||
m_hEffect->SetControlPointEntity( 0, this );
|
||||
if ( m_hEffect )
|
||||
{
|
||||
m_hEffect = ParticleProp()->Create( "vortigaunt_charge_token", PATTACH_ABSORIGIN_FOLLOW );
|
||||
m_hEffect->SetControlPointEntity( 0, this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,8 +395,11 @@ void C_VortigauntEffectDispel::NotifyShouldTransmit( ShouldTransmitState_t state
|
||||
// Turn on
|
||||
if ( state == SHOULDTRANSMIT_START )
|
||||
{
|
||||
if( m_hEffect )
|
||||
{
|
||||
m_hEffect = ParticleProp()->Create( "vortigaunt_hand_glow", PATTACH_ABSORIGIN_FOLLOW );
|
||||
m_hEffect->SetControlPointEntity( 0, this );
|
||||
m_hEffect->SetControlPointEntity( 0, this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1509,6 +1509,9 @@ void CRagdollPropAttached::InitRagdollAttached(
|
||||
|
||||
IPhysicsObject *pRefObject = m_ragdoll.list[ragdollAttachedIndex].pObject;
|
||||
|
||||
if( !pRefObject )
|
||||
return;
|
||||
|
||||
Vector attachmentPointRagdollSpace;
|
||||
pRefObject->WorldToLocal( &attachmentPointRagdollSpace, worldAttachOrigin );
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ bool g_bBumpedByLinkedPortal;
|
||||
|
||||
ConVar sv_portal_placement_debug ("sv_portal_placement_debug", "0", FCVAR_REPLICATED );
|
||||
ConVar sv_portal_placement_never_bump ("sv_portal_placement_never_bump", "0", FCVAR_REPLICATED | FCVAR_CHEAT );
|
||||
|
||||
extern ConVar sv_allow_mobile_portals;
|
||||
|
||||
bool IsMaterialInList( const csurface_t &surface, char *g_ppszMaterials[] )
|
||||
{
|
||||
@ -1188,22 +1188,7 @@ float VerifyPortalPlacement( const CProp_Portal *pIgnorePortal, Vector &vOrigin,
|
||||
return PORTAL_ANALOG_SUCCESS_INVALID_SURFACE;
|
||||
}
|
||||
|
||||
// Check if the surface is moving
|
||||
Vector vVelocityCheck;
|
||||
AngularImpulse vAngularImpulseCheck;
|
||||
|
||||
IPhysicsObject *pPhysicsObject = tr.m_pEnt->VPhysicsGetObject();
|
||||
|
||||
if ( pPhysicsObject )
|
||||
{
|
||||
pPhysicsObject->GetVelocity( &vVelocityCheck, &vAngularImpulseCheck );
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.m_pEnt->GetVelocity( &vVelocityCheck, &vAngularImpulseCheck );
|
||||
}
|
||||
|
||||
if ( vVelocityCheck != vec3_origin || vAngularImpulseCheck != vec3_origin )
|
||||
if ( !sv_allow_mobile_portals.GetBool() && UTIL_IsEntityMovingOrRotating( tr.m_pEnt )/*(vVelocityCheck != vec3_origin || vAngularImpulseCheck != vec3_origin)*/ )
|
||||
{
|
||||
if ( sv_portal_placement_debug.GetBool() )
|
||||
{
|
||||
|
||||
@ -1371,7 +1371,7 @@ void CProp_Portal::Touch( CBaseEntity *pOther )
|
||||
DoFizzleEffect( PORTAL_FIZZLE_KILLED, false );
|
||||
Fizzle();
|
||||
}
|
||||
else if ( tr.m_pEnt && tr.m_pEnt->IsMoving() )
|
||||
else if ( !sv_allow_mobile_portals.GetBool() && tr.m_pEnt && tr.m_pEnt->IsMoving() )
|
||||
{
|
||||
DevMsg( "Surface behind portal is moving.\n" );
|
||||
|
||||
|
||||
@ -162,5 +162,6 @@ inline const VMatrix& CProp_Portal::MatrixThisToLinked() const
|
||||
return m_matrixThisToLinked;
|
||||
}
|
||||
|
||||
extern ConVar sv_allow_mobile_portals;
|
||||
|
||||
#endif //#ifndef PROP_PORTAL_H
|
||||
|
||||
@ -402,7 +402,7 @@ float CWeaponPortalgun::TraceFirePortal( bool bPortal2, const Vector &vTraceStar
|
||||
qFinalAngles = pPortal->m_qDelayedAngles;
|
||||
}
|
||||
|
||||
return PORTAL_ANALOG_SUCCESS_BUMPED;
|
||||
return PORTAL_ANALOG_SUCCESS_PASSTHROUGH_SURFACE;
|
||||
}
|
||||
|
||||
// Trace to the surface to see if there's a rotating door in the way
|
||||
|
||||
@ -34,7 +34,7 @@ extern IFileSystem *filesystem;
|
||||
#include "env_player_surface_trigger.h"
|
||||
static ConVar dispcoll_drawplane( "dispcoll_drawplane", "0" );
|
||||
#endif
|
||||
|
||||
static ConVar sv_autojump_( "sv_autojump_", "0" );
|
||||
|
||||
// tickcount currently isn't set during prediction, although gpGlobals->curtime and
|
||||
// gpGlobals->frametime are. We should probably set tickcount (to player->m_nTickBase),
|
||||
@ -2347,7 +2347,6 @@ void CGameMovement::PlaySwimSound()
|
||||
MoveHelper()->StartSound( mv->GetAbsOrigin(), "Player.Swim" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2404,8 +2403,11 @@ bool CGameMovement::CheckJumpButton( void )
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if ( mv->m_nOldButtons & IN_JUMP )
|
||||
if ( (mv->m_nOldButtons & IN_JUMP) &&
|
||||
(!sv_autojump_.GetBool() && player->GetGroundEntity()) )
|
||||
{
|
||||
return false; // don't pogo stick
|
||||
}
|
||||
|
||||
// Cannot jump will in the unduck transition.
|
||||
if ( player->m_Local.m_bDucking && ( player->GetFlags() & FL_DUCKING ) )
|
||||
@ -2526,6 +2528,7 @@ bool CGameMovement::CheckJumpButton( void )
|
||||
|
||||
// Flag that we jumped.
|
||||
mv->m_nOldButtons |= IN_JUMP; // don't jump again until released
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include "cbase.h"
|
||||
#include "PortalSimulation.h"
|
||||
#include "convar.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "physics.h"
|
||||
#include "portal_shareddefs.h"
|
||||
@ -16,6 +17,7 @@
|
||||
#include "filesystem.h"
|
||||
#include "collisionutils.h"
|
||||
#include "tier1/callqueue.h"
|
||||
#include "vphysics/virtualmesh.h"
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
@ -44,6 +46,7 @@ extern IPhysicsConstraintEvent *g_pConstraintEvents;
|
||||
static ConVar sv_portal_collision_sim_bounds_x( "sv_portal_collision_sim_bounds_x", "200", FCVAR_REPLICATED, "Size of box used to grab collision geometry around placed portals. These should be at the default size or larger only!" );
|
||||
static ConVar sv_portal_collision_sim_bounds_y( "sv_portal_collision_sim_bounds_y", "200", FCVAR_REPLICATED, "Size of box used to grab collision geometry around placed portals. These should be at the default size or larger only!" );
|
||||
static ConVar sv_portal_collision_sim_bounds_z( "sv_portal_collision_sim_bounds_z", "252", FCVAR_REPLICATED, "Size of box used to grab collision geometry around placed portals. These should be at the default size or larger only!" );
|
||||
ConVar portal_clone_displacements ( "portal_clone_displacements", "1", FCVAR_REPLICATED | FCVAR_CHEAT );
|
||||
|
||||
//#define DEBUG_PORTAL_SIMULATION_CREATION_TIMES //define to output creation timings to developer 2
|
||||
//#define DEBUG_PORTAL_COLLISION_ENVIRONMENTS //define this to allow for glview collision dumps of portal simulators
|
||||
@ -1208,6 +1211,19 @@ void CPortalSimulator::CreateLocalPhysics( void )
|
||||
m_InternalData.Simulation.Static.World.Brushes.pPhysicsObject->RecheckCollisionFilter(); //some filters only work after the variable is stored in the class
|
||||
}
|
||||
|
||||
if( m_InternalData.Simulation.Static.World.Displacements.pCollideable != NULL )
|
||||
{
|
||||
m_InternalData.Simulation.Static.World.Displacements.pPhysicsObject = m_InternalData.Simulation.pPhysicsEnvironment->CreatePolyObjectStatic( m_InternalData.Simulation.Static.World.Displacements.pCollideable, m_InternalData.Simulation.Static.SurfaceProperties.surface.surfaceProps, vec3_origin, vec3_angle, ¶ms );
|
||||
|
||||
if( (m_InternalData.Simulation.pCollisionEntity != NULL) && (m_InternalData.Simulation.pCollisionEntity->VPhysicsGetObject() == NULL) )
|
||||
{
|
||||
m_InternalData.Simulation.pCollisionEntity->VPhysicsSetObject(m_InternalData.Simulation.Static.World.Displacements.pPhysicsObject);
|
||||
m_InternalData.Simulation.pCollisionEntity = NULL;
|
||||
}
|
||||
|
||||
m_InternalData.Simulation.Static.World.Displacements.pPhysicsObject->RecheckCollisionFilter(); //some filters only work after the variable is stored in the class
|
||||
}
|
||||
|
||||
//Assert( m_InternalData.Simulation.Static.World.StaticProps.PhysicsObjects.Count() == 0 ); //Be sure to find graceful fixes for asserts, performance is a big concern with portal simulation
|
||||
#ifdef _DEBUG
|
||||
for( int i = m_InternalData.Simulation.Static.World.StaticProps.ClippedRepresentations.Count(); --i >= 0; )
|
||||
@ -1435,12 +1451,20 @@ void CPortalSimulator::ClearLocalPhysics( void )
|
||||
m_InternalData.Simulation.pPhysicsEnvironment->CleanupDeleteList();
|
||||
m_InternalData.Simulation.pPhysicsEnvironment->SetQuickDelete( true ); //if we don't do this, things crash the next time we cleanup the delete list while checking mindists
|
||||
|
||||
//world brushes
|
||||
if( m_InternalData.Simulation.Static.World.Brushes.pPhysicsObject )
|
||||
{
|
||||
m_InternalData.Simulation.pPhysicsEnvironment->DestroyObject( m_InternalData.Simulation.Static.World.Brushes.pPhysicsObject );
|
||||
m_InternalData.Simulation.Static.World.Brushes.pPhysicsObject = NULL;
|
||||
}
|
||||
|
||||
//world displacement surfaces
|
||||
if( m_InternalData.Simulation.Static.World.Displacements.pPhysicsObject )
|
||||
{
|
||||
m_InternalData.Simulation.pPhysicsEnvironment->DestroyObject( m_InternalData.Simulation.Static.World.Displacements.pPhysicsObject );
|
||||
m_InternalData.Simulation.Static.World.Displacements.pPhysicsObject = NULL;
|
||||
}
|
||||
|
||||
if( m_InternalData.Simulation.Static.World.StaticProps.bPhysicsExists &&
|
||||
(m_InternalData.Simulation.Static.World.StaticProps.ClippedRepresentations.Count() != 0) )
|
||||
{
|
||||
@ -1646,6 +1670,181 @@ bool CPortalSimulator::CreateLocalCollision( void )
|
||||
STOPDEBUGTIMER( worldBrushTimer );
|
||||
DEBUGTIMERONLY( DevMsg( 2, "[PSDT:%d] %sWorld Brushes=%fms\n", GetPortalSimulatorGUID(), TABSPACING, worldBrushTimer.GetDuration().GetMillisecondsF() ); );
|
||||
|
||||
// Displacements
|
||||
if ( portal_clone_displacements.GetBool() )
|
||||
{
|
||||
//scale the extents to usable sizes
|
||||
float flScaleX = sv_portal_collision_sim_bounds_x.GetFloat();
|
||||
if ( flScaleX < 200.0f )
|
||||
flScaleX = 200.0f;
|
||||
float flScaleY = sv_portal_collision_sim_bounds_y.GetFloat();
|
||||
if ( flScaleY < 200.0f )
|
||||
flScaleY = 200.0f;
|
||||
float flScaleZ = sv_portal_collision_sim_bounds_z.GetFloat();
|
||||
if ( flScaleZ < 252.0f )
|
||||
flScaleZ = 252.0f;
|
||||
|
||||
VPlane displacementRejectRegions[6];
|
||||
displacementRejectRegions[0].m_Normal = -m_InternalData.Placement.vForward;
|
||||
displacementRejectRegions[0].m_Dist = displacementRejectRegions[0].m_Normal.Dot( m_InternalData.Placement.ptCenter );
|
||||
displacementRejectRegions[1].m_Normal = m_InternalData.Placement.vForward;
|
||||
displacementRejectRegions[1].m_Dist = displacementRejectRegions[1].m_Normal.Dot( m_InternalData.Placement.ptCenter ) + flScaleX;
|
||||
displacementRejectRegions[2].m_Normal = m_InternalData.Placement.vRight;
|
||||
displacementRejectRegions[2].m_Dist = displacementRejectRegions[2].m_Normal.Dot( m_InternalData.Placement.ptCenter ) + flScaleY;
|
||||
displacementRejectRegions[3].m_Normal = -m_InternalData.Placement.vRight;
|
||||
displacementRejectRegions[3].m_Dist = displacementRejectRegions[3].m_Normal.Dot( m_InternalData.Placement.ptCenter ) + flScaleY;
|
||||
displacementRejectRegions[4].m_Normal = m_InternalData.Placement.vUp;
|
||||
displacementRejectRegions[4].m_Dist = displacementRejectRegions[4].m_Normal.Dot( m_InternalData.Placement.ptCenter ) + flScaleZ;
|
||||
displacementRejectRegions[5].m_Normal = -m_InternalData.Placement.vUp;
|
||||
displacementRejectRegions[5].m_Dist = displacementRejectRegions[5].m_Normal.Dot( m_InternalData.Placement.ptCenter ) + flScaleZ;
|
||||
|
||||
CREATEDEBUGTIMER( dispTimer );
|
||||
STARTDEBUGTIMER( dispTimer );
|
||||
Assert( m_InternalData.Simulation.Static.World.Displacements.pCollideable == NULL );
|
||||
virtualmeshlist_t DisplacementMeshes[32];
|
||||
|
||||
int iMeshes = enginetrace->GetMeshesFromDisplacementsInAABB( m_InternalData.Placement.vecCurAABBMins, m_InternalData.Placement.vecCurAABBMaxs, DisplacementMeshes, ARRAYSIZE(DisplacementMeshes) );
|
||||
if( iMeshes > 0 )
|
||||
{
|
||||
CPhysPolysoup *pDispCollideSoup = physcollision->PolysoupCreate();
|
||||
|
||||
// Count total triangles added to this poly soup- Can't support more than 65535.
|
||||
int iTriCount = 0;
|
||||
|
||||
for( int i = 0; (i != iMeshes) && (iTriCount < 65535); ++i )
|
||||
{
|
||||
virtualmeshlist_t *pMesh = &DisplacementMeshes[i];
|
||||
|
||||
for ( int j = 0; j < pMesh->indexCount; j+=3 )
|
||||
{
|
||||
Vector *points[3] = { &pMesh->pVerts[ pMesh->indices[j+0] ], &pMesh->pVerts[ pMesh->indices[j+1] ], &pMesh->pVerts[ pMesh->indices[j+2] ] };
|
||||
|
||||
//test for triangles that lie completely outside our collision area
|
||||
{
|
||||
int k;
|
||||
for( k = 0; k != ARRAYSIZE( displacementRejectRegions ); ++k )
|
||||
{
|
||||
//test all 3 points on each plane
|
||||
if( (displacementRejectRegions[k].DistTo( *points[0] ) >= 0.0f) &&
|
||||
(displacementRejectRegions[k].DistTo( *points[1] ) >= 0.0f) &&
|
||||
(displacementRejectRegions[k].DistTo( *points[2] ) >= 0.0f) )
|
||||
{
|
||||
break; //break out if all 3 are in front of a rejection plane
|
||||
}
|
||||
}
|
||||
|
||||
if( k != ARRAYSIZE( displacementRejectRegions ) )
|
||||
{
|
||||
//was fully rejected by a plane
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//clip to portal plane
|
||||
{
|
||||
//we do however need to clip to the wall plane
|
||||
int iFront = 0;
|
||||
int iBack = 0;
|
||||
float fDists[3];
|
||||
int iForwardPoints[3];
|
||||
int iBackPoints[3];
|
||||
for( int k = 0; k != 3; ++k )
|
||||
{
|
||||
fDists[k] = m_InternalData.Placement.PortalPlane.DistTo( *points[k] );
|
||||
if( fDists[k] >= 0.0f )
|
||||
{
|
||||
iForwardPoints[iFront] = k;
|
||||
++iFront;
|
||||
}
|
||||
else
|
||||
{
|
||||
iBackPoints[iBack] = k;
|
||||
++iBack;
|
||||
}
|
||||
}
|
||||
if( iFront != 0 )
|
||||
{
|
||||
if( iBack != 0 )
|
||||
{
|
||||
//need to clip the triangle
|
||||
Vector vClippedPoints[2]; //guaranteed to intersect exactly twice
|
||||
|
||||
if( iBack == 2 )
|
||||
{
|
||||
if( fDists[iForwardPoints[0]] < 0.1f )
|
||||
continue;
|
||||
|
||||
//easy case.
|
||||
float fTotalDist = fDists[iForwardPoints[0]] - fDists[iBackPoints[0]];
|
||||
if( fTotalDist < 0.1f )
|
||||
continue;
|
||||
|
||||
vClippedPoints[0] = ((*points[iBackPoints[0]]) * (fDists[iForwardPoints[0]]/fTotalDist)) - ((*points[iForwardPoints[0]]) * (fDists[iBackPoints[0]]/fTotalDist));
|
||||
points[iBackPoints[0]] = &vClippedPoints[0];
|
||||
|
||||
fTotalDist = fDists[iForwardPoints[0]] - fDists[iBackPoints[1]];
|
||||
if( fTotalDist < 0.1f )
|
||||
continue;
|
||||
|
||||
vClippedPoints[1] = ((*points[iBackPoints[1]]) * (fDists[iForwardPoints[0]]/fTotalDist)) - ((*points[iForwardPoints[0]]) * (fDists[iBackPoints[1]]/fTotalDist));
|
||||
points[iBackPoints[1]] = &vClippedPoints[1];
|
||||
|
||||
physcollision->PolysoupAddTriangle( pDispCollideSoup, *points[0], *points[1], *points[2], pMesh->surfacePropsIndex );
|
||||
++iTriCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( fDists[iBackPoints[0]] > -0.1f )
|
||||
{
|
||||
physcollision->PolysoupAddTriangle( pDispCollideSoup, *points[0], *points[1], *points[2], pMesh->surfacePropsIndex );
|
||||
++iTriCount;
|
||||
continue;
|
||||
}
|
||||
|
||||
//need to create 2 triangles
|
||||
float fTotalDist = fDists[iForwardPoints[0]] - fDists[iBackPoints[0]];
|
||||
vClippedPoints[0] = ((*points[iBackPoints[0]]) * (fDists[iForwardPoints[0]]/fTotalDist)) - ((*points[iForwardPoints[0]]) * (fDists[iBackPoints[0]]/fTotalDist));
|
||||
fTotalDist = fDists[iForwardPoints[1]] - fDists[iBackPoints[0]];
|
||||
vClippedPoints[1] = ((*points[iBackPoints[0]]) * (fDists[iForwardPoints[1]]/fTotalDist)) - ((*points[iForwardPoints[1]]) * (fDists[iBackPoints[0]]/fTotalDist));
|
||||
|
||||
points[iBackPoints[0]] = &vClippedPoints[0];
|
||||
physcollision->PolysoupAddTriangle( pDispCollideSoup, *points[0], *points[1], *points[2], pMesh->surfacePropsIndex );
|
||||
++iTriCount;
|
||||
|
||||
points[iBackPoints[0]] = &vClippedPoints[1];
|
||||
points[iForwardPoints[0]] = &vClippedPoints[0];
|
||||
physcollision->PolysoupAddTriangle( pDispCollideSoup, *points[0], *points[1], *points[2], pMesh->surfacePropsIndex );
|
||||
++iTriCount;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//triangle resides wholly in front of the portal plane
|
||||
physcollision->PolysoupAddTriangle( pDispCollideSoup, *points[0], *points[1], *points[2], pMesh->surfacePropsIndex );
|
||||
++iTriCount;
|
||||
}
|
||||
|
||||
if( iTriCount >= 65535 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}// triangle loop
|
||||
}
|
||||
|
||||
m_InternalData.Simulation.Static.World.Displacements.pCollideable = physcollision->ConvertPolysoupToCollide( pDispCollideSoup, false );
|
||||
|
||||
// clean up poly soup
|
||||
physcollision->PolysoupDestroy( pDispCollideSoup );
|
||||
}
|
||||
|
||||
//m_InternalData.Simulation.Static.World.Displacements.pCollideable = enginetrace->GetCollidableFromDisplacementsInAABB( m_InternalData.Placement.vecCurAABBMins, m_InternalData.Placement.vecCurAABBMaxs );
|
||||
STOPDEBUGTIMER( dispTimer );
|
||||
DEBUGTIMERONLY( DevMsg( 2, "[PSDT:%d] %sDisplacement Surfaces=%fms\n", GetPortalSimulatorGUID(), TABSPACING, dispTimer.GetDuration().GetMillisecondsF() ); );
|
||||
}
|
||||
|
||||
CREATEDEBUGTIMER( worldPropTimer );
|
||||
STARTDEBUGTIMER( worldPropTimer );
|
||||
#ifdef _DEBUG
|
||||
@ -1806,6 +2005,12 @@ void CPortalSimulator::ClearLocalCollision( void )
|
||||
m_InternalData.Simulation.Static.Wall.Local.Tube.pCollideable = NULL;
|
||||
}
|
||||
|
||||
if( m_InternalData.Simulation.Static.World.Displacements.pCollideable )
|
||||
{
|
||||
physcollision->DestroyCollide( m_InternalData.Simulation.Static.World.Displacements.pCollideable );
|
||||
m_InternalData.Simulation.Static.World.Displacements.pCollideable = NULL;
|
||||
}
|
||||
|
||||
if( m_InternalData.Simulation.Static.World.Brushes.pCollideable )
|
||||
{
|
||||
physcollision->DestroyCollide( m_InternalData.Simulation.Static.World.Brushes.pCollideable );
|
||||
@ -1919,6 +2124,9 @@ void CPortalSimulator::CreatePolyhedrons( void )
|
||||
if( ptTest.z > vAABBMaxs.z ) vAABBMaxs.z = ptTest.z;
|
||||
}
|
||||
|
||||
m_InternalData.Placement.vecCurAABBMins = vAABBMins;
|
||||
m_InternalData.Placement.vecCurAABBMaxs = vAABBMaxs;
|
||||
|
||||
//Brushes
|
||||
{
|
||||
Assert( m_InternalData.Simulation.Static.World.Brushes.Polyhedrons.Count() == 0 );
|
||||
@ -2413,7 +2621,7 @@ void CPortalSimulator::PrePhysFrame( void )
|
||||
|
||||
Assert( (pEntity != NULL) && (pEntity->IsMarkedForDeletion() == false) );
|
||||
IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
|
||||
if( (pPhysObject == NULL) || pPhysObject->IsAsleep() )
|
||||
if( pPhysObject == NULL /*|| pPhysObject->IsAsleep() */)
|
||||
continue;
|
||||
|
||||
int iEntIndex = pEntity->entindex();
|
||||
@ -2572,7 +2780,15 @@ bool CPortalSimulator::CreatedPhysicsObject( const IPhysicsObject *pObject, PS_P
|
||||
*pOut_SourceType = PSPOST_HOLYWALL_TUBE;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( pObject == m_InternalData.Simulation.Static.World.Displacements.pPhysicsObject )
|
||||
{
|
||||
if( pOut_SourceType )
|
||||
*pOut_SourceType = PSPOST_LOCAL_DISPLACEMENT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -2980,6 +3196,14 @@ int CPSCollisionEntity::VPhysicsGetObjectList( IPhysicsObject **pList, int listM
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
if( m_pOwningSimulator->m_DataAccess.Simulation.Static.World.Displacements.pPhysicsObject != NULL )
|
||||
{
|
||||
pList[iRetVal] = m_pOwningSimulator->m_DataAccess.Simulation.Static.World.Displacements.pPhysicsObject;
|
||||
++iRetVal;
|
||||
if( iRetVal == listMax )
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
@ -3028,6 +3252,9 @@ void DumpActiveCollision( const CPortalSimulator *pPortalSimulator, const char *
|
||||
}
|
||||
}
|
||||
|
||||
if ( pPortalSimulator->GetInternalData().Simulation.Static.World.Displacements.pCollideable )
|
||||
PortalSimulatorDumps_DumpCollideToGlView( pPortalSimulator->GetInternalData().Simulation.Static.World.Displacements.pCollideable, vec3_origin, vec3_angle, PSDAC_INTENSITY_LOCALBRUSH, szFileName );
|
||||
|
||||
if( pPortalSimulator->m_DataAccess.Simulation.Static.Wall.Local.Brushes.pCollideable )
|
||||
PortalSimulatorDumps_DumpCollideToGlView( pPortalSimulator->m_DataAccess.Simulation.Static.Wall.Local.Brushes.pCollideable, vec3_origin, vec3_angle, PSDAC_INTENSITY_LOCALBRUSH, szFileName );
|
||||
|
||||
|
||||
@ -40,7 +40,8 @@ enum PS_PhysicsObjectSourceType_t
|
||||
PSPOST_REMOTE_BRUSHES,
|
||||
PSPOST_LOCAL_STATICPROPS,
|
||||
PSPOST_REMOTE_STATICPROPS,
|
||||
PSPOST_HOLYWALL_TUBE
|
||||
PSPOST_HOLYWALL_TUBE,
|
||||
PSPOST_LOCAL_DISPLACEMENT
|
||||
};
|
||||
|
||||
struct PortalTransformAsAngledPosition_t //a matrix transformation from this portal to the linked portal, stored as vector and angle transforms
|
||||
@ -105,6 +106,8 @@ struct PS_PlacementData_t //stuff useful for geometric operations
|
||||
PortalTransformAsAngledPosition_t ptaap_ThisToLinked;
|
||||
PortalTransformAsAngledPosition_t ptaap_LinkedToThis;
|
||||
CPhysCollide *pHoleShapeCollideable; //used to test if a collideable is in the hole, should NOT be collided against in general
|
||||
Vector vecCurAABBMins;
|
||||
Vector vecCurAABBMaxs;
|
||||
PS_PlacementData_t( void )
|
||||
{
|
||||
memset( this, 0, sizeof( PS_PlacementData_t ) );
|
||||
@ -124,6 +127,17 @@ struct PS_SD_Static_World_Brushes_t
|
||||
|
||||
};
|
||||
|
||||
struct PS_SD_Static_World_Displacements_t
|
||||
{
|
||||
CPhysCollide *pCollideable;
|
||||
#ifndef CLIENT_DLL
|
||||
IPhysicsObject *pPhysicsObject;
|
||||
PS_SD_Static_World_Displacements_t() : pCollideable(NULL), pPhysicsObject(NULL) {};
|
||||
#else
|
||||
PS_SD_Static_World_Displacements_t() : pCollideable(NULL) {};
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct PS_SD_Static_World_StaticProps_ClippedProp_t
|
||||
{
|
||||
@ -153,6 +167,7 @@ struct PS_SD_Static_World_StaticProps_t
|
||||
struct PS_SD_Static_World_t //stuff in front of the portal
|
||||
{
|
||||
PS_SD_Static_World_Brushes_t Brushes;
|
||||
PS_SD_Static_World_Displacements_t Displacements;
|
||||
PS_SD_Static_World_StaticProps_t StaticProps;
|
||||
};
|
||||
|
||||
|
||||
@ -35,6 +35,9 @@ ConVar sv_portal_trace_vs_holywall ("sv_portal_trace_vs_holywall", "1", FCVAR_RE
|
||||
ConVar sv_portal_trace_vs_staticprops ("sv_portal_trace_vs_staticprops", "1", FCVAR_REPLICATED | FCVAR_CHEAT, "Use traces against portal environment static prop geometry" );
|
||||
ConVar sv_use_find_closest_passable_space ("sv_use_find_closest_passable_space", "1", FCVAR_REPLICATED | FCVAR_CHEAT, "Enables heavy-handed player teleporting stuck fix code." );
|
||||
ConVar sv_use_transformed_collideables("sv_use_transformed_collideables", "1", FCVAR_REPLICATED | FCVAR_CHEAT, "Disables traces against remote portal moving entities using transforms to bring them into local space." );
|
||||
|
||||
extern ConVar portal_clone_displacements;
|
||||
|
||||
class CTransformedCollideable : public ICollideable //wraps an existing collideable, but transforms everything that pertains to world space by another transform
|
||||
{
|
||||
public:
|
||||
@ -623,6 +626,16 @@ void UTIL_Portal_TraceRay( const CProp_Portal *pPortal, const Ray_t &ray, unsign
|
||||
bCopyBackBrushTraceData = true;
|
||||
}
|
||||
|
||||
if( portalSimulator.m_DataAccess.Simulation.Static.World.Displacements.pCollideable && sv_portal_trace_vs_world.GetBool() && portal_clone_displacements.GetBool() )
|
||||
{
|
||||
physcollision->TraceBox( ray, portalSimulator.m_DataAccess.Simulation.Static.World.Displacements.pCollideable, vec3_origin, vec3_angle, &TempTrace );
|
||||
if( (TempTrace.startsolid == false) && (TempTrace.fraction < pTrace->fraction) ) //never allow something to be stuck in the tube, it's more of a last-resort guide than a real collideable
|
||||
{
|
||||
*pTrace = TempTrace;
|
||||
bCopyBackBrushTraceData = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( bTraceHolyWall )
|
||||
{
|
||||
if( portalSimulator.m_DataAccess.Simulation.Static.Wall.Local.Tube.pCollideable )
|
||||
@ -938,6 +951,18 @@ void UTIL_Portal_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, c
|
||||
}
|
||||
}
|
||||
|
||||
if( pPortalSimulator->m_DataAccess.Simulation.Static.World.Displacements.pCollideable &&
|
||||
sv_portal_trace_vs_world.GetBool() &&
|
||||
portal_clone_displacements.GetBool() )
|
||||
{
|
||||
physcollision->TraceBox( entRay, MASK_ALL, NULL, pPortalSimulator->m_DataAccess.Simulation.Static.World.Displacements.pCollideable, vec3_origin, vec3_angle, &tempTrace );
|
||||
|
||||
if ( tempTrace.startsolid || (tempTrace.fraction < pTrace->fraction) )
|
||||
{
|
||||
*pTrace = tempTrace;
|
||||
}
|
||||
}
|
||||
|
||||
//if( pPortalSimulator->m_DataAccess.Simulation.Static.Wall.RemoteTransformedToLocal.Brushes.pCollideable &&
|
||||
if( pLinkedPortalSimulator &&
|
||||
pLinkedPortalSimulator->m_DataAccess.Simulation.Static.World.Brushes.pCollideable &&
|
||||
@ -955,6 +980,20 @@ void UTIL_Portal_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, c
|
||||
}
|
||||
}
|
||||
|
||||
if( pLinkedPortalSimulator &&
|
||||
pLinkedPortalSimulator->m_DataAccess.Simulation.Static.World.Displacements.pCollideable &&
|
||||
sv_portal_trace_vs_world.GetBool() &&
|
||||
sv_portal_trace_vs_holywall.GetBool() &&
|
||||
portal_clone_displacements.GetBool() )
|
||||
{
|
||||
physcollision->TraceBox( entRay, MASK_ALL, NULL, pLinkedPortalSimulator->m_DataAccess.Simulation.Static.World.Displacements.pCollideable, pPortalSimulator->m_DataAccess.Placement.ptaap_LinkedToThis.ptOriginTransform, pPortalSimulator->m_DataAccess.Placement.ptaap_LinkedToThis.qAngleTransform, &tempTrace );
|
||||
|
||||
if ( tempTrace.startsolid || (tempTrace.fraction < pTrace->fraction) )
|
||||
{
|
||||
*pTrace = tempTrace;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pPortalSimulator->m_DataAccess.Simulation.Static.Wall.Local.Brushes.pCollideable &&
|
||||
sv_portal_trace_vs_holywall.GetBool() )
|
||||
{
|
||||
@ -1717,6 +1756,58 @@ PaintPowerType UTIL_Paint_TracePower(CBaseEntity *pBrushEntity,Vector contactPoi
|
||||
return NO_POWER;
|
||||
}
|
||||
|
||||
bool UTIL_IsEntityMovingOrRotating( CBaseEntity* pEntity )
|
||||
{
|
||||
Vector vLinearVelocity;
|
||||
AngularImpulse vAngularVelocity;
|
||||
|
||||
IPhysicsObject *pEntityPhysicsObject = pEntity->VPhysicsGetObject();
|
||||
#ifdef GAME_DLL
|
||||
if ( pEntityPhysicsObject )
|
||||
{
|
||||
pEntityPhysicsObject->GetVelocity( &vLinearVelocity, &vAngularVelocity );
|
||||
}
|
||||
else
|
||||
{
|
||||
pEntity->GetVelocity( &vLinearVelocity, &vAngularVelocity );
|
||||
}
|
||||
#else
|
||||
vLinearVelocity = pEntity->GetAbsVelocity();
|
||||
// vAngularVelocity = vec3_origin; //TODO: Find client equivalent of server code above for angular impulse
|
||||
QAngleToAngularImpulse( pEntity->GetLocalAngularVelocity(), vAngularVelocity );
|
||||
#endif
|
||||
|
||||
if ( pEntity->GetAbsVelocity() != vec3_origin )
|
||||
return true;
|
||||
|
||||
//ugh, func_brush attached to an animating entity doesn't give the entity a velocity. Check implicit velocity
|
||||
if( pEntityPhysicsObject && pEntityPhysicsObject->IsMoveable() )
|
||||
{
|
||||
Vector vOtherImplicitVelocity;
|
||||
pEntityPhysicsObject->GetImplicitVelocity( &vOtherImplicitVelocity, NULL );
|
||||
if( vOtherImplicitVelocity.LengthSqr() > 1e-1 )
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
CBaseEntity *pCheck = pEntity;
|
||||
while( pCheck )
|
||||
{
|
||||
if( pCheck->GetLocalAngularVelocity() != vec3_angle )
|
||||
return true;
|
||||
|
||||
pCheck = pCheck->GetParent();
|
||||
}
|
||||
#endif
|
||||
|
||||
// don't check for the speed, and check for position offset from when the portal is placed instead.
|
||||
/*if ( vLinearVelocity.LengthSqr() > 1e-1 || vAngularVelocity.LengthSqr() > 1e-1 )
|
||||
return true;*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
void UTIL_TransformInterpolatedAngle( CInterpolatedVar< QAngle > &qInterped, matrix3x4_t matTransform, bool bSkipNewest )
|
||||
{
|
||||
|
||||
@ -92,6 +92,7 @@ void UTIL_Portal_NDebugOverlay( const Vector &ptPortalCenter, const QAngle &qPor
|
||||
void UTIL_Portal_NDebugOverlay( const CProp_Portal *pPortal, int r, int g, int b, int a, bool noDepthTest, float duration );
|
||||
|
||||
bool FindClosestPassableSpace( CBaseEntity *pEntity, const Vector &vIndecisivePush, unsigned int fMask = MASK_SOLID ); //assumes the object is already in a mostly passable space
|
||||
bool UTIL_IsEntityMovingOrRotating( CBaseEntity* pEntity );
|
||||
|
||||
bool UTIL_IsPaintableSurface( const csurface_t *surface );
|
||||
PaintPowerType UTIL_Paint_TracePower(CBaseEntity *pBrushEntity,Vector contactPoint,Vector *vContactNormal);
|
||||
|
||||
@ -15,6 +15,36 @@
|
||||
|
||||
CUtlVector<CProp_Portal *> CProp_Portal_Shared::AllPortals;
|
||||
|
||||
void MobilePortalsUpdatedCallback( IConVar *var, const char *pOldValue, float flOldValue );
|
||||
ConVar sv_allow_mobile_portals( "sv_allow_mobile_portals", "0", FCVAR_REPLICATED, "", MobilePortalsUpdatedCallback );
|
||||
|
||||
void MobilePortalsUpdatedCallback( IConVar *var, const char *pOldValue, float flOldValue )
|
||||
{
|
||||
if ( sv_allow_mobile_portals.GetFloat() == flOldValue )
|
||||
return;
|
||||
|
||||
static ConVarRef sv_cheats ( "sv_cheats" );
|
||||
bool bCheatsAllowed = (sv_cheats.IsValid() && sv_cheats.GetBool() );
|
||||
|
||||
if ( !bCheatsAllowed )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
DevMsg( engine->GetLevelName() );
|
||||
if ( V_stricmp( engine->GetLevelName(), "sp_a2_bts5" ) == 0 )
|
||||
#else
|
||||
if ( V_stricmp( gpGlobals->mapname.ToCStr(), "sp_a2_bts5" ) == 0 )
|
||||
#endif
|
||||
{
|
||||
bCheatsAllowed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bCheatsAllowed )
|
||||
{
|
||||
var->SetValue( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
const Vector CProp_Portal_Shared::vLocalMins( 0.0f, -PORTAL_HALF_WIDTH, -PORTAL_HALF_HEIGHT );
|
||||
const Vector CProp_Portal_Shared::vLocalMaxs( 64.0f, PORTAL_HALF_WIDTH, PORTAL_HALF_HEIGHT );
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user