XR_EXT_spatial_anchor
سلسلة الاسم
XR_EXT_spatial_anchor
نوع الإضافة
إضافة مثيل
رقم الإضافة المسجَّل
763
المراجعة
1
حالة التصديق
تم التصديق عليه
الاعتماديات على الإضافات والإصدارات
XR_EXT_spatial_entity
المساهمون
نيهات جين، Google
ناتالي فلوري، Meta
يويتشي تاغوتشي، Meta
رون بيسيمز، Meta
يين لي، Microsoft
جيمي ألامبارامبيل، ByteDance
تشيبينغ ليو، ByteDance
جون يان، ByteDance
نظرة عامة
تستند هذه الإضافة إلى XR_EXT_spatial_entity وتسمح للتطبيقات بإنشاء نقاط ارتساء مكانية، وهي نقاط عشوائية في البيئة المادية للمستخدم سيتم تتبُّعها بعد ذلك بواسطة وقت التشغيل. يجب أن يعدّل وقت التشغيل بعد ذلك موضع نقطة الأصل لمرساة واتجاهها بمرور الوقت حسب الحاجة، بشكل مستقل عن جميع المساحات والمراسي الأخرى، لضمان الحفاظ على الربط الأصلي بالعالم الحقيقي.
يتم تمثيل نقطة ارتساء تتتبّع موضعًا واتجاهًا محدّدَين ضمن XrSpatialContextEXT ككيان مكاني يتضمّن المكوّن XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT (أو "يحتوي على").
ميزة استخدام المراسي
مع تعديل فهم وقت التشغيل للبيئة المادية للمستخدم طوال مدة XrSpatialContextEXT، قد تنحرف الكائنات الافتراضية عن المكان الذي وضعتها فيه التطبيقات، ما يؤثر في واقعية التطبيق وجودة تجربة المستخدم. من خلال إنشاء نقطة ارتساء قريبة من المكان الذي يتم فيه وضع عنصر افتراضي، ثم عرض هذا العنصر الافتراضي دائمًا بالنسبة إلى نقطة الارتساء، يمكن لأحد التطبيقات التأكّد من أنّ كل عنصر افتراضي يظهر ثابتًا في الموضع والاتجاه نفسيهما في البيئة المحيطة. بالإضافة إلى ذلك، وعلى عكس بعض المساحات المرجعية، لا تتأثر نقاط الارتكاز بإعادة التوسيط على مستوى النظام.
دعم وقت التشغيل
إذا كان وقت التشغيل يتيح استخدام المرساة المكانية، يجب الإشارة إلى ذلك من خلال تعداد XR_SPATIAL_CAPABILITY_ANCHOR_EXT في xrEnumerateSpatialCapabilitiesEXT .
الإعداد
يتم تعريف بنية XrSpatialCapabilityConfigurationAnchorEXT على النحو التالي:
typedef struct XrSpatialCapabilityConfigurationAnchorEXT {
XrStructureType type;
const void* next;
XrSpatialCapabilityEXT capability;
uint32_t enabledComponentCount;
const XrSpatialComponentTypeEXT* enabledComponents;
} XrSpatialCapabilityConfigurationAnchorEXT;
أوصاف الأعضاء
typeهو XrStructureType لهذه البنية.nextهيNULLأو مؤشر إلى البنية التالية في سلسلة البنية.-
capabilityهو XrSpatialCapabilityEXT . -
enabledComponentCountهوuint32_tيصف عدد العناصر في مصفوفةenabledComponents. -
enabledComponentsهو مؤشر إلى مصفوفة من XrSpatialComponentTypeEXT .
يمكن للتطبيقات تفعيل إمكانية XR_SPATIAL_CAPABILITY_ANCHOR_EXT المكانية من خلال تضمين مؤشر إلى بنية XrSpatialCapabilityConfigurationAnchorEXT في XrSpatialContextCreateInfoEXT :: capabilityConfigs .
يجب أن تعرض قيمة وقت التشغيل XR_ERROR_VALIDATION_FAILURE إذا لم تكن قيمة capability هي XR_SPATIAL_CAPABILITY_ANCHOR_EXT .
الاستخدام الصحيح (الضمني)
- يجب تفعيل الإضافة
XR_EXT_spatial_anchorقبل استخدام XrSpatialCapabilityConfigurationAnchorEXT - يجب أن يكون
typeXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT - يجب أن تكون قيمة
nextهيNULLأو مؤشرًا صالحًا إلى البنية التالية في سلسلة البِنى - يجب أن تكون قيمة
capabilityصالحة XrSpatialCapabilityEXT - يجب أن يكون
enabledComponentsمؤشرًا إلى مصفوفة من قيم XrSpatialComponentTypeEXT صالحةenabledComponentCount - يجب أن تكون قيمة المَعلمة
enabledComponentCountأكبر من0
المكوّنات المضمونة
يجب أن يوفّر وقت التشغيل الذي يتيح استخدام XR_SPATIAL_CAPABILITY_ANCHOR_EXT المكوّنات المكانية التالية كمكوّنات مضمونة لجميع الكيانات التي يتم إنشاؤها أو اكتشافها من خلال هذه الإمكانية، ويجب أن يسردها في xrEnumerateSpatialCapabilityComponentTypesEXT :
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
مكوّن Anchor
بيانات المكوّن
يستخدم XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT XrPosef لبياناته التي توفّر موضع المرساة واتجاهها.
بنية قائمة المكوّنات للاستعلام عن البيانات
يتم تعريف بنية XrSpatialComponentAnchorListEXT على النحو التالي:
typedef struct XrSpatialComponentAnchorListEXT {
XrStructureType type;
void* next;
uint32_t locationCount;
XrPosef* locations;
} XrSpatialComponentAnchorListEXT;
أوصاف الأعضاء
typeهو XrStructureType لهذه البنية.nextهيNULLأو مؤشر إلى البنية التالية في سلسلة البنية.-
locationCountهوuint32_tيصف عدد العناصر في مصفوفةlocations. -
locationsهي مصفوفة من XrPosef .
يجب أن تعرض بيئة التشغيل القيمة XR_ERROR_VALIDATION_FAILURE من xrQuerySpatialComponentDataEXT إذا كان XrSpatialComponentAnchorListEXT في السلسلة XrSpatialComponentDataQueryResultEXT :: next ولكن لم يتم تضمين XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT في XrSpatialComponentDataQueryConditionEXT :: componentTypes .
يجب أن تعرض بيئة التشغيل القيمة XR_ERROR_SIZE_INSUFFICIENT من xrQuerySpatialComponentDataEXT إذا كانت قيمة locationCount أقل من XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .
الاستخدام الصحيح (الضمني)
- يجب تفعيل إضافة
XR_EXT_spatial_anchorقبل استخدام XrSpatialComponentAnchorListEXT - يجب أن يكون
typeXR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT - يجب أن تكون قيمة
nextهيNULLأو مؤشرًا صالحًا إلى البنية التالية في سلسلة البِنى - يجب أن يكون
locationsمؤشرًا إلى مصفوفة من بنىlocationCountXrPosef - يجب أن تكون قيمة المَعلمة
locationCountأكبر من0
الإعداد
إذا تم تعداد XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT في XrSpatialCapabilityComponentTypesEXT :: componentTypes لبعض الإمكانات، يمكن لأحد التطبيقات تفعيلها من خلال تضمين القيمة المُعدَّدة في قائمة XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents الخاصة ببنية XrSpatialCapabilityConfigurationBaseHeaderEXT المشتقة من الإمكانية التي تتوافق مع هذا المكوّن.
لا يتطلّب هذا المكوّن أي إعدادات خاصة ليتم تضمينه في سلسلة XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.
إنشاء نقطة تثبيت مكانية
يتم تعريف الدالة xrCreateSpatialAnchorEXT على النحو التالي:
XrResult xrCreateSpatialAnchorEXT(
XrSpatialContextEXT spatialContext,
const XrSpatialAnchorCreateInfoEXT* createInfo,
XrSpatialEntityIdEXT* anchorEntityId,
XrSpatialEntityEXT* anchorEntity);
أوصاف المَعلمات
-
spatialContextهو XrSpatialContextEXT تم إنشاؤه سابقًا باستخدام xrCreateSpatialContextAsyncEXT . -
createInfoهو مؤشر إلى XrSpatialAnchorCreateInfoEXT . -
anchorEntityIdهو مؤشر إلىXrSpatialEntityIdEXTيتم فيه عرض رقم تعريف عنصر الربط. -
anchorEntityهو مؤشر إلى XrSpatialEntityEXT يتم فيه عرض معرّف عنصر الربط.
يمكن للتطبيق إنشاء نقطة تثبيت مكانية باستخدام xrCreateSpatialAnchorEXT .
للحصول على بيانات محدَّثة للمكوّن الخاص بعنصر ارتساء، مرِّر القيمة التي تمّت تعبئتها في anchorEntity إلى XrSpatialUpdateSnapshotCreateInfoEXT :: entities عند إنشاء لقطة. يمكن للتطبيق استخدام anchorEntityId لتحديد هذا العنصر الثابت بشكل فريد في مصفوفة XrSpatialComponentDataQueryResultEXT :: entityIds عند استخدام xrQuerySpatialComponentDataEXT .
يجب أن تعرض بيئة التشغيل القيمة XR_ERROR_VALIDATION_FAILURE من xrCreateSpatialAnchorEXT إذا لم يتم ضبط XR_SPATIAL_CAPABILITY_ANCHOR_EXT على spatialContext . راجِع الإعداد لمعرفة كيفية إعداد XrSpatialContextEXT لإمكانية XR_SPATIAL_CAPABILITY_ANCHOR_EXT.
لا يكون العنصر الثابت الذي يمثّله anchorEntity صالحًا إلا طوال مدة spatialContext أو إلى أن يستدعي التطبيق xrDestroySpatialEntityEXT عليه، أيهما أقرب. قد توفّر الإضافات الأخرى وظائف للاحتفاظ بهذا العنصر الثابت الذي تم إنشاؤه حديثًا في عدة XrSession أو لمشاركته عبر حدود العمليات مع تطبيقات أخرى.
يجب أن يكون المرساة التي تم إنشاؤها حديثًا قابلة للاكتشاف في سياقها المكاني الرئيسي إلى أن يتم إتلافها. يعني ذلك أنّه يجب أن يتضمّن وقت التشغيل anchorEntityId في اللقطة التي تم إنشاؤها باستخدام xrCreateSpatialDiscoverySnapshotAsyncEXT لـ spatialContext إذا كان عنصر التثبيت يطابق معايير البحث المحدّدة في XrSpatialDiscoverySnapshotCreateInfoEXT . قد يكون العنصر الثابت الذي تم إنشاؤه حديثًا قابلاً للاكتشاف أيضًا في سياقات مكانية أخرى تم ضبطها باستخدام XR_SPATIAL_CAPABILITY_ANCHOR_EXT، ولكن مع XrSpatialEntityIdEXT مختلف لأنّ كل XrSpatialEntityIdEXT فريد بالنسبة إلى XrSpatialContextEXT .
الاستخدام الصحيح (الضمني)
- يجب تفعيل الإضافة
XR_EXT_spatial_anchorقبل استدعاء xrCreateSpatialAnchorEXT - يجب أن يكون
spatialContextmust معرّفًا صالحًا XrSpatialContextEXT - يجب أن يكون
createInfoمؤشرًا إلى بنية XrSpatialAnchorCreateInfoEXT صالحة - يجب أن يكون
anchorEntityIdمؤشرًا إلى قيمةXrSpatialEntityIdEXT - يجب أن يكون
anchorEntityمؤشرًا إلى معرّف XrSpatialEntityEXT
رموز الإرجاع
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_LIMIT_REACHEDXR_ERROR_OUT_OF_MEMORYXR_ERROR_POSE_INVALIDXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_TIME_INVALIDXR_ERROR_VALIDATION_FAILUREXR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID(في حال تفعيلXR_ANDROID_spatial_entity_bound_anchor)XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT(في حال تفعيلXR_ANDROID_spatial_entity_bound_anchor)
يتم تعريف بنية XrSpatialAnchorCreateInfoEXT على النحو التالي:
typedef struct XrSpatialAnchorCreateInfoEXT {
XrStructureType type;
const void* next;
XrSpace baseSpace;
XrTime time;
XrPosef pose;
} XrSpatialAnchorCreateInfoEXT;
أوصاف الأعضاء
typeهو XrStructureType لهذه البنية.nextهيNULLأو مؤشر إلى البنية التالية في سلسلة البنية.baseSpaceهي XrSpace التي يتم فيها تطبيقpose.timeهوXrTimeالذي يقع فيهbaseSpace(ويتم تطبيقpose).-
poseهو الموقع الجغرافي لعنصر التثبيت.
الاستخدام الصحيح (الضمني)
- يجب تفعيل الإضافة
XR_EXT_spatial_anchorقبل استخدام XrSpatialAnchorCreateInfoEXT - يجب أن يكون
typeXR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT - يجب أن تكون قيمة
nextهيNULLأو مؤشرًا صالحًا إلى البنية التالية في سلسلة البِنى. راجِع أيضًا: XrSpatialAnchorParentANDROID - يجب أن يكون
baseSpaceمقابض XrSpace صالحًا
Query Anchor Pose
بعد إنشاء نقطة الربط، يجب أن يضبط وقت التشغيل موضعها واتجاهها بمرور الوقت بالنسبة إلى المساحات الأخرى للحفاظ على أفضل محاذاة ممكنة لموقعها الأصلي في العالم الحقيقي، حتى إذا غيّر ذلك علاقة نقطة الربط بـ XrSpatialAnchorCreateInfoEXT :: baseSpace الأصلي المستخدَم لتهيئة نقطة الربط.
يمكن للتطبيق استخدام xrCreateSpatialUpdateSnapshotEXT مع XrSpatialEntityEXT الخاص بعنصر التثبيت لإنشاء XrSpatialSnapshotEXT جديد، ثم طلب البحث عن مكوّن XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT من تلك اللقطة باستخدام xrQuerySpatialComponentDataEXT . يمكن للتطبيق إضافة XrSpatialComponentAnchorListEXT إلى XrSpatialComponentDataQueryResultEXT :: next لاسترداد أحدث بيانات الموقع الجغرافي لعناصر الربط.
قد تضبط بيئة التشغيل حالة التتبُّع لمرتكز تم إنشاؤه حديثًا على XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT . يجب أن يقرأ التطبيق فقط حالة كيان الربط المقدَّمة في XrSpatialComponentDataQueryResultEXT :: entityStates وبيانات مكوِّن الربط الخاص بالكيان إذا كانت حالة التتبُّع هي XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT .
إرشادات استخدام المراسي
- يتم تعديل وضع كل نقطة ارتساء بشكل مستقل عن أي نقطة ارتساء أو مساحة أخرى. قد تتحرّك الكائنات الافتراضية المثبّتة بشكل منفصل أو تدور بالنسبة إلى بعضها البعض، ما يؤدي إلى كسر التسلسل الهرمي المكاني في الحالات التي يُتوقّع فيها أن تبقى هذه الكائنات الافتراضية ثابتة بالنسبة إلى بعضها البعض. في مثل هذه الحالات، يجب أن يعيد التطبيق استخدام نقطة الارتكاز نفسها لجميع الكائنات الافتراضية التي لا تتحرّك بالنسبة إلى بعضها البعض.
- يجب أن يتلف التطبيق أي مقابض XrSpatialEntityEXT للمرساة التي لم يعُد يتم استخدامها من أجل إتاحة الموارد التي قد يستخدمها وقت التشغيل لتتبُّع هذه المرساة.
مثال على الشفرة
ضبط إمكانية Anchor
يوضّح المثال التالي كيفية ضبط إمكانية الربط عند إنشاء سياق مكاني.
// Create a spatial spatial context
XrSpatialContextEXT spatialContext{};
{
std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT,
};
XrSpatialCapabilityConfigurationAnchorEXT anchorConfig{XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT};
anchorConfig.capability = XR_SPATIAL_CAPABILITY_ANCHOR_EXT;
anchorConfig.enabledComponentCount = enabledComponents.size();
anchorConfig.enabledComponents = enabledComponents.data();
std::array<XrSpatialCapabilityConfigurationBaseHeaderEXT*, 1> capabilityConfigs = {
reinterpret_cast<XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&anchorConfig),
};
XrSpatialContextCreateInfoEXT spatialContextCreateInfo{XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT};
spatialContextCreateInfo.capabilityConfigCount = capabilityConfigs.size();
spatialContextCreateInfo.capabilityConfigs = capabilityConfigs.data();
XrFutureEXT createContextFuture;
CHK_XR(xrCreateSpatialContextAsyncEXT(session, &spatialContextCreateInfo, &createContextFuture));
waitUntilReady(createContextFuture);
XrCreateSpatialContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT};
CHK_XR(xrCreateSpatialContextCompleteEXT(session, createContextFuture, &completion));
if (completion.futureResult != XR_SUCCESS) {
return;
}
spatialContext = completion.spatialContext;
}
// ...
// Create spatial anchors and get their latest pose in the frame loop.
// ...
CHK_XR(xrDestroySpatialContextEXT(spatialContext));
إنشاء نقطة تثبيت مكانية والحصول على موقعها الجغرافي
يوضّح المثال التالي كيفية إنشاء مرساة مكانية والحصول على وضعها في كل إطار.
XrSpatialAnchorCreateInfoEXT createInfo{XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT};
createInfo.baseSpace = localSpace;
createInfo.time = predictedDisplayTime;
createInfo.pose = {{0, 0, 0, 1}, {1, 1, 1}};
XrSpatialEntityIdEXT spatialAnchorEntityId;
XrSpatialEntityEXT spatialAnchorEntity;
CHK_XR(xrCreateSpatialAnchorEXT(spatialContext, &createInfo, &spatialAnchorEntityId, &spatialAnchorEntity));
auto updateAnchorLocation = [&](XrTime time) {
// We want to get updated data for all components of the entities, so skip specifying componentTypes.
XrSpatialUpdateSnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT};
snapshotCreateInfo.entityCount = 1;
snapshotCreateInfo.entities = &spatialAnchorEntity;
snapshotCreateInfo.baseSpace = localSpace;
snapshotCreateInfo.time = time;
XrSpatialSnapshotEXT snapshot;
CHK_XR(xrCreateSpatialUpdateSnapshotEXT(spatialContext, &snapshotCreateInfo, &snapshot));
// Query for the entities that have the anchor component on them.
std::array<XrSpatialComponentTypeEXT, 1> componentsToQuery {XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT};
XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
queryCond.componentTypeCount = componentsToQuery.size();
queryCond.componentTypes = componentsToQuery.data();
XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
CHK_XR(xrQuerySpatialComponentDataEXT(snapshot, &queryCond, &queryResult));
std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
queryResult.entityIdCapacityInput = entityIds.size();
queryResult.entityIds = entityIds.data();
queryResult.entityStateCapacityInput = entityStates.size();
queryResult.entityStates = entityStates.data();
// query for the pose data
std::vector<XrPosef> locations(queryResult.entityIdCountOutput);
XrSpatialComponentAnchorListEXT locationList{XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT};
locationList.locationCount = locations.size();
locationList.locations = locations.data();
queryResult.next = &locationList;
CHK_XR(xrQuerySpatialComponentDataEXT(snapshot, &queryCond, &queryResult));
for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
if (entityStates[i] == XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT) {
// Pose for entity entityIds[i] is locations[i].
}
}
CHK_XR(xrDestroySpatialSnapshotEXT(snapshot));
};
while (1) {
// ...
// For every frame in frame loop
// ...
XrFrameState frameState; // previously returned from xrWaitFrame
const XrTime time = frameState.predictedDisplayTime;
updateAnchorLocation(time);
// ...
// Finish frame loop
// ...
}
CHK_XR(xrDestroySpatialEntityEXT(spatialAnchorEntity));
الأوامر الجديدة
بنى جديدة
ثوابت التعداد الجديدة
XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAMEXR_EXT_spatial_anchor_SPEC_VERSIONتمديد XrSpatialCapabilityEXT :
XR_SPATIAL_CAPABILITY_ANCHOR_EXT
تمديد XrSpatialComponentTypeEXT :
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
تمديد XrStructureType :
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXTXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXTXR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT
المشاكل
لماذا يعرض xrCreateSpatialAnchorEXT رقم تعريف كيان بالإضافة إلى معرّف كيان؟
- تم الحلّ
- الإجابة: كان من الممكن أن توفّر الدالة xrCreateSpatialAnchorEXT معرّف الكيان فقط كناتج، ويمكن للتطبيقات إنشاء معرّف كيان لهذا المعرّف باستخدام xrCreateSpatialEntityFromIdEXT . ومع ذلك، نظرًا للاستخدام النموذجي لنقطة الارتكاز حيث تستعلم التطبيقات عن وضع نقطة الارتكاز في كل إطار، تصبح نقطة الارتكاز خيارًا جيدًا لاستخدامها في "تعديل اللقطة"، الأمر الذي يتطلّب معرّفات الكيانات كمدخلات. تتوقّع الدالة xrCreateSpatialAnchorEXT حالة الاستخدام النموذجية هذه، لذا تنفّذ الدالة xrCreateSpatialEntityFromIdEXT نيابةً عن التطبيق وتزوّده بمقبض الكيان لاستخدامه مع الدالة xrCreateSpatialUpdateSnapshotEXT .
سجلّ الإصدارات
الإصدار 1، 10/07/2024 (نيهيف جاين، Google)
- الوصف الأوّلي للإضافة