void CC_DispatchParticle( const CCommand& args ) { C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pLocalPlayer ) return; if ( args.ArgC() < 2 ) { DevMsg( "Use: dispatch_particle {particle_name} {surface_offset_distance}\n" ); return; } float flSurfaceOffsetDistance = 0.f; if ( args.ArgC() == 3 ) { flSurfaceOffsetDistance = atof( args[2] ); } Vector vForward; pLocalPlayer->GetVectors( &vForward, NULL, NULL ); trace_t tr; UTIL_TraceLine( pLocalPlayer->EyePosition(), pLocalPlayer->EyePosition() + vForward * 3000, MASK_SOLID_BRUSHONLY, NULL, &tr ); Vector vTargetDeathPos = tr.endpos; DispatchParticleEffect( args[1], vTargetDeathPos + flSurfaceOffsetDistance * tr.plane.normal, vec3_angle ); }
void CC_PickerShader ( const CCommand &args ) { C_BasePlayer *pPlayer = (C_BasePlayer *) C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return; trace_t tr; Vector vecAbsStart, vecAbsEnd, vecDir; AngleVectors( pPlayer->EyeAngles(), &vecDir ); vecAbsStart = pPlayer->EyePosition(); vecAbsEnd = vecAbsStart + (vecDir * MAX_TRACE_LENGTH); UTIL_TraceLine( vecAbsStart, vecAbsEnd, MASK_ALL, pPlayer, COLLISION_GROUP_NONE, &tr ); if ( tr.DidHitWorld() ) { IMaterial *pMaterial = materials->FindMaterial( tr.surface.name, TEXTURE_GROUP_PRECACHED ); if ( !IsErrorMaterial( pMaterial ) ) { const char* shadername = pMaterial->GetShaderName(); Msg("Material shader name: %s\n", shadername); } else { Msg("Could not get material shader name.\n"); } } else { Msg("This command only supports world geometry.\n"); } }
bool C_EnvProjectedTexture::IsWithinFarZ(float flLightFOV) { //No need to check camera space lights for visibility, as they should always be close enough to the player. if (m_bCameraSpace) return true; //Trace forward to the nearest opaque brush face Vector vForward; GetVectors(&vForward, NULL, NULL); Vector vTraceStart = GetAbsOrigin(); Vector vTraceEnd = GetAbsOrigin() + vForward; trace_t tr; CTraceFilterWorldOnly filter; UTIL_TraceLine(vTraceStart, vTraceEnd, CONTENTS_SOLID && CONTENTS_OPAQUE, &filter, &tr); //Test to see if the player is close enough to the light to actually see the light's projection. This is based entirely on it's FarZ. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if (pPlayer) { Vector vDistance; VectorSubtract(tr.endpos, pPlayer->EyePosition(), vDistance); float fDistance = vDistance.LengthSqr(); //If distance is greater than the light's FarZ, cease to render. //FarZ determines how far away a light can be seen by the player, AND how far the light travels from it's source in stock Valve code. if (fDistance > Square(m_flFarZ + flLightFOV * 10)) return false; } return true; }
bool CClientTools::GetLocalPlayerEyePosition( Vector& org, QAngle& ang, float &fov ) { C_BasePlayer *pl = C_BasePlayer::GetLocalPlayer(); if ( pl == NULL ) return false; org = pl->EyePosition(); ang = pl->EyeAngles(); fov = pl->GetFOV(); return true; }
bool CClientTools::GetLocalPlayerEyePosition( Vector& org, QAngle& ang, float &fov ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 ); C_BasePlayer *pl = C_BasePlayer::GetLocalPlayer(); if ( pl == NULL ) return false; org = pl->EyePosition(); ang = pl->EyeAngles(); fov = pl->GetFOV(); return true; }
bool CWeaponDODBase::ShouldAutoEjectBrass( void ) { // Don't eject brass if further than N units from the local player C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pLocalPlayer ) return true; float flMaxDistSqr = 250; flMaxDistSqr *= flMaxDistSqr; float flDistSqr = pLocalPlayer->EyePosition().DistToSqr( GetAbsOrigin() ); return ( flDistSqr < flMaxDistSqr ); }
void C_WeaponSpawner::ClientThink() { m_qAngle.y += 90 * gpGlobals->frametime; if ( m_qAngle.y >= 360 ) m_qAngle.y -= 360; SetAbsAngles( m_qAngle ); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); bool bShouldGlow = false; bool bTouchingPlayer = false; if ( pPlayer ) { Vector vecPlayerOrigin = pPlayer->GetAbsOrigin(); Vector vecPlayerMins = vecPlayerOrigin + pPlayer->GetPlayerMins(); Vector vecPlayerMaxs = vecPlayerOrigin + pPlayer->GetPlayerMaxs(); bTouchingPlayer = IsBoxIntersectingBox( GetAbsOrigin() + WorldAlignMins(), GetAbsOrigin() + WorldAlignMaxs(), vecPlayerMins, vecPlayerMaxs ); // Disable the outline if the weapon has been picked up. if ( !m_bRespawning && !m_bDisabled ) { // Temp crutch for Occluded\Unoccluded glow parameters not working. trace_t tr; UTIL_TraceLine( GetAbsOrigin(), pPlayer->EyePosition(), MASK_OPAQUE, this, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction == 1.0f ) { bShouldGlow = true; } } } if ( m_bShouldGlow != bShouldGlow || m_bTouchingPlayer != bTouchingPlayer ) { m_bShouldGlow = bShouldGlow; m_bTouchingPlayer = bTouchingPlayer; UpdateGlowEffect(); } SetNextClientThink( CLIENT_THINK_ALWAYS ); }
//----------------------------------------------------------------------------- // Purpose: Deal with input //----------------------------------------------------------------------------- void C_VGuiScreen::ClientThink( void ) { BaseClass::ClientThink(); // FIXME: We should really be taking bob, shake, and roll into account // but if we did, then all the inputs would be generated multiple times // if the world was rendered multiple times (for things like water, etc.) vgui::Panel *pPanel = m_PanelWrapper.GetPanel(); if (!pPanel) return; C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); if (!pLocalPlayer) return; // Generate a ray along the view direction Vector vecEyePosition = pLocalPlayer->EyePosition(); QAngle viewAngles = pLocalPlayer->EyeAngles( ); Vector viewDir, endPos; AngleVectors( viewAngles, &viewDir ); VectorMA( vecEyePosition, 1000.0f, viewDir, endPos ); // Compute cursor position... Ray_t lookDir; lookDir.Init( vecEyePosition, endPos ); float u, v; if (!IntersectWithRay( lookDir, &u, &v, NULL )) return; if ( ((u < 0) || (v < 0) || (u > 1) || (v > 1)) && !m_bLooseThinkNextFrame) return; // This will cause our panel to grab all input! g_pClientMode->ActivateInGameVGuiContext( pPanel ); // Convert (u,v) into (px,py) int px = (int)(u * m_nPixelWidth + 0.5f); int py = (int)(v * m_nPixelHeight + 0.5f); // Generate mouse input commands if ((px != m_nOldPx) || (py != m_nOldPy)) { g_InputInternal->InternalCursorMoved( px, py ); m_nOldPx = px; m_nOldPy = py; } if (m_nButtonPressed & IN_ATTACK) { g_InputInternal->InternalMousePressed(vgui::MOUSE_LEFT); } if (m_nButtonPressed & IN_ATTACK2) { g_InputInternal->InternalMousePressed(vgui::MOUSE_RIGHT); } if ( (m_nButtonReleased & IN_ATTACK) || m_bLooseThinkNextFrame) // for a button release on loosing focus { g_InputInternal->InternalMouseReleased(vgui::MOUSE_LEFT); } if (m_nButtonReleased & IN_ATTACK2) { g_InputInternal->InternalMouseReleased(vgui::MOUSE_RIGHT); } if ( m_bLooseThinkNextFrame == true ) { m_bLooseThinkNextFrame = false; SetNextClientThink( CLIENT_THINK_NEVER ); } g_pClientMode->DeactivateInGameVGuiContext( ); }
void CSDKMapOverview::UpdatePlayers() { C_SDK_PlayerResource *pSDKPR = (C_SDK_PlayerResource*)GameResources(); if ( !pSDKPR ) return; CBasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer(); if( localPlayer == NULL ) return; MapPlayer_t *localMapPlayer = GetPlayerByUserID(localPlayer->GetUserID()); if( localMapPlayer == NULL ) return; for ( int i = 1; i<= gpGlobals->maxClients; i++) { MapPlayer_t *player = &m_Players[i-1]; SDKMapPlayer_t *playerSDK = GetSDKInfoForPlayerIndex(i-1); if ( !playerSDK ) continue; // update from global player resources if ( pSDKPR->IsConnected(i) ) { player->health = pSDKPR->GetHealth( i ); if ( !pSDKPR->IsAlive( i ) ) { // Safety actually happens after a TKPunish. player->health = 0; playerSDK->isDead = true; } if ( player->team != pSDKPR->GetTeam( i ) ) { player->team = pSDKPR->GetTeam( i ); if( player == localMapPlayer ) player->icon = m_TeamIconsSelf[ GetIconNumberFromTeamNumber(player->team) ]; else player->icon = m_TeamIcons[ GetIconNumberFromTeamNumber(player->team) ]; player->color = m_TeamColors[ GetIconNumberFromTeamNumber(player->team) ]; } } Vector position = player->position; QAngle angles = player->angle; C_BasePlayer *pPlayer = UTIL_PlayerByIndex( i ); if ( pPlayer && !pPlayer->IsDormant() ) { // update position of active players in our PVS position = pPlayer->EyePosition(); angles = pPlayer->EyeAngles(); SetPlayerPositions( i-1, position, angles ); } } }
//----------------------------------------------------------------------------- // Purpose: Render current view into specified rectangle // Input : *rect - //----------------------------------------------------------------------------- void CViewRender::Render( vrect_t *rect ) { /*static*/ std::vector<smCoord3f> view_head_pos; /*static*/ std::vector<smRotEuler> view_head_rot; static float learnt_x = 0.0; static float learnt_y = 0.0; static float learnt_z = fa_default_depth; static float learnt_xRot = fa_default_pitch; static float learnt_yRot = 0.0; static float learnt_zRot = 0.0; int i = 0; fa_fov_min = ( fov_desired.GetInt() + fov_fapi_window_adj_amount.GetInt() ); Assert(s_DbgSetupOrigin == m_View.origin); Assert(s_DbgSetupAngles == m_View.angles); VPROF_BUDGET( "CViewRender::Render", "CViewRender::Render" ); vrect_t vr = *rect; // Stub out the material system if necessary. CMatStubHandler matStub; bool drawViewModel; engine->EngineStats_BeginFrame(); // Assume normal vis m_bForceNoVis = false; C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); // IMPORTANT: Please acknowledge the author Torben Sko ([email protected], torbensko.com/software/head_tracking), // if you: // 1.1 Use or replicate any of the code pertaining to the utilisation of the head tracking data. // 1.2 Use any of the custom assets, including the modified crossbow and the human // character model. float aspectRatio = engine->GetScreenAspectRatio() * 0.75f; // / (4/3) if(pPlayer && pPlayer->IsAlive() && face_api.m_bFaceAPIHasCamera) { int head_pos_size = 0; if(!fa_paused) { // Warning: this code does not take parellel operations into account if(head_confidence > 0.0f) { view_head_pos.push_back(latest_head_pos); view_head_rot.push_back(latest_head_rot); } // Restore to a neutral position on loss of the head by // scaling down the last recieved head position static float lost_time = 0.0f; if(fa_lost) { if(head_confidence == 0.0f && view_head_pos.size() > 0) { if(lost_time == 0.0f) { lost_time = engine->Time(); } else if(engine->Time() > lost_time + fa_lost_pause) { smCoord3f previous_offset = view_head_pos.back(); previous_offset.x *= fa_lost_scale; previous_offset.y *= fa_lost_scale; previous_offset.z = ((previous_offset.z - learnt_z) * fa_lost_scale) + learnt_z; smRotEuler previous_rotation = view_head_rot.back(); previous_rotation.x_rads = ((previous_rotation.x_rads - learnt_xRot) * fa_lost_scale) + learnt_xRot; previous_rotation.y_rads *= fa_lost_scale; previous_rotation.z_rads *= fa_lost_scale; view_head_pos.push_back(previous_offset); view_head_rot.push_back(previous_rotation); } } else { if(lost_time > 0.0f) { /*char log[40]; sprintf(log, "lost the head for %f seconds", engine->Time() - lost_time); record(log);*/ lost_time = 0.0f; } } } // Use a while statement in case the user has decreased the // smoothing rate since last time head_pos_size = view_head_pos.size(); while( head_pos_size > fa_smoothing ) { view_head_pos.erase(view_head_pos.begin()); view_head_rot.erase(view_head_rot.begin()); } } x = 0.0f; y = 0.0f; z = 0.0f; float xRot = 0.0f; float yRot = 0.0f; float zRot = 0.0f; // Compute the smoothed head movements head_pos_size = view_head_pos.size(); if(head_pos_size > 0) { for(i = 0; i < head_pos_size; i++) { x += view_head_pos[i].x; y += view_head_pos[i].y; z += view_head_pos[i].z; xRot += view_head_rot[i].x_rads; yRot += view_head_rot[i].y_rads; zRot += view_head_rot[i].z_rads; } x /= view_head_pos.size(); y /= view_head_pos.size(); z /= view_head_pos.size(); xRot /= view_head_pos.size(); yRot /= view_head_pos.size(); zRot /= view_head_pos.size(); } // Corrects the arching that occurs when moving towards the camera if(fa_arcCorrection) y += (z - fa_default_depth) * fa_arcCorrection_scale; // Show the head data //if(fa_show_preHeadData) DevMsg(" pre: pos\tx:%f\ty:%f\tz:%f\n rot\tx:%f\ty:%f\tz:%f\n", x, y, z, xRot, yRot, zRot); // IMPORTANT: Please acknowledge the author Torben Sko ([email protected], torbensko.com/software/head_tracking), // if you: // 1.1 Use or replicate any of the code pertaining to the utilisation of the head tracking data. // 1.2 Use any of the custom assets, including the modified crossbow and the human // character model. // Learns the player's neutral position static bool reset_learning = false; if(!fa_learning) { if(reset_learning) { learnt_x = 0.0f; learnt_y = 0.0f; learnt_z = fa_default_depth; learnt_xRot = fa_default_pitch; learnt_yRot = 0.0f; learnt_zRot = 0.0f; reset_learning = true; } } else if(fa_learning && head_confidence > 0.0f && !fa_paused) { float diff, change; diff = learnt_x - x; (diff != 0.0f) ? change = (0.0000001 * fa_learning_influence) / diff : change = 0.0f; (fabs(change) < fabs(diff)) ? learnt_x -= change : learnt_x = x; x -= learnt_x; diff = learnt_y - y; (diff != 0.0f) ? change = (0.0000001 * fa_learning_influence) / diff : change = 0.0f; (fabs(change) < fabs(diff)) ? learnt_y -= change : learnt_y = y; y -= learnt_y; diff = learnt_z - z; (diff != 0.0f) ? change = (0.0000001 * fa_learning_influence) / diff : change = 0.0f; (fabs(change) < fabs(diff)) ? learnt_z -= change : learnt_z = z; z = fa_default_depth + (z - learnt_z); diff = learnt_xRot - xRot; (diff != 0.0f) ? change = (0.0000001 * fa_learning_influence) / diff : change = 0.0f; (fabs(change) < fabs(diff)) ? learnt_xRot -= change : learnt_xRot = xRot; xRot = fa_default_pitch + (xRot - learnt_xRot); diff = learnt_yRot - yRot; (diff != 0.0f) ? change = (0.0000001 * fa_learning_influence) / diff : change = 0.0f; (fabs(change) < fabs(diff)) ? learnt_yRot -= change : learnt_yRot = yRot; yRot -= learnt_yRot; diff = learnt_zRot - zRot; (diff != 0.0f) ? change = (0.0000001 * fa_learning_influence) / diff : change = 0.0f; (fabs(change) < fabs(diff)) ? learnt_zRot -= change : learnt_zRot = zRot; zRot -= learnt_zRot; reset_learning = true; } // IMPORTANT: Please acknowledge the author Torben Sko ([email protected], torbensko.com/software/head_tracking), // if you: // 1.1 Use or replicate any of the code pertaining to the utilisation of the head tracking data. // 1.2 Use any of the custom assets, including the modified crossbow and the human // character model. // Resets the tracker on low confidence static float reset_time = 0.0f; static float waiting_for_reset = 0.0f; if(fa_confidenceMinimum) { if(waiting_for_reset > 0.0f) { if(head_confidence > 0.0f) { /*char log[40]; sprintf(log, "Reset FaceAPI engine and regained head after %f seconds", engine->Time() - waiting_for_reset); record(log);*/ waiting_for_reset = 0.0f; } } else if(head_confidence < fa_confidenceMinimum_threshold && learnt_x <= fabs(fa_confidenceMinimum_widthRange) && learnt_zRot <= fabs(fa_confidenceMinimum_yollRange)) { if(reset_time == 0.0f) { reset_time = engine->Time() + fa_confidenceMinimum_timeout; } else if(engine->Time() > reset_time) { //char logMsg[256]; reset_time = 0.0f; face_api.reset(); waiting_for_reset = engine->Time(); // The learnt values were probably wrong, so reset them learnt_x = 0.0f; learnt_y = 0.0f; learnt_z = fa_default_depth; learnt_xRot = fa_default_pitch; learnt_yRot = 0.0f; learnt_zRot = 0.0f; /*sprintf(logMsg, "confidence droped below %.2f%% for %.2f seconds, whilst (learnt) head.width <= |%.2f| and (learnt) head.roll <= |%.2f|", fa_confidenceMinimum_threshold, fa_confidenceMinimum_timeout, fa_confidenceMinimum_widthRange, fa_confidenceMinimum_yollRange); record(logMsg);*/ } } else { reset_time = 0.0f; } } // IMPORTANT: Please acknowledge the author Torben Sko ([email protected], torbensko.com/software/head_tracking), // if you: // 1.1 Use or replicate any of the code pertaining to the utilisation of the head tracking data. // 1.2 Use any of the custom assets, including the modified crossbow and the human // character model. if(faceapi_mode.GetInt() > 1 && !engine->IsPaused()) { // alters the fov based user's head position float forward = fa_fov_depthScale * (z + fa_fov_depthOffset); float head_fov = fa_fov_min + (1 - fa_fov_influence) * default_fov.GetFloat() + fa_fov_influence * (2 * radToDeg(atan((fa_fov_screenWidth / 2) / (forward)))); m_View.fov = ScaleFOVByWidthRatio( head_fov, aspectRatio ); m_View.fovViewmodel = m_View.fov * fa_fov_modelViewScale; // rotate the camera based on the user's head offsets m_View.angles[YAW] += fa_camRotByHeadOff_globalScale * fa_camRotByHeadOff_yawScale * radToDeg(atan(x / z)); m_View.angles[PITCH] += fa_camRotByHeadOff_globalScale * fa_camRotByHeadOff_pitchScale * radToDeg(atan(y / z)); // offset the camera based on the user's head offsets float depth, height, width; depth = fa_camOffByHeadOff_depthScale * fa_camOffByHeadOff_globalScale * (z - fa_default_depth); m_View.origin.x -= depth * cos(degToRad(m_View.angles[YAW])); m_View.origin.y -= depth * sin(degToRad(m_View.angles[YAW])); width = fa_camOffByHeadOff_widthScale * fa_camOffByHeadOff_globalScale * x; m_View.origin.y -= width * cos(degToRad(m_View.angles[YAW])); m_View.origin.x += width * sin(degToRad(m_View.angles[YAW])); height = fa_camOffByHeadOff_heightScale * fa_camOffByHeadOff_globalScale * y; m_View.origin.z += height; // Alters the vanishing point based on the user's head offset offHor = -fa_vanish_depth * (x / z); offVert = -fa_vanish_depth * (y / z); m_View.m_bOffCenter = true; m_View.m_flOffCenterTop = 1.0f - offVert; m_View.m_flOffCenterBottom = 0.0f - offVert; m_View.m_flOffCenterLeft = 0.0f - offHor; m_View.m_flOffCenterRight = 1.0f - offHor; } else { m_View.fov = ScaleFOVByWidthRatio( m_View.fov, aspectRatio ); m_View.fovViewmodel = ScaleFOVByWidthRatio( m_View.fovViewmodel, aspectRatio ); m_View.m_bOffCenter = false; offHor = 0.0f; offVert = 0.0f; } // Show the head data //if(fa_show_postHeadData) DevMsg(" post: pos\tx:%f\ty:%f\tz:%f\n rot\tx:%f\ty:%f\tz:%f\n", x, y, z, xRot, yRot, zRot); // Show the learnt head data //if(fa_show_learntHeadData) DevMsg("learnt: pos\tx:%f\ty:%f\tz:%f\n rot\tx:%f\ty:%f\tz:%f\n", learnt_x, learnt_y, learnt_z, learnt_xRot, learnt_yRot, learnt_zRot); // IMPORTANT: Please acknowledge the author Torben Sko ([email protected], torbensko.com/software/head_tracking), // if you: // 1.1 Use or replicate any of the code pertaining to the utilisation of the head tracking data. // 1.2 Use any of the custom assets, including the modified crossbow and the human // character model. if((faceapi_mode.GetInt() == 1 || faceapi_mode.GetInt() == 3) && !engine->IsPaused()) { //float offPeer = 0.0f; float rollPeer = 0.0f; //float yawPeer = 0.0f; /*if(fa_peering_off) if(x > fa_peering_offStart) offPeer = (x - fa_peering_offStart) / (fa_peering_offEnd - fa_peering_offStart); else if(x < -fa_peering_offStart) offPeer = (x + fa_peering_offStart) / (fa_peering_offEnd - fa_peering_offStart);*/ if(fa_peering_roll) if(zRot > fa_peering_rollStart) rollPeer = -(zRot - fa_peering_rollStart) / (fa_peering_rollEnd - fa_peering_rollStart); else if(zRot < -fa_peering_rollStart) rollPeer = -(zRot + fa_peering_rollStart) / (fa_peering_rollEnd - fa_peering_rollStart); /*if(fa_peering_yaw) if(yRot > fa_peering_yawStart) yawPeer = -(yRot - fa_peering_yawStart) / (fa_peering_yawEnd - fa_peering_yawStart); else if(yRot < -fa_peering_yawStart) yawPeer = -(yRot + fa_peering_yawStart) / (fa_peering_yawEnd - fa_peering_yawStart);*/ float peer = /*offPeer + */rollPeer /*+ yawPeer*/; if(peer > 1.0f) peer = 1.0f; if(peer < -1.0f) peer = -1.0f; if(peer != 0.0f) { peer = pow(fabs(peer), fa_peering_ease) * (fabs(peer) / peer); QAngle angles = pPlayer->GetViewModel()->GetAbsAngles(); angles[PITCH] += fabs(peer) * fa_peering_gunTilt; pPlayer->GetViewModel()->SetAbsAngles(angles); m_View.angles[ROLL] += peer * fa_peering_headTilt; Vector eyes, eye_offset; eyes = pPlayer->EyePosition(); float hor_move = peer * fa_peering_size; eye_offset.y = -hor_move * cos(degToRad(m_View.angles[YAW])); eye_offset.x = hor_move * sin(degToRad(m_View.angles[YAW])); eye_offset.z = 0.0f; // Don't allow peering through walls trace_t tr; UTIL_TraceHull(eyes, eyes + eye_offset, PEER_HULL_MIN, PEER_HULL_MAX, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr); eye_offset.z = -fabs(peer) * fa_peering_headLower; m_View.origin += eye_offset * tr.fraction; static float peer_right = 0.0f; if(peer_right == 0.0f && peer == 1.0f) { peer_right = engine->Time(); } else if(peer_right != 0.0f && peer != 1.0f) { /*char log[40]; sprintf(log, "peered right for %f seconds", engine->Time() - peer_right); record(log);*/ peer_right = 0.0f; } static float peer_left = 0.0f; if(peer_left == 0.0f && peer == -1.0f) { peer_left = engine->Time(); } else if(peer_left != 0.0f && peer != -1.0f) { /*char log[40]; sprintf(log, "peered left for %f seconds", engine->Time() - peer_left); record(log);*/ peer_left = 0.0f; } } } // IMPORTANT: Please acknowledge the author Torben Sko ([email protected], torbensko.com/software/head_tracking), // if you: // 1.1 Use or replicate any of the code pertaining to the utilisation of the head tracking data. // 1.2 Use any of the custom assets, including the modified crossbow and the human // character model. rotate_x = 0.0f; rotate_y = 0.0f; if(fa_plyRotByHeadRot) { if(fabs(yRot) > fa_plyRotByHeadRot_yawMin) { float n_yRot = (fabs(yRot) - fa_plyRotByHeadRot_yawMin) / (fa_plyRotByHeadRot_yawMax - fa_plyRotByHeadRot_yawMin); if(n_yRot > 1.0f) n_yRot = 1.0f; if(n_yRot > 0.0f) n_yRot = pow(n_yRot, fa_plyRotByHeadRot_ease); rotate_x = n_yRot * fa_plyRotByHeadRot_yawSpeed * (yRot / fabs(yRot)); } float off_xRot = xRot - learnt_xRot; if(fabs(off_xRot) > fa_plyRotByHeadRot_pitchMin) { float n_xRot = (fabs(off_xRot) - fa_plyRotByHeadRot_pitchMin) / (fa_plyRotByHeadRot_pitchMax - fa_plyRotByHeadRot_pitchMin); if(n_xRot > 1.0f) n_xRot = 1.0f; if(n_xRot > 0.0f) n_xRot = pow(n_xRot, fa_plyRotByHeadRot_ease); rotate_y = n_xRot * fa_plyRotByHeadRot_pitchSpeed * (off_xRot / fabs(off_xRot)); } } } else { m_View.fov = ScaleFOVByWidthRatio( m_View.fov, aspectRatio ); m_View.fovViewmodel = ScaleFOVByWidthRatio( m_View.fovViewmodel, aspectRatio ); } //m_View.fov = ScaleFOVByWidthRatio( m_View.fov, aspectRatio ); //m_View.fovViewmodel = ScaleFOVByWidthRatio( m_View.fovViewmodel, aspectRatio ); // Let the client mode hook stuff. g_pClientMode->PreRender(&m_View); g_pClientMode->AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height ); ToolFramework_AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height ); float flViewportScale = mat_viewportscale.GetFloat(); float engineAspectRatio = engine->GetScreenAspectRatio(); m_View.x = vr.x; m_View.y = vr.y; m_View.width = vr.width * flViewportScale; m_View.height = vr.height * flViewportScale; m_View.m_flAspectRatio = ( engineAspectRatio > 0.0f ) ? engineAspectRatio : ( (float)m_View.width / (float)m_View.height ); int nClearFlags = VIEW_CLEAR_DEPTH | VIEW_CLEAR_STENCIL; if( gl_clear_randomcolor.GetBool() ) { CMatRenderContextPtr pRenderContext( materials ); pRenderContext->ClearColor3ub( rand()%256, rand()%256, rand()%256 ); pRenderContext->ClearBuffers( true, false, false ); pRenderContext->Release(); } else if ( gl_clear.GetBool() ) { nClearFlags |= VIEW_CLEAR_COLOR; } // Determine if we should draw view model ( client mode override ) drawViewModel = g_pClientMode->ShouldDrawViewModel(); if ( cl_leveloverview.GetFloat() > 0 ) { SetUpOverView(); nClearFlags |= VIEW_CLEAR_COLOR; drawViewModel = false; } // Apply any player specific overrides //C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer ) { // Override view model if necessary if ( !pPlayer->m_Local.m_bDrawViewmodel ) { drawViewModel = false; } } if(fa_weapon) drawViewModel = false; render->SetMainView( m_View.origin, m_View.angles ); int flags = RENDERVIEW_DRAWHUD; if ( drawViewModel ) { flags |= RENDERVIEW_DRAWVIEWMODEL; } RenderView( m_View, nClearFlags, flags ); g_pClientMode->PostRender(); engine->EngineStats_EndFrame(); #if !defined( _X360 ) // Stop stubbing the material system so we can see the budget panel matStub.End(); #endif CViewSetup view2d; // Draw all of the UI stuff "fullscreen" view2d.x = rect->x; view2d.y = rect->y; view2d.width = rect->width; view2d.height = rect->height; render->Push2DView( view2d, 0, NULL, GetFrustum() ); render->VGui_Paint( PAINT_UIPANELS ); render->PopView( GetFrustum() ); }
//----------------------------------------------------------------------------- // Purpose: Deal with input //----------------------------------------------------------------------------- void C_VGuiScreen::ClientThink( void ) { int nButtonsChanged = m_nOldButtonState ^ m_nButtonState; m_nOldButtonState = m_nButtonState; // Debounced button codes for pressed/released // UNDONE: Do we need auto-repeat? m_nButtonPressed = nButtonsChanged & m_nButtonState; // The changed ones still down are "pressed" m_nButtonReleased = nButtonsChanged & (~m_nButtonState); // The ones not down are "released" BaseClass::ClientThink(); // FIXME: We should really be taking bob, shake, and roll into account // but if we did, then all the inputs would be generated multiple times // if the world was rendered multiple times (for things like water, etc.) vgui::Panel *pPanel = m_PanelWrapper.GetPanel(); if (!pPanel) return; C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); if (!pLocalPlayer) return; // Generate a ray along the view direction Vector vecEyePosition = pLocalPlayer->EyePosition(); QAngle viewAngles = pLocalPlayer->EyeAngles( ); // Compute cursor position... Ray_t lookDir; Vector endPos; float u, v; // Viewmodel attached screens that take input need to have a moving cursor // Do a pick under the cursor as our selection Vector viewDir; AngleVectors( viewAngles, &viewDir ); VectorMA( vecEyePosition, 1000.0f, viewDir, endPos ); lookDir.Init( vecEyePosition, endPos ); if (!IntersectWithRay( lookDir, &u, &v, NULL )) return; if ( ((u < 0) || (v < 0) || (u > 1) || (v > 1)) && !m_bLoseThinkNextFrame) return; // This will cause our panel to grab all input! g_pClientMode->ActivateInGameVGuiContext( pPanel ); // Convert (u,v) into (px,py) int px = (int)(u * m_nPixelWidth + 0.5f); int py = (int)(v * m_nPixelHeight + 0.5f); // Generate mouse input commands if ((px != m_nOldPx) || (py != m_nOldPy)) { g_InputInternal->InternalCursorMoved( px, py ); m_nOldPx = px; m_nOldPy = py; } if (m_nButtonPressed & IN_ATTACK) { g_InputInternal->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_PRESSED ); g_InputInternal->InternalMousePressed(MOUSE_LEFT); } if (m_nButtonPressed & IN_ATTACK2) { g_InputInternal->SetMouseCodeState( MOUSE_RIGHT, vgui::BUTTON_PRESSED ); g_InputInternal->InternalMousePressed( MOUSE_RIGHT ); } if ( (m_nButtonReleased & IN_ATTACK) || m_bLoseThinkNextFrame) // for a button release on loosing focus { g_InputInternal->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_RELEASED ); g_InputInternal->InternalMouseReleased( MOUSE_LEFT ); } if (m_nButtonReleased & IN_ATTACK2) { g_InputInternal->SetMouseCodeState( MOUSE_RIGHT, vgui::BUTTON_RELEASED ); g_InputInternal->InternalMouseReleased( MOUSE_RIGHT ); } if ( m_bLoseThinkNextFrame == true ) { m_bLoseThinkNextFrame = false; SetNextClientThink( CLIENT_THINK_NEVER ); } g_pClientMode->DeactivateInGameVGuiContext( ); }
void CMumbleSystem::PostRender() { #ifndef NO_STEAM if ( !g_pMumbleMemory || !sv_mumble_positionalaudio.GetBool() ) return; if ( g_pMumbleMemory->uiVersion != 2 ) { V_wcscpy_safe( g_pMumbleMemory->name, L"Source engine: " ); wchar_t wcsGameDir[MAX_PATH]; Q_UTF8ToUnicode( COM_GetModDirectory(), wcsGameDir, sizeof(wcsGameDir) ); V_wcscat_safe( g_pMumbleMemory->name, wcsGameDir ); V_wcscpy_safe( g_pMumbleMemory->description, L"Links Source engine games to Mumble." ); g_pMumbleMemory->uiVersion = 2; } g_pMumbleMemory->uiTick++; Vector vecOriginPlayer, vecOriginCamera = MainViewOrigin(); QAngle anglesPlayer, anglesCamera = MainViewAngles(); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer ) { vecOriginPlayer = pPlayer->EyePosition(); anglesPlayer = pPlayer->GetAbsAngles(); } else { vecOriginPlayer = vecOriginCamera; anglesPlayer = anglesCamera; } anglesPlayer.x = 0; Vector vecPlayerForward, vecPlayerUp, vecCameraForward, vecCameraUp; AngleVectors( anglesPlayer, &vecPlayerForward, NULL, &vecPlayerUp ); AngleVectors( anglesCamera, &vecCameraForward, NULL, &vecCameraUp ); // 1 Source unit is about one inch // 1 mumble unit = 1 meter vecOriginPlayer *= METERS_PER_INCH; vecOriginCamera *= METERS_PER_INCH; VectorToMumbleFloatArray( vecPlayerForward, g_pMumbleMemory->fAvatarFront ); VectorToMumbleFloatArray( vecPlayerUp, g_pMumbleMemory->fAvatarTop ); VectorToMumbleFloatArray( vecOriginPlayer, g_pMumbleMemory->fAvatarPosition ); VectorToMumbleFloatArray( vecCameraForward, g_pMumbleMemory->fCameraFront ); VectorToMumbleFloatArray( vecCameraUp, g_pMumbleMemory->fCameraTop ); VectorToMumbleFloatArray( vecOriginCamera, g_pMumbleMemory->fCameraPosition ); if ( pPlayer && m_bHasSetPlayerUniqueId && m_nTeamSetInUniqueId != pPlayer->GetTeamNumber() ) { // Player changed team since we set the unique ID. Set it again. m_bHasSetPlayerUniqueId = false; } if ( !m_bHasSetPlayerUniqueId && steamapicontext && steamapicontext->SteamUser() ) { CSteamID steamid = steamapicontext->SteamUser()->GetSteamID(); if ( steamid.IsValid() ) { int unTeam = pPlayer ? pPlayer->GetTeamNumber() : 0; char szSteamId[256]; V_sprintf_safe( szSteamId, "universe:%u;account_type:%u;id:%u;instance:%u;team:%d", steamid.GetEUniverse(), steamid.GetEAccountType(), steamid.GetAccountID(), steamid.GetUnAccountInstance(), unTeam ); wchar_t wcsSteamId[256]; Q_UTF8ToUnicode( szSteamId, wcsSteamId, sizeof(wcsSteamId) ); // Identifier which uniquely identifies a certain player in a context. V_wcscpy_safe( g_pMumbleMemory->identity, wcsSteamId ); m_bHasSetPlayerUniqueId = true; m_nTeamSetInUniqueId = unTeam; } } // Context should be equal for players which should be able to hear each other positional and // differ for those who shouldn't (e.g. it could contain the server+port and team) memcpy( g_pMumbleMemory->context, &m_szSteamIDCurrentServer, m_cubSteamIDCurrentServer ); g_pMumbleMemory->context_len = m_cubSteamIDCurrentServer; #endif // NO_STEAM }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int iPoint, bool bInitializing ) { ParticleControlPoint_t *pPoint = &pEffect->pControlPoints[iPoint]; if ( pEffect->pParticleEffect->m_pDef->IsScreenSpaceEffect() && iPoint == 0 ) { pEffect->pParticleEffect->SetControlPointOrientation( pPoint->iControlPoint, Vector(1,0,0), Vector(0,1,0), Vector(0,0,1) ); pEffect->pParticleEffect->SetControlPoint( pPoint->iControlPoint, vec3_origin ); return; } if ( !pPoint->hEntity.Get() ) { if ( pPoint->iAttachType == PATTACH_WORLDORIGIN && bInitializing ) { pEffect->pParticleEffect->SetControlPointOrientation( pPoint->iControlPoint, Vector(1,0,0), Vector(0,1,0), Vector(0,0,1) ); pEffect->pParticleEffect->SetControlPoint( pPoint->iControlPoint, pPoint->vecOriginOffset ); pEffect->pParticleEffect->SetSortOrigin( pPoint->vecOriginOffset ); } pEffect->pParticleEffect->SetControlPointEntity( pPoint->iControlPoint, NULL ); return; } // Only update non-follow particles when we're initializing, if ( !bInitializing && (pPoint->iAttachType == PATTACH_ABSORIGIN || pPoint->iAttachType == PATTACH_POINT ) ) return; if ( pPoint->iAttachType == PATTACH_CUSTOMORIGIN ) return; Vector vecOrigin, vecForward, vecRight, vecUp; switch ( pPoint->iAttachType ) { case PATTACH_POINT: case PATTACH_POINT_FOLLOW: { C_BaseAnimating *pAnimating = pPoint->hEntity->GetBaseAnimating(); bool bValid = false; Assert( pAnimating ); if ( pAnimating ) { matrix3x4_t attachmentToWorld; if ( pAnimating->IsViewModel() ) { C_BasePlayer *pPlayer = ToBasePlayer( ((C_BaseViewModel *)pAnimating)->GetOwner() ); ACTIVE_SPLITSCREEN_PLAYER_GUARD( C_BasePlayer::GetSplitScreenSlotForPlayer( pPlayer ) ); if ( pAnimating->GetAttachment( pPoint->iAttachmentPoint, attachmentToWorld ) ) { bValid = true; MatrixVectors( attachmentToWorld, &vecForward, &vecRight, &vecUp ); MatrixPosition( attachmentToWorld, vecOrigin ); if ( pEffect->pParticleEffect->m_pDef->IsViewModelEffect() ) { FormatViewModelAttachment( pPlayer, vecOrigin, true ); } } } else { // HACK_GETLOCALPLAYER_GUARD( "CParticleProperty::UpdateControlPoint" ); if ( pAnimating->GetAttachment( pPoint->iAttachmentPoint, attachmentToWorld ) ) { bValid = true; MatrixVectors( attachmentToWorld, &vecForward, &vecRight, &vecUp ); #ifdef _DEBUG float flTests[3] = {vecForward.Dot( vecRight ), vecRight.Dot( vecUp ), vecUp.Dot( vecForward )}; static float s_flMaxTest = 0.001f; Assert( fabs( flTests[0] ) + fabs( flTests[1] ) + fabs( flTests[2] ) < s_flMaxTest ); #endif MatrixPosition( attachmentToWorld, vecOrigin ); if ( pEffect->pParticleEffect->m_pDef->IsViewModelEffect() ) { HACK_GETLOCALPLAYER_GUARD( "CParticleProperty::UpdateControlPoint" ); FormatViewModelAttachment( NULL, vecOrigin, true ); } } } } if ( !bValid ) { static bool bWarned = false; if ( !bWarned ) { bWarned = true; DevWarning( "Attempted to attach particle effect %s to an unknown attachment on entity %s\n", pEffect->pParticleEffect->m_pDef->GetName(), pAnimating->GetClassname() ); } } if ( !bValid ) { AssertOnce( 0 ); return; } } break; case PATTACH_ABSORIGIN: case PATTACH_ABSORIGIN_FOLLOW: default: { vecOrigin = pPoint->hEntity->GetAbsOrigin() + pPoint->vecOriginOffset; pPoint->hEntity->GetVectors( &vecForward, &vecRight, &vecUp ); } break; case PATTACH_EYES_FOLLOW: { C_BaseEntity *pEnt = pPoint->hEntity; if ( !pEnt->IsPlayer() ) return; C_BasePlayer *pPlayer = assert_cast< C_BasePlayer* >( pEnt ); bool bValid = false; Assert( pPlayer ); if ( pPlayer ) { bValid = true; vecOrigin = pPlayer->EyePosition() + pPoint->vecOriginOffset; pPlayer->EyeVectors( &vecForward, &vecRight, &vecUp ); } if ( !bValid ) { AssertOnce( 0 ); return; } } break; case PATTACH_CUSTOMORIGIN_FOLLOW: { matrix3x4_t mat; MatrixMultiply( pPoint->hEntity->RenderableToWorldTransform(), pPoint->matOffset, mat ); MatrixVectors( mat, &vecForward, &vecRight, &vecUp ); vecOrigin = pPoint->hEntity->GetAbsOrigin() + pPoint->vecOriginOffset; } break; } pEffect->pParticleEffect->SetControlPointOrientation( pPoint->iControlPoint, vecForward, vecRight, vecUp ); pEffect->pParticleEffect->SetControlPointEntity( pPoint->iControlPoint, pPoint->hEntity ); pEffect->pParticleEffect->SetControlPoint( pPoint->iControlPoint, vecOrigin ); pEffect->pParticleEffect->SetSortOrigin( vecOrigin ); }