תוסף OpenXR‏ XR_ANDROID_hand_mesh

מחרוזת שם

XR_ANDROID_hand_mesh

סוג התוסף

תוסף למכונה

מספר תוסף רשום

704

גרסה

1

תלות בתוספים ובגרסאות

OpenXR 1.0

תאריך השינוי האחרון

2024-09-10

סטטוס כתובת ה-IP

לא ידוע על תלונות על הפרת זכויות יוצרים בנושא כתובת IP.

שותפים ביצירת התוכן

Nihav Jain, ‏ Google

קארן אוברטורף (Cairn Overturf), Google

ספנסר קווין (Spencer Quin), Google

לבנה צ'ן, Google

סקירה כללית

התוסף הזה מאפשר מעקב אחר תנועות הידיים שמוצגות כרשת דינמית של היד.

התוסף הזה מיועד לספק מאגרי קודקודים ומאגרי אינדקסים למערך של ייצוג מותאם אישית של הידיים של המשתמש. אפשר להשתמש בו כדי להציג חסימה ותצוגה חזותית.

אסור להשתמש בתוסף הזה למטרות אחרות של מעקב אחר תנועות ידיים.

נתוני מעקב אחר תנועות ידיים יכולים להיות מידע אישי רגיש, והם קשורים באופן הדוק לפרטיות ולשלמות האישית. מומלץ מאוד שאפליקציות ששומרות או מעבירות נתוני מעקב אחר תנועות ידיים תמיד יבקשו מהמשתמשים אישור פעיל וספציפי לכך.

בדיקת יכולות המערכת

כדי לבדוק אם המערכת מסוגלת לעקוב אחרי רשתות של מעקב אחר תנועות ידיים, אפליקציה יכולה לצרף מבנה XrSystemHandMeshTrackingPropertiesANDROID ל-XrSystemProperties בזמן הקריאה ל-xrGetSystemProperties.

typedef struct XrSystemHandMeshTrackingPropertiesANDROID {
  XrStructureType    type;
  void*              next;
  XrBool32           supportsHandMeshTracking;
  XrBool32           supportsTextureUV;
  XrBool32           supportsVertexNormal;
} XrSystemHandMeshTrackingPropertiesANDROID;

תיאורי חברים

  • type הוא XrStructureType של המבנה הזה.
  • next הוא NULL או הפניה למבנה הבא בשרשרת המבנים. לא מוגדרים מבנים כאלה ב-OpenXR או בהרחבה הזו.
  • supportsHandMeshTracking הוא XrBool32, שמציין אם XrSystemId שנבחר תומך במעקב אחר רשת של יד.
  • supportsTextureUV הוא XrBool32, שמציין אם XrSystemId שנבחר תומך ב-UV של טקסטורה עבור קודקודי המאגר.
  • supportsVertexNormal הוא XrBool32, שמציין אם XrSystemId שנבחר תומך ברגלי קודקודים של קודקודי המאגר.

צריך להימנע משימוש ביכולות של רשת יד כשהערך של supportsHandMeshTracking הוא XR_FALSE, כי המשמעות היא שהמערכת לא תומכת במעקב אחר רשת יד. במקרה כזה, הפונקציה xrCreateHandMeshTrackerANDROID תחזיר את הערך XR_ERROR_FEATURE_UNSUPPORTED.

אם הפונקציה supportsHandMeshTracking מחזירה את הערך XR_TRUE, המערכת תומכת במעקב אחר רשת של יד. אפליקציה צריכה להשתמש ב-XrHandMeshANDROID::indexCount וב-XrHandMeshANDROID::vertexCount כדי לגשת למאגרי הרשת של היד ולעשות בהם שימוש חוזר בלולאת הרינדור שלה כשקוראים ל-xrGetHandMeshANDROID בכל פריים.

אם הפונקציה supportsTextureUV מחזירה את הערך XR_FALSE, המערכת לא תומכת ב-UV של טקסטורה עבור קודקודי המאגר, ולכן האפליקציה תקבל את הערך XrHandMeshANDROID::textureUVs NULL בקריאה ל-xrGetHandMeshANDROID.

אם הפונקציה supportsVertexNormal מחזירה את הערך XR_FALSE, המערכת לא תומכת ברגלי קודקודים של קודקודי המאגר, ולכן האפליקציה תקבל את הערך XrHandMeshANDROID::normals NULL בקריאה ל-xrGetHandMeshANDROID.

שימוש תקין (מרומז)

יצירת כינוי למעקב אחר תנועות היד

XR_DEFINE_HANDLE(XrHandMeshTrackerANDROID)

הידית XrHandMeshTrackerANDROID מייצגת מכשיר מעקב אחר רשתות של יד (hand mesh) למעקב אחר רשתות של יד ולניהול המשאבים הקשורים.

אפשר להשתמש בכינוי הזה כדי לגשת למאגרי ה-mesh של היד באמצעות פונקציות אחרות בתוסף הזה.

אפליקציה יכולה ליצור מנוף מסוג XrHandMeshTrackerANDROID באמצעות הפונקציה xrCreateHandMeshTrackerANDROID.

XrResult xrCreateHandMeshTrackerANDROID(
    XrSession                                   session,
    const XrHandMeshTrackerCreateInfoANDROID*   createInfo,
    XrHandMeshTrackerANDROID*                   handMeshTracker);

תיאורי פרמטרים

אם המערכת לא תומכת במעקב אחר רשת של כף יד, הפונקציה xrCreateHandMeshTrackerANDROID תחזיר את הערך XR_ERROR_FEATURE_UNSUPPORTED.

הידית XrHandMeshTrackerANDROID היא הבעלים של כל המשאבים למעקב אחר רשתות של כף היד. אחרי שמסיימים את חוויות המעקב אחר רשתות של כפות ידיים, האפליקציה חייבת למחוק את הידית באמצעות הפונקציה xrDestroyHandMeshTrackerANDROID.

שימוש תקין (מרומז)

קודי החזרה

הצלחה

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

כישלון

  • XR_ERROR_FEATURE_UNSUPPORTED
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_LIMIT_REACHED

המבנה XrHandMeshTrackerCreateInfoANDROID מתאר את המידע שנחוץ כדי ליצור את הידית XrHandMeshTrackerANDROID.

typedef struct XrHandMeshTrackerCreateInfoANDROID {
    XrStructureType    type;
    const void*        next;
} XrHandMeshTrackerCreateInfoANDROID;

תיאורי חברים

  • type הוא XrStructureType של המבנה הזה.
  • next הוא NULL או הפניה למבנה הבא בשרשרת המבנים. לא מוגדרים מבנים כאלה ב-OpenXR או בהרחבה הזו.

שימוש תקין (מרומז)

הפונקציה xrDestroyHandMeshTrackerANDROID משחררת את handMeshTracker ואת המשאבים הבסיסיים כשמסיימים את חוויית המעקב אחר רשתות של כפות הידיים.

XrResult xrDestroyHandMeshTrackerANDROID(
    XrHandMeshTrackerANDROID handMeshTracker);

תיאורי פרמטרים

שימוש תקין (מרומז)

בטיחות בשרשור

  • חובה לסנכרן באופן חיצוני את הגישה ל-handMeshTracker ולכל כינויים משניים

קודי החזרה

הצלחה

  • XR_SUCCESS

כישלון

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID

איתור רשתות של ידיים

האפליקציה יכולה להשתמש בפונקציה xrGetHandMeshANDROID כדי לאחזר את רשת היד בחותמת זמן נתונה. המיקום והנורמלי של הקודקודים של רשת היד מיוצגים במרחב שצוין על ידי XrHandMeshGetInfoANDROID::baseSpace בזמן הקריאה ל-xrGetHandMeshANDROID.

XrResult xrGetHandMeshANDROID(
    XrHandMeshTrackerANDROID                    handMeshTracker,
    const XrHandMeshGetInfoANDROID*             getInfo,
    XrHandTrackingMeshesANDROID*                handMeshes);

תיאורי פרמטרים

האפליקציה יכולה להשתמש בפונקציה xrGetHandMeshANDROID כדי לגשת למאגרי המידע של רשתות היד שנוצרו בסביבת זמן הריצה.

היישום צריך לבצע קריאה ל-xrBeginFrame לפחות פעם אחת במהלך הסשן, לפני הקריאה הראשונה ל-xrGetHandMeshANDROID.

אפליקציה צריכה להשתמש ב-XrHandMeshANDROID::indexCount וב-XrHandMeshANDROID::vertexCount כדי לגשת למאגרי הרשת של היד ולהשתמש בהם שוב בלולאת הרינדור שלה כשקוראים ל-xrGetHandMeshANDROID בכל פריים.

שימוש תקין (מרומז)

קודי החזרה

הצלחה

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

כישלון

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_SIZE_INSUFFICIENT
  • XR_ERROR_TIME_INVALID

ב-XrHandMeshGetInfoANDROID מתואר המידע הנדרש כדי לקבל נתוני רשת של היד.

typedef struct XrHandMeshGetInfoANDROID {
    XrStructureType    type;
    const void*        next;
    XrSpace            baseSpace;
    XrTime             time;
} XrHandMeshGetInfoANDROID;

תיאורי חברים

  • type הוא XrStructureType של המבנה הזה.
  • next הוא NULL או הפניה למבנה הבא בשרשרת המבנים. לא מוגדרים מבנים כאלה ב-OpenXR או בהרחבה הזו.
  • baseSpace הוא XrSpace שמגדיר את מרחב העזר שבו ממוקם הטרנספורמציה של הנקודות ב-time.
  • time הוא XrTime שמתאר את הזמן שבו האפליקציה רוצה לשלוח שאילתה לרשת היד.

שימוש תקין (מרומז)

המבנה XrHandTrackingMeshesANDROID מכיל נתוני רשת (mesh) לשתי הידיים.

typedef struct XrHandTrackingMeshesANDROID {
    XrStructureType      type;
    void*                next;
    XrHandMeshANDROID    leftHandMesh;
    XrHandMeshANDROID    rightHandMesh;
} XrHandTrackingMeshesANDROID;

תיאורי חברים

  • type הוא XrStructureType של המבנה הזה.
  • next הוא NULL או הפניה למבנה הבא בשרשרת המבנים. לא מוגדרים מבנים כאלה ב-OpenXR או בהרחבה הזו.
  • leftHandMesh הוא XrHandMeshANDROID ליד שמאל.
  • rightHandMesh הוא XrHandMeshANDROID ליד הימנית.

שימוש תקין (מרומז)

המבנה XrHandMeshANDROID מכיל נתונים ומאגרים לקבלת נתוני מעקב אחר רשת של יד מפונקציית xrGetHandMeshANDROID עבור יד אחת.

typedef struct XrHandMeshANDROID {
    XrBool32             isActive;
    XrTime               dynamicLastUpdateTime;
    uint32_t             indexCount;
    uint32_t             vertexCount;
    const uint32_t*      indices;
    const XrVector2f*    textureUVs;
    const XrVector3f*    positions;
    const XrVector3f*    normals;
    XrPosef              baseSpaceFromVertexSpace;
} XrHandMeshANDROID;

תיאורי חברים

  • type הוא XrStructureType של המבנה הזה.
  • next הוא NULL או הפניה למבנה הבא בשרשרת המבנים. לא מוגדרים מבנים כאלה ב-OpenXR או בהרחבה הזו.
  • isActive הוא XrBool32 שמציין אם מכשיר המעקב הנוכחי אחרי רשת היד פעיל ונתוני הרשת תקינים.
  • dynamicLastUpdateTime הוא XrTime שמציין את המועד שבו המאגרים הדינמיים עודכנו לאחרונה.
  • indexCount הוא uint32_t שמשמש כמספר indices של רשת היד.
  • vertexCount הוא uint32_t שמשמש כמספר של positions של רשת היד. אפשר גם להשתמש בו עבור textureUVs או normals אם הם נתמכים במערכת.
  • indices הוא מערך של uint32_t שמייצג את אינדקסי הרשת של המשולשים בסדר נגד כיוון השעון. מספר הערכים שמוצגים הוא indexCount.
  • textureUVs הוא NULL או מערך של XrVector2f שמייצג את קואורדינטות המרקם של הנקודה. מספר הערכים שמוצגים הוא vertexCount.
  • positions הוא מערך של XrVector3f שמייצג את מיקומי הנקודות ב-baseSpaceFromVertexSpace. מספר הערכים שמוצגים הוא vertexCount.
  • normals הוא NULL או מערך של XrVector3f שמייצג את נורמלי הקודקודים ב-baseSpaceFromVertexSpace. מספר הערכים שמוצגים הוא vertexCount.
  • baseSpaceFromVertexSpace הוא הנקודה XrSpace שנמצאת ב-XrHandMeshGetInfoANDROID::baseSpace בזמן הקריאה ל-xrGetHandMeshANDROID. אפליקציות יכולות להשתמש בכך כדי לשנות את מרחב הקואורדינטות של הנקודות והנורמלים של המארג במהלך העיבוד.

רשת היד מיוצגת ברשימות של משולשים, והקודקודים של כל משולש מסודרים בסדר הפוך לשעון כשמסתכלים מבחוץ על היד.

כשהערך המוחזר של isActive הוא XR_FALSE, המשמעות היא שאין מעקב פעיל אחרי היד. לדוגמה, היד מחוץ לטווח החיישן, המיקוד של הקלט הועבר מהאפליקציה או לאפליקציה אין הרשאות לגשת לנתוני המעקב אחרי היד.

כשהערך המוחזר של isActive הוא XR_TRUE, רשת המעקב אחר הידיים שמיוצגת ב-indices וב-positions, כולל textureUVs ו-normals אם הם נתמכים במערכת, מתעדכנת בנתונים העדכניים ביותר של XrHandMeshGetInfoANDROID::time שניתנים לפונקציה xrGetHandMeshANDROID.

הזיכרון שאליו מפנים מאגרי המשנה של רשתות היד שמוחזרים ב-XrHandMeshANDROID הוא בבעלות סביבת זמן הריצה, והוא משותף עם האפליקציה. אפשר לגשת לזיכרון בבטחה מכל שרשור עד לקריאה הבאה ל-xrBeginFrame, כל עוד ה-handle‏ XrHandMeshTrackerANDROID תקף.

  • הערכים ש-indices ו-textureUVs מפנים אליהם לא דינמיים
  • הסמן והערכים ש-positions ו-normals מפנים אליהם הם דינמיים, ויכולים להשתנות בין קריאות ל-xrBeginFrame. האפליקציה יכולה להשתמש ב-dynamicLastUpdateTime כדי לבדוק אם הערכים השתנו מאז המסגרת האחרונה, וכך להימנע מעיבודי נתונים מיותרים כשאין שינויים.

שימוש תקין (מרומז)

  • חובה להפעיל את התוסף XR_ANDROID_hand_mesh לפני שמשתמשים ב-XrHandMeshANDROID
  • indices חייב להיות הפניה לערך uint32_t חוקי
  • textureUVs חייב להיות הפניה למבנה XrVector2f חוקי
  • positions חייב להיות הפניה למבנה XrVector3f חוקי
  • normals חייב להיות הפניה למבנה XrVector3f חוקי

קוד לדוגמה למעקב אחר רשת של יד

דוגמת הקוד הבאה מראה איך לגשת למאגרי המר mesh של היד לצורך רינדור.

XrInstance instance;  // Created at app startup
XrSystemId systemId;  // Received from xrGetSystem() at app startup
XrSession session;    // Created at app startup.
XrSpace appPlaySpace; // Created at app startup.

// The function pointers are previously initialized using xrGetInstanceProcAddr.
PFN_xrCreateHandMeshTrackerANDROID xrCreateHandMeshTrackerANDROID; // previously initialized
PFN_xrDestroyHandMeshTrackerANDROID xrDestroyHandMeshTrackerANDROID; // previously initialized
PFN_xrGetHandMeshANDROID xrGetHandMeshANDROID; // previously initialized

// Inspect system capability
XrSystemHandMeshTrackingPropertiesANDROID handMeshTrackingProps = {
  .type = XR_TYPE_SYSTEM_HAND_MESH_TRACKING_PROPERTIES_ANDROID,
};
XrSystemProperties sysProps = {
  .type = XR_TYPE_SYSTEM_PROPERTIES,
  .next = &handMeshTrackingProps
};
CHK_XR(xrGetSystemProperties(instance, systemId, &sysProps));
if (!handMeshTrackingProps.supportsHandMeshTracking) {
  // hand mesh tracking is not supported.
  return;
}

XrHandMeshTrackerCreateInfoANDROID trackerCreateInfo = {
  .type = XR_TYPE_HAND_MESH_TRACKER_CREATE_INFO_ANDROID
};
XrHandMeshTrackerANDROID handMeshTracker = XR_NULL_HANDLE;
CHK_XR(xrCreateHandMeshTrackerANDROID(
    session, &trackerCreateInfo, &handMeshTracker));
// app update loop
while (true) {
    // ...
    // For every frame in frame loop
    // ...

    XrFrameState frameState;  // previously returned from xrWaitFrame
    const XrTime time = frameState.predictedDisplayTime;

    // ...
    XrHandMeshGetInfoANDROID getInfo = {
        .type = XR_TYPE_HAND_MESH_GET_INFO_ANDROID,
        .baseSpace = appPlaySpace,
        .time = time,
    };
    XrHandTrackingMeshesANDROID handMeshes = {
        .type = XR_TYPE_HAND_TRACKING_MESHES_ANDROID
    };
    CHK_XR(xrGetHandMeshANDROID(handMeshTracker, &getInfo, &handMeshes));

    if (handMeshes.leftHandMesh.isActive) {
        // access vertex/index buffers for rendering.
    }

    // ...
    // Finish frame loop
    // ...
}

CHECK_XR(xrDestroyHandMeshTracker(handMeshTracker));

סוגי אובייקטים חדשים

קבועים חדשים של Enum

המניין XrObjectType הורחב עם:

  • XR_OBJECT_TYPE_HAND_MESH_TRACKER_ANDROID

המניין XrStructureType הורחב עם:

  • XR_TYPE_SYSTEM_HAND_MESH_TRACKING_PROPERTIES_ANDROID
  • XR_TYPE_HAND_MESH_TRACKER_CREATE_INFO_ANDROID
  • XR_TYPE_HAND_MESH_GET_INFO_ANDROID
  • XR_TYPE_HAND_TRACKING_MESHES_ANDROID

משתני Enum חדשים

מבנים חדשים

פונקציות חדשות

בעיות

היסטוריית הגרסאות

  • גרסה 1, 10 בספטמבר 2024 (Levana Chen)
    • תיאור ראשוני של התוסף