Example #1
0
 override public void EnableTool(bool bEnable)
 {
     base.EnableTool(bEnable);
     m_PreviewSegment.renderer.enabled = false;
     m_ExtendPath     = null;
     m_ExtendPathType = ExtendPathType.None;
 }
        override protected void Awake()
        {
            base.Awake();

            m_PathWidget = WidgetManager.m_Instance.GetNthActiveCameraPath(m_PathNumber);

            // We need to set m_CommandParam so we're properly highlighted in
            // SketchControlsScript.IsCommandActive.
            if (m_PathWidget != null)
            {
                int?index = WidgetManager.m_Instance.GetIndexOfCameraPath(m_PathWidget);
                if (index == null)
                {
                    throw new ArgumentException("SelectCameraPathButton m_PathWidget index invalid.");
                }
                m_CommandParam = index.Value;
            }
            else
            {
                m_CommandParam = -1;
            }

            // Count the number of active camera paths at the time we were created.
            // Note that this caching method is ok in this instance because these buttons are transient.
            var datas = WidgetManager.m_Instance.CameraPathWidgets;

            m_NumActivePaths = 0;
            foreach (TypedWidgetData <CameraPathWidget> data in datas)
            {
                ++m_NumActivePaths;
            }
        }
Example #3
0
 override public void HideTool(bool hide)
 {
     base.HideTool(hide);
     RefreshMeshVisibility();
     m_PreviewSegment.renderer.enabled = false;
     m_ExtendPath     = null;
     m_ExtendPathType = ExtendPathType.None;
 }
Example #4
0
 // Adds a path knot of type knotType to the path owned by widget at the
 // transform defined by spawnXf.
 public CreatePathKnotCommand(CameraPathWidget widget, CameraPathKnot.Type knotType,
                              PathT pathT, TrTransform spawnXf,
                              BaseCommand parent = null)
     : base(parent)
 {
     m_Widget   = widget;
     m_KnotType = knotType;
     m_SpawnXf  = spawnXf;
     m_PathT    = pathT;
 }
Example #5
0
        override protected void UpdateVisuals()
        {
            base.UpdateVisuals();

            CameraPathWidget cpw = WidgetManager.m_Instance.GetCurrentCameraPath().WidgetScript;

            if (cpw != null)
            {
                cpw.HighlightEntirePath();
            }
        }
Example #6
0
  override protected void OnButtonPressed() {
    // Create a new path if we pressed the + icon.
    if (m_NumActivePaths == m_PathNumber) {
      m_PathWidget = WidgetManager.m_Instance.CreatePathWidget();
      SketchSurfacePanel.m_Instance.EnableSpecificTool(BaseTool.ToolType.CameraPathTool);
      App.Switchboard.TriggerCameraPathModeChanged(CameraPathTool.Mode.AddPositionKnot);
    }

    WidgetManager.m_Instance.CameraPathsVisible = true;
    WidgetManager.m_Instance.SetCurrentCameraPath(m_PathWidget);
    SketchControlsScript.m_Instance.EatGazeObjectInput();
  }
        public RemovePathKnotCommand(CameraPathWidget widget, CameraPathKnot knot,
                                     TrTransform removeXf, BaseCommand parent = null)
            : base(parent)
        {
            Knot        = knot;
            m_Widget    = widget;
            m_RemovedXf = removeXf;

            // If we're removing a position knot, remember its ordered index. This is necessary
            // because it's probable that the path will change after removal and Undo won't be able
            // to place the knot back on the path at the current position.
            if (Knot.KnotType == CameraPathKnot.Type.Position)
            {
                m_KnotIndex = m_Widget.Path.PositionKnots.IndexOf((CameraPathPositionKnot)Knot);
                m_PathT     = new PathT();
            }
            else
            {
                m_PathT = Knot.PathT;
            }
        }
Example #8
0
        public static void DrawCameraPath(int index)
        {
            CameraPathWidget widget = WidgetManager.m_Instance.CameraPathWidgets.ElementAt(index).WidgetScript;
            CameraPath       path   = widget.Path;
            var positions           = new List <Vector3>();
            var rotations           = new List <Quaternion>();

            for (float t = 0; t < path.Segments.Count; t += .1f)
            {
                positions.Add(path.GetPosition(new PathT(t)));
                rotations.Add(path.GetRotation(new PathT(t)));
            }
            DrawStrokes.MultiPositionPathsToStrokes(
                new List <List <Vector3> > {
                positions
            },
                new List <List <Quaternion> > {
                rotations
            },
                null,
                Vector3.zero
                );
        }
Example #9
0
        override public void LateUpdateTool()
        {
            Transform xf = InputManager.Brush.Geometry.ToolAttachPoint;

            m_RemoveKnot.transform.position = xf.position;
            m_RemoveKnot.transform.rotation = xf.rotation;

            if (m_LastPlacedKnot == null)
            {
                // Detect point nearest to path and jump to path if close enough.
                float bestDistance = float.MaxValue;
                m_PrevLastValidPath = m_LastValidPath;
                m_LastValidPosition = xf.position;
                m_LastValidPath     = null;

                GrabWidgetData currentData = WidgetManager.m_Instance.GetCurrentCameraPath();
                var            datas       = WidgetManager.m_Instance.CameraPathWidgets;
                foreach (TypedWidgetData <CameraPathWidget> data in datas)
                {
                    CameraPathWidget widget = data.WidgetScript;
                    Debug.AssertFormat(widget != null, "Non-CameraPathWidget in CameraPathWidget list");

                    // Check our tool attach point against the path.  If there is a collision, we're going
                    // to jump the position of our mesh to the point on the path.
                    Vector3?projected = widget.Path.ProjectPositionOntoPath(xf.position);
                    if (projected != null)
                    {
                        float distToProjected = Vector3.Distance(projected.Value, xf.position);
                        if (distToProjected < bestDistance)
                        {
                            bestDistance        = distToProjected;
                            m_LastValidPosition = projected.Value;
                            m_LastValidPath     = widget;

                            // We reset this here and not above (with m_LastValidPath) because we want the value
                            // to retain as the user moves around beyond the end.  It's only when hiding and
                            // interacting with a path do we want it to reset.
                            m_ExtendPath = null;
                        }
                    }

                    // In addition to checking collision with the path, check collision with the end points
                    // of the paths.  If the user comes near an end point, but is *not* colliding with the
                    // path, they should be able to extend the length of the path.  That is, add a new knot
                    // off the respective end.
                    bool currentWidget = (currentData == null) ? false : currentData.m_WidgetScript == widget;
                    if (currentWidget && m_Mode == Mode.AddPositionKnot)
                    {
                        if (widget.Path.PathLoops)
                        {
                            // We never want to show an extended path when the path loops.
                            m_ExtendPath     = null;
                            m_ExtendPathType = ExtendPathType.None;
                        }
                        else
                        {
                            // logic for extending off one end of the path.
                            CameraPath.EndType end = widget.Path.IsPositionNearEnd(xf.position);
                            // If we're not near an end point but we're in loop mode, break out of loop mode.
                            if (end == CameraPath.EndType.None && m_ExtendPathType == ExtendPathType.Loop)
                            {
                                m_ExtendPath     = null;
                                m_ExtendPathType = ExtendPathType.None;
                            }
                            else if (end != CameraPath.EndType.None && m_ExtendPathType != ExtendPathType.Loop)
                            {
                                m_ExtendPath = widget;
                                // If we're currently extending our path and we're now close to the other end,
                                // set our extend type to looping.
                                if (widget.Path.NumPositionKnots > 1 &&
                                    (m_ExtendPathType == ExtendPathType.ExtendAtHead &&
                                     end == CameraPath.EndType.Tail) ||
                                    (m_ExtendPathType == ExtendPathType.ExtendAtTail &&
                                     end == CameraPath.EndType.Head))
                                {
                                    m_ExtendPathType = ExtendPathType.Loop;
                                }
                                else
                                {
                                    m_ExtendPathType = (end == CameraPath.EndType.Head) ? ExtendPathType.ExtendAtHead :
                                                       ExtendPathType.ExtendAtTail;
                                }
                            }
                        }
                    }
                }

                m_PositionKnot.transform.position = m_LastValidPosition;
                m_PositionKnot.transform.rotation = xf.rotation;
                m_RotationKnot.transform.position = m_LastValidPosition;
                m_RotationKnot.transform.rotation = xf.rotation;
                m_SpeedKnot.transform.position    = m_LastValidPosition;
                m_SpeedKnot.transform.rotation    = Quaternion.identity;
                m_FovKnot.transform.position      = m_LastValidPosition;
                m_FovKnot.transform.rotation      = Quaternion.identity;

                // If we're not colliding with a path, but we are colliding with an end, show the preview
                // segment.
                if (m_LastValidPath == null && m_ExtendPath != null)
                {
                    m_PreviewSegment.renderer.enabled = true;
                    m_ExtendPath.Path.RefreshSegmentVisuals(xf.position, m_PreviewSegment, m_ExtendPathType);
                }
                else
                {
                    m_PreviewSegment.renderer.enabled = false;
                }
            }
            else
            {
                m_PreviewSegment.renderer.enabled = false;
                m_PrevLastValidPath = m_LastValidPath;
                m_LastValidPath     = null;
            }
        }
Example #10
0
        override public void UpdateTool()
        {
            base.UpdateTool();

            // If we're in the recording state, just look for cancel and get out.
            if (CurrentMode == Mode.Recording)
            {
                if (InputManager.m_Instance.GetCommandDown(InputManager.SketchCommands.MenuContextClick))
                {
                    SketchControlsScript.m_Instance.CameraPathCaptureRig.StopRecordingPath(false);
                }
                return;
            }

            var       widgets      = WidgetManager.m_Instance.CameraPathWidgets;
            Transform toolAttachXf = InputManager.Brush.Geometry.ToolAttachPoint;

            bool input     = InputManager.m_Instance.GetCommand(InputManager.SketchCommands.Activate);
            bool inputDown = InputManager.m_Instance.GetCommandDown(InputManager.SketchCommands.Activate);

            // Tint any path we're intersecting with.
            if (!input && m_LastValidPath != null && m_Mode != Mode.RemoveKnot)
            {
                m_LastValidPath.TintSegments(m_LastValidPosition);
            }

            // Initiating input.
            if (inputDown)
            {
                // We clicked, but the path we clicked on isn't the active path.  In that case,
                // switch it to the active path and eat up this input.
                // Don't do this for removing knots.  That input should be explicit.
                if (m_Mode != Mode.RemoveKnot && m_LastValidPath != null)
                {
                    GrabWidgetData data = WidgetManager.m_Instance.GetCurrentCameraPath();
                    bool           lastValidIsCurrent = (data == null) ? false : data.m_WidgetScript == m_LastValidPath;
                    if (!lastValidIsCurrent)
                    {
                        WidgetManager.m_Instance.SetCurrentCameraPath(m_LastValidPath);
                        return;
                    }
                }

                switch (m_Mode)
                {
                case Mode.AddPositionKnot:
                    // Create a new path if none exists or if we're trying to add a position point
                    // in a place where we're not extending an existing path.
                    if (!WidgetManager.m_Instance.AnyCameraPathWidgetsActive ||
                        (m_LastValidPath == null && m_ExtendPath == null))
                    {
                        m_ExtendPath     = WidgetManager.m_Instance.CreatePathWidget();
                        m_ExtendPathType = ExtendPathType.ExtendAtHead;
                        WidgetManager.m_Instance.SetCurrentCameraPath(m_ExtendPath);
                    }

                    if (m_LastValidPath != null)
                    {
                        m_LastValidPath.AddPathConstrainedKnot(
                            CameraPathKnot.Type.Position, m_LastValidPosition, toolAttachXf.rotation);
                        m_LastPlacedKnot     = m_LastValidPath.Path.LastPlacedKnotInfo;
                        m_LastPlacedKnotPath = m_LastValidPath;
                    }
                    else if (m_ExtendPath != null)
                    {
                        // Manipulation of a path we wish to extend.
                        m_ExtendPath.ExtendPath(toolAttachXf.position, m_ExtendPathType);

                        // Remember the index of the path we just added to, so we can manipulate it
                        // while input is held.
                        // Don't record this if we just made our path loop.
                        if (!m_ExtendPath.Path.PathLoops)
                        {
                            m_LastPlacedKnot     = m_ExtendPath.Path.LastPlacedKnotInfo;
                            m_LastPlacedKnotPath = m_ExtendPath;
                        }
                    }
                    break;

                case Mode.AddRotationKnot:
                    if (m_LastValidPath != null)
                    {
                        m_LastValidPath.AddPathConstrainedKnot(
                            CameraPathKnot.Type.Rotation, m_LastValidPosition, toolAttachXf.rotation);
                        m_LastPlacedKnot     = m_LastValidPath.Path.LastPlacedKnotInfo;
                        m_LastPlacedKnotPath = m_LastValidPath;
                    }
                    break;

                case Mode.AddSpeedKnot:
                    if (m_LastValidPath != null)
                    {
                        m_LastValidPath.AddPathConstrainedKnot(
                            CameraPathKnot.Type.Speed, m_LastValidPosition, toolAttachXf.rotation);
                        m_LastPlacedKnot     = m_LastValidPath.Path.LastPlacedKnotInfo;
                        m_LastPlacedKnotPath = m_LastValidPath;
                    }
                    break;

                case Mode.AddFovKnot:
                    if (m_LastValidPath != null)
                    {
                        m_LastValidPath.AddPathConstrainedKnot(
                            CameraPathKnot.Type.Fov, m_LastValidPosition, toolAttachXf.rotation);
                        m_LastPlacedKnot     = m_LastValidPath.Path.LastPlacedKnotInfo;
                        m_LastPlacedKnotPath = m_LastValidPath;
                    }
                    break;

                case Mode.RemoveKnot:
                    CheckToRemoveKnot(toolAttachXf.position);
                    break;
                }

                // Remember what our controller looked like so we can manipulate this knot.
                if (m_LastPlacedKnot != null)
                {
                    Transform   controller  = InputManager.Brush.Transform;
                    Transform   knotXf      = m_LastPlacedKnot.knot.transform;
                    TrTransform newWidgetXf = Coords.AsGlobal[knotXf];
                    m_LastPlacedKnotXf_LS = Coords.AsGlobal[controller].inverse * newWidgetXf;
                    HideAllMeshes();
                }
            }
            else if (input)
            {
                if (m_Mode == Mode.RemoveKnot)
                {
                    CheckToRemoveKnot(toolAttachXf.position);
                }
                else if (m_LastPlacedKnot != null)
                {
                    // Holding input from last frame can allow us to manipulate a just placed position knot.
                    WidgetManager.m_Instance.PathTinter.TintKnot(m_LastPlacedKnot.knot);

                    TrTransform controllerXf = Coords.AsGlobal[InputManager.Brush.Transform];
                    TrTransform inputXf      = controllerXf * m_LastPlacedKnotXf_LS;

                    switch (m_LastPlacedKnot.knot.KnotType)
                    {
                    case CameraPathKnot.Type.Position:
                        if (m_LastPlacedKnot.control != 0)
                        {
                            CameraPathPositionKnot pk = m_LastPlacedKnot.knot as CameraPathPositionKnot;
                            float   tangentMag        = pk.GetTangentMagnitudeFromControlXf(inputXf);
                            Vector3 knotFwd           =
                                (inputXf.translation - m_LastPlacedKnot.knot.transform.position).normalized;
                            if ((CameraPathPositionKnot.ControlType)m_LastPlacedKnot.control ==
                                CameraPathPositionKnot.ControlType.TangentControlBack)
                            {
                                knotFwd *= -1.0f;
                            }

                            SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                                new ModifyPositionKnotCommand(
                                    m_LastPlacedKnotPath.Path, m_LastPlacedKnot, tangentMag, knotFwd,
                                    mergesWithCreateCommand: true));
                        }
                        break;

                    case CameraPathKnot.Type.Rotation:
                        // Rotation knots hide when we grab them, and in their place, we set the preview widget.
                        m_LastPlacedKnot.knot.gameObject.SetActive(false);
                        SketchControlsScript.m_Instance.CameraPathCaptureRig.OverridePreviewWidgetPathT(
                            m_LastPlacedKnot.knot.PathT);
                        SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                            new MoveConstrainedKnotCommand(m_LastPlacedKnotPath.Path, m_LastPlacedKnot,
                                                           inputXf.rotation, mergesWithCreateCommand: true));
                        break;

                    case CameraPathKnot.Type.Speed:
                        CameraPathSpeedKnot sk = m_LastPlacedKnot.knot as CameraPathSpeedKnot;
                        float speed            = sk.GetSpeedValueFromY(
                            InputManager.Brush.Behavior.PointerAttachPoint.transform.position.y);
                        SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                            new ModifySpeedKnotCommand(sk, speed, mergesWithCreateCommand: true));
                        break;

                    case CameraPathKnot.Type.Fov:
                        CameraPathFovKnot fk  = m_LastPlacedKnot.knot as CameraPathFovKnot;
                        float             fov = fk.GetFovValueFromY(
                            InputManager.Brush.Behavior.PointerAttachPoint.transform.position.y);
                        SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                            new ModifyFovKnotCommand(fk, fov, mergesWithCreateCommand: true));
                        break;
                    }
                }
            }
            else
            {
                // No input to work with.  Forget we had anything and make sure our meshes are showing.
                if (m_LastPlacedKnot != null)
                {
                    RefreshMeshVisibility();

                    // Rotation knots hide when we grab them, make sure it's enabled.
                    if (m_LastPlacedKnot.knot.KnotType == CameraPathKnot.Type.Rotation)
                    {
                        m_LastPlacedKnot.knot.gameObject.SetActive(true);
                        SketchControlsScript.m_Instance.CameraPathCaptureRig.OverridePreviewWidgetPathT(null);
                    }
                }
                m_LastPlacedKnot     = null;
                m_LastPlacedKnotPath = null;
            }
        }
Example #11
0
 void CacheCurrentPathWidget() {
   var data = WidgetManager.m_Instance.GetCurrentCameraPath();
   m_CurrentPathWidget = (data == null) ? null : data.WidgetScript;
 }
  static public void CreateFromSaveData(CameraPathMetadata cameraPath) {
    // Create a new widget.
    CameraPathWidget widget = Instantiate<CameraPathWidget>(
        WidgetManager.m_Instance.CameraPathWidgetPrefab);
    widget.transform.parent = App.Scene.MainCanvas.transform;

    // The scale of path widgets is arbitrary.  However, the scale should be one at creation
    // time so the knots added below have appropriate mesh scales.
    widget.transform.localScale = Vector3.one;
    widget.transform.localPosition = Vector3.zero;
    widget.transform.localRotation = Quaternion.identity;

    // Add the path knots and set their tangent speed.
    for (int i = 0; i < cameraPath.PathKnots.Length; ++i) {
      GameObject go = Instantiate<GameObject>(
          WidgetManager.m_Instance.CameraPathPositionKnotPrefab);
      go.transform.position = cameraPath.PathKnots[i].Xf.translation;
      go.transform.rotation = cameraPath.PathKnots[i].Xf.rotation;
      go.transform.parent = widget.transform;

      CameraPathPositionKnot knot = go.GetComponent<CameraPathPositionKnot>();
      knot.TangentMagnitude = cameraPath.PathKnots[i].TangentMagnitude;

      widget.m_Path.PositionKnots.Add(knot);
      widget.m_Path.AllKnots.Add(knot);

      if (i > 0) {
        widget.m_Path.Segments.Add(CameraPath.CreateSegment(widget.transform));
      }
    }

    // Refresh the path so the segment curves are correct.
    for (int i = 0; i < cameraPath.PathKnots.Length - 1; ++i) {
      widget.m_Path.RefreshSegment(i);
    }

    // Add the rotation knots.  Note this list is ordered, and they're serialized in order,
    // so we need to make sure they're created in order.
    for (int i = 0; i < cameraPath.RotationKnots.Length; ++i) {
      GameObject go = Instantiate<GameObject>(
          WidgetManager.m_Instance.CameraPathRotationKnotPrefab);
      go.transform.position = cameraPath.RotationKnots[i].Xf.translation;
      go.transform.rotation = cameraPath.RotationKnots[i].Xf.rotation;
      go.transform.parent = widget.transform;

      CameraPathRotationKnot knot = go.GetComponent<CameraPathRotationKnot>();
      knot.PathT = new PathT(cameraPath.RotationKnots[i].PathTValue);
      knot.DistanceAlongSegment = widget.m_Path.GetSegmentDistanceToT(knot.PathT);

      widget.m_Path.RotationKnots.Add(knot);
      widget.m_Path.AllKnots.Add(knot);
    }
    // Align quaternions on all rotation knots so we don't have unexpected camera flips
    // when calculating rotation as we walk the path.
    widget.m_Path.RefreshRotationKnotPolarities();

    // Add the speed knots.  Note this list is ordered, and they're serialized in order,
    // so we need to make sure they're created in order.
    for (int i = 0; i < cameraPath.SpeedKnots.Length; ++i) {
      GameObject go = Instantiate<GameObject>(
          WidgetManager.m_Instance.CameraPathSpeedKnotPrefab);
      go.transform.position = cameraPath.SpeedKnots[i].Xf.translation;
      go.transform.rotation = cameraPath.SpeedKnots[i].Xf.rotation;
      go.transform.parent = widget.transform;

      CameraPathSpeedKnot knot = go.GetComponent<CameraPathSpeedKnot>();

      knot.PathT = new PathT(cameraPath.SpeedKnots[i].PathTValue);
      knot.DistanceAlongSegment = widget.m_Path.GetSegmentDistanceToT(knot.PathT);
      knot.SpeedValue = cameraPath.SpeedKnots[i].Speed;

      widget.m_Path.SpeedKnots.Add(knot);
      widget.m_Path.AllKnots.Add(knot);
    }

    // Add the fov knots.  Note this list is ordered, and they're serialized in order,
    // so we need to make sure they're created in order.
    for (int i = 0; i < cameraPath.FovKnots.Length; ++i) {
      GameObject go = Instantiate<GameObject>(
          WidgetManager.m_Instance.CameraPathFovKnotPrefab);
      go.transform.position = cameraPath.FovKnots[i].Xf.translation;
      go.transform.rotation = cameraPath.FovKnots[i].Xf.rotation;
      go.transform.parent = widget.transform;

      CameraPathFovKnot knot = go.GetComponent<CameraPathFovKnot>();

      knot.PathT = new PathT(cameraPath.FovKnots[i].PathTValue);
      knot.DistanceAlongSegment = widget.m_Path.GetSegmentDistanceToT(knot.PathT);
      knot.FovValue = cameraPath.FovKnots[i].Fov;

      widget.m_Path.FovKnots.Add(knot);
      widget.m_Path.AllKnots.Add(knot);
    }

    // Refresh visuals on the whole path.
    for (int i = 0; i < widget.m_Path.AllKnots.Count; ++i) {
      widget.m_Path.AllKnots[i].RefreshVisuals();
      widget.m_Path.AllKnots[i].ActivateTint(false);
      widget.m_Path.AllKnots[i].SetActivePathVisuals(false);
    }

    // And turn them off.
    widget.m_Path.ValidatePathLooping();
    widget.m_Path.SetKnotsActive(false);
    App.Switchboard.TriggerCameraPathCreated();
  }