From d0c8146d43c611295da1e8b6279138929e445fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Delgado=20Kr=C3=A4mer?= Date: Tue, 16 Jul 2024 22:54:56 +0200 Subject: [PATCH] WIP --- src/libguc/CMakeLists.txt | 2 ++ src/libguc/src/converter.cpp | 44 ++++++++++++++++++++++++++++++++++-- src/libguc/src/converter.h | 2 +- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/libguc/CMakeLists.txt b/src/libguc/CMakeLists.txt index 4a871a1..a093bf3 100644 --- a/src/libguc/CMakeLists.txt +++ b/src/libguc/CMakeLists.txt @@ -38,6 +38,7 @@ set(LIBGUC_DEFINES GUC_VERSION_STRING="${CMAKE_PROJECT_VERSION}" ) +# TODO: allow monolithic USD set(LIBGUC_SHARED_LIBRARIES # Header-only library without link dependencies -- # we can get away with not installing the target. @@ -49,6 +50,7 @@ set(LIBGUC_SHARED_LIBRARIES usdShade usdUtils usdMtlx + usdSkel MaterialXCore MaterialXFormat ) diff --git a/src/libguc/src/converter.cpp b/src/libguc/src/converter.cpp index 964fb0c..fda9e9e 100644 --- a/src/libguc/src/converter.cpp +++ b/src/libguc/src/converter.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -535,7 +536,7 @@ namespace guc std::string meshName = nodeData->mesh->name ? std::string(nodeData->mesh->name) : "mesh"; auto meshPath = makeUniqueStageSubpath(m_stage, path, meshName); - createOrOverMesh(nodeData->mesh, meshPath); + createOrOverMesh(nodeData->mesh, nodeData->skin, meshPath); } if (nodeData->camera) @@ -689,7 +690,7 @@ namespace guc m_uniquePaths[(void*) lightData] = path; } - void Converter::createOrOverMesh(const cgltf_mesh* meshData, SdfPath path) + void Converter::createOrOverMesh(const cgltf_mesh* meshData, const cgltf_skin* skinData, SdfPath path) { auto xform = UsdGeomXform::Define(m_stage, path); @@ -757,6 +758,44 @@ namespace guc submesh.SetDisplayName(meshData->name); } } + + if (skinData) + { + fprintf(stderr, "skin %s found for mesh %s\n", skinData->name, path.GetText()); + + // TODO: Xform isn't boundable -> doesn't work. What to do? can we replace sub-meshes with GeomSubsets? + UsdPrim prim = xform.GetPrim(); + + auto skelApi = UsdSkelBindingAPI::Apply(prim); + + // TODO: create and link skeleton (TODO: lazy/global or not?) + // m_uniquePaths[skinData->skeleton] = skelPath; + + bool isConstant = true; + + // joint indices + { + VtArray jointIndices(skinData->joints_count); + for (size_t i = 0; i < jointIndices.size(); i++) + { + jointIndices[i] = (int) cgltf_node_index(m_data, skinData->joints[i]); + + isConstant &= (i == 0) || (jointIndices[i - 1] == jointIndices[i]); + } + + UsdGeomPrimvar primvar = skelApi.CreateJointIndicesPrimvar(isConstant, jointIndices.size()); // TODO: create Attr with VtValue default? + primvar.Set(jointIndices); + } + + // weights + { + VtArray jointWeights(meshData->weights_count); + memcpy(jointWeights.data(), meshData->weights, jointWeights.size()); // TODO: better way? + + UsdGeomPrimvar primvar = skelApi.CreateJointWeightsPrimvar(isConstant, jointWeights.size()); + primvar.Set(jointWeights); + } + } } void Converter::createMaterialBinding(UsdPrim& prim, const std::string& materialName) @@ -782,6 +821,7 @@ namespace guc } } +// TODO: path -> const path& bool Converter::createPrimitive(const cgltf_primitive* primitiveData, SdfPath path, UsdPrim& prim) { const cgltf_material* material = primitiveData->material; diff --git a/src/libguc/src/converter.h b/src/libguc/src/converter.h index d6abe3e..bb0f742 100644 --- a/src/libguc/src/converter.h +++ b/src/libguc/src/converter.h @@ -68,7 +68,7 @@ namespace guc void createNodesRecursively(const cgltf_node* nodeData, SdfPath path); void createOrOverCamera(const cgltf_camera* cameraData, SdfPath path); void createOrOverLight(const cgltf_light* lightData, SdfPath path); - void createOrOverMesh(const cgltf_mesh* meshData, SdfPath path); + void createOrOverMesh(const cgltf_mesh* meshData, const cgltf_skin* skin, SdfPath path); void createMaterialBinding(UsdPrim& prim, const std::string& materialName); bool createPrimitive(const cgltf_primitive* primitiveData, SdfPath path, UsdPrim& prim);