override protected void OnUserBeginInteracting() {
    GrabWidgetData data = WidgetManager.m_Instance.GetCurrentCameraPath();
    m_EatInteractingInput = (data == null) ? false : data.m_WidgetScript != this;
    WidgetManager.m_Instance.SetCurrentCameraPath(this);

    Debug.Assert(m_InteractingController == InputManager.ControllerName.Brush ||
        m_InteractingController == InputManager.ControllerName.Wand);
    m_ActiveKnot = m_LastValidCollisionResults[(int)m_InteractingController];

    // If we just grabbed a knot control, record the Y position of the controller grab point.
    if (m_ActiveKnot.control != CameraPathKnot.kDefaultControl) {
      BaseControllerBehavior b = InputManager.Controllers[(int)m_InteractingController].Behavior;
      if (m_ActiveKnot.knot.KnotType == CameraPathKnot.Type.Fov) {
        CameraPathFovKnot fovKnot = m_ActiveKnot.knot as CameraPathFovKnot;
        m_GrabControlInitialYDiff = b.PointerAttachPoint.transform.position.y -
            fovKnot.GetGrabTransform(
              (int)CameraPathFovKnot.ControlType.FovControl).position.y;
      }
      if (m_ActiveKnot.knot.KnotType == CameraPathKnot.Type.Speed) {
        CameraPathSpeedKnot speedKnot = m_ActiveKnot.knot as CameraPathSpeedKnot;
        m_GrabControlInitialYDiff = b.PointerAttachPoint.transform.position.y -
            speedKnot.GetGrabTransform(
              (int)CameraPathSpeedKnot.ControlType.SpeedControl).position.y;
      }
    }
  }
        public ModifyPositionKnotCommand(CameraPath path, KnotDescriptor knotDesc, float endSpeed,
                                         Vector3 endForward_GS, bool mergesWithCreateCommand = false, bool final = false,
                                         BaseCommand parent = null)
            : base((CameraPathPositionKnot)knotDesc.knot, mergesWithCreateCommand, parent)
        {
            m_Path      = path;
            m_EndSpeed  = endSpeed;
            m_KnotIndex = knotDesc.positionKnotIndex.Value;
            m_Final     = final;

            // Store the local space rotation because the knot's parent (the canvas) may change
            // between undo/redos.
            m_EndRotation_CS = Quaternion.Inverse(App.Scene.Pose.rotation) *
                               Quaternion.LookRotation(endForward_GS);
            m_StartRotation_CS = Knot.transform.localRotation;
            m_StartSpeed       = Knot.TangentMagnitude;

            // Cache our dance partner if the path loops and we're an end knot.
            if (m_Path.PathLoops)
            {
                if (m_KnotIndex == 0 || m_KnotIndex == m_Path.NumPositionKnots - 1)
                {
                    m_PartnerKnotIndex        = (m_KnotIndex == 0) ? (m_Path.NumPositionKnots - 1) : 0;
                    m_KnotLoopPartner         = m_Path.PositionKnots[m_PartnerKnotIndex];
                    m_PartnerStartRotation_CS = m_KnotLoopPartner.transform.localRotation;
                    m_PartnerStartSpeed       = m_KnotLoopPartner.TangentMagnitude;
                }
            }
        }
        public MoveConstrainedKnotCommand(CameraPath path, KnotDescriptor knotDesc, Quaternion rot_GS,
                                          bool mergesWithCreateCommand = false, bool final = false, BaseCommand parent = null)
            : base(knotDesc.knot, mergesWithCreateCommand, parent)
        {
            m_Path           = path;
            m_EndRotation_CS = Quaternion.Inverse(App.Scene.Pose.rotation) * rot_GS;
            m_EndT           = knotDesc.pathT.Value;
            m_Final          = final;

            m_StartRotation_CS = Knot.transform.localRotation;
            m_StartT           = Knot.PathT;
        }
  override protected void OnUserEndInteracting() {
    base.OnUserEndInteracting();

    if (!m_EatInteractingInput) {
      // Finalize our move commands with the current state of whatever's being actively modified.
      switch (m_ActiveKnot.knot.KnotType) {
      case CameraPathKnot.Type.Position:
        if (m_ActiveKnot.control == 0) {
          SketchMemoryScript.m_Instance.PerformAndRecordCommand(
              new MovePositionKnotCommand(m_Path, m_ActiveKnot,
                TrTransform.FromTransform(m_ActiveKnot.knot.transform), true));
        } else {
          CameraPathPositionKnot pk = m_ActiveKnot.knot as CameraPathPositionKnot;
          Vector3 knotFwd = m_ActiveKnot.knot.transform.forward;
          SketchMemoryScript.m_Instance.PerformAndRecordCommand(
              new ModifyPositionKnotCommand(
                m_Path, m_ActiveKnot, pk.TangentMagnitude, knotFwd, final:true));
        }
        break;
      case CameraPathKnot.Type.Rotation:
      case CameraPathKnot.Type.Speed:
      case CameraPathKnot.Type.Fov:
        // Reset any PreviewWidget overrides.
        m_ActiveKnot.knot.gameObject.SetActive(true);
        InputManager.Wand.Geometry.PreviewKnotHint.Activate(false);
        InputManager.Brush.Geometry.PreviewKnotHint.Activate(false);
        SketchControlsScript.m_Instance.CameraPathCaptureRig.OverridePreviewWidgetPathT(null);

        if (m_ActiveKnot.control == 0) {
          SketchMemoryScript.m_Instance.PerformAndRecordCommand(
              new MoveConstrainedKnotCommand(m_Path, m_ActiveKnot,
                m_ActiveKnot.knot.transform.rotation, final:true));
        } else {
          if (m_ActiveKnot.knot.KnotType == CameraPathKnot.Type.Speed) {
            CameraPathSpeedKnot sk = m_ActiveKnot.knot as CameraPathSpeedKnot;
            SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                new ModifySpeedKnotCommand(sk, sk.SpeedValue));
          } else if (m_ActiveKnot.knot.KnotType == CameraPathKnot.Type.Fov) {
            CameraPathFovKnot fk = m_ActiveKnot.knot as CameraPathFovKnot;
            SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                new ModifyFovKnotCommand(fk, fk.FovValue));
          }
        }
        break;
      }
    }

    m_KnotEditingLastInputXf = null;
    m_ActiveKnot = null;
  }
  override protected void Awake() {
    base.Awake();

    m_LastValidCollisionResults = new KnotDescriptor[(int)InputManager.ControllerName.Num];
    m_LastCollisionResults = new KnotDescriptor[(int)InputManager.ControllerName.Num];
    for (int i = 0; i < m_LastValidCollisionResults.Length; ++i) {
      m_LastValidCollisionResults[i] = new KnotDescriptor();
      m_LastCollisionResults[i] = new KnotDescriptor();
    }

    m_Path = new CameraPath(transform, m_KnotSegmentRadius,
        m_EndRadius, m_DefaultSpeed, m_DefaultFov);

    App.Scene.MainCanvas.PoseChanged += OnPoseChanged;
  }
        public MovePositionKnotCommand(CameraPath path, KnotDescriptor knotDesc,
                                       TrTransform endXf_GS, bool final = false, BaseCommand parent = null)
            : base((CameraPathPositionKnot)knotDesc.knot, false, parent)
        {
            m_Path                  = path;
            m_EndXf_CS              = App.Scene.Pose.inverse * endXf_GS;
            m_KnotIndex             = knotDesc.positionKnotIndex.Value;
            m_StartTangentMagnitude = Knot.TangentMagnitude;
            m_Final                 = final;

            if (Knot == null)
            {
                throw new ArgumentException("MovePositionKnotCommand requires CameraPathPositionKnot");
            }
            m_StartXf_CS = TrTransform.FromLocalTransform(Knot.transform);
        }
示例#7
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;
            }
        }
  override public float GetActivationScore(Vector3 point, InputManager.ControllerName name) {
    float nearestKnotScore = -1.0f;
    KnotDescriptor nearestResult = new KnotDescriptor();

    if (VideoRecorderUtils.ActiveVideoRecording == null &&
        !WidgetManager.m_Instance.WidgetsDormant &&
        !InputManager.m_Instance.GetCommand(InputManager.SketchCommands.Activate)) {
      // Check against all knots and put our results in storage bins.
      // Note that we're walking along the sorted lists instead of using m_Path.m_AllKnots.
      // This ensures the knotIndex stored in KnotCollisionResult is correct.
      for (int i = 0; i < m_Path.PositionKnots.Count; ++i) {
        int control = -1;
        CameraPathPositionKnot pk = m_Path.PositionKnots[i];
        float knotScore = pk.gameObject.activeSelf ?
            pk.CollisionWithPoint(point, out control) : -1.0f;
        if (knotScore > nearestKnotScore) {
          nearestResult.Set(pk, control, i, null);
          nearestKnotScore = knotScore;
        }
      }
      for (int i = 0; i < m_Path.RotationKnots.Count; ++i) {
        int control = -1;
        CameraPathRotationKnot rk = m_Path.RotationKnots[i];
        float knotScore = rk.CollisionWithPoint(point, out control);
        if (knotScore > nearestKnotScore) {
          nearestResult.Set(rk, control, null, rk.PathT);
          nearestKnotScore = knotScore;
        }
      }
      for (int i = 0; i < m_Path.SpeedKnots.Count; ++i) {
        int control = -1;
        CameraPathSpeedKnot sk = m_Path.SpeedKnots[i];
        float knotScore = sk.CollisionWithPoint(point, out control);
        if (knotScore > nearestKnotScore) {
          nearestResult.Set(sk, control, null, sk.PathT);
          nearestKnotScore = knotScore;
        }
      }
      for (int i = 0; i < m_Path.FovKnots.Count; ++i) {
        int control = -1;
        CameraPathFovKnot fk = m_Path.FovKnots[i];
        float knotScore = fk.CollisionWithPoint(point, out control);
        if (knotScore > nearestKnotScore) {
          nearestResult.Set(fk, control, null, fk.PathT);
          nearestKnotScore = knotScore;
        }
      }
    }

    bool brushOrWand = (name == InputManager.ControllerName.Brush) ||
        (name == InputManager.ControllerName.Wand);
    if (!m_UserInteracting) {
      if (brushOrWand) {
        m_LastCollisionResults[(int)name].Set(nearestResult);
        if ((nearestResult.knot != null) && (nearestResult.control != -1)) {
          m_LastValidCollisionResults[(int)name].Set(nearestResult);
        }
      }
    } else if (m_InteractingController != name && brushOrWand) {
      m_LastCollisionResults[(int)name].Set(null, CameraPathKnot.kDefaultControl, null, null);
    }
    return nearestKnotScore;
  }