Beispiel #1
0
        public override void OverrideRayEndPoint(Ray ray, ref Vector3 rayEndPoint)
        {
            bool triggerJustClicked  = false;
            bool triggerJustReleased = false;

            VRInput.GetInstantButtonEvent(VRInput.primaryController, CommonUsages.triggerButton, ref triggerJustClicked, ref triggerJustReleased);

            // Project ray on the widget plane.
            Plane widgetPlane = new Plane(-transform.forward, transform.position);
            float enter;

            widgetPlane.Raycast(ray, out enter);
            Vector3 worldCollisionOnWidgetPlane = ray.GetPoint(enter);

            Vector3 localWidgetPosition          = transform.InverseTransformPoint(worldCollisionOnWidgetPlane);
            Vector3 localProjectedWidgetPosition = new Vector3(localWidgetPosition.x, localWidgetPosition.y, 0.0f);

            if (IgnoreRayInteraction())
            {
                // return endPoint at the surface of the widget.
                rayEndPoint = transform.TransformPoint(localProjectedWidgetPosition);
                return;
            }

            float startX = 0;
            float endX   = width;
            float startY = 0;
            float endY   = -height;

            Vector2 currentKnobPosition = new Vector2(cursorPosition.x * width, (-1.0f + cursorPosition.y) * height);

            // DRAG

            if (!triggerJustClicked) // if trigger just clicked, use the actual projection, no interpolation.
            {
                localProjectedWidgetPosition.x = Mathf.Lerp(currentKnobPosition.x, localProjectedWidgetPosition.x, GlobalState.Settings.RaySliderDrag);
                localProjectedWidgetPosition.y = Mathf.Lerp(currentKnobPosition.y, localProjectedWidgetPosition.y, GlobalState.Settings.RaySliderDrag);
            }

            // CLAMP

            if (localProjectedWidgetPosition.x < startX)
            {
                localProjectedWidgetPosition.x = startX;
            }

            if (localProjectedWidgetPosition.x > endX)
            {
                localProjectedWidgetPosition.x = endX;
            }

            if (localProjectedWidgetPosition.y > startY)
            {
                localProjectedWidgetPosition.y = startY;
            }

            if (localProjectedWidgetPosition.y < endY)
            {
                localProjectedWidgetPosition.y = endY;
            }

            // SET

            float x = localProjectedWidgetPosition.x / width;
            float y = 1.0f - (-localProjectedWidgetPosition.y / height);

            x = Mathf.Clamp(x, 0, 1);
            y = Mathf.Clamp(y, 0, 1);
            SetSaturation(new Vector2(x, y));
            colorPicker.OnColorChanged();

            // Haptic intensity as we go deeper into the widget.
            //float intensity = Mathf.Clamp01(0.001f + 0.999f * localWidgetPosition.z / UIElement.collider_min_depth_deep);
            //intensity *= intensity; // ease-in

            //VRInput.SendHaptic(VRInput.rightController, 0.005f, intensity);

            Vector3 worldProjectedWidgetPosition = transform.TransformPoint(localProjectedWidgetPosition);

            //cursorShapeTransform.position = worldProjectedWidgetPosition;
            rayEndPoint = worldProjectedWidgetPosition;
        }
Beispiel #2
0
        public override void OverrideRayEndPoint(Ray ray, ref Vector3 rayEndPoint)
        {
            bool triggerJustClicked  = false;
            bool triggerJustReleased = false;

            VRInput.GetInstantButtonEvent(VRInput.primaryController, CommonUsages.triggerButton, ref triggerJustClicked, ref triggerJustReleased);

            // Project ray on the widget plane.
            Plane widgetPlane = new Plane(-transform.forward, transform.position);
            float enter;

            widgetPlane.Raycast(ray, out enter);
            Vector3 worldCollisionOnWidgetPlane = ray.GetPoint(enter);

            Vector3 localWidgetPosition          = transform.InverseTransformPoint(worldCollisionOnWidgetPlane);
            Vector3 localProjectedWidgetPosition = new Vector3(localWidgetPosition.x, localWidgetPosition.y, 0.0f);

            if (IgnoreRayInteraction())
            {
                // return endPoint at the surface of the widget.
                rayEndPoint = transform.TransformPoint(localProjectedWidgetPosition);
                return;
            }

            float startX = 0;
            float endX   = width;

            float currentKnobPositionX = cursorPosition * width;

            // DRAG

            if (!triggerJustClicked) // if trigger just clicked, use the actual projection, no interpolation.
            {
                localProjectedWidgetPosition.x = Mathf.Lerp(currentKnobPositionX, localProjectedWidgetPosition.x, GlobalState.Settings.RaySliderDrag);
            }

            // CLAMP

            if (localProjectedWidgetPosition.x < startX)
            {
                localProjectedWidgetPosition.x = startX;
            }

            if (localProjectedWidgetPosition.x > endX)
            {
                localProjectedWidgetPosition.x = endX;
            }

            localProjectedWidgetPosition.y = -height / 2.0f;

            // SET

            float pct = localProjectedWidgetPosition.x / width;

            SetAlpha(Mathf.Clamp(pct, 0, 1));
            colorPicker.OnColorChanged();

            Vector3 worldProjectedWidgetPosition = transform.TransformPoint(localProjectedWidgetPosition);

            //cursorShapeTransform.position = worldProjectedWidgetPosition;
            rayEndPoint = worldProjectedWidgetPosition;
        }
Beispiel #3
0
        public override void OverrideRayEndPoint(Ray ray, ref Vector3 rayEndPoint)
        {
            bool triggerJustClicked  = false;
            bool triggerJustReleased = false;

            VRInput.GetInstantButtonEvent(VRInput.primaryController, CommonUsages.triggerButton, ref triggerJustClicked, ref triggerJustReleased);

            // Project ray on the widget plane.
            Plane widgetPlane = new Plane(-transform.forward, transform.position);
            float enter;

            widgetPlane.Raycast(ray, out enter);
            Vector3 worldCollisionOnWidgetPlane = ray.GetPoint(enter);

            Vector3 localWidgetPosition          = transform.InverseTransformPoint(worldCollisionOnWidgetPlane);
            Vector3 localProjectedWidgetPosition = new Vector3(localWidgetPosition.x, localWidgetPosition.y, -thickness);

            if (IgnoreRayInteraction())
            {
                // return endPoint at the surface of the widget.
                rayEndPoint = transform.TransformPoint(localProjectedWidgetPosition);
                return;
            }

            float w2 = width / 2.0f;
            float h2 = height / 2.0f;
            float ir = innerCirclePct * w2; // circle inner radius
            float or = outerCirclePct * w2; // circle outer radius
            float mr = (ir + or) / 2.0f;    // circle middle radius
            float cw = (or - ir);           // circle width
            float tr = trianglePct * w2;

            Vector2 circleCenter_L = new Vector2(w2, -h2);
            Vector2 cursor_L       = new Vector2(localProjectedWidgetPosition.x, localProjectedWidgetPosition.y);

            // Just clicked, find out which subpart to lock on
            if (triggerJustClicked)
            {
                float cursorDistanceFromCenter = Vector2.Distance(cursor_L, circleCenter_L);
                if (cursorDistanceFromCenter >= ir && cursorDistanceFromCenter <= or)
                {
                    lockedOnCircle = true;
                }
                else
                {
                    // TODO: really check for triangle bounds, not only bounding circle.
                    if (cursorDistanceFromCenter <= tr)
                    {
                        lockedOnTriangle = true;
                    }
                }
            }

            if (lockedOnCircle)
            {
                Vector2 cursor_C = cursor_L - circleCenter_L;
                float   angle    = Mathf.Rad2Deg * (Mathf.PI - Mathf.Atan2(cursor_C.y, cursor_C.x));
                float   newHue   = angle / 360.0f;

                // DRAG
                if (!triggerJustClicked)
                {
                    float oldHue = hsv.x;
                    if (newHue - oldHue < -0.5f) // ex: 0.9 -> 0.1 ==> 0.9 -> 1.1
                    {
                        newHue = Mathf.Lerp(oldHue, newHue + 1.0f, GlobalState.Settings.RayHueDrag);
                        if (newHue >= 1.0f)
                        {
                            newHue -= 1.0f;
                        }
                    }
                    else if (newHue - oldHue > 0.5f) // ex: 0.1 -> 0.9 ==> 1.1 -> 0.9
                    {
                        newHue = Mathf.Lerp(oldHue + 1.0f, newHue, GlobalState.Settings.RayHueDrag);
                        if (newHue >= 1.0f)
                        {
                            newHue -= 1.0f;
                        }
                    }
                    else // ex: 0.1 -> 0.2
                    {
                        newHue = Mathf.Lerp(oldHue, newHue, GlobalState.Settings.RayHueDrag);
                    }
                }

                HSV = new Vector3(newHue, hsv.y, hsv.z); // NOTE: also re-position the cursors.

                colorPicker.OnColorChanged();

                localProjectedWidgetPosition = new Vector3(
                    w2 + mr * -Mathf.Cos(hsv.x * 2.0f * Mathf.PI),
                    -h2 + mr * Mathf.Sin(hsv.x * 2.0f * Mathf.PI),
                    -thickness);
            }
            else if (lockedOnTriangle)
            {
                Vector3 closest;
                Vector3 baryOfClosest;
                ClosestPointToTriangle2D(localProjectedWidgetPosition, pt_A_HUE, pt_B_WHITE, pt_C_BLACK, out closest, out baryOfClosest);
                localProjectedWidgetPosition = new Vector3(closest.x, closest.y, -thickness);
                barycentric = baryOfClosest;

                // DRAG
                //if (!triggerJustClicked)
                //{
                //    localProjectedWidgetPosition = Vector3.Lerp(lastProjected, localProjectedWidgetPosition, GlobalState.Settings.RaySliderDrag);
                //    barycentric = GetBarycentricCoordinates2D(localProjectedWidgetPosition, pt_A_HUE, pt_B_WHITE, pt_C_BLACK);
                //}
                //lastProjected = localProjectedWidgetPosition;

                //float H, S, V;
                //Color.RGBToHSV(BarycentricToRGB(), out H, out S, out V);
                //// TODO: make a function PointInTriangleToRGB(closest, a, b, c), using the resterizer algo to find color instead of barycentric.
                //hsv = new Vector3(hsv.x, S, V);

                Vector3 _sv = PointInTriangleToHSV(closest);
                hsv = new Vector3(hsv.x, _sv.y, _sv.z);

                UpdateCursorPositions();

                colorPicker.OnColorChanged();
            }

            Vector3 worldProjectedWidgetPosition = transform.TransformPoint(localProjectedWidgetPosition);

            rayEndPoint = worldProjectedWidgetPosition;
        }