コード例 #1
0
        // 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);
        }
コード例 #2
0
 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
     });
 }
コード例 #3
0
        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
            });
        }
コード例 #4
0
 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
     });
 }
コード例 #5
0
 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
     });
 }
コード例 #6
0
ファイル: SceneUtil.cs プロジェクト: ly774508966/frame3Sharp
 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;
 }
コード例 #7
0
ファイル: SceneUtil.cs プロジェクト: ly774508966/frame3Sharp
 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;
 }
コード例 #8
0
 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;
 }
コード例 #9
0
 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;
 }
コード例 #10
0
        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);
        }
コード例 #11
0
        // 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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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;
        }
コード例 #14
0
        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);
        }
コード例 #15
0
ファイル: FContext.cs プロジェクト: Alan-Baylis/frame3Sharp
        // 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);
        }
コード例 #16
0
        // 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);
            }
        }
コード例 #17
0
        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);
            }
        }
コード例 #18
0
        // 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();
                }
            }
        }
コード例 #19
0
        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);
        }
コード例 #20
0
 public void BeginDraw_Spatial(Ray3f ray, AnyRayHit rayHit, Frame3f handFrame, int nStep)
 {
     BeginDraw_Ray(ray, rayHit, nStep);
 }
コード例 #21
0
        // 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);
        }