XR_EXT_spatial_anchor
رشته نام
XR_EXT_spatial_anchor
نوع افزونه
افزونه نمونه
شماره داخلی ثبتشده
763
بازبینی
1
وضعیت تصویب
تصویبشده
وابستگیهای افزونه و نسخه
XR_EXT_spatial_entity
همیاران
Nihav Jain، Google
Natalie Fleury، Meta
Yuichi Taguchi، Meta
Ron Bessems، Meta
Yin Li، Microsoft
Jimmy Alamparambil، ByteDance
Zhipeng Liu، ByteDance
Jun Yan، 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;
توضیحات عضو
typeXrStructureType این ساختار است.-
nextبرابر باNULLیا اشارهگری به ساختار بعدی در زنجیره ساختار است. capabilityیک XrSpatialCapabilityEXT است .enabledComponentCountیکuint32_tاست که تعداد عناصر را در آرایهenabledComponentsتوصیف میکند.-
enabledComponentsاشارهگری به آرایهای از XrSpatialComponentTypeEXT است.
برنامهها میتوانند با گنجاندن اشارهگری به ساختار XrSpatialCapabilityConfigurationAnchorEXT در XrSpatialContextCreateInfoEXT :: capabilityConfigs ، قابلیت فضایی XR_SPATIAL_CAPABILITY_ANCHOR_EXT را فعال کنند.
اگر capability XR_SPATIAL_CAPABILITY_ANCHOR_EXT نباشد، زمان اجرا باید XR_ERROR_VALIDATION_FAILURE را برگرداند.
استفاده معتبر (ضمنی)
- افزونه
XR_EXT_spatial_anchorباید قبلاز استفاده از XrSpatialCapabilityConfigurationAnchorEXT فعال شود -
typeبایدXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXTباشد -
nextبایدNULLیا اشارهگر معتبری به ساختار بعدی در زنجیره ساختار باشد -
capabilityباید مقدار XrSpatialCapabilityEXT معتبری باشد -
enabledComponentsباید اشارهگری به آرایهای از مقادیر معتبرenabledComponentCountXrSpatialComponentTypeEXT باشد - پارامتر
enabledComponentCountباید بزرگتر از0باشد
قطعات تضمینشده
زمان اجرایی که از XR_SPATIAL_CAPABILITY_ANCHOR_EXT پشتیبانی میکند باید مؤلفههای فضایی زیر را بهعنوان مؤلفههای تضمینشده همه موجودیتهای ایجادشده یا کشفشده توسط این قابلیت ارائه دهد و باید آنها را در xrEnumerateSpatialCapabilityComponentTypesEXT فهرست کند:
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
مؤلفه لنگر
دادههای مؤلفه
XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT از XrPosef برای دادههایش استفاده میکند که موقعیت و جهت لنگر را ارائه میدهد.
ساختار فهرست مؤلفه برای پُرسمان دادهها
ساختار XrSpatialComponentAnchorListEXT بهصورت زیر تعریف میشود:
typedef struct XrSpatialComponentAnchorListEXT {
XrStructureType type;
void* next;
uint32_t locationCount;
XrPosef* locations;
} XrSpatialComponentAnchorListEXT;
توضیحات عضو
typeXrStructureType این ساختار است.-
nextبرابر باNULLیا اشارهگری به ساختار بعدی در زنجیره ساختار است. locationCountیکuint32_tاست که تعداد عناصر را در آرایهlocationsتوصیف میکند.-
locationsآرایهای از XrPosef است.
اگر XrSpatialComponentAnchorListEXT در زنجیره XrSpatialComponentDataQueryResultEXT :: next باشد اما XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT در XrSpatialComponentDataQueryConditionEXT :: componentTypes گنجانده نشده باشد، زمان اجرا باید XR_ERROR_VALIDATION_FAILURE را از xrQuerySpatialComponentDataEXT برگرداند.
اگر locationCount کمتر از XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput باشد، زمان اجرا باید XR_ERROR_SIZE_INSUFFICIENT را از xrQuerySpatialComponentDataEXT برگرداند.
استفاده معتبر (ضمنی)
- افزونه
XR_EXT_spatial_anchorباید پیشاز استفاده از XrSpatialComponentAnchorListEXT فعال شود -
typeبایدXR_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_SPATIAL_CAPABILITY_ANCHOR_EXT برای spatialContext پیکربندی نشده باشد، زمان اجرا باید XR_ERROR_VALIDATION_FAILURE را از xrCreateSpatialAnchorEXT برگرداند. برای نحوه پیکربندی 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;
توضیحات عضو
typeXrStructureType این ساختار است.-
nextبرابر باNULLیا اشارهگری به ساختار بعدی در زنجیره ساختار است. baseSpaceXrSpace است کهposeدر آن اعمال میشود.timeXrTimeاست کهbaseSpaceدر آن قرار دارد (وposeاعمال میشود).poseمکان نهاد لنگر است.
استفاده معتبر (ضمنی)
- افزونه
XR_EXT_spatial_anchorباید قبلاز استفاده از XrSpatialAnchorCreateInfoEXT فعال شود -
typeبایدXR_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));
فرمانهای جدید
سازههای جدید
- XrSpatialAnchorCreateInfoEXT
- XrSpatialCapabilityConfigurationAnchorEXT
درحال گسترش دادن XrSpatialComponentDataQueryResultEXT :
ثابتهای شمارشی جدید
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 دراختیار آن قرار میدهد.
سابقه نسخه
بازبینی ۱، ۲۰۲۴/۰۷/۱۰ (نیهاو جین، Google)
- شرح اولیه افزونه