void CHudCrosshair::GetDrawPosition ( float *pX, float *pY, bool *pbBehindCamera, QAngle angleCrosshairOffset ) { QAngle curViewAngles = CurrentViewAngles(); Vector curViewOrigin = CurrentViewOrigin(); int vx, vy, vw, vh; vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh ); float screenWidth = vw; float screenHeight = vh; float x = screenWidth / 2; float y = screenHeight / 2; bool bBehindCamera = false; C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); if ( ( pPlayer != NULL ) && ( pPlayer->GetObserverMode()==OBS_MODE_NONE ) ) { bool bUseOffset = false; Vector vecStart; Vector vecEnd; if ( UseVR() ) { // These are the correct values to use, but they lag the high-speed view data... vecStart = pPlayer->Weapon_ShootPosition(); Vector vecAimDirection = pPlayer->GetAutoaimVector( 1.0f ); // ...so in some aim modes, they get zapped by something completely up-to-date. g_ClientVirtualReality.OverrideWeaponHudAimVectors ( &vecStart, &vecAimDirection ); vecEnd = vecStart + vecAimDirection * MAX_TRACE_LENGTH; bUseOffset = true; } #ifdef SIXENSE // TODO: actually test this Sixsense code interaction with things like HMDs & stereo. if ( g_pSixenseInput->IsEnabled() && !UseVR() ) { // Never autoaim a predicted weapon (for now) vecStart = pPlayer->Weapon_ShootPosition(); Vector aimVector; AngleVectors( CurrentViewAngles() - g_pSixenseInput->GetViewAngleOffset(), &aimVector ); // calculate where the bullet would go so we can draw the cross appropriately vecEnd = vecStart + aimVector * MAX_TRACE_LENGTH; bUseOffset = true; } #endif if ( bUseOffset ) { trace_t tr; UTIL_TraceLine( vecStart, vecEnd, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr ); Vector screen; screen.Init(); bBehindCamera = ScreenTransform(tr.endpos, screen) != 0; x = 0.5f * ( 1.0f + screen[0] ) * screenWidth + 0.5f; y = 0.5f * ( 1.0f - screen[1] ) * screenHeight + 0.5f; } } // MattB - angleCrosshairOffset is the autoaim angle. // if we're not using autoaim, just draw in the middle of the // screen if ( angleCrosshairOffset != vec3_angle ) { QAngle angles; Vector forward; Vector point, screen; // this code is wrong angles = curViewAngles + angleCrosshairOffset; AngleVectors( angles, &forward ); VectorAdd( curViewOrigin, forward, point ); ScreenTransform( point, screen ); x += 0.5f * screen[0] * screenWidth + 0.5f; y += 0.5f * screen[1] * screenHeight + 0.5f; } *pX = x; *pY = y; *pbBehindCamera = bBehindCamera; }
//----------------------------------------------------------------------------- // Purpose: Third-person function call to render world model //----------------------------------------------------------------------------- int CWeaponGravityGun::DrawModel( int flags ) { // Only render these on the transparent pass if ( flags & STUDIO_TRANSPARENCY ) { if ( !m_active ) return 0; C_BasePlayer *pOwner = ToBasePlayer( GetOwner() ); if ( !pOwner ) return 0; Vector points[3]; QAngle tmpAngle; C_BaseEntity *pObject = m_hObject; //if ( pObject == NULL ) // return 0; GetAttachment( 1, points[0], tmpAngle ); // a little noise 11t & 13t should be somewhat non-periodic looking //points[1].z += 4*sin( gpGlobals->curtime*11 ) + 5*cos( gpGlobals->curtime*13 ); if ( pObject == NULL ) { //points[2] = m_targetPosition; trace_t tr; TraceLine( &tr ); points[2] = tr.endpos; } else { pObject->EntityToWorldSpace( m_worldPosition, &points[2] ); } Vector forward, right, up; QAngle playerAngles = pOwner->EyeAngles(); AngleVectors( playerAngles, &forward, &right, &up ); if ( pObject == NULL ) { Vector vecDir = points[2] - points[0]; VectorNormalize( vecDir ); points[1] = points[0] + 0.5f * (vecDir * points[2].DistTo(points[0])); } else { Vector vecSrc = pOwner->Weapon_ShootPosition( ); points[1] = vecSrc + 0.5f * (forward * points[2].DistTo(points[0])); } IMaterial *pMat = materials->FindMaterial( "sprites/physbeam1", TEXTURE_GROUP_CLIENT_EFFECTS ); if ( pObject ) pMat = materials->FindMaterial( "sprites/physbeam", TEXTURE_GROUP_CLIENT_EFFECTS ); Vector color; color.Init(1,1,1); float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime; CMatRenderContextPtr pRenderContext( materials ); pRenderContext->Bind( pMat ); DrawBeamQuadratic( points[0], points[1], points[2], pObject ? 13/3.0f : 13/5.0f, color, scrollOffset ); DrawBeamQuadratic( points[0], points[1], points[2], pObject ? 13/3.0f : 13/5.0f, color, -scrollOffset ); IMaterial *pMaterial = materials->FindMaterial( "sprites/physglow", TEXTURE_GROUP_CLIENT_EFFECTS ); color32 clr={0,64,255,255}; if ( pObject ) { clr.r = 186; clr.g = 253; clr.b = 247; clr.a = 255; } float scale = random->RandomFloat( 3, 5 ) * ( pObject ? 3 : 2 ); // Draw the sprite pRenderContext->Bind( pMaterial ); for ( int i = 0; i < 3; i++ ) { DrawSprite( points[2], scale, scale, clr ); } return 1; } // Only do this on the opaque pass return BaseClass::DrawModel( flags ); }
//----------------------------------------------------------------------------- // Purpose: First-person function call after viewmodel has been drawn //----------------------------------------------------------------------------- void CWeaponGravityGun::ViewModelDrawn( C_BaseViewModel *pBaseViewModel ) { if ( !m_active ) return; // Render our effects C_BasePlayer *pOwner = ToBasePlayer( GetOwner() ); if ( !pOwner ) return; Vector points[3]; QAngle tmpAngle; C_BaseEntity *pObject = m_hObject; //if ( pObject == NULL ) // return; pBaseViewModel->GetAttachment( 1, points[0], tmpAngle ); // a little noise 11t & 13t should be somewhat non-periodic looking //points[1].z += 4*sin( gpGlobals->curtime*11 ) + 5*cos( gpGlobals->curtime*13 ); if ( pObject == NULL ) { //points[2] = m_targetPosition; trace_t tr; TraceLine( &tr ); points[2] = tr.endpos; } else { pObject->EntityToWorldSpace(m_worldPosition, &points[2]); } Vector forward, right, up; QAngle playerAngles = pOwner->EyeAngles(); AngleVectors( playerAngles, &forward, &right, &up ); Vector vecSrc = pOwner->Weapon_ShootPosition( ); points[1] = vecSrc + 0.5f * (forward * points[2].DistTo(points[0])); IMaterial *pMat = materials->FindMaterial( "sprites/physbeam1", TEXTURE_GROUP_CLIENT_EFFECTS ); if ( pObject ) pMat = materials->FindMaterial( "sprites/physbeam", TEXTURE_GROUP_CLIENT_EFFECTS ); Vector color; color.Init(1,1,1); // Now draw it. CViewSetup beamView = *view->GetPlayerViewSetup(); Frustum dummyFrustum; render->Push3DView( beamView, 0, NULL, dummyFrustum ); float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime; CMatRenderContextPtr pRenderContext( materials ); pRenderContext->Bind( pMat ); #if 1 // HACK HACK: Munge the depth range to prevent view model from poking into walls, etc. // Force clipped down range pRenderContext->DepthRange( 0.1f, 0.2f ); #endif DrawBeamQuadratic( points[0], points[1], points[2], pObject ? 13/3.0f : 13/5.0f, color, scrollOffset ); DrawBeamQuadratic( points[0], points[1], points[2], pObject ? 13/3.0f : 13/5.0f, color, -scrollOffset ); IMaterial *pMaterial = materials->FindMaterial( "sprites/physglow", TEXTURE_GROUP_CLIENT_EFFECTS ); color32 clr={0,64,255,255}; if ( pObject ) { clr.r = 186; clr.g = 253; clr.b = 247; clr.a = 255; } float scale = random->RandomFloat( 3, 5 ) * ( pObject ? 3 : 2 ); // Draw the sprite pRenderContext->Bind( pMaterial ); for ( int i = 0; i < 3; i++ ) { DrawSprite( points[2], scale, scale, clr ); } #if 1 pRenderContext->DepthRange( 0.0f, 1.0f ); #endif render->PopView( dummyFrustum ); // Pass this back up BaseClass::ViewModelDrawn( pBaseViewModel ); }
void CHudCrosshair::Paint( void ) { if ( !m_pCrosshair ) return; if ( !IsCurrentViewAccessAllowed() ) return; float x, y; x = ScreenWidth()/2; y = ScreenHeight()/2; m_curViewAngles = CurrentViewAngles(); m_curViewOrigin = CurrentViewOrigin(); Vector screen; screen.Init(); // TrackIR if ( IsHeadTrackingEnabled() ) { C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return; // TrackIR // get the direction the player is aiming Vector aimVector = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); // calculate where the bullet would go so we can draw the cross appropriately Vector vecEnd = pPlayer->Weapon_ShootPosition() + aimVector * MAX_TRACE_LENGTH; trace_t tr; UTIL_TraceLine( pPlayer->Weapon_ShootPosition(), vecEnd, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr ); QAngle angles; Vector forward; Vector point; // this code is wrong angles = m_curViewAngles + m_vecCrossHairOffsetAngle; AngleVectors( angles, &forward ); // need to project forward into an object to see how far this // vector should be!! //forward *= 1000; //VectorAdd( m_curViewOrigin, forward, point ); //ScreenTransform( point, screen ); ScreenTransform(tr.endpos, screen); } // TrackIR else { // MattB - m_vecCrossHairOffsetAngle is the autoaim angle. // if we're not using autoaim, just draw in the middle of the // screen if ( m_vecCrossHairOffsetAngle != vec3_angle ) { QAngle angles; Vector forward; Vector point; // this code is wrong angles = m_curViewAngles + m_vecCrossHairOffsetAngle; AngleVectors( angles, &forward ); VectorAdd( m_curViewOrigin, forward, point ); ScreenTransform( point, screen ); } } x += 0.5f * screen[0] * ScreenWidth() + 0.5f; y += 0.5f * screen[1] * ScreenHeight() + 0.5f; m_pCrosshair->DrawSelf( x - 0.5f * m_pCrosshair->Width(), y - 0.5f * m_pCrosshair->Height(), m_clrCrosshair ); }