mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-12 11:49:09 +00:00
1
This commit is contained in:
@@ -0,0 +1,377 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "C_PortalGhostRenderable.h"
|
||||
#include "PortalRender.h"
|
||||
#include "c_portal_player.h"
|
||||
#include "model_types.h"
|
||||
|
||||
C_PortalGhostRenderable::C_PortalGhostRenderable( C_Prop_Portal *pOwningPortal, C_BaseEntity *pGhostSource, RenderGroup_t sourceRenderGroup, const VMatrix &matGhostTransform, float *pSharedRenderClipPlane, bool bLocalPlayer )
|
||||
: m_pGhostedRenderable( pGhostSource ),
|
||||
m_matGhostTransform( matGhostTransform ),
|
||||
m_pSharedRenderClipPlane( pSharedRenderClipPlane ),
|
||||
m_bLocalPlayer( bLocalPlayer ),
|
||||
m_pOwningPortal( pOwningPortal )
|
||||
{
|
||||
m_bSourceIsBaseAnimating = (dynamic_cast<C_BaseAnimating *>(pGhostSource) != NULL);
|
||||
|
||||
cl_entitylist->AddNonNetworkableEntity( GetIClientUnknown() );
|
||||
g_pClientLeafSystem->AddRenderable( this, sourceRenderGroup );
|
||||
}
|
||||
|
||||
C_PortalGhostRenderable::~C_PortalGhostRenderable( void )
|
||||
{
|
||||
m_pGhostedRenderable = NULL;
|
||||
g_pClientLeafSystem->RemoveRenderable( RenderHandle() );
|
||||
cl_entitylist->RemoveEntity( GetIClientUnknown()->GetRefEHandle() );
|
||||
|
||||
DestroyModelInstance();
|
||||
}
|
||||
|
||||
void C_PortalGhostRenderable::PerFrameUpdate( void )
|
||||
{
|
||||
if( m_pGhostedRenderable )
|
||||
{
|
||||
SetModelName( m_pGhostedRenderable->GetModelName() );
|
||||
SetModelIndex( m_pGhostedRenderable->GetModelIndex() );
|
||||
SetEffects( m_pGhostedRenderable->GetEffects() | EF_NOINTERP );
|
||||
m_flAnimTime = m_pGhostedRenderable->m_flAnimTime;
|
||||
|
||||
if( m_bSourceIsBaseAnimating )
|
||||
{
|
||||
C_BaseAnimating *pSource = (C_BaseAnimating *)m_pGhostedRenderable;
|
||||
SetCycle( pSource->GetCycle() );
|
||||
SetSequence( pSource->GetSequence() );
|
||||
m_nBody = pSource->m_nBody;
|
||||
m_nSkin = pSource->m_nSkin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set position and angles relative to the object it's ghosting
|
||||
Vector ptNewOrigin = m_matGhostTransform * m_pGhostedRenderable->GetAbsOrigin();
|
||||
QAngle qNewAngles = TransformAnglesToWorldSpace( m_pGhostedRenderable->GetAbsAngles(), m_matGhostTransform.As3x4() );
|
||||
|
||||
SetAbsOrigin( ptNewOrigin );
|
||||
SetAbsAngles( qNewAngles );
|
||||
|
||||
AddEffects( EF_NOINTERP );
|
||||
|
||||
RemoveFromInterpolationList();
|
||||
|
||||
g_pClientLeafSystem->RenderableChanged( RenderHandle() );
|
||||
}
|
||||
|
||||
Vector const& C_PortalGhostRenderable::GetRenderOrigin( void )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return m_ReferencedReturns.vRenderOrigin;
|
||||
|
||||
m_ReferencedReturns.vRenderOrigin = m_matGhostTransform * m_pGhostedRenderable->GetRenderOrigin();
|
||||
return m_ReferencedReturns.vRenderOrigin;
|
||||
}
|
||||
|
||||
QAngle const& C_PortalGhostRenderable::GetRenderAngles( void )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return m_ReferencedReturns.qRenderAngle;
|
||||
|
||||
m_ReferencedReturns.qRenderAngle = TransformAnglesToWorldSpace( m_pGhostedRenderable->GetRenderAngles(), m_matGhostTransform.As3x4() );
|
||||
return m_ReferencedReturns.qRenderAngle;
|
||||
}
|
||||
|
||||
bool C_PortalGhostRenderable::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
int nModelIndex = 0;
|
||||
CBaseCombatWeapon *pParent = dynamic_cast<CBaseCombatWeapon*>( m_pGhostedRenderable );
|
||||
if ( pParent )
|
||||
{
|
||||
nModelIndex = pParent->GetModelIndex();
|
||||
pParent->SetModelIndex( pParent->GetWorldModelIndex() );
|
||||
}
|
||||
|
||||
if( m_pGhostedRenderable->SetupBones( pBoneToWorldOut, nMaxBones, boneMask, currentTime ) )
|
||||
{
|
||||
if( pBoneToWorldOut )
|
||||
{
|
||||
for( int i = 0; i != nMaxBones; ++i ) //FIXME: nMaxBones is most definitely greater than the actual number of bone transforms actually used, find the subset somehow
|
||||
{
|
||||
pBoneToWorldOut[i] = (m_matGhostTransform * pBoneToWorldOut[i]).As3x4();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( pParent )
|
||||
{
|
||||
pParent->SetModelIndex( nModelIndex );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void C_PortalGhostRenderable::GetRenderBounds( Vector& mins, Vector& maxs )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
{
|
||||
mins = maxs = vec3_origin;
|
||||
return;
|
||||
}
|
||||
|
||||
m_pGhostedRenderable->GetRenderBounds( mins, maxs );
|
||||
}
|
||||
|
||||
void C_PortalGhostRenderable::GetRenderBoundsWorldspace( Vector& mins, Vector& maxs )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
{
|
||||
mins = maxs = vec3_origin;
|
||||
return;
|
||||
}
|
||||
|
||||
m_pGhostedRenderable->GetRenderBoundsWorldspace( mins, maxs );
|
||||
TransformAABB( m_matGhostTransform.As3x4(), mins, maxs, mins, maxs );
|
||||
}
|
||||
|
||||
void C_PortalGhostRenderable::GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType )
|
||||
{
|
||||
m_pGhostedRenderable->GetShadowRenderBounds( mins, maxs, shadowType );
|
||||
TransformAABB( m_matGhostTransform.As3x4(), mins, maxs, mins, maxs );
|
||||
}
|
||||
|
||||
/*bool C_PortalGhostRenderable::GetShadowCastDistance( float *pDist, ShadowType_t shadowType ) const
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
return m_pGhostedRenderable->GetShadowCastDistance( pDist, shadowType );
|
||||
}
|
||||
|
||||
bool C_PortalGhostRenderable::GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
if( m_pGhostedRenderable->GetShadowCastDirection( pDirection, shadowType ) )
|
||||
{
|
||||
if( pDirection )
|
||||
*pDirection = m_matGhostTransform.ApplyRotation( *pDirection );
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}*/
|
||||
|
||||
const matrix3x4_t & C_PortalGhostRenderable::RenderableToWorldTransform()
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return m_ReferencedReturns.matRenderableToWorldTransform;
|
||||
|
||||
ConcatTransforms( m_matGhostTransform.As3x4(), m_pGhostedRenderable->RenderableToWorldTransform(), m_ReferencedReturns.matRenderableToWorldTransform );
|
||||
return m_ReferencedReturns.matRenderableToWorldTransform;
|
||||
}
|
||||
|
||||
bool C_PortalGhostRenderable::GetAttachment( int number, Vector &origin, QAngle &angles )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
if( m_pGhostedRenderable->GetAttachment( number, origin, angles ) )
|
||||
{
|
||||
origin = m_matGhostTransform * origin;
|
||||
angles = TransformAnglesToWorldSpace( angles, m_matGhostTransform.As3x4() );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool C_PortalGhostRenderable::GetAttachment( int number, matrix3x4_t &matrix )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
if( m_pGhostedRenderable->GetAttachment( number, matrix ) )
|
||||
{
|
||||
ConcatTransforms( m_matGhostTransform.As3x4(), matrix, matrix );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool C_PortalGhostRenderable::GetAttachment( int number, Vector &origin )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
if( m_pGhostedRenderable->GetAttachment( number, origin ) )
|
||||
{
|
||||
origin = m_matGhostTransform * origin;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool C_PortalGhostRenderable::GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
Vector ghostVel;
|
||||
if( m_pGhostedRenderable->GetAttachmentVelocity( number, ghostVel, angleVel ) )
|
||||
{
|
||||
Vector3DMultiply( m_matGhostTransform, ghostVel, originVel );
|
||||
Vector3DMultiply( m_matGhostTransform, *(Vector*)( &angleVel ), *(Vector*)( &angleVel ) );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int C_PortalGhostRenderable::DrawModel( int flags )
|
||||
{
|
||||
if( m_bSourceIsBaseAnimating )
|
||||
{
|
||||
if( m_bLocalPlayer )
|
||||
{
|
||||
C_Portal_Player *pPlayer = C_Portal_Player::GetLocalPlayer();
|
||||
|
||||
if ( !pPlayer->IsAlive() )
|
||||
{
|
||||
// Dead player uses a ragdoll to draw, so don't ghost the dead entity
|
||||
return 0;
|
||||
}
|
||||
else if( g_pPortalRender->GetViewRecursionLevel() == 0 )
|
||||
{
|
||||
if( pPlayer->m_bEyePositionIsTransformedByPortal )
|
||||
return 0;
|
||||
}
|
||||
else if( g_pPortalRender->GetViewRecursionLevel() == 1 )
|
||||
{
|
||||
if( !pPlayer->m_bEyePositionIsTransformedByPortal )
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return C_BaseAnimating::DrawModel( flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawBrushModelMode_t mode = DBM_DRAW_ALL;
|
||||
if ( flags & STUDIO_TWOPASS )
|
||||
{
|
||||
mode = ( flags & STUDIO_TRANSPARENCY ) ? DBM_DRAW_TRANSLUCENT_ONLY : DBM_DRAW_OPAQUE_ONLY;
|
||||
}
|
||||
|
||||
render->DrawBrushModelEx( m_pGhostedRenderable,
|
||||
(model_t *)m_pGhostedRenderable->GetModel(),
|
||||
GetRenderOrigin(),
|
||||
GetRenderAngles(),
|
||||
mode );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ModelInstanceHandle_t C_PortalGhostRenderable::GetModelInstance()
|
||||
{
|
||||
if ( m_pGhostedRenderable )
|
||||
return m_pGhostedRenderable->GetModelInstance();
|
||||
|
||||
return BaseClass::GetModelInstance();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool C_PortalGhostRenderable::IsTransparent( void )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
return m_pGhostedRenderable->IsTransparent();
|
||||
}
|
||||
|
||||
bool C_PortalGhostRenderable::UsesPowerOfTwoFrameBufferTexture()
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
return m_pGhostedRenderable->UsesPowerOfTwoFrameBufferTexture();
|
||||
}
|
||||
|
||||
/*const model_t* C_PortalGhostRenderable::GetModel( ) const
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return NULL;
|
||||
|
||||
return m_pGhostedRenderable->GetModel();
|
||||
}
|
||||
|
||||
int C_PortalGhostRenderable::GetBody()
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return 0;
|
||||
|
||||
return m_pGhostedRenderable->GetBody();
|
||||
}*/
|
||||
|
||||
void C_PortalGhostRenderable::GetColorModulation( float* color )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return;
|
||||
|
||||
return m_pGhostedRenderable->GetColorModulation( color );
|
||||
}
|
||||
|
||||
/*ShadowType_t C_PortalGhostRenderable::ShadowCastType()
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return SHADOWS_NONE;
|
||||
|
||||
return m_pGhostedRenderable->ShadowCastType();
|
||||
}*/
|
||||
|
||||
int C_PortalGhostRenderable::LookupAttachment( const char *pAttachmentName )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return -1;
|
||||
|
||||
|
||||
return m_pGhostedRenderable->LookupAttachment( pAttachmentName );
|
||||
}
|
||||
|
||||
/*int C_PortalGhostRenderable::GetSkin()
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return -1;
|
||||
|
||||
|
||||
return m_pGhostedRenderable->GetSkin();
|
||||
}
|
||||
|
||||
bool C_PortalGhostRenderable::IsTwoPass( void )
|
||||
{
|
||||
if( m_pGhostedRenderable == NULL )
|
||||
return false;
|
||||
|
||||
return m_pGhostedRenderable->IsTwoPass();
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user