/***************************************************** * METHOD: UPDATE * * INFO: Recupere la distance de la translation et met * à jour l'objet à chaque frame. Un amplificateur * de mouvement est utilisé pour faciliter les * déplacements. * * Ex: Si l'amplificateur est de 2.0f et que la * main se déplace de 1" vers la gauche, l'objet * va se déplacer de 2" vers la gauche. * *****************************************************/ void Update() { //Si la manipulation contrôlé d'objet est activé if (PalmUIController.GetInstance().IsManipulationControlled()) { // Si la main initialisé avec le geste Fist est détecté, on effectue une translation if (isTranslating && DetectionController.GetInstance().IsHandDetected(hand)) { //La liste des objets sélectionnés avec le raycast List <SelectedObject> objectsToTranslateList = SelectionController.GetInstance().GetSelectedObjects(); if (objectsToTranslateList.Count > 0) { // Calcul la distance du déplacement Vector3 newHandPosition = GetStartHandPosition(); Vector3 handDistance = newHandPosition - lastHandPosition; foreach (SelectedObject objectToTranslate in objectsToTranslateList) { // Met à jour la position de l'objet (X,Y,Z) avec l'amplificateur pris en compte. objectToTranslate.TransformObject.position += handDistance * amplifyMovement; } lastHandPosition = newHandPosition; } } } }
/***************************************************** * UPDATE * * INFO: Recupere la distance du scaling et met à jour * l'objet à chaque frame. Un amplificateur de * mouvement est utilisé pour faciliter le * redimensionnement. * * Ex: Si l'amplificateur est de 2.0f et que les * mains se déplacent de 1" vers l'extérieur, * l'objet va grossir de 2" dans tous les sens. * *****************************************************/ void Update() { //Si la manipulation contrôlé d'objet est activé et que les deux mains sont détectés. if (isScaling && DetectionController.GetInstance().IsBothHandsDetected() && PalmUIController.GetInstance().IsManipulationControlled()) { //La liste des objets sélectionnés avec le raycast List <SelectedObject> objectsToScaleList = SelectionController.GetInstance().GetSelectedObjects(); if (objectsToScaleList.Count > 0) { float newDistance = GetDistance(); float distance = newDistance - lastDistance; foreach (SelectedObject objectToScale in objectsToScaleList) { // Met à jour la dimension de l'objet (X,Y,Z) avec l'amplificateur pris en compte. objectToScale.TransformObject.localScale += new Vector3(distance, distance, distance) * amplifyScale; // Évite que le redimensionnement de l'objet soit trop petit ou trop grand if (objectToScale.GetScale().x < minimumScale) { objectToScale.TransformObject.localScale = new Vector3(minimumScale, minimumScale, minimumScale); } if (objectToScale.GetScale().x > maximumScale) { objectToScale.TransformObject.localScale = new Vector3(maximumScale, maximumScale, maximumScale); } } lastDistance = newDistance; } } }
/***************************************************** * UPDATE THUMB/INDEX ROTATION * * INFO: Maintient à jour la rotation de l'objet 3D * en fonction du pouce et de l'index de la main. * Ajuste dynamiquement la vitesse de rotation * selon la position du ou des doigts qui * causent la rotation. C'est ici qu'on valide * quels sont les doigts ouverts. * * *** TO OPTIMIZE *** * *****************************************************/ private void ThumbIndexRotation() { //Si la main qui permet d'effecuer la rotation est détectée. //Si la manipulation contrôlé d'objet est activé. if (DetectionController.GetInstance().IsHandDetected(ThumbOrIndexGesture.GetInstance().GetHand()) && PalmUIController.GetInstance().IsManipulationControlled()) { //La liste des objets sélectionnés avec le raycast List <SelectedObject> objectsToRotateList = SelectionController.GetInstance().GetSelectedObjects(); if (objectsToRotateList.Count > 0) { //Recupère le contrôleur de la la main detectedHand = DetectionController.GetInstance().GetHand(ThumbOrIndexGesture.GetInstance().GetHand()); //Change l'etat des doigts si le pouce et/ou l'index est ouvert if (detectedHand.GetFinger(FingersE.pouce).IsFingerOpen() || detectedHand.GetFinger(FingersE.index).IsFingerOpen()) { isThumbOpen = detectedHand.GetFinger(FingersE.pouce).IsFingerOpen() ? true : false; isIndexOpen = detectedHand.GetFinger(FingersE.index).IsFingerOpen() ? true : false; } foreach (SelectedObject objectToRotate in objectsToRotateList) { //Applique la rotation en fonction de la force Vector3 rotationSpeed = stopPosition * amplifyFingerRotation; Vector3 dynamicRotation = objectToRotate.TransformObject.worldToLocalMatrix * rotationSpeed; objectToRotate.TransformObject.Rotate(dynamicRotation); startPosition = Vector3.Lerp(stopPosition, Vector3.zero, Time.deltaTime); } } } }
/***************************************************** * UPDATE FINGER ROTATION * * INFO: Evenement qui permet de maintenir a jour la * rotation de l'objet. Permet aussi d'appliquer * et modifier la vitesse de rotation selon * les valeurs entrées en paramètres. * *****************************************************/ public void UpdateFingerRotation() { //Si la manipulation contrôlé d'objet est activé if (PalmUIController.GetInstance().IsManipulationControlled()) { //La liste des objets sélectionnés avec le raycast List <SelectedObject> objectsToRotateList = SelectionController.GetInstance().GetSelectedObjects(); if (objectsToRotateList.Count > 0) { foreach (SelectedObject objectToRotate in objectsToRotateList) { //Plus la main est près de l'olbjet 3D, plus la vitesse de rotation sera réduite Vector3 torque = GetFingerPosition() - startPosition; Vector3 newTorque = Vector3.zero; //Le pouce et/ou l'index est ouvert, donc rotation sur l'axe X et/ou Y if (isThumbOpen && isRotationX) { newTorque.y = -torque.x; } if (isIndexOpen && isRotationY) { newTorque.x = torque.y; } //Applique la rotation en fonction de la force Vector3 rotationSpeed = newTorque * amplifyFingerRotation; Vector3 dynamicRotation = objectToRotate.TransformObject.worldToLocalMatrix * rotationSpeed; objectToRotate.TransformObject.Rotate(dynamicRotation); } } } }
/***************************************************** * UPDATE SWIPE ROTATION * * INFO: Evenement qui permet de maintenir a jour la * rotation de l'objet lorsque l'utilisateur effectue * un geste Swipe. * * *** TO OPTIMIZE *** * *****************************************************/ public void UpdateSwipeRotation() { //Si la manipulation contrôlé d'objet est activé if (PalmUIController.GetInstance().IsManipulationControlled()) { //La liste des objets sélectionnés avec le raycast List <SelectedObject> objectsToRotateList = SelectionController.GetInstance().GetSelectedObjects(); if (objectsToRotateList.Count > 0) { //Le type de Swipe effectué (gauche, droite, haut, bas) swipeType = GestureMediator.GetGestureType(); if (swipeType.Contains("Swipe")) { foreach (SelectedObject objectToRotate in objectsToRotateList) { detectedHand = DetectionController.GetInstance().GetHand(GestureMediator.GetDetectedHand()); float velocityX = 0f; float velocityY = 0f; //La velocité du swipe en X ou Y if (isRotationX) { velocityX = -detectedHand.GetHandVelocity().x; } if (isRotationY) { velocityY = detectedHand.GetHandVelocity().y; } allowCoroutine = true; //Rotation horizontale (Swipe gauche ou droite) if (isRotationX && (swipeType.Contains("droite") || swipeType.Contains("gauche"))) { //Demarre la rotation horizontale selon le type choisi (swipe lock angle / swipe velocity) Vector3 axis = Mathf.Sign(velocityX) * Vector3.up; StartCoroutine(isLockRotation ? RotateWhenSwipe(objectToRotate.TransformObject, axis, rotationAngle, secondsToRotate) : RotateFreeWhenSwipe(objectToRotate.TransformObject, axis, velocityX)); } //Rotation verticale (Swipe haut ou bas) if (isRotationY && (swipeType.Contains("haut") || swipeType.Contains("bas"))) { //Demarre la rotation verticale selon le type choisi (swipe lock angle / swipe velocity) Vector3 axis = Mathf.Sign(velocityY) * Vector3.right; StartCoroutine(isLockRotation ? RotateWhenSwipe(objectToRotate.TransformObject, axis, rotationAngle, secondsToRotate) : RotateFreeWhenSwipe(objectToRotate.TransformObject, axis, velocityY)); } } } } } }
/***************************************************** * UPDATE - TARGET OBJECT * * INFO: Detection de l'action qui consiste a effectuer * un tir (trigger) avec le pouce lorsque la main * fait un geste de fusil (pouce et index). * *****************************************************/ void Update() { isGunActionDetected = false; //Si le Palm UI n'est pas ouvert et la main droite détecté if (!PalmUIController.GetInstance().IsPalmUIOpen() && DetectionController.GetInstance().IsHandDetected(raycastHand)) { //Étape 1: l'index et le pouce (fusil) sont ouverts if (wasOnlyIndexThumbOpen) { //Étape 2: le pouce est désormais fermé (trigger) et l'index est ouvert if (isOnlyIndexOpen && !isOnlyIndexThumbOpen) { //Le temps du trugger (pouce: ouvert --> fermé --> ouvert) timer += Time.deltaTime; } //Étape 3: l'index et le pouce sont ouverts à nouveau et le trigger respecte le delais if (timer < triggerTimer && timer > 0f && wasOnlyIndexOpen && isOnlyIndexThumbOpen) { isGunActionDetected = true; timer = 0f; } //Pour tout déselectionner les objets, on maintient le pouce descendu plus longtemps if (timer > timeBeforeUnselect && timer > triggerTimer && isOnlyIndexOpen && !isOnlyIndexThumbOpen) { //Change le materiel de couleur (rouge) UnselectAllObjects(false); } //Si apres prolongation du pouce fermé et qu'on le relève, désélectionne tous les objets. if (timer > timeBeforeUnselect && timer > triggerTimer && wasOnlyIndexOpen && isOnlyIndexThumbOpen) { //Remet le materiel par defaut et vide les liste de sélection UnselectAllObjects(true); timer = 0f; } //timer = 0f; } //Si on ne pointe pas et que le geste Gun (pouce et index) n'est pas détecté if (!isOnlyIndexOpen && !isOnlyIndexThumbOpen) { ResetAllState(); } } else { ResetAllState(); } }
/***************************************************** * AWAKE * * INFO: Instance de la classe * *****************************************************/ private void Awake() { //Initialise l'instance de cette classe if (instance == null) { instance = this; } else { Destroy(this); } //Le seul bouton de départ du Palm UI ne devrait pas etre affiché manipulationType = GameObject.FindWithTag("ManipulationType"); if (manipulationType != null) { manipulationType.SetActive(false); } }
/***************************************************** * UPDATE * * INFO: Déclenche des événements selon la détection * de gestes pour démarrer, arrêter ou maintenir * une fonctionalité quelconque. * *****************************************************/ void Update() { //Si le Palm UI n'est pas ouvert if (!PalmUIController.GetInstance().IsPalmUIOpen()) { //Quantité de gestes détectés int gesturesQty = 0; //Pour tous les gestes détectés foreach (GestureMediator gesture in gestures) { if (gesture.IsGestureDetected()) { gesturesQty++; } } //Si le systeme détecte au moin un geste configuré if (gesturesQty >= gestures.Length) { //Si aucun geste actif if (!detectedGesture) { //Démarre la fonctionnalité du geste startGesture.Invoke(); detectedGesture = true; } //Maintient la fonctionnalité du geste keepGesture.Invoke(); } else { //Si le geste est encore perçu comme actif if (detectedGesture) { //Arret de la fonctionnalité du geste stopGesture.Invoke(); detectedGesture = false; } } } }
/***************************************************** * INITIATE RAYCAST * * INFO: Demarre le raycast effectué à partir du bout * d'un doigt pour une main quelconque. * * Initialise le laser et la sélection d'objet * par raycast et Gun gesture. * * Fonction appelé en boucle par le DetectionController. * *****************************************************/ public void InitiateRaycast() { //Si la main du raycast est détecté if (DetectionController.GetInstance().IsHandDetected(raycastHand)) { handController = DetectionController.GetInstance().GetHand(raycastHand); //Si le doigt du raycast est le seul d'ouvert et le Palm UI n'est pas affiché if (handController.IsIndexOpened() && !PalmUIController.GetInstance().IsPalmUIOpen()) { //Les controleurs de la main et doigt fingerController = handController.GetFinger(raycastFinger); Ray ray = fingerController.GetFingerRay(); //Trace la ligne rouge dans le sens que pointe le doigt de la main 3D Debug.DrawRay( fingerController.GetFingertipPosition(), ray.direction, raycastColor, Time.deltaTime, true); //Active le point de lumiere (point raycast) lightDot.SetActive(activateLightDot); //Permet la selection d'objets 3D avec le raycast SelectObjectWithRaycast(ray); } // Si le raycast est désactivé, on reset une fois le highlight des objets else { CheckResetHighlight(); } } // Si la main du raycast n'est plus détecté, on reset une fois le highlight des objets else { CheckResetHighlight(); } }
void Update() { if (Input.GetKeyDown(_toggleGuiState)) { _showGUI = !_showGUI; } //Si ole mode de manipulation contrôlé (restreint) n'est pas activé if (!PalmUIController.GetInstance().IsManipulationControlled()) { selectedObjects = SelectionController.GetInstance().GetSelectedObjects(); if (selectedObjects.Count > 0) { foreach (SelectedObject objectToManipulate in selectedObjects) { if (!objectToManipulate.HasAnchor) { GameObject pinchControl = new GameObject("RTS Anchor"); Transform anchor = pinchControl.transform; anchor.transform.parent = objectToManipulate.TransformObject.parent; objectToManipulate.TransformObject.parent = anchor; objectToManipulate.Anchor = anchor; objectToManipulate.HasAnchor = true; } bool didUpdate = false; if (_pinchDetectorA != null) { didUpdate |= _pinchDetectorA.DidChangeFromLastFrame; } if (_pinchDetectorB != null) { didUpdate |= _pinchDetectorB.DidChangeFromLastFrame; } if (didUpdate) { objectToManipulate.TransformObject.SetParent(null, true); } //Si au moin un des deux Pinch est actif if (_pinchDetectorA != null && _pinchDetectorB != null && (_pinchDetectorA.IsActive || _pinchDetectorB.IsActive)) { /*if (disableGravity) * { * GravityController.GetInstance().ToAllowGravity(false, true); * disableGravity = false; * }*/ } //Si aucun des deux Pinch est actif if (_pinchDetectorA != null && _pinchDetectorB != null && (!_pinchDetectorA.IsActive && !_pinchDetectorB.IsActive)) { /*if (!disableGravity) * { * //GravityController.GetInstance().ToAllowGravity(true, false); * disableGravity = true; * }*/ } //Pinch main gauche et droite if (_pinchDetectorA != null && _pinchDetectorA.IsActive && _pinchDetectorB != null && _pinchDetectorB.IsActive) { transformDoubleAnchor(objectToManipulate); } //Pinch main gauche else if (_pinchDetectorA != null && _pinchDetectorA.IsActive) { transformSingleAnchor(_pinchDetectorA, objectToManipulate); } //Pinch main droite else if (_pinchDetectorB != null && _pinchDetectorB.IsActive) { transformSingleAnchor(_pinchDetectorB, objectToManipulate); } if (didUpdate) { objectToManipulate.TransformObject.SetParent(objectToManipulate.Anchor, true); } } } } }