10 #include <Eigen/Geometry>
18 #define TINYGLTF_IMPLEMENTATION
19 #define TINYGLTF_NO_STB_IMAGE
20 #define TINYGLTF_NO_STB_IMAGE_WRITE
21 #define STBIWDEF static inline
22 #include "tiny_gltf.h"
38 std::vector<GHOST_XrControllerModelVertex>
vertices;
47 const tinygltf::BufferView &buffer_view,
53 if (accessor.byteOffset + (accessor.count - 1) * byte_stride + element_size >
54 buffer_view.byteLength) {
59 if (buffer_view.byteOffset + buffer_view.byteLength >
buffer.data.size()) {
64 template<
float (GHOST_XrControllerModelVertex::*field)[3]>
66 const tinygltf::BufferView &buffer_view,
70 if (accessor.type != TINYGLTF_TYPE_VEC3) {
72 "glTF: Accessor for primitive attribute has incorrect type (VEC3 expected).");
75 if (accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
77 "glTF: Accessor for primitive attribute has incorrect component type (FLOAT expected).");
81 constexpr
size_t packed_size =
sizeof(
float) * 3;
82 const size_t stride = buffer_view.byteStride == 0 ? packed_size : buffer_view.byteStride;
88 primitive.
vertices.resize(accessor.count);
91 const uint8_t *buffer_ptr =
buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
92 for (
size_t i = 0; i < accessor.count; i++, buffer_ptr +=
stride) {
98 const std::string &attribute_name,
102 const auto &accessor = gltf_model.accessors.at(accessor_id);
104 if (accessor.bufferView == -1) {
105 throw GHOST_XrException(
"glTF: Accessor for primitive attribute specifies no bufferview.");
108 const tinygltf::BufferView &buffer_view = gltf_model.bufferViews.at(accessor.bufferView);
109 if (buffer_view.target != TINYGLTF_TARGET_ARRAY_BUFFER && buffer_view.target != 0) {
111 "glTF: Accessor for primitive attribute uses bufferview with invalid 'target' type.");
116 if (attribute_name.compare(
"POSITION") == 0) {
117 read_vertices<&GHOST_XrControllerModelVertex::position>(
118 accessor, buffer_view,
buffer, primitive);
120 else if (attribute_name.compare(
"NORMAL") == 0) {
121 read_vertices<&GHOST_XrControllerModelVertex::normal>(
122 accessor, buffer_view,
buffer, primitive);
130 template<
typename TSrcIndex>
132 const tinygltf::BufferView &buffer_view,
138 if (buffer_view.target != TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER && buffer_view.target != 0) {
140 "glTF: Accessor for indices uses bufferview with invalid 'target' type.");
143 constexpr
size_t component_size_bytes =
sizeof(TSrcIndex);
144 if (buffer_view.byteStride != 0 &&
145 buffer_view.byteStride !=
146 component_size_bytes) {
148 "glTF: Accessor for indices uses bufferview with invalid 'byteStride'.");
154 if ((accessor.count % 3) != 0) {
155 throw GHOST_XrException(
"glTF: Unexpected number of indices for triangle primitive");
158 const TSrcIndex *index_buffer =
reinterpret_cast<const TSrcIndex *
>(
159 buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset);
160 for (
uint32_t i = 0; i < accessor.count; i++) {
161 primitive.
indices.push_back(*(index_buffer + i));
169 const tinygltf::Accessor &accessor,
172 if (accessor.type != TINYGLTF_TYPE_SCALAR) {
176 if (accessor.bufferView == -1) {
177 throw GHOST_XrException(
"glTF: Index accessor without bufferView is currently not supported.");
180 const tinygltf::BufferView &buffer_view = gltf_model.bufferViews.at(accessor.bufferView);
183 if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
184 read_indices<uint8_t>(accessor, buffer_view,
buffer, primitive);
186 else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
187 read_indices<uint16_t>(accessor, buffer_view,
buffer, primitive);
189 else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) {
190 read_indices<uint32_t>(accessor, buffer_view,
buffer, primitive);
193 throw GHOST_XrException(
"glTF: Accessor for indices specifies invalid 'componentType'.");
198 const tinygltf::Primitive &gltf_primitive)
200 if (gltf_primitive.mode != TINYGLTF_MODE_TRIANGLES) {
202 "glTF: Unsupported primitive mode. Only TINYGLTF_MODE_TRIANGLES is supported.");
209 for (
const auto &[attr_name, accessor_idx] : gltf_primitive.attributes) {
213 if (gltf_primitive.indices != -1) {
215 load_index_accessor(gltf_model, gltf_model.accessors.at(gltf_primitive.indices), primitive);
225 const float parent_transform[4][4],
226 float r_local_transform[4][4],
227 float r_world_transform[4][4])
231 if (gltf_node.matrix.size() == 16) {
232 const std::vector<double> &dm = gltf_node.matrix;
233 float m[4][4] = {{(
float)dm[0], (
float)dm[1], (
float)dm[2], (
float)dm[3]},
234 {(
float)dm[4], (
float)dm[5], (
float)dm[6], (
float)dm[7]},
235 {(
float)dm[8], (
float)dm[9], (
float)dm[10], (
float)dm[11]},
236 {(
float)dm[12], (
float)dm[13], (
float)dm[14], (
float)dm[15]}};
237 memcpy(r_local_transform, m,
sizeof(
float[4][4]));
241 std::vector<double> translation = gltf_node.translation;
242 std::vector<double> rotation = gltf_node.rotation;
243 std::vector<double> scale = gltf_node.scale;
244 Eigen::Matrix4f &m = *(Eigen::Matrix4f *)r_local_transform;
245 Eigen::Quaternionf q;
246 Eigen::Matrix3f scalemat;
248 if (translation.size() != 3) {
249 translation.resize(3);
250 translation[0] = translation[1] = translation[2] = 0.0;
252 if (rotation.size() != 4) {
254 rotation[0] = rotation[1] = rotation[2] = 0.0;
257 if (scale.size() != 3) {
259 scale[0] = scale[1] = scale[2] = 1.0;
262 q.w() = (
float)rotation[3];
263 q.x() = (
float)rotation[0];
264 q.y() = (
float)rotation[1];
265 q.z() = (
float)rotation[2];
268 scalemat.setIdentity();
269 scalemat(0, 0) = (
float)scale[0];
270 scalemat(1, 1) = (
float)scale[1];
271 scalemat(2, 2) = (
float)scale[2];
274 m.block<3, 3>(0, 0) = q.toRotationMatrix() * scalemat;
275 m.block<3, 1>(0, 3) = Eigen::Vector3f(
276 (
float)translation[0], (
float)translation[1], (
float)translation[2]);
279 *(Eigen::Matrix4f *)r_world_transform = *(Eigen::Matrix4f *)parent_transform *
280 *(Eigen::Matrix4f *)r_local_transform;
283 static void load_node(
const tinygltf::Model &gltf_model,
286 const float parent_transform[4][4],
287 const std::string &parent_name,
288 const std::vector<XrControllerModelNodePropertiesMSFT> &node_properties,
289 std::vector<GHOST_XrControllerModelVertex> &vertices,
290 std::vector<uint32_t> &
indices,
291 std::vector<GHOST_XrControllerModelComponent> &components,
292 std::vector<GHOST_XrControllerModelNode> &nodes,
293 std::vector<int32_t> &node_state_indices)
295 const tinygltf::Node &gltf_node = gltf_model.nodes.at(gltf_node_id);
296 float world_transform[4][4];
300 node.parent_idx = parent_idx;
303 for (
size_t i = 0; i < node_properties.size(); ++i) {
304 if ((node_state_indices[i] < 0) && (parent_name == node_properties[i].parentNodeName) &&
305 (gltf_node.name == node_properties[i].nodeName)) {
306 node_state_indices[i] = node_idx;
311 if (gltf_node.mesh != -1) {
312 const tinygltf::Mesh &gltf_mesh = gltf_model.meshes.at(gltf_node.mesh);
314 GHOST_XrControllerModelComponent &
component = components.emplace_back();
315 node.component_idx = components.size() - 1;
317 component.vertex_offset = vertices.size();
320 for (
const tinygltf::Primitive &gltf_primitive : gltf_mesh.primitives) {
324 const size_t start_vertex = vertices.size();
325 size_t offset = start_vertex;
328 memcpy(vertices.data() +
offset,
335 for (
size_t i = 0; i <
count; i += 3) {
347 for (
const int child_node_id : gltf_node.children) {
375 #define INIT_EXTENSION_FUNCTION(name) \
377 xrGetInstanceProcAddr(instance, #name, reinterpret_cast<PFN_xrVoidFunction *>(&g_##name)), \
378 "Failed to get pointer to extension function: " #name);
412 const char *subaction_path_str)
417 (std::string(
"Failed to get user path \"") + subaction_path_str +
"\".").
data());
422 if (m_load_task.valid()) {
429 if (m_data_loaded || m_load_task.valid()) {
434 XrControllerModelKeyStateMSFT key_state{XR_TYPE_CONTROLLER_MODEL_KEY_STATE_MSFT};
436 "Failed to get controller model key state.");
438 if (key_state.modelKey != XR_NULL_CONTROLLER_MODEL_KEY_MSFT) {
439 m_model_key = key_state.modelKey;
441 m_load_task = std::async(std::launch::async,
442 [&, session = session]() {
return loadControllerModel(session); });
446 void GHOST_XrControllerModel::loadControllerModel(XrSession session)
451 "Failed to get controller model buffer size.");
453 std::vector<uint8_t> buf((
size_t)buf_size);
455 "Failed to load controller model binary buffers.");
458 tinygltf::TinyGLTF gltf_loader;
459 tinygltf::Model gltf_model;
470 const unsigned char *p5,
472 void *user_pointer) ->
bool {
484 gltf_loader.SetImageLoader(load_img_func,
nullptr);
487 if (!gltf_loader.LoadBinaryFromMemory(&gltf_model, &err_msg,
nullptr, buf.data(), buf_size)) {
488 throw GHOST_XrException((
"Failed to load glTF controller model: " + err_msg).c_str());
492 XrControllerModelPropertiesMSFT model_properties{XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT};
493 model_properties.nodeCapacityInput = 0;
495 "Failed to get controller model node properties count.");
497 std::vector<XrControllerModelNodePropertiesMSFT> node_properties(
498 model_properties.nodeCountOutput, {XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT});
499 model_properties.nodeCapacityInput = (
uint32_t)node_properties.size();
500 model_properties.nodeProperties = node_properties.data();
502 "Failed to get controller model node properties.");
504 m_node_state_indices.resize(node_properties.size(), -1);
508 (gltf_model.defaultScene == -1) ? 0 : gltf_model.defaultScene);
510 const std::string root_name =
"";
511 float root_transform[4][4] = {{0}};
512 root_transform[0][0] = root_transform[1][1] = root_transform[2][2] = root_transform[3][3] = 1.0f;
514 for (
const int node_id : default_scene.nodes) {
525 m_node_state_indices);
528 m_data_loaded =
true;
533 if (!m_data_loaded) {
538 XrControllerModelStateMSFT model_state{XR_TYPE_CONTROLLER_MODEL_STATE_MSFT};
539 model_state.nodeCapacityInput = 0;
541 "Failed to get controller model node state count.");
544 std::vector<XrControllerModelNodeStateMSFT> node_states(
545 count, {XR_TYPE_CONTROLLER_MODEL_NODE_STATE_MSFT});
546 model_state.nodeCapacityInput =
count;
547 model_state.nodeStates = node_states.data();
549 "Failed to get controller model node states.");
552 assert(m_node_state_indices.size() ==
count);
554 for (
uint32_t state_idx = 0; state_idx <
count; ++state_idx) {
555 const int32_t &node_idx = m_node_state_indices[state_idx];
557 const XrPosef &pose = node_states[state_idx].nodePose;
558 Eigen::Matrix4f &m = *(Eigen::Matrix4f *)m_nodes[node_idx].local_transform;
559 Eigen::Quaternionf q(
560 pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z);
562 m.block<3, 3>(0, 0) = q.toRotationMatrix();
563 m.block<3, 1>(0, 3) = Eigen::Vector3f(pose.position.x, pose.position.y, pose.position.z);
568 std::vector<Eigen::Matrix4f> world_transforms(m_nodes.size());
571 world_transforms[i] = (
node.parent_idx >= 0) ? world_transforms[
node.parent_idx] *
572 *(Eigen::Matrix4f *)
node.local_transform :
573 *(Eigen::Matrix4f *)
node.local_transform;
574 if (
node.component_idx >= 0) {
575 memcpy(m_components[
node.component_idx].transform,
576 world_transforms[i].data(),
577 sizeof(m_components[
node.component_idx].transform));
586 r_data.count_vertices = (
uint32_t)m_vertices.size();
587 r_data.vertices = m_vertices.data();
588 r_data.count_indices = (
uint32_t)m_indices.size();
589 r_data.indices = m_indices.data();
590 r_data.count_components = (
uint32_t)m_components.size();
591 r_data.components = m_components.data();
594 r_data.count_vertices = 0;
595 r_data.vertices =
nullptr;
596 r_data.count_indices = 0;
597 r_data.indices =
nullptr;
598 r_data.count_components = 0;
599 r_data.components =
nullptr;
typedef float(TangentPoint)[2]
static uint8 component(Color32 c, uint i)
static void init_controller_model_extension_functions(XrInstance instance)
static void load_node(const tinygltf::Model &gltf_model, 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_XrControllerModelNode > &nodes, std::vector< int32_t > &node_state_indices)
static void read_vertices(const tinygltf::Accessor &accessor, const tinygltf::BufferView &buffer_view, const tinygltf::Buffer &buffer, GHOST_XrPrimitive &primitive)
static XrInstance g_instance
static void validate_accessor(const tinygltf::Accessor &accessor, const tinygltf::BufferView &buffer_view, const tinygltf::Buffer &buffer, size_t byte_stride, size_t element_size)
static PFN_xrLoadControllerModelMSFT g_xrLoadControllerModelMSFT
static void read_indices(const tinygltf::Accessor &accessor, const tinygltf::BufferView &buffer_view, const tinygltf::Buffer &buffer, GHOST_XrPrimitive &primitive)
#define INIT_EXTENSION_FUNCTION(name)
static PFN_xrGetControllerModelPropertiesMSFT g_xrGetControllerModelPropertiesMSFT
static void load_index_accessor(const tinygltf::Model &gltf_model, const tinygltf::Accessor &accessor, GHOST_XrPrimitive &primitive)
static PFN_xrGetControllerModelStateMSFT g_xrGetControllerModelStateMSFT
static PFN_xrGetControllerModelKeyMSFT g_xrGetControllerModelKeyMSFT
static GHOST_XrPrimitive read_primitive(const tinygltf::Model &gltf_model, const tinygltf::Primitive &gltf_primitive)
static void calc_node_transforms(const tinygltf::Node &gltf_node, const float parent_transform[4][4], float r_local_transform[4][4], float r_world_transform[4][4])
static void load_attribute_accessor(const tinygltf::Model &gltf_model, const std::string &attribute_name, int accessor_id, GHOST_XrPrimitive &primitive)
#define CHECK_XR(call, error_msg)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei stride
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object instance
void updateComponents(XrSession session)
GHOST_XrControllerModel(XrInstance instance, const char *subaction_path)
void getData(GHOST_XrControllerModelData &r_data)
~GHOST_XrControllerModel()
void load(XrSession session)
SyclQueue void void size_t num_bytes void
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_gpu_kernel_postfix int ccl_global int * indices
float local_transform[4][4]
std::vector< GHOST_XrControllerModelVertex > vertices
std::vector< uint32_t > indices