XR_EXT_spatial_anchor
Name String
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يجب أن يكون مؤشرًا إلى مصفوفة من قيمenabledComponentCountصالحة من النوع XrSpatialComponentTypeEXT - يجب أن تكون المَعلمة
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 - يجب أن يكون
spatialContextمؤشرًا صالحًا لـ 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_FAILURE-
XR_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
طلب البحث عن وضعية الارتساء
بعد إنشاء نقطة الارتكاز، يجب أن يعدّل وقت التشغيل موضعها واتجاهها بمرور الوقت بالنسبة إلى المساحات الأخرى من أجل الحفاظ على أفضل محاذاة ممكنة لموقعها الأصلي في العالم الحقيقي، حتى إذا غيّر ذلك علاقة نقطة الارتكاز بالبنية الأصلية 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 للمثبّتات التي لم تعُد قيد الاستخدام من أجل إخلاء الموارد التي قد يستخدمها وقت التشغيل لتتبُّع هذه المثبّتات.
مثال على الشفرة
ضبط إمكانية الربط
يوضّح المثال التالي كيفية ضبط ميزة الارتساء عند إنشاء سياق مكاني.
// 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)
- الوصف الأولي للإضافة