private static void StylusPress(StylusState state) { if (_currentPointIdx == -1) { Console.WriteLine($"{state.Tilt.X}\t{state.Tilt.Y}\t{state.DevicePosition.X}\t{state.DevicePosition.Y}"); return; } var currentPoint = _referencePoints[_currentPointIdx]; CalibrationPoints[currentPoint] = state.Position; _currentPointIdx++; if (_currentPointIdx == _referencePoints.Length) { _currentPointIdx = -1; OutputDevices.Display.Draw(_frame.Clone(context => context.DrawPolygon(Color.Black, 2, Square(10, _referencePoints[4], 45)) .DrawPolygon(Color.Black, 1, Square(1, _referencePoints[4])) ), _frame.Bounds(), Point.Empty, waveformMode: WaveformMode.Auto); } else { OutputDevices.Display.Draw(_frame.Clone(DrawCalibrationMarker), _frame.Bounds(), Point.Empty, waveformMode: WaveformMode.Auto); } }
public void ConsumeMove(StylusState stylus) { var eligibleControls = GetControlsAtPoint(stylus.GetDevicePosition()); foreach (var control in eligibleControls) { control.OnMove(stylus); } }
public void ConsumeRelease(StylusState stylus, DigitizerEventKeyCode code) { var eligibleControls = GetControlsAtPoint(stylus.GetDevicePosition()); foreach (var control in eligibleControls) { control.OnRelease(stylus, code); } }
public void ConsumePress(StylusState stylus, DigitizerEventKeyCode code) { var eligibleControls = GetControlsAtPoint(stylus.DevicePosition); foreach (var control in eligibleControls) { control.OnPress(stylus, code); } }
void Update() { #region zspace #endregion if (PlateformData.GetCurrentPlatform() == PlatformType.zSpace) { bool isButtonPressed = ViveInput.GetPress(HandRole.RightHand, ControllerButton.Trigger) || ViveInput.GetPress(HandRole.RightHand, ControllerButton.Grip) || ViveInput.GetPress(HandRole.RightHand, ControllerButton.PadTouch); Vector3 rayDir = raycaster.BreakPoints[1] - raycaster.BreakPoints[0]; switch (StylusFunctionState) { case StylusState.Idle: { // Perform a raycast on the entire scene to determine what the // stylus is currently colliding with. RaycastHit hit; if (Physics.Raycast(raycaster.BreakPoints[0], rayDir, out hit)) { // If the front stylus button was pressed, initiate a grab. if (isButtonPressed && !_wasButtonPressed) { // Begin the grab. this.BeginGrab(hit.collider.gameObject, hit.distance, raycaster.BreakPoints[0], this.transform.rotation); StylusFunctionState = StylusState.Grab; } } } break; case StylusState.Grab: { // Update the grab. this.UpdateGrab(raycaster.BreakPoints[0], this.transform.rotation); // End the grab if the front stylus button was released. if (!isButtonPressed && _wasButtonPressed) { StylusFunctionState = StylusState.Idle; } } break; default: break; } // Cache state for next frame. _wasButtonPressed = isButtonPressed; } }
void Update() { ZCore.Pose pose = _core.GetTargetPose(ZCore.TargetType.Primary, ZCore.CoordinateSpace.World); bool isButtonPressed = _core.IsTargetButtonPressed(ZCore.TargetType.Primary, 0) || _core.IsTargetButtonPressed(ZCore.TargetType.Primary, 1); switch (_stylusState) { case StylusState.Idle: { _stylusBeamLength = DEFAULT_STYLUS_BEAM_LENGTH; sceneManage.CurrentGrabPart = null; //对整个场景进行碰撞检测确定与笔进行碰撞的物体 RaycastHit hit; if (Physics.Raycast(pose.Position, pose.Direction, out hit)) { // 更新zSpace操作笔的长度 _stylusBeamLength = hit.distance / _core.ViewerScale; // 如果zSpace触控笔主按钮按下,开始抓取物体。 if (isButtonPressed && !_wasButtonPressed) { // 开始抓取 this.BeginGrab(hit.collider.gameObject, hit.distance, pose.Position, pose.Rotation); _stylusState = StylusState.Grab; if (lastHoverPart != null && lastHoverPart.GetComponent <FlashingController>() != null) { Destroy(lastHoverPart.GetComponent <FlashingController>()); Destroy(lastHoverPart.GetComponent <Highlighter>()); lastHoverPart = null; } } else { currentHoverPart = hit.collider.gameObject; if (lastHoverPart != currentHoverPart) { if (lastHoverPart != null && lastHoverPart.GetComponent <FlashingController>() != null) { Destroy(lastHoverPart.GetComponent <FlashingController>()); Destroy(lastHoverPart.GetComponent <Highlighter>()); } lastHoverPart = currentHoverPart; FlashingController fla = currentHoverPart.AddComponent <FlashingController>(); fla.flashingDelay = 0; fla.flashingFrequency = 1; } } } else { if (lastHoverPart != null && lastHoverPart.GetComponent <FlashingController>() != null) { Destroy(lastHoverPart.GetComponent <FlashingController>()); Destroy(lastHoverPart.GetComponent <Highlighter>()); lastHoverPart = null; } } } break; case StylusState.Grab: { // Update the grab. this.UpdateGrab(pose.Position, pose.Rotation); // End the grab if the front stylus button was released. if (!isButtonPressed && _wasButtonPressed) { _stylusState = StylusState.Idle; } } break; default: break; } // 更新zSpace操作笔的位置以及旋转参数。 this.UpdateStylusBeam(pose.Position, pose.Direction); // 为下一帧缓存点击状态. _wasButtonPressed = isButtonPressed; }
// 将更新眼镜和笔数据放在FixedUpdate里面是为了保证数据更新速度大于画线的速度 ,防止线跳动情况发生。但是这样会牺牲一定的帧数 void Update() { ///if there is no line renderer of stylus then search for it if (stylusObject != null && stylusRenderer == null) { stylusRenderer = stylusObject.transform.GetComponent <LineRenderer>(); } //编辑器状态执行逻辑 if (Application.isEditor && !Application.isPlaying) { ///Update Stylus length here if (stylusRenderer != null) { if (stylusRenderer.startWidth != stylusWidth || (stylusRenderer.GetPosition(1) != stylusRenderer.transform.position + (stylusRenderer.transform.forward * 0.1f * stylusLength))) { stylusRenderer.startWidth = stylusWidth; stylusRenderer.endWidth = stylusWidth; stylusRenderer.SetPosition(0, stylusRenderer.transform.position); stylusRenderer.SetPosition(1, stylusRenderer.transform.position + (stylusRenderer.transform.forward * 0.1f * stylusLength)); //(we are reciveing direction in 0.1f scale and forward transform is 1) } } } if (Application.isPlaying && voxelData.isRecievedData) { //获取按钮数据 UpdateButton(voxelData.keyType); //获取视觉计算后的两个点的数据 if (leftCamera != null && rightCamera != null) { if (stylusObject != null) { stylusHead = stylusObject.transform.GetChild(0).gameObject; stylusScaleInital = stylusObject.transform.localScale; } if (isHeadTrackingEnabled) { int isTrackingGlasses = voxelData.isTrackingGlasses; glassPosition = new double[] { voxelData.headPosition[0], voxelData.headPosition[1], voxelData.headPosition[2] }; if (currentScreenMode == ScreenMode.ScreenTilt) { WireDraw.transform.localRotation = Quaternion.Euler(voxelData.screenAngle, 0, 0); } if (stereoCameraInstance == null) { stereoCameraInstance = GetComponentInChildren <StereoCamera>(); } if (!isFirstRun) { if (isTrackingGlasses == 1) { stereoCameraInstance.stereoMode = StereoCamera.StereoModes.Active; } else { stereoCameraInstance.stereoMode = StereoCamera.StereoModes.Disabled; } } else { isFirstRun = false; } UpdateDataToMeter(ref glassPosition); //将单位从毫米换算成米 UpdateCameraPose(new Vector3((float)glassPosition[0] - 0.26f, -(float)glassPosition[1] + 0.05f, (float)glassPosition[2])); //更新眼镜位置 } if (currentScreenMode == ScreenMode.LookAt) { sceneCamera.LookAt(centerObject); } } stylusPositionOne = new double[] { voxelData.penAtPt1[0], voxelData.penAtPt1[1], voxelData.penAtPt1[2], voxelData.penAtPt1[3] }; stylusPositionTwo = new double[] { voxelData.penAtPt2[0], voxelData.penAtPt2[1], voxelData.penAtPt2[2], voxelData.penAtPt2[3] }; Vector3 stylusFinalPointOne, stylusFinalPointTwo; bool isTherePoint = VoxelStationMathSdk.Math.UpdatePenPose(stylusPositionOne, stylusPositionTwo, leftCamera, rightCamera, out stylusFinalPointOne, out stylusFinalPointTwo);//两条射线是否有交点 if (isTherePoint) { UpdatePose(stylusFinalPointOne, stylusFinalPointTwo);//更新笔的位置 } //Note: Idle to hover state can be ignored for assigning delegates //but hover to grab is a must if a user want to pick a object RaycastHit hit = new RaycastHit(); switch (stylusState) { case StylusState.Idle: { // Perform a raycast on the entire scene to determine what the // stylus is currently colliding with. STYLUS_BEAM_WIDTH = stylusWidth * viewSize; if (Physics.Raycast(pose.Position, pose.Direction, out hit)) { // Update the stylus beam length. STYLUS_BEAM_LENGTH = hit.distance; switch (hit.collider.tag) { case "UI": stylusState = StylusState.Hover; if (this.onStylusHoverUIBegin != null) { //Calls on hover function this.onStylusHoverUIBegin(new ActionEventInfo(hit.collider.gameObject)); _UISelection = hit.collider.gameObject; } break; case "Grab": stylusState = StylusState.Hover; if (this.onStylusHoverObjectBegin != null) { previousModelSelection = hit.collider.gameObject; this.onStylusHoverObjectBegin(new ActionEventInfo(hit.collider.gameObject)); previousModelSelection = hit.collider.gameObject; } break; default: break; } } else { STYLUS_BEAM_LENGTH = stylusLength; } } break; case StylusState.Hover: //PreviousSelection if (Physics.Raycast(pose.Position, pose.Direction, out hit)) { // Update the stylus beam length. STYLUS_BEAM_LENGTH = hit.distance; switch (hit.collider.tag) { case "UI": //If user pointer came directly from model to UI //then call object hover end and reset to idle if (previousModelSelection != null && this.onStylusHoverObjectEnd != null) { this.onStylusHoverObjectEnd(new ActionEventInfo(previousModelSelection)); previousModelSelection = null; stylusState = StylusState.Idle; } if (isButtonOnePressed && !wasButtonOnePressed && this.onStylusButtonOnePressedUI != null) { this.onStylusButtonOnePressedUI(new ActionEventInfo(hit.collider.gameObject)); } break; case "Grab": //if user pointer came from UI to model directly //then all end on hover of UI and reset to idle if (_UISelection != null && this.onStylusHoverUIEnd != null) { //Call the function to say the UI hover event is over this.onStylusHoverUIEnd(new ActionEventInfo(_UISelection)); _UISelection = null; stylusState = StylusState.Idle; } //Call the grab function if (isButtonOnePressed && !wasButtonOnePressed && this.onStylusGrabObjectBegin != null) { grabObject = hit.collider.gameObject; this.onStylusGrabObjectBegin(new ActionEventInfo(grabObject, pose, STYLUS_BEAM_LENGTH)); stylusState = StylusState.Grab; } break; default: break; } } else { if (this.onStylusHoverObjectEnd != null) { this.onStylusHoverObjectEnd(new ActionEventInfo(previousModelSelection)); } stylusState = StylusState.Idle; previousModelSelection = null; STYLUS_BEAM_LENGTH = stylusLength * viewSize; } break; case StylusState.Grab: { if (grabObject.tag.Equals("Grab") && this.onStylusGrabObjectUpdate != null) { ///Update the grab. ///this.UpdateGrab(pose.Position, pose.Rotation); ///calls the update for model this.onStylusGrabObjectUpdate(new ActionEventInfo(grabObject, pose, STYLUS_BEAM_LENGTH)); } /// End the grab if the front stylus button was released. if (!isButtonOnePressed && wasButtonOnePressed) { ///Calls the end grab delegate to stop movin model if (this.onStylusGrabObjectEnd != null) { this.onStylusGrabObjectEnd(new ActionEventInfo(grabObject)); } stylusState = StylusState.Hover; grabObject = null; } } break; default: break; } //if we have previously hovered over UI and now the hit.collider is giving empty response then we need to set slection as Idle //and notify the call back function if (hit.collider == null) { if (_UISelection != null && this.onStylusHoverUIEnd != null) { //Call the function to say the UI hover event is over this.onStylusHoverUIEnd(new ActionEventInfo(_UISelection)); _UISelection = null; stylusState = StylusState.Idle; } if (previousModelSelection != null && (stylusState != StylusState.Grab && stylusState != StylusState.Hover)) { if (this.onStylusHoverObjectEnd != null) { this.onStylusHoverObjectEnd(new ActionEventInfo(previousModelSelection)); } previousModelSelection = null; stylusState = StylusState.Idle; } } // Update the stylus beam. this.UpdateStylus(pose.Position, pose.Direction); // Cache state for next frame. wasButtonOnePressed = isButtonOnePressed; } #if !UNITY_EDITOR //鼠标隐藏函数,通过操作inspector面板执行 UpdateMouseAutoHide(); #endif //键盘热键相关逻辑 HotKey(); }
static void Main(string[] args) { var logger = Lumberjack.CreateLogger("Sandbox"); var threadLock = new ManualResetEventSlim(); var screen = OutputDevices.Display; // var w = new Window(screen.VisibleWidth, screen.VisibleHeight); // w.Update += WindowUpdate; // // InputDevices.Digitizer.Pressed += (sender, code) => w.ConsumePress(InputDevices.Digitizer.State, code); // InputDevices.Digitizer.Released += (sender, code) => w.ConsumeRelease(InputDevices.Digitizer.State, code); // InputDevices.Digitizer.StylusUpdate += (sender, state) => w.ConsumeMove(state); // // InputDevices.Touchscreen.Pressed += (sender, finger) => w.ConsumePress(finger); // InputDevices.Touchscreen.Released += (sender, finger) => w.ConsumeRelease(finger); // InputDevices.Touchscreen.Moved += (sender, finger) => w.ConsumeMove(finger); // // var mainPage = w.CreatePage<MainPage>(); // // logger.Info("Showing main page"); // w.ShowPage(mainPage); var center = new PointF(screen.VisibleWidth / 2f, screen.VisibleHeight / 2f); var margin = 50; _referencePoints = new[] { new PointF(margin, margin), new PointF(center.X, margin), new PointF(screen.VisibleWidth - margin, margin), new PointF(margin, center.Y), new PointF(center.X, center.Y), new PointF(screen.VisibleWidth - margin, center.Y), new PointF(margin, screen.VisibleHeight - margin), new PointF(center.X, screen.VisibleHeight - margin), new PointF(screen.VisibleWidth - margin, screen.VisibleHeight - margin), }; _frame = new Image <Rgb24>(screen.VisibleWidth, screen.VisibleHeight); _frame.Mutate(context => context .SetGraphicsOptions(options => options.Antialias = false) .Clear(Color.White) // .DrawPolygon(Color.Black, 1, Square(5, center, 45)) // .DrawPolygon(Color.Black, 1, Square(1, center)) ); OutputDevices.Display.Draw(_frame, _frame.Bounds(), Point.Empty, waveformMode: WaveformMode.Auto); // InputDevices.Digitizer.Calibrator.Calibration = BuiltinStylusCalibrations.FujitsuLifebookStylus; StylusState prevState = null; var time = DateTime.Now; InputDevices.Digitizer.StylusUpdate += (sender, state) => { if (prevState == null) { prevState = state; return; } if (((prevState.Pressure < 10 && state.Pressure >= 10) || _currentPointIdx == -1) && time <= DateTime.Now) { StylusPress(state); time = DateTime.Now + TimeSpan.FromMilliseconds(50); } prevState = state; }; OutputDevices.Display.Draw(_frame.Clone(DrawCalibrationMarker), _frame.Bounds(), Point.Empty, waveformMode: WaveformMode.Auto); threadLock.Wait(); }
public StylusPressEventArgs(StylusState stylus, DigitizerEventKeyCode code) { Stylus = stylus; Code = code; }