You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
377 lines
9.4 KiB
377 lines
9.4 KiB
//========= 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(); |
|
}*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|