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); }
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; }