//------------------------------------------------------------------------------ // Purpose: //------------------------------------------------------------------------------ void CInput::CAM_CameraThirdThink( void ) { // Verify data. if ( !m_pCameraThirdData ) return; // Verify that we are in third person mode. if( !m_fCameraInThirdPerson ) return; // Obtain engine view angles and if they popped while the camera was static, fix the camera angles as well. QAngle angView; engine->GetViewAngles( angView ); // Move the CameraOffset "towards" the idealAngles, Note: CameraOffset = viewangle + idealAngle Vector vecCamOffset; VectorCopy( g_ThirdPersonManager.GetCameraOffsetAngles(), vecCamOffset ); // Move the camera. float flLag = MAX( 1, 1 + m_pCameraThirdData->m_flLag ); if( vecCamOffset[PITCH] - angView[PITCH] != m_pCameraThirdData->m_flPitch ) { vecCamOffset[PITCH] = MoveToward( vecCamOffset[PITCH], ( m_pCameraThirdData->m_flPitch + angView[PITCH] ), flLag ); } if( vecCamOffset[YAW] - angView[YAW] != m_pCameraThirdData->m_flYaw ) { vecCamOffset[YAW] = MoveToward( vecCamOffset[YAW], ( m_pCameraThirdData->m_flYaw + angView[YAW] ), flLag ); } if( abs( vecCamOffset[DIST] - m_pCameraThirdData->m_flDist ) < 2.0 ) { vecCamOffset[DIST] = m_pCameraThirdData->m_flDist; } else { vecCamOffset[DIST] += ( m_pCameraThirdData->m_flDist - vecCamOffset[DIST] ) / flLag; } C_BasePlayer* pLocalPlayer = C_BasePlayer::GetLocalPlayer(); if ( pLocalPlayer ) { QAngle desiredCamAngles = QAngle( vecCamOffset[ PITCH ], vecCamOffset[ YAW ], vecCamOffset[DIST] ); g_ThirdPersonManager.PositionCamera( C_BasePlayer::GetLocalPlayer(), desiredCamAngles ); // vecCamOffset = g_ThirdPersonManager.GetCameraOffsetAngles(); } ClampRange180( vecCamOffset[PITCH] ); ClampRange180( vecCamOffset[YAW] ); g_ThirdPersonManager.SetCameraOffsetAngles( vecCamOffset ); }
void CUnitScript::TickAnims(int deltaTime, AnimType type, std::list< std::list<AnimInfo*>::iterator >& doneAnims) { switch (type) { case AMove: { for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) { AnimInfo* ai = *it; // NOTE: we should not need to copy-and-set here, because // MoveToward/TurnToward/DoSpin modify pos/rot by reference float3 pos = pieces[ai->piece]->GetPosition(); if (MoveToward(pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime))) { ai->done = true; doneAnims.push_back(it); } pieces[ai->piece]->SetPosition(pos); unit->localModel->PieceUpdated(ai->piece); } } break; case ATurn: { for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) { AnimInfo* ai = *it; float3 rot = pieces[ai->piece]->GetRotation(); if (TurnToward(rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime))) { ai->done = true; doneAnims.push_back(it); } pieces[ai->piece]->SetRotation(rot); unit->localModel->PieceUpdated(ai->piece); } } break; case ASpin: { for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) { AnimInfo* ai = *it; float3 rot = pieces[ai->piece]->GetRotation(); if (DoSpin(rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime)) { ai->done = true; doneAnims.push_back(it); } pieces[ai->piece]->SetRotation(rot); unit->localModel->PieceUpdated(ai->piece); } } break; default: { } break; } }
// Head toward the specified vector, and return if bot is touching it bool CBotNav::HeadToward(const Vector &vec) { // move toward the specified vector bool ret = MoveToward(vec); // press the forward key m_pBot->bi.actionflags |= ACTION_MOVEFORWARD; // also face the position m_pBot->FacePosition(vec); // Return if bot touched that vector return ret; }
/** * @brief Called by the engine when we are registered as animating. If we return -1 it means that * there is no longer anything animating * @param deltaTime int delta time to update * @return 0 if there are still animations going, -1 else */ int CUnitScript::Tick(int deltaTime) { std::vector<struct AnimInfo *> remove; for (std::list<struct AnimInfo *>::iterator it = anims.begin(); it != anims.end(); ) { struct AnimInfo *ai = *it; bool done = false; switch (ai->type) { case AMove: { float3 pos = pieces[ai->piece]->GetPosition(); done = MoveToward(pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime)); pieces[ai->piece]->SetPosition(pos); } break; case ATurn: { float3 rot = pieces[ai->piece]->GetRotation(); done = TurnToward(rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime)); pieces[ai->piece]->SetRotation(rot); } break; case ASpin: { float3 rot = pieces[ai->piece]->GetRotation(); done = DoSpin(rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime); pieces[ai->piece]->SetRotation(rot); } break; } // Queue for removal (UnblockAll may add new anims) if (done) { remove.push_back(ai); } ++it; } //Tell listeners to unblock? for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) { UnblockAll(*it); //! NOTE: UnblockAll might result in new anims being added } for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) { anims.remove(*it); delete *it; } return anims.empty() ? -1 : 0; }
/** * @brief Called by the engine when we are registered as animating. If we return -1 it means that * there is no longer anything animating * @param deltaTime int delta time to update * @return 0 if there are still animations going, -1 else */ int CUnitScript::Tick(int deltaTime) { std::vector<struct AnimInfo *> remove; for (std::list<struct AnimInfo *>::iterator it = anims.begin(); it != anims.end(); ) { struct AnimInfo *ai = *it; bool done = false; switch (ai->type) { case AMove: done = MoveToward(pieces[ai->piece]->pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime)); break; case ATurn: done = TurnToward(pieces[ai->piece]->rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime)); break; case ASpin: done = DoSpin(pieces[ai->piece]->rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime); break; } // Queue for removal (UnblockAll may add new anims) if (done) { remove.push_back(ai); it = anims.erase(it); } else { ++it; } } //Tell listeners to unblock? for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) { UnblockAll(*it); delete *it; } if (anims.empty()) return -1; else return 0; }
//Called by the engine when we are registered as animating. If we return -1 it means that //there is no longer anything animating int CCobInstance::Tick(int deltaTime) { int done; list<struct AnimInfo *>::iterator it = anims.begin(); list<struct AnimInfo *>::iterator cur; while (it != anims.end()) { //Advance it, so we can erase cur safely cur = it++; done = false; pieces[(*cur)->piece].updated = true; switch ((*cur)->type) { case AMove: done = MoveToward(pieces[(*cur)->piece].coords[(*cur)->axis], (*cur)->dest, (*cur)->speed / (1000 / deltaTime)); break; case ATurn: done = TurnToward(pieces[(*cur)->piece].rot[(*cur)->axis], (*cur)->dest, (*cur)->speed / (1000 / deltaTime)); break; case ASpin: done = DoSpin(pieces[(*cur)->piece].rot[(*cur)->axis], (*cur)->dest, (*cur)->speed, (*cur)->accel, 1000 / deltaTime); break; } //Tell listeners to unblock? if (done) { UnblockAll(*cur); delete *cur; anims.erase(cur); } } if (anims.size() == 0) return -1; else return 0; }
void CTourist::MoveOn(float fElapsedTime) { if ((m_pTourInfo == NULL)||(m_nNowTour < 0)||(m_nNowTour >= m_nNumTour)) return; switch(m_pTourInfo[m_nNowTour].nType) { case 0x01: //直线向前运动 MoveToward(fElapsedTime); m_fTimeTest -= fElapsedTime; break; case 0x02: //原地转动 YawPitchPos(m_vAngleVel.y*fElapsedTime, m_vAngleVel.x*fElapsedTime); m_fTimeTest -= fElapsedTime; break; case 0x08: //面向圆心做圆周运动 YawPitchAt(m_vAngleVel.y*fElapsedTime, m_vAngleVel.x*fElapsedTime, &m_pTourInfo[m_nNowTour].vTarget); m_fTimeTest -= fElapsedTime; break; default: break; } if (m_fTimeTest < 1e-6) { m_nNowTour++; PrepairTour(); if (m_nNowTour == m_nNumTour) { m_nNowTour = 0; ::SendMessage(g_app->GetWindowHandle(), MSG_GAME_PRE, 0, 0); } if (m_nNowTour == 1) { char szFile[64]; g_app->m_Reader.GetMusicFile(aside_music, "new_game", szFile); ::SendMessage(g_app->GetWindowHandle(), MSG_SWITCH_MUSIC, 0, (LPARAM)szFile); } } }
/* ============================== CAM_Think ============================== */ void CInput::CAM_Think( void ) { VPROF("CAM_Think"); // if ( m_pCameraThirdData ) { return CAM_CameraThirdThink(); } Vector idealAngles; Vector camOffset; float flSensitivity; QAngle viewangles; switch( cam_command.GetInt() ) { case CAM_COMMAND_TOTHIRDPERSON: CAM_ToThirdPerson(); break; case CAM_COMMAND_TOFIRSTPERSON: CAM_ToFirstPerson(); break; case CAM_COMMAND_NONE: default: break; } //All this code after this comment has to do with thirdperson g_ThirdPersonManager.Update(); if( !m_fCameraInThirdPerson ) return; // In Maya-mode if ( Is_CAM_ThirdPerson_MayaMode() ) { // Unless explicitly moving the camera, don't move it m_fCameraInterceptingMouse = m_fCameraMovingWithMouse = vgui::input()->IsKeyDown( KEY_LALT ) || vgui::input()->IsKeyDown( KEY_RALT ); if ( !m_fCameraMovingWithMouse ) return; // Zero-out camera-control kbutton_t structures memset( &cam_pitchup, 0, sizeof( cam_pitchup ) ); memset( &cam_pitchdown, 0, sizeof( cam_pitchdown ) ); memset( &cam_yawleft, 0, sizeof( cam_yawleft ) ); memset( &cam_yawright, 0, sizeof( cam_yawright ) ); memset( &cam_in, 0, sizeof( cam_in ) ); memset( &cam_out, 0, sizeof( cam_out ) ); // Unless left or right mouse button is down, don't do anything #ifndef _XBOX if ( /* Left+Middle Button Down */ vgui::input()->IsMouseDown( MOUSE_LEFT ) && vgui::input()->IsMouseDown( MOUSE_MIDDLE ) ) { // Do only zoom in/out camera adjustment m_fCameraDistanceMove = true; } else if ( /* Left Button Down */ vgui::input()->IsMouseDown( MOUSE_LEFT ) ) { // Do only rotational camera movement m_fCameraDistanceMove = false; } else if ( /* Right Button Down */ vgui::input()->IsMouseDown( MOUSE_RIGHT ) ) { // Do only zoom in/out camera adjustment m_fCameraDistanceMove = true; } else { // Neither left or right buttons down, don't do anything ResetMouse(); return; } #endif } idealAngles[ PITCH ] = cam_idealpitch.GetFloat(); idealAngles[ YAW ] = cam_idealyaw.GetFloat(); idealAngles[ DIST ] = cam_idealdist.GetFloat(); // //movement of the camera with the mouse // if ( m_fCameraMovingWithMouse ) { int cpx, cpy; #ifndef _XBOX //get windows cursor position GetMousePos (cpx, cpy); #else //xboxfixme cpx = cpy = 0; #endif m_nCameraX = cpx; m_nCameraY = cpy; //check for X delta values and adjust accordingly //eventually adjust YAW based on amount of movement //don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera if (!m_fCameraDistanceMove) { int x, y; GetWindowCenter( x, y ); //keep the camera within certain limits around the player (ie avoid certain bad viewing angles) if (m_nCameraX>x) { //if ((idealAngles[YAW]>=225.0)||(idealAngles[YAW]<135.0)) if (idealAngles[YAW]<c_maxyaw.GetFloat()) { idealAngles[ YAW ] += (CAM_ANGLE_MOVE)*((m_nCameraX-x)/2); } if (idealAngles[YAW]>c_maxyaw.GetFloat()) { idealAngles[YAW]=c_maxyaw.GetFloat(); } } else if (m_nCameraX<x) { //if ((idealAngles[YAW]<=135.0)||(idealAngles[YAW]>225.0)) if (idealAngles[YAW]>c_minyaw.GetFloat()) { idealAngles[ YAW ] -= (CAM_ANGLE_MOVE)* ((x-m_nCameraX)/2); } if (idealAngles[YAW]<c_minyaw.GetFloat()) { idealAngles[YAW]=c_minyaw.GetFloat(); } } //check for y delta values and adjust accordingly //eventually adjust PITCH based on amount of movement //also make sure camera is within bounds if (m_nCameraY > y) { if(idealAngles[PITCH]<c_maxpitch.GetFloat()) { idealAngles[PITCH] +=(CAM_ANGLE_MOVE)* ((m_nCameraY-y)/2); } if (idealAngles[PITCH]>c_maxpitch.GetFloat()) { idealAngles[PITCH]=c_maxpitch.GetFloat(); } } else if (m_nCameraY<y) { if (idealAngles[PITCH]>c_minpitch.GetFloat()) { idealAngles[PITCH] -= (CAM_ANGLE_MOVE)*((y-m_nCameraY)/2); } if (idealAngles[PITCH]<c_minpitch.GetFloat()) { idealAngles[PITCH]=c_minpitch.GetFloat(); } } //set old mouse coordinates to current mouse coordinates //since we are done with the mouse if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 ) { m_nCameraOldX=m_nCameraX*flSensitivity; m_nCameraOldY=m_nCameraY*flSensitivity; } else { m_nCameraOldX=m_nCameraX; m_nCameraOldY=m_nCameraY; } #ifndef _XBOX ResetMouse(); #endif } } //Nathan code here if( input->KeyState( &cam_pitchup ) ) idealAngles[ PITCH ] += cam_idealdelta.GetFloat(); else if( input->KeyState( &cam_pitchdown ) ) idealAngles[ PITCH ] -= cam_idealdelta.GetFloat(); if( input->KeyState( &cam_yawleft ) ) idealAngles[ YAW ] -= cam_idealdelta.GetFloat(); else if( input->KeyState( &cam_yawright ) ) idealAngles[ YAW ] += cam_idealdelta.GetFloat(); if( input->KeyState( &cam_in ) ) { idealAngles[ DIST ] -= 2*cam_idealdelta.GetFloat(); if( idealAngles[ DIST ] < CAM_MIN_DIST ) { // If we go back into first person, reset the angle idealAngles[ PITCH ] = 0; idealAngles[ YAW ] = 0; idealAngles[ DIST ] = CAM_MIN_DIST; } } else if( input->KeyState( &cam_out ) ) idealAngles[ DIST ] += 2*cam_idealdelta.GetFloat(); if (m_fCameraDistanceMove) { int x, y; GetWindowCenter( x, y ); if (m_nCameraY>y) { if(idealAngles[ DIST ]<c_maxdistance.GetFloat()) { idealAngles[ DIST ] +=cam_idealdelta.GetFloat() * ((m_nCameraY-y)/2); } if (idealAngles[ DIST ]>c_maxdistance.GetFloat()) { idealAngles[ DIST ]=c_maxdistance.GetFloat(); } } else if (m_nCameraY<y) { if (idealAngles[ DIST ]>c_mindistance.GetFloat()) { idealAngles[ DIST ] -= (cam_idealdelta.GetFloat())*((y-m_nCameraY)/2); } if (idealAngles[ DIST ]<c_mindistance.GetFloat()) { idealAngles[ DIST ]=c_mindistance.GetFloat(); } } //set old mouse coordinates to current mouse coordinates //since we are done with the mouse m_nCameraOldX=m_nCameraX*gHUD.GetSensitivity(); m_nCameraOldY=m_nCameraY*gHUD.GetSensitivity(); #ifndef _XBOX ResetMouse(); #endif } // Obtain engine view angles and if they popped while the camera was static, // fix the camera angles as well engine->GetViewAngles( viewangles ); static QAngle s_oldAngles = viewangles; if ( Is_CAM_ThirdPerson_MayaMode() && ( s_oldAngles != viewangles ) ) { idealAngles[ PITCH ] += s_oldAngles[ PITCH ] - viewangles[ PITCH ]; idealAngles[ YAW ] += s_oldAngles[ YAW ] - viewangles[ YAW ]; s_oldAngles = viewangles; } // bring the pitch values back into a range that MoveToward can handle if ( idealAngles[ PITCH ] > 180 ) idealAngles[ PITCH ] -= 360; else if ( idealAngles[ PITCH ] < -180 ) idealAngles[ PITCH ] += 360; // bring the yaw values back into a range that MoveToward can handle // -- // Vitaliy: going with >= 180 and <= -180. // This introduces a potential discontinuity when looking directly at model face // as camera yaw will be jumping from +180 to -180 and back, but when working with // the camera allows smooth rotational transitions from left to right and back. // Otherwise one of the transitions that has ">"-comparison will be locked. // -- if ( idealAngles[ YAW ] >= 180 ) idealAngles[ YAW ] -= 360; else if ( idealAngles[ YAW ] <= -180 ) idealAngles[ YAW ] += 360; // clamp pitch, yaw and dist... idealAngles[ PITCH ] = clamp( idealAngles[ PITCH ], c_minpitch.GetFloat(), c_maxpitch.GetFloat() ); idealAngles[ YAW ] = clamp( idealAngles[ YAW ], c_minyaw.GetFloat(), c_maxyaw.GetFloat() ); idealAngles[ DIST ] = clamp( idealAngles[ DIST ], c_mindistance.GetFloat(), c_maxdistance.GetFloat() ); // update ideal angles cam_idealpitch.SetValue( idealAngles[ PITCH ] ); cam_idealyaw.SetValue( idealAngles[ YAW ] ); cam_idealdist.SetValue( idealAngles[ DIST ] ); // Move the CameraOffset "towards" the idealAngles // Note: CameraOffset = viewangle + idealAngle VectorCopy( g_ThirdPersonManager.GetCameraOffsetAngles(), camOffset ); if( cam_snapto.GetInt() ) { camOffset[ YAW ] = cam_idealyaw.GetFloat() + viewangles[ YAW ]; camOffset[ PITCH ] = cam_idealpitch.GetFloat() + viewangles[ PITCH ]; camOffset[ DIST ] = cam_idealdist.GetFloat(); } else { float lag = MAX( 1, 1 + cam_ideallag.GetFloat() ); if( camOffset[ YAW ] - viewangles[ YAW ] != cam_idealyaw.GetFloat() ) camOffset[ YAW ] = MoveToward( camOffset[ YAW ], cam_idealyaw.GetFloat() + viewangles[ YAW ], lag ); if( camOffset[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch.GetFloat() ) camOffset[ PITCH ] = MoveToward( camOffset[ PITCH ], cam_idealpitch.GetFloat() + viewangles[ PITCH ], lag ); if( abs( camOffset[ DIST ] - cam_idealdist.GetFloat() ) < 2.0 ) camOffset[ DIST ] = cam_idealdist.GetFloat(); else camOffset[ DIST ] += ( cam_idealdist.GetFloat() - camOffset[ DIST ] ) / lag; } // move the camera closer to the player if it hit something if ( cam_collision.GetInt() ) { QAngle desiredCamAngles = QAngle( camOffset[ PITCH ], camOffset[ YAW ], camOffset[ DIST ] ); if ( g_ThirdPersonManager.IsOverridingThirdPerson() == false ) { desiredCamAngles = viewangles; } g_ThirdPersonManager.PositionCamera( C_BasePlayer::GetLocalPlayer(), desiredCamAngles ); } if ( cam_showangles.GetInt() ) { engine->Con_NPrintf( 4, "Pitch: %6.1f Yaw: %6.1f %38s", viewangles[ PITCH ], viewangles[ YAW ], "view angles" ); engine->Con_NPrintf( 6, "Pitch: %6.1f Yaw: %6.1f Dist: %6.1f %19s", cam_idealpitch.GetFloat(), cam_idealyaw.GetFloat(), cam_idealdist.GetFloat(), "ideal angles" ); engine->Con_NPrintf( 8, "Pitch: %6.1f Yaw: %6.1f Dist: %6.1f %16s", g_ThirdPersonManager.GetCameraOffsetAngles()[ PITCH ], g_ThirdPersonManager.GetCameraOffsetAngles()[ YAW ], g_ThirdPersonManager.GetCameraOffsetAngles()[ DIST ], "camera offset" ); } //g_ThirdPersonManager.SetCameraOffsetAngles( camOffset ); g_ThirdPersonManager.SetCameraOffsetAngles(camOffset); }
void CL_DLLEXPORT CAM_Think( void ) { RecClCamThink(); #ifdef HL_CAMERA vec3_t origin; vec3_t ext, pnt, camForward, camRight, camUp; moveclip_t clip; float dist; vec3_t camAngles; float flSensitivity; #ifdef LATER int i; #endif vec3_t viewangles; switch( (int) cam_command->value ) { case CAM_COMMAND_TOTHIRDPERSON: CAM_ToThirdPerson(); break; case CAM_COMMAND_TOFIRSTPERSON: CAM_ToFirstPerson(); break; case CAM_COMMAND_NONE: default: break; } if( !cam_thirdperson ) return; #ifdef LATER if ( cam_contain->value ) { gEngfuncs.GetClientOrigin( origin ); ext[0] = ext[1] = ext[2] = 0.0; } #endif camAngles[ PITCH ] = cam_idealpitch->value; camAngles[ YAW ] = cam_idealyaw->value; dist = cam_idealdist->value; // //movement of the camera with the mouse // if (cam_mousemove) { //get windows cursor position GetCursorPos (&cam_mouse); //check for X delta values and adjust accordingly //eventually adjust YAW based on amount of movement //don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera if (!cam_distancemove) { //keep the camera within certain limits around the player (ie avoid certain bad viewing angles) if (cam_mouse.x>gEngfuncs.GetWindowCenterX()) { //if ((camAngles[YAW]>=225.0)||(camAngles[YAW]<135.0)) if (camAngles[YAW]<c_maxyaw->value) { camAngles[ YAW ] += (CAM_ANGLE_MOVE)*((cam_mouse.x-gEngfuncs.GetWindowCenterX())/2); } if (camAngles[YAW]>c_maxyaw->value) { camAngles[YAW]=c_maxyaw->value; } } else if (cam_mouse.x<gEngfuncs.GetWindowCenterX()) { //if ((camAngles[YAW]<=135.0)||(camAngles[YAW]>225.0)) if (camAngles[YAW]>c_minyaw->value) { camAngles[ YAW ] -= (CAM_ANGLE_MOVE)* ((gEngfuncs.GetWindowCenterX()-cam_mouse.x)/2); } if (camAngles[YAW]<c_minyaw->value) { camAngles[YAW]=c_minyaw->value; } } //check for y delta values and adjust accordingly //eventually adjust PITCH based on amount of movement //also make sure camera is within bounds if (cam_mouse.y>gEngfuncs.GetWindowCenterY()) { if(camAngles[PITCH]<c_maxpitch->value) { camAngles[PITCH] +=(CAM_ANGLE_MOVE)* ((cam_mouse.y-gEngfuncs.GetWindowCenterY())/2); } if (camAngles[PITCH]>c_maxpitch->value) { camAngles[PITCH]=c_maxpitch->value; } } else if (cam_mouse.y<gEngfuncs.GetWindowCenterY()) { if (camAngles[PITCH]>c_minpitch->value) { camAngles[PITCH] -= (CAM_ANGLE_MOVE)*((gEngfuncs.GetWindowCenterY()-cam_mouse.y)/2); } if (camAngles[PITCH]<c_minpitch->value) { camAngles[PITCH]=c_minpitch->value; } } //set old mouse coordinates to current mouse coordinates //since we are done with the mouse if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 ) { cam_old_mouse_x=cam_mouse.x*flSensitivity; cam_old_mouse_y=cam_mouse.y*flSensitivity; } else { cam_old_mouse_x=cam_mouse.x; cam_old_mouse_y=cam_mouse.y; } SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); } } //Nathan code here if( CL_KeyState( &cam_pitchup ) ) camAngles[ PITCH ] += CAM_ANGLE_DELTA; else if( CL_KeyState( &cam_pitchdown ) ) camAngles[ PITCH ] -= CAM_ANGLE_DELTA; if( CL_KeyState( &cam_yawleft ) ) camAngles[ YAW ] -= CAM_ANGLE_DELTA; else if( CL_KeyState( &cam_yawright ) ) camAngles[ YAW ] += CAM_ANGLE_DELTA; if( CL_KeyState( &cam_in ) ) { dist -= CAM_DIST_DELTA; if( dist < CAM_MIN_DIST ) { // If we go back into first person, reset the angle camAngles[ PITCH ] = 0; camAngles[ YAW ] = 0; dist = CAM_MIN_DIST; } } else if( CL_KeyState( &cam_out ) ) dist += CAM_DIST_DELTA; if (cam_distancemove) { if (cam_mouse.y>gEngfuncs.GetWindowCenterY()) { if(dist<c_maxdistance->value) { dist +=CAM_DIST_DELTA * ((cam_mouse.y-gEngfuncs.GetWindowCenterY())/2); } if (dist>c_maxdistance->value) { dist=c_maxdistance->value; } } else if (cam_mouse.y<gEngfuncs.GetWindowCenterY()) { if (dist>c_mindistance->value) { dist -= (CAM_DIST_DELTA)*((gEngfuncs.GetWindowCenterY()-cam_mouse.y)/2); } if (dist<c_mindistance->value) { dist=c_mindistance->value; } } //set old mouse coordinates to current mouse coordinates //since we are done with the mouse cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); } #ifdef LATER if( cam_contain->value ) { // check new ideal VectorCopy( origin, pnt ); AngleVectors( camAngles, camForward, camRight, camUp ); for (i=0 ; i<3 ; i++) pnt[i] += -dist*camForward[i]; // check line from r_refdef.vieworg to pnt memset ( &clip, 0, sizeof ( moveclip_t ) ); clip.trace = SV_ClipMoveToEntity( sv.edicts, r_refdef.vieworg, ext, ext, pnt ); if( clip.trace.fraction == 1.0 ) { // update ideal cam_idealpitch->value = camAngles[ PITCH ]; cam_idealyaw->value = camAngles[ YAW ]; cam_idealdist->value = dist; } } else #endif { // update ideal cam_idealpitch->value = camAngles[ PITCH ]; cam_idealyaw->value = camAngles[ YAW ]; cam_idealdist->value = dist; } // Move towards ideal VectorCopy( cam_ofs, camAngles ); gEngfuncs.GetViewAngles( (float *)viewangles ); if( cam_snapto->value ) { camAngles[ YAW ] = cam_idealyaw->value + viewangles[ YAW ]; camAngles[ PITCH ] = cam_idealpitch->value + viewangles[ PITCH ]; camAngles[ 2 ] = cam_idealdist->value; } else { if( camAngles[ YAW ] - viewangles[ YAW ] != cam_idealyaw->value ) camAngles[ YAW ] = MoveToward( camAngles[ YAW ], cam_idealyaw->value + viewangles[ YAW ], CAM_ANGLE_SPEED ); if( camAngles[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch->value ) camAngles[ PITCH ] = MoveToward( camAngles[ PITCH ], cam_idealpitch->value + viewangles[ PITCH ], CAM_ANGLE_SPEED ); if( abs( camAngles[ 2 ] - cam_idealdist->value ) < 2.0 ) camAngles[ 2 ] = cam_idealdist->value; else camAngles[ 2 ] += ( cam_idealdist->value - camAngles[ 2 ] ) / 4.0; } #ifdef LATER if( cam_contain->value ) { // Test new position dist = camAngles[ ROLL ]; camAngles[ ROLL ] = 0; VectorCopy( origin, pnt ); AngleVectors( camAngles, camForward, camRight, camUp ); for (i=0 ; i<3 ; i++) pnt[i] += -dist*camForward[i]; // check line from r_refdef.vieworg to pnt memset ( &clip, 0, sizeof ( moveclip_t ) ); ext[0] = ext[1] = ext[2] = 0.0; clip.trace = SV_ClipMoveToEntity( sv.edicts, r_refdef.vieworg, ext, ext, pnt ); if( clip.trace.fraction != 1.0 ) return; } #endif cam_ofs[ 0 ] = camAngles[ 0 ]; cam_ofs[ 1 ] = camAngles[ 1 ]; cam_ofs[ 2 ] = dist; // HL_CAMERA #endif }
void CHostage::DoFollow(void) { if (m_hTargetEnt == NULL) return; CBaseEntity *pFollowing; Vector vecDest; float flRadius; int nindexPath; pFollowing = GetClassPtr((CBaseEntity *)m_hTargetEnt->pev); m_LocalNav->SetTargetEnt(pFollowing); vecDest = pFollowing->pev->origin; vecDest.z += pFollowing->pev->mins.z; flRadius = (vecDest - pev->origin).Length(); if (flRadius < 80) { if (m_fHasPath) return; if (m_LocalNav->PathTraversable(pev->origin, vecDest, TRUE) != TRAVERSABLE_NO) return; } if (FBitSet(pev->flags, FL_ONGROUND)) { if (gpGlobals->time > m_flLastPathCheck + m_flPathCheckInterval) { if (!m_fHasPath || pFollowing->pev->velocity.Length2D() > 1) { m_flLastPathCheck = gpGlobals->time; m_LocalNav->RequestNav(this); } } } if (m_fHasPath) { nTargetNode = nindexPath = m_LocalNav->GetFurthestTraversableNode(pev->origin, vecNodes, m_nPathNodes, TRUE); if (!nindexPath) { if ((vecNodes[nTargetNode] - pev->origin).Length2D() < HOSTAGE_STEPSIZE) nTargetNode = -1; } if (nTargetNode == -1) { m_fHasPath = FALSE; m_flPathCheckInterval = 0.1; } } if (gpGlobals->time < m_flFlinchTime) return; if (nTargetNode != -1) { if (FBitSet(pev->flags, FL_ONGROUND)) PointAt(vecNodes[nTargetNode]); if (IsOnLadder()) pev->v_angle.x = -60; MoveToward(vecNodes[nTargetNode]); m_bStuck = FALSE; } if (pev->takedamage == DAMAGE_YES) { if (m_improv) { } if (m_hTargetEnt != NULL && m_State == FOLLOW) { if (!m_bStuck) { if (flRadius > 200) { m_bStuck = TRUE; m_flStuckTime = gpGlobals->time; } } } } if (FBitSet(pev->flags, FL_ONGROUND)) { if (m_flPathAcquired != -1 && m_flPathAcquired + 2 > gpGlobals->time) { if (pev->velocity.Length2D() < 1 || nTargetNode == -1) Wiggle(); } } }
void CSDKInput::CAM_Think( void ) { VPROF("CAM_Think"); Vector idealAngles; Vector camOffset; QAngle viewangles; if( !CAM_IsThirdPerson() ) return; ConVarRef cam_idealpitch( "cam_idealpitch" ); ConVarRef cam_idealyaw( "cam_idealyaw" ); ConVarRef cam_idealdist( "cam_idealdist" ); idealAngles[ PITCH ] = cam_idealpitch.GetFloat(); idealAngles[ YAW ] = cam_idealyaw.GetFloat(); idealAngles[ DIST ] = cam_idealdist.GetFloat(); // Obtain engine view angles and if they popped while the camera was static, // fix the camera angles as well engine->GetViewAngles( viewangles ); // bring the pitch values back into a range that MoveToward can handle if ( idealAngles[ PITCH ] > 180 ) idealAngles[ PITCH ] -= 360; else if ( idealAngles[ PITCH ] < -180 ) idealAngles[ PITCH ] += 360; // bring the yaw values back into a range that MoveToward can handle // -- // Vitaliy: going with >= 180 and <= -180. // This introduces a potential discontinuity when looking directly at model face // as camera yaw will be jumping from +180 to -180 and back, but when working with // the camera allows smooth rotational transitions from left to right and back. // Otherwise one of the transitions that has ">"-comparison will be locked. // -- if ( idealAngles[ YAW ] >= 180 ) idealAngles[ YAW ] -= 360; else if ( idealAngles[ YAW ] <= -180 ) idealAngles[ YAW ] += 360; ConVarRef c_minpitch( "c_minpitch" ); ConVarRef c_maxpitch( "c_maxpitch" ); ConVarRef c_minyaw( "c_minyaw" ); ConVarRef c_maxyaw( "c_maxyaw" ); ConVarRef c_mindistance( "c_mindistance" ); ConVarRef c_maxdistance( "c_maxdistance" ); // clamp pitch, yaw and dist... idealAngles[ PITCH ] = clamp( idealAngles[ PITCH ], c_minpitch.GetFloat(), c_maxpitch.GetFloat() ); idealAngles[ YAW ] = clamp( idealAngles[ YAW ], c_minyaw.GetFloat(), c_maxyaw.GetFloat() ); idealAngles[ DIST ] = clamp( idealAngles[ DIST ], c_mindistance.GetFloat(), c_maxdistance.GetFloat() ); // update ideal angles cam_idealpitch.SetValue( idealAngles[ PITCH ] ); cam_idealyaw.SetValue( idealAngles[ YAW ] ); cam_idealdist.SetValue( idealAngles[ DIST ] ); // Move the CameraOffset "towards" the idealAngles // Note: CameraOffset = viewangle + idealAngle CAM_GetCameraOffset( camOffset ); ConVarRef cam_snapto( "cam_snapto" ); if( cam_snapto.GetInt() ) { camOffset[ YAW ] = cam_idealyaw.GetFloat() + viewangles[ YAW ]; camOffset[ PITCH ] = cam_idealpitch.GetFloat() + viewangles[ PITCH ]; camOffset[ DIST ] = cam_idealdist.GetFloat(); } else { ConVarRef cam_ideallag( "cam_ideallag" ); float lag = max( 1, 1 + cam_ideallag.GetFloat() ); if( camOffset[ YAW ] - viewangles[ YAW ] != cam_idealyaw.GetFloat() ) camOffset[ YAW ] = MoveToward( camOffset[ YAW ], cam_idealyaw.GetFloat() + viewangles[ YAW ], lag ); if( camOffset[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch.GetFloat() ) camOffset[ PITCH ] = MoveToward( camOffset[ PITCH ], cam_idealpitch.GetFloat() + viewangles[ PITCH ], lag ); if( abs( camOffset[ DIST ] - cam_idealdist.GetFloat() ) < 2.0 ) camOffset[ DIST ] = cam_idealdist.GetFloat(); else camOffset[ DIST ] += ( cam_idealdist.GetFloat() - camOffset[ DIST ] ) / lag; } // move the camera closer to the player if it hit something trace_t trace; C_BasePlayer* localPlayer = C_BasePlayer::GetLocalPlayer(); if ( localPlayer ) { Vector camForward; // find our player's origin, and from there, the eye position Vector origin = localPlayer->GetLocalOrigin(); origin += localPlayer->GetViewOffset(); // get the forward vector AngleVectors( QAngle(camOffset[ PITCH ], camOffset[ YAW ], 0), &camForward, NULL, NULL ); // use our previously #defined hull to collision trace CTraceFilterSimple traceFilter( localPlayer, COLLISION_GROUP_NONE ); UTIL_TraceHull( origin, origin - (camForward * camOffset[ DIST ]), Vector(-CAM_HULL_OFFSET, -CAM_HULL_OFFSET, -CAM_HULL_OFFSET), Vector(CAM_HULL_OFFSET, CAM_HULL_OFFSET, CAM_HULL_OFFSET), MASK_SOLID, &traceFilter, &trace ); // move the camera closer if it hit something if( trace.fraction < 1.0 ) { camOffset[ DIST ] *= trace.fraction; } // For now, I'd rather see the insade of a player model than punch the camera through a wall // might try the fade out trick at some point //if( camOffset[ DIST ] < CAM_MIN_DIST ) // camOffset[ DIST ] = CAM_MIN_DIST; // clamp up to minimum } ConVarRef cam_showangles( "cam_showangles" ); if ( cam_showangles.GetInt() ) { engine->Con_NPrintf( 4, "Pitch: %6.1f Yaw: %6.1f %38s", viewangles[ PITCH ], viewangles[ YAW ], "view angles" ); engine->Con_NPrintf( 6, "Pitch: %6.1f Yaw: %6.1f Dist: %6.1f %19s", cam_idealpitch.GetFloat(), cam_idealyaw.GetFloat(), cam_idealdist.GetFloat(), "ideal angles" ); engine->Con_NPrintf( 8, "Pitch: %6.1f Yaw: %6.1f Dist: %6.1f %16s", camOffset[ PITCH ], camOffset[ YAW ], camOffset[ DIST ], "camera offset" ); } QAngle angOffset; angOffset.x = camOffset.x; angOffset.y = camOffset.y; angOffset.z = camOffset.z; CAM_SetCameraThirdData(NULL, angOffset); }