Using Morph resources

Use the Morph resource to morph between morph targets through a seamless transition.

Kanzi uses shaders to enable morphing. See Shaders.

Before you can morph between meshes in Kanzi you need to create the 3D models in a third-party tool and import them to Kanzi Studio.

When you create in your third-party tool meshes between which you want to morph, first create the base mesh and then from that mesh shape the mesh to which you want to morph. When creating the meshes keep in mind:

  • All meshes must have the same amount of vertices and clusters.

  • Do not change the topology of meshes.

Morphing meshes

To morph meshes:

  1. In the Assets click Import Assets and import the 3D model which uses morph mesh with morph targets between which you want to morph.

    After Kanzi Studio imports the 3D model to your project, it adds:

    • In the Library > Meshes the meshes from the 3D model and a Morph resource which uses the imported meshes.

    • In the Prefabs a Scene prefab which contains the nodes that use the Morph and Mesh resources.

      Kanzi Studio sets the Material property of the imported Model nodes which use Morph resources to a material which supports morphing.

    For example, import a 3D model which includes a morph called Morph_Warning_Start, and meshes Warning_Middle, Warning_Start, and Warning_Ready.

    ../../_images/assets-import-assets8.png ../../_images/morph-and-meshes.png ../../_images/imported-meshes-in-prefabs.png
  2. In the Prefabs copy the Model node which uses the Morph resource and in the Node Tree paste it to the node where you want to add the morph.

    For example, in the Prefabs copy the Warning_Start node and in the Node Tree paste it to the Scene node.

    ../../_images/warning_start-in-library.png
  3. In the Properties in the Morph Target Weights property adjust the weight for each of the Mesh items in the Morph resource to control the shape of the Morph.

    The higher the value, the closer the Morph takes the shape of that mesh. The Kanzi morph shader sets the weight of the base morph shape so that the sum of the Morph Target Weights is kept at 1, which makes the scale of the resulting shape stay true to the target shapes.

    For example, to change the shape of a morph, use a keyframe animation. See Creating a morph weight animation.

    ../../_images/morph-adjusting-weights.gif

Adding meshes to a Morph

Add meshes to a Morph to add shapes between which you want to morph. For the morphing to work correctly add only meshes that are shaped from the same base mesh and have the same topology and amount of vertices and clusters.

To add meshes to a Morph:

  1. In the Library > Meshes create or select a Morph.

    For example, select Morph_Warning_Start.

    ../../_images/morph-and-meshes.png
  2. In the Properties in the Morph Target Weights property:

    1. Click Add and in the dropdown menu select the mesh you want to add to the Morph.

      ../../_images/morph-targets-add.png ../../_images/set-morph-targets.png
    2. Adjust the weights of the morph targets.

      The higher the value, the closer the Morph takes the shape of that mesh. The Kanzi morph shader sets the weight of the base morph shape so that the sum of the Morph Target Weights is kept at 1, which makes the scale of the resulting shape stay true to the target shapes.

      ../../_images/set-morph-target-weight.png

Creating a morph weight animation

Use keyframe animations to change the shape of a morph. You can import the morph weight animation from fbx or glTF files, or create the animation in Kanzi Studio.

To create a morph weight animation in Kanzi Studio:

  1. In the Library press Alt and right-click Animations and create an Animation Clip.

    For example, name it Morph Animation Clip.

    You use the Animation Clip to host keyframe animations for the meshes in your morph. Each animation targets a specific mesh in the morph and defines the weight of the mesh at different points in time.

    ../../_images/create-animation-clip.png
  2. In the Library > Animations select the animation clip you created in the previous step and create a keyframe animation for the first mesh you want to morph.

    For example, name the animation Middle Animation and in the Properties set:

    • Target Property to <Expression>, click image0 to add the Morph Weight property, and set it to <MorphWeight>[1]

    • Property Field to Whole property

    ../../_images/create-morph-animation.png ../../_images/middle-animation-target-property-add-morph-weight-adding.png ../../_images/middle-animation-properties.png
  3. Repeat the previous step as many times as there are target shapes in the Morph that you want to animate, and for each animation in the <MorphWeight>[n] set the n to the mesh in the Morph the weight of which you want change with the animation. Do not add an animation for the base mesh.

    For example, to animate a morph with three meshes, create two animations, name them Middle Animation and Ready Animation, and set:

    • Middle Animation Target Property to <Expression> <MorphWeight>[1]

    • Ready Animation Target Property to <Expression> <MorphWeight>[2]

    You use Middle Animation to set the weight of the second mesh in your morph and Ready Animation to set the weight of the third mesh in your morph at different points in time. The Kanzi morph shader sets the weight of the first mesh.

    ../../_images/morph-animations-in-the-library.png ../../_images/middle-animation-properties.png ../../_images/ready-animation-properties.png
  4. Create keyframes for the animations you created in the previous step. See Creating keyframe animations for target property fields.

    You use the keyframe values to set the Weight properties of the meshes in the morph at different points in time. The higher the value, the closer the Morph takes the shape of that mesh. The Kanzi morph shader sets the weight of the base morph shape so that the sum of the Morph Target Weights is kept at 1, which makes the scale of the resulting shape stay true to the target shapes.

    For example, to create a one-second linear animation of a morph with three meshes, use these keyframes:

    • Middle Animation:

      • First keyframe:

        • Time to 0

        • Value to 0

      • Second keyframe:

        • Time to 0,5

        • Value to 1

      • Third keyframe:

        • Time to 1

        • Value to 0

      ../../_images/middle-animation-in-animation-clip-editor.png
    • Ready Animation:

      • First keyframe:

        • Time to 0,5

        • Value to 0

      • Second keyframe:

        • Time to 1

        • Value to 1

      ../../_images/ready-animation-in-animation-clip-editor.png
    ../../_images/morph-animation-clip-in-animation-clip-editor.png
  5. Animate the morph with the keyframe animations that you created:

    1. In the Node Tree select the Model node the Mesh property of which is set to the Morph you want to animate. See Morphing meshes.

      ../../_images/model-in-the-project.png ../../_images/set-model-mesh-property.png
    2. In the Node Components > Animation section press Alt and right-click Animation and select Animation Player.

      ../../_images/triggers-add-animation-player3.png
    3. In the Node Components in the Animation Player that you created set the Target Animation Timeline property to the Animation Clip that you created in the first step, and set the animation playback. See Playing keyframe animations.

      For example, set:

      • Autoplay Enabled to enabled

      • Playback Mode to Ping pong

      • Repeat Count Infinite to enabled

      ../../_images/animation-player-target-animation-timeline-morph-animation-clip.png ../../_images/morph-animation.gif

Using morphs in the API

To manually create a morph timeline and create a playback for timeline clock:

// Create morph and add meshes (created beforehand) into it.
MorphSharedPtr morph = Morph::create(domain, "testMorph");
morph->add(mesh1, 0.0f);
morph->add(mesh2, 1.0f);

// Add node that will hold the morph, then add it to the scene graph (scene).
Model3DSharedPtr model = Model3D::create(domain, "testSphere");
model->setMesh(morph);
scene->addChild(model);

// Create float animation and add two keyframes.
FloatKeyframeAnimationSharedPtr animation = FloatKeyframeAnimation::create(domain);
animation->addLinearKeyframe(chrono::milliseconds(0), 0.0f);
animation->addLinearKeyframe(chrono::milliseconds(100), 1.0f);

// Create timeline and playback.
MorphWeightTimelineSharedPtr morphTimeline = MorphWeightTimeline::create(domain, "testSphere", 1, animation);
SceneGraphTimelinePlaybackContext context(*scene);
TimelinePlaybackSharedPtr playback = morphTimeline->createPlayback(context);

// Add playback to root clock
domain->getRootTimelineClock()->addTimelinePlayback(playback);

For details, see the Morph class in the Kanzi Engine API reference.