Beispiel #1
0
 protected void standard_update_capture(InputEvent e, InteractionMode eMode)
 {
     if (eMode == InteractionMode.InPressDrag)
     {
         Vector3f hitPos = vHandleStartW.RayPlaneIntersection(e.ray.Origin, e.ray.Direction, 1);
         onSliderBarPressDrag(e, hitPos);
     }
     else if (eMode == InteractionMode.InHandleDrag)
     {
         Vector3f hitPos  = vHandleStartW.RayPlaneIntersection(e.ray.Origin, e.ray.Direction, 1);
         Vector3f dv      = hitPos - vStartHitW;
         Vector3f vRelPos = vHandleStartW.Origin + dv;
         onHandlePressDrag(e, vRelPos);
     }
 }
            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;
            }
Beispiel #3
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with world-space translation plane
            Vector3f planeHit = translateFrameW.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, nTranslationPlaneNormal);
            int      e0       = (nTranslationPlaneNormal + 1) % 3;
            int      e1       = (nTranslationPlaneNormal + 2) % 3;

            // construct delta in world space and project into frame coordinates
            Vector3f delta = (planeHit - vInitialHitPos);

            delta *= TranslationScaleF();
            float dx = Vector3f.Dot(delta, translateFrameW.GetAxis(e0));
            float dy = Vector3f.Dot(delta, translateFrameW.GetAxis(e1));

            if (DeltaDistanceConstraintF != null)
            {
                dx = DeltaDistanceConstraintF(translateFrameL, e0, dx);
                dy = DeltaDistanceConstraintF(translateFrameL, e1, dy);
            }

            // construct new local frame translated along plane axes
            Frame3f newFrame = translateFrameL;

            newFrame.Origin += dx * translateFrameL.GetAxis(e0) + dy * translateFrameL.GetAxis(e1);

            // update target
            target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords);

            return(true);
        }
Beispiel #4
0
        // try to compute a stable ray/plane intersection. when origin is at < +/- an altitude threshold,
        // use ray/line distance with view-perp line, instead of actual intersection
        public static Vector3f SafeRayPlaneIntersection(Ray3f ray, Vector3f forwardDir,
                                                        Vector3f planeOrigin, Vector3f planeNormal, float fAngleThresh = 10.0f)
        {
            // determine if we are in unstable condition
            float fOriginAngleDeg = (float)Math.Abs(
                planeNormal.AngleD((planeOrigin - ray.Origin).Normalized));
            bool bOriginUnstable = Math.Abs(fOriginAngleDeg - 90.0f) < fAngleThresh;

            // we use ray/plane intersect if stable
            Frame3f  planeF   = new Frame3f(planeOrigin, planeNormal);
            Vector3f planeHit = planeF.RayPlaneIntersection(ray.Origin, ray.Direction, 2);

            if (bOriginUnstable == false)
            {
                return(planeHit);
            }

            // if unstable, find "right" direction in plane (ie perp to forward dir, which
            //  may just be ray dir), then intersection is ray/axis closest point
            Vector3f fwDirInPlane   = (forwardDir - planeNormal.Dot(forwardDir)).Normalized;
            Vector3f perpDirInPlane = Quaternionf.AxisAngleD(planeNormal, 90.0f) * fwDirInPlane;
            float    fAxisDist      = (float)DistLine3Ray3.MinDistanceLineParam(ray, new Line3d(planeOrigin, perpDirInPlane));

            return(planeOrigin + fAxisDist * perpDirInPlane);
        }
Beispiel #5
0
        public void UpdateDraw_Ray(Ray3f ray)
        {
            float    fScale = scene.GetSceneScale();
            Vector3f vHit   = planarF.RayPlaneIntersection(ray.Origin, ray.Direction, 2);

            smooth_append(preview, scene.SceneFrame.ToFrameP(vHit) / fScale, dist_thresh(Width, fScale));
        }
        public override bool UpdateCapture(ITransformable target, Ray worldRay)
        {
            // ray-hit with plane perpendicular to rotateAxisW
            Vector3f planeHit = raycastFrame.RayPlaneIntersection(worldRay.origin, worldRay.direction, 2);

            // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle
            Vector3f dv          = planeHit - rotateFrameW.Origin;
            int      iX          = (nRotationAxis + 1) % 3;
            int      iY          = (nRotationAxis + 2) % 3;
            float    fX          = Vector3.Dot(dv, rotateFrameW.GetAxis(iX));
            float    fY          = Vector3.Dot(dv, rotateFrameW.GetAxis(iY));
            float    fNewAngle   = (float)Math.Atan2(fY, fX);
            float    fDeltaAngle = (fNewAngle - fRotateStartAngle);

            // construct new frame for target that is rotated around axis
            Vector3f    rotateAxisL = rotateFrameL.GetAxis(nRotationAxis);
            Quaternionf q           = Quaternion.AngleAxis(fDeltaAngle * Mathf.Rad2Deg, rotateAxisL);
            Frame3f     newFrame    = rotateFrameL;

            newFrame.Rotation = q * newFrame.Rotation;                          // order matters here!

            // update target
            target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords);

            return(true);
        }
        void update_last_hit(SculptCurveTool tool, Ray3f ray)
        {
            SORayHit soHit;

            // stick brush to target if we have one
            if (tool.BrushTarget != null)
            {
                Vector3d hitPos, hitNormal;
                bool     bHit = tool.BrushTarget.RayIntersect(ray, out hitPos, out hitNormal);
                if (bHit)
                {
                    lastHitPosW = (Vector3f)hitPos;
                }
            }
            else if (in_draw)
            {
                lastHitPosW = curDrawFrameW.RayPlaneIntersection(ray.Origin, ray.Direction, 2);
            }
            else if (SceneUtil.FindNearestRayIntersection(tool.Targets, ray, out soHit))
            {
                lastHitPosW = soHit.hitPos;
            }
            else
            {
                Frame3f f = new Frame3f(lastHitPosW, context.ActiveCamera.Forward());
                lastHitPosW = f.RayPlaneIntersection(ray.Origin, ray.Direction, 2);
            }
        }
Beispiel #8
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with plane that contains translation axis
            Vector3f planeHit = raycastFrame.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            // figure out new T-value along axis, then our translation update is delta-t
            float fNewT   = Distance.ClosestPointOnLineT(translateFrameW.Origin, translateAxisW, planeHit);
            float fDeltaT = (fNewT - fTranslateStartT);

            fDeltaT *= TranslationScaleF();
            if (DeltaDistanceConstraintF != null)
            {
                fDeltaT = DeltaDistanceConstraintF(translateFrameL, nTranslationAxis, fDeltaT);
            }

            // construct new frame translated along axis (in local space)
            Frame3f newFrame = translateFrameL;

            newFrame.Origin += fDeltaT * translateFrameL.GetAxis(nTranslationAxis);

            // update target
            target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords);

            return(true);
        }
Beispiel #9
0
        public void UpdateDraw_Ray(Ray3f ray)
        {
            float    fScale = scene.GetSceneScale();
            Vector3f vHit   = planarF.RayPlaneIntersection(ray.Origin, ray.Direction, 2);

            smooth_append(preview.Curve, scene.ToSceneP(vHit), dist_thresh(Radius, fScale));
        }
        public virtual void BeginStroke(Ray3f rayS)
        {
            Vector3f camDirW = Scene.ActiveCamera.Forward();
            Vector3f camDirS = Scene.ToSceneP(camDirW);

            PlaneFrameS = new Frame3f(Target.GetLocalFrame(CoordSpace.SceneCoords).Origin, camDirS);

            CurrentStroke.Clear();
            CurrentStroke.Add(rayS);

            CurrentStart = PlaneFrameS.RayPlaneIntersection(rayS.Origin, rayS.Direction, 2);
            CurrentEnd   = CurrentStart;

            if (currentLine == null)
            {
                currentLine = new LineIndicator()
                {
                    SceneStartF = () => { return(CurrentStart); },
                    SceneEndF   = () => { return(CurrentEnd); },
                    VisibleF    = () => { return(CurrentStroke.Count > 1); },
                    ColorF      = () => { return(this.LineColor); },
                    LineWidth   = fDimension.Scene(LineWidth)
                };
                Indicators.AddIndicator(currentLine);
            }
        }
Beispiel #11
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with plane perpendicular to rotateAxisW
            Vector3f planeHitW = raycastFrame.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle
            Vector3f dv = planeHitW - rotateFrameW.Origin;
            int      iX = (nRotationAxis + 1) % 3;
            int      iY = (nRotationAxis + 2) % 3;
            float    fX = Vector3.Dot(dv, rotateFrameW.GetAxis(iX));
            float    fY = Vector3.Dot(dv, rotateFrameW.GetAxis(iY));

            float fNewAngle = (float)Math.Atan2(fY, fX);

            if (AbsoluteAngleConstraintF != null)
            {
                fNewAngle = AbsoluteAngleConstraintF(rotateFrameL, nRotationAxis, fNewAngle);
            }

            float fDeltaAngle = (fNewAngle - fRotateStartAngle);

            if (DeltaAngleConstraintF != null)
            {
                fDeltaAngle = DeltaAngleConstraintF(rotateFrameL, nRotationAxis, fDeltaAngle);
            }


            bool on_snap = false;

            if (EnableSnapping)
            {
                double dist = (planeHitW - rotateFrameW.Origin).Length;
                on_snap = Math.Abs(dist - gizmoRadiusW) < gizmoRadiusW * 0.15f;
                if (on_snap)
                {
                    fDeltaAngle = (float)Snapping.SnapToIncrement(fDeltaAngle, SnapIncrementDeg * MathUtil.Deg2Radf);
                }
                enable_snap_indicator(true);
                update_snap_indicator(-fDeltaAngle, on_snap);
            }

            // construct new frame for target that is rotated around axis
            Vector3f    rotateAxisL = rotateFrameL.GetAxis(nRotationAxis);
            Quaternionf q           = Quaternion.AngleAxis(fDeltaAngle * Mathf.Rad2Deg, rotateAxisL);
            Frame3f     newFrame    = rotateFrameL;

            newFrame.Rotation = q * newFrame.Rotation;                          // order matters here!

            // update target
            target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords);

            if (EnableSnapping)
            {
                update_circle_indicator(on_snap);
            }

            return(true);
        }
Beispiel #12
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            Frame3f plane = new Frame3f(Vector3.zero, Vector3.forward);
            Vector3 vHit  = plane.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            vHit = targetW.ToFrameP(vHit);
            deformer.UpdateDeformation(vHit);

            return(true);
        }
Beispiel #13
0
        Vector3f vInitialHitPos;                        // initial hit position in frame

        public override bool BeginCapture(ITransformable target, Ray3f worldRay, UIRayHit hit)
        {
            // save local and world frames
            translateFrameL = target.GetLocalFrame(CoordSpace.ObjectCoords);
            translateFrameW = target.GetLocalFrame(CoordSpace.WorldCoords);

            // save initial hitpos in translation plane
            vInitialHitPos = translateFrameW.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, nTranslationPlaneNormal);

            return(true);
        }
Beispiel #14
0
        override public bool UpdateCapture(InputEvent e)
        {
            if (eInterMode == InteractionMode.InCustom)
            {
                custom_update_capture(e);
            }
            else if (eInterMode == InteractionMode.InPressDrag)
            {
                Vector3f hitPos = vHandleStartW.RayPlaneIntersection(e.ray.Origin, e.ray.Direction, 1);
                onSliderBarPressDrag(e, hitPos);
            }
            else if (eInterMode == InteractionMode.InHandleDrag)
            {
                Vector3f hitPos  = vHandleStartW.RayPlaneIntersection(e.ray.Origin, e.ray.Direction, 1);
                Vector3f dv      = hitPos - vStartHitW;
                Vector3f vRelPos = vHandleStartW.Origin + dv;
                onHandlePressDrag(e, vRelPos);
            }

            return(true);
        }
Beispiel #15
0
        Vector3f vInitialHitPos;     // initial hit position in frame

        public override bool BeginCapture(ITransformable target, Ray3f worldRay, UIRayHit hit)
        {
            if (target.SupportsScaling == false)
            {
                return(false);
            }

            // save local and world frames
            scaleFrameW  = target.GetLocalFrame(CoordSpace.WorldCoords);
            cameraFrameW = new Frame3f(scaleFrameW.Origin, activeCamera.transform.rotation);
            startScale   = target.GetLocalScale();

            // save initial hitpos in plane
            vInitialHitPos = cameraFrameW.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            return(true);
        }
Beispiel #16
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with plane that contains translation axis
            Vector3f planeHit = raycastFrame.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            // figure out new T-value along axis, then our translation update is delta-t
            float fNewT   = Distance.ClosestPointOnLineT(targetFrameW.Origin, heightAxisW, planeHit);
            float fDeltaT = (fNewT - fHeightStartT);

            fDeltaT *= DeltaScalingF();

            float fNewValue = fStartValue + fDeltaT;

            fNewValue = Mathf.Clamp(fNewValue, ValidRangeMin, ValidRangeMax);

            primitive.Parameters.SetValue(AxisParamName, fNewValue);

            return(true);
        }
Beispiel #17
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with world-space translation plane
            Vector3f planeHit = cameraFrameW.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            // construct delta in world space and project into frame coordinates
            Vector3f delta = (planeHit - vInitialHitPos);

            delta *= ScaleMultiplierF();
            //float dx = Vector3f.Dot(delta, cameraFrameW.GetAxis(0));
            float dy          = Vector3f.Dot(delta, cameraFrameW.GetAxis(1));
            float scaleDelta  = 1.0f + dy;
            float scaleFactor = Mathf.Clamp(scaleDelta, 0.1f, 1000.0f);

            // update target
            target.SetLocalScale(startScale * scaleFactor);

            return(true);
        }
Beispiel #18
0
        public bool UpdateCapture(MMDModel target, RayWrap worldRay)
        {
            int normalAxis = 2;

            if (nTranslationAxis == 2)
            {
                normalAxis = 1;
            }
            // ray-hit with plane that contains translation axis
            var planeHitOpt = raycastFrame.RayPlaneIntersection(worldRay.From, worldRay.Dir, normalAxis);

            if (!planeHitOpt.HasValue)
            {
                return(false);
            }
            Vector3 planeHit = planeHitOpt.Value;

            // figure out new T-value along axis, then our translation update is delta-t
            float fNewT   = ClosestPointOnLineT(translateFrameW.Origin, translateAxisW, planeHit);
            float fDeltaT = (fNewT - fTranslateStartT);

            fDeltaT *= TranslationScaleF( );
            if (DeltaDistanceConstraintF != null)
            {
                fDeltaT = DeltaDistanceConstraintF(translateFrameL, nTranslationAxis, fDeltaT);
            }

            // construct new frame translated along axis (in local space)
            Frame3f newFrame = translateFrameL;

            newFrame.Origin += fDeltaT * translateFrameL.GetAxis(nTranslationAxis);

            // update target
            //target.SetLocalFrame (newFrame, CoordSpace.ObjectCoords);
            target.Position = newFrame.Origin;
            return(true);
        }
        // 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);
            }
        }
Beispiel #20
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();
                }
            }
        }
 public void UpdateStroke(Ray3f rayS)
 {
     CurrentStroke.Add(rayS);
     CurrentEnd = PlaneFrameS.RayPlaneIntersection(rayS.Origin, rayS.Direction, 2);
 }
Beispiel #22
0
        public bool UpdateCapture(MMDModel target, RayWrap worldRay)
        {
            int normalAxis = 2;

            if (nRotationAxis == 2)
            {
                normalAxis = 1;
            }

            // ray-hit with plane perpendicular to rotateAxisW
            var planeHitWOpt = raycastFrame.RayPlaneIntersection(worldRay.From, worldRay.Dir, normalAxis);

            if (!planeHitWOpt.HasValue)
            {
                return(false);
            }
            var planeHitW = planeHitWOpt.Value;

            // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle
            Vector3f dv = planeHitW - rotateFrameW.Origin;
            int      iX = (nRotationAxis + 1) % 3;
            int      iY = (nRotationAxis + 2) % 3;
            float    fX = Vector3.Dot(dv, rotateFrameW.GetAxis(iX));
            float    fY = Vector3.Dot(dv, rotateFrameW.GetAxis(iY));

            Util.DebugWrite("dv " + dv.ToString( ));
            Util.DebugWrite("planeHitW " + planeHitW.ToString( ));
            Util.DebugWrite("rotateFrameW " + rotateFrameW.Origin.ToString( ));

            float fNewAngle = (float)Math.Atan2(fY, fX);

            //if ( AbsoluteAngleConstraintF != null )
            //	fNewAngle = AbsoluteAngleConstraintF( rotateFrameL , nRotationAxis , fNewAngle );

            float fDeltaAngle = (fNewAngle - fRotateStartAngle);

            //if (DeltaAngleConstraintF != null)
            //    fDeltaAngle = DeltaAngleConstraintF(rotateFrameL, nRotationAxis, fDeltaAngle);

            Util.DebugWrite("fDeltaAngle " + fDeltaAngle);

            fDeltaAngle *= 0.03f;

            bool on_snap = false;

            if (EnableSnapping)
            {
                //double dist = (planeHitW - rotateFrameW.Origin).Length();
                //on_snap = Math.Abs(dist - gizmoRadiusW) < gizmoRadiusW * 0.15f;
                //if (on_snap)
                //    fDeltaAngle = (float)Snapping.SnapToIncrement(fDeltaAngle, SnapIncrementDeg * MathUtil.Deg2Radf);
                //enable_snap_indicator(true);
                //update_snap_indicator(-fDeltaAngle, on_snap);
            }

            // 軸を中心に回るターゲットのための新しいフレームを作る
            Vector3f   rotateAxisL = rotateFrameL.GetAxis(nRotationAxis);
            Quaternion q           = Quaternion.RotationAxis(rotateAxisL, fDeltaAngle.Deg());
            Frame3f    newFrame    = rotateFrameL;

            newFrame.Rotation = q * newFrame.Rotation;                          // order matters here!

            // update target
            target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords);

            if (EnableSnapping)
            {
                //update_circle_indicator(on_snap);
            }

            return(true);
        }