Obtenir le résultat d’exécution de session
Pendant l’exécution de session, le transform de certains objets de la scène ainsi que l’image de la caméra sont modifiés. Parfois, ces changements ne suffisent pas encore pour l’application, et il peut être nécessaire d’obtenir le résultat d’exécution de session à chaque frame puis de retraiter ces données. Cet article explique comment obtenir et utiliser ces données.
Avant de commencer
- Comprendre les notions de base, la composition et le flux de travail de session via Introduction à ARSession
- Apprendre comment créer une session
- Apprendre comment accéder aux composants de fonctions AR
Obtenir les mises à jour de InputFrame
Vous pouvez utiliser l’événement InputFrameUpdate pour obtenir les mises à jour de InputFrame. Cet événement ne se déclenche que lorsque InputFrame change dans les données de sortie de chaque frame de session.
Note
InputFrameUpdate n’est valide que dans les sessions où l’image est rendue par EasyAR. En général, il n’est pas valide avec AR Foundation ou les casques, et il faut alors utiliser les méthodes fournies par ces bibliothèques tierces pour obtenir les mises à jour de données.
Avec InputFrame, vous pouvez obtenir l’image de la caméra physique, les paramètres de caméra, l’horodatage, le transform de la caméra physique par rapport au système de coordonnées du monde et l’état de tracking, entre autres. Cependant, comme le transform de la caméra est déjà appliqué à la caméra virtuelle et aux autres objets par session, il n’est généralement pas nécessaire d’obtenir le transform de la caméra via InputFrame.
Obtenir l’image de la caméra physique de la frame courante
Vous pouvez utiliser la méthode InputFrame.image() pour obtenir des données d’image de la caméra physique de type Image.
Par exemple, le code suivant obtient l’image de la caméra physique lors de la mise à jour de InputFrame :
Session.InputFrameUpdate += (inputFrame) => {
using (var image = inputFrame.image())
{
}
};
Attention
Lors de l’utilisation de données de type Image et d’autres données de type class obtenues à partir de celles-ci, vous devez vous assurer que Dispose() est correctement appelé (l’instruction using du code ci-dessus le garantit) ; sinon, cela peut provoquer une fuite mémoire, voire l’arrêt de la mise à jour de l’image.
Si vous devez conserver InputFrame ou Image pour l’utiliser à la frame suivante, il faut augmenter la valeur de ARAssembly.ExtraBufferCapacity en fonction de la quantité de données conservées ; sinon, l’obtention des données peut échouer à cause d’un tampon insuffisant.
Si vous devez conserver InputFrame, vous devez aussi appeler Clone() pour créer une copie de référence, puis appeler Dispose() sur cette copie quand vous n’en avez plus besoin.
Comme la fréquence de la caméra physique est généralement plus faible que celle du rendu, tous les frames de rendu ne reçoivent pas l’événement InputFrameUpdate, mais de la même manière l’image de la caméra physique ne se met pas à jour à chaque frame de rendu. Tous les frames de rendu avant le prochain déclenchement de InputFrameUpdate ont le même contenu d’image que l’InputFrame courant.
Note
L’image dans InputFrame est toujours identique à l’image d’arrière-plan de la caméra virtuelle de la frame courante, mais le rendu de l’arrière-plan peut être redimensionné ou rogné ; il est donc normal que la taille ou le ratio obtenu ne corresponde pas à ce qui est affiché à l’écran.
Il faut aussi noter que les données d’image renvoyées par InputFrame.image() sont lisibles par le CPU et ne constituent pas une texture GPU. Si vous devez utiliser ces données sur le GPU, il faut les transférer dans une texture GPU, ou obtenir directement la texture GPU via l’interface CameraImageRenderer.RequestTargetTexture(Action<Camera, RenderTexture>).
[Optionnel] Intercepter le rendu de l’image de la caméra physique
Vous pouvez utiliser ARAssembly.CameraImageRenderer pour contrôler le rendu de l’image de la caméra physique.
Le code suivant peut arrêter le rendu de l’image de la caméra physique :
if (Session.Assembly != null && Session.Assembly.CameraImageRenderer.OnSome)
{
Session.Assembly.CameraImageRenderer.Value.enabled = false;
}
Notez qu’il faut d’abord vérifier si ARAssembly.CameraImageRenderer existe.
Note
Ce n’est que dans les sessions où l’image est rendue par EasyAR que vous pouvez arrêter la mise à jour de l’image avec la méthode ci-dessus. En général, elle n’est pas valide avec AR Foundation ou les casques, et il faut alors utiliser les méthodes fournies par ces bibliothèques tierces pour obtenir la fonction correspondante.
Après avoir arrêté le rendu de l’image de la caméra physique, l’application peut obtenir les données d’image de la caméra physique via InputFrame et utiliser ces données pour un rendu personnalisé.
Obtenir les mises à jour de transform
Vous pouvez obtenir les données de transform des objets de la scène après chaque mise à jour de session grâce à l’événement PostSessionUpdate.
Note
Pour certaines fonctions (par exemple Mega), même s’il n’y a pas de changement d’image ni de demande visible de mise à jour au service, le calcul AR s’exécute à chaque frame de rendu. Si vous devez obtenir tous les changements de transform, vous devez donc récupérer les données de transform à chaque frame et non seulement sur certaines frames.
Obtenir le transform de la caméra virtuelle
Vous pouvez obtenir le transform de la caméra de la scène via ARAssembly.Camera.
Session.PostSessionUpdate += () =>
{
var position = Session.Assembly.Camera.transform.position;
var rotation = Session.Assembly.Camera.transform.rotation;
};
Obtenir le transform du target
Vous pouvez obtenir le transform du target de la scène via l’objet target spécifique utilisé. Par exemple, pour l’image tracking, ce target est l’objet qui contient le composant ImageTargetController.
Session.PostSessionUpdate += () =>
{
var position = target.transform.position;
var rotation = target.transform.rotation;
};
[Optionnel] Obtenir la pose
La pose est une structure de données qui décrit la position et l’orientation d’un objet, et se compose généralement de position et rotation. Dans les applications AR, la pose est souvent utilisée pour décrire la position et l’orientation de la caméra physique ou du target de tracking par rapport à un repère.
Unity ne fournit pas de données de pose brutes, car la pose sert généralement à piloter le mouvement des objets de la scène, et c’est précisément ce que session fait automatiquement. Pour le calcul et le rendu du contenu, transform suffit.
Important
Avant de lire la méthode ci-dessous, demandez-vous à nouveau si les données de transform de la caméra, du target de tracking et des autres objets satisfont déjà vos besoins. En général, des données de pose supplémentaires ne sont pas nécessaires.
Si, pour une raison particulière, vous avez vraiment besoin de données de pose, vous pouvez les calculer à partir de transform dans l’événement PostSessionUpdate. En général, le transform relatif du target et de la camera obtenu dans PostSessionUpdate correspond déjà à la pose.
Le code suivant montre comment obtenir les transforms de camera et target, puis calculer la pose relative entre les deux :
Session.PostSessionUpdate += () =>
{
Pose cameraToWorld = new(Session.Assembly.Camera.transform.position, Session.Assembly.Camera.transform.rotation);
Pose targetToWorld = new(target.transform.position, target.transform.rotation);
Pose worldToTarget = new()
{
position = Quaternion.Inverse(targetToWorld.rotation) * (-targetToWorld.position),
rotation = Quaternion.Inverse(targetToWorld.rotation)
};
Pose cameraToTarget = cameraToWorld.GetTransformedBy(worldToTarget);
};
Attention
Si vous utilisez en même temps AR Foundation, un casque ou d’autres bibliothèques tierces en cours d’exécution, ces bibliothèques peuvent aussi modifier le transform de la caméra de la scène. Il faut s’assurer que le calcul de pose est fait après la fin de leurs logiques de mise à jour ; sinon, le résultat peut être incorrect. Dans un tel scénario, la pose relative du target et de l’origin dans PostSessionUpdate reste correcte.
[Optionnel] Intercepter les mises à jour de transform
Lorsque les fonctions AR sont en cours d’exécution, le transform de la caméra, du target de tracking et d’autres objets dans Unity est généralement mis à jour automatiquement par session. Ces mises à jour garantissent la justesse et la cohérence du rendu AR, il n’existe donc aucun moyen d’intercepter directement ces mises à jour.
Mais si vous avez besoin d’une logique personnalisée de mise à jour du transform des objets, vous pouvez le faire en écoutant l’événement PostSessionUpdate. Ici, il faut utiliser une méthode un peu lourde :
- Même si, en temps normal, le contenu de rendu devrait être attaché sous les objets contrôlés par session sous forme d’enfants ou de composants ajoutés, si vous devez personnaliser la mise à jour du transform de ces objets, il faut les retirer de la hiérarchie contrôlée par session. Autrement dit, ces objets ne doivent pas être des enfants des objets contrôlés par session.
- Dans l’événement PostSessionUpdate, enregistrez le transform des objets que vous souhaitez mettre à jour de manière personnalisée.
- Enfin, dans l’événement PostSessionUpdate, utilisez votre logique personnalisée pour mettre à jour ces objets selon les données fournies par session.
Note
L’utilisation de l’événement PostSessionUpdate est nécessaire, car ce n’est qu’après ce moment que session n’agit plus sur les objets de la scène.
Notez que cette méthode ne peut pas être utilisée pour modifier la camera ; une logique plus complexe est nécessaire pour gérer la mise à jour personnalisée de la caméra.
De plus, cette méthode ne sert qu’à mettre à jour de manière personnalisée le transform des objets, et non à modifier le transform des objets contrôlés par session. Si le transform d’un objet contrôlé par session est modifié de l’extérieur, session écrasera toujours ces modifications lors de la mise à jour de la frame suivante, ce qui peut affecter la justesse de certains calculs.
Attention
L’utilisation de cette méthode exige que vous garantissiez la justesse du transform des objets ; sinon, cela peut provoquer des erreurs de rendu AR.
Si vous utilisez aussi AR Foundation, un casque ou d’autres bibliothèques tierces, ces bibliothèques peuvent modifier le transform des objets de la scène. Il faut s’assurer que la logique de mise à jour de ces bibliothèques n’entre pas en conflit avec votre logique personnalisée ; sinon, cela peut produire des résultats imprévisibles.
Sujets connexes
- Mode central limite quels objets la session peut modifier via transform
- Présentation des composants AR de base