// called on per-frame Update() virtual public void PreRender() { root.Show(); float useDegrees = (GizmoVisualDegrees > 0) ? GizmoVisualDegrees : SceneGraphConfig.DefaultAxisGizmoVisualDegrees; float fWorldSize = VRUtil.GetVRRadiusForVisualAngle( root.GetPosition(), parentScene.ActiveCamera.GetPosition(), useDegrees); float fSceneSize = fWorldSize / parentScene.GetSceneScale(); float fGeomScale = fSceneSize / initialGizmoRadius; root.SetLocalScale(new Vector3f(fGeomScale)); foreach (var widget in Widgets) { widget.Value.UpdateGizmoWorldSize(fWorldSize); } if (DynamicVisibilityFiltering && targetWrapper != null) { Frame3f frameW = targetWrapper.GetLocalFrame(CoordSpace.WorldCoords); Vector3d camPosW = parentScene.ActiveCamera.GetPosition(); foreach (var go in enabledWidgetGOs) { Standard3DTransformWidget widget = Widgets[go]; bool visible = widget.CheckVisibility(ref frameW, ref camPosW); go.SetVisible(visible); } } }
// figuring out a decent line width is tricky. Want to be responsive to camera // pos, so line doesn't get super-thick when zoomed in. So we want to measure // screen-space radius. But off-screen vertices are a problem. So, only consider // vertices within a level, pointing-forward view cone (can't be actual view cone // because then line thickness changes as you turn head!). // // Also sub-sample verts for efficiency. Probably we don't need to do this // every frame...but how to distribute? // // ***returns 0*** if we couldn't find any points in view cone public static float EstimateStableCurveWidth(FScene scene, Frame3f curveFrameS, DCurve3 curve, float fVisualAngleDeg) { // do computations in Scene coords..."safest"? Vector3f camPos = scene.ActiveCamera.GetPosition(); Vector3f camForward = scene.ActiveCamera.Forward(); // use level-forward camForward[1] = 0; camForward.Normalize(); camPos = scene.ToSceneP(camPos); camForward = scene.ToSceneN(camForward); const float ViewConeDotThresh = 0.707106f; // 45 degrees int nSubSampleInc = Math.Max(2, curve.VertexCount / 10); float rSum = 0; int iSum = 0; for (int k = 0; k < curve.VertexCount; k += nSubSampleInc) { Vector3f vS = (Vector3f)curve.GetVertex(k); vS = curveFrameS.FromFrameP(vS); Vector3f dv = (vS - camPos).Normalized; if (dv.Dot(camForward) < ViewConeDotThresh) { continue; } float r = VRUtil.GetVRRadiusForVisualAngle(vS, camPos, fVisualAngleDeg); rSum += r; iSum++; } return((rSum == 0) ? 0 : scene.ToWorldDimension(rSum / (float)iSum)); }
public override void update_width(float width) { // how to convert this width to pixels? //float near_plane_w = Camera.main.nearClipPlane * (float)Math.Tan(Camera.main.fieldOfView); //float near_pixel_w = Camera.main.pixelWidth / near_plane_w; float near_plane_pixel_deg = Camera.main.fieldOfView / Camera.main.pixelWidth; float fWidth = VRUtil.GetVRRadiusForVisualAngle(center, Camera.main.transform.position, near_plane_pixel_deg); r.startWidth = r.endWidth = width * fWidth; }
public override void PreRender() { float fScaling = VRUtil.GetVRRadiusForVisualAngle( pivot.transform.position, parentScene.ActiveCamera.GetPosition(), SceneGraphConfig.DefaultPivotVisualDegrees); fScaling /= parentScene.GetSceneScale(); pivot.transform.localScale = new Vector3(fScaling, fScaling, fScaling); }
public override void PreRender() { if (MaintainConsistentViewSize) { float fScaling = VRUtil.GetVRRadiusForVisualAngle( pivotGO.GetPosition(), parentScene.ActiveCamera.GetPosition(), SceneGraphConfig.DefaultPivotVisualDegrees); fScaling /= parentScene.GetSceneScale(); pivotGO.SetLocalScale(new Vector3f(fScaling, fScaling, fScaling)); } }
// called on per-frame Update() override public void PreRender() { gizmo.Show(); foreach (var v in Widgets) { float fScaling = VRUtil.GetVRRadiusForVisualAngle( v.Key.GetPosition(), parentScene.ActiveCamera.GetPosition(), SceneGraphConfig.DefaultPivotVisualDegrees); fScaling /= parentScene.GetSceneScale(); v.Key.SetLocalScale(fScaling * WidgetScale); } }
public void UpdateSetWorldScale(Ray3f left, Ray3f right) { Vector3f hit1 = hitFrame.RayPlaneIntersection(left.Origin, left.Direction, 2); Vector3f hit2 = hitFrame.RayPlaneIntersection(right.Origin, right.Direction, 2); Vector3f avg = (hit1 + hit2) * 0.5f; float r0 = (hit1 - (Vector3f)go.transform.position).Length; float r1 = (hit2 - (Vector3f)go.transform.position).Length; float r = (r0 + r1) * 0.5f; float min_r = VRUtil.GetVRRadiusForVisualAngle(avg, camState.camPosition, 2.0f); r = (float)Math.Max(r, min_r); go.transform.localScale = r * Vector3f.One; go.GetComponent <Renderer>().material = (r > deadzone_r) ? mYes : mNo; }
// called on per-frame Update() virtual public void PreRender() { gizmo.Show(); float fScaling = VRUtil.GetVRRadiusForVisualAngle( gizmo.transform.position, parentScene.ActiveCamera.GetPosition(), SceneGraphConfig.DefaultAxisGizmoVisualDegrees); fScaling /= parentScene.GetSceneScale(); float fGeomDim = gizmoGeomBounds.size.magnitude; fScaling /= fGeomDim; gizmo.transform.localScale = new Vector3(fScaling, fScaling, fScaling); }
public void PreRender(Vector3f cameraPosW) { float fSceneScale = parentSO.GetScene().GetSceneScale(); foreach (var i in vObjects) { Vector3f vPos = i.go.transform.position; float fR = VRUtil.GetVRRadiusForVisualAngle(vPos, cameraPosW, i.fVisualRadiusDeg); // have to compensate for scaling of parent SO float fParentSOScale = parentSO.GetLocalScale()[0]; fR = fR / fParentSOScale / fSceneScale; i.go.transform.localScale = fR * Vector3f.One; } }
public override Capture BeginCapture(InputState input, CaptureSide eSide) { HandInfo hi = new HandInfo(); hi.eMode = ActionMode.TransformCamera; Frame3f camFrame = cockpit.ActiveCamera.GetWorldFrame(); // if both rays hit scene and are within a few visual degrees, then we // we pull out a sphere and use it to re-scale the world. // Otherwise do normal hand-transform actions AnyRayHit hit1, hit2; bool bHit1 = cockpit.Scene.FindSceneRayIntersection(input.vLeftSpatialWorldRay, out hit1); bool bHit2 = cockpit.Scene.FindSceneRayIntersection(input.vRightSpatialWorldRay, out hit2); if (bHit1 && bHit2) { Vector3 avg = (hit1.hitPos + hit2.hitPos) * 0.5f; float d = VRUtil.GetVRRadiusForVisualAngle(avg, camFrame.Origin, 2.0f); if ((hit1.hitPos - hit2.hitPos).Length < d) { hi.eMode = ActionMode.SetWorldScale; Frame3f centerF = cockpit.Scene.SceneFrame; centerF.Origin = avg; Frame3f planeF = new Frame3f(centerF.Origin, camFrame.Z); hi.BeginSetWorldScale(centerF, planeF, 2 * d); hi.UpdateSetWorldScale(input.vLeftSpatialWorldRay, input.vRightSpatialWorldRay); } } hi.leftStartF = input.LeftHandFrame; hi.rightStartF = input.RightHandFrame; hi.camState = cockpit.ActiveCamera.Manipulator().GetCurrentState(cockpit.Scene); hi.camRight = camFrame.X; hi.camForward = camFrame.Z; cockpit.ActiveCamera.SetTargetVisible(true); return(Capture.Begin(this, CaptureSide.Both, hi)); }
public void Update() { targetGO.transform.position = TargetPoint; float fScaling = VRUtil.GetVRRadiusForVisualAngle(TargetPoint, gameObject.transform.position, 1.0f); targetGO.transform.localScale = new Vector3(fScaling, fScaling, fScaling); if (ShowTarget) { Material setMaterial = hiddenMaterial; // raycast into scene and if we hit ball before we hit anything else, render // it darker red, to give some sense of inside/outside if (this.context != null) { Vector3 camPos = this.context.ActiveCamera.GetPosition(); float fDistSqr = (TargetPoint - camPos).sqrMagnitude; Ray ray_t = new Ray(camPos, (TargetPoint - camPos).normalized); AnyRayHit hit; if (this.context.Scene.FindSceneRayIntersection(ray_t, out hit) == false) { setMaterial = visibleMaterial; } else if (hit.fHitDist * hit.fHitDist * 1.005f > fDistSqr) { setMaterial = visibleMaterial; } } MaterialUtil.SetMaterial(targetGO, setMaterial); targetGO.Show(); } else { targetGO.Hide(); } }
public void Update() { targetGO.transform.position = TargetPoint; float fScaling = VRUtil.GetVRRadiusForVisualAngle(TargetPoint, gameObject.transform.position, SceneGraphConfig.CameraPivotVisualDegrees); targetGO.transform.localScale = fScaling * Vector3f.One; if (ShowTarget && SceneGraphConfig.EnableVisibleCameraPivot) { Material setMaterial = hiddenMaterial; // raycast into scene and if we hit ball before we hit anything else, render // it darker red, to give some sense of inside/outside if (this.context != null) { Vector3f camPos = this.context.ActiveCamera.GetPosition(); float fDistSqr = TargetPoint.DistanceSquared(camPos); Ray3f ray_t = new Ray3f(camPos, (TargetPoint - camPos).Normalized); AnyRayHit hit; if (this.context.Scene.FindSceneRayIntersection(ray_t, out hit) == false) { setMaterial = visibleMaterial; } else if (hit.fHitDist * hit.fHitDist * 1.005f > fDistSqr) { setMaterial = visibleMaterial; } } MaterialUtil.SetMaterial(targetGO, setMaterial); targetGO.Show(); } else { targetGO.Hide(); } }
// 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(); } } }