Multiple-frames BlendShape (failed) Animation in Reality Composer Pro

Goal: To render in an apple vision pro app, the solid-mechanics 3D simulation results coming form an FEA code.

Starting point: I have surface vtks with deformations on each node. Each time step has a a mesh with the nodal coordinates. This is straighforward translatable to a usd MeshSequence. Unfortunately, the results cannot be simplified to a scaling o linear transformation as you would do with other game-oriented animations.

Tools: Right now, I am using Xcode and reality composer pro (RCP) to build the scenes.

Technical limitations: I am aware that RCP can do animations with BlendMesh and skeletons and that MeshSequence is not a problem.

Progress:

  1. Coverting to the sequence of vtk meshes to a usd MeshSequence is straighforward. This animates correctly in Preview and Blender (see screenshot).
  2. I managed to convert from MeshSequence to multiple keys and BlendMesh. This also animates correctly in Blender and preview. Unfortunately, the BlendMesh of multiple blended meshes shows a zero animation time in RCP (see screenshot below)

Also, see below usda file scheme for the animation. Of course I am not showing full vectors such as faceVertexCounts, faceVertexIndex, normals.

Question: what is the right set up to create a BlendMesh animation that RCP will correctly import and animate, form a set of Meshes or multiple key shapes?

Blender animation

Time zero RCP "animations"

#usda 1.0
(
    defaultPrim = "BlendMeshRoot"
    doc = "Blender v4.5.3 LTS"
    endTimeCode = 48
    framesPerSecond = 24
    metersPerUnit = 1
    startTimeCode = 0
    timeCodesPerSecond = 24
    upAxis = "Z"
)

def Xform "BlendMeshRoot" (
    customData = {
        dictionary Blender = {
            bool generated = 1
        }
    }
)
{
    def SkelRoot "Mesh"
    {
        custom string userProperties:blender:object_name = "Mesh"
        float3 xformOp:rotateXYZ = (89.99999, -0, 0)
        float3 xformOp:scale = (0.009999999, 0.01, 0.01)
        double3 xformOp:translate = (0, 0, 0)
        uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"]

        def Mesh "Mesh" (
            active = true
            prepend apiSchemas = ["MaterialBindingAPI", "SkelBindingAPI"]
        )        
        {
            uniform bool doubleSided = 1
            float3[] extent = [(25.091871, -34.121277, -13.298501), (299.94482, 245.10088, 202.35126)]
            int[] faceVertexCounts = [3, 3, ...
            int[] faceVertexIndices = [0, 10293, ...
            rel material:binding = </BlendMeshRoot/_materials/MeshSequence_Default>
            normal3f[] normals = [(-0.3632836, -0.9102419, -0.19870725), ....
            point3f[] points = [(244.41148, 155.42062, 70.454926),.....
            float3[] primvars:node_displacement = [(93.54703, 110.9341, 48.37992)....
           float3[] primvars:Normals = [(-0.0050530406, -0.9910114, -0.13368203),...
            int[] primvars:skel:jointIndices = [0, 0, 0, 0, 0 ...
            float[] primvars:skel:jointWeights = [1, 1, 1, 1, 1...
            uniform token[] skel:blendShapes = ["frame_0000", "frame_0001", "frame_0002", "frame_0003", "frame_0004", "frame_0005"]
            rel skel:blendShapeTargets = [
                </BlendMeshRoot/Mesh/Mesh/frame_0000>,
               .......
                </BlendMeshRoot/Mesh/Mesh/frame_0005>,
            ]
            prepend rel skel:skeleton = </BlendMeshRoot/Mesh/Skel>
            uniform token subdivisionScheme = "none"
            custom string userProperties:blender:data_name = "Mesh"
            custom float userProperties:originalTime
            float userProperties:originalTime.timeSamples = {
                0: 0,
            }

            def BlendShape "frame_0000"
            {
                uniform vector3f[] offsets = [(0, 0, 0), (0, 0, 0),.....
               uniform int[] pointIndices = [0, 1, 2, .....
            }
           .....
           .....
#### BlendShape frame to 0005
           .....
        def Skeleton "Skel" (
            prepend apiSchemas = ["SkelBindingAPI"]
        )
        {
            uniform matrix4d[] bindTransforms = [( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )]
            uniform token[] joints = ["joint1"]
            uniform matrix4d[] restTransforms = [( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )]
            prepend rel skel:animationSource = </BlendMeshRoot/Mesh/Skel/Anim>

            def SkelAnimation "Anim"
            {
                uniform token[] blendShapes = ["frame_0000", "frame_0001", "frame_0002", "frame_0003", "frame_0004", "frame_0005"]
                float[] blendShapeWeights.timeSamples = {
                    0: [1, 0, 0, 0, 0, 0],
                    1: [0.9697085, 0.03029152, 0, 0, 0, 0],
                    2: [0.88787615, 0.11212383, 0, 0, 0, 0],
                     .....
                    46: [0, 0, 0, 0, 0.11212379, 0.8878762],
                    47: [0, 0, 0, 0, 0.030291557, 0.96970844],
                    48: [0, 0, 0, 0, 0, 1],
                }
            }
        }
    }

    def Scope "_materials"
    {
        def Material "MeshSequence_Default"
        {
            token outputs:surface.connect = </BlendMeshRoot/_materials/MeshSequence_Default/Principled_BSDF.outputs:surface>
            custom string userProperties:blender:data_name = "MeshSequence_Default"

            def Shader "Principled_BSDF"
            {
                uniform token info:id = "UsdPreviewSurface"
                float inputs:clearcoat = 0
                float inputs:clearcoatRoughness = 0.03
                color3f inputs:diffuseColor = (0.8, 0.4, 0.3)
                float inputs:ior = 1.5
                float inputs:metallic = 0
                float inputs:opacity = 1
                float inputs:roughness = 0.5
                float inputs:specular = 0.2
                token outputs:surface
            }
        }
    }

    def Scope "AnimationClips"
    {
        custom rel animations = </BlendMeshRoot/Mesh/Skel/Anim>
    }

    def RealityKitComponent "AnimationLibrary"
    {
        custom rel animations = </BlendMeshRoot/Mesh/Skel/Anim>
        custom token info:id = "RealityKit.AnimationLibrary"
        custom double realitykit:approximateDuration = 2
        custom double[] realitykit:clipDurations = [2]
        custom string[] realitykit:clipNames = ["Anim"]
        custom rel realitykit:clipTargets = </BlendMeshRoot/Mesh/Skel/Anim>
        custom double realitykit:frameRate = 24
        custom bool realitykit:isAnimationLibrary = 1
    }
}
  

Multiple-frames BlendShape (failed) Animation in Reality Composer Pro
 
 
Q