[Bf-blender-cvs] [1990bb921f2] xr-controller-support: XR: Support dynamic controller model components

Peter Kim noreply at git.blender.org
Sun Aug 15 08:47:06 CEST 2021


Commit: 1990bb921f2cfbfbbfa9c56cbbeafb40b06f453e
Author: Peter Kim
Date:   Sun Aug 15 15:18:34 2021 +0900
Branches: xr-controller-support
https://developer.blender.org/rB1990bb921f2cfbfbbfa9c56cbbeafb40b06f453e

XR: Support dynamic controller model components

Updating the transforms, or "animating", supported controller
model parts (trigger, grip, thumbstick, etc.) provides better visual
feedback for the user and adds little overhead due to caching of node
transforms/indices.

===================================================================

M	intern/ghost/GHOST_C-api.h
M	intern/ghost/intern/GHOST_C-api.cpp
M	intern/ghost/intern/GHOST_XrControllerModel.cpp
M	intern/ghost/intern/GHOST_XrControllerModel.h
M	intern/ghost/intern/GHOST_XrSession.cpp
M	intern/ghost/intern/GHOST_XrSession.h
M	source/blender/windowmanager/xr/intern/wm_xr_session.c

===================================================================

diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index d3ef610a5ac..784febe8581 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -1151,6 +1151,12 @@ int GHOST_XrLoadControllerModel(GHOST_XrContextHandle xr_context, const char *su
  */
 void GHOST_XrUnloadControllerModel(GHOST_XrContextHandle xr_context, const char *subaction_path);
 
+/**
+ * Update component transforms for the OpenXR controller model.
+ */
+int GHOST_XrUpdateControllerModelComponents(GHOST_XrContextHandle xr_context,
+                                            const char *subaction_path);
+
 /**
  * Get vertex data for the OpenXR controller model.
  */
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 08c0f38cdaa..a21c3a90c06 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -1085,6 +1085,15 @@ void GHOST_XrUnloadControllerModel(GHOST_XrContextHandle xr_contexthandle,
   GHOST_XR_CAPI_CALL(xr_session->unloadControllerModel(subaction_path), xr_context);
 }
 
+int GHOST_XrUpdateControllerModelComponents(GHOST_XrContextHandle xr_contexthandle,
+                                            const char *subaction_path)
+{
+  GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
+  GHOST_XrSession *xr_session = xr_context->getSession();
+  GHOST_XR_CAPI_CALL_RET(xr_session->updateControllerModelComponents(subaction_path), xr_context);
+  return 0;
+}
+
 int GHOST_XrGetControllerModelData(GHOST_XrContextHandle xr_contexthandle,
                                    const char *subaction_path,
                                    GHOST_XrControllerModelData *r_data)
diff --git a/intern/ghost/intern/GHOST_XrControllerModel.cpp b/intern/ghost/intern/GHOST_XrControllerModel.cpp
index cd2637a4e77..fdd1c12af5b 100644
--- a/intern/ghost/intern/GHOST_XrControllerModel.cpp
+++ b/intern/ghost/intern/GHOST_XrControllerModel.cpp
@@ -35,6 +35,13 @@
 #define STBIWDEF static inline
 #include "tiny_gltf.h"
 
+struct GHOST_XrControllerModelNode {
+  int32_t parent_idx = -1;
+  int32_t component_idx = -1;
+  float local_transform[4][4];
+  float world_transform[4][4];
+};
+
 /* -------------------------------------------------------------------- */
 /** \name glTF Utilities
  *
@@ -224,7 +231,7 @@ static GHOST_XrPrimitive read_primitive(const tinygltf::Model &gltf_model,
 /* Calculate node transform in world space. */
 static void calc_node_transform(const tinygltf::Node &gltf_node,
                                 const float parent_transform[4][4],
-                                float r_transform[4][4])
+                                GHOST_XrControllerModelNode &node)
 {
   /* A node may specify either a 4x4 matrix or TRS (Translation - Rotation - Scale) values, but not
    * both. */
@@ -246,15 +253,14 @@ static void calc_node_transform(const tinygltf::Node &gltf_node,
                      (float)dm[13],
                      (float)dm[14],
                      (float)dm[15]};
-
-    *(Eigen::Matrix4f *)r_transform = *(Eigen::Matrix4f *)parent_transform * *(Eigen::Matrix4f *)m;
+    memcpy(node.local_transform, m, sizeof(node.local_transform));
   }
   else {
     /* No matrix is present, so construct a matrix from the TRS values (each one is optional). */
     std::vector<double> translation = gltf_node.translation;
     std::vector<double> rotation = gltf_node.rotation;
     std::vector<double> scale = gltf_node.scale;
-    Eigen::Matrix4f m;
+    Eigen::Matrix4f &m = *(Eigen::Matrix4f *)node.local_transform;
     Eigen::Quaternionf q;
     Eigen::Matrix3f scalemat;
 
@@ -287,28 +293,45 @@ static void calc_node_transform(const tinygltf::Node &gltf_node,
     m.block<3, 3>(0, 0) = q.toRotationMatrix() * scalemat;
     m.block<3, 1>(0, 3) = Eigen::Vector3f(
         (float)translation[0], (float)translation[1], (float)translation[2]);
-
-    *(Eigen::Matrix4f *)r_transform = *(Eigen::Matrix4f *)parent_transform * m;
   }
+
+  *(Eigen::Matrix4f *)node.world_transform = *(Eigen::Matrix4f *)parent_transform *
+                                             *(Eigen::Matrix4f *)node.local_transform;
 }
 
 static void load_node(tinygltf::Model gltf_model,
-                      int node_id,
+                      int gltf_node_id,
+                      int32_t parent_idx,
                       const float parent_transform[4][4],
+                      const std::string &parent_name,
+                      const std::vector<XrControllerModelNodePropertiesMSFT> &node_properties,
                       std::vector<GHOST_XrControllerModelVertex> &vertices,
                       std::vector<uint32_t> &indices,
-                      std::vector<GHOST_XrControllerModelComponent> &components)
+                      std::vector<GHOST_XrControllerModelComponent> &components,
+                      std::vector<GHOST_XrControllerModelNode> &nodes,
+                      std::vector<int32_t> &node_state_indices)
 {
-  const tinygltf::Node &gltf_node = gltf_model.nodes.at(node_id);
-  float transform[4][4];
-
-  calc_node_transform(gltf_node, parent_transform, transform);
+  const tinygltf::Node &gltf_node = gltf_model.nodes.at(gltf_node_id);
+
+  GHOST_XrControllerModelNode &node = nodes.emplace_back();
+  const int32_t node_idx = (int32_t)(nodes.size() - 1);
+  node.parent_idx = parent_idx;
+  calc_node_transform(gltf_node, parent_transform, node);
+
+  for (size_t i = 0; i < node_properties.size(); ++i) {
+    if ((node_state_indices[i] < 0) && (parent_name == node_properties[i].parentNodeName) &&
+        (gltf_node.name == node_properties[i].nodeName)) {
+      node_state_indices[i] = node_idx;
+      break;
+    }
+  }
 
   if (gltf_node.mesh != -1) {
     const tinygltf::Mesh &gltf_mesh = gltf_model.meshes.at(gltf_node.mesh);
 
     GHOST_XrControllerModelComponent &component = components.emplace_back();
-    memcpy(component.transform, transform, sizeof(component.transform));
+    node.component_idx = components.size() - 1;
+    memcpy(component.transform, node.world_transform, sizeof(component.transform));
     component.vertex_offset = vertices.size();
     component.index_offset = indices.size();
 
@@ -340,7 +363,17 @@ static void load_node(tinygltf::Model gltf_model,
 
   /* Recursively load all children. */
   for (const int child_node_id : gltf_node.children) {
-    load_node(gltf_model, child_node_id, transform, vertices, indices, components);
+    load_node(gltf_model,
+              child_node_id,
+              node_idx,
+              node.world_transform,
+              gltf_node.name,
+              node_properties,
+              vertices,
+              indices,
+              components,
+              nodes,
+              node_state_indices);
   }
 }
 
@@ -357,12 +390,12 @@ static PFN_xrGetControllerModelPropertiesMSFT g_xrGetControllerModelPropertiesMS
 static PFN_xrGetControllerModelStateMSFT g_xrGetControllerModelStateMSFT = nullptr;
 static XrInstance g_instance = XR_NULL_HANDLE;
 
-#define LOAD_EXTENSION_FUNCTION(name) \
+#define INIT_EXTENSION_FUNCTION(name) \
   CHECK_XR( \
       xrGetInstanceProcAddr(instance, #name, reinterpret_cast<PFN_xrVoidFunction *>(&g_##name)), \
-      "Failed to load extension function: " #name);
+      "Failed to get pointer to extension function: " #name);
 
-static void load_controller_model_extension_functions(XrInstance instance)
+static void init_controller_model_extension_functions(XrInstance instance)
 {
   if (instance != g_instance) {
     g_instance = instance;
@@ -373,16 +406,16 @@ static void load_controller_model_extension_functions(XrInstance instance)
   }
 
   if (g_xrGetControllerModelKeyMSFT == nullptr) {
-    LOAD_EXTENSION_FUNCTION(xrGetControllerModelKeyMSFT);
+    INIT_EXTENSION_FUNCTION(xrGetControllerModelKeyMSFT);
   }
   if (g_xrLoadControllerModelMSFT == nullptr) {
-    LOAD_EXTENSION_FUNCTION(xrLoadControllerModelMSFT);
+    INIT_EXTENSION_FUNCTION(xrLoadControllerModelMSFT);
   }
   if (g_xrGetControllerModelPropertiesMSFT == nullptr) {
-    LOAD_EXTENSION_FUNCTION(xrGetControllerModelPropertiesMSFT);
+    INIT_EXTENSION_FUNCTION(xrGetControllerModelPropertiesMSFT);
   }
   if (g_xrGetControllerModelStateMSFT == nullptr) {
-    LOAD_EXTENSION_FUNCTION(xrGetControllerModelStateMSFT);
+    INIT_EXTENSION_FUNCTION(xrGetControllerModelStateMSFT);
   }
 }
 
@@ -396,8 +429,7 @@ static void load_controller_model_extension_functions(XrInstance instance)
 GHOST_XrControllerModel::GHOST_XrControllerModel(XrInstance instance,
                                                  const char *subaction_path_str)
 {
-  /* Load extension functions. */
-  load_controller_model_extension_functions(instance);
+  init_controller_model_extension_functions(instance);
 
   CHECK_XR(xrStringToPath(instance, subaction_path_str, &m_subaction_path),
            (std::string("Failed to get user path \"") + subaction_path_str + "\".").data());
@@ -410,7 +442,7 @@ GHOST_XrControllerModel::~GHOST_XrControllerModel()
   }
 }
 
-void GHOST_XrControllerModel::update(XrSession session)
+void GHOST_XrControllerModel::load(XrSession session)
 {
   if (m_data_loaded || m_load_task.valid()) {
     return;
@@ -422,23 +454,22 @@ void GHOST_XrControllerModel::update(XrSession session)
            "Failed to get controller model key state.");
 
   if (key_state.modelKey != XR_NULL_CONTROLLER_MODEL_KEY_MSFT) {
+    m_model_key = key_state.modelKey;
+    /* Load asynchronously. */
     m_load_task = std::async(std::launch::async,
-                             [&, session = session, model_key = key_state.modelKey]() {
-                               return loadControllerModel(session, model_key);
-                             });
+                             [&, session = session]() { return loadControllerModel(session); });
   }
 }
 
-void GHOST_XrControllerModel::loadControllerModel(XrSession session,
-                                                  XrControllerModelKeyMSFT model_key)
+void GHOST_XrControllerModel::loadControllerModel(XrSession session)
 {
   /* Load binary buffers. */
   uint32_t buf_size = 0;
-  CHECK_XR(g_xrLoadControllerModelMSFT(session, model_key, 0, &buf_size, nullptr),
+  CHECK_XR(g_xrLoadControll

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list