private void ApplyAutoPanTranslation(ref CinematicCameraState state, float clipPosition) { Vector3 worldSpaceTranslate = this.transform.TransformPoint(_autoPanTranslation); Vector3 movement = worldSpaceTranslate - this.transform.position; state._position += MathUtils.Interpolate(_autoPanEase, movement, _autoPanStyle == eAutoPanStyle.PanThrough ? -movement : Vector3.zero, clipPosition); }
public virtual void SetState(CinematicCameraState state) { this.transform.position = state._position; this.transform.rotation = state._rotation; GetCamera().fieldOfView = state._fieldOfView; GetCamera().rect = state._cameraRect; _focusInfo = state._focusInfo; }
public static CinematicCameraState Interpolate(CinematicCamera camera, CinematicCameraState from, CinematicCameraState to, InterpolationType ease, float t) { return(new CinematicCameraState( MathUtils.Interpolate(ease, from._position, to._position, t), MathUtils.Interpolate(ease, from._rotation, to._rotation, t), MathUtils.Interpolate(ease, from._fieldOfView, to._fieldOfView, t), MathUtils.Interpolate(ease, from._cameraRect, to._cameraRect, t), CinematicCameraFocusInfo.Interpolate(camera, ease, from._focusInfo, to._focusInfo, t) )); }
private static void StartPreviewing(CinematicCameraShotInspector inspector) { if (!_preview) { CinematicCamera previewCamera = (CinematicCamera)inspector._previewCameraProperty.objectReferenceValue; _originalCameraState = previewCamera.GetState(); EditorApplication.update += UpdateKeys; EditorSceneManager.sceneSaving += OnSaveScene; _preview = true; _previewShot = inspector; _previewClipTime = 0.0f; } }
private void ApplyAutoPanRotation(ref CinematicCameraState state, float clipPosition) { float angle = MathUtils.Interpolate(_autoPanEase, _autoRotateAngle, _autoPanStyle == eAutoPanStyle.PanThrough ? -_autoRotateAngle : 0.0f, clipPosition); switch (_autoRotateType) { case AutoRotateType.RotateAroundFocusPoint: { if (state._focusInfo._focusPointTarget != null) { Vector3 pivotPoint = state._focusInfo._focusPointTarget.position; Vector3 toPivot = this.transform.position - pivotPoint; if (toPivot.sqrMagnitude > 0.0f) { Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.up); state._position = pivotPoint + (rotation * toPivot); state._rotation *= rotation; } } } break; case AutoRotateType.RotateAroundLocalPoint: { Vector3 pivotPoint = this.transform.TransformPoint(_autoRotateLocalPoint); Vector3 toPivot = this.transform.position - pivotPoint; if (toPivot.sqrMagnitude > 0.0f) { Vector3 axis = Vector3.Cross(toPivot, this.transform.right); Quaternion rotation = Quaternion.AngleAxis(angle, axis); state._position = pivotPoint + (rotation * toPivot); state._rotation *= rotation; } } break; case AutoRotateType.RotateAroundAxis: default: { Vector3 axis = _autoRotateLocalPoint; Quaternion rotation = Quaternion.AngleAxis(angle, axis); state._rotation *= rotation; } break; } }
public override void ModifiyState(ref CinematicCameraState state, float shotTime, float shotDuration) { float panDuration = shotDuration > 0f ? shotDuration : _panDuration; float clipPosition = panDuration > 0f ? shotTime / panDuration : 1f; #if UNITY_EDITOR if (IsBeingPreviewed()) { clipPosition = _previewClipPos; } #endif ApplyAutoPan(ref state, Mathf.Clamp01(clipPosition)); }
private void ApplyAutoPan(ref CinematicCameraState state, float clipPosition) { if ((_autoPanFlags & AutoPanFlags.Zoom) == AutoPanFlags.Zoom) { ApplyAutoPanZoom(ref state, clipPosition); } if ((_autoPanFlags & AutoPanFlags.Rotate) == AutoPanFlags.Rotate) { ApplyAutoPanRotation(ref state, clipPosition); } if ((_autoPanFlags & AutoPanFlags.Translate) == AutoPanFlags.Translate) { ApplyAutoPanTranslation(ref state, clipPosition); } }
void Update() { if (_currentShot._shot != null) { _currentShot._time += Time.deltaTime; if (_currentShot._weight < 1.0f) { _currentShot._weight = Mathf.Clamp01(_currentShot._weight + _currentShotBlendSpeed * Time.deltaTime); } } if (_currentShot._shot != null && _currentShot._weight >= 1.0f) { float shotPosition = _currentShot._time / _currentShot._duration; _camera.SetState(_currentShot.GetState()); } else if (_blendingShots != null && _blendingShots.Length > 0 || _currentShot._shot != null) { CinematicCameraState blendedState; if (_blendingShots.Length > 0) { _blendingShots[0]._time += Time.deltaTime; blendedState = _blendingShots[0].GetState(); for (int i = 1; i < _blendingShots.Length; i++) { _blendingShots[i]._time += Time.deltaTime; blendedState = CinematicCameraState.Interpolate(_camera, blendedState, _blendingShots[i].GetState(), _blendingShots[i]._blendType, _blendingShots[i]._weight); } } else { blendedState = _camera.GetState(); } if (_currentShot._shot != null) { blendedState = CinematicCameraState.Interpolate(_camera, blendedState, _currentShot.GetState(), _currentShot._blendType, _currentShot._weight); } _camera.SetState(blendedState); } }
public CinematicCameraState GetState(float clipPosition = 0.0f) { //Get default state CinematicCameraState state = new CinematicCameraState { _position = this.transform.position, _rotation = this.transform.rotation, _fieldOfView = this._fieldOfView, _cameraRect = this._cameraRect, _focusInfo = this._focusInfo }; //Apply modifiers for (int i = 0; i < _cinematicCameraShotModifiers.Length; i++) { _cinematicCameraShotModifiers[i].ModifiyState(ref state, clipPosition); } return(state); }
private void GetPathNodeStateInfo(Path path, int nodeIndex, out CinematicCameraState cameraState, out Quaternion rotationToPath, out Vector3 forwardDir, out Vector3 upDir) { // (TO DO: cache components) CinematicCameraShot shot = path._nodes[nodeIndex]._node.GetComponent <CinematicCameraShot>(); if (shot != null) { cameraState = shot.GetState(); PathPosition nodePos = path.GetPoint(path.GetPathT(path._nodes[nodeIndex]._node)); rotationToPath = Quaternion.FromToRotation(nodePos._pathForward, shot.transform.forward); forwardDir = shot.transform.forward; upDir = shot.transform.up; } else { cameraState = default; rotationToPath = Quaternion.identity; forwardDir = Vector3.forward; upDir = Vector3.up; } }
private void ApplyAutoPanZoom(ref CinematicCameraState state, float clipPosition) { float fieldOfView = state._fieldOfView + MathUtils.Interpolate(_autoPanEase, _autoZoomAmount, _autoPanStyle == eAutoPanStyle.PanThrough ? -_autoZoomAmount : 0.0f, clipPosition); switch (_autoZoomStyle) { case AutoZoomStyle.DollyZoom: { //From here https://en.wikipedia.org/wiki/Dolly_zoom // distance = fixedWidth / 2tan(FoV*0.5) // width = distance * 2tan(fov*0.5) float focusDistance = state._focusInfo.GetFocusDistance(state._position); float frustrumHeightAtDistance = focusDistance * 2.0f * Mathf.Tan(state._fieldOfView * 0.5f * Mathf.Deg2Rad); //Now need to work out need camera distance to target float distance = frustrumHeightAtDistance / (2.0f * Mathf.Tan(fieldOfView * Mathf.Deg2Rad * 0.5f)); //Then move camera back so its now this far away float neededMovement = distance - focusDistance; state._position -= state._rotation * Vector3.forward * neededMovement; //update field of view state._fieldOfView = fieldOfView; //Also need to update focus data state._focusInfo._focusPointDistance += neededMovement; //Also need to update focus width??? state._focusInfo._focusPointFNumber += neededMovement * 0.01f; } break; case AutoZoomStyle.PlainZoom: { state._fieldOfView = fieldOfView; } break; } }
public override void ProcessFrame(Playable playable, FrameData info, object playerData) { _trackBinding = playerData as CinematicCamera; if (_trackBinding == null) { return; } if (!_firstFrameHappened) { _defaultState = _trackBinding.GetState(); _firstFrameHappened = true; } int numInputs = playable.GetInputCount(); float[] inputWeights = new float[numInputs]; float totalWeights = 0.0f; CinematicCameraState[] states = new CinematicCameraState[numInputs]; for (int i = 0; i < numInputs; i++) { ScriptPlayable <CinematicCameraPlayableBehaviour> scriptPlayable = (ScriptPlayable <CinematicCameraPlayableBehaviour>)playable.GetInput(i); CinematicCameraPlayableBehaviour inputBehaviour = scriptPlayable.GetBehaviour(); if (inputBehaviour != null && (inputBehaviour._cameraShot != null || inputBehaviour._path != null)) { float inputWeight = playable.GetInputWeight(i); if (inputWeight > 0.0f) { TimelineClip clip = _trackAsset.GetClip(inputBehaviour._clipAsset); if (clip != null) { double clipStart = clip.hasPreExtrapolation ? clip.extrapolatedStart : clip.start; double clipDuration = clip.hasPreExtrapolation || clip.hasPostExtrapolation ? clip.extrapolatedDuration : clip.duration; if (_director.time >= clipStart && _director.time <= clipStart + clipDuration) { inputWeights[i] = inputWeight; Extrapolation extrapolation = Extrapolation.Hold; if (clip.hasPreExtrapolation && _director.time < clip.start) { extrapolation = GetExtrapolation(clip.preExtrapolationMode); } else if (clip.hasPostExtrapolation && _director.time > clip.start + clip.duration) { extrapolation = GetExtrapolation(clip.postExtrapolationMode); } float timeInClip = (float)(_director.time - clip.start); //Single shot if (inputBehaviour._cameraShot != null) { states[i] = inputBehaviour._cameraShot.GetState(timeInClip, (float)clip.duration); } //Camera path else if (inputBehaviour._path != null) { float clipPosition = CinematicCameraMixer.GetClipPosition(extrapolation, timeInClip, (float)clip.duration); float pathT = (float)MathUtils.Interpolate(inputBehaviour._pathInterpolation, 0d, 1f, clipPosition); //Work out path position PathPosition pos = inputBehaviour._path.GetPoint(pathT); //Work out a lerp between to path nodes inputBehaviour._path.GetNodeSection(pathT, out int startNode, out int endNode, out float sectionT); //Lerp camera shot state based on the relevant section of the path GetPathNodeStateInfo(timeInClip, (float)clip.duration, inputBehaviour._path, startNode, out CinematicCameraState startNodeState, out Quaternion startNodeFromTo, out Vector3 startNodeCamFor, out Vector3 startNodeCamUp); GetPathNodeStateInfo(timeInClip, (float)clip.duration, inputBehaviour._path, endNode, out CinematicCameraState endNodeState, out Quaternion endNodeFromTo, out Vector3 endNodeCamFor, out Vector3 endNodeCamUp); Vector3 cameraForward; Vector3 cameraUp; if (sectionT <= 0f) { states[i] = startNodeState; //cameraForward = startNodeFromTo * pos._pathForward; cameraForward = startNodeCamFor; cameraUp = startNodeCamUp; } else if (sectionT >= 1f) { states[i] = endNodeState; //cameraForward = endNodeFromTo * pos._pathForward; cameraForward = endNodeCamFor; cameraUp = endNodeCamUp; } else { states[i] = CinematicCameraState.Interpolate(_trackBinding, startNodeState, endNodeState, InterpolationType.Linear, sectionT); //Work out rotation based on Quaternion cameraRotation = Quaternion.Slerp(startNodeFromTo, endNodeFromTo, sectionT); cameraForward = cameraRotation * pos._pathForward; cameraForward = Vector3.Lerp(startNodeCamFor, endNodeCamFor, sectionT); cameraUp = Vector3.Lerp(startNodeCamUp, endNodeCamUp, sectionT); } //Set camera position from path pos states[i]._position = pos._pathPosition; states[i]._rotation = Quaternion.LookRotation(cameraForward, cameraUp); } totalWeights += inputWeights[i]; } } } } } if (totalWeights > 0.0f) { CinematicCameraState blendedState = _defaultState; float weightAdjust = 1.0f / totalWeights; bool firstBlend = true; for (int i = 0; i < numInputs; i++) { if (inputWeights[i] > 0.0f) { if (firstBlend) { blendedState = states[i]; firstBlend = false; } else { blendedState = CinematicCameraState.Interpolate(_trackBinding, blendedState, states[i], InterpolationType.Linear, inputWeights[i] * weightAdjust); } } } _trackBinding.SetState(blendedState); } else { _trackBinding.SetState(_defaultState); } }
public override void ModifiyState(ref CinematicCameraState state, float clipPosition) { ApplyAutoPan(ref state, clipPosition); }
private void ApplyAutoPanTranslation(ref CinematicCameraState state, float clipPosition) { Vector3 worldSpaceTranslate = this.transform.TransformDirection(_autoPanTranslation); state._position += MathUtils.Interpolate(_autoPanEase, worldSpaceTranslate, _autoPanStyle == AutoPanStyle.PanThrough ? -worldSpaceTranslate : Vector3.zero, clipPosition); }
public override void ModifiyState(ref CinematicCameraState state, float shotTime, float shotDuration) { state._rotation *= _rotation; state._position += state._rotation * _translation; }
public abstract void ModifiyState(ref CinematicCameraState state, float shotTime, float shotDuration);
public abstract void ModifiyState(ref CinematicCameraState state, float clipPosition);