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;
 }
コード例 #3
0
 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)
                ));
 }
コード例 #4
0
 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;
                }
            }
コード例 #6
0
            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);
                }
            }
コード例 #8
0
            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);
 }
コード例 #14
0
            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;
 }
コード例 #16
0
 public abstract void ModifiyState(ref CinematicCameraState state, float shotTime, float shotDuration);
 public abstract void ModifiyState(ref CinematicCameraState state, float clipPosition);