Models

Un modelo, en Azure Remote Rendering, se refiere a una representación de objeto completa, formada por entidades y componentes. Los modelos son la manera principal de obtener datos personalizados en el servicio Remote Rendering.

Estructura del modelo

Un modelo tiene exactamente una entidad como nodo raíz. Por debajo, puede tener una jerarquía arbitraria de entidades secundarias. Al cargar un modelo, se devuelve una referencia a esta entidad raíz.

Cada entidad puede tener componentes adjuntos. En el caso más común, las entidades tienen MeshComponents, que hacen referencia a los recursos de malla.

Creación de modelos

La creación de modelos para el entorno de tiempo de ejecución se logra mediante la conversión de modelos de entrada a partir de formatos de archivo como FBX, GLTF y E57. El proceso de conversión extrae todos los recursos, como texturas, materiales y mallas, y los convierte en formatos para entornos en tiempo de ejecución optimizados. También extrae la información estructural y la convierte en la estructura del grafo de entidad/componente de ARR.

Importante

La conversión de modelos es la única manera de crear mallas. Aunque las mallas se pueden compartir entre entidades en tiempo de ejecución, no hay otra manera de obtener una malla en el entorno en tiempo de ejecución, aparte de cargar un modelo.

Carga de modelos

Una vez que se convierte un modelo, se puede cargar desde Azure Blob Storage en el entorno en tiempo de ejecución.

Hay dos funciones de carga distintas que difieren en la forma en que se trata el recurso en Blob Storage:

  • El modelo se puede direccionar directamente mediante parámetros de Blob Storage, en caso de que Blob Storage esté vinculado a la cuenta. En este caso, la función de carga pertinente es LoadModelAsync con el parámetro LoadModelOptions.
  • El modelo se puede direccionar desde su URI de SAS. La función de carga pertinente es LoadModelFromSasAsync con el parámetro LoadModelFromSasOptions. Use también esta variante al cargar modelos integrados.

Los fragmentos de código siguientes muestran cómo cargar modelos con ambas funciones. Para cargar un modelo usando sus parámetros de almacenamiento de blobs, use código como el siguiente:

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

Si quiere cargar un modelo mediante un token de SAS, use código similar al siguiente fragmento de código:

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

Después, puede atravesar la jerarquía de entidades y modificar las entidades y los componentes. Al cargar el mismo modelo varias veces, se crean varias instancias, cada una con su propia copia de la estructura de entidad/componente. Sin embargo, dado que las mallas, los materiales y las texturas son recursos compartidos, sus datos no se volverán a cargar. Por lo tanto, la creación de instancias de un modelo más de una vez incurre en una sobrecarga de memoria relativamente escasa.

Documentación de la API

Pasos siguientes