Autodesk / Autodesk/3dsmax-usd

Broken mesh and absent skeleton if not modeled under a common parent

Open
#41 7 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C++
Stars
94
Forks
6
Avg merge
6d 20h
Merged PRs (30d)
1

Description

**Describe the bug**

If a Mesh is skinned but its Skeleton is not placed under a common parent:
- the Skeleton is not exported
- the export Mesh is broken (as it does not have any properties beyond its transform

**Steps to reproduce**

The scene attached to this issues contains three elements:

- `SkinnedMeshRoot` contains a skeleton and a skinned mesh
- `JustASkeletonRoot` contains a skeleton, without a mesh
- `BoxC` is skinned by the Skeleton `BottomC/MiddleC/TopC`, but they don't have a common parent.

Image

When exported with these options:

Image

Then:
- OK: `SkinnedMeshRoot` is exported as expected: a Mesh and Skel nested under a SkelRoot
- OK: `JustASkeletonRoot` is exported as expected: a Skel under a Skelroot
- PROBLEM: `BoxC` is only exported as a transform and does not contain other properties
- PROBLEM: `BottomC/MiddleC/TopC` is not exported at all

Image

**Expected behavior**

First, the mesh should not be broken.

Second, I think that we should export both the Mesh and the Skeleton **without a SkelRoot**. The SkelRoot itself does not have properties that are authored to represent the skinning of the mesh. SkelRoot are "only" needed when the USD is consumed down the line by something that needs the skinning operation to be **computed**, but not **represented**. By requiring a top level 3ds Max node, we force an uneeded scene structure convention: we might want to export just a Skeleton from a scene, without a SkelRoot, to be assembled later by another process down the pipeline.

It's actually a very common workflow for our gaming pipeline, where the assembly is not even done in USD but by the game engine itself: we just need to transfer a Skeleton and a skinned Mesh.

For new scenes, it would be possible to always create this common toplevel node. The problem we're facing is with current production scenes: it forces us to adapt our export scripts to temporarily reparent the objects to be exported under a common node, export, then de-parent the exported objects and deal with an USD structure that does not match the 3ds Max original scene structure.

I think the right way would be for 3ds Max to:
- export the most top-level node as a `SkelRoot` to indicate that this stage subtree is Skinned
- just not have a `SkelRoot` if there is no top level node

In the example below:
- `b` will become a `SkelRoot`, because the subtree below has skinned prims
- `Mesh003` and `Skel003` do not have a `SkelRoot` ancestor, and that's exactly the intent

```
.
├── a/
│ └── b/
│ ├── Mesh001 (skinned by Skel001)
│ ├── d/
│ │ └── Skel001
│ └── e/
│ ├── Mesh002 (skinned by Skel002)
│ └── Skel002
├── Mesh003 (Skinned by Skel003)
└── Skel003
```

**Attachments**

[test-no-skelroot.zip](https://github.com/user-attachments/files/30104114/test-no-skelroot.zip)

Contains:
- `test-no-skelroot.max`, the sample scene above
- `test-no-skelroot.usda`, the full exported usda

**Specs (if applicable):**
- 3ds Max version: 2024.2.11
- 3ds USD version: 0.15.0.14

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the attached test-no-skelroot.max scene and compare its exported test-no-skelroot.usda, focusing on handling of skinned meshes and skeletons without a common parent. Reproduce the BoxC and BottomC/MiddleC/TopC cases, then verify that the mesh retains its properties and the skeleton exports without requiring a common SkelRoot.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-graphics, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.