Entità

Un entità rappresenta un oggetto mobile nello spazio ed è il blocco predefinito fondamentale del contenuto sottoposto a rendering da remoto.

Proprietà delle entità

Le entità subiscono una trasformazione definita in termini di posizione, rotazione e scalabilità. Le entità non dispongono di alcuna funzionalità osservabile. Al contrario, il comportamento viene aggiunto tramite componenti, che sono collegati alle entità. Ad esempio, l'associazione di un elemento CutPlaneComponent crea un piano di taglio nella posizione dell'entità.

L'aspetto più importante dell'entità stessa è rappresentato dalla gerarchia e dalla trasformazione gerarchica risultante. Ad esempio, quando più entità sono collegate come elementi figlio a un'entità padre condivisa, tutte queste entità possono essere spostate, ruotate e ridimensionate all'unisono modificando la trasformazione dell'entità padre. Inoltre, lo stato dell'entità enabled può essere usato per disattivare la visibilità e le risposte ai cast di raggi per un sottografo completo nella gerarchia.

Un'entità è di proprietà esclusiva dell'elemento padre e ciò significa che, quando l'elemento padre viene eliminato definitivamente con Entity.Destroy(), vengono eliminati anche i relativi elementi figlio e tutti i componenti connessi. Pertanto, la rimozione di un modello dalla scena viene eseguita chiamando Destroy sul nodo radice di un modello, restituito da RenderingSession.Connection.LoadModelAsync() o dalla relativa variante SAS RenderingSession.Connection.LoadModelFromSasAsync().

Le entità vengono create quando il server carica contenuti o quando l'utente desidera aggiungere un oggetto alla scena. Se, ad esempio, un utente desidera aggiungere un piano di taglio per visualizzare l'area interna di una mesh, può creare un'entità in cui deve esistere il piano e quindi aggiungervi il componente del piano tagliato.

Creare un'entità

Per aggiungere una nuova entità alla scena, ad esempio per passarla come oggetto radice per il caricamento di modelli o il collegamento di componenti, usare il codice seguente:

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;
}

Funzioni di query

Esistono due tipi di funzioni di query sulle entità: chiamate sincrone e asincrone. Le query sincrone possono essere usate solo per i dati presenti nel client e non comportano molto calcolo. Ne sono un esempio le query per componenti, trasformazioni di oggetti relativi o relazioni padre/figlio. Le query asincrone vengono usate per i dati che risiedono solo nel server o implicano calcoli aggiuntivi che sarebbero troppo costosi da eseguire sul client. Ne sono un esempio le query sui limiti spaziali o sui metadati.

Esecuzione di query sui componenti

Per trovare un componente di un tipo specifico, usare 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>();

Esecuzione di query sulle trasformazioni

Le query di trasformazione sono chiamate sincrone sull'oggetto. È importante notare che le trasformazioni archiviate sul lato API sono trasformazioni dello spazio locale rispetto all'elemento padre dell'oggetto. Fanno eccezione gli oggetti radice, per cui lo spazio locale e lo spazio globale sono identici.

// 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();

Nel caso in cui tutti i componenti della trasformazione albero (posizione, rotazione e scala) debbano essere recuperati o impostati contemporaneamente, è consigliabile usare la proprietà dell'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;

È disponibile anche una funzione helper per recuperare la trasformazione globale (spazio globale) di un'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;

Quando GlobalTransform viene chiamato , la trasformazione globale viene calcolata in tempo reale attraversando la gerarchia di entità. Questo attraversamento comporta calcoli significativi, ma rispetto all'esecuzione delle stesse operazioni sul lato client tramite la classe Entity, la funzione predefinita è più veloce. Tuttavia, la chiamata GlobalTransform a un set di entità più ampio potrebbe imporre un collo di bottiglia delle prestazioni.

LocalToGlobalMatrix è una variante di GlobalTransform che calcola la trasformazione globale come matrice, utile nel contesto di Unity:

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

Query sui limiti spaziali

Le query sui limiti sono chiamate asincrone che operano su una gerarchia completa di oggetti, usando un'unica entità come radice. Vedere il capitolo dedicato sui limiti degli oggetti.

Query dei metadati

I metadati sono dati aggiuntivi archiviati in oggetti ignorati dal server. I metadati relativi ad oggetti sono essenzialmente un set di coppie (nome/valore), dove il valore può essere di tipo numerico o booleano oppure una stringa. I metadati possono essere esportati con il modello.

Le query sui metadati sono chiamate asincrone su un'entità specifica. La query restituisce solo i metadati di una singola entità, non le informazioni unite di un sottografico.

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 query ha esito positivo anche se l'oggetto non contiene metadati.

Documentazione sull'API

Passaggi successivi