Kanzi 3.9.3 migration guide

Use this migration guide to update Kanzi applications from Kanzi 3.9.2 to Kanzi 3.9.3.

Changes in render passes

  • Moved the CameraProperty from DrawObjectsRenderPass to RenderPass.

    This enables you to set in any render pass the Camera node that the render pass and its descendants use to render content.

  • Changed the profile of renderOverride() for render passes to void renderOverride(Renderer3D& renderer, CompositionStack& compositionStack, const CameraSettings* cameraSettings).

    Unless a RenderPass specialization wants to alter the camera settings, it passes the pointer down to child render pass rendering as is. The pointer can be nullptr.

    When you implement custom rendering that modifies the camera settings, construct a local CameraSettings from stack by copying from the passed parameter.

  • Introduced virtual void renderChildrenOverride(Renderer3D& renderer, CompositionStack& compositionStack, const CameraSettings* cameraSettings) for render passes.

    This function controls how to render the children of a render pass. Typical specializations of RenderPass do not need to override it.

Changes in Java API

  • When you define a message type, you must now specify an associated message argument class. Accordingly, when you dispatch or handle a message, you must use the message argument class associated with the message type.

    Kanzi Studio uses this association to give you a list of properties that you can set to or get from the arguments of a message.

    Message argument classes must now derive from the MessageArguments class and provide a constructor of fixed signature:

    • Change your message type and message argument definitions from

      @Metadata
      public static final MessageType XMessage = new MessageType("Message.X", MessageRouting.MessageRoutingBubbling);
      
      @Metadata
      public interface XMessageArguments
      {
          @Metadata
          public static PropertyType<Integer> SomeProperty = new PropertyType<>(Integer.class);
      }
      

      to

      @Metadata
      public static final MessageType<XMessageArguments> XMessage = new MessageType<>("Message.X", MessageRouting.MessageRoutingBubbling, XMessageArguments.class);
      
      @Metadata
      public class XMessageArguments extends MessageArguments
      {
          // A constructor with a long argument that Kanzi uses to wrap native arguments.
          public XMessageArguments(long nativeObject)
          {
             super(nativeObject);
          }
      
          // Any additional constructors for you to use when dispatching messages.
          public XMessageArguments()
          {
             super();
          }
      
          @Metadata
          public static PropertyType<Integer> SomeProperty = new PropertyType<>(Integer.class);
          // Accessors for properties.
          public Integer getSomeProperty()
          {
                return getArgument(SomeProperty);
          }
          public void setSomeProperty(Integer value)
          {
                setArgument(SomeProperty, value);
          }
      }
      
    • Change your message dispatch call from

      MessageArguments args = new MessageArguments();
      args.setArgument(XMessageArguments.SomeProperty, 1);
      node.dispatchMessage(XMessageArguments, args);
      

      to

      XMessageArguments args = new XMessageArguments();
      args.setSomeProperty(1);
      node.dispatchMessage(XMessageArguments, args);
      
    • Change your message handlers from

      node.addMessageHandler(XMessage, messageArguments -> {
          Integer someProperty = messageArguments.getArgument(XMessageArguments.SomeProperty);
      });
      

      to

      node.addMessageHandler(XMessage, messageArguments -> {
          Integer someProperty = messageArguments.getSomeProperty();
      });
      

    You do not have to define your own message argument class. Instead, you can use the base class MessageArguments in all of the above cases. Also, defining accessors for properties is only for convenience purposes. You can still use the the generic argument setter and setter.

    See Using messages and Creating a custom type.

  • Metaclass interfaces iteratePropertyTypes() and iterateMessageTypes() now return iterables over AbstractPropertyType and AbstractMessageType respectively.

  • Changed the type of resource id argument on these Node interfaces from String to ResourceID:

    • addResource

    • removeResource

    • containsResource

    • findResourceUrl

    • acquireResource

    • tryAcquireResource

    • acquireResourcesAsync

    Change from:

    node.acquireResource("resource id");
    

    to:

    node.acquireResource(new ResourceID("resource id"));
    

Changes to Android application templates

Android application templates now support addition of Java Code Behind from Kanzi Studio. To use the Code Behind features in Kanzi Studio, you must migrate your existing applications that are based on the old templates.

A known issue in Kanzi Studio requires that the package of an Android application that uses Java Code Behind features must remain com.example.<ProjectName>.

To migrate your Kanzi application to use the updated template:

  1. In Kanzi Studio, open your project. In the main menu, select Project > Properties and in the Properties set the Java Project property to enabled.

    ../../_images/properties-project-java-project.png
  2. Save the project and restart Kanzi Studio.

  3. In your application package directory, create the KanziGenerated.java file and add to the file the code below.

    For example, create this file in the <ProjectName>/Application/configs/platforms/android_gradle/app/src/main/java/com/example/<ProjectName> directory.

    // GENERATED FILE. DO NOT EDIT.
    
    package com.example.<ProjectName>;
    
    import com.rightware.kanzi.Domain;
    
    // [Plugin imports]
    
    public class KanziGenerated {
    
    static void registerPlugins(Domain domain) {
    
    // [Plugin registrations]
    }
    
    }
    
  4. During the initialization of your activities or the attachment of your Kanzi views, call KanziGenerated.registerPlugins(domain).

To learn more about KanziGenerated.java, see Using Kanzi Studio generated plugins.

Changes in class metadata

  • Renamed the PropertyTargetEasingInterpolator metaclass to Kanzi.PropertyTargetEasingInterpolator.

  • Renamed the PropertyTargetEasingInterpolator.SetEnabledMessageArguments MessageArgument metaclass to Kanzi.PropertyTargetEasingInterpolator.SetEnabledMessageArguments.

  • Renamed these StateManager MessageArgument metaclasses:

    Kanzi 3.9.2

    Kanzi 3.9.3

    Message.StateManagerMessageArguments

    Kanzi.StateManager.StateManagerMessageArguments

    Message.StateManagerStateChangeMessageArguments

    Kanzi.StateManager.StateChangeMessageArguments

    Message.StateManagerGoToStateMessageArguments

    Kanzi.StateManager.GoToStateMessageArguments

    Message.StateManagerGoToDefinedStateMessageArguments

    Kanzi.StateManager.GoToDefinedStateMessageArguments

    Message.StateManagerGoToNextDefinedStateMessageArguments

    Kanzi.StateManager.GoToNextDefinedStateMessageArguments

    Message.StateManagerGoToPreviousDefinedStateMessageArguments

    Kanzi.StateManager.GoToPreviousDefinedStateMessageArguments

    Message.StateManagerEnteredStateMessageArguments

    Kanzi.StateManager.EnteredStateMessageArguments

    Message.StateManagerLeftStateMessageArguments

    Kanzi.StateManager.LeftStateMessageArguments

    Message.StateManagerTransitionMessageArguments

    Kanzi.StateManager.TransitionMessageArguments

    Message.StateManagerTransitionStartedMessageArguments

    Kanzi.StateManager.TransitionStartedMessageArguments

    Message.StateManagerTransitionFinishedMessageArguments

    Kanzi.StateManager.TransitionFinishedMessageArguments

  • Renamed these ValueAccumulator MessageArgument metaclasses:

    Kanzi 3.9.2

    Kanzi 3.9.3

    FloatValueAccumulator.SetAccumulatedValueBoundariesMessageArguments

    Kanzi.FloatValueAccumulator.SetAccumulatedValueBoundariesMessageArguments

    IntValueAccumulator.SetAccumulatedValueBoundariesMessageArguments

    Kanzi.IntValueAccumulator.SetAccumulatedValueBoundariesMessageArguments

    ValueAccumulator.StartMessageArguments

    Kanzi.ValueAccumulator.StartMessageArguments

    ValueAccumulator.StopMessageArguments

    Kanzi.ValueAccumulator.StopMessageArguments

    ValueAccumulator.PauseMessageArguments

    Kanzi.ValueAccumulator.PauseMessageArguments

    ValueAccumulator.ResumeMessageArguments

    Kanzi.ValueAccumulator.ResumeMessageArguments

Changes for skinned meshes

To enable multiple nodes to use the same skinned mesh, Kanzi now stores the runtime data of skinned meshes in Model3D instead of Mesh. To make this possible, made these changes to the Mesh API:

  • Removed these skinned mesh accessors:

    • Mesh::getBoneCount() > size_t

    • Mesh::getBoneNode(size_t) > Node3D*

    • Mesh::getBoneChildJoint(size_t) > Node3D*

  • Added these skinned mesh accessors:

    • Mesh::getSkeleton > Mesh::Skeleton

    • Model3D::getSkeletonRuntime > Mesh::Skeleton

  • Changed these function signatures:

    Kanzi 3.9.2

    Kanzi 3.9.3

    Mesh::updateBoundingBox(Node3D*)

    Mesh::updateSkeletonTransformation(Model3D&)

    Mesh::attach(Node*)

    Mesh::attachSkeleton(Model3D*)

    Mesh::detach(Node*)

    Mesh::detachSkeleton(Model3D*)

Changes for mesh data access

Kanzi now supports 32-bit indices in meshes. The improvement introduces these changes in the Mesh API:

  • Changed these function signatures:

    Kanzi 3.9.2

    Kanzi 3.9.3

    void* Mesh::getVertexData(size_t)

    span<const byte> Mesh::getVertexData(size_t)

    uint16_t* Mesh::getClusterIndexData(size_t)

    span<const byte> Mesh::getClusterIndexData(size_t)

  • Added Mesh::getClusterIndexType() for checking the index type of a mesh cluster.

Changes to the morph shader

The morph shader now calculates the weight for the base morph. To apply this change to a project that uses the old morph shader:

  1. In the Library > Materials and Textures > Material Types delete the morph material type that you want to update.

    For example, if you use the VertexPhongMorph material type, delete that material type.

    ../../_images/morph-delete-material.png
  2. In the Library > Materials and Textures press Alt and right-click Material Types and import the morph material type that you want to use.

    For example, import the VertexPhongMorph material type.

    ../../_images/morph-import-material.png
  3. In the Library > Materials and Textures > Materials select the material that you used with the old morph shader material type and in the Properties set the Material Type property to the morph material that you imported in the previous step.

    ../../_images/morph-material-library.png ../../_images/morph-material-properties.png
  4. In the Library > Materials and Textures > Materials delete the morph material that Kanzi Studio creates automatically when it imports a material type.

    ../../_images/morph-delete-auto-material.png

Changes in the application.cfg error handling

If Kanzi encounters an error when parsing a application.cfg configuration file or that file is missing, Kanzi logs an error message and no longer throws an exception.

If you are building a fault-tolerant application, in the event of a corrupted or missing application.cfg file, you no longer have to simultaneously parse the log output for the missing file and catch the exception for the corrupted file. You only have to parse the application log output to detect both a missing and a corrupted application.cfg file.

See Error handling for application.cfg.

Kanzi Studio plugins

Kanzi Studio now uses .NET Framework 4.8. To migrate your Kanzi Studio plugin, in the Visual Studio project of your plugin update the target framework version to 4.8.