Page 1 sur 1

[RESOLU] Twist Infini

Publié : 20 Avr 2018 13:03
par QDRemix
Bonjour à tous,

J'essaye de scripter un twist infini entre deux éléments et je me heurt à un problème avec les quaternions. J'ai fait pas mal de recherche sur internet, mais je n'arrive pas à trouver la solution...
J'ai donc un élément de début et de fin qui doivent contrôler tous les intermédiaires en rotation. Tant que la valeur de weight sur la rotation est supérieur à 0.5 je n'ai pas le problème. Mais en dessous, j'ai des flips. Je sais que les quaternions fonctionnent entre -180/180°, mais du coup, je ne sais pas trop comment faire autrement.

J'ai aussi avec un slerp classique et un SlerpUnclamped mais ça ne fonctionne pas. J'ai aussi essayé différent truc, mais sans succés pour le moment.

Si jamais vous avez des solutions, je suis très intéresse :)

Voila un script de test.

Code : Tout sélectionner

using System.Collections.Generic;
using UnityEngine;

public class QuaternionTest : MonoBehaviour {

    [SerializeField]
    private int numObject = 10;

    [SerializeField]
    private float startRotation = 0.0f;

    [SerializeField]
    private float endRotation = 0.0f;

    private GameObject startObject;
    private GameObject endObject;
    private List<GameObject> inBetweenObject = new List<GameObject>();

	
    void Start()
    {

        startObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
        endObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
        endObject.transform.position = new Vector3(numObject, 0.0f, 0.0f);
   
        for (int i = 1; i < numObject; i++)
        {
            GameObject newCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
            newCube.transform.position = new Vector3(1.0f * i, 0.0f, 0.0f);
            inBetweenObject.Add(newCube);
        }

    }

	void Update () {

        startObject.transform.localRotation = Quaternion.AngleAxis(endRotation, Vector3.right); 
        endObject.transform.localRotation = Quaternion.AngleAxis(startRotation, Vector3.right);

        float weightStep = 1.0f / (inBetweenObject.Count + 1);
        for (int i = 0; i < inBetweenObject.Count; i++)
        {
            float weight = weightStep * (i + 1);
            inBetweenObject[i].transform.localRotation = Quaternion.SlerpUnclamped(startObject.transform.localRotation, endObject.transform.localRotation, weight);// startObject.transform.localRotation;
        }

	}

}


Re: Twist Infinie

Publié : 20 Avr 2018 13:05
par boubouk50
Utilise tout simplement les fonctions de rotation existantes:
Rotate () ou RotateAround ()

Re: Twist Infinie

Publié : 20 Avr 2018 14:39
par QDRemix
Le rotate ne convient pas car après avoir isolé une rotation et fait la soustraction pour calculer les inbetween j'ai quand même un flip quand je le set. Je ne pense pas que le RotateAround fonctionne non plus car même si je calcul le vecteur en fonction d'un angle trouvé je vais me retrouver avec des flips à coup sure (ça revient à faire un slerp). Je vais essayé mais je n'y crois pas trop (il me semble avoir fait un truc similaire sans utilisé la fonction de unity car je l'avais oublié celle la :))

EDIT:
Je précise que le but est que ça bouge automatiquement en fonction de deux éléments contrôlable par un utilisateur. Donc qu'il peut faire n'importe quoi.
Faire tourner à l'infini des éléments avec des angles connu je n'ai pas eu de problème que se soit en initialiser la rotation en fonction d'un nombre d'élément ou en ajoutant une valeur d'angle connu.
Le problème est que je cherche à isoler des angles et pour ça je n'ai que la matrix ou le quaternion (il me semble) calculer la différence entre ces angles pour ensuite calculer un step (angle / nombre d'élément)

Re: Twist Infinie

Publié : 24 Avr 2018 13:20
par QDRemix
Je pense avoir réussi à avoir le résultat voulu.
Je n'ai pas réussi à le faire avec le Rotate ou le RotateArround du Transform mais avec le AngleAxis du Quaternion.
Il suffit que je récupère le Roll de mes Transforms et j'ai le résultat au complet.

Code : Tout sélectionner

using System.Collections.Generic;
using UnityEngine;

public class QuaternionTest : MonoBehaviour {

    [SerializeField]
    private int numObject = 10;

    [SerializeField]
    private float startRotation = 0.0f;

    [SerializeField]
    private float endRotation = 0.0f;

    private GameObject startObject;
    private GameObject endObject;
    private List<GameObject> inBetweenObject = new List<GameObject>();

	
    void Start()
    {

        startObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
        endObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
        endObject.transform.position = new Vector3(numObject, 0.0f, 0.0f);
   
        for (int i = 1; i < numObject; i++)
        {
            GameObject newCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
            newCube.transform.position = new Vector3(1.0f * i, 0.0f, 0.0f);
            inBetweenObject.Add(newCube);
        }

    }

	void Update () {

        startObject.transform.localRotation = Quaternion.AngleAxis(endRotation, Vector3.right); 
        endObject.transform.localRotation = Quaternion.AngleAxis(startRotation, Vector3.right);

        float diffAngle = endRotation - startRotation;
        float weightStep = 1.0f / (inBetweenObject.Count + 1);

        for (int i = 0; i < inBetweenObject.Count; i++)
        {
            float weight = weightStep * (i + 1);
            inBetweenObject[i].transform.rotation = startObject.transform.rotation * Quaternion.AngleAxis(diffAngle * weight, Vector3.left);
        }

	}

}


Re: Twist Infinie

Publié : 24 Avr 2018 13:33
par boubouk50
A solution trouvée, problème résolu.
Merci de penser à éditer le titre du premier message en ajoutant [RESOLU] en début de celui-ci.
Je le fais cette fois-ci.

Re: [RESOLU] Twist Infini

Publié : 24 Avr 2018 14:29
par QDRemix
Merci