Template Engine

The Ventuz Template Engine extends the capabilities of the AnimationState Logic to make it more suitable for certain kinds of applications. As the name indicates, it is built for creating graphical templates which can be easily populated with dynamic data and/or customized on the fly. Examples for this could be slide-show style presentations or broadcast on-air graphics.

There are a number of functionalities that are combined in the Template Engine:

Auto-routing between states

Ventuz can automatically perform pathfinding inside the State Engine to find a path to a given state. So rather then performing a chain of trigger events, all one needs to do is tell Ventuz which template to arrive at and the pathfinding will figure out how to get there. This also is possible between multiple templates, animation nodes or even scenes. Essentially it allows for Ventuz to find a transition between any two templates without the need for complex transition tables.

Relationships between Templates

The Ventuz Template Engine allows for the definition of relationships between templates in terms of concurrency, dependency or independency. For example, you can determine whether two templates can exist at the same time, or whether they are mutually exclusive. Thus, a fullscreen graphic might not be allowed to co-exist with another fullscreen graphic, but two smaller graphics in different screen spaces might be.

Templates

A Template is an entity that describes both a logical and visual part that can be activated in conjunction with its corresponding data population. Every scene automatically defines a Scene Template, which represents the scene without any dynamic data defined for it. All other templates in the scene are defined by Present States of an animation logic and are usually associated with some amount of dynamic data. All Templates defined by a scene are organized in a hierarchical order that also declares their relationship between each other (Concurrency, Dependency, Independency).
Templates are always organized in so called Template Hosts. Template hosts are organized in a host-tree where each host has exactly one parent host (except the root) and has one or multiple sub-hosts.

Relationships

Every Template defines which templates of a direct sub-host are allowed as a sub-template. This definition creates the template-dependency.

Template Hosts

Ventuz manages 3 different types of template hosts:

Project Templates

If the template engine is used Scene-comprehensively, it defines the root of the host-tree. For every scene that is injected into the project template host one Template is defined. So all scenes managed by this host are concurrent: there's none or one scene active at a time.

Scene Templates

Every scene defines exactly one single template that describes the Scene Template even if the user did not explicitly define such a template (in that case the scene template has no DataModel. Every template defined in the project host has a direct dependency to its corresponding scene template host. These templates do not define any data and are not addressable by the user. They are of type System Template since they are only required by the system (the template engine).

Scene Template hosts can only be parented by a Project Template host. A Scene Template Host can also act as a root (without parent) if the template engine runs only on one single scene and is never asked to switch between scenes.

Animation Templates

The Present States of an State Logic declare the actual templates and their dependency to sub-templates. An Animation Template Host can have another Animation Template Host or the Scene Template Host as its parent.

Therefore user defined template-nesting is only possible below scene-level.



Animation Groups

Multiple Animation nodes can be grouped into one or multiple nested Animation Groups. All templates defined in all animations within a group-tree are treated as concurrent as if they were defined by a single Animation Node. This grouping technique increases the usability since technically independent animations can be combined into one logical animation host if the actual templates shall behave concurrently. A template host that is defined by an animation group is the only host that can have multiple DataModels and is therefore restricted in some functionality.


Every Template of the entire system defines the dependent sub-hosts. This is either done automatically (system-templates) or manually via the DataModel. Only templates defined in a Template Host that is linked in the host-tree are accessible. Unlinked elements are currently useless. In order to link a template host into the system, the user has to either inject the scene into the project template host (programmatically) or add the animation to the DataModel of the parent host which can be the SceneData or the DataModel of another animation node, see Project and Scene Data.

DataModel

A DataModel defines the structure, names and types of the data required for the hosted templates. Every template within a host selects a subset of one of these data models. This subset could be empty or the entire data model. Every Template Host defines zero, one or multiple DataModels. A template host defines its default DataModel where grouped animations do not have a default DataModel.

The data model can be created and accessed via the Data View of the animation editor window. As we saw above, this is also where Subtemplates are added and controlled.

To add a data item, simply drag and drop the property to be controlled as animation data into the animation data panel. It will be added in a similar fashion to a scene data or project data element, except that each data element can be associated or disassociated with any of the templates of that animation node. The data panel lists all of the data items for the templates in an animation node and a column layout allowing for every item to be checked or unchecked for each template. By checking the item, the data will be associated with that template. Thus it is possible to have quite complex data models where some data items are shared between templates and others are not.


Each element should be given a unique name, and by clicking on it, you can also edit, in the properties panel, settings such as default value, allowable minimum and maximum values, a label for operator identification, or a description. Remember that as soon as you set up a data channel, any local value you had set will be overridden by the animation data, so it is worth setting up a default value first.


An important key to transitions is the exact point when this data, associated with a template, is passed to the animation node. So, for example, if a self-to-self transition is called, but the data changes, perhaps an animation is desired where the data is changed at a specific moment, but the actual template changes very little. The exact transfer point for the data can be defined in the timeline by positioning a data marker. To place this marker, enter the animation editor window and position the timeline at the point where the data should be transferred, then press M. It will add a small marker at the top of the animation timeline. This marker can be moved, as its properties edited by dragging or selecting it. Multiple markers are allowable, in which case data will be updated on the first marker that is passed and subsequent markers ignored unless the data has changed.


Grouped animations define the name of their DataModels by combining all names of the Animation Group and Animation Nodes together where the root-group is not part of that name. Multiple name segments are separated with an underscore character "_".

The name of a default DataModel is the empty string "".


Example: The names of the three DataModels defined by group (Group1) that contains one animation (Animation1) and another group (Group2) that again contains two more animations (Animation2 and Animation3):

Animation1
Group2_Animation2
Group2_Animation3

DataItems

A DataModel defines a list of DataItems. The following types of DataItems exist:

Name C# Type Modes Description Attributes
Animation - - The Animation item defines a field that addresses a possible sub-template. The actual value of this field is null or a data instance (TemplateData) of a sub-template. Required
Trigger - RW A Trigger can be either an asynchronous event sent out to the remote client (R), a trigger sent from the remote client to Ventuz (W) or both (RW).
Group - (RW) A Group contains multiple sub-DataItems and acts like a folder. The mode is the sum of all sub-items only defines if the items below are readable and/or writable. The group itself has no value.
Float float RW A floating point value Default, Min, Max, Speed
Integer int RW An integer value Default, Min, Max, Speed
Boolean bool RW A boolean value Default
String string RW A string value Default, MaxLines, MinLines
Enum string RW A string value of type that matches the values of an enumeration. The possible values are define in the field Elements. Default, Elements
Color Color RW A color value Default, Alpha
Asset Uri RW A general Uri value that addresses one or multiple asset pools AssetPools
FloatArray float[] RW An array of float values Default, MinLength, MaxLength
IntegerArray float[] RW An array of integer values Default, MinLength, MaxLength
BooleanArray bool[] RW An array of boolean values Default, MinLength, MaxLength
ByteArray byte[] RW An array of byte values Default, MinLength, MaxLength
StringArray string[] RW An array of string values Default, MinLength, MaxLength

Attributes of DataItems

Name C# Type Description
Name string Defines the technical name of the DataItem
Label string Contains the label text how the DataItem should be presented to the user.
Description string Contains a short description of the DataItem
Required bool Defines if a sub-template must be assigned (true) or not (false)
Default item type Default value of the DataItem
Min/Max item type Minimum and maximum value of the DataItem
Speed item type Edit speed of the DataItem
Min/MaxLines uint Minimum and maximum number of text lines for the DataItem
Elements string[] List of valid elements to fill the DataItem
Alpha bool True if the color requires the alpha component
AssetPools AssetPool Asset pools of the DataItem
Min/MaxLength uint Minimum and maximum number of elements in the array
UserData string A user-defined general purpose string.

Addressing Templates

The Ventuz Template Engine is not only available in the given workflow with the Ventuz Director but can be integrated in almost every system by the Ventuz Remoting API. Therefor the following section describes the Template address structure.


Examples:

.Text1
Animation1/Template1.Line1.Text
Animation1/Template1.Line1.Color
Animation1/Animation2/$Group2.Headline.Text

Data Formats

In order to store and transfer a complete set of data, we plan to integrate multiple different data formats for being compatible to different platforms and integrators:

Ventuz 4 supports three different data formats: XML, JSON and BIN. all of these formats are 100% compatible to each other and the user can decide which format he wants to use. All three formats are text based and the receiver (Ventuz) can easily decide which parser to user. It simply looks to the first non-whitespace character: "<" for XML, "{" for JSON and any other for base64-BIN

The JavaScript Object Notation (JSON.org) has some advantages and disadvantages compared to XML:

The BINary format is always expressed in base64 encoding in order to ensure that a simple text can be used to store the data. Handling 'real' binary data sometimes become complicated. So we accept the base64 overhead of 33% (3 bytes -> 4 bytes).

Examples for all three formats. The three instance contain exactly the same information. The BIN format has the smallest size but is not human-readable anymore. Ventuz Director is using the BIN format to transfer data to the Ventuz Renderer, but XML and/or JSON to store data instance on disk.

XML

<VTD ns="ventuz://templates/ingame/Scene">
  <LowerThird_Center ns="ventuz://templates/ingame/LowerThird_Center/NS2LAdd">
    <FirstLine>First Line</FirstLine>
    <FirstAdd>Addon Text</FirstAdd>
    <SecondLine>Second Line</SecondLine>
    <Visual01>ventuz://scenes/Assets/logos/FrankfurtSnakes.vzs</Visual01>
    <Visual02>ventuz://images/Assets/sponsorlogos/HH.png</Visual02>
  </LowerThird_Center>
  <UpperThird ns="ventuz://templates/ingame/UpperThird/Scoreboard">
    <Banner ns="ventuz://templates/ingame/UpperThird/Scoreboard_Banner/Banner2LAdd">
      <FistLine>First Line</FistLine>
      <FirstAdd>Addon Text</FirstAdd>
      <SecondLine>Second Line</SecondLine>
      <Visual>ventuz://scenes/Assets/logos/HP.vzs</Visual>
    </Banner>
  </UpperThird>
</VTD>

JSON

{
	"@": "ventuz://templates/ingame/Scene",
	"LowerThird_Center": {
		"@": "ventuz://templates/ingame/LowerThird_Center/NS2LAdd",
		"FirstLine": "First Line",
		"FirstAdd": "Addon Text",
		"SecondLine": "Second Line",
		"Visual01": "ventuz://scenes/Assets/logos/FrankfurtSnakes.vzs",
		"Visual02": "ventuz://images/Assets/sponsorlogos/HH.png"
	},
	"UpperThird": {
		"@": "ventuz://templates/ingame/UpperThird/Scoreboard",
		"Banner": {
			"@": "ventuz://templates/ingame/UpperThird/Scoreboard_Banner/Banner2LAdd",
			"FistLine": "First Line",
			"FirstAdd": "Addon Text",
			"SecondLine": "Second Line",
			"Visual": "ventuz://scenes/Assets/logos/HP.vzs"
		}
	}
}

BIN

VlREMSAfdmVudHV6Oi8vdGVtcGxhdGVzL2luZ2FtZS9TY2VuZaARTG93ZXJUaGly
ZF9DZW50ZXIgM3ZlbnR1ejovL3RlbXBsYXRlcy9pbmdhbWUvTG93ZXJUaGlyZF9D
ZW50ZXIvTlMyTEFkZGEKRmlyc3QgTGluZQlGaXJzdExpbmVhCkFkZG9uIFRleHQI
Rmlyc3RBZGRhC1NlY29uZCBMaW5lClNlY29uZExpbmVhMHZlbnR1ejovL3NjZW5l
cy9Bc3NldHMvbG9nb3MvRnJhbmtmdXJ0U25ha2VzLnZ6cwhWaXN1YWwwMWEqdmVu
dHV6Oi8vaW1hZ2VzL0Fzc2V0cy9zcG9uc29ybG9nb3MvSEgucG5nCFZpc3VhbDAy
/6AKVXBwZXJUaGlyZCAvdmVudHV6Oi8vdGVtcGxhdGVzL2luZ2FtZS9VcHBlclRo
aXJkL1Njb3JlYm9hcmSgBkJhbm5lciBCdmVudHV6Oi8vdGVtcGxhdGVzL2luZ2Ft
ZS9VcHBlclRoaXJkL1Njb3JlYm9hcmRfQmFubmVyL0Jhbm5lcjJMQWRkYQpGaXJz
dCBMaW5lCEZpc3RMaW5lYQpBZGRvbiBUZXh0CEZpcnN0QWRkYQtTZWNvbmQgTGlu
ZQpTZWNvbmRMaW5lYSN2ZW50dXo6Ly9zY2VuZXMvQXNzZXRzL2xvZ29zL0hQLnZ6
cwZWaXN1YWz/////