// Envoi des vibrations dans la manette jusqu'à ce que le joueur se décide à tourner les photos
    IEnumerator FirstTimeUsingHapticCoroutine()
    {
        while (firstTimeUsing)
        {
            yield return(new WaitForSeconds(1));

            if (lastControllerActions != null && blackoutProgression <= 0 && !pressingButton)
            {
                lastControllerActions.TriggerHapticPulse(.1f);
            }
        }
    }
        public void Update()
        {
            if (frictionObjects != null)
            {
                if (frictionObjects.Count > 0)
                {
                    //CheckTouchedObjectList();

                    if (frictionObjects[0] != null && !frictionObjects[0].IsGrabbed && frictionObjects[0].enabled)
                    {
                        VRTK_FrictionObject friction = frictionObjects[0];
                        //Debug.Log(frictionObjects[0].name + "\n");

                        float dist = (myLastTouchingPosition - transform.position).magnitude * 200;
                        //If we're moving
                        if (dist > friction.minimumVelocity)
                        {
                            ushort total = (ushort)Mathf.Clamp(dist * friction.velocityMultiplier, friction.hapticDensity.x, friction.hapticDensity.y);
                            //Debug.Log(dist + "\t  " + total + "  \n" + touchedObjectActiveColliders.Count + "  ");
                            //Debug.Log(friction.hapticFriction + "\n" + dist + "  " + total + "\n");
                            controllerActions.TriggerHapticPulse(total, friction.hapticFriction.x * friction.hapticFriction.y, friction.hapticFriction.y);
                        }
                    }
                }
                myLastTouchingPosition = transform.position;
            }
        }
Esempio n. 3
0
        private void AttemptGrabObject()
        {
            var objectToGrab = GetGrabbableObject();

            if (objectToGrab != null)
            {
                IncrementGrabState();
                var initialGrabAttempt = false;
                var objectToGrabScript = objectToGrab.GetComponent <VRTK_InteractableObject>();

                if (grabbedObject == null && IsObjectGrabbable(interactTouch.GetTouchedObject()))
                {
                    initialGrabAttempt = CheckGrabAttempt(objectToGrabScript);
                }

                undroppableGrabbedObject = (grabbedObject && grabbedObject.GetComponent <VRTK_InteractableObject>() && !grabbedObject.GetComponent <VRTK_InteractableObject>().IsDroppable() ? grabbedObject : null);

                if (grabbedObject && initialGrabAttempt)
                {
                    var rumbleAmount = grabbedObject.GetComponent <VRTK_InteractableObject>().rumbleOnGrab;
                    if (!rumbleAmount.Equals(Vector2.zero))
                    {
                        controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                    }
                }
            }
            else
            {
                grabPrecognitionTimer = Time.time + grabPrecognition;
            }
        }
Esempio n. 4
0
        private void OnTriggerStay(Collider collider)
        {
            if (touchedObject == null && IsObjectInteractable(collider.gameObject))
            {
                if (collider.gameObject.GetComponent <VRTK_InteractableObject>())
                {
                    touchedObject = collider.gameObject;
                }
                else
                {
                    touchedObject = collider.gameObject.GetComponentInParent <VRTK_InteractableObject>().gameObject;
                }

                OnControllerTouchInteractableObject(SetControllerInteractEvent(touchedObject));
                touchedObject.GetComponent <VRTK_InteractableObject>().ToggleHighlight(true, globalTouchHighlightColor);
                touchedObject.GetComponent <VRTK_InteractableObject>().StartTouching(this.gameObject);

                if (controllerActions.IsControllerVisible() && hideControllerOnTouch)
                {
                    Invoke("HideController", hideControllerDelay);
                }

                var rumbleAmount = touchedObject.GetComponent <VRTK_InteractableObject>().rumbleOnTouch;
                if (!rumbleAmount.Equals(Vector2.zero))
                {
                    controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, (int)rumbleAmount.x, 0.05f);
                }
            }
        }
Esempio n. 5
0
 private void TriggerHapticPulse(VRTK_ControllerActions controllerActions, float strength, float duration, float interval)
 {
     if (controllerActions)
     {
         controllerActions.TriggerHapticPulse(strength, duration, (interval >= minInterval ? interval : minInterval));
     }
 }
Esempio n. 6
0
        private void AttemptGrabObject()
        {
            var objectToGrab = GetGrabbableObject();

            if (objectToGrab != null)
            {
                IncrementGrabState();
                var initialGrabAttempt = false;

                if (objectToGrab.GetComponent <VRTK_InteractableObject>().AttachIsTrackObject())
                {
                    initialGrabAttempt = GrabTrackedObject();
                }
                else
                {
                    initialGrabAttempt = GrabInteractedObject();
                }

                if (grabbedObject && initialGrabAttempt)
                {
                    VRTK_InteractableObject grabbedInteractableObject = grabbedObject.GetComponent <VRTK_InteractableObject>();
                    var rumbleAmount = grabbedInteractableObject.rumbleOnGrab;
                    if (!rumbleAmount.Equals(Vector2.zero))
                    {
                        controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                    }
                    if (hasAnimations)
                    {
                        if (grabbedInteractableObject.grabLarge)
                        {
                            animator.GrabLarge();
                        }
                        else if (grabbedInteractableObject.grabSmall)
                        {
                            animator.GrabSmall();
                        }
                        else if (grabbedInteractableObject.grabStickUp)
                        {
                            animator.GrabStickUp();
                        }
                        else if (grabbedInteractableObject.grabStickFront)
                        {
                            animator.GrabStickFront();
                        }
                        else
                        {
                            animator.Grab();
                        }
                    }
                }
            }
            else
            {
                grabPrecognitionTimer = grabPrecognition;
                if (createRigidBodyWhenNotTouching)
                {
                    interactTouch.ToggleControllerRigidBody(true);
                }
            }
        }
Esempio n. 7
0
        private void OnTriggerStay(Collider collider)
        {
            if (!enabled)
            {
                return;
            }

            if (touchedObject != null && touchedObject != lastTouchedObject && !touchedObject.GetComponent <VRTK_InteractableObject>().IsGrabbed())
            {
                // 如果当前触碰物体不为空,并且和最新的触碰对象不一样,且此物体还没有被抓取,那么手柄应该触碰最新的进入范围的游戏对象

                CancelInvoke("ResetTriggerRumble"); // 取消ResetTriggerRumble调用
                ResetTriggerRumble();               // 调用ResetTriggerRumble
                ForceStopTouching();                // 停止触碰当前的触碰物体,touchedObject = null
            }

            if (touchedObject == null && IsObjectInteractable(collider.gameObject))
            {
                // 如果当前没有正在触碰的物体且进入范围的碰撞器对应的游戏对象可以交互

                // 将停留在范围内的碰撞器对应的游戏对象作为当前触碰对象和最新触碰对象
                touchedObject     = GetColliderInteractableObject(collider);
                lastTouchedObject = touchedObject;

                var touchedObjectScript = touchedObject.GetComponent <VRTK_InteractableObject>();

                if (!touchedObjectScript.IsValidInteractableController(gameObject, touchedObjectScript.allowedTouchControllers))
                {
                    // 如果新进来的物体不允许与当前手柄交互,那么就不能交互
                    touchedObject = null;
                    return;
                }

                // 是否隐藏手柄
                updatedHideControllerOnTouch = touchedObjectScript.CheckHideMode(hideControllerOnTouch, touchedObjectScript.hideControllerOnTouch);
                // 发送事件,回调委托给ControllerTouchInteractableObject的方法,参数为touchedObject
                OnControllerTouchInteractableObject(SetControllerInteractEvent(touchedObject));
                // 让可交互物体开启高亮
                touchedObjectScript.ToggleHighlight(true, globalTouchHighlightColor);
                touchedObjectScript.StartTouching(gameObject);

                if (controllerActions.IsControllerVisible() && updatedHideControllerOnTouch)
                {
                    // 如果当前手柄可见并且设定触碰时隐藏,就调用HideController方法
                    Invoke("HideController", hideControllerDelay);
                }

                // 处理手柄上的震动反馈,需要controllerActions
                // 从物体上的脚本获取震动数据
                var rumbleAmount = touchedObjectScript.rumbleOnTouch;
                if (!rumbleAmount.Equals(Vector2.zero) && !triggerRumble)
                {
                    // 如果震动不为0,并且还没有震动,就开始震动
                    triggerRumble = true;
                    controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                    // rumbleAmount.x秒后停止震动
                    Invoke("ResetTriggerRumble", rumbleAmount.x);
                }
            }
        }
Esempio n. 8
0
        private void UseInteractedObject(GameObject touchedObject)
        {
            if ((usingObject == null || usingObject != touchedObject) && IsObjectUsable(touchedObject))
            {
                usingObject = touchedObject;
                var usingObjectScript = usingObject.GetComponent <VRTK_InteractableObject>();

                if (!usingObjectScript.IsValidInteractableController(gameObject, usingObjectScript.allowedUseControllers))
                {
                    usingObject = null;
                    return;
                }

                updatedHideControllerOnUse = usingObjectScript.CheckHideMode(hideControllerOnUse, usingObjectScript.hideControllerOnUse);
                OnControllerUseInteractableObject(interactTouch.SetControllerInteractEvent(usingObject));
                usingObjectScript.StartUsing(gameObject);

                if (updatedHideControllerOnUse)
                {
                    Invoke("HideController", hideControllerDelay);
                }

                usingObjectScript.ToggleHighlight(false);

                var rumbleAmount = usingObjectScript.rumbleOnUse;
                if (!rumbleAmount.Equals(Vector2.zero))
                {
                    controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                }
            }
        }
Esempio n. 9
0
        private void CheckRumbleController(VRTK_InteractableObject touchedObjectScript)
        {
            var rumbleAmount = touchedObjectScript.rumbleOnTouch;

            if (!rumbleAmount.Equals(Vector2.zero) && !triggerRumble)
            {
                triggerRumble = true;
                controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                Invoke("ResetTriggerRumble", rumbleAmount.x);
            }
        }
        private void OnTriggerStay(Collider collider)
        {
            if (!enabled)
            {
                return;
            }

            if (touchedObject != null && touchedObject != lastTouchedObject && touchedObject != collider.gameObject && !touchedObject.GetComponent <VRTK_InteractableObject>().IsGrabbed())
            {
                CancelInvoke("ResetTriggerRumble");
                ResetTriggerRumble();
                ForceStopTouching();
            }

            if (touchedObject == null && IsObjectInteractable(collider.gameObject))
            {
                touchedObject     = GetColliderInteractableObject(collider);
                lastTouchedObject = touchedObject;

                var touchedObjectScript = touchedObject.GetComponent <VRTK_InteractableObject>();

                if (!touchedObjectScript.IsValidInteractableController(gameObject, touchedObjectScript.allowedTouchControllers))
                {
                    touchedObject = null;
                    return;
                }

                CheckButtonOverrides(touchedObjectScript);

                updatedHideControllerOnTouch = touchedObjectScript.CheckHideMode(hideControllerOnTouch, touchedObjectScript.hideControllerOnTouch);
                OnControllerTouchInteractableObject(SetControllerInteractEvent(touchedObject));
                touchedObjectScript.ToggleHighlight(true, globalTouchHighlightColor);
                touchedObjectScript.StartTouching(gameObject);

                if (controllerActions.IsControllerVisible() && updatedHideControllerOnTouch)
                {
                    Invoke("HideController", hideControllerDelay);
                }

                var rumbleAmount = touchedObjectScript.rumbleOnTouch;
                if (!rumbleAmount.Equals(Vector2.zero) && !triggerRumble)
                {
                    triggerRumble = true;
                    controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                    Invoke("ResetTriggerRumble", rumbleAmount.x);
                }
            }
        }
Esempio n. 11
0
        private void OnTriggerStay(Collider collider)
        {
            if (touchedObject != null && touchedObject != lastTouchedObject && !touchedObject.GetComponent <VRTK_InteractableObject>().IsGrabbed())
            {
                ForceStopTouching();
            }

            if (touchedObject == null && IsObjectInteractable(collider.gameObject))
            {
                if (collider.gameObject.GetComponent <VRTK_InteractableObject>())
                {
                    touchedObject = collider.gameObject;
                }
                else
                {
                    touchedObject = collider.gameObject.GetComponentInParent <VRTK_InteractableObject>().gameObject;
                }

                var touchedObjectScript = touchedObject.GetComponent <VRTK_InteractableObject>();

                if (!touchedObjectScript.IsValidInteractableController(this.gameObject, touchedObjectScript.allowedTouchControllers))
                {
                    touchedObject = null;
                    return;
                }

                OnControllerTouchInteractableObject(SetControllerInteractEvent(touchedObject));
                touchedObjectScript.ToggleHighlight(true, globalTouchHighlightColor);
                touchedObjectScript.StartTouching(this.gameObject);

                if (controllerActions.IsControllerVisible() && hideControllerOnTouch)
                {
                    Invoke("HideController", hideControllerDelay);
                }

                var rumbleAmount = touchedObjectScript.rumbleOnTouch;
                if (!rumbleAmount.Equals(Vector2.zero) && !triggerRumble)
                {
                    triggerRumble = true;
                    controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                    Invoke("ResetTriggerRumble", rumbleAmount.x);
                }
            }
        }
Esempio n. 12
0
        private void UseInteractedObject(GameObject touchedObject)
        {
            if ((usingObject == null || usingObject != touchedObject) && IsObjectUsable(touchedObject))
            {
                usingObject = touchedObject;
                OnControllerUseInteractableObject(interactTouch.SetControllerInteractEvent(usingObject));
                usingObject.GetComponent <VRTK_InteractableObject>().StartUsing(this.gameObject);
                if (hideControllerOnUse)
                {
                    Invoke("HideController", hideControllerDelay);
                }
                usingObject.GetComponent <VRTK_InteractableObject>().ToggleHighlight(false);

                var rumbleAmount = usingObject.GetComponent <VRTK_InteractableObject>().rumbleOnUse;
                if (!rumbleAmount.Equals(Vector2.zero))
                {
                    controllerActions.TriggerHapticPulse((int)rumbleAmount.x, (ushort)rumbleAmount.y);
                }
            }
        }
Esempio n. 13
0
        /// <summary>
        /// AttemptGrabObject方法尝试抓取物体,首先获取一个可抓取的游戏对象,然后根据此对象的连接设置,调用不同的方法初始化grabbedObject
        /// 根据该对象的内部参数,来添加手柄的震动反馈
        /// 如果没有可以抓取的游戏对象就更新计时器
        /// </summary>
        private void AttemptGrabObject()
        {
            // 获取一个可抓取的游戏对象
            var objectToGrab = GetGrabbableObject();

            if (objectToGrab != null)
            {
                IncrementGrabState();
                // 生成被抓取对象是否成功
                var initialGrabAttempt = false;

                // 根据可抓取的游戏对象的连接设置,调用不同的方法初始化grabbedObject
                if (objectToGrab.GetComponent <VRTK_InteractableObject>().AttachIsTrackObject())
                {
                    initialGrabAttempt = GrabTrackedObject();
                }
                else if (objectToGrab.GetComponent <VRTK_InteractableObject>().AttachIsClimbObject())
                {
                    initialGrabAttempt = GrabClimbObject();
                }
                else
                {
                    initialGrabAttempt = GrabInteractedObject();
                }

                // 震动反馈处理
                if (grabbedObject && initialGrabAttempt)
                {
                    var rumbleAmount = grabbedObject.GetComponent <VRTK_InteractableObject>().rumbleOnGrab;
                    if (!rumbleAmount.Equals(Vector2.zero))
                    {
                        controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                    }
                }
            }
            else
            {
                // 如果没有可抓取的对象,更新计时器
                grabPrecognitionTimer = Time.time + grabPrecognition;
            }
        }
Esempio n. 14
0
        /// <summary>
        /// UseInteractedObject方法用来开始使用手柄正在接触的游戏对象
        /// </summary>
        /// <param name="touchedObject">手柄当前接触的游戏对象</param>
        private void UseInteractedObject(GameObject touchedObject)
        {
            // 如果手柄第一次使用游戏对象或者之前使用的游戏对象和手柄现在接触的游戏对象不一致,且现在接触的游戏对象是可以使用的时候
            if ((usingObject == null || usingObject != touchedObject) && IsObjectUsable(touchedObject))
            {
                usingObject = touchedObject;
                var usingObjectScript = usingObject.GetComponent <VRTK_InteractableObject>();

                if (!usingObjectScript.IsValidInteractableController(gameObject, usingObjectScript.allowedUseControllers))
                {
                    usingObject = null;
                    return;
                }

                updatedHideControllerOnUse = usingObjectScript.CheckHideMode(hideControllerOnUse, usingObjectScript.hideControllerOnUse);

                // 发送事件给监听的方法,开始调用
                OnControllerUseInteractableObject(interactTouch.SetControllerInteractEvent(usingObject));

                // 调用交互对象的StartUsing
                usingObjectScript.StartUsing(gameObject);

                if (updatedHideControllerOnUse)
                {
                    // 隐藏手柄模型renderer
                    Invoke("HideController", hideControllerDelay);
                }

                // 关闭高亮
                usingObjectScript.ToggleHighlight(false);

                // 震动反馈
                var rumbleAmount = usingObjectScript.rumbleOnUse;
                if (!rumbleAmount.Equals(Vector2.zero))
                {
                    controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                }
            }
        }
Esempio n. 15
0
        private void AttemptGrabObject()
        {
            var objectToGrab = GetGrabbableObject();

            if (objectToGrab != null)
            {
                IncrementGrabState();
                var initialGrabAttempt = false;

                if (objectToGrab.GetComponent <VRTK_InteractableObject>().AttachIsTrackObject())
                {
                    initialGrabAttempt = GrabTrackedObject();
                }
                else if (objectToGrab.GetComponent <VRTK_InteractableObject>().AttachIsClimbObject())
                {
                    initialGrabAttempt = GrabClimbObject();
                }
                else
                {
                    initialGrabAttempt = GrabInteractedObject();
                }

                undroppableGrabbedObject = (grabbedObject && grabbedObject.GetComponent <VRTK_InteractableObject>() && !grabbedObject.GetComponent <VRTK_InteractableObject>().isDroppable ? grabbedObject : null);

                if (grabbedObject && initialGrabAttempt)
                {
                    var rumbleAmount = grabbedObject.GetComponent <VRTK_InteractableObject>().rumbleOnGrab;
                    if (!rumbleAmount.Equals(Vector2.zero))
                    {
                        controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, rumbleAmount.x, 0.05f);
                    }
                }
            }
            else
            {
                grabPrecognitionTimer = Time.time + grabPrecognition;
            }
        }
Esempio n. 16
0
        private void AttemptGrabObject()
        {
            if (IsValidGrab())
            {
                if (interactTouch.GetTouchedObject().GetComponent <VRTK_InteractableObject>().AttachIsTrackObject())
                {
                    GrabTrackedObject();
                }
                else
                {
                    GrabInteractedObject();
                }

                if (!IsObjectHoldOnGrab(interactTouch.GetTouchedObject()))
                {
                    grabEnabledState++;
                }

                if (grabbedObject)
                {
                    var rumbleAmount = grabbedObject.GetComponent <VRTK_InteractableObject>().rumbleOnGrab;
                    if (!rumbleAmount.Equals(Vector2.zero))
                    {
                        controllerActions.TriggerHapticPulse((ushort)rumbleAmount.y, (int)rumbleAmount.x, 0.05f);
                    }
                }
            }
            else
            {
                grabPrecognitionTimer = grabPrecognition;
                if (createRigidBodyWhenNotTouching)
                {
                    interactTouch.ToggleControllerRigidBody(true);
                }
            }
        }
    void Update()
    {
        // calcul de la progression du fondu au noir
        float oldProgression = blackoutProgression;

        if (viewmasterObject.IsGrabbed())
        {
            float distance = 999;
            foreach (Transform anchorPoint in viewmasterObjectAnchors)
            {
                distance = Mathf.Min(distance, Vector3.Distance(anchorPoint.position, Camera.main.transform.position));
            }
            float range = maxDistance - minDistance;
            blackoutProgression = (distance - minDistance) / range;
        }
        else
        {
            blackoutProgression += Time.deltaTime;
        }
        blackoutProgression = Mathf.Clamp(blackoutProgression, 0, 1);
        Color matCol = blackoutMesh.material.color;

        matCol.a = 1 - blackoutProgression * .9f;
        blackoutMesh.material.color = matCol;

        renderCam.enabled = blackoutProgression <= 1;
        if (blackoutProgression < 1 && oldProgression >= 1)
        {
            // calcul de la position de l'image en fonction de la tête du joueur
            portraitOrientation.localPosition = renderCam.transform.localPosition + new Vector3(0, -.1f, 0);
            portraitOrientation.localRotation = Quaternion.Euler(
                portraitOrientation.localEulerAngles.x,
                renderCam.transform.localEulerAngles.y,
                portraitOrientation.localEulerAngles.z);
            // désactivation TP
            teleportHandler.enabled = false;
        }
        else if (blackoutProgression >= 1 && oldProgression < 1)
        {
            teleportHandler.enabled = true;
        }

        // calcul de la progression du fondu de l'image
        if (blackoutProgression <= 0)
        {
            canvasProgression += Time.deltaTime;
        }
        else
        {
            canvasProgression -= Time.deltaTime * 7;
        }

        canvasProgression    = Mathf.Clamp(canvasProgression, 0, 1);
        portraitsGroup.alpha = canvasProgression;

        if (blackoutProgression <= 0)
        {
            float angleBetweenPictures = 30;
            if (currentClip != null)
            {
                angleBetweenPictures = 180f / currentClip.images.Length;
            }
            // float angleBetweenPictures = 30; // à n'utiliser que si l'autre n'est pas assez intuitif

            GameObject grabbingObj = viewmasterObject.GetGrabbingObject();
            if (grabbingObj != null)
            {
                VRTK.VRTK_ControllerEvents eventCtrl = grabbingObj.GetComponent <VRTK.VRTK_ControllerEvents>();
                lastControllerActions = grabbingObj.GetComponent <VRTK.VRTK_ControllerActions>();
                if (eventCtrl != null)
                {
                    // on est en train de visionner l'image, on récupère la manette en train de tenir le VM afin de récupérer les swipes sur le pavé tactile
                    eventCtrl.axisFidelity = 5;
                    bool wasPressing = pressingButton;
                    pressingButton = eventCtrl.IsButtonPressed(VRTK.VRTK_ControllerEvents.ButtonAlias.Touchpad_Touch);
                    if (pressingButton && !wasPressing)
                    {
                        lastRotation = eventCtrl.GetTouchpadAxisAngle();
                    }
                    float trigger = eventCtrl.GetTriggerAxis();
                    if (trigger != 1)
                    {
                        ignoreTrigger = false;
                    }
                    if (trigger == 1 && !ignoreTrigger)
                    {
                        ignoreTrigger         = true;
                        autoMoveToNextPicture = true;
                        StartCoroutine(TriggerHapticCoroutine());
                    }
                    if (pressingButton && trigger == 0 && false)
                    {
                        float oldPortraitRotation = currentPortraitRotation;
                        // en train de faire un swipe
                        float currentPadRotation = eventCtrl.GetTouchpadAxisAngle();
                        if (lastRotation - currentPadRotation < 180 && lastRotation - currentPadRotation > -180)
                        {
                            currentPortraitRotation += (lastRotation - currentPadRotation) * rotateSensitivity;
                        }
                        if (lastControllerActions != null && ((int)(currentPadRotation) / 35) != ((int)(lastRotation) / 35))
                        {
                            lastControllerActions.TriggerHapticPulse(.05f);
                        }
                        if (currentPortraitRotation > angleBetweenPictures / 2 && oldPortraitRotation < angleBetweenPictures / 2)
                        {
                            StartCoroutine(TriggerHapticCoroutine());
                        }
                        if (currentPortraitRotation < -angleBetweenPictures / 2 && oldPortraitRotation > -angleBetweenPictures / 2)
                        {
                            StartCoroutine(TriggerHapticCoroutine());
                        }
                        lastRotation = currentPadRotation;
                    }
                }
            }

            if (!pressingButton || autoMoveToNextPicture)
            {
                if (autoMoveToNextPicture)
                {
                    currentPortraitRotation += Time.deltaTime * (angleBetweenPictures + .01f - currentPortraitRotation) * 10;
                }
                else
                {
                    // retour à l'image la plus proche
                    if (currentPortraitRotation > angleBetweenPictures / 2)
                    {
                        currentPortraitRotation += Time.deltaTime * (angleBetweenPictures + .01f - currentPortraitRotation) * 10;
                    }
                    else if (currentPortraitRotation < -angleBetweenPictures / 2)
                    {
                        currentPortraitRotation += Time.deltaTime * -(angleBetweenPictures + .01f + currentPortraitRotation) * 10;
                    }
                    else
                    {
                        currentPortraitRotation -= Time.deltaTime * currentPortraitRotation * 10;
                    }
                }
            }

            if (currentPortraitRotation > angleBetweenPictures)
            {
                currentPortraitRotation -= angleBetweenPictures;
                nextImage();
            }
            if (currentPortraitRotation < -angleBetweenPictures)
            {
                currentPortraitRotation += angleBetweenPictures;
                previousImage();
            }

            // rotation de l'image
            leftImageTransform.transform.localRotation      = Quaternion.Euler(0, 0, currentPortraitRotation);
            rightImageTransform.transform.localRotation     = Quaternion.Euler(0, 0, currentPortraitRotation);
            leftImageTransformNext.transform.localRotation  = Quaternion.Euler(0, 0, currentPortraitRotation + angleBetweenPictures);
            leftImageTransformPrev.transform.localRotation  = Quaternion.Euler(0, 0, currentPortraitRotation - angleBetweenPictures);
            rightImageTransformNext.transform.localRotation = Quaternion.Euler(0, 0, currentPortraitRotation + angleBetweenPictures);
            rightImageTransformPrev.transform.localRotation = Quaternion.Euler(0, 0, currentPortraitRotation - angleBetweenPictures);
        }
        else
        {
            // rotation du disque du grabbable, pas de la vue.

            GameObject grabbingObj = viewmasterObject.GetGrabbingObject();
            if (grabbingObj != null)
            {
                VRTK.VRTK_ControllerEvents eventCtrl = grabbingObj.GetComponent <VRTK.VRTK_ControllerEvents>();
                lastControllerActions = grabbingObj.GetComponent <VRTK.VRTK_ControllerActions>();
                if (eventCtrl != null)
                {
                    // on est en train de visionner l'image, on récupère la manette en train de tenir le VM afin de récupérer les swipes sur le pavé tactile
                    eventCtrl.axisFidelity = 5;
                    bool wasPressing = pressingButton;
                    pressingButton = eventCtrl.IsButtonPressed(VRTK.VRTK_ControllerEvents.ButtonAlias.Touchpad_Touch);
                    if (pressingButton && !wasPressing)
                    {
                        lastRotation = eventCtrl.GetTouchpadAxisAngle();
                    }
                    if (pressingButton && false)
                    {
                        // en train de faire un swipe
                        float currentPadRotation = eventCtrl.GetTouchpadAxisAngle();
                        if (lastRotation - currentPadRotation < 180 && lastRotation - currentPadRotation > -180)
                        {
                            currentClipRotation += (lastRotation - currentPadRotation) * rotateSensitivity;
                        }
                        if (lastControllerActions != null && ((int)(currentPadRotation) / 275) != ((int)(lastRotation) / 275))
                        {
                            triggerAnimator.SetTrigger("Trigger");
                        }
                        lastRotation = currentPadRotation;

                        viewmasterGrabbableClipRotation.transform.localRotation = Quaternion.Euler(currentClipRotation, 0, 0);
                    }
                }
            }
        }
    }