Пример #1
0
        private void UpdateSelection()
        {
            // Get right controller buttons states
            bool primaryButtonState = VRInput.GetValue(VRInput.primaryController, CommonUsages.primaryButton);
            bool triggerState       = VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton);

            GameObject hoveredObject = Selection.HoveredObject;

            VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.grip,
                                () =>
            {
                Selection.HoveredObject = hoveredObject;
            },
                                () => { Selection.AuxiliarySelection = null; });

            // Multi-selection using the trigger button
            if (triggerState && !GlobalState.Instance.selectionGripped && null != hoveredObject && !selector.Deforming)
            {
                if (!primaryButtonState)
                {
                    foreach (GameObject obj in collidedObjects)
                    {
                        selector.AddSiblingsToSelection(obj);
                    }
                }
            }
        }
Пример #2
0
        protected override void DoUpdate()
        {
            VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.triggerButton,
                                () =>
            {
                group = new CommandGroup("Gun");
            },
                                () =>
            {
                group.Submit();
                group = null;
            }
                                );

            bool triggered = VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton);

            if (triggered && prefabs.Count > 0)
            {
                if (Time.time - prevTime > 1f / fireRate)
                {
                    int           prefabIndex = UnityEngine.Random.Range(0, prefabs.Count);
                    GameObject    spawned     = Instantiate(prefabs[prefabIndex]);
                    ThrowedObject throwed     = spawned.AddComponent <ThrowedObject>();
                    throwed.AddForce(transform.forward * power);
                    throwed.SetScale(objectScale);
                    new CommandAddGameObject(spawned).Submit();
                    Matrix4x4 matrix = SceneManager.RightHanded.worldToLocalMatrix * mouthpiece.localToWorldMatrix;
                    Maths.DecomposeMatrix(matrix, out Vector3 t, out _, out _);
                    Vector3 scale = Vector3.one;
                    SceneManager.SetObjectMatrix(spawned, Matrix4x4.TRS(t, Quaternion.identity, scale));
                    prevTime = Time.time;
                }
            }
        }
Пример #3
0
        private void Update()
        {
            // Trigger action forwarded to Colorize script
            bool triggerState = VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton);

            if (triggerState && collidedObjects.Count > 0)
            {
                // Process then remove objects from the list of collided objects in order to prevent
                // processing the same objects each frame (until trigger exit)
                colorizer.ProcessObjects(collidedObjects.ToList());
                collidedObjects.Clear();
            }

            // Scaling of collider
            if (navigation.CanUseControls(NavigationMode.UsedControls.RIGHT_JOYSTICK))
            {
                Vector2 val = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis);
                if (val != Vector2.zero)
                {
                    float scale = gameObject.transform.localScale.x;
                    if (val.y > 0.3f)
                    {
                        scale += 0.001f;
                    }
                    if (val.y < -0.3f)
                    {
                        scale -= 0.001f;
                    }
                    scale = Mathf.Clamp(scale, 0.001f, 0.5f);
                    gameObject.transform.localScale = new Vector3(scale, scale, scale);
                }
            }
        }
Пример #4
0
        private void UpdateEraser()
        {
            GameObject hoveredObject = Selection.HoveredObject;

            if (null == hoveredObject && Selection.SelectedObjects.Count == 0)
            {
                return;
            }

            // If we have a hovered object, only destroy it
            if (null != hoveredObject)
            {
                // Don't delete UI handles
                if (hoveredObject.GetComponent <UIHandle>())
                {
                    return;
                }

                if (VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton))
                {
                    CommandGroup group = new CommandGroup("Erase Hovered Object");
                    try
                    {
                        RemoveCollidedObject(hoveredObject);
                        selector.RemoveSiblingsFromSelection(hoveredObject, false);

                        new CommandRemoveGameObject(hoveredObject).Submit();
                    }
                    finally
                    {
                        group.Submit();
                    }
                }
            }

            // If we don't have any hovered object but we collided with a selection, delete the whole selection
            else if (collidedObjects.Count > 0 && Selection.IsSelected(collidedObjects[0]))
            {
                if (VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton))
                {
                    CommandGroup group = new CommandGroup("Erase Selected Objects");
                    try
                    {
                        foreach (GameObject gobject in Selection.SelectedObjects)
                        {
                            RemoveCollidedObject(gobject);
                            selector.RemoveSiblingsFromSelection(gobject, false);

                            new CommandRemoveGameObject(gobject).Submit();
                        }
                    }
                    finally
                    {
                        group.Submit();
                    }
                }
            }
        }
Пример #5
0
        // Update is called once per frame
        void Update()
        {
            if (!device.isValid)
            {
                CaptureController();
                CaptureInitialTransforms();
            }

            // GRIP
            if (null != gripTransform)
            {
                float gripAmount = VRInput.GetValue(device, CommonUsages.grip);
                gripTransform.localRotation = initGripRotation * Quaternion.Euler(0, gripAmount * gripRotationAmplitude * gripDirection, 0);
                gripTransform.gameObject.GetComponent <MeshRenderer>().material.SetColor("_BaseColor", gripAmount > 0.01f ? UIOptions.SelectedColor : Color.black);
            }

            // TRIGGER
            if (null != triggerTransform)
            {
                float triggerAmount = VRInput.GetValue(device, CommonUsages.trigger);
                triggerTransform.localRotation = initTriggerRotation * Quaternion.Euler(triggerAmount * triggerRotationAmplitude, 0, 0);
                triggerTransform.gameObject.GetComponent <MeshRenderer>().material.SetColor("_BaseColor", triggerAmount > 0.01f ? UIOptions.SelectedColor : Color.black);
            }

            // JOYSTICK
            if (null != joystickTransform)
            {
                Vector2 joystick = VRInput.GetValue(device, CommonUsages.primary2DAxis);
                joystickTransform.localRotation = initJoystickRotation * Quaternion.Euler(joystick.y * joystickRotationAmplitude, 0, joystick.x * -joystickRotationAmplitude);
                joystickTransform.gameObject.GetComponent <MeshRenderer>().materials[1].SetColor("_BaseColor", joystick.magnitude > 0.05f ? UIOptions.SelectedColor : Color.black);
            }

            // PRIMARY
            if (null != primaryTransform)
            {
                bool primaryState = VRInput.GetValue(device, CommonUsages.primaryButton);
                primaryTransform.localPosition = initPrimaryTranslation;
                primaryTransform.gameObject.GetComponent <MeshRenderer>().material.SetColor("_BaseColor", primaryState ? UIOptions.SelectedColor : Color.black);
                if (primaryState)
                {
                    primaryTransform.localPosition += new Vector3(0, 0, primaryTranslationAmplitude); // TODO: quick anim? CoRoutine.
                }
            }

            // SECONDARY
            if (null != secondaryTransform)
            {
                bool secondaryState = VRInput.GetValue(device, CommonUsages.secondaryButton);
                secondaryTransform.localPosition = initSecondaryTranslation;
                secondaryTransform.gameObject.GetComponent <MeshRenderer>().material.SetColor("_BaseColor", secondaryState ? UIOptions.SelectedColor : Color.black);
                if (secondaryState)
                {
                    secondaryTransform.localPosition += new Vector3(0, 0, secondaryTranslationAmplitude); // TODO: quick anim? CoRoutine.
                }
            }
        }
Пример #6
0
        private void HandlePalette()
        {
            if (null == ToolsUIManager.Instance)
            {
                return;
            }

            if (VRInput.GetValue(VRInput.secondaryController, CommonUsages.trigger) > deadZone)
            {
                ToolsUIManager.Instance.PopUpPalette(true);
            }
            else
            {
                ToolsUIManager.Instance.PopUpPalette(false);
            }
        }
Пример #7
0
        private void SelectObjects(List <GameObject> gobjects)
        {
            bool     primaryState = VRInput.GetValue(VRInput.primaryController, CommonUsages.primaryButton);
            ICommand command;

            if (!primaryState)
            {
                command = new CommandAddToSelection(gobjects);
            }
            else
            {
                command = new CommandRemoveFromSelection(gobjects);
            }
            command.Redo();
            command.Submit();
            selectionHasChanged = true;
        }
        // Update is called once per frame
        void Update()
        {
            if (!device.isValid)
            {
                CaptureController();
                CaptureInitialTransforms();
            }

            // GRIP
            if (null != gripTransform)
            {
                float gripAmount = VRInput.GetValue(device, CommonUsages.grip);
                AnimateGrip(gripAmount);
            }

            // TRIGGER
            if (null != triggerTransform)
            {
                float triggerAmout = VRInput.GetValue(device, CommonUsages.trigger);
                AnimateTrigger(triggerAmout);
            }

            // JOYSTICK
            if (null != joystickTransform)
            {
                Vector2 joystick = VRInput.GetValue(device, CommonUsages.primary2DAxis);
                AnimateJoystick(joystick);
            }

            // PRIMARY
            if (null != primaryTransform)
            {
                bool primaryState = VRInput.GetValue(device, CommonUsages.primaryButton);
                AnimatePrimaryButton(primaryState);
            }

            // SECONDARY
            if (null != secondaryTransform)
            {
                bool secondaryState = VRInput.GetValue(device, CommonUsages.secondaryButton);
                AnimateSecondaryButton(secondaryState);
            }
        }
Пример #9
0
        private Vector4 GetJoysticksValue()
        {
            Vector2 leftJoyValue  = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis);
            Vector2 rightJoyValue = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis);
            Vector4 currentValue  = new Vector4(leftJoyValue.x, leftJoyValue.y, rightJoyValue.x, rightJoyValue.y);

            float damping   = options.fpsDamping * 5f;
            int   elemCount = (int)damping;

            int currentSize = prevJoysticksStates.Count;

            if (currentSize > elemCount)
            {
                prevJoysticksStates.RemoveRange(0, currentSize - elemCount);
                deltaTimes.RemoveRange(0, currentSize - elemCount);
            }

            prevJoysticksStates.Add(currentValue);
            deltaTimes.Add(Time.deltaTime);

            Vector4 average  = Vector4.zero;
            float   invCount = 1f / (float)prevJoysticksStates.Count;

            float dtSum = 0;

            foreach (float dt in deltaTimes)
            {
                dtSum += dt;
            }

            float invDtSum = 1f / dtSum;

            for (int i = 0; i < prevJoysticksStates.Count; i++)
            {
                average += prevJoysticksStates[i] * deltaTimes[i] * invDtSum;
            }

            return(average);
        }
Пример #10
0
        protected override void DoUpdate()
        {
            // Update feedback position and scale
            if (GlobalState.Settings.cameraFeedbackVisible)
            {
                bool trigger = false;
                if (feedbackPositioning &&
                    VRInput.GetValue(VRInput.primaryController, CommonUsages.gripButton))
                {
                    GlobalState.Settings.cameraFeedbackDirection = rig.InverseTransformDirection(transform.forward); // direction local to rig
                    trigger = true;
                }
                if (trigger)
                {
                    // Cam feedback scale
                    Vector2 joystickAxis = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis);
                    float   value        = GlobalState.Settings.cameraFeedbackScaleValue;
                    if (joystickAxis.y > deadZone)
                    {
                        value *= cameraFeedbackScaleFactor;
                    }
                    if (joystickAxis.y < -deadZone)
                    {
                        value /= cameraFeedbackScaleFactor;
                    }
                    GlobalState.Settings.cameraFeedbackScaleValue = Mathf.Clamp(value, GlobalState.Settings.cameraFeedbackMinScaleValue, GlobalState.Settings.cameraFeedbackMaxScaleValue);
                    GlobalState.Instance.cameraFeedback.GetComponent <CameraFeedback>().UpdateTransform();
                }
            }

            // called to update focal slider value
            UpdateUI();

            if (!GlobalState.Settings.cameraFeedbackVisible || !feedbackPositioning)
            {
                base.DoUpdate();
            }
        }
Пример #11
0
        protected override void DoUpdateGui()
        {
            bool gripped = false;

            VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.gripButton, async() =>
            {
                await OnGrabUIObject();

                // Since OnGrabUIObject may take some time, check we are still gripped
                gripped = VRInput.GetValue(VRInput.primaryController, CommonUsages.gripButton);
                if (gripped)
                {
                    OnStartGrip();
                }
            }, () =>
            {
                // Only end grip if we were effectively gripped
                if (gripped)
                {
                    OnEndGrip();
                }
            });
        }
Пример #12
0
 protected override void DoUpdate()
 {
     if (navigation.CanUseControls(NavigationMode.UsedControls.RIGHT_JOYSTICK))
     {
         Vector2 AxisValue = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis);
         if (AxisValue != Vector2.zero)
         {
             float scaleFactor = 1f + GlobalState.Settings.scaleSpeed / 1000f;
             if (null == curveManip)
             {
                 float selectorRadius = mouthpiece.localScale.x;
                 if (AxisValue.y > deadzone)
                 {
                     selectorRadius *= scaleFactor;
                 }
                 if (AxisValue.y < deadzone)
                 {
                     selectorRadius /= scaleFactor;
                 }
                 selectorRadius        = Mathf.Clamp(selectorRadius, 0.001f, 0.5f);
                 mouthpiece.localScale = Vector3.one * selectorRadius;
             }
             else
             {
                 if (AxisValue.y > deadzone)
                 {
                     scaleIndice *= scaleFactor;
                 }
                 if (AxisValue.y < deadzone)
                 {
                     scaleIndice /= scaleFactor;
                 }
                 scaleIndice = Mathf.Clamp(scaleIndice, 0.001f, 100f);
             }
         }
     }
 }
Пример #13
0
        public override void Update()
        {
            if (ray == null)
            {
                return;
            }

            //
            // RAY - collision with scene objects.
            //
            if (!isLocked)
            {
                RaycastHit hit;
                Vector3    worldStart     = paletteController.TransformPoint(0.01f, 0.0f, 0.05f);
                Vector3    worldEnd       = paletteController.TransformPoint(0, 0, 3);
                Vector3    worldDirection = worldEnd - worldStart;
                Ray        r          = new Ray(worldStart, worldDirection);
                int        layersMask = LayerMask.GetMask(new string[] { "Default", "Selection", "Hover" });
                if (Physics.Raycast(r, out hit, 100.0f, layersMask))
                {
                    target         = hit.collider.transform;
                    targetPosition = hit.collider.bounds.center;
                    minDistance    = hit.collider.bounds.extents.magnitude;
                    ray.SetStartPosition(worldStart);
                    ray.SetEndPosition(hit.point);
                    ray.SetActiveColor();
                    if (target)
                    {
                        Selection.HoveredObject = target.gameObject;
                    }
                }
                else
                {
                    if (target)
                    {
                        Selection.HoveredObject = null;
                    }
                    target         = null;
                    targetPosition = Vector3.zero;
                    minDistance    = 0.0f;
                    ray.SetStartPosition(worldStart);
                    ray.SetEndPosition(worldEnd);
                    ray.SetDefaultColor();
                }
            }
            else
            {
                Vector3 up       = Vector3.up; //rig.up;
                Vector3 forward  = Vector3.Normalize(camera.position - targetPosition);
                Vector3 right    = Vector3.Cross(up, forward);
                float   distance = Vector3.Distance(camera.position, targetPosition);

                //
                // Left Joystick -- left/right = rotate left/right.
                //                  up/down = rotate up/down.
                Vector2 val = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis);
                if (val != Vector2.zero)
                {
                    // Horizontal rotation
                    if (Mathf.Abs(val.x) > deadZone)
                    {
                        float value           = Mathf.Sign(val.x) * (Mathf.Abs(val.x) - deadZone) / (1.0f - deadZone); // remap
                        float rotate_amount_h = value * options.orbitRotationalSpeed;                                  //rotationalSpeed;
                        rig.RotateAround(targetPosition, up, -rotate_amount_h);
                    }

                    // Vertical rotation
                    if (Mathf.Abs(val.y) > deadZone)
                    {
                        float value                = Mathf.Sign(val.y) * (Mathf.Abs(val.y) - deadZone) / (1.0f - deadZone); // remap
                        float dot                  = Vector3.Dot(up, forward);
                        bool  in_safe_zone         = (Mathf.Abs(dot) < 0.8f);
                        bool  above_but_going_down = (dot > 0.8f) && (value < 0.0f);
                        bool  below_but_going_up   = (dot < -0.8f) && (value > 0.0f);
                        if (!limitVertical || in_safe_zone || above_but_going_down || below_but_going_up) // only within limits
                        {
                            float rotate_amount_v = value * options.orbitRotationalSpeed;                 //rotationalSpeed;
                            rig.RotateAround(targetPosition, right, -rotate_amount_v);
                        }
                    }
                }

                //
                // Right Joystick -- left/right = move closer/farther
                //                   up/down = scale world
                val = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis);
                if (val != Vector2.zero)
                {
                    float remainingDistance = distance - minDistance;
                    bool  in_safe_zone      = (remainingDistance > 0.0f);

                    // Move the world closer/farther
                    if (Mathf.Abs(val.x) > deadZone)
                    {
                        float value = Mathf.Sign(val.x) * (Mathf.Abs(val.x) - deadZone) / (1.0f - deadZone); // remap
                        bool  too_close_but_going_back = (remainingDistance <= 0.0f) && (value < 0.0f);
                        if (in_safe_zone || too_close_but_going_back)
                        {
                            Vector3 offset = forward * value * (minMoveDistance + options.orbitMoveSpeed * Mathf.Abs(remainingDistance)); //moveSpeed
                            rig.position -= offset;
                        }
                    }

                    /*
                     * // Scale the world
                     * if (Mathf.Abs(val.y) > deadZone)
                     * {
                     *  float value = Mathf.Sign(val.y) * (Mathf.Abs(val.y) - deadZone) / (1.0f - deadZone); // remap
                     *  bool too_close_but_scaling_down = (remainingDistance <= 0.0f) && (value < 0.0f);
                     *  if (in_safe_zone || too_close_but_scaling_down)
                     *  {
                     *      float scale = 1.0f + (value * options.orbitScaleSpeed); // scaleSpeed
                     *
                     *      Vector3 scalePivot = targetPosition;
                     *      Vector3 pivot_to_world = world.position - scalePivot;
                     *      pivot_to_world.Scale(new Vector3(scale, scale, scale));
                     *      world.position = scalePivot + pivot_to_world;
                     *      targetPosition = world.position - pivot_to_world;
                     *      minDistance *= scale;
                     *
                     *      float finalScale = scale * world.localScale.x;
                     *      float clampedScale = Mathf.Clamp(finalScale, 1.0f / maxPlayerScale, minPlayerScale);
                     *
                     *      // should touch rig, not world
                     *      world.localScale = new Vector3(clampedScale, clampedScale, clampedScale);
                     *
                     *      GlobalState.WorldScale = world.localScale.x;
                     *
                     *      UpdateCameraClipPlanes();
                     *  }
                     * }
                     */
                }

                // Position the ray AFTER the rotation of the camera, to avoid a one frame shift.
                ray.SetStartPosition(paletteController.TransformPoint(0.01f, 0.0f, 0.05f));
                ray.SetEndPosition(targetPosition);
            }


            //
            // LEFT GRIP (click) - lock on targetted object/point.
            //

            VRInput.ButtonEvent(VRInput.secondaryController, CommonUsages.gripButton,
                                () =>
            {
                if (target != null)
                {
                    isLocked = true;
                    ray.gameObject.SetActive(false); // hide ray on grip
                }

                GlobalState.IsGrippingWorld = true;
            },
                                () =>
            {
                isLocked = false;
                ray.gameObject.SetActive(true);
                GlobalState.IsGrippingWorld = false;
            });
        }
Пример #14
0
        public override void Update()
        {
            //
            // LEFT GRIP WORLD
            //

            VRInput.ButtonEvent(VRInput.secondaryController, CommonUsages.gripButton,
                                () =>
            {
                // left AFTER right => reset all
                // NOTE: isRightGripped && Selection.selection.Count > 0 means that the selectionTool will/has gripped objects,
                //       and is no longer able to be used for two-hands interaction.
                if (isRightGripped) // && Selection.selection.Count == 0)
                {
                    ResetInitControllerMatrices(ResetType.LEFT_AND_RIGHT);
                    ResetInitWorldMatrix();
                    ResetDistance(); // after reset world, use scale

                    SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL);

                    lineUI.Show(true, StretchUI.LineMode.DOUBLE);
                    GlobalState.IsGrippingWorld = true;
                    ToolsManager.ActivateCurrentTool(false);
                }

                isLeftGripped = true;
            },
                                () =>
            {
                SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL);

                lineUI.Show(false);
                ToolsManager.ActivateCurrentTool(true);
                GlobalState.IsGrippingWorld = false;

                isLeftGripped = false;
            });

            //
            // RIGHT GRIP WORLD
            //

            // NOTE: On ne peut predire dans quel ordre les Update vont s'executer. Le Selector/SelectorTrigger peuvent
            //       recuperer le LeftGrip avant nous, et commencer a grip un objet avant qu'on ait pu set la property
            //       GlobalState.IsGrippingWorld. Cela pose-t-il encore un probleme?
            VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.gripButton,
                                () =>
            {
                //if (Selection.selection.Count == 0)
                {
                    // right AFTER left and no selection, reset all
                    if (isLeftGripped)
                    {
                        ResetInitControllerMatrices(ResetType.LEFT_AND_RIGHT);
                        ResetInitWorldMatrix();
                        ResetDistance(); // NOTE: called after "reset world", because it uses the scale.

                        SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL);
                        lineUI.Show(true, StretchUI.LineMode.DOUBLE);
                        GlobalState.IsGrippingWorld = true;
                        ToolsManager.ActivateCurrentTool(false);
                    }

                    // even if no left gripped, just flag the right as gripped for the next update
                    isRightGripped = true;
                }
            },
                                () =>
            {
                // si on relache le right et que le left est tjs grip, reset left
                if (isLeftGripped)
                {
                    ResetInitControllerMatrices(ResetType.LEFT_ONLY);
                    ResetInitWorldMatrix();

                    SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL);
                }
                //lineUI.Show(true, StretchUI.LineMode.SINGLE);
                ToolsManager.ActivateCurrentTool(true);
                GlobalState.IsGrippingWorld = false;

                isRightGripped = false;
            });

            // NOTE: we test isLeftGrip because we can be ungripped but still over the deadzone, strangely.
            if (isLeftGripped && VRInput.GetValue(VRInput.secondaryController, CommonUsages.grip) > deadZone)
            {
                if (isRightGripped)
                {
                    float prevScale = scale;

                    VRInput.GetControllerTransform(VRInput.secondaryController, out Vector3 currentLeftControllerPosition_L, out Quaternion currentLeftControllerRotation_L);
                    VRInput.GetControllerTransform(VRInput.primaryController, out Vector3 currentRightControllerPosition_L, out Quaternion currentRightControllerRotation_L);

                    Matrix4x4 currentLeftControllerMatrix_L_Scaled = Matrix4x4.TRS(currentLeftControllerPosition_L, currentLeftControllerRotation_L, new Vector3(scale, scale, scale));
                    Matrix4x4 currentLeftControllerMatrix_W        = initPivotMatrix * currentLeftControllerMatrix_L_Scaled;
                    Vector3   currentLeftControllerPosition_W      = currentLeftControllerMatrix_W.MultiplyPoint(Vector3.zero);

                    // update right joystick
                    Matrix4x4 currentRightControllerMatrix_L_Scaled = Matrix4x4.TRS(currentRightControllerPosition_L, currentRightControllerRotation_L, new Vector3(scale, scale, scale));
                    Vector3   currentRightControllerPosition_W      = (initPivotMatrix * currentRightControllerMatrix_L_Scaled).MultiplyPoint(Vector3.zero);

                    // scale handling (before computing the "transformed" matrix with the new scale)
                    float newDistance = Vector3.Distance(currentLeftControllerPosition_W, currentRightControllerPosition_W);
                    float factor      = newDistance / prevDistance;

                    float oldScale = scale;
                    scale       *= factor;
                    prevDistance = newDistance;

                    Vector3    middlePosition_L    = (currentLeftControllerPosition_L + currentRightControllerPosition_L) * 0.5f;
                    Vector3    middleXVector       = (currentRightControllerPosition_L - currentLeftControllerPosition_L).normalized;
                    Vector3    middleForwardVector = -Vector3.Cross(middleXVector, pivot.up).normalized;
                    Quaternion middleRotation_L    = Quaternion.LookRotation(middleForwardVector, pivot.up);

                    Matrix4x4 middleMatrix_L_Scaled = Matrix4x4.TRS(middlePosition_L, middleRotation_L, Vector3.one) * Matrix4x4.Scale(Vector3.one * scale);
                    Matrix4x4 middleMatrix_W_Delta  = initPivotMatrix * middleMatrix_L_Scaled * initMiddleMatrix_WtoL;
                    Matrix4x4 transformed           = middleMatrix_W_Delta * initWorldMatrix_W;
                    transformed = transformed.inverse;

                    float s            = 1.0f;
                    float clampedScale = Mathf.Clamp(transformed.lossyScale.x, 1.0f / maxPlayerScale, minPlayerScale);
                    if (transformed.lossyScale.x == clampedScale)
                    {
                        // translate/rotate/scale using the new scale
                        rig.localPosition = new Vector3(transformed.GetColumn(3).x, transformed.GetColumn(3).y, transformed.GetColumn(3).z);
                        rig.localRotation = transformed.rotation;
                        rig.localScale    = new Vector3(clampedScale, clampedScale, clampedScale);

                        s = oldScale;
                    }

                    // Get head position
                    VRInput.GetControllerTransform(VRInput.head, out Vector3 HeadPosition, out Quaternion headRotation);
                    Matrix4x4 invHeadMatrix = Matrix4x4.TRS(HeadPosition, headRotation, Vector3.one).inverse;
                    // Project left & right controller into head matrix to determine which one is on the left
                    Vector3 leftControllerInHeadMatrix  = invHeadMatrix.MultiplyPoint(currentLeftControllerPosition_L);
                    Vector3 rightControllerInHeadMatrix = invHeadMatrix.MultiplyPoint(currentRightControllerPosition_L);
                    // reverse text if right and left hands are crossed
                    if (leftControllerInHeadMatrix.x > rightControllerInHeadMatrix.x)
                    {
                        middleXVector = -middleXVector;
                    }

                    // Rotation for the line text
                    Vector3    middleForward180              = Vector3.Cross(middleXVector, pivot.up).normalized;
                    Vector3    rolledUp                      = Vector3.Cross(-middleXVector, middleForward180).normalized;
                    Quaternion middleRotationWithRoll_L      = Quaternion.LookRotation(middleForward180, rolledUp);
                    Matrix4x4  middleMatrixWithRoll_L_Scaled = Matrix4x4.TRS(middlePosition_L, middleRotationWithRoll_L, new Vector3(s, s, s));
                    Quaternion middleRotationWithRoll_W      = (pivot.localToWorldMatrix * middleMatrixWithRoll_L_Scaled).rotation;

                    lineUI.UpdateLineUI(pivot.TransformPoint(currentLeftControllerPosition_L), pivot.TransformPoint(currentRightControllerPosition_L), middleRotationWithRoll_W, 1f / GlobalState.WorldScale);
                }
                GlobalState.WorldScale = 1f / rig.localScale.x;

                UpdateCameraClipPlanes();
            }
        }
Пример #15
0
        public override void Update()
        {
            if (teleport == null)
            {
                return;
            }

            // Teleport
            Vector2 leftJoyValue = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis);
            float   joyMag       = leftJoyValue.magnitude;
            float   yVal         = leftJoyValue.y;
            float   xVal         = leftJoyValue.x;

            if (teleporting)
            {
                if (joyMag > deadZone)
                {
                    Vector3 rayStartPosition  = GlobalState.Instance.VRControllers.GetFrontAnchor().position;
                    Vector3 rayStartDirection = GlobalState.Instance.VRControllers.GetFrontAnchor().up;

                    List <Vector3> points;
                    RaycastHit     hitInfo;
                    bool           hit = ComputeTrajectory(rayStartPosition, rayStartDirection, trajectoryParams, out points, out hitInfo);
                    if (hit)
                    {
                        isValidLocationHit = true;
                        teleportTarget     = hitInfo.point;
                        teleport.SetActiveColor();
                        teleportTargetObject.gameObject.SetActive(true);
                    }
                    else
                    {
                        teleport.SetImpossibleColor();
                        teleportTargetObject.gameObject.SetActive(false);
                    }

                    float cameraYAngle = Camera.main.transform.rotation.eulerAngles.y;
                    float joyAngle     = 90.0f - Mathf.Rad2Deg * Mathf.Atan2(leftJoyValue.y, leftJoyValue.x);
                    teleportRay.positionCount = points.Count;
                    teleportRay.SetPositions(points.ToArray());
                    teleportTargetObject.position = teleportTarget + new Vector3(0f, 0.01f, 0f);
                    teleportTargetObject.rotation = Quaternion.Euler(0.0f, cameraYAngle + joyAngle, 0.0f);
                    teleportRay.startWidth        = rayWidth / GlobalState.WorldScale;
                    teleportRay.endWidth          = rayWidth / GlobalState.WorldScale;
                }
                else // GO OUT of teleport mode, and TELEPORT
                {
                    teleporting = false;

                    if (isValidLocationHit)
                    {
                        float   cameraHeight = camera.position.y;
                        Vector3 cameraToRig  = rig.position;
                        cameraToRig = camera.InverseTransformPoint(cameraToRig);

                        Vector3    cameraForwardProj = new Vector3(camera.forward.x, 0.0f, camera.forward.z).normalized;
                        float      YAngleDelta       = Vector3.SignedAngle(cameraForwardProj, teleportTargetObject.forward, Vector3.up);
                        Quaternion deltaRotation     = Quaternion.Euler(0.0f, YAngleDelta, 0.0f);
                        rig.rotation = rig.rotation * deltaRotation;

                        /* place camera above target
                         * Vector3 camera_to_rig = rig.transform.position - camera.transform.position;
                         * Vector3 new_camera_to_target = new Vector3(0.0f, teleportTarget.y - camera.transform.position.y, 0.0f);
                         * Vector3 deltaPosition = camera_to_rig - new_camera_to_target;
                         */
                        rig.position = teleportTarget;

                        rig.localScale = Vector3.one;

                        if (options.lockHeight)
                        {
                            rig.position = new Vector3(rig.position.x, cameraHeight + cameraToRig.y, rig.position.z);
                        }

                        GlobalState.WorldScale = 1f;
                        UpdateCameraClipPlanes();

                        isValidLocationHit = false;
                    }

                    teleport.gameObject.SetActive(false);
                }
            }
            else
            {
                // GO IN teleport mode
                if (yVal > deadZone)
                {
                    teleporting = true;
                    teleport.gameObject.SetActive(true);
                    teleportTargetObject.gameObject.layer = 2; // Ignore Raycast - TODO: put in prefab.
                }
                else
                {
                    // ROTATE +/- 45 degrees using Left/Right impulses.
                    if (Mathf.Abs(xVal) > 0.8f && !rotating)
                    {
                        rig.RotateAround(camera.position, Vector3.up, Mathf.Sign(xVal) * 45f);
                        rotating = true;
                    }
                    if (Mathf.Abs(xVal) <= 0.8f && rotating)
                    {
                        rotating = false;
                    }
                }
            }
        }
Пример #16
0
        public override void Update()
        {
            // TODO: on garde le rotate 45 degres ou on le reserve au mode teleport (et on fait du continu vomitif pour le mode fly)?

            //
            // Joystick -- go forward/backward, and rotate 45 degrees.
            //

            Vector2 val = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis);

            if (val != Vector2.zero)
            {
                float d = Vector3.Distance(world.transform.TransformPoint(Vector3.one), world.transform.TransformPoint(Vector3.zero));

                Vector3 velocity = Camera.main.transform.forward * val.y * d;
                rig.position += velocity * flySpeed;

                if (Mathf.Abs(val.x) > 0.95f && !rotating)
                {
                    rig.rotation *= Quaternion.Euler(0f, Mathf.Sign(val.x) * 45f, 0f);
                    rotating      = true;
                }
                if (Mathf.Abs(val.x) <= 0.95f && rotating)
                {
                    rotating = false;
                }
            }

            //
            // LEFT GRIP WORLD (on click)
            //

            VRInput.ButtonEvent(VRInput.secondaryController, CommonUsages.gripButton,
                                () =>
            {
                ResetInitControllerMatrices();
                ResetInitWorldMatrix();

                SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL);
                isLeftGripped = true;
                GlobalState.IsGrippingWorld = true;
            },
                                () =>
            {
                SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL);
                isLeftGripped = false;
                GlobalState.IsGrippingWorld = false;
            });

            // NOTE: we test isLeftGrip because we can be ungripped but still over the deadzone, strangely.
            if (isLeftGripped && VRInput.GetValue(VRInput.secondaryController, CommonUsages.grip) > deadZone)
            {
                float prevScale = scale;

                // Scale using left joystick.
                Vector2 joystickAxis = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis);
                if (joystickAxis.y > deadZone)
                {
                    scale *= fixedScaleFactor;
                }
                if (joystickAxis.y < -deadZone)
                {
                    scale /= fixedScaleFactor;
                }

                // update left joystick
                Vector3    currentLeftControllerPosition_L;
                Quaternion currentLeftControllerRotation_L;
                VRInput.GetControllerTransform(VRInput.secondaryController, out currentLeftControllerPosition_L, out currentLeftControllerRotation_L);
                Matrix4x4 currentLeftControllerMatrix_L_Scaled = Matrix4x4.TRS(currentLeftControllerPosition_L, currentLeftControllerRotation_L, new Vector3(scale, scale, scale));

                Matrix4x4 currentLeftControllerMatrix_W_Delta = initPivotMatrix * currentLeftControllerMatrix_L_Scaled * initLeftControllerMatrix_WtoL;
                Matrix4x4 transformed = currentLeftControllerMatrix_W_Delta * initRigMatrix_W;

                transformed = transformed.inverse;

                rig.localPosition = new Vector3(transformed.GetColumn(3).x, transformed.GetColumn(3).y, transformed.GetColumn(3).z);
                rig.localRotation = transformed.rotation;
                float clampedScale = Mathf.Clamp(transformed.lossyScale.x, 1.0f / maxPlayerScale, minPlayerScale);
                rig.localScale = new Vector3(clampedScale, clampedScale, clampedScale);
                if (transformed.lossyScale.x != clampedScale)
                {
                    scale = prevScale;
                }

                GlobalState.WorldScale = 1f / rig.localScale.x;

                UpdateCameraClipPlanes();
            }
        }
Пример #17
0
        private void UpdateToolPaint(Vector3 position, Quaternion _)
        {
            // ON TRIGGER
            VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.trigger, () =>
            {
                BeginPaint();

                paintPrevPosition = Vector3.zero;
                undoGroup         = new CommandGroup("Paint");
            },
                                () =>
            {
                try
                {
                    EndCurrentPaint();
                }
                finally
                {
                    if (null != undoGroup)
                    {
                        undoGroup.Submit();
                        undoGroup = null;
                    }
                }
            });

            float triggerValue = VRInput.GetValue(VRInput.primaryController, CommonUsages.trigger);

            // Change brush size
            if (navigation.CanUseControls(NavigationMode.UsedControls.RIGHT_JOYSTICK))
            {
                Vector2 val = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis);
                if (val != Vector2.zero)
                {
                    if (val.y > 0.3f)
                    {
                        brushSize += 0.001f;
                    }
                    if (val.y < -0.3f)
                    {
                        brushSize -= 0.001f;
                    }
                    brushSize             = Mathf.Clamp(brushSize, 0.001f, 0.5f);
                    mouthpiece.localScale = new Vector3(brushSize, brushSize, brushSize);
                }
            }

            paintLineRenderer.enabled = false;
            Vector3 penPosition = mouthpiece.position;

            if (paintOnSurface)
            {
                Vector3 direction = transform.forward; // (paintItem.position - centerEye.position).normalized;
                Vector3 startRay  = penPosition + mouthpiece.lossyScale.x * direction;
                Vector3 endRay    = startRay + 1000f * direction;
                paintLineRenderer.enabled       = true;
                paintLineRenderer.positionCount = 2;
                paintLineRenderer.SetPosition(0, startRay);
                paintLineRenderer.SetPosition(1, endRay);
                paintLineRenderer.startWidth = 0.005f / GlobalState.WorldScale;
                paintLineRenderer.endWidth   = paintLineRenderer.startWidth;
                bool hit = Physics.Raycast(startRay, direction, out RaycastHit hitInfo, Mathf.Infinity);
                if (!hit)
                {
                    return;
                }
                penPosition = hitInfo.point - 0.001f * direction;
                paintLineRenderer.SetPosition(1, penPosition);
            }
            else if (paintTool == PaintTools.Volume)
            {
                if (currentVolume)
                {
                    VolumeController controller = currentVolume.GetComponent <VolumeController>();
                    if (null != controller)
                    {
                        paintLineRenderer.enabled = true;

                        Vector3 C = controller.bounds.center;
                        Vector3 E = controller.bounds.extents;

                        Vector3 tlf = controller.transform.TransformPoint(C + new Vector3(-E.x, E.y, -E.z));
                        Vector3 trf = controller.transform.TransformPoint(C + new Vector3(E.x, E.y, -E.z));
                        Vector3 blf = controller.transform.TransformPoint(C + new Vector3(-E.x, -E.y, -E.z));
                        Vector3 brf = controller.transform.TransformPoint(C + new Vector3(E.x, -E.y, -E.z));
                        Vector3 tlb = controller.transform.TransformPoint(C + new Vector3(-E.x, E.y, E.z));
                        Vector3 trb = controller.transform.TransformPoint(C + new Vector3(E.x, E.y, E.z));
                        Vector3 blb = controller.transform.TransformPoint(C + new Vector3(-E.x, -E.y, E.z));
                        Vector3 brb = controller.transform.TransformPoint(C + new Vector3(E.x, -E.y, E.z));

                        paintLineRenderer.positionCount = 16;
                        paintLineRenderer.SetPositions(new Vector3[] {
                            blf, tlf, brf, trf, brb, trb, blb,
                            blf, brf, brb, blb,
                            tlb, tlf, trf, trb, tlb
                        });
                        paintLineRenderer.startWidth = 0.001f / GlobalState.WorldScale;
                        paintLineRenderer.endWidth   = 0.001f / GlobalState.WorldScale;
                    }
                }
            }

            // Draw
            float deadZone = VRInput.deadZoneIn;

            if (triggerValue >= deadZone &&
                (
                    (position != paintPrevPosition && currentPaint != null) || currentVolume != null)
                )
            {
                // Add a point (the current world position) to the line renderer

                float pressure = (triggerValue - deadZone) / (1f - deadZone);
                float value    = brushSize / GlobalState.WorldScale * pressure;

                switch (paintTool)
                {
                case PaintTools.Pencil: freeDraw.AddControlPoint(penPosition, 0.5f * value); break;

                case PaintTools.FlatPencil: freeDraw.AddFlatLineControlPoint(penPosition, -transform.forward, 0.5f * value); break;

                case PaintTools.ConvexHull: freeDraw.AddConvexHullPoint(penPosition); break;

                case PaintTools.Volume: volumeGenerator.AddPoint(penPosition, 2.0f * value * strength); break;
                }

                switch (paintTool)
                {
                case PaintTools.Pencil:
                case PaintTools.FlatPencil:
                case PaintTools.ConvexHull:
                {
                    // set mesh components
                    MeshFilter meshFilter = currentPaint.GetComponent <MeshFilter>();
                    Mesh       mesh       = meshFilter.mesh;
                    mesh.Clear();
                    mesh.vertices  = freeDraw.vertices;
                    mesh.normals   = freeDraw.normals;
                    mesh.triangles = freeDraw.triangles;
                    break;
                }

                case PaintTools.Volume:
                    if (null != currentVolume)
                    {
                        MeshFilter meshFilter = currentVolume.GetComponent <MeshFilter>();
                        Mesh       mesh       = meshFilter.mesh;
                        mesh.Clear();
                        mesh.vertices  = volumeGenerator.vertices;
                        mesh.triangles = volumeGenerator.triangles;
                        mesh.RecalculateNormals();

                        // Recompute collider
                        MeshCollider meshCollider = currentVolume.GetComponent <MeshCollider>();
                        meshCollider.sharedMesh = mesh;
                        // force update
                        meshCollider.enabled = false;
                        meshCollider.enabled = true;

                        VolumeController controller = currentVolume.GetComponent <VolumeController>();
                        controller.origin     = volumeGenerator.origin;
                        controller.bounds     = volumeGenerator.bounds; // TODO: dont duplicate data? use volumeparameters in volumegenerator?
                        controller.field      = volumeGenerator.field;
                        controller.resolution = volumeGenerator.resolution;
                        controller.stepSize   = volumeGenerator.stepSize;
                        //controller.UpdateBoundsRenderer();
                    }
                    break;
                }
            }

            paintPrevPosition = position;
        }