// tests SceneObjects and Bounds public bool FindSceneRayIntersection(Ray3f ray, out AnyRayHit hit, bool bFindBoundsHits = true, Func <SceneObject, bool> sofilter = null) { hit = null; SORayHit bestSOHit = null; GameObjectRayHit bestBoundsHit = null; bool bHitSO = FindSORayIntersection(ray, out bestSOHit, sofilter); bool bHitBounds = bFindBoundsHits && FindWorldBoundsHit(ray, out bestBoundsHit); if (bHitSO && bHitBounds) { if (bestSOHit.fHitDist < bestBoundsHit.fHitDist) { hit = new AnyRayHit(bestSOHit); } else { hit = new AnyRayHit(bestBoundsHit, HitType.BoundsObjectHit); } } else if (bHitSO) { hit = new AnyRayHit(bestSOHit); } else if (bHitBounds) { hit = new AnyRayHit(bestBoundsHit, HitType.BoundsObjectHit); } return(hit != null); }
public static InputEvent Gamepad(InputState input, AnyRayHit hit = null) { return(new InputEvent() { ray = input.vGamepadWorldRay, side = CaptureSide.Any, device = InputDevice.Gamepad, input = input, hit = hit }); }
public AnyRayHit hit; // only set for WantsCapture / BeginCapture calls... public static InputEvent Mouse(InputState input, AnyRayHit hit = null) { return(new InputEvent() { ray = input.vMouseWorldRay, side = CaptureSide.Any, device = InputDevice.Mouse, input = input, hit = hit }); }
public static InputEvent Touch(InputState input, AnyRayHit hit = null) { return(new InputEvent() { ray = input.vTouchWorldRay, side = CaptureSide.Any, device = InputDevice.TabletFingers, input = input, hit = hit }); }
public static InputEvent Spatial(CaptureSide which, InputState input, AnyRayHit hit = null) { return(new InputEvent() { ray = (which == CaptureSide.Left) ? input.vLeftSpatialWorldRay : input.vRightSpatialWorldRay, side = which, device = InputDevice.AnySpatialDevice, input = input, hit = hit }); }
public UIRayHit(AnyRayHit init) { Debug.Assert(init.eType == HitType.SceneUIElementHit); hitPos = init.hitPos; hitNormal = init.hitNormal; fHitDist = init.fHitDist; hitGO = init.hitGO; hitUI = init.hitUI; }
public SORayHit(AnyRayHit init) { Debug.Assert(init.eType == HitType.SceneObjectHit); hitPos = init.hitPos; hitNormal = init.hitNormal; fHitDist = init.fHitDist; hitGO = init.hitGO; hitSO = init.hitSO; }
public UIRayHit(AnyRayHit init) { Util.gDevAssert(init.eType == HitType.SceneUIElementHit); hitPos = init.hitPos; hitNormal = init.hitNormal; hitIndex = init.hitIndex; fHitDist = init.fHitDist; hitGO = init.hitGO; hitUI = init.hitUI; }
public SORayHit(AnyRayHit init) { Util.gDevAssert(init.eType == HitType.SceneObjectHit); hitPos = init.hitPos; hitNormal = init.hitNormal; hitIndex = init.hitIndex; fHitDist = init.fHitDist; hitGO = init.hitGO; hitSO = init.hitSO; }
public bool FindAnyRayIntersection(Ray3f ray, out AnyRayHit hit) { hit = null; UIRayHit bestUIHit = null; if (FindUIRayIntersection(ray, out bestUIHit)) { hit = new AnyRayHit(bestUIHit); } return(hit != null); }
// does not test bounds! // [TODO] this is going to be weird... need to test bounds, I think public bool FindAnyRayIntersection(Ray3f ray, out AnyRayHit hit) { hit = null; UIRayHit bestUIHit = null; SORayHit bestSOHit = null; foreach (var ui in vUIElements) { UIRayHit uiHit; if (ui.FindRayIntersection(ray, out uiHit)) { if (bestUIHit == null || uiHit.fHitDist < bestUIHit.fHitDist) { bestUIHit = uiHit; } } } foreach (var so in VisibleSceneObjects) { if (!is_selectable(so)) { continue; } SORayHit objHit; if (so.FindRayIntersection(ray, out objHit)) { if (bestSOHit == null || objHit.fHitDist < bestSOHit.fHitDist) { bestSOHit = objHit; } } } if (bestUIHit != null) { if (bestSOHit == null || bestSOHit.fHitDist > bestUIHit.fHitDist) { hit = new AnyRayHit(bestUIHit); } else { hit = new AnyRayHit(bestSOHit); } } else if (bestSOHit != null) { hit = new AnyRayHit(bestSOHit); } return(hit != null); }
public void BeginDraw_Ray(Ray3f ray, AnyRayHit rayHit, int nStep) { CreateNewPrimitive(); Vector3f hitPos = rayHit.hitPos; Frame3f sceneW = scene.SceneFrame; if (rayHit.hitSO == null) { primStartW = sceneW; primStartW.Origin = hitPos; } else { if (scene.Context.TransformManager.ActiveFrameType == FrameType.WorldFrame) { primStartW = sceneW; primStartW.Origin = hitPos; } else if (rayHit.hitSO is PivotSO) { primStartW = (rayHit.hitSO as PivotSO).GetLocalFrame(CoordSpace.WorldCoords); primStartW.Origin = hitPos; } else if (rayHit.hitSO is PrimitiveSO) { // align with object frame as much as possible, given that we still want // to use hit normal... Frame3f objFrame = (rayHit.hitSO as PrimitiveSO).GetLocalFrame(CoordSpace.WorldCoords); int nBestAxis = MathUtil.MostParallelAxis(objFrame, rayHit.hitNormal); int nPerp = (nBestAxis + 1) % 3; primStartW = new Frame3f(hitPos, rayHit.hitNormal, 1); primStartW.ConstrainedAlignAxis(0, objFrame.GetAxis(nPerp), primStartW.Y); } else { primStartW = new Frame3f(hitPos, rayHit.hitNormal, 1); primStartW.ConstrainedAlignAxis(1, sceneW.Y, primStartW.Y); } } primitive.Frame = primStartW; primStartS = scene.ToSceneFrame(primStartW); }
void update_position(AnyRayHit hit) { int nNormalAxis = 1; int nUpAxis = 2; // as we drag object we will align Y with hit surface normal, but // we also want to constrain rotation so it is stable. Hence, we are // going to use world or local frame of target object to stabilize // rotation around normal. Frame3f hitF = TargetScene.SceneFrame; Vector3 targetAxis = hitF.GetAxis(1); if (hit.hitSO is SceneObject) { hitF = (hit.hitSO as SceneObject).GetLocalFrame(CoordSpace.WorldCoords); } bool bUseLocal = (TargetScene.Context.TransformManager.ActiveFrameType == FrameType.LocalFrame); if (bUseLocal && hit.hitSO is SceneObject) { hitF = (hit.hitSO as SceneObject).GetLocalFrame(CoordSpace.WorldCoords); targetAxis = hitF.GetAxis(1); } // if normal is parallel to target, this would become unstable, so use another axis if (Vector3.Dot(targetAxis, hit.hitNormal) > 0.99f) { targetAxis = hitF.GetAxis(0); } if (lastHitObject == null || hit.hitSO != lastHitObject) { lastHitF = new Frame3f(hit.hitPos, hit.hitNormal, nNormalAxis); lastHitF.ConstrainedAlignAxis(nUpAxis, targetAxis, lastHitF.GetAxis(nNormalAxis)); } else { lastHitF.Origin = hit.hitPos; lastHitF.AlignAxis(nNormalAxis, hit.hitNormal); lastHitF.ConstrainedAlignAxis(nUpAxis, targetAxis, lastHitF.GetAxis(nNormalAxis)); } lastHitObject = hit.hitSO; }
public bool FindAnyRayIntersection(Ray eyeRay, out AnyRayHit anyHit) { anyHit = new AnyRayHit(); AnyRayHit sceneHit = null; UIRayHit cockpitHit = null; if (scene.FindAnyRayIntersection(eyeRay, out sceneHit)) { anyHit = sceneHit; } if (cockpit.FindUIRayIntersection(eyeRay, out cockpitHit)) { if (cockpitHit.fHitDist < anyHit.fHitDist) { anyHit = new AnyRayHit(cockpitHit); } } return(anyHit.IsValid); }
// currently used to change cursor highlight in VR views. Perhaps the VR input Controllers // should do this themselves! public bool FindAnyRayIntersection(Ray eyeRay, out AnyRayHit anyHit) { anyHit = new AnyRayHit(); AnyRayHit sceneHit = null; UIRayHit cockpitHit = null; bool bCockpitOnly = (options.EnableCockpit && activeCockpit.GrabFocus); if (bCockpitOnly == false && scene.FindAnyRayIntersection(eyeRay, out sceneHit)) { anyHit = sceneHit; } if (Use2DCockpit == false && options.EnableCockpit && activeCockpit.FindUIRayIntersection(eyeRay, out cockpitHit)) { if (cockpitHit.fHitDist < anyHit.fHitDist) { anyHit = new AnyRayHit(cockpitHit); } } return(anyHit.IsValid); }
// FixedUpdate is called before any Update public void Update() { if (bFreezeCursor) { return; } // if we are in capture we freeze the cursor plane if (context.InCaptureMouse == false) { Vector3 camPos = camera.gameObject.transform.position; Vector3 forward = camera.gameObject.transform.forward; // orient Y-up plane so that it is in front of eye, perp to camera direction float fCursorDepth = 10.0f; fCursorSpeedNormalization = 1.0f; if (context.ActiveCockpit != null && context.ActiveCockpit.DefaultCursorDepth > 0) { fCursorDepth = context.ActiveCockpit.DefaultCursorDepth; // cursor speed will change depending on cursor plane distance, unless we normalize fCursorSpeedNormalization *= (fCursorDepth / 10.0f); } xformObject.transform.position = camPos + fCursorDepth * forward; xformObject.transform.LookAt(camera.gameObject.transform); xformObject.transform.RotateAround(xformObject.transform.position, xformObject.transform.right, 90); // that plane is the plane the mouse cursor moves on this.vCursorPlaneOrigin = xformObject.transform.position; this.vCursorPlaneRight = xformObject.transform.right; this.vCursorPlaneUp = xformObject.transform.forward; // because we rotated? weird... this.vRaySourcePosition = camera.transform.position; // if we were capturing, then plane was frozen and when we stop capturing, if // head moved, the cursor will pop to a new position (because it is stored in // local plane coords). So raycast through old cursor to hit new plane and figure // out new local coords (fCurPlaneX, fCurPlaneY) if (bWasInCaptureFreeze) { Frame3f newF = new Frame3f(vCursorPlaneOrigin, this.camera.transform.forward); Vector3 vPlaneHit = newF.RayPlaneIntersection(this.vRaySourcePosition, (vPlaneCursorPos - vRaySourcePosition).normalized, 2); fCurPlaneX = Vector3.Dot((vPlaneHit - vCursorPlaneOrigin), vCursorPlaneRight); fCurPlaneY = Vector3.Dot((vPlaneHit - vCursorPlaneOrigin), vCursorPlaneUp); bWasInCaptureFreeze = false; } } else { bWasInCaptureFreeze = true; } Vector2f mousePos = InputExtension.Get.Mouse.PositionDelta; Vector2f leftStick = InputExtension.Get.GamepadLeftStick.Position; float fX = mousePos.x + leftStick.x; float fY = mousePos.y + leftStick.y; // auto-hide cursor if it doesn't move for a while if (fX == 0 && fY == 0 && SceneGraphConfig.MouseCursorHideTimeout > 0) { if ((FPlatform.RealTime() - lastMouseEventTime) > SceneGraphConfig.MouseCursorHideTimeout) { Cursor.SetVisible(false); mouseInactiveState = true; } if (mouseInactiveState) { return; } } else { lastMouseEventTime = FPlatform.RealTime(); if (mouseInactiveState) { Cursor.SetVisible(true); } mouseInactiveState = false; } // update cursor location fCurPlaneX -= 0.3f * fX * fCursorSpeedNormalization; fCurPlaneY -= 0.3f * fY * fCursorSpeedNormalization; vPlaneCursorPos = vCursorPlaneOrigin + fCurPlaneX * vCursorPlaneRight + fCurPlaneY * vCursorPlaneUp; vSceneCursorPos = vPlaneCursorPos; // if cursor gets outside of viewpoint it is almost impossible to get it back. // So, if it goes too far out of view (45 deg here), we snap it back to the origin if (context.InCameraManipulation == false && context.InCaptureMouse == false) { float fAngle = Vector3.Angle((vPlaneCursorPos - camera.transform.position).normalized, camera.transform.forward); if (fAngle > 50.0f) { fCurPlaneX = fCurPlaneY = 0; vPlaneCursorPos = vCursorPlaneOrigin + fCurPlaneX * vCursorPlaneRight + fCurPlaneY * vCursorPlaneUp; vSceneCursorPos = vPlaneCursorPos; } } bool bHit = false; // [RMS] boundsHit cursor orientation could be useful for things where you are picking a point // on the ground plane (eg like drawing contours). Not sure how to toggle that though. // Just disabling for now... //bool bIsBoundsHit = false; if (context != null) { Ray r = new Ray(camera.transform.position, (vPlaneCursorPos - camera.transform.position).normalized); AnyRayHit hit = null; if (context.FindAnyRayIntersection(r, out hit)) { vSceneCursorPos = hit.hitPos; bHit = true; } else { GameObjectRayHit ghit = null; if (context.GetScene().FindWorldBoundsHit(r, out ghit)) { vSceneCursorPos = ghit.hitPos; //bIsBoundsHit = true; } } } this.CurrentCursorPosWorld = vPlaneCursorPos; this.CurrentCursorRaySourceWorld = this.vRaySourcePosition; Vector3 vEyeToPos = (vPlaneCursorPos - camera.transform.position).normalized; //if (bIsBoundsHit) { // Vector3 rotAxis = (vEyeToPos + camera.transform.right).normalized; // Cursor.transform.localRotation = Quaternion.AngleAxis(180.0f-45.0f, rotAxis); //} else { Quaternion rotAlignUp = Quaternion.FromToRotation(Vector3.up, camera.transform.up); Vector3 rotAxis = (vEyeToPos + camera.transform.right).normalized; Cursor.transform.localRotation = Quaternion.AngleAxis(45.0f, rotAxis) * rotAlignUp; //} Cursor.transform.position = vSceneCursorPos; if (context.InCaptureMouse) { Cursor.GetComponent <MeshRenderer> ().material = CursorCapturingMaterial; } else if (bHit) { Cursor.GetComponent <MeshRenderer> ().material = CursorHitMaterial; } else { Cursor.GetComponent <MeshRenderer> ().material = CursorDefaultMaterial; } Cursor.SetLayer(FPlatform.CursorLayer); // maintain a consistent visual size for 3D cursor sphere float fScaling = VRUtil.GetVRRadiusForVisualAngle(vSceneCursorPos, camera.transform.position, CursorVisualAngleInDegrees); Cursor.transform.localScale = new Vector3(fScaling, fScaling, fScaling); // update cursor Mesh useMesh = context.ToolManager.HasActiveTool(ToolSide.Right) ? activeToolCursorMesh : standardCursorMesh; if (Cursor.GetSharedMesh() != useMesh) { Cursor.SetSharedMesh(useMesh); } }
public bool HandleShortcuts() { bool bShiftDown = Input.GetKey(KeyCode.LeftShift); bool bCtrlDown = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); // ESCAPE CLEARS ACTIVE TOOL OR SELECTION if (Input.GetKeyUp(KeyCode.Escape)) { if (context.ToolManager.HasActiveTool(0) || context.ToolManager.HasActiveTool(1)) { context.ToolManager.DeactivateTool(0); context.ToolManager.DeactivateTool(1); } else if (context.Scene.Selected.Count > 0) { context.Scene.ClearSelection(); } return(true); } else if (Input.GetKeyUp(KeyCode.A)) { if (PanelGroup != null) { PanelGroup.SelectModulo(PanelGroup.Selected + 1); } return(true); } else if (Input.GetKeyUp(KeyCode.S)) { if (PanelGroup != null) { PanelGroup.SelectModulo(PanelGroup.Selected - 1); } return(true); // CENTER TARGET (??) } else if (Input.GetKeyUp(KeyCode.C)) { Ray3f cursorRay = context.MouseController.CurrentCursorWorldRay(); AnyRayHit hit = null; if (context.Scene.FindSceneRayIntersection(cursorRay, out hit)) { context.ActiveCamera.Manipulator().ScenePanFocus(context.Scene, context.ActiveCamera, hit.hitPos, true); } return(true); // TOGGLE FRAME TYPE } else if (Input.GetKeyUp(KeyCode.F)) { FrameType eCur = context.TransformManager.ActiveFrameType; context.TransformManager.ActiveFrameType = (eCur == FrameType.WorldFrame) ? FrameType.LocalFrame : FrameType.WorldFrame; return(true); // DROP A COPY } else if (Input.GetKeyUp(KeyCode.D)) { foreach (SceneObject so in context.Scene.Selected) { SceneObject copy = so.Duplicate(); if (copy != null) { // [TODO] could have a lighter record here because we can just re-run Duplicate() ? context.Scene.History.PushChange( new AddSOChange() { scene = context.Scene, so = copy }); context.Scene.History.PushInteractionCheckpoint(); } } return(true); // VISIBILITY (V HIDES, SHIFT+V SHOWS) } else if (Input.GetKeyUp(KeyCode.V)) { // show/hide (should be abstracted somehow?? instead of directly accessing GOs?) if (bShiftDown) { foreach (SceneObject so in context.Scene.SceneObjects) { so.RootGameObject.Show(); } } else { foreach (SceneObject so in context.Scene.Selected) { so.RootGameObject.Hide(); } context.Scene.ClearSelection(); } return(true); // UNDO } else if (bCtrlDown && Input.GetKeyUp(KeyCode.Z)) { context.Scene.History.InteractiveStepBack(); return(true); // REDO } else if (bCtrlDown && Input.GetKeyUp(KeyCode.Y)) { context.Scene.History.InteractiveStepForward(); return(true); // FILE OPEN } else if (bCtrlDown && Input.GetKeyUp(KeyCode.O)) { var cp = new FileOpenCockpit() { InitialPath = SceneGraphConfig.LastFileOpenPath }; context.PushCockpit(cp); return(true); // FILE SAVE } else if (bCtrlDown && Input.GetKeyUp(KeyCode.S)) { var cp = new FileSaveCockpit() { InitialPath = SceneGraphConfig.LastFileOpenPath }; context.PushCockpit(cp); return(true); // FILE IMPORT } else if (bCtrlDown && Input.GetKeyUp(KeyCode.I)) { var cp = new FileImportCockpit() { InitialPath = SceneGraphConfig.LastFileOpenPath }; context.PushCockpit(cp); return(true); // FILE EXPORT } else if (bCtrlDown && Input.GetKeyUp(KeyCode.E)) { var cp = new FileExportCockpit() { InitialPath = SceneGraphConfig.LastFileOpenPath }; context.PushCockpit(cp); return(true); // APPLY CURRENT TOOL IF POSSIBLE } else if (Input.GetKeyUp(KeyCode.Return)) { if (((context.ActiveInputDevice & InputDevice.Mouse) != 0) && context.ToolManager.HasActiveTool(ToolSide.Right) && context.ToolManager.ActiveRightTool.CanApply) { context.ToolManager.ActiveRightTool.Apply(); } return(true); } else if (Input.GetKeyUp(KeyCode.Alpha1)) { context.ToolManager.SetActiveToolType(SnapDrawPrimitivesTool.Identifier, 1); context.ToolManager.ActivateTool(1); return(true); } else if (Input.GetKeyUp(KeyCode.Alpha2)) { context.ToolManager.SetActiveToolType(DrawTubeTool.Identifier, 1); context.ToolManager.ActivateTool(1); return(true); } else if (Input.GetKeyUp(KeyCode.Alpha3)) { context.ToolManager.SetActiveToolType(DrawCurveTool.Identifier, 1); context.ToolManager.ActivateTool(1); return(true); } else if (Input.GetKeyUp(KeyCode.S)) { return(true); } else if (Input.GetKeyUp(KeyCode.Equals)) { if (Application.isEditor) { string sName = UniqueNames.GetNext("Screenshot"); sName = "C:\\scratch\\" + sName + ".png"; ScreenCapture.CaptureScreenshot(sName, 4); Debug.Log("Wrote screenshot " + sName); } return(true); } else { return(false); } }
// FixedUpdate is called before any Update public void Update() { if (CheckForSpatialInputActive() == false) { return; } Vector3 rootPos = spatialCamRig.transform.position; SpatialDevice[] hands = { Left, Right }; for (int i = 0; i < 2; ++i) { SpatialDevice h = hands[i]; h.CursorActive = VRPlatform.IsSpatialDeviceTracked(i); if (h.CursorActive) { h.Hand.Show(); h.Cursor.Show(); Vector3 handPos = VRPlatform.GetLocalControllerPosition(i); Quaternion handRot = VRPlatform.GetLocalControllerRotation(i); h.AbsoluteHandFrame = new Frame3f(rootPos + handPos, handRot); float fPositionT = 0.2f; float fRotationT = 0.2f; //float fPositionT = 1.0f; //float fRotationT = 1.0f; if (h.SmoothedHandFrame.Origin != Vector3f.Zero) { Vector3 new_origin = Vector3.Lerp(h.SmoothedHandFrame.Origin, h.AbsoluteHandFrame.Origin, fPositionT); Quaternion new_rotation = Quaternion.Slerp(h.SmoothedHandFrame.Rotation, h.AbsoluteHandFrame.Rotation, fRotationT); h.SmoothedHandFrame = new Frame3f(new_origin, new_rotation); } else { h.SmoothedHandFrame = h.AbsoluteHandFrame; } h.Hand.transform.position = h.SmoothedHandFrame.Origin; h.Hand.transform.rotation = h.SmoothedHandFrame.Rotation * (Quaternionf)handGeomRotation; h.CursorRay = new Ray(h.SmoothedHandFrame.Origin, (h.SmoothedHandFrame.Rotation * Vector3.forward).Normalized); if (Mathf.Abs(h.CursorRay.direction.sqrMagnitude - 1.0f) > 0.001f) { DebugUtil.Log(2, "SpatialInputController.Update - invlaid cursor ray! rotation was {0}", h.SmoothedHandFrame.Rotation); h.CursorRay = new Ray(h.SmoothedHandFrame.Origin, Vector3.up); } // raycast into scene to see if we hit object, UI, bounds, etc. bool bHit = false; if (context != null) { // want to hit-test active gizmo first, because that has hit-priority if (context.TransformManager.HaveActiveGizmo) { UIRayHit uiHit = null; if (context.TransformManager.ActiveGizmo.FindRayIntersection(h.CursorRay, out uiHit)) { h.RayHitPos = uiHit.hitPos; bHit = true; } } // next we tested scene if (bHit == false) { AnyRayHit hit = null; if (context.FindAnyRayIntersection(h.CursorRay, out hit)) { h.RayHitPos = hit.hitPos; bHit = true; } } // finally test worldbounds if (bHit == false) { GameObjectRayHit ghit = null; if (context.GetScene().FindWorldBoundsHit(h.CursorRay, out ghit)) { h.RayHitPos = ghit.hitPos; } } } // if not, plane cursor on view-perp plane centered at last hit pos, // otherwise it will be stuck/disappear if (bHit == false) { Frame3f f = new Frame3f(h.RayHitPos, camera.transform.forward); h.RayHitPos = f.RayPlaneIntersection(h.CursorRay.origin, h.CursorRay.direction, 2); } h.Cursor.transform.position = h.RayHitPos; //if (scene.InCapture) // MaterialUtil.SetMaterial(h.Cursor, h.CursorCapturingMaterial); //else if (bHit) { MaterialUtil.SetMaterial(h.Cursor, h.CursorHitMaterial); } else { MaterialUtil.SetMaterial(h.Cursor, h.CursorDefaultMaterial); } // maintain a consistent visual size for 3D cursor sphere float fScaling = VRUtil.GetVRRadiusForVisualAngle(h.RayHitPos, camera.transform.position, CursorVisualAngleInDegrees); h.Cursor.transform.localScale = fScaling * Vector3.one; // orient cursor so it is tilted like a 2D cursor, but per-hand Vector3 cursor_right = Vector3.Cross(camera.transform.up, h.CursorRay.direction); Vector3 cursor_fw = Vector3.Cross(cursor_right, camera.transform.up); float rotSign = (h == Right) ? 1.0f : -1.0f; Vector3 pointDir = (camera.transform.up + cursor_fw - 0.5f * rotSign * cursor_right).normalized; h.Cursor.transform.localRotation = Quaternion.FromToRotation(Vector3.up, pointDir); // update laser line if (h.Laser != null) { float hDist = (h.RayHitPos - h.CursorRay.origin).magnitude; Vector3 p0 = h.RayHitPos - 0.9f * hDist * h.CursorRay.direction; Vector3 p1 = h.RayHitPos + 100.0f * h.CursorRay.direction; float r0 = VRUtil.GetVRRadiusForVisualAngle(p0, camera.transform.position, 0.5f); h.LaserRen.SetPosition(0, p0); h.LaserRen.SetPosition(1, p1); h.LaserRen.startWidth = h.LaserRen.endWidth = r0; } // udpate cursor Mesh useMesh = context.ToolManager.HasActiveTool(i) ? activeToolCursorMesh : standardCursorMesh; if (h.Cursor.GetSharedMesh() != useMesh) { h.Cursor.SetSharedMesh(useMesh); } } else { h.Hand.Hide(); h.Cursor.Hide(); } } }
override public bool UpdateCapture(InputEvent e) { if (eState == CaptureState.ClickType && FindHitGO(e.ray) != null) { return(true); } // otherwise we fall into drag state eState = CaptureState.DragType; if (newPrimitive == null) { newPrimitive = CreatePrimitive(); fPrimScale = 1.0f; if (newPrimitive is PivotSO) { fPrimShift = 0.0f; } else { if (newPrimitive is PrimitiveSO) { if (SavedSettings.Restore("DropPrimButton_scale") != null) { fPrimScale = (float)SavedSettings.Restore("DropPrimButton_scale"); newPrimitive.SetLocalScale(fPrimScale * Vector3f.One); } } fPrimShift = newPrimitive.GetLocalBoundingBox().Extents[1] * TargetScene.GetSceneScale(); } // [RMS] this is kind of cheating - we are going to tell this SO // it is part of the scene, but not actually put it in the scene. // This is because sometimes the SO needs to query the scene/camera // (eg for pivot resizing) TargetScene.ReparentSceneObject(newPrimitive, false); newPrimitive.SetScene(TargetScene); lastHitF = UnityUtil.GetGameObjectFrame(TargetScene.RootGameObject, CoordSpace.WorldCoords); newPrimitive.SetLocalFrame(lastHitF.Translated(fPrimShift, 1), CoordSpace.WorldCoords); } // [RMS] only Touch for this?? if (InputState.IsDevice(e.device, InputDevice.OculusTouch) && newPrimitive is PrimitiveSO) { Vector2f vStick = e.input.StickDelta2D((int)e.side); if (vStick[1] != 0) { fPrimScale = fPrimScale * (1.0f + vStick[1] * 0.1f); fPrimScale = MathUtil.Clamp(fPrimScale, 0.01f, 10.0f); newPrimitive.SetLocalScale(fPrimScale * Vector3f.One); fPrimShift = newPrimitive.GetLocalBoundingBox().Extents[1] * TargetScene.GetSceneScale(); } } AnyRayHit hit = null; if (TargetScene.FindSceneRayIntersection(e.ray, out hit)) { update_position(hit); newPrimitive.SetLocalFrame(lastHitF.Translated(fPrimShift, 1), CoordSpace.WorldCoords); } // [RMS] have to do this because prim is not part of scene yet, // and things like pivots need to be resized if (newPrimitive != null) { newPrimitive.PreRender(); } return(true); }
public void BeginDraw_Spatial(Ray3f ray, AnyRayHit rayHit, Frame3f handFrame, int nStep) { BeginDraw_Ray(ray, rayHit, nStep); }
// FixedUpdate is called before any Update public void Update() { // if we are in capture we freeze the cursor plane if (Scene.InCapture == false) { Vector3 camPos = camera.gameObject.transform.position; Vector3 forward = camera.gameObject.transform.forward; // orient Y-up plane so that it is in front of eye, perp to camera direction xformObject.transform.position = camPos + 10 * forward; xformObject.transform.LookAt(camera.gameObject.transform); xformObject.transform.RotateAround(xformObject.transform.position, xformObject.transform.right, 90); // that plane is the plane the mouse cursor moves on this.vCursorPlaneOrigin = xformObject.transform.position; this.vCursorPlaneRight = xformObject.transform.right; this.vCursorPlaneForward = xformObject.transform.forward; this.vRaySourcePosition = camera.transform.position; } Vector3 curPos = new Vector3(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"), 0); dx -= 0.3f * curPos.x; dy -= 0.3f * curPos.y; vPlaneCursorPos = vCursorPlaneOrigin + dx * vCursorPlaneRight + dy * vCursorPlaneForward; vSceneCursorPos = vPlaneCursorPos; bool bHit = false; if (Scene != null) { Ray r = new Ray(camera.transform.position, (vPlaneCursorPos - camera.transform.position).normalized); AnyRayHit hit = null; if (Scene.FindAnyRayIntersection(r, out hit)) { vSceneCursorPos = hit.hitPos; bHit = true; } else { GameObjectRayHit ghit = null; if (Scene.GetScene().FindWorldBoundsHit(r, out ghit)) { vSceneCursorPos = ghit.hitPos; } } } this.CurrentCursorPosWorld = vPlaneCursorPos; this.CurrentCursorRaySourceWorld = this.vRaySourcePosition; Cursor.transform.position = vSceneCursorPos; if (Scene.InCapture) { Cursor.GetComponent <MeshRenderer> ().material = CursorCapturingMaterial; } else if (bHit) { Cursor.GetComponent <MeshRenderer> ().material = CursorHitMaterial; } else { Cursor.GetComponent <MeshRenderer> ().material = CursorDefaultMaterial; } Cursor.layer = (bHit || Scene.InCapture) ? LayerMask.NameToLayer(SceneGraphConfig.WidgetOverlayLayerName) : 0; // maintain a consistent visual size for 3D cursor sphere float fScaling = MathUtil.GetVRRadiusForVisualAngle(vSceneCursorPos, camera.transform.position, CursorVisualAngleInDegrees); Cursor.transform.localScale = new Vector3(fScaling, fScaling, fScaling); }