モデル

Azure Remote Rendering の モデル とは、エンティティコンポーネントで構成される完全なオブジェクト表現を指します。 モデルは、リモート レンダリング サービスにカスタム データを取得するための主な方法です。

モデルの構造

モデルには、そのルート ノードとしてエンティティが 1 つだけあります。 その下に、任意の子エンティティの階層を含めることができます。 モデルを読み込むときに、このルート エンティティへの参照が返されます。

各エンティティには、コンポーネントがアタッチされている場合があります。 最も一般的なケースでは、エンティティには メッシュ リソースを参照する MeshComponents があります。

モデルの作成

ランタイム用のモデルの作成は、FBX や GLTF などのファイル形式から入力モデルを変換することによって行われます。 変換プロセスでは、テクスチャ、素材、メッシュなどのすべてのリソースが抽出され、最適化されたランタイム形式に変換されます。 また、構造情報が抽出され、それが ARR のエンティティまたはコンポーネント グラフ構造に変換されます。

重要

モデルの変換は、メッシュを作成する唯一の方法です。 メッシュは実行時にエンティティ間で共有できますが、ランタイムにメッシュを取得する方法は、モデルを読み込む以外にありません。

モデルの読み込み

変換されたモデルは、Azure Blob Storage からランタイムに読み込むことができます。

BLOB ストレージでのアセットのアドレス指定方法が異なる、2 つの別個の読み込み関数があります。

  • BLOB ストレージがアカウントにリンクされている場合、BLOB ストレージ パラメーターによってモデルを直接アドレス指定することができます。 この場合、関連する読み込み関数は、LoadModelAsync とパラメーター LoadModelOptions です。
  • モデルは、その SAS URI でアドレス指定できます。 関連する読み込み関数は、LoadModelFromSasAsync とパラメーター LoadModelFromSasOptions です。 組み込みのモデルを読み込む場合にもこのバリアントを使用します。

次のコード スニペットは、いずれかの関数を使用してモデルを読み込む方法を示しています。 Blob Storage パラメーターを使用してモデルを読み込むには、次のようなコードを使用します。

async void LoadModel(RenderingSession session, Entity modelParent, string storageAccount, string containerName, string assetFilePath)
{
    // load a model that will be parented to modelParent
    var modelOptions = new LoadModelOptions(
        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);
        }
    );
}

SAS トークンを使用してモデルを読み込む場合は、次のスニペットのようなコードを使用します。

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

その後、エンティティ階層を走査し、エンティティとコンポーネントを変更することができます。 同じモデルを複数回読み込むと、複数のインスタンスが作成され、それぞれにエンティティまたはコンポーネント構造のコピーが作成されます。 一方、メッシュ、素材、テクスチャは共有リソースであるため、それらのデータは再度読み込まれません。 したがって、モデルを複数回インスタンス化すると、比較的小さいメモリのオーバーヘッドが発生します。

API のドキュメント

次のステップ