467 lines
13 KiB
Scheme
Executable File
467 lines
13 KiB
Scheme
Executable File
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
//
|
|
// MISSION NAME : RC_Camera_Public.sch
|
|
// AUTHOR : Aaron Gandaa
|
|
// DESCRIPTION : Camera Helper Functions
|
|
//
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
|
|
//----------------------
|
|
// INCLUDES
|
|
//----------------------
|
|
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
USING "rgeneral_include.sch"
|
|
USING "RC_Helper_Functions.sch"
|
|
|
|
//----------------------
|
|
// CONSTANTS
|
|
//----------------------
|
|
CONST_FLOAT FPSCAM_LIMITYAW 80.0
|
|
CONST_FLOAT FPSCAM_LIMITPITCH 30.0
|
|
CONST_FLOAT FPSCAM_LOOKSPEED 60.0
|
|
CONST_FLOAT FPSCAM_MINZOOM 20.0
|
|
CONST_FLOAT FPSCAM_MAXZOOM 50.0
|
|
CONST_FLOAT CAMERA_NOSWITCHRATIO -99.0
|
|
|
|
//----------------------
|
|
// STRUCT
|
|
//----------------------
|
|
STRUCT BASIC_CAMERA
|
|
BOOL bFPSMode = FALSE
|
|
BOOL bSetup = FALSE
|
|
|
|
VECTOR vPosition
|
|
VECTOR vLookAt
|
|
|
|
ENTITY_INDEX sourceID
|
|
ENTITY_INDEX targetID // if this is set - look at is ignored
|
|
CAMERA_INDEX cameraID
|
|
|
|
FLOAT fLookPitch = 0.0
|
|
FLOAT fLookYaw = 0.0
|
|
FLOAT fFov = 0.0
|
|
|
|
BOOL bWrapLookPitch = FALSE
|
|
BOOL bWrapLookYaw = FALSE
|
|
ENDSTRUCT
|
|
|
|
STRUCT CAMERA_STRUCT
|
|
BOOL bSetup = FALSE
|
|
VECTOR vPosition[2]
|
|
VECTOR vRotation[2]
|
|
FLOAT fFov[2]
|
|
FLOAT fHeightOffset // Bump the camera up this amount for large vehicles
|
|
INT iActivationTime // the time the camera turned on
|
|
INT iInterpolateTime // time to move from point a to b (in ms)
|
|
ENTITY_INDEX targetID // if this is set - rotation is ignored
|
|
|
|
FLOAT fSwitchRatio = CAMERA_NOSWITCHRATIO
|
|
ENDSTRUCT
|
|
|
|
//----------------------
|
|
// CAMERA FUNCTIONS
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// Shutdown and Destroy A Camera
|
|
/// PARAMS:
|
|
/// cameraID - camera index
|
|
/// bInterp - set this to interpolate back to game camera
|
|
PROC SHUTDOWN_CAMERA(CAMERA_INDEX &cameraID, BOOL bInterp = FALSE)
|
|
IF DOES_CAM_EXIST(cameraID)
|
|
RENDER_SCRIPT_CAMS(FALSE, bInterp)
|
|
SET_CAM_ACTIVE(cameraID, FALSE)
|
|
DESTROY_CAM(cameraID)
|
|
cameraID = NULL
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
//----------------------
|
|
// STRUCT FUNCTIONS
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// Resets the camera struct to zero
|
|
/// PARAMS:
|
|
/// cr - camera struct reference
|
|
PROC ZERO_CAMERA_STRUCT(CAMERA_STRUCT &cr)
|
|
cr.bSetup = FALSE
|
|
cr.vPosition[0] = <<0, 0, 0>>
|
|
cr.vPosition[1] = <<0, 0, 0>>
|
|
cr.vRotation[0] = <<0, 0, 0>>
|
|
cr.vRotation[1] = <<0, 0, 0>>
|
|
cr.fFov[0] = 50.0
|
|
cr.fFov[1] = 0.0
|
|
cr.targetID = NULL
|
|
cr.iInterpolateTime = 0
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets up a single non moving camera struct
|
|
/// PARAMS:
|
|
/// cr - camera reference
|
|
/// pos - position of camera
|
|
/// rot - rotation of camera
|
|
PROC SETUP_CAMERA_STRUCT(CAMERA_STRUCT &cr, VECTOR pos, VECTOR rot, ENTITY_INDEX tgtent = NULL, FLOAT fHeightOffset = 0.0)
|
|
ZERO_CAMERA_STRUCT(cr)
|
|
cr.vPosition[0] = pos
|
|
cr.vRotation[0] = rot
|
|
cr.bSetup = TRUE
|
|
cr.targetID = tgtent // if this is set - rotation is ignored
|
|
cr.fHeightOffset = fHeightOffset
|
|
cr.iInterpolateTime = 0
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets up a single non moving camera struct
|
|
/// PARAMS:
|
|
/// cr - camera reference
|
|
/// pos - position of camera
|
|
/// rot - rotation of camera
|
|
PROC SETUP_CAMERA_STRUCT_END_SHOT(CAMERA_STRUCT &cr, VECTOR pos, VECTOR rot, INT iTime)
|
|
cr.vPosition[1] = pos
|
|
cr.vRotation[1] = rot
|
|
cr.bSetup = TRUE
|
|
cr.iInterpolateTime = iTime
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets up a tracking camera struct
|
|
/// PARAMS:
|
|
/// cr - camera reference
|
|
/// pos - position of start camera
|
|
/// rot - rotation of start camera
|
|
/// pos2 - position of end camera
|
|
/// rot2 - rotation of end camera
|
|
/// iTime - time to interpolate
|
|
PROC SETUP_CAMERA_STRUCT_INTERPOLATE(CAMERA_STRUCT &cr, VECTOR pos1, VECTOR rot1, VECTOR pos2, VECTOR rot2, INT iTime, FLOAT fHeightOffset = 0.0)
|
|
SETUP_CAMERA_STRUCT(cr, pos1, rot1, DEFAULT, fHeightOffset)
|
|
SETUP_CAMERA_STRUCT_END_SHOT(cr, pos2, rot2, iTime)
|
|
ENDPROC
|
|
|
|
PROC SETUP_CAMERA_SWITCH_RATIO(CAMERA_STRUCT &cr, FLOAT swr)
|
|
cr.fSwitchRatio = swr
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the camera fov
|
|
/// PARAMS:
|
|
/// cr - camera reference
|
|
/// fov1 - start field of view
|
|
/// fov2 - end field of view - set this to zero to ignore
|
|
PROC SETUP_CAMERA_STRUCT_FOV(CAMERA_STRUCT &cr, FLOAT fov1, FLOAT fov2 = 0.0)
|
|
cr.fFov[0] = fov1
|
|
IF (fov2 = 0.0)
|
|
cr.fFov[1] = fov1
|
|
ELSE
|
|
cr.fFov[1] = fov2
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC SETUP_CAMERA_STRUCT_INTERPOLATE_TIME(CAMERA_STRUCT &cr, INT iTime)
|
|
cr.iInterpolateTime = iTime
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Enables the camera struct
|
|
/// PARAMS:
|
|
/// cr - camera reference
|
|
/// cameraID - camera index to write to
|
|
PROC ENABLE_CAMERA_STRUCT(CAMERA_STRUCT &cr, CAMERA_INDEX &cameraID, BOOL bBigVehicle = FALSE, BOOL bDontLerp = FALSE, CAMERA_GRAPH_TYPE cameraGraphPos = GRAPH_TYPE_SIN_ACCEL_DECEL, CAMERA_GRAPH_TYPE cameraGraphRot = GRAPH_TYPE_SIN_ACCEL_DECEL)
|
|
VECTOR vPos
|
|
|
|
FLOAT fov = cr.fFov[1]
|
|
|
|
IF (cr.bSetup = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
|
|
SHUTDOWN_CAMERA(cameraID)
|
|
|
|
vPos = cr.vPosition[0]
|
|
IF bBigVehicle
|
|
vPos.z += cr.fHeightOffset
|
|
ENDIF
|
|
|
|
cameraID = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", vPos, cr.vRotation[0], cr.fFov[0], TRUE)
|
|
IF NOT DOES_CAM_EXIST(cameraID)
|
|
EXIT
|
|
ENDIF
|
|
|
|
cr.iActivationTime = GET_GAME_TIMER()
|
|
SET_CAM_ACTIVE(cameraID, TRUE)
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
|
|
IF (NOT bDontLerp) AND (cr.iInterpolateTime > 0) AND NOT IS_VECTOR_ZERO(cr.vPosition[1])
|
|
vPos = cr.vPosition[1]
|
|
IF bBigVehicle
|
|
vPos.z += cr.fHeightOffset
|
|
ENDIF
|
|
|
|
IF (fov = 0.0)
|
|
fov = cr.fFov[0]
|
|
ENDIF
|
|
|
|
SET_CAM_PARAMS(cameraID, vPos, cr.vRotation[1], fov, cr.iInterpolateTime, cameraGraphPos, cameraGraphRot)
|
|
ELIF IS_ENTITY_OK(cr.targetID)
|
|
POINT_CAM_AT_ENTITY(cameraID, cr.targetID, <<0, 0, 0>>)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Enables the camera struct
|
|
/// PARAMS:
|
|
/// cr - camera reference
|
|
/// cameraID - camera index to write to
|
|
PROC ENABLE_CAMERA_STRUCT_REVERSE_INTERPOLATE(CAMERA_STRUCT &cr, CAMERA_INDEX &cameraID)
|
|
FLOAT fov = cr.fFov[1]
|
|
|
|
IF (cr.bSetup = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (cr.iInterpolateTime <= 0) OR IS_VECTOR_ZERO(cr.vPosition[1])
|
|
ENABLE_CAMERA_STRUCT(cr, cameraID)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (fov = 0.0)
|
|
fov = cr.fFov[0]
|
|
ENDIF
|
|
|
|
SHUTDOWN_CAMERA(cameraID)
|
|
cameraID = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", cr.vPosition[1], cr.vRotation[1], fov, TRUE)
|
|
IF NOT DOES_CAM_EXIST(cameraID)
|
|
EXIT
|
|
ENDIF
|
|
|
|
cr.iActivationTime = GET_GAME_TIMER()
|
|
SET_CAM_ACTIVE(cameraID, TRUE)
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
SET_CAM_PARAMS(cameraID, cr.vPosition[0], cr.vRotation[0], cr.fFov[0], cr.iInterpolateTime)
|
|
IF IS_ENTITY_OK(cr.targetID)
|
|
POINT_CAM_AT_ENTITY(cameraID, cr.targetID, <<0, 0, 0>>)
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Check if camera has finished interpolating
|
|
/// PARAMS:
|
|
/// cr - camera struct
|
|
/// RETURNS:
|
|
///
|
|
FUNC BOOL HAS_CAMERA_STRUCT_FINISHED_INTERPOLATING(CAMERA_STRUCT &cr, FLOAT fCheckRatio = CAMERA_NOSWITCHRATIO)
|
|
|
|
BOOL bUseSwitchRatio = (fCheckRatio <> CAMERA_NOSWITCHRATIO) AND (cr.fSwitchRatio <> CAMERA_NOSWITCHRATIO)
|
|
|
|
IF NOT (cr.bSetup = TRUE)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF (bUseSwitchRatio) AND (fCheckRatio >= cr.fSwitchRatio)
|
|
CPRINTLN(DEBUG_AMBIENT, "SWITCHING CAMERA GONE PAST SWITCH RATIO")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() > (cr.iActivationTime + cr.iInterpolateTime))
|
|
CPRINTLN(DEBUG_AMBIENT, "SWITCHING CAMERA - INTERPOLATION HAS FINISHED - SWITCH RATIO STATUS:", (fCheckRatio >= cr.fSwitchRatio))
|
|
RETURN (fCheckRatio >= cr.fSwitchRatio)
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Gets ratio of camera interpolate -
|
|
/// PARAMS:
|
|
/// cr - camera struct
|
|
/// RETURNS:
|
|
/// 0 is not start, 1 is done
|
|
FUNC FLOAT GET_CAMERA_STRUCT_INTERPOLATE_RATIO(CAMERA_STRUCT &cr)
|
|
IF (cr.iInterpolateTime <= 0)
|
|
RETURN 1.0
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() > (cr.iActivationTime + cr.iInterpolateTime))
|
|
RETURN 1.0
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() <= cr.iActivationTime)
|
|
RETURN 0.0
|
|
ENDIF
|
|
|
|
RETURN TO_FLOAT(GET_GAME_TIMER() - cr.iActivationTime) / TO_FLOAT(cr.iInterpolateTime)
|
|
ENDFUNC
|
|
|
|
FUNC BOOL IS_POINT_IN_CAMERA_STRUCT_CONE(CAMERA_STRUCT &cr, VECTOR pos)
|
|
VECTOR fwd = <<-SIN(cr.vRotation[0].z) * COS(cr.vRotation[0].x), COS(cr.vRotation[0].z) * COS(cr.vRotation[0].x), SIN(cr.vRotation[0].x)>>
|
|
VECTOR vNormalisedVec = NORMALISE_VECTOR(pos - cr.vPosition[0])
|
|
FLOAT fViewAngle = DOT_PRODUCT(fwd, vNormalisedVec)
|
|
|
|
IF fViewAngle <= COS(cr.fFov[0] / 2.0)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
//----------------------
|
|
// FUNCTIONS
|
|
//-----------------------
|
|
|
|
PROC SETUP_BASIC_ENTITY_TARGET_CAMERA(BASIC_CAMERA &cr, ENTITY_INDEX srcent, ENTITY_INDEX tgtent = NULL, BOOL bFPS = FALSE)
|
|
cr.bSetup = TRUE
|
|
cr.sourceID = srcent
|
|
cr.targetID = tgtent
|
|
cr.bFPSMode = bFPS
|
|
ENDPROC
|
|
|
|
PROC SETUP_BASIC_TARGET_CAMERA(BASIC_CAMERA &cr, VECTOR pos, VECTOR tgt, ENTITY_INDEX tgtent = NULL)
|
|
cr.bSetup = TRUE
|
|
cr.vPosition = pos
|
|
cr.vLookAt = tgt
|
|
cr.targetID = tgtent // if this is set - look at is ignored
|
|
ENDPROC
|
|
|
|
PROC SETUP_BASIC_FPS_CAMERA(BASIC_CAMERA &cr, BOOL b360Look = FALSE)
|
|
cr.bFPSMode = TRUE
|
|
cr.bSetup = TRUE
|
|
cr.targetID = PLAYER_PED_ID()
|
|
cr.fLookPitch = 0.0
|
|
cr.fLookYaw = 0.0
|
|
|
|
IF (b360Look)
|
|
cr.bWrapLookYaw = TRUE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC DISABLE_BASIC_CAMERA(BASIC_CAMERA &cr)
|
|
IF DOES_CAM_EXIST(cr.cameraID)
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
SET_CAM_ACTIVE(cr.cameraID, FALSE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC DESTROY_BASIC_CAMERA(BASIC_CAMERA &cr)
|
|
IF DOES_CAM_EXIST(cr.cameraID)
|
|
DISABLE_BASIC_CAMERA(cr)
|
|
DESTROY_CAM(cr.cameraID)
|
|
ENDIF
|
|
cr.cameraID = NULL
|
|
ENDPROC
|
|
|
|
FUNC BOOL ENABLE_BASIC_CAMERA(BASIC_CAMERA &cr, BOOL interp = FALSE, INT time = DEFAULT_INTERP_TO_FROM_GAME)
|
|
IF NOT (cr.bSetup = TRUE)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
cr.fFov = 50.0
|
|
IF NOT DOES_CAM_EXIST(cr.cameraID)
|
|
cr.cameraID = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", cr.vPosition, cr.vLookAt, 50.000, TRUE)
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_OK(cr.sourceID)
|
|
ATTACH_CAM_TO_ENTITY(cr.cameraID, cr.sourceID, <<0, 0, 0>>)
|
|
ENDIF
|
|
|
|
IF (cr.bFPSMode = TRUE)
|
|
IF IS_ENTITY_OK(PLAYER_PED_ID()) AND NOT IS_ENTITY_OK(cr.sourceID)
|
|
ATTACH_CAM_TO_PED_BONE(cr.cameraID, PLAYER_PED_ID(), BONETAG_HEAD, <<0, 0.2, 0>>)
|
|
ENDIF
|
|
|
|
cr.fLookPitch = 0.0
|
|
cr.fLookYaw = 0.0
|
|
ELIF IS_ENTITY_OK(cr.targetID)
|
|
POINT_CAM_AT_ENTITY(cr.cameraID, cr.targetID, <<0, 0, 0>>)
|
|
ENDIF
|
|
|
|
IF DOES_CAM_EXIST(cr.cameraID)
|
|
SET_CAM_ACTIVE(cr.cameraID, TRUE)
|
|
RENDER_SCRIPT_CAMS(TRUE, interp, time)
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
PROC UPDATE_BASIC_CAMERA(BASIC_CAMERA &cr)
|
|
IF NOT (cr.bSetup = TRUE)
|
|
EXIT
|
|
ENDIF
|
|
|
|
FLOAT pitch, yaw
|
|
FLOAT cpi
|
|
|
|
ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT(FRONTEND_CONTROL)
|
|
|
|
IF (cr.bFPSMode = TRUE)
|
|
IF ABSF(GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_RIGHT_AXIS_X)) > 0.1
|
|
cr.fLookYaw -= (GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_RIGHT_AXIS_X) * FPSCAM_LOOKSPEED * TIMESTEP())
|
|
|
|
IF (cr.bWrapLookYaw)
|
|
IF (cr.fLookYaw < -180.0)
|
|
cr.fLookYaw += 360.0
|
|
ENDIF
|
|
|
|
IF (cr.fLookYaw > 180.0)
|
|
cr.fLookYaw -= 360.0
|
|
ENDIF
|
|
ELSE
|
|
cr.fLookYaw = CLAMP(cr.fLookYaw, -FPSCAM_LIMITYAW, FPSCAM_LIMITYAW)
|
|
ENDIF
|
|
|
|
//CPRINTLN(DEBUG_AMBIENT, "YAW:", cr.fLookYaw)
|
|
ENDIF
|
|
|
|
IF ABSF(GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_RIGHT_AXIS_Y)) > 0.1
|
|
cpi = (GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_RIGHT_AXIS_Y) * FPSCAM_LOOKSPEED * TIMESTEP())
|
|
IF IS_LOOK_INVERTED()
|
|
cpi *= -1
|
|
ENDIF
|
|
cr.fLookPitch -= cpi
|
|
|
|
IF (cr.bWrapLookPitch)
|
|
IF (cr.fLookPitch < -180.0)
|
|
cr.fLookPitch += 360.0
|
|
ENDIF
|
|
|
|
IF (cr.fLookPitch > 180.0)
|
|
cr.fLookPitch -= 360.0
|
|
ENDIF
|
|
ELSE
|
|
cr.fLookPitch = CLAMP(cr.fLookPitch, -FPSCAM_LIMITPITCH, FPSCAM_LIMITPITCH)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RS)
|
|
cr.fLookPitch = 0.0
|
|
cr.fLookYaw = 0.0
|
|
ENDIF
|
|
|
|
// zoom
|
|
IF ABSF(GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_Y)) > 0.1
|
|
cpi = (GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_Y) * (FPSCAM_LOOKSPEED / 2.0) * TIMESTEP())
|
|
cr.fFov += cpi
|
|
cr.fFov = CLAMP(cr.fFov, FPSCAM_MINZOOM, FPSCAM_MAXZOOM)
|
|
ENDIF
|
|
|
|
IF DOES_CAM_EXIST(cr.cameraID)
|
|
SET_CAM_FOV(cr.cameraID, cr.fFov)
|
|
IF NOT IS_ENTITY_OK(cr.sourceID) AND IS_ENTITY_OK(PLAYER_PED_ID())
|
|
SET_CAM_ROT(cr.cameraID, GET_ENTITY_ROTATION(PLAYER_PED_ID()) + <<cr.fLookPitch, 0, cr.fLookYaw>>)
|
|
ELIF IS_ENTITY_OK(cr.sourceID) AND IS_ENTITY_OK(cr.targetID)
|
|
GET_PITCH_AND_HEADING_FROM_COORDS(GET_ENTITY_COORDS(cr.sourceID), GET_ENTITY_COORDS(cr.targetID), pitch, yaw)
|
|
SET_CAM_ROT(cr.cameraID, <<pitch, 0, yaw>> + <<cr.fLookPitch, 0, cr.fLookYaw>>)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
|