Aide à la manipulation d’objets virtuels dans des scènes 3D (PWIMP 2019-2020)

De Ensiwiki
Révision de 2 février 2020 à 17:42 par Bigea (discussion | contributions) (Intéraction CamH-ObjH)

Aller à : navigation, rechercher

Expert.png  Troisième Année 


Présentation de l’équipe

  • Anne Beurard (MMIS)
  • Alexis Bigé (MMIS)
  • Alexandre Frances (MMIS)
  • Chris Janaqi (MMIS)

Nous avons été encadrés par François Bérard.


Contexte et objectifs d'utilisation

Le projet proposé s’inscrit le cadre du perfectionnement des outils de modélisation 3D. Pour le grand public et la plupart des professionnel·le·s de la modélisation 3D, l’interaction avec les logiciels comme Maya, Blender ou encore 3DS Max s’effectue uniquement par le biais d’une interaction Wimp et la manipulation des objets virtuels se fait à la souris. Nous aimerions améliorer le mode de manipulation d’objets dans l’espace 3D ou 2D. Le but de ce projet est de pouvoir in fine manipuler - c’est à dire translater, tourner, redimensionner - l’objet, via la manipulation d’un dispositif physique tangible, que l’on appellera le “Hérisson”. Il s’agirait donc de prototyper un dispositif tangible qui tiendrait dans la main de l’utilisateur·rice. A l’image de la souris d’un ordinateur, cet objet serait le vecteur du mouvement de l’objet sélectionné à l’écran. Il serait donc possible d’observer en temps réel le mouvement de notre objet et de l’examiner sous tous ses angles tout comme on pourrait le faire pour un objet physique.


Motivations

Nous voulons apporter aux artistes 3D une facilité de manipulation des objets présents dans leur scène. L’utilisation d’une souris prive l'utilisateur·rice de beaucoup de degrés de liberté : en un seul geste, il n’est pas possible de mouvoir et tourner l’objet dans les 3 directions. Pour effectuer des mouvements “complexes” type déplacement suivant 3 axes ou rotation suivant l’axe normal à l’écran, il faut effectuer des compositions de gestes basiques à la souris. Par exemple, afin de repositionner un objet sur une scène 3D à la souris, l'utilisateur·rice devra :

  • Sélectionner l'objet concerné,
  • Sélectionner un axe de translation,
  • Effectuer la translation selon un axe,
  • Répéter les deux étapes précédentes pour les deux autres axes de translation,
  • Sélectionner un axe de rotation,
  • Effectuer la rotation selon l'axe choisi,
  • Répéter les deux étapes précédentes pour les deux autres axes de rotation,
  • Désélectionner l'objet.

Par ailleurs, l'utilisateur·rice d'un éditeur 3D a souvent besoin de faire un va et vient entre le contrôle des objets et celui du point de vue. Pour ce faire, avec une interaction uniquement à la souris, il devra sans cesse changer d'un mode point de vue à un mode objet.

Notre outil permettrait ainsi d’accélérer des tâches courantes de type composition de mouvements basiques pour des artistes 3D. Aussi, pour un public non averti, nous pouvons faire l'hypothèse que l’interaction pourrait devenir plus facile à apprendre. En effet, celle-ci est plus proche de celle du monde réel, dans le sens où l'on manipule un objet virtuel par le biais d'une interaction tangible sans passer par les abstractions d'axes de rotations et de translations utilisés à la souris. Notre but final serait d’augmenter l’indice de performance des utilisateur·rice·s par rapport à une interaction classique uniquement à la souris.


Solution proposée

Modèle 3D du Hérisson : objet tangible utilisé dans notre prototype
Modèle 3D du Hérisson avec réflecteurs IR

La solution proposée est centrée autour d'un objet tangible, nommé le "Hérisson", qui remplacera en partie la souris lors de l’interaction avec des logiciels 3D. Les objectifs fixés pour la conception du hérisson sont les suivants :

  • ergonomique et facile à prendre en main pour l’utilisateur·rice,
  • compatible avec un ou plusieurs éditeur 3D tel que Unity par exemple,
  • permettant le contrôle d'objets composants de la scène (objet ou caméra),
  • permettant la modification de la position et de la rotation de l’objet sélectionné dans l’espace 3D,
  • propose différents modes : par exemple avoir un mode translation et un mode rotation activables et désactivables dans le temps,
Prototype du Hérisson en mouvement

Une situation d'utilisation type de notre prototype serait la suivante. L'utilisateur·rice est assis·e devant son poste de travail avec un éditeur de scène 3D ouvert. De sa main dominante, il ou elle modèle à la souris plusieurs objets afin de créer une scène. Lors du placement de ces objets, il ou elle peut décider d'utiliser l'interaction à la souris ou au hérisson. Une fois l'objet sélectionné, dans le cas où l'on utilise le hérisson, le placement (en translation et rotation) s'effectue en déplaçant le hérisson dans l'espace autour de soi, en observant les transformations s'opérer sur l'objet sélectionné à l'écran. Avant et après les déplacements, l'utilisateur·rice signifie au système qu'il faut prendre en compte les actions effectuées au hérisson. Cela peut se faire par exemple par la main non dominante, par l'appuie sur une touche définie du clavier, ou encore au pied à l'aide d'une pédale.

Dans un deuxième cas de figure, l'interaction prototypée pourrait permettre de garder la main dominante sur la souris afin de modifier les objets de la scène, et de réserver le hérisson pour modifier le point de vue de la fenêtre d'édition. En effet, cela permettrait de tirer partie des deux mains dans la mesure où la main non dominante serait utilisée en soutien pour fluidifier l'interaction globale et éviter les changements de mode intempestifs entre changement de point de vue et modelage d'un objet. Avec le hérisson qui gère le point de vue de la fenêtre d'édition, la souris peut être utilisée uniquement pour déplacer l'objet.

Ainsi, nous pouvons résumer la solution proposée à trois utilisations:

  • contrôle d'un objet 3D,
  • contrôle de la caméra de la scène,
  • contrôle simultané de la caméra et de l'objet.



Réalisation du prototype

Prototype de Hérisson

Le hérisson

Nous avons fabriqué deux modèles différents du hérisson, dont l'un possède des réflecteurs Infra-rouge collés sur la surface, et l'autre possède des légères protubérances intégrées. Les caractéristiques du premier sont :

  • Taille : 6x6x6 cm
  • Infra-rouge : 8 réflecteurs adhésifs semi-sphériques de 2 mm de diamètre,
  • Matière : plastique (imprimé avec imprimante 3D).

Le second est légèrement plus petit. Cela nous permet de l’interaction dans différentes configurations :

  • Taille : 5x5x5 cm
  • Infra-rouge : 8 carrés de ruban adhésif réfléchissant,
  • Matière : plastique (imprimé avec imprimante 3D).

Le système de capture

Nous utilisons la technologie de motion capture passive OptiTrack. Il s'agit de "tracker" ou suivre les marqueurs réfléchissants se trouvant à la surface du hérisson afin d'envoyer ses informations de translation et de rotation au moteur de rendu (ici Unity). Les marqueurs sont vus par 4 à 6 caméras infra-rouge orientées vers la zone de travail, leur position dans l'espace est calculée par triangulation. Pour le hérisson, le principe est de créer un "rigid body" à partir des 8 marqueurs. Avec cette technique seuls 8 points représentent l'intégralité de l'objet hérisson. La calibration des caméras et la création du rigid body se font à l'aide du logiciel Motive. La marche à suivre afin d'utiliser ce logiciel est décrite ici.

L'installation est détaillée dans le schéma suivant :

Schéma du système de capture

Spécificités de notre solution

Nous avons choisi Unity pour construire, implémenter et tester notre solution car c'est un outil qui permet facilement de créer et aménager des scènes 3D. Cependant, nous l'avons utilisé dans un moyen peu conventionnel.

Manipulation dans la Scene view

À gauche : scene view, à droite : game

L'interface de Unity est composée de beaucoup d'onglets, dont 2 très importants : l'onglet scene et l'onglet Game. L'onglet scene permet de voir et de modeler la scène : d'y bouger, tourner, réduire, créer, supprimer des objets, lumières et autres composants de la scène. Une fois que l'on veut tester ce que l'on a créé, on interagit via l'onglet Game, qui est rendu par une caméra (elle aussi créée et placée grâce à l'onglet scene) et sensible aux Input au clavier ou à la souris. Cependant, parce que nous voulions mesurer le temps mis pour placer un objet, il nous avons dû utiliser l'onglet scene pour y voir les repères permettant de déplacer l'objet (cf. photo ci-jointe). Cela nous a posé quelques problèmes comme la modification de la scene view camera par un script (normalement elle est modifiée par la souris en temps réel humain) ou encore comment détecter des inputs alors que l'onglet actif est l'onglet scene et non pas game.

Manipulation dans le repère de la Scene view Camera

En plus de manipuler dans cet onglet, nous voulions que la manipulation de l'objet et/ou de la caméra soit le plus instinctif possible. Pour ce faire, nous avons modifié les données reçues de Motive (Optitrack) pour qu'elles soient plus adaptées à nos manipulations. Les données reçues par Motive sont la position absolue (x, y, z dans le repère créé dans Motive lors de la calibration des caméras) ainsi que la rotation, elle aussi absolue et liée au repère Motive.

  • Pour la translation, nous avons voulu transformer la position en deltas de positions afin de prendre en compte les déplacements relatifs plutôt que la position absolue à chaque instant. Nous avons ensuite utilisé ces deltas en x, y et z avec l'orientation de la scene view camera.
  • Pour la rotation, nous avons gardé la rotation absolue envoyée par Motive, mais : d'une part, nous prenions soin de configurer l'orientation initiale dans Motive, et d'autre part, nous composions cette rotation avec l'orientation de la caméra qui rendait la scène. Ainsi, nous avions toujours une rotation et une translation en adéquation avec le positionnement de la caméra. Peu importe sa position et son orientation, pousser le hérisson vers l'écran aura toujours pour effet de déplacer l'objet contrôlé vers l'avant, et, de même, le tourner en avant aura toujours pour effet de tourner l'objet virtuel vers l'avant (par rapport à l'utilisateur·rice et non à sa rotation intrinsèque).
  • De plus, nous avons modifié le déplacement en profondeur, pour que lorsque l'on veut avancer ou reculer l'objet dans la scène, il se déplace toujours parallèlement au sol. Ainsi, même si la caméra regarde un peu en plongée, l'objet ne pourra pas disparaître sous le sol.
  • Enfin, nous avons pondéré le déplacement de l'objet par sa distance à la caméra. Nous pensions en effet que plus on est proche de l'objet, plus on veut le manipuler avec précision. Ainsi, plus on est loin de l'objet, plus un petit déplacement réel induira un grand déplacement virtuel, et inversement quand on est proche de l'objet.

De cette implémentation découle deux limitations :

  • Lorsque l'on regarde la scène d'en haut, et que l'on veut bouger le cube vers l'avant (absolu), le geste à faire n'existe pas. En effet, on multiplie le déplacement en z Motive par l'axe de la caméra (camera.forward), qui est alors orthogonal au plan. Or, comme dit précédemment, on veut que l'objet ne s'enfonce pas dans le plan, donc nous projetons ce vecteur camera.forward sur le plan. Ainsi, quand on regarde la scène du dessus, et que l'on avance ou recule le hérisson de l'écran, l'objet virtuel ne bouge pas.
  • Comme nous voulons que la rotation soit consistante avec le déplacement de la caméra, on compose la rotation absolue reçue par l'orientation de la caméra. Cela a pour effet que la rotation est agréable peu importe l'emplacement de la caméra, certes, mais provoque une rotation de l'objet sur lui-même simplement en bougeant la caméra.

Implémentation en C#

Organisation générale du code

Organisation générale du code et relation entre les objets dans Unity
  • OptitrackDataConverter.cs

Nous avons modifié légèrement le cadre proposé par le professeur. Nous avons gardé le script OptitrackStreamingClient pour recevoir les données, mais au lieu d'attacher aux objets le script OptitrackRigidBody, nous avons créé un script OptitrackDataConverter qui agit de manière presque similaire. Ce script récupère également les données depuis OptitrackStreamingClient, mais au lieu de stocker les positions et rotations absolues, il stocke les deltas de position et la rotation absolue. Tout comme pour OptitrackStreamingClient, on le greffe à un GameObject vide. Son utilisation se fera dans les scripts TestObject et CameraController, qui se chargeront d'appliquer les transformations voulues (composition de quaternions, projection dans le repère de la caméra, etc.)

  • TestObject.cs

C'est le script qui va entièrement gérer les objets de test (les objets à placer dans leurs cibles). Pour fonctionner, il a besoin d'une cible (Target.cs) ainsi que des données de l'optitrack (OptitrackDataConverter) mais on peut tout de même l'utiliser à la souris en l'absence de ces dernières. C'est ce script qui va s'occuper de vérifier l'inclusion d'un objet dans sa cible (et de prévenir la cible). Il contient aussi un booléen pour savoir si oui ou non cet objet doit être contrôlé par la souris ou le hérisson. On doit aussi manuellement (avec une checkbox) indiquer si l'objet test est un cube ou non. Cela va influer sur le test d'inclusion. Si c'est un cube, on va récupérer les positions des 8 coins du cube (qui doivent avoir été créés et placés au préalable dans la scène en tant qu'enfants du cube) et on va tester l'inclusion de chacun de ces points dans la cible. C'est la meilleure solution pour s'assurer une réelle inclusion - celle opérée de base par Unity utilise les AABB (Axis-aligned boundig box). Si ce n'est pas un cube (on veut alors que l'objet soit asymétrique comme le lapin), alors les tests effectués seront une tolérance à la translation (assez grande) et une tolérance à la rotation (assez exigeante).

  • Target.cs

Un script mineur qui a pour unique rôle de changer la couleur de la cible (semi-transparente). Si l'objet n'est pas dans la cible, la couleur est bleue. Sinon, elle est verte. Cette information lui est fournie par TestObject.cs

Utilisation pour les expérimentations

Organisation du code et des objets dans Unity pour organiser les tests

Concernant le test réalisé par différents participants, il est géré par le script ExperienceManager.cs

Remplissage des attributs du script ExperienceManager.cs

Ce script a besoin des 2 objets tests et des 2 cibles associées (TestObject.cs et Target.cs). Il a également besoin du script CameraController.cs au cas où on voudrait contrôler la caméra avec un hérisson. Il prend également un Canvas sur lequel un texte est écrit (il sert à avertir les participants à chaque fois qu'un objet a été correctement amené à sa cible). Enfin, il possède 3 attributs qu'il faut régler à la main : 2 checkbox pour indiquer quelle(s) feature(s) le(s) hérisson(s) gère(nt), ainsi que le nom du participant (cf. figure ci-contre).

Ces trois derniers paramètres servent à écrire (et différencier) les fichiers de données qui sont écrits en fin d'expérience.

Le script gère, à partir de ces variables d'entrée, quel objet afficher et quelle est sa cible. Quand la cible est atteinte, il génère aléatoirement une nouvelle position et orientation pour la cible et replace l'objet au centre de la scène. Parce qu'on lui a donné les deux objets à tester, il peut changer d'objet-test en cours d'expérience (et le fait) Avec certaines touches (celles utilisées par le pédalier), le script permet aussi de stopper momentanément le tracking (il arrête de mettre à jour la position des objets) et/ou de repositionner les objets trackés (caméra ou objet-test) au centre de la scène.

Les difficultés rencontrées

La tâche d'acquisition de cible dans un espace en 3 dimensions requiert généralement de changer le point de vue de la caméra afin de pouvoir positionner précisément l'objet manipulé. Lorsque nous avons commencé à tester notre prototype, un des obstacles les plus handicapants a été que le changement du point de vue d'une caméra sous Unity se fait à la souris en gardant la touche "alt" du clavier appuyée. Ainsi, le simple changement de point de vue se fait à deux mains. Or, dans le cas d'utilisation premier auquel nous avions pensé, l'utilisateur·rice tient dans la main gauche le hérisson et dans la main droite contrôle la caméra à la souris. Afin de pallier ce problème nous avons ajouté à notre prototype une pédale permettant de remplacer l'appuie "alt" du clavier par un appuie au pied, libérant ainsi pleinement la main gauche pour le contrôle du hérisson.

Un deuxième problème que nous a permis de régler la mise en place d'une pédale est la possibilité pour l'utilisateur·rice de se replacer dans une position plus confortable durant un déplacement d'amplitude conséquente. En effet, un appuie sur la pédale de droite permet de figer la position de notre objet durant 1 seconde.

Nous avons également introduit la possibilité de recentrer la caméra et l'objet à une position prédéfinie par appuie sur 2 pédales simultanément. Cela peut être très utile si l'utilisateur·rice se perd momentanément dans la scène. Ainsi, l'ajout de pédales à notre prototype nous a permis de rendre l'interaction plus confortable et d'éviter 3 problèmes différents.


Evaluation de la solution proposée

Durant l'évaluation de notre projet, nous avons proposé à des personnes de tester notre prototype dans différentes conditions. Cela nous permet de mesurer les éventuels gains de notre interaction par rapport à une interaction à la souris. Nous avons défini quatre phases de tests durant lesquelles on demande à l'utilisateur·rice de placer un objet 3D dans une cible de même forme est légèrement plus grosse que l'objet. Nous réalisons des tests pour les cas suivants d'interaction :

  1. Interaction uniquement à la souris pour le déplacement de l'objet et de la caméra selon les standards Unity (CamS-ObjS),
  2. Interaction à la souris pour les déplacements de l'objet et au hérisson pour le contrôle de la caméra (CamH-ObjS),
  3. Interaction au hérisson pour les déplacements de l'objet et à la souris pour le contrôle de la caméra (CamS-ObjH),
  4. Interaction avec deux hérissons, l'un pour les déplacements de l'objet et le deuxième pour le contrôle de la caméra (CamH-ObjH).

Expériences réalisées

Les deux objets, l'un symétrique et l'autre asymétrique

Pour chaque interaction, l'utilisateur·rice effectue 10 placements : 5 acquisitions de cible avec un objet symétrique (un cube) et 5 acquisitions de cible avec un objet asymétrique (un lapin).

Pour chaque acquisition, nous retenons l'identité du testeur et nous faisons varier différents paramètres :

  • la distance initiale objet/cible
  • la différence initiale de rotation objet/cible
  • le temps d'acquisition
  • l'objet utilisé: un simple cube ou un solide plus complexe (lapin)

Pour chacun des utilisateur·rice·s, nous avons rassemblé les résultats pour les quatre interactions dans un même graphique, en représentant pour chacune la moyenne et la variance des "durées normalisées". Cette dernière a été calculée à partir de la durée de l'expérience, à laquelle nous avons divisé:

  • la distance entre l'objet et sa cible en mètres,
  • la norme des angles en radians (angles de la rotation nécessaire pour le placement dans la cible).

Cela nous permet d'obtenir des valeurs d'expériences qui sont comparables entre elles, en seconde par mètres par radians.

Comparaison entre les différents modes proposés

Afin de pouvoir comparer les quatre interactions, il faut aussi pouvoir rassembler les données pour chaque l'utilisateur·rice dans un même graphique. Nous avons donc calculé les "durées normalisées" relatives par rapport à l'expérience à la souris, pour chacun des utilisateur·rice·s. Par exemple, si une personne prend 60 secondes avec la souris et 30 secondes avec le hérisson en mode objet, on retiendra le ratio de 1/2. On représente les résultats en échelle logarithmique.

Exploitation des résultats

Bien entendu, afin de pouvoir donner des résultats plus cohérents et précis, il faudrait davantage de testeu·r·se·s et les faire pratiquer sur davantage d'expériences. Cependant, se limiter à 5 expériences par objet, permet de limiter l'impact de l'apprentissage et de l'habitude sur nos résultats, en particulier dans le cas des utilisat·eur·rice·s qui n'auraient jamais eu l'habitude de manipuler le logiciel Unity.

Ainsi, les courbes des données relatives pour le lapin et le cube permettent de faire ressortir des tendances.

Intéraction CamH-ObjS

Le rapport de temps de l'utilisat·eur·rice serait très proche de 1 lorsque que l'on compare l'interaction CamH-ObjS à l'interaction CamS-ObjS. Cela signifie que manipuler la caméra avec le hérisson tout en contrôlant les objets avec la souris ne serait pas plus efficace que la manipulation classique avec la souris uniquement.

Intéraction CamS-ObjH

Le rapport de temps de l'utilisat·eur·rice semble cette fois-ci en faveur de l’interaction proposée, lorsque qu'on la compare à l'interaction CamS-ObjS. Cela signifie que manipuler l'objet avec le hérisson tout en contrôlant la caméra avec la souris semble provoquer un gain important de temps pour la plupart des utilisat·eur·rice·s.

Intéraction CamH-ObjH

Le rapport de temps de l'utilisat·eur·rice semble encore une fois en faveur de l’interaction proposée, lorsque qu'on la compare à l'interaction CamS-ObjS. Cela signifie que manipuler l'objet avec le hérisson tout en contrôlant la caméra avec un deuxième hérisson semble provoquer un gain de temps pour la plupart des utilisat·eur·rice·s. Cependant, le gain semble inférieur à l'interaction précédente. Nous avions pensé obtenir de meilleurs résultats lorsque la caméra est contrôlée par le hérisson : en effet, le contrôle traditionnel à la souris nécessite plusieurs actions successives pour effectuer le mouvement nécessaire. Nous avons remarqué que certains utilisat·eur·rice·s pouvait perdre rapidement leurs repères lorsqu'ils pouvaient contrôler la caméra aussi directement et sans besoin de combiner les actions.

Conclusion

TODO CONCLURE !

Nous pouvons remarquer que l'utilisation de l'optitrack n'est pas adapté dans le cadre de la commercialisation du hérisson. Notre prototype vise uniquement à faire une "proof of concept" de l'interaction imaginée. L'utilisation d'une IMU (Inertial Measurement Unit) placée à l'intérieur du hérisson pourrait permettre de rendre le dispositif compact, portable, sans contraintes filaires et facilement commercialisable.