Entidades

Uma Entidade representa um objeto móvel no espaço e é o bloco de construção fundamental do conteúdo renderizado remotamente.

Propriedades da entidade

As entidades têm uma transformação definida por posição, rotação e escala. Por si só, as entidades não têm nenhuma funcionalidade observável. Em vez disso, o comportamento é adicionado por meio de componentes, que são anexados às entidades. Por exemplo, anexar um CutPlaneComponent cria um plano de corte na posição da entidade.

O aspecto mais importante da entidade em si é a hierarquia e a transformação hierárquica resultante. Por exemplo, quando várias entidades estão anexadas como filhos a uma entidade pai compartilhada, todas elas podem ser movidas, giradas e dimensionadas de forma não dinâmica alterando a transformação da entidade pai. Além disso, o estado enabled da entidade pode ser usado para desativar a visibilidade e as respostas a ray casts para um subgrafo completo na hierarquia.

Uma entidade é de propriedade exclusiva de seu pai, o que significa que, quando o pai é destruído com Entity.Destroy(), também são seus filhos e todos os componentes conectados. Deste modo, a remoção de um modelo da cena é realizada chamando Destroy no nó raiz de um modelo, retornado por RenderingSession.Connection.LoadModelAsync() ou sua variante SAS RenderingSession.Connection.LoadModelFromSasAsync().

As entidades são criadas quando o servidor carrega o conteúdo ou quando o usuário quer adicionar um objeto à cena. Por exemplo, se um usuário quiser adicionar um plano de corte para visualizar o interior de uma malha, o usuário poderá criar uma entidade em que o plano deve existir e, em seguida, adicionar o componente do plano de corte a ela.

Criar uma entidade

Para adicionar uma nova entidade à cena, por exemplo, para passá-la como um objeto raiz para carregar modelos ou anexar componentes a ela, use o seguinte código:

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

Funções de consulta

Há dois tipos de funções de consulta em entidades: chamadas síncronas e chamadas assíncronas. As consultas síncronas só podem ser usadas para dados que estão presentes no cliente e não envolvem muita computação. Por exemplo, consultas para componentes, transformações de objeto relativo ou relações pai/filho. As consultas assíncronas são usadas para dados que residem apenas no servidor ou envolvem computação extra que seria muito cara para ser executada no cliente. Por exemplo, consultas de limites espaciais ou consultas de metadados.

Consultando componentes

Para encontrar um componente de um tipo específico, use 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>();

Como consultar transformações

As chamadas síncronas no objeto são consultas de transformação. É importante observar que as transformações armazenadas no lado da API são transformações de espaço local, em relação ao pai do objeto. As exceções são objetos raiz para os quais o espaço local e o espaço do mundo são idênticos.

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

Caso todos os componentes da transformação em árvore (posição, rotação e escala) precisem ser recuperados ou definidos simultaneamente, recomenda-se usar a propriedade da LocalTransform entidade:

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

Há também uma função auxiliar para recuperar a transformação global (espaço mundial) de uma entidade:

// 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 é chamada, a transformação global é computada em tempo real, atravessando a hierarquia de entidade. Essa travessia envolve computação significativa, mas em comparação com fazer as mesmas operações no lado do cliente através da classe Entity, a função interna é mais rápida. Ainda assim, recorrer a GlobalTransform um conjunto maior de entidades pode impor um gargalo de desempenho.

LocalToGlobalMatrix é uma variante do GlobalTransform que calcula a transformação global como uma matriz, o que é conveniente no contexto de Unity:

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

Consultando limites espaciais

Chamadas assíncronas são consultas de limites que operam em uma hierarquia de objetos completa, usando uma entidade como raiz. Consulte o capítulo dedicado sobre limites de objetos.

Consultando metadados

Metadados são dados extras armazenados em objetos que são ignorados pelo servidor. Os metadados de objeto são essencialmente um conjunto de pares (nome, valor), em que o valor pode ser numérico, booliano ou tipo de cadeia de caracteres. Os metadados podem ser exportados com o modelo.

Consultas de metadados são as chamadas assíncronas em uma entidade específica. A consulta fornece apenas os metadados de uma única entidade, não as informações mescladas de um subgrafo.

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

        // ...
    }
});

A consulta será bem-sucedida mesmo se o objeto não contiver metadados.

Documentação da API

Próximas etapas