Entités

Une entité représente un objet déplaçable dans l’espace et constitue le bloc de construction de base d’un contenu rendu à distance.

Propriétés d’entité

Les entités ont une transformation définie par une position, une rotation et une échelle. Par eux-mêmes, les entités n’ont aucune fonctionnalité observable. Au lieu de cela, leur comportement est ajouté au travers de composants attachés à des entités. Par exemple, l’attachement d’un CutPlaneComponent crée un plan de coupe à la position de l’entité.

L’aspect le plus important de l’entité elle-même est la hiérarchie et la transformation hiérarchique qui en résulte. Par exemple, quand plusieurs entités sont jointes en tant qu’enfants à une entité parente partagée, toutes ces entités peuvent être déplacées, pivotées et mises à l’échelle en modifiant la transformation de l’entité parente. De même, l’état enabled de l’entité peut être utilisé pour désactiver la visibilité et les réponses aux ray casts pour un sous-graphique complet de la hiérarchie.

Une entité est la propriété exclusive de son entité parente. Cela signifie que, quand celle-ci est détruite à l’aide de la commande Entity.Destroy(), ses entités enfants et tous les composants connectés le sont également. Ainsi, la suppression d’un modèle de la scène s’effectue en appelant Destroy sur le nœud racine d’un modèle retourné par la commande RenderingSession.Connection.LoadModelAsync() ou sa variante SAP RenderingSession.Connection.LoadModelFromSasAsync().

Des entités sont créées quand le serveur charge du contenu ou quand l’utilisateur souhaite ajouter un objet à la scène. Par exemple, si un utilisateur souhaite ajouter un plan de coupe pour visualiser l’intérieur d’un maillage, l’utilisateur peut créer une entité dans laquelle le plan doit exister, puis y ajouter le composant plan de coupe.

Créer une entité

Pour ajouter une nouvelle entité à la scène, par exemple pour la transmettre en tant qu’objet racine pour charger des modèles ou y attacher des composants, utilisez le code suivant :

Entity CreateNewEntity(RenderingSession session)
{
    Entity entity = session.Connection.CreateEntity();
    entity.Position = new LocalPosition(1, 2, 3);
    return entity;
}
ApiHandle<Entity> CreateNewEntity(ApiHandle<RenderingSession> session)
{
    ApiHandle<Entity> entity(nullptr);
    if (auto entityRes = session->Connection()->CreateEntity())
    {
        entity = entityRes.value();
        entity->SetPosition(Double3{ 1, 2, 3 });
        return entity;
    }
    return entity;
}

Fonctions de requête

Il existe deux types de fonctions de requête sur les entités : les appels synchrones et asynchrones. Les requêtes synchrones peuvent uniquement être utilisées pour les données présentes sur le client et n’impliquent pas beaucoup de calcul. Il s’agit, par exemple, de requêtes portant sur des composants, des transformations d’objets relatifs ou des relations parent/enfant. Les requêtes asynchrones sont utilisées pour des données qui résident uniquement sur le serveur ou qui impliquent un calcul supplémentaire dont l’exécution sur le client serait trop coûteuse. Il s’agit, par exemple, de requêtes portant sur des limites spatiales ou des métadonnées.

Interrogation de composants

Pour rechercher un composant d’un type spécifique, utilisez la commande FindComponentOfType :

CutPlaneComponent cutplane = (CutPlaneComponent)entity.FindComponentOfType(ObjectType.CutPlaneComponent);

// or alternatively:
CutPlaneComponent cutplane = entity.FindComponentOfType<CutPlaneComponent>();
ApiHandle<CutPlaneComponent> cutplane = entity->FindComponentOfType(ObjectType::CutPlaneComponent)->as<CutPlaneComponent>();

// or alternatively:
ApiHandle<CutPlaneComponent> cutplane = entity->FindComponentOfType<CutPlaneComponent>();

Interrogation de transformations

Les requêtes de transformation sont des appels synchrones sur l’objet. Il est important de noter que les transformations stockées côté API sont des transformations d’espace local, par rapport au parent de l’objet. Y font exception les objets racine, pour lesquels l’espace local et l’espace universel sont identiques.

// local space transform of the entity
Double3 translation = entity.Position;
Quaternion rotation = entity.Rotation;
Float3 scale = entity.Scale;
// local space transform of the entity
Double3 translation = entity->GetPosition();
Quaternion rotation = entity->GetRotation();
Float3 scale = entity->GetScale();

Si tous les composants de transformation d’arborescence (position, rotation et échelle) doivent être récupérés ou définis simultanément, il est recommandé d’utiliser la propriété de l’entité LocalTransform :

// local space transform of the entity
Transform localTransform = entity.LocalTransform;
Double3 translation = localTransform.Position;
Quaternion rotation = localTransform.Rotation;
Float3 scale = localTransform.Scale;
// local space transform of the entity
Transform localTransform = entity->GetLocalTransform();
Double3& translation = localTransform.Position;
Quaternion& rotation = localTransform.Rotation;
Float3& scale = localTransform.Scale;

Il existe également une fonction d’assistance pour récupérer la transformation globale (espace mondial) d’une entité :

// global space transform of the entity
Transform globalTransform = entity.GlobalTransform;
Double3 translation = globalTransform.Position;
// global space transform of the entity
Transform globalTransform = entity->GetGlobalTransform();
Double3& translation = globalTransform.Position;

Quand GlobalTransform elle est appelée, la transformation globale est calculée à la volée en parcourant la hiérarchie d’entités. Ce parcours implique un calcul significatif, mais par rapport à l’exécution des mêmes opérations côté client par classe Entity, la fonction intégrée est plus rapide. Néanmoins, l’appel GlobalTransform à un plus grand ensemble d’entités peut imposer un goulot d’étranglement des performances.

LocalToGlobalMatrix est une variante de GlobalTransform ce qui calcule la transformation globale en tant que matrice, qui est pratique dans le contexte d’Unity :

UnityEngine.Matrix4x4 globalMatrix = entity.LocalToGlobalMatrix.toUnity();
UnityEngine.Vector3 localPos = new UnityEngine.Vector3(0, 0, 0);
UnityEngine.Vector3 globalPos = globalMatrix.MultiplyPoint(localPos);

Interrogation des limites spatiales

Les requêtes de limites sont des appels asynchrones qui opèrent sur une hiérarchie d’objets complète, en utilisant une entité comme racine. Reportez-vous au chapitre dédié aux limites d’objets.

Interrogation des métadonnées

Les métadonnées sont des données supplémentaires stockées sur des objets qui sont ignorés par le serveur. Des métadonnées d’objet sont essentiellement un ensemble de paires (nom, valeur), où la valeur peut être de type numérique, booléen ou chaîne. Les métadonnées peuvent être exportées avec le modèle.

Les requêtes de métadonnées sont des appels asynchrones sur une entité spécifique. La requête retourne uniquement les métadonnées d’une entité, non les informations fusionnées d’un sous-graphe.

Task<ObjectMetadata> metaDataQuery = entity.QueryMetadataAsync();
ObjectMetadata metaData = await metaDataQuery;
ObjectMetadataEntry entry = metaData.GetMetadataByName("MyInt64Value");
System.Int64 intValue = entry.AsInt64;
// ...
entity->QueryMetadataAsync([](Status status, ApiHandle<ObjectMetadata> metaData) 
{
    if (status == Status::OK)
    {
        ApiHandle<ObjectMetadataEntry> entry = *metaData->GetMetadataByName("MyInt64Value");
        int64_t intValue = *entry->GetAsInt64();

        // ...
    }
});

La requête réussit même si l’objet ne contient pas de métadonnées.

Documentation de l’API

Étapes suivantes