Closed improbable-andreaskrugersen closed 1 year ago
Hi, this is not related to glTFRuntime, but to how Unreal works:
In glTFRuntime the first problem has been solved by adding tick-based node animations, in-fact if you open the outliner details you will see that the asset exposes a node based curve. Unfortunately the curve modifies the morph targets, and they do not exist in a static mesh (and so we fall into the second problem).
The second problem can be addressed by forcing the generation of a dumb skeleton (just the root) by enabling the StaticMeshAsSkeletalMesh flag:
The cool side-effect is that now the cat walking animation become a true unreal skeletal-animation (that obviously just modifies morph targets)
Thanks for responding.
Unfortunately, we can't use this flag for various reasons, the most important being that our users can import arbitrary, user-generated glb files and if I understand correctly, setting this flag would turn all static meshes into skeletal meshes, which is not what we want.
We'd need a way to determine programmatically whether this case was encountered or not. How can I check that? I should mention that we're not using AglTFRuntimeAssetActor
or AglTFRuntimeAssetActorAsync
directly but we've extracted the logic of the latter into our own actor, so we're flexible in adding additional logic here.
@improbable-andreaskrugersen probably (for your case) the best approach is to set statics as skeletals if morph targets are present:
{
"primitives": [
{
"attributes": {
"NORMAL": 23,
"POSITION": 22,
"TANGENT": 24,
"TEXCOORD_0": 25
},
"indices": 21,
"material": 3,
"targets": [
{
"NORMAL": 33,
"POSITION": 32,
"TANGENT": 34
},
{
"NORMAL": 43,
"POSITION": 42,
"TANGENT": 44
}
]
}
],
"weights": [0, 0.5]
}
"targets" is a property of the primitive object, so you can check for the size of the array len(meshes[mesh_id][primitives][any_id][targets]) > 0
.
You can use the low level JSON api of Unreal (given that you are working in cpp) or you can rely on the gltfruntime simplified api described here: https://github.com/rdeioris/glTFRuntime-docs/blob/master/VRM.md#extensionsvrmmeta
The second problem can be addressed by forcing the generation of a dumb skeleton (just the root) by enabling the StaticMeshAsSkeletalMesh flag:
@rdeioris Hi, whereabouts is this StaticMeshAsSkeletalMesh flag? I'm struggling to find it
@alexellismpg hi, it is in the options you get when you use the "spawn actor from class" node and select the gltfruntime asset actor
Hi,
when loading https://ht290.s3.amazonaws.com/kitten_walk.glb, the contained mesh is interpreted as a static mesh, although the GLB file contains animations. If I load this in other clients, e.g. with the three.js GLTFLoader or in the Windows 3D Viewer, the mesh is correctly animated though.
If I understand correctly, that decision is made based on whether the mesh node contains a
skin
value. Looking at the JSON data, it seems that thekitten_GEO
node does indeed not have this value. And a quick look at the three.js GLTFLoader code suggests that it's also using that check to determine whether it's a skinned mesh. But both those loaders seem to interpret it correctly after all while glTFRuntime doesn't.