Сущности

Сущность представляет перемещаемый в пространстве объект и является базовым строительным блоком для любого содержимого удаленной отрисовки.

Свойства сущности

Для сущностей задаются преобразования со свойствами перемещения, поворота и масштабирования. Сами сущности не имеют наблюдаемых функций. Любое поведение реализуется через добавление компонентов к сущностям. Например, присоединение CutPlaneComponent создает плоскость вырезания в позиции сущности.

Наиболее важным аспектом самой сущности является иерархия и итоговое иерархическое преобразование. Например, если несколько сущностей присоединены как дочерние элементы к одной родительской сущности, все эти сущности можно перемещать, поворачивать и масштабировать синхронно, изменяя преобразование для родительской сущности. Кроме того, состояние сущности enabled можно использовать для отключения видимости и реакций на падение лучей для полного вложенного графа в иерархии.

Сущность имеет строго один родительский элемент. При удалении родительского элемента с помощью Entity.Destroy() удаляются и все его дочерние элементы, в том числе подключенные компоненты. Таким образом, модель из сцены можно удалить путем вызова Destroy для корневого узла модели, полученного от метода RenderingSession.Connection.LoadModelAsync() или аналогичного метода SAS RenderingSession.Connection.LoadModelFromSasAsync().

Сущности создаются, когда сервер загружает содержимое или пользователь выражает намерение добавить объект в сцену. Например, если пользователь хочет добавить плоскость разрезания для визуализации внутренней части сетки, он может создать сущность в том положении, где должна располагаться эта плоскость, а затем добавить к ней компонент плоскости разрезания.

Создание сущности

Чтобы добавить новую сущность в сцену, например передать ее в качестве корневого объекта для загрузки моделей или подключения компонентов к ней, используйте следующий код:

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

Функции запросов

В сущностях есть два типа функций запросов: синхронные и асинхронные вызовы. Синхронные запросы можно использовать только для данных, присутствующих на клиенте, и не требует много вычислений. Например, к ним относится получение компонентов, относительных преобразований объектов или связей "родительский элемент — дочерний элемент". Асинхронные запросы используются для данных, существующих только на сервере или требующих дополнительных вычислений, для которых в клиенте недостаточно ресурсов. К ним относятся запросы пространственных границ или метаданных.

Запросы для получения компонентов

Чтобы получить компонент определенного типа, используйте 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>();

Запросы для получения преобразований

Запросы преобразования выполняются синхронно и адресуются объекту. Важно отметить, что преобразования, хранящиеся на стороне API, являются локальными преобразованиями пространства относительно родительского объекта. Исключением можно считать корневые объекты, для которых локальное пространство и мировое пространство совпадают.

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

Если необходимо получить или задать одновременно все компоненты преобразования дерева (положение, поворот и масштабирование), рекомендуется использовать свойство сущности 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;

Существует также вспомогательной функцией для получения глобального (мирового пространства) сущности:

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

При GlobalTransform вызове глобальное преобразование вычисляется во всплывающем режиме путем обхода иерархии сущностей. Этот обход включает значительные вычисления, но по сравнению с выполнением одних и то же операций на стороне клиента через класс Entity, встроенная функция быстрее. Тем не менее, вызов GlobalTransform большего набора сущностей может привести к узким местам производительности.

LocalToGlobalMatrix — это вариант GlobalTransform , который вычисляет глобальное преобразование как матрицу, которая удобна в контексте Unity:

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

Запросы для получения пространственных границ

Запросы к границам выполняются асинхронно и могут применяться к полной иерархии объектов, где одна сущность считается корневой. Описанию границ объектов посвящена отдельная глава руководства.

Запрос метаданных

Метаданные — это дополнительные данные, хранящиеся на объектах, которые игнорируются сервером. Метаданные объекта, по сути, представляют собой набор пар (имя и значение), где значение может иметь числовой, логический или строковый тип. Метаданные можно экспортировать с помощью модели.

Запросы к метаданным выполняются асинхронно и адресуются определенной сущности. Такой запрос возвращает метаданные только для одной сущности, но не объединяет их по вложенному графу.

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

        // ...
    }
});

Запрос завершается успешно, даже если объект не содержит метаданных.

Документация по API

Следующие шаги