void V_GetDeathCam(cl_entity_t * ent1, cl_entity_t * ent2, float * angle, float * origin) { float newAngle[3]; float newOrigin[3]; static vec3_t nonDestructedOrigin; float distance = 168.0f; v_lastDistance += v_frametime * 96.0f; // move unit per seconds back if ( v_resetCamera ) v_lastDistance = 64.0f; if ( distance > v_lastDistance ) distance = v_lastDistance; if (ent1->origin.x == 0 && ent1->origin.y == 0 && ent1->origin.z == 0) nonDestructedOrigin.CopyToArray(newOrigin); else { nonDestructedOrigin = ent1->origin; VectorCopy(ent1->origin, newOrigin); } if ( ent1->player ) newOrigin[2]+= 17; // head level of living player // get new angle towards second target if ( ent2 ) { VectorSubtract(ent2->origin, nonDestructedOrigin, newAngle); VectorAngles( newAngle, newAngle ); newAngle[0] = -newAngle[0]; } else { // if no second target is given, look down to dead player newAngle[0] = 90.0f; newAngle[1] = 0.0f; newAngle[2] = 0; } // and smooth view V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 120.0f ); V_GetChaseOrigin( angle, newOrigin, distance, origin ); VectorCopy(angle, v_lastAngles); }
void V_GetSingleTargetCam(cl_entity_t * ent1, float * angle, float * origin) { float newAngle[3]; float newOrigin[3]; int flags = gHUD.m_Spectator.m_iObserverFlags; // see is target is a dead player qboolean deadPlayer = ent1->player && (ent1->curstate.solid == SOLID_NOT); float dfactor = ( flags & DRC_FLAG_DRAMATIC )? -1.0f : 1.0f; float distance = 112.0f + ( 16.0f * dfactor ); // get close if dramatic; // go away in final scenes or if player just died if ( flags & DRC_FLAG_FINAL ) distance*=2.0f; else if ( deadPlayer ) distance*=1.5f; // let v_lastDistance float smoothly away v_lastDistance+= v_frametime * 32.0f; // move unit per seconds back if ( distance > v_lastDistance ) distance = v_lastDistance; VectorCopy(ent1->origin, newOrigin); if ( ent1->player ) { if ( deadPlayer ) newOrigin[2]+= 2; //laying on ground else newOrigin[2]+= 17; // head level of living player } else newOrigin[2]+= 8; // object, tricky, must be above bomb in CS // we have no second target, choose view direction based on // show front of primary target VectorCopy(ent1->angles, newAngle); // show dead players from front, normal players back if ( flags & DRC_FLAG_FACEPLAYER ) newAngle[1]+= 180.0f; newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic // if final scene (bomb), show from real high pos if ( flags & DRC_FLAG_FINAL ) newAngle[0] = 22.5f; // choose side of object/player if ( flags & DRC_FLAG_SIDE ) newAngle[1]+=22.5f; else newAngle[1]-=22.5f; V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 120.0f ); // HACK, if player is dead don't clip against his dead body, can't check this V_GetChaseOrigin( angle, newOrigin, distance, origin ); }
void V_GetDoubleTargetsCam(cl_entity_t * ent1, cl_entity_t * ent2,float * angle, float * origin) { float newAngle[3]; float newOrigin[3]; float tempVec[3]; int flags = gHUD.m_Spectator.m_iObserverFlags; float dfactor = ( flags & DRC_FLAG_DRAMATIC )? -1.0f : 1.0f; float distance = 112.0f + ( 16.0f * dfactor ); // get close if dramatic; // go away in final scenes or if player just died if ( flags & DRC_FLAG_FINAL ) distance*=2.0f; // let v_lastDistance float smoothly away v_lastDistance+= v_frametime * 32.0f; // move unit per seconds back if ( distance > v_lastDistance ) distance = v_lastDistance; VectorCopy(ent1->origin, newOrigin); if ( ent1->player ) newOrigin[2]+= 17; // head level of living player else newOrigin[2]+= 8; // object, tricky, must be above bomb in CS // get new angle towards second target VectorSubtract( ent2->origin, ent1->origin, newAngle ); VectorAngles( newAngle, newAngle ); newAngle[0] = -newAngle[0]; // set angle diffrent in Dramtaic scenes newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic if ( flags & DRC_FLAG_SIDE ) newAngle[1]+=22.5f; else newAngle[1]-=22.5f; float d = MaxAngleBetweenAngles( v_lastAngles, newAngle ); if ( ( d < v_cameraFocusAngle) && ( v_cameraMode == CAM_MODE_RELAX ) ) { // difference is to small and we are in relax camera mode, keep viewangles VectorCopy(v_lastAngles, newAngle ); } else if ( (d < v_cameraRelaxAngle) && (v_cameraMode == CAM_MODE_FOCUS) ) { // we catched up with our target, relax again v_cameraMode = CAM_MODE_RELAX; } else { // target move too far away, focus camera again v_cameraMode = CAM_MODE_FOCUS; } // and smooth view, if not a scene cut if ( v_resetCamera || (v_cameraMode == CAM_MODE_RELAX) ) { VectorCopy( newAngle, angle ); } else { V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 180.0f ); } V_GetChaseOrigin( newAngle, newOrigin, distance, origin ); // move position up, if very close at target if ( v_lastDistance < 64.0f ) origin[2]+= 16.0f*( 1.0f - (v_lastDistance / 64.0f ) ); // calculate angle to second target VectorSubtract( ent2->origin, origin, tempVec ); VectorAngles( tempVec, tempVec ); tempVec[0] = -tempVec[0]; /* take middle between two viewangles InterpolateAngles( newAngle, tempVec, newAngle, 0.5f); */ }
void V_GetDirectedChasePosition(cl_entity_t * ent1, cl_entity_t * ent2,float * angle, float * origin) { float newAngle[3]; float newOrigin[3]; float tempVec[3]; int flags = gHUD.m_Spectator.m_iObserverFlags; qboolean deadPlayer = ent1->player && (ent1->curstate.solid == SOLID_NOT); float dfactor = ( flags & DRC_FLAG_DRAMATIC )? -1.0f : 1.0f; if ( ent1->player && (ent1->curstate.solid == SOLID_NOT) ) dfactor = 1.5f; // zoom away if player dies float distance = 112.0f + ( 16.0f * dfactor ); // get close if dramatic; // go away in final scenes if (flags & DRC_FLAG_FINAL ) distance*=2.0f; // let v_lastDistance float smoothly away v_lastDistance+= v_frametime * 24.0f; // move unit per seconds back if ( distance > v_lastDistance ) distance = v_lastDistance; VectorCopy(ent1->origin, newOrigin); if ( ent1->player ) { if ( deadPlayer ) newOrigin[2]+= 2; //laying on ground else newOrigin[2]+= 28; // head level of living player } else newOrigin[2]+= 8; // object, tricky, must be above bomb in CS if ( ( ent2 == (cl_entity_t*)0xFFFFFFFF ) || deadPlayer ) // we have no second target or player just died { // we have no second target, choose view direction based on // show front of primary target VectorCopy(ent1->angles, newAngle); newAngle[1]+= 180.0f; newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic // if final scene (bomb), show from real high pos if ( flags & DRC_FLAG_FINAL ) newAngle[0] = 22.5f; // choose side of object/player if ( flags & DRC_FLAG_SIDE ) newAngle[1]+=22.5f; else newAngle[1]-=22.5f; // if ( AngleBetweenVectors( tempVec, newAngle ) > 1.0f ) V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 120.0f ); // HACK, if player is dead don't clip against his dead body, can't check this V_GetChaseOrigin( angle, newOrigin, distance, deadPlayer, origin ); } else if ( ent2 ) { // get new angle towards second target VectorSubtract( ent2->origin, ent1->origin, newAngle ); VectorAngles( newAngle, newAngle ); newAngle[0] = -newAngle[0]; // set angle diffrent in Dramtaic scenes newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic if ( flags & DRC_FLAG_SIDE ) newAngle[1]+=22.5f; else newAngle[1]-=22.5f; V_GetChaseOrigin( newAngle, newOrigin, distance, false, origin ); origin[2]+= 16.0f*( 1.0f - (v_lastDistance / distance) ); // calculate angle to second target VectorSubtract( ent2->origin, origin, tempVec ); VectorAngles( tempVec, tempVec ); tempVec[0] = -tempVec[0]; // take middle between two viewangles InterpolateAngles( newAngle, tempVec, angle, 0.5f); } else { // second target disappeard somehow (dead) // keep last good viewangle V_GetChaseOrigin( angle, newOrigin, distance, false, origin ); } VectorCopy(angle, v_lastAngles); }