// tests SceneObjects and Bounds public bool FindSceneRayIntersection(Ray ray, out AnyRayHit hit, Func <SceneObject, bool> sofilter = null) { hit = null; SORayHit bestSOHit = null; GameObjectRayHit bestBoundsHit = null; bool bHitSO = FindSORayIntersection(ray, out bestSOHit, sofilter); bool bHitBounds = 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); }
// rayhit-test a GameObject, handling collider enable/disable public static bool FindGORayIntersection(Ray ray, GameObject go, out GameObjectRayHit hit) { hit = null; Collider collider = go.GetComponent <Collider>(); if (collider == null) { return(false); } bool bIsEnabled = collider.enabled; collider.enabled = true; RaycastHit hitInfo; if (collider.Raycast(ray, out hitInfo, Mathf.Infinity)) { hit = new GameObjectRayHit(); hit.fHitDist = hitInfo.distance; hit.hitPos = hitInfo.point; hit.hitNormal = hitInfo.normal; hit.hitGO = go; } collider.enabled = bIsEnabled; return(hit != null); }
override public bool FindRayIntersection(Ray3f ray, out SORayHit hit) { hit = null; GameObjectRayHit hitg = null; if (FindGORayIntersection(ray, out hitg)) { if (hitg.hitGO != null) { hit = new SORayHit(hitg, this); // compute analytic normal on cylinder body if (hitg.hitGO == body) { Vector3 up = this.RootGameObject.transform.rotation * Vector3.up; Vector3 l = hitg.hitPos - this.RootGameObject.transform.position; l -= Vector3.Dot(l, up) * up; l.Normalize(); hit.hitNormal = l; } return(true); } } return(false); }
// override and return true to get hover events public virtual bool FindHoverRayIntersection(Ray3f ray, out UIRayHit hit) { hit = null; if (Enabled == false) { return(false); } if (EnableHover == false) { return(false); } GameObjectRayHit hitg = null; if (FindGORayIntersection(ray, out hitg)) { if (hitg.hitGO != null) { hit = new UIRayHit(hitg, this); return(true); } } return(false); }
public AnyRayHit(GameObjectRayHit init, SceneUIElement ui) { hitPos = init.hitPos; fHitDist = init.fHitDist; hitGO = init.hitGO; eType = HitType.SceneUIElementHit; hitUI = ui; }
public UIRayHit(GameObjectRayHit init, SceneUIElement ui) { hitPos = init.hitPos; hitNormal = init.hitNormal; fHitDist = init.fHitDist; hitGO = init.hitGO; hitUI = ui; }
public SORayHit(GameObjectRayHit init, SceneObject so) { hitPos = init.hitPos; hitNormal = init.hitNormal; fHitDist = init.fHitDist; hitGO = init.hitGO; hitSO = so; }
public AnyRayHit(GameObjectRayHit init, SceneObject so) { hitPos = init.hitPos; fHitDist = init.fHitDist; hitGO = init.hitGO; eType = HitType.SceneObjectHit; hitSO = so; }
public AnyRayHit(GameObjectRayHit init, HitType eType) { Debug.Assert(eType == HitType.BoundsObjectHit); hitPos = init.hitPos; hitNormal = init.hitNormal; fHitDist = init.fHitDist; hitGO = init.hitGO; this.eType = eType; }
public AnyRayHit(GameObjectRayHit init, HitType eType) { Util.gDevAssert(eType == HitType.BoundsObjectHit); hitPos = init.hitPos; hitNormal = init.hitNormal; hitIndex = init.hitIndex; fHitDist = init.fHitDist; hitGO = init.hitGO; this.eType = eType; }
virtual public bool FindRayIntersection(Ray3f ray, out UIRayHit hit) { hit = null; GameObjectRayHit hitg = null; if (is_interactive && FindGORayIntersection(ray, out hitg)) { if (hitg.hitGO != null) { hit = new UIRayHit(hitg, this); return(true); } } return(false); }
public bool FindRayIntersection(Ray ray, out SORayHit hit) { hit = null; GameObjectRayHit hitg = null; if (FindGORayIntersection(ray, out hitg)) { if (hitg.hitGO != null) { hit = new SORayHit(hitg, this); return(true); } } return(false); }
public virtual bool FindRayIntersection(UnityEngine.Ray ray, out UIRayHit hit) { hit = null; GameObjectRayHit hitg = null; if (FindGORayIntersection(ray, out hitg)) { if (hitg.hitGO != null) { hit = new UIRayHit(hitg, this); return(true); } } return(false); }
public bool FindWorldBoundsHit(Ray3f ray, out GameObjectRayHit hit) { hit = null; foreach (var go in this.vBoundsObjects) { GameObjectRayHit myHit = null; if (UnityUtil.FindGORayIntersection(ray, go, out myHit)) { if (hit == null || myHit.fHitDist < hit.fHitDist) { hit = myHit; } } } return(hit != null); }
protected void standard_begin_capture(InputEvent e, GameObjectRayHit hit) { if (handleGO.IsSameOrChild(hit.hitGO)) { onHandlePress(e, hit.hitPos); eInterMode = InteractionMode.InHandleDrag; vStartHitW = hit.hitPos; vHandleStartW = handleGO.GetWorldFrame(); } else if (backgroundGO.IsSameOrChild(hit.hitGO)) { onSliderbarPress(e, hit.hitPos); eInterMode = InteractionMode.InPressDrag; vStartHitW = hit.hitPos; vHandleStartW = handleGO.GetWorldFrame(); } }
override public bool FindRayIntersection(Ray3f ray, out SORayHit hit) { hit = null; GameObjectRayHit hitg = null; if (FindGORayIntersection(ray, out hitg)) { if (hitg.hitGO != null) { hit = new SORayHit(hitg, this); // compute analytic normal hit.hitNormal = (hit.hitPos - this.RootGameObject.GetPosition()).Normalized; return(true); } } return(false); }
public virtual bool FindGORayIntersection(Ray ray, out GameObjectRayHit hit, Func <GameObject, bool> FilterF = null) { hit = new GameObjectRayHit(); RaycastHit hitInfo; // [RMS] this keeps popping up...why?? //if (Mathf.Abs(ray.direction.sqrMagnitude - 1.0f) > 0.001) { // DebugUtil.Log(2, "FindGORayIntersection: ray direction is not normalized! {0} {1}", ray.direction, ray.direction.magnitude); // return false; //} foreach (var go in vObjects) { if (FilterF != null && FilterF(go) == false) { continue; } if (go.IsVisible() == false) { continue; } Collider collider = go.GetComponent <Collider>(); if (collider) { go.EnableCollider(); if (collider.Raycast(ray, out hitInfo, Mathf.Infinity)) { if (hitInfo.distance < hit.fHitDist) { hit.fHitDist = hitInfo.distance; hit.hitPos = hitInfo.point; hit.hitNormal = hitInfo.normal; hit.hitGO = go; } } go.DisableCollider(); } } return(hit.hitGO != null); }
// rayhit-test a GameObject, handling collider enable/disable public static bool FindGORayIntersection(Ray ray, GameObject go, out GameObjectRayHit hit) { hit = null; bool bIsEnabled = go.GetComponent <MeshCollider> ().enabled; go.GetComponent <MeshCollider> ().enabled = true; RaycastHit hitInfo; if (go.GetComponent <MeshCollider> ().Raycast(ray, out hitInfo, Mathf.Infinity)) { hit = new GameObjectRayHit(); hit.fHitDist = hitInfo.distance; hit.hitPos = hitInfo.point; hit.hitGO = go; } go.GetComponent <MeshCollider> ().enabled = bIsEnabled; return(hit != null); }
public virtual bool FindGORayIntersection(Ray ray, out GameObjectRayHit hit) { hit = new GameObjectRayHit(); RaycastHit hitInfo; foreach (var go in vObjects) { go.GetComponent <MeshCollider> ().enabled = true; if (go.GetComponent <MeshCollider> ().Raycast(ray, out hitInfo, Mathf.Infinity)) { if (hitInfo.distance < hit.fHitDist) { hit.fHitDist = hitInfo.distance; hit.hitPos = hitInfo.point; hit.hitGO = go; } } go.GetComponent <MeshCollider> ().enabled = false; } return(hit.hitGO != null); }
// 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); }
// 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); } }
// 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(); } } }
// subclass can implement these to add custom behaviors virtual public bool custom_begin_capture(InputEvent e, GameObjectRayHit hit) { return(false); }