// Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
//
// SPDX-License-Identifier: CC-BY-4.0

include::{generated}/meta/XR_FB_render_model.adoc[]

*Contributors*::
    Leonard Tsai, Meta +
    Xiang Wei, Meta +
    Robert Memmott, Meta +


*Overview*

This extension allows applications to request GLTF models for certain
connected devices supported by the runtime.
Paths that correspond to these devices will be provided through the
extension and can be used to get information about the models as well as
loading them.

*New Flag Types*

[open,refpage='XrRenderModelFlagsFB',type='flags',desc='XrRenderModelFlagsFB',xrefs='XrRenderModelFlagBitsFB']
--
include::{generated}/api/flags/XrRenderModelFlagsFB.adoc[]
--

[open,refpage='XrRenderModelFlagBitsFB',type='enums',desc='XrRenderModelFlagBitsFB',xrefs='XrRenderModelFlagsFB']
--
include::{generated}/api/enums/XrRenderModelFlagBitsFB.adoc[]

include::{generated}/api/enums/XrRenderModelFlagBitsFB.comments.adoc[]

Render Model Support Levels: An application should: request a model of a
certain complexity via the slink:XrRenderModelCapabilitiesRequestFB on the
structure chain of slink:XrRenderModelPropertiesFB passed into
flink:xrGetRenderModelPropertiesFB.
The flags on the slink:XrRenderModelCapabilitiesRequestFB are an
acknowledgement of the application's ability to render such a model.
Multiple values of elink:XrRenderModelFlagBitsFB can be set on this variable
to indicate acceptance of different support levels.
The flags parameter on the slink:XrRenderModelPropertiesFB will indicate
what capabilities the model in the runtime actually requires.
It will be set to a single value of elink:XrRenderModelFlagBitsFB.
--

*New Enum Constants*

elink:XrStructureType enumeration is extended with:

* ename:XR_TYPE_SYSTEM_RENDER_MODEL_PROPERTIES_FB
* ename:XR_TYPE_RENDER_MODEL_PATH_INFO_FB
* ename:XR_TYPE_RENDER_MODEL_PROPERTIES_FB
* ename:XR_TYPE_RENDER_MODEL_BUFFER_FB
* ename:XR_TYPE_RENDER_MODEL_LOAD_INFO_FB
* ename:XR_MAX_RENDER_MODEL_NAME_SIZE_FB

*New Defines*

[open,refpage='XR_NULL_RENDER_MODEL_KEY_FB',type='defines',desc='The value representing an invalid model key',xrefs='XrRenderModelKeyFB XrRenderModelPropertiesFB']
--
include::{generated}/api/defines/XR_NULL_RENDER_MODEL_KEY_FB.adoc[]

dlink:XR_NULL_RENDER_MODEL_KEY_FB defines an invalid model key atom.
--

*New Base Types*

[open,refpage='XrRenderModelKeyFB',desc='Model key',type='basetypes',xrefs='XR_NULL_RENDER_MODEL_KEY_FB']
--
include::{generated}/api/basetypes/XrRenderModelKeyFB.adoc[]

The unique model key used to retrieve the data for the render model that is
valid across multiple instances and installs.
The application can use this key along with the model version to update its
cached or saved version of the model.
--

*New Structures*

[open,refpage='XrSystemRenderModelPropertiesFB',type='structs',desc='A render model system property',xrefs='']
--
The slink:XrSystemRenderModelPropertiesFB structure is defined as:

include::{generated}/api/structs/XrSystemRenderModelPropertiesFB.adoc[]

It describes a render model system property.

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  No such structures are defined in core OpenXR or this extension.
* pname:supportsRenderModelLoading defines whether the system supports
  loading render models.
****

include::{generated}/validity/structs/XrSystemRenderModelPropertiesFB.adoc[]
--

[open,refpage='XrRenderModelPathInfoFB',type='structs',desc='Supported model paths',xrefs='xrEnumerateRenderModelPathsFB']
--
The slink:XrRenderModelPathInfoFB structure is defined as:

include::{generated}/api/structs/XrRenderModelPathInfoFB.adoc[]

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  No such structures are defined in core OpenXR or this extension.
* pname:path is a valid basetype:XrPath used for retrieving model properties
  from flink:xrGetRenderModelPropertiesFB.
****

slink:XrRenderModelPathInfoFB contains a model path supported by the device
when returned from flink:xrEnumerateRenderModelPathsFB.
This path can be used to request information about the render model for the
connected device that the path represents using
flink:xrGetRenderModelPropertiesFB.

.Possible Render Model Paths
****
* Controller models with origin at the grip pose.
** pathname:/model_fb/controller/left
** pathname:/model_fb/controller/right
* Keyboard models with origin at the center of its bounding box.
** pathname:/model_fb/keyboard/local
** pathname:/model_fb/keyboard/remote
** pathname:/model_meta/keyboard/virtual +
  (if the apiext:XR_META_virtual_keyboard extension is enabled)
****

include::{generated}/validity/structs/XrRenderModelPathInfoFB.adoc[]
--

[open,refpage='XrRenderModelPropertiesFB',type='structs',desc='The information about the render model',xrefs='xrGetRenderModelPropertiesFB']
--


The slink:XrRenderModelPropertiesFB structure is defined as:

include::{generated}/api/structs/XrRenderModelPropertiesFB.adoc[]

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  slink:XrRenderModelCapabilitiesRequestFB is a structure in this structure
  chain and should: be linked when this structure is passed to
  flink:xrGetRenderModelPropertiesFB.
* pname:vendorId is the vendor id of the model.
* pname:modelName is the name of the model.
* pname:modelKey is the unique model key used to load the model in
  flink:xrLoadRenderModelFB.
* pname:modelVersion is the version number of the model.
* pname:flags is a bitmask of elink:XrRenderModelFlagsFB.
  After a successful call to flink:xrGetRenderModelPropertiesFB, flags must
  contain the support level of the model and no other support levels.
****

slink:XrRenderModelPropertiesFB contains information about the render model
for a device.
slink:XrRenderModelPropertiesFB must: be provided when calling
flink:xrGetRenderModelPropertiesFB.
The basetype:XrRenderModelKeyFB included in the properties is a unique key
for each render model that is valid across multiple instances and installs.

If the application decides to cache or save the render model in any way,
pname:modelVersion can be used to determine if the render model has changed.
The application should: then update its cached or saved version.

include::{generated}/validity/structs/XrRenderModelPropertiesFB.adoc[]
--

[open,refpage='XrRenderModelCapabilitiesRequestFB',type='structs',desc='A render model system property',xrefs='']
--
The slink:XrRenderModelCapabilitiesRequestFB structure is defined as:

include::{generated}/api/structs/XrRenderModelCapabilitiesRequestFB.adoc[]

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  No such structures are defined in core OpenXR or this extension.
* pname:flags is a bit mask of the model complexities that the application
  is able to support.
****


slink:XrRenderModelCapabilitiesRequestFB contains information about the
render capabilities requested for a model.
slink:XrRenderModelCapabilitiesRequestFB must: be set in the structure chain
of the pname:next pointer on the slink:XrRenderModelPropertiesFB passed into
the flink:xrGetRenderModelPropertiesFB call.
The pname:flags on slink:XrRenderModelCapabilitiesRequestFB represent an
acknowledgement of being able to handle the individual model capability
levels.
If no slink:XrRenderModelCapabilitiesRequestFB is on the structure chain
then the runtime should: treat it as if a value of
ename:XR_RENDER_MODEL_SUPPORTS_GLTF_2_0_SUBSET_1_BIT_FB was set.
If the runtime does not have a model available that matches any of the
supports flags set, then it must: return a
ename:XR_RENDER_MODEL_UNAVAILABLE_FB result.


include::{generated}/validity/structs/XrRenderModelCapabilitiesRequestFB.adoc[]
--

[open,refpage='XrRenderModelLoadInfoFB',type='structs',desc='The information for which render model to load',xrefs='xrLoadRenderModelFB']
--
The slink:XrRenderModelLoadInfoFB structure is defined as:

include::{generated}/api/structs/XrRenderModelLoadInfoFB.adoc[]

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  No such structures are defined in core OpenXR or this extension.
* pname:modelKey is the unique model key for a connected device.
****


slink:XrRenderModelLoadInfoFB is used to provide information about which
render model to load.
slink:XrRenderModelLoadInfoFB must: be provided when calling
flink:xrLoadRenderModelFB.

include::{generated}/validity/structs/XrRenderModelLoadInfoFB.adoc[]
--

[open,refpage='XrRenderModelBufferFB',type='structs',desc='The buffer containing the data for the render model',xrefs='xrLoadRenderModelFB']
--

The slink:XrRenderModelBufferFB structure is defined as:

include::{generated}/api/structs/XrRenderModelBufferFB.adoc[]

.Member Descriptions
****
* pname:type is the elink:XrStructureType of this structure.
* pname:next is code:NULL or a pointer to the next structure in a structure
  chain.
  No such structures are defined in core OpenXR or this extension.
* pname:bufferCapacityInput is the capacity of the pname:buffer, or `0` to
  retrieve the required capacity.
* pname:bufferCountOutput is the count of code:uint8_t pname:buffer written,
  or the required capacity in the case that pname:bufferCapacityInput is
  insufficient.
* pname:buffer is a pointer to an application-allocated array that will be
  filled with the render model binary data.
* See the <<fundamentals-buffer-size-parameters>> section for a detailed
  description of retrieving the required pname:buffer size.
****

slink:XrRenderModelBufferFB is used when loading the binary data for a
render model.
slink:XrRenderModelBufferFB must: be provided when calling
flink:xrLoadRenderModelFB.

include::{generated}/validity/structs/XrRenderModelBufferFB.adoc[]
--

*New Functions*

[open,refpage='xrEnumerateRenderModelPathsFB',desc='Enumerate supported render model paths',type='protos',xrefs='']
--
The flink:xrEnumerateRenderModelPathsFB function is defined as:

include::{generated}/api/protos/xrEnumerateRenderModelPathsFB.adoc[]

.Parameter Descriptions
****
* pname:session is the specified slink:XrSession.
* pname:pathCapacityInput is the capacity of the pname:paths, or 0 to
  retrieve the required capacity.
* pname:pathCountOutput is a pointer to the count of code:float pname:paths
  written, or a pointer to the required capacity in the case that
  pname:pathCapacityInput is insufficient.
* pname:paths is a pointer to an application-allocated array that will be
  filled with slink:XrRenderModelPathInfoFB values that are supported by the
  runtime, but can: be code:NULL if pname:pathCapacityInput is `0`
* See the <<fundamentals-buffer-size-parameters>> section for a detailed
  description of retrieving the required pname:paths size.
****

The application must: call flink:xrEnumerateRenderModelPathsFB to enumerate
the valid render model paths that are supported by the runtime before
calling flink:xrGetRenderModelPropertiesFB.
The paths returned may: be used later in flink:xrGetRenderModelPropertiesFB.

include::{generated}/validity/protos/xrEnumerateRenderModelPathsFB.adoc[]
--

[open,refpage='xrGetRenderModelPropertiesFB',desc='Get information for a render model',type='protos',xrefs='']
--
The flink:xrGetRenderModelPropertiesFB function is defined as:

include::{generated}/api/protos/xrGetRenderModelPropertiesFB.adoc[]

.Parameter Descriptions
****
* pname:session is the specified slink:XrSession.
* pname:path is the path of the render model to get the properties for.
* pname:properties is a pointer to the slink:XrRenderModelPropertiesFB to
  write the render model information to.
****

flink:xrGetRenderModelPropertiesFB is used for getting information for a
render model using a path retrieved from
flink:xrEnumerateRenderModelPathsFB.
The information returned will be for the connected device that corresponds
to the path given.
For example, using pathname:/model_fb/controller/left will return
information for the left controller that is currently connected and will
change if a different device that also represents a left controller is
connected.

The runtime must: return ename:XR_ERROR_CALL_ORDER_INVALID if
flink:xrGetRenderModelPropertiesFB is called with render model paths before
calling flink:xrEnumerateRenderModelPathsFB.
The runtime must: return ename:XR_ERROR_PATH_INVALID if a path not given by
flink:xrEnumerateRenderModelPathsFB is used.

If flink:xrGetRenderModelPropertiesFB returns a success code of
ename:XR_RENDER_MODEL_UNAVAILABLE_FB and has a
slink:XrRenderModelPropertiesFB::pname:modelKey of
dlink:XR_NULL_RENDER_MODEL_KEY_FB, this indicates that the model for the
device is unavailable.
The application may: keep calling flink:xrGetRenderModelPropertiesFB because
the model may: become available later when a device is connected.

include::{generated}/validity/protos/xrGetRenderModelPropertiesFB.adoc[]
--

[open,refpage='xrLoadRenderModelFB',desc='Load binary data for a render model',type='protos',xrefs='']
--
The flink:xrLoadRenderModelFB function is defined as:

include::{generated}/api/protos/xrLoadRenderModelFB.adoc[]

.Parameter Descriptions
****
* pname:session is the specified slink:XrSession.
* pname:info is a pointer to the slink:XrRenderModelLoadInfoFB structure.
* pname:buffer is a pointer to the slink:XrRenderModelBufferFB structure to
  write the binary data into.
****

flink:xrLoadRenderModelFB is used to load the GLTF model data using a valid
slink:XrRenderModelLoadInfoFB::pname:modelKey.
flink:xrLoadRenderModelFB loads the model as a byte buffer containing the
GLTF in the binary format (GLB).
The GLB data must: conform to the glTF 2.0 format defined at {uri-gltf2}.
The GLB may: contain texture data in a format that requires the use of the
`KHR_texture_basisu` GLTF extension defined at {uri-gltf2-basisu}.
Therefore, the application should: ensure it can handle this extension.

If the device for the requested model is disconnected or does not match the
slink:XrRenderModelLoadInfoFB::pname:modelKey provided,
flink:xrLoadRenderModelFB must: return ename:XR_RENDER_MODEL_UNAVAILABLE_FB
as well as an slink:XrRenderModelBufferFB::pname:bufferCountOutput value of
0 indicating that the model was not available.

The flink:xrLoadRenderModelFB function may: be slow, therefore applications
should: call it from a non-time sensitive thread.

include::{generated}/validity/protos/xrLoadRenderModelFB.adoc[]
--

*Issues*

*Version History*

* Revision 1, 2021-08-17 (Leonard Tsai)
** Initial extension description
* Revision 2, 2022-05-03 (Robert Memmott)
** Render Model Support Subsets
* Revision 3, 2022-07-07 (Rylie Pavlik, Collabora, Ltd.)
** Fix implicit valid usage for `XrRenderModelCapabilitiesRequestFB`
* Revision 4, 2023-04-14 (Peter Chan)
** Add possible render model path for apiext:XR_META_virtual_keyboard
