Jednostki

Jednostka reprezentuje obiekt ruchomy w przestrzeni i jest podstawowym blokiem konstrukcyjnym zdalnie renderowanej zawartości.

Właściwości jednostki

Jednostki mają transformację zdefiniowaną przez położenie, rotację i skalę. Same jednostki nie mają żadnych zauważalnych funkcji. Zamiast tego zachowanie jest dodawane za pośrednictwem składników dołączonych do jednostek. Na przykład dołączenie elementu CutPlaneComponent powoduje utworzenie płaszczyzny wycinania na pozycji jednostki.

Najważniejszym aspektem samej jednostki jest hierarchia i wynikowa transformacja hierarchiczna. Jeśli na przykład wiele jednostek jest dołączonych jako elementy podrzędne do udostępnionej jednostki nadrzędnej, wszystkie te jednostki można przenosić, obracać i skalować w sposób jednoszonowy, zmieniając przekształcenie jednostki nadrzędnej. Ponadto stan jednostki enabled może służyć do wyłączania widoczności i odpowiedzi na rzutowania promieni dla pełnego wykresu podrzędnego w hierarchii.

Jednostka jest unikatowo własnością jej elementu nadrzędnego, co oznacza, że gdy element nadrzędny zostanie zniszczony z elementem , są więc jego elementami podrzędnymi i wszystkimi połączonymi składnikami.Entity.Destroy() W związku z tym usunięcie modelu ze sceny odbywa się przez wywołanie Destroy węzła głównego modelu, zwróconego przez RenderingSession.Connection.LoadModelAsync() wariant SYGNATURy dostępu współdzielonego lub jego wariantu sygnatury dostępu współdzielonego RenderingSession.Connection.LoadModelFromSasAsync().

Jednostki są tworzone, gdy serwer ładuje zawartość lub kiedy użytkownik chce dodać obiekt do sceny. Jeśli na przykład użytkownik chce dodać płaszczyznę wycinania w celu wizualizacji wnętrza siatki, użytkownik może utworzyć jednostkę, w której powinna istnieć płaszczyzna, a następnie dodać do niej składnik płaszczyzny wycięcia.

Tworzenie jednostki

Aby dodać nową jednostkę do sceny, na przykład przekazać ją jako obiekt główny do ładowania modeli lub dołączania do niego składników, użyj następującego kodu:

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

Funkcje zapytań

Istnieją dwa typy funkcji zapytań dla jednostek: wywołania synchroniczne i asynchroniczne. Zapytania synchroniczne mogą być używane tylko w przypadku danych znajdujących się na kliencie i nie wymagają dużej ilości obliczeń. Przykładami są zapytania dotyczące składników, przekształceń obiektów względnych lub relacji nadrzędnych/podrzędnych. Zapytania asynchroniczne są używane w przypadku danych, które znajdują się tylko na serwerze lub obejmują dodatkowe obliczenia, które byłyby zbyt kosztowne do uruchomienia na kliencie. Przykłady to zapytania dotyczące granic przestrzennych lub zapytania dotyczące metadanych.

Wykonywanie zapytań dotyczących składników

Aby znaleźć składnik określonego typu, użyj polecenia 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>();

Wykonywanie zapytań dotyczących przekształceń

Zapytania przekształcania to synchroniczne wywołania obiektu. Należy pamiętać, że przekształcenia przechowywane po stronie interfejsu API to przekształcenia przestrzeni lokalnej względem obiektu nadrzędnego obiektu. Wyjątki to obiekty główne, dla których przestrzeń lokalna i przestrzeń światowa są identyczne.

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

Jeśli wszystkie składniki przekształcania drzewa (pozycja, rotacja i skala) muszą być pobierane lub ustawiane jednocześnie, zaleca się użycie właściwości jednostki 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;

Istnieje również funkcja pomocnika służąca do pobierania globalnej (przestrzeni światowej) jednostki:

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

Po GlobalTransform wywołaniu transformacja globalna jest obliczana na bieżąco przez przechodzenie w górę hierarchii jednostek. Ten przechodzenie obejmuje znaczne obliczenia, ale w porównaniu z wykonywaniem tych samych operacji po stronie klienta za pośrednictwem klasy Entity, wbudowana funkcja jest szybsza. Mimo to wywołanie GlobalTransform większego zestawu jednostek może powodować wąskie gardło wydajności.

LocalToGlobalMatrix jest wariantem GlobalTransform , który oblicza globalną transformację jako macierz, która jest wygodna w kontekście aparatu Unity:

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

Wykonywanie zapytań dotyczących granic przestrzennych

Zapytania dotyczące granic to asynchroniczne wywołania, które działają w pełnej hierarchii obiektów, używając jednej jednostki jako katalogu głównego. Zobacz dedykowany rozdział o granicach obiektów.

Wykonywanie zapytań dotyczących metadanych

Metadane są dodatkowymi danymi przechowywanymi w obiektach ignorowanych przez serwer. Metadane obiektu to zasadniczo zestaw par (nazwa, wartość), w których wartość może być typu liczbowego, logicznego lub ciągu. Metadane można eksportować za pomocą modelu.

Zapytania metadanych to asynchroniczne wywołania określonej jednostki. Zapytanie zwraca tylko metadane pojedynczej jednostki, a nie scalone informacje o wykresie podrzędnym.

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

        // ...
    }
});

Zapytanie powiedzie się, nawet jeśli obiekt nie przechowuje żadnych metadanych.

Dokumentacja interfejsu API

Następne kroki