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; }
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 ); }