Modelos

Um modelo no Azure Remote Rendering refere-se a uma representação de objeto completa, composta de entidades e componentes. Os modelos são a principal maneira de obter dados personalizados para o serviço de renderização remoto.

Estrutura do modelo

Um modelo tem exatamente um entidade como seu nó raiz. Abaixo disso, ele pode ter uma hierarquia arbitrária de entidades filho. Ao carregar um modelo, uma referência a essa entidade raiz é retornada.

Cada entidade pode ter componentes anexados. No caso mais comum, as entidades têm MeshComponents, que fazem referência a recursos de malha.

Criar modelos

A criação de modelos para runtime é obtida convertendo modelos de entrada a partir dos formatos de arquivo, como FBX, GLTF ou E57. O processo de conversão extrai todos os recursos, como texturas, materiais e malhas, e os converte em formatos de runtime otimizados. Ele também extrairá as informações estruturais e as converterá na estrutura do grafo de entidade/componente do Application Request Routing.

Importante

A conversão de modelo é a única maneira de criar malhas. Embora as malhas possam ser compartilhadas entre entidades no runtime, não há outra maneira de obter uma malha no runtime, a não ser ao carregar um modelo.

Carregar modelos

Depois que um modelo é convertido, ele pode ser carregado a partir do armazenamento de blobs do Azure para o runtime.

Há duas funções de carregamento distintas que diferem na maneira como o ativo é endereçado no armazenamento de blobs:

  • O modelo pode ser tratado pelos parâmetros de armazenamento de blobs, caso o Armazenamento de Blobs esteja vinculado à conta. A função de carregamento relevante nesse caso é LoadModelAsync com o parâmetro LoadModelOptions.
  • O modelo pode ser endereçado por seu URI de SAS. A função de carregamento relevante é LoadModelFromSasAsync com o parâmetro LoadModelFromSasOptions. Use essa variante também ao carregar modelos integrados.

Os trechos de código a seguir mostram como carregar modelos com uma das funções. Para carregar um modelo usando os parâmetros de armazenamento de blob, use um código como este abaixo:

async void LoadModel(RenderingSession session, Entity modelParent, string storageAccount, string containerName, string assetFilePath)
{
    // load a model that will be parented to modelParent
    var modelOptions = LoadModelOptions.CreateForBlobStorage(
        storageAccount, // storage account name + '.blob.core.windows.net', e.g., 'mystorageaccount.blob.core.windows.net'
        containerName,  // name of the container in your storage account, e.g., 'mytestcontainer'
        assetFilePath,  // the file path to the asset within the container, e.g., 'path/to/file/myAsset.arrAsset'
        modelParent
    );

    var loadOp = session.Connection.LoadModelAsync(modelOptions, (float progress) =>
    {
        Debug.WriteLine($"Loading: {progress * 100.0f}%");
    });

    await loadOp;
}
void LoadModel(ApiHandle<RenderingSession> session, ApiHandle<Entity> modelParent, std::string storageAccount, std::string containerName, std::string assetFilePath)
{
    LoadModelOptions modelOptions;
    modelOptions.Parent = modelParent;
    modelOptions.Blob.StorageAccountName = std::move(storageAccount);
    modelOptions.Blob.BlobContainerName = std::move(containerName);
    modelOptions.Blob.AssetPath = std::move(assetFilePath);

    ApiHandle<LoadModelResult> result;
    session->Connection()->LoadModelAsync(modelOptions,
        // completion callback
        [](Status status, ApiHandle<LoadModelResult> result)
        {
            printf("Loading: finished.");
        },
        // progress callback
        [](float progress)
        {
            printf("Loading: %.1f%%", progress * 100.f);
        }
    );
}

Se quiser carregar um modelo usando token SAS, use um código semelhante ao trecho a seguir:

async void LoadModel(RenderingSession session, Entity modelParent, string modelUri)
{
    // load a model that will be parented to modelParent
    var modelOptions = new LoadModelFromSasOptions(modelUri, modelParent);

    var loadOp = session.Connection.LoadModelFromSasAsync(modelOptions, (float progress) =>
    {
        Debug.WriteLine($"Loading: {progress * 100.0f}%");
    });

    await loadOp;
}
void LoadModel(ApiHandle<RenderingSession> session, ApiHandle<Entity> modelParent, std::string modelUri)
{
    LoadModelFromSasOptions modelOptions;
    modelOptions.ModelUri = modelUri;
    modelOptions.Parent = modelParent;

    ApiHandle<LoadModelResult> result;
    session->Connection()->LoadModelFromSasAsync(modelOptions,
        // completion callback
        [](Status status, ApiHandle<LoadModelResult> result)
        {
            printf("Loading: finished.");
        },
        // progress callback
        [](float progress)
        {
            printf("Loading: %.1f%%", progress * 100.f);
        }
    );
}

Posteriormente, é possível percorrer a hierarquia de entidade e mudar as entidades e os componentes. Carregar o mesmo modelo várias vezes cria várias instâncias, cada uma com sua própria cópia da estrutura de entidade/componente. Como as malhas, os materiais e as texturas são recursos compartilhados, os dados não serão carregados novamente. Portanto, instanciar um modelo mais de uma vez gera uma sobrecarga de memória relativamente pequena.

Documentação da API

Próximas etapas