From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/client/c_sprite.cpp | 1000 +++++++++++++++++++-------------------- 1 file changed, 500 insertions(+), 500 deletions(-) (limited to 'mp/src/game/client/c_sprite.cpp') diff --git a/mp/src/game/client/c_sprite.cpp b/mp/src/game/client/c_sprite.cpp index 6cedec12..9146eefc 100644 --- a/mp/src/game/client/c_sprite.cpp +++ b/mp/src/game/client/c_sprite.cpp @@ -1,500 +1,500 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// -#include "cbase.h" -#include "c_sprite.h" -#include "model_types.h" -#include "iviewrender.h" -#include "view.h" -#include "enginesprite.h" -#include "engine/ivmodelinfo.h" -#include "util_shared.h" -#include "tier0/vprof.h" -#include "materialsystem/imaterial.h" -#include "materialsystem/imaterialvar.h" -#include "view_shared.h" -#include "viewrender.h" -#include "tier1/KeyValues.h" -#include "toolframework/itoolframework.h" -#include "toolframework_client.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -ConVar r_drawsprites( "r_drawsprites", "1", FCVAR_CHEAT ); - -//----------------------------------------------------------------------------- -// Purpose: Generic sprite model renderer -// Input : *baseentity - -// *psprite - -// fscale - -// frame - -// rendermode - -// r - -// g - -// b - -// a - -// forward - -// right - -// up - -//----------------------------------------------------------------------------- -static unsigned int s_nHDRColorScaleCache = 0; -void DrawSpriteModel( IClientEntity *baseentity, CEngineSprite *psprite, const Vector &origin, float fscale, float frame, - int rendermode, int r, int g, int b, int a, const Vector& forward, const Vector& right, const Vector& up, float flHDRColorScale ) -{ - float scale; - IMaterial *material; - - // don't even bother culling, because it's just a single - // polygon without a surface cache - if ( fscale > 0 ) - scale = fscale; - else - scale = 1.0f; - - if ( rendermode == kRenderNormal ) - { - render->SetBlend( 1.0f ); - } - - material = psprite->GetMaterial( (RenderMode_t)rendermode, frame ); - if ( !material ) - return; - - CMatRenderContextPtr pRenderContext( materials ); - - if ( ShouldDrawInWireFrameMode() || r_drawsprites.GetInt() == 2 ) - { - IMaterial *pMaterial = materials->FindMaterial( "debug/debugspritewireframe", TEXTURE_GROUP_OTHER ); - pRenderContext->Bind( pMaterial, NULL ); - } - else - { - pRenderContext->Bind( material, (IClientRenderable*)baseentity ); - } - - unsigned char color[4]; - color[0] = r; - color[1] = g; - color[2] = b; - color[3] = a; - - IMaterialVar *pHDRColorScaleVar = material->FindVarFast( "$HDRCOLORSCALE", &s_nHDRColorScaleCache ); - if( pHDRColorScaleVar ) - { - pHDRColorScaleVar->SetVecValue( flHDRColorScale, flHDRColorScale, flHDRColorScale ); - } - - Vector point; - IMesh* pMesh = pRenderContext->GetDynamicMesh(); - - CMeshBuilder meshBuilder; - meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); - - Vector vec_a; - Vector vec_b; - Vector vec_c; - Vector vec_d; - - // isolate common terms - VectorMA( origin, psprite->GetDown() * scale, up, vec_a ); - VectorScale( right, psprite->GetLeft() * scale, vec_b ); - VectorMA( origin, psprite->GetUp() * scale, up, vec_c ); - VectorScale( right, psprite->GetRight() * scale, vec_d ); - - float flMinU, flMinV, flMaxU, flMaxV; - psprite->GetTexCoordRange( &flMinU, &flMinV, &flMaxU, &flMaxV ); - - meshBuilder.Color4ubv( color ); - meshBuilder.TexCoord2f( 0, flMinU, flMaxV ); - VectorAdd( vec_a, vec_b, point ); - meshBuilder.Position3fv( point.Base() ); - meshBuilder.AdvanceVertex(); - - meshBuilder.Color4ubv( color ); - meshBuilder.TexCoord2f( 0, flMinU, flMinV ); - VectorAdd( vec_c, vec_b, point ); - meshBuilder.Position3fv( point.Base() ); - meshBuilder.AdvanceVertex(); - - meshBuilder.Color4ubv( color ); - meshBuilder.TexCoord2f( 0, flMaxU, flMinV ); - VectorAdd( vec_c, vec_d, point ); - meshBuilder.Position3fv( point.Base() ); - meshBuilder.AdvanceVertex(); - - meshBuilder.Color4ubv( color ); - meshBuilder.TexCoord2f( 0, flMaxU, flMaxV ); - VectorAdd( vec_a, vec_d, point ); - meshBuilder.Position3fv( point.Base() ); - meshBuilder.AdvanceVertex(); - - meshBuilder.End(); - pMesh->Draw(); -} - -//----------------------------------------------------------------------------- -// Purpose: Determine glow brightness/scale based on distance to render origin and trace results -// Input : entorigin - -// rendermode - -// renderfx - -// alpha - -// pscale - Pointer to the value for scale, will be changed based on distance and rendermode. -//----------------------------------------------------------------------------- -float StandardGlowBlend( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle, int rendermode, int renderfx, int alpha, float *pscale ) -{ - float dist; - float brightness; - - brightness = PixelVisibility_FractionVisible( params, queryHandle ); - if ( brightness <= 0.0f ) - { - return 0.0f; - } - dist = GlowSightDistance( params.position, false ); - if ( dist <= 0.0f ) - { - return 0.0f; - } - - if ( renderfx == kRenderFxNoDissipation ) - { - return (float)alpha * (1.0f/255.0f) * brightness; - } - - // UNDONE: Tweak these magic numbers (1200 - distance at full brightness) - float fadeOut = (1200.0f*1200.0f) / (dist*dist); - fadeOut = clamp( fadeOut, 0.0f, 1.0f ); - - if (rendermode != kRenderWorldGlow) - { - // Make the glow fixed size in screen space, taking into consideration the scale setting. - if ( *pscale == 0.0f ) - { - *pscale = 1.0f; - } - - *pscale *= dist * (1.0f/200.0f); - } - - return fadeOut * brightness; -} - -static float SpriteAspect( CEngineSprite *pSprite ) -{ - if ( pSprite ) - { - float x = fabsf(pSprite->GetRight() - pSprite->GetLeft()); - float y = fabsf(pSprite->GetDown() - pSprite->GetUp()); - if ( y != 0 && x != 0 ) - { - return x / y; - } - } - - return 1.0f; -} - -float C_SpriteRenderer::GlowBlend( CEngineSprite *psprite, const Vector& entorigin, int rendermode, int renderfx, int alpha, float *pscale ) -{ - pixelvis_queryparams_t params; - float aspect = SpriteAspect(psprite); - params.Init( entorigin, PIXELVIS_DEFAULT_PROXY_SIZE, aspect ); - return StandardGlowBlend( params, &m_queryHandle, rendermode, renderfx, alpha, pscale ); -} - -// since sprites can network down a glow proxy size, handle that here -float CSprite::GlowBlend( CEngineSprite *psprite, const Vector& entorigin, int rendermode, int renderfx, int alpha, float *pscale ) -{ - pixelvis_queryparams_t params; - float aspect = SpriteAspect(psprite); - params.Init( entorigin, m_flGlowProxySize, aspect ); - return StandardGlowBlend( params, &m_queryHandle, rendermode, renderfx, alpha, pscale ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Determine sprite orientation axes -// Input : type - -// forward - -// right - -// up - -//----------------------------------------------------------------------------- -void C_SpriteRenderer::GetSpriteAxes( SPRITETYPE type, - const Vector& origin, - const QAngle& angles, - Vector& forward, - Vector& right, - Vector& up ) -{ - int i; - float dot, angle, sr, cr; - Vector tvec; - - // Automatically roll parallel sprites if requested - if ( angles[2] != 0 && type == SPR_VP_PARALLEL ) - { - type = SPR_VP_PARALLEL_ORIENTED; - } - - switch( type ) - { - case SPR_FACING_UPRIGHT: - { - // generate the sprite's axes, with vup straight up in worldspace, and - // r_spritedesc.vright perpendicular to modelorg. - // This will not work if the view direction is very close to straight up or - // down, because the cross product will be between two nearly parallel - // vectors and starts to approach an undefined state, so we don't draw if - // the two vectors are less than 1 degree apart - tvec[0] = -origin[0]; - tvec[1] = -origin[1]; - tvec[2] = -origin[2]; - VectorNormalize (tvec); - dot = tvec[2]; // same as DotProduct (tvec, r_spritedesc.vup) because - // r_spritedesc.vup is 0, 0, 1 - if ((dot > 0.999848f) || (dot < -0.999848f)) // cos(1 degree) = 0.999848 - return; - up[0] = 0; - up[1] = 0; - up[2] = 1; - right[0] = tvec[1]; - // CrossProduct(r_spritedesc.vup, -modelorg, - right[1] = -tvec[0]; - // r_spritedesc.vright) - right[2] = 0; - VectorNormalize (right); - forward[0] = -right[1]; - forward[1] = right[0]; - forward[2] = 0; - // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, - // r_spritedesc.vpn) - } - break; - - case SPR_VP_PARALLEL: - { - // generate the sprite's axes, completely parallel to the viewplane. There - // are no problem situations, because the sprite is always in the same - // position relative to the viewer - for (i=0 ; i<3 ; i++) - { - up[i] = CurrentViewUp()[i]; - right[i] = CurrentViewRight()[i]; - forward[i] = CurrentViewForward()[i]; - } - } - break; - - case SPR_VP_PARALLEL_UPRIGHT: - { - // generate the sprite's axes, with g_vecVUp straight up in worldspace, and - // r_spritedesc.vright parallel to the viewplane. - // This will not work if the view direction is very close to straight up or - // down, because the cross product will be between two nearly parallel - // vectors and starts to approach an undefined state, so we don't draw if - // the two vectors are less than 1 degree apart - dot = CurrentViewForward()[2]; // same as DotProduct (vpn, r_spritedesc.g_vecVUp) because - // r_spritedesc.vup is 0, 0, 1 - if ((dot > 0.999848f) || (dot < -0.999848f)) // cos(1 degree) = 0.999848 - return; - up[0] = 0; - up[1] = 0; - up[2] = 1; - right[0] = CurrentViewForward()[1]; - // CrossProduct (r_spritedesc.vup, vpn, - right[1] = -CurrentViewForward()[0]; // r_spritedesc.vright) - right[2] = 0; - VectorNormalize (right); - forward[0] = -right[1]; - forward[1] = right[0]; - forward[2] = 0; - // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, - // r_spritedesc.vpn) - } - break; - - case SPR_ORIENTED: - { - // generate the sprite's axes, according to the sprite's world orientation - AngleVectors( angles, &forward, &right, &up ); - } - break; - - case SPR_VP_PARALLEL_ORIENTED: - { - // generate the sprite's axes, parallel to the viewplane, but rotated in - // that plane around the center according to the sprite entity's roll - // angle. So vpn stays the same, but vright and vup rotate - angle = angles[ROLL] * (M_PI*2.0f/360.0f); - SinCos( angle, &sr, &cr ); - - for (i=0 ; i<3 ; i++) - { - forward[i] = CurrentViewForward()[i]; - right[i] = CurrentViewRight()[i] * cr + CurrentViewUp()[i] * sr; - up[i] = CurrentViewRight()[i] * -sr + CurrentViewUp()[i] * cr; - } - } - break; - - default: - Warning( "GetSpriteAxes: Bad sprite type %d\n", type ); - break; - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : int -//----------------------------------------------------------------------------- -int C_SpriteRenderer::DrawSprite( - IClientEntity *entity, - const model_t *model, - const Vector& origin, - const QAngle& angles, - float frame, - IClientEntity *attachedto, - int attachmentindex, - int rendermode, - int renderfx, - int alpha, - int r, - int g, - int b, - float scale, - float flHDRColorScale - ) -{ - VPROF_BUDGET( "C_SpriteRenderer::DrawSprite", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); - - if ( !r_drawsprites.GetBool() || !model || modelinfo->GetModelType( model ) != mod_sprite ) - { - return 0; - } - - // Get extra data - CEngineSprite *psprite = (CEngineSprite *)modelinfo->GetModelExtraData( model ); - if ( !psprite ) - { - return 0; - } - - Vector effect_origin; - VectorCopy( origin, effect_origin ); - - // Use attachment point - if ( attachedto ) - { - C_BaseEntity *ent = attachedto->GetBaseEntity(); - if ( ent ) - { - // don't draw viewmodel effects in reflections - if ( CurrentViewID() == VIEW_REFLECTION ) - { - int group = ent->GetRenderGroup(); - if ( group == RENDER_GROUP_VIEW_MODEL_TRANSLUCENT || group == RENDER_GROUP_VIEW_MODEL_OPAQUE ) - return 0; - } - QAngle temp; - ent->GetAttachment( attachmentindex, effect_origin, temp ); - } - } - - if ( rendermode != kRenderNormal ) - { - float blend = render->GetBlend(); - - // kRenderGlow and kRenderWorldGlow have a special blending function - if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow )) - { - blend *= GlowBlend( psprite, effect_origin, rendermode, renderfx, alpha, &scale ); - - // Fade out the sprite depending on distance from the view origin. - r *= blend; - g *= blend; - b *= blend; - } - - render->SetBlend( blend ); - if ( blend <= 0.0f ) - { - return 0; - } - } - - // Get orthonormal basis - Vector forward, right, up; - GetSpriteAxes( (SPRITETYPE)psprite->GetOrientation(), origin, angles, forward, right, up ); - - // Draw - DrawSpriteModel( - entity, - psprite, - effect_origin, - scale, - frame, - rendermode, - r, - g, - b, - alpha, - forward, right, up, flHDRColorScale ); - - return 1; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CSprite::GetToolRecordingState( KeyValues *msg ) -{ - if ( !ToolsEnabled() ) - return; - - VPROF_BUDGET( "CSprite::GetToolRecordingState", VPROF_BUDGETGROUP_TOOLS ); - - BaseClass::GetToolRecordingState( msg ); - - // Use attachment point - if ( m_hAttachedToEntity ) - { - C_BaseEntity *ent = m_hAttachedToEntity->GetBaseEntity(); - if ( ent ) - { - BaseEntityRecordingState_t *pState = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" ); - - // override position if we're driven by an attachment - QAngle temp; - pState->m_vecRenderOrigin = GetAbsOrigin(); - ent->GetAttachment( m_nAttachment, pState->m_vecRenderOrigin, temp ); - - // override viewmodel if we're driven by an attachment - bool bViewModel = dynamic_cast< C_BaseViewModel* >( ent ) != NULL; - msg->SetInt( "viewmodel", bViewModel ); - } - } - - float renderscale = GetRenderScale(); - if ( m_bWorldSpaceScale ) - { - CEngineSprite *psprite = ( CEngineSprite * )modelinfo->GetModelExtraData( GetModel() ); - float flMinSize = MIN( psprite->GetWidth(), psprite->GetHeight() ); - renderscale /= flMinSize; - } - - // sprite params - static SpriteRecordingState_t state; - state.m_flRenderScale = renderscale; - state.m_flFrame = m_flFrame; - state.m_flProxyRadius = m_flGlowProxySize; - state.m_nRenderMode = GetRenderMode(); - state.m_nRenderFX = m_nRenderFX; - state.m_Color.SetColor( m_clrRender.GetR(), m_clrRender.GetG(), m_clrRender.GetB(), GetRenderBrightness() ); - - msg->SetPtr( "sprite", &state ); -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// +#include "cbase.h" +#include "c_sprite.h" +#include "model_types.h" +#include "iviewrender.h" +#include "view.h" +#include "enginesprite.h" +#include "engine/ivmodelinfo.h" +#include "util_shared.h" +#include "tier0/vprof.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imaterialvar.h" +#include "view_shared.h" +#include "viewrender.h" +#include "tier1/KeyValues.h" +#include "toolframework/itoolframework.h" +#include "toolframework_client.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +ConVar r_drawsprites( "r_drawsprites", "1", FCVAR_CHEAT ); + +//----------------------------------------------------------------------------- +// Purpose: Generic sprite model renderer +// Input : *baseentity - +// *psprite - +// fscale - +// frame - +// rendermode - +// r - +// g - +// b - +// a - +// forward - +// right - +// up - +//----------------------------------------------------------------------------- +static unsigned int s_nHDRColorScaleCache = 0; +void DrawSpriteModel( IClientEntity *baseentity, CEngineSprite *psprite, const Vector &origin, float fscale, float frame, + int rendermode, int r, int g, int b, int a, const Vector& forward, const Vector& right, const Vector& up, float flHDRColorScale ) +{ + float scale; + IMaterial *material; + + // don't even bother culling, because it's just a single + // polygon without a surface cache + if ( fscale > 0 ) + scale = fscale; + else + scale = 1.0f; + + if ( rendermode == kRenderNormal ) + { + render->SetBlend( 1.0f ); + } + + material = psprite->GetMaterial( (RenderMode_t)rendermode, frame ); + if ( !material ) + return; + + CMatRenderContextPtr pRenderContext( materials ); + + if ( ShouldDrawInWireFrameMode() || r_drawsprites.GetInt() == 2 ) + { + IMaterial *pMaterial = materials->FindMaterial( "debug/debugspritewireframe", TEXTURE_GROUP_OTHER ); + pRenderContext->Bind( pMaterial, NULL ); + } + else + { + pRenderContext->Bind( material, (IClientRenderable*)baseentity ); + } + + unsigned char color[4]; + color[0] = r; + color[1] = g; + color[2] = b; + color[3] = a; + + IMaterialVar *pHDRColorScaleVar = material->FindVarFast( "$HDRCOLORSCALE", &s_nHDRColorScaleCache ); + if( pHDRColorScaleVar ) + { + pHDRColorScaleVar->SetVecValue( flHDRColorScale, flHDRColorScale, flHDRColorScale ); + } + + Vector point; + IMesh* pMesh = pRenderContext->GetDynamicMesh(); + + CMeshBuilder meshBuilder; + meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); + + Vector vec_a; + Vector vec_b; + Vector vec_c; + Vector vec_d; + + // isolate common terms + VectorMA( origin, psprite->GetDown() * scale, up, vec_a ); + VectorScale( right, psprite->GetLeft() * scale, vec_b ); + VectorMA( origin, psprite->GetUp() * scale, up, vec_c ); + VectorScale( right, psprite->GetRight() * scale, vec_d ); + + float flMinU, flMinV, flMaxU, flMaxV; + psprite->GetTexCoordRange( &flMinU, &flMinV, &flMaxU, &flMaxV ); + + meshBuilder.Color4ubv( color ); + meshBuilder.TexCoord2f( 0, flMinU, flMaxV ); + VectorAdd( vec_a, vec_b, point ); + meshBuilder.Position3fv( point.Base() ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color4ubv( color ); + meshBuilder.TexCoord2f( 0, flMinU, flMinV ); + VectorAdd( vec_c, vec_b, point ); + meshBuilder.Position3fv( point.Base() ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color4ubv( color ); + meshBuilder.TexCoord2f( 0, flMaxU, flMinV ); + VectorAdd( vec_c, vec_d, point ); + meshBuilder.Position3fv( point.Base() ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color4ubv( color ); + meshBuilder.TexCoord2f( 0, flMaxU, flMaxV ); + VectorAdd( vec_a, vec_d, point ); + meshBuilder.Position3fv( point.Base() ); + meshBuilder.AdvanceVertex(); + + meshBuilder.End(); + pMesh->Draw(); +} + +//----------------------------------------------------------------------------- +// Purpose: Determine glow brightness/scale based on distance to render origin and trace results +// Input : entorigin - +// rendermode - +// renderfx - +// alpha - +// pscale - Pointer to the value for scale, will be changed based on distance and rendermode. +//----------------------------------------------------------------------------- +float StandardGlowBlend( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle, int rendermode, int renderfx, int alpha, float *pscale ) +{ + float dist; + float brightness; + + brightness = PixelVisibility_FractionVisible( params, queryHandle ); + if ( brightness <= 0.0f ) + { + return 0.0f; + } + dist = GlowSightDistance( params.position, false ); + if ( dist <= 0.0f ) + { + return 0.0f; + } + + if ( renderfx == kRenderFxNoDissipation ) + { + return (float)alpha * (1.0f/255.0f) * brightness; + } + + // UNDONE: Tweak these magic numbers (1200 - distance at full brightness) + float fadeOut = (1200.0f*1200.0f) / (dist*dist); + fadeOut = clamp( fadeOut, 0.0f, 1.0f ); + + if (rendermode != kRenderWorldGlow) + { + // Make the glow fixed size in screen space, taking into consideration the scale setting. + if ( *pscale == 0.0f ) + { + *pscale = 1.0f; + } + + *pscale *= dist * (1.0f/200.0f); + } + + return fadeOut * brightness; +} + +static float SpriteAspect( CEngineSprite *pSprite ) +{ + if ( pSprite ) + { + float x = fabsf(pSprite->GetRight() - pSprite->GetLeft()); + float y = fabsf(pSprite->GetDown() - pSprite->GetUp()); + if ( y != 0 && x != 0 ) + { + return x / y; + } + } + + return 1.0f; +} + +float C_SpriteRenderer::GlowBlend( CEngineSprite *psprite, const Vector& entorigin, int rendermode, int renderfx, int alpha, float *pscale ) +{ + pixelvis_queryparams_t params; + float aspect = SpriteAspect(psprite); + params.Init( entorigin, PIXELVIS_DEFAULT_PROXY_SIZE, aspect ); + return StandardGlowBlend( params, &m_queryHandle, rendermode, renderfx, alpha, pscale ); +} + +// since sprites can network down a glow proxy size, handle that here +float CSprite::GlowBlend( CEngineSprite *psprite, const Vector& entorigin, int rendermode, int renderfx, int alpha, float *pscale ) +{ + pixelvis_queryparams_t params; + float aspect = SpriteAspect(psprite); + params.Init( entorigin, m_flGlowProxySize, aspect ); + return StandardGlowBlend( params, &m_queryHandle, rendermode, renderfx, alpha, pscale ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Determine sprite orientation axes +// Input : type - +// forward - +// right - +// up - +//----------------------------------------------------------------------------- +void C_SpriteRenderer::GetSpriteAxes( SPRITETYPE type, + const Vector& origin, + const QAngle& angles, + Vector& forward, + Vector& right, + Vector& up ) +{ + int i; + float dot, angle, sr, cr; + Vector tvec; + + // Automatically roll parallel sprites if requested + if ( angles[2] != 0 && type == SPR_VP_PARALLEL ) + { + type = SPR_VP_PARALLEL_ORIENTED; + } + + switch( type ) + { + case SPR_FACING_UPRIGHT: + { + // generate the sprite's axes, with vup straight up in worldspace, and + // r_spritedesc.vright perpendicular to modelorg. + // This will not work if the view direction is very close to straight up or + // down, because the cross product will be between two nearly parallel + // vectors and starts to approach an undefined state, so we don't draw if + // the two vectors are less than 1 degree apart + tvec[0] = -origin[0]; + tvec[1] = -origin[1]; + tvec[2] = -origin[2]; + VectorNormalize (tvec); + dot = tvec[2]; // same as DotProduct (tvec, r_spritedesc.vup) because + // r_spritedesc.vup is 0, 0, 1 + if ((dot > 0.999848f) || (dot < -0.999848f)) // cos(1 degree) = 0.999848 + return; + up[0] = 0; + up[1] = 0; + up[2] = 1; + right[0] = tvec[1]; + // CrossProduct(r_spritedesc.vup, -modelorg, + right[1] = -tvec[0]; + // r_spritedesc.vright) + right[2] = 0; + VectorNormalize (right); + forward[0] = -right[1]; + forward[1] = right[0]; + forward[2] = 0; + // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, + // r_spritedesc.vpn) + } + break; + + case SPR_VP_PARALLEL: + { + // generate the sprite's axes, completely parallel to the viewplane. There + // are no problem situations, because the sprite is always in the same + // position relative to the viewer + for (i=0 ; i<3 ; i++) + { + up[i] = CurrentViewUp()[i]; + right[i] = CurrentViewRight()[i]; + forward[i] = CurrentViewForward()[i]; + } + } + break; + + case SPR_VP_PARALLEL_UPRIGHT: + { + // generate the sprite's axes, with g_vecVUp straight up in worldspace, and + // r_spritedesc.vright parallel to the viewplane. + // This will not work if the view direction is very close to straight up or + // down, because the cross product will be between two nearly parallel + // vectors and starts to approach an undefined state, so we don't draw if + // the two vectors are less than 1 degree apart + dot = CurrentViewForward()[2]; // same as DotProduct (vpn, r_spritedesc.g_vecVUp) because + // r_spritedesc.vup is 0, 0, 1 + if ((dot > 0.999848f) || (dot < -0.999848f)) // cos(1 degree) = 0.999848 + return; + up[0] = 0; + up[1] = 0; + up[2] = 1; + right[0] = CurrentViewForward()[1]; + // CrossProduct (r_spritedesc.vup, vpn, + right[1] = -CurrentViewForward()[0]; // r_spritedesc.vright) + right[2] = 0; + VectorNormalize (right); + forward[0] = -right[1]; + forward[1] = right[0]; + forward[2] = 0; + // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, + // r_spritedesc.vpn) + } + break; + + case SPR_ORIENTED: + { + // generate the sprite's axes, according to the sprite's world orientation + AngleVectors( angles, &forward, &right, &up ); + } + break; + + case SPR_VP_PARALLEL_ORIENTED: + { + // generate the sprite's axes, parallel to the viewplane, but rotated in + // that plane around the center according to the sprite entity's roll + // angle. So vpn stays the same, but vright and vup rotate + angle = angles[ROLL] * (M_PI*2.0f/360.0f); + SinCos( angle, &sr, &cr ); + + for (i=0 ; i<3 ; i++) + { + forward[i] = CurrentViewForward()[i]; + right[i] = CurrentViewRight()[i] * cr + CurrentViewUp()[i] * sr; + up[i] = CurrentViewRight()[i] * -sr + CurrentViewUp()[i] * cr; + } + } + break; + + default: + Warning( "GetSpriteAxes: Bad sprite type %d\n", type ); + break; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : int +//----------------------------------------------------------------------------- +int C_SpriteRenderer::DrawSprite( + IClientEntity *entity, + const model_t *model, + const Vector& origin, + const QAngle& angles, + float frame, + IClientEntity *attachedto, + int attachmentindex, + int rendermode, + int renderfx, + int alpha, + int r, + int g, + int b, + float scale, + float flHDRColorScale + ) +{ + VPROF_BUDGET( "C_SpriteRenderer::DrawSprite", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); + + if ( !r_drawsprites.GetBool() || !model || modelinfo->GetModelType( model ) != mod_sprite ) + { + return 0; + } + + // Get extra data + CEngineSprite *psprite = (CEngineSprite *)modelinfo->GetModelExtraData( model ); + if ( !psprite ) + { + return 0; + } + + Vector effect_origin; + VectorCopy( origin, effect_origin ); + + // Use attachment point + if ( attachedto ) + { + C_BaseEntity *ent = attachedto->GetBaseEntity(); + if ( ent ) + { + // don't draw viewmodel effects in reflections + if ( CurrentViewID() == VIEW_REFLECTION ) + { + int group = ent->GetRenderGroup(); + if ( group == RENDER_GROUP_VIEW_MODEL_TRANSLUCENT || group == RENDER_GROUP_VIEW_MODEL_OPAQUE ) + return 0; + } + QAngle temp; + ent->GetAttachment( attachmentindex, effect_origin, temp ); + } + } + + if ( rendermode != kRenderNormal ) + { + float blend = render->GetBlend(); + + // kRenderGlow and kRenderWorldGlow have a special blending function + if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow )) + { + blend *= GlowBlend( psprite, effect_origin, rendermode, renderfx, alpha, &scale ); + + // Fade out the sprite depending on distance from the view origin. + r *= blend; + g *= blend; + b *= blend; + } + + render->SetBlend( blend ); + if ( blend <= 0.0f ) + { + return 0; + } + } + + // Get orthonormal basis + Vector forward, right, up; + GetSpriteAxes( (SPRITETYPE)psprite->GetOrientation(), origin, angles, forward, right, up ); + + // Draw + DrawSpriteModel( + entity, + psprite, + effect_origin, + scale, + frame, + rendermode, + r, + g, + b, + alpha, + forward, right, up, flHDRColorScale ); + + return 1; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::GetToolRecordingState( KeyValues *msg ) +{ + if ( !ToolsEnabled() ) + return; + + VPROF_BUDGET( "CSprite::GetToolRecordingState", VPROF_BUDGETGROUP_TOOLS ); + + BaseClass::GetToolRecordingState( msg ); + + // Use attachment point + if ( m_hAttachedToEntity ) + { + C_BaseEntity *ent = m_hAttachedToEntity->GetBaseEntity(); + if ( ent ) + { + BaseEntityRecordingState_t *pState = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" ); + + // override position if we're driven by an attachment + QAngle temp; + pState->m_vecRenderOrigin = GetAbsOrigin(); + ent->GetAttachment( m_nAttachment, pState->m_vecRenderOrigin, temp ); + + // override viewmodel if we're driven by an attachment + bool bViewModel = dynamic_cast< C_BaseViewModel* >( ent ) != NULL; + msg->SetInt( "viewmodel", bViewModel ); + } + } + + float renderscale = GetRenderScale(); + if ( m_bWorldSpaceScale ) + { + CEngineSprite *psprite = ( CEngineSprite * )modelinfo->GetModelExtraData( GetModel() ); + float flMinSize = MIN( psprite->GetWidth(), psprite->GetHeight() ); + renderscale /= flMinSize; + } + + // sprite params + static SpriteRecordingState_t state; + state.m_flRenderScale = renderscale; + state.m_flFrame = m_flFrame; + state.m_flProxyRadius = m_flGlowProxySize; + state.m_nRenderMode = GetRenderMode(); + state.m_nRenderFX = m_nRenderFX; + state.m_Color.SetColor( m_clrRender.GetR(), m_clrRender.GetG(), m_clrRender.GetB(), GetRenderBrightness() ); + + msg->SetPtr( "sprite", &state ); +} -- cgit v1.2.3