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.
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.
Ventuz manages 3 different types of template hosts:
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.
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.
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.
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.
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
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 |
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) |
Choices | string[] | Optional predefined choices for that string |
Default | item type | Default value of the DataItem |
Format | string | Specifies a format string for automatically created template data description |
Min/Max | item type | Minimum and maximum value of the DataItem |
RegEx | string | If specified, the string must match this regular expression |
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 |
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.
ventuz://templates
ventuz://templates/
ventuz://templates/<sceneidentity>/Examples:
ventuz://templates/scene1/ ventuz://templates/scene2/ ventuz://templates/folder|scene3/
Please note that the Project Template Host does not have a name! Therefore the first path segment after the base uri is always the name of the Scene Template Host regardless if the scene host is parented in a project host or not!
Two scenes saved as .\Scenes\Folder\Scene1.vzs and .\Scenes\Folder_Scene1.vzs would result in an identical Uri address for their template hosts: ventuz://templates/folder_scene3/. Injecting these two scenes into a project template host will cause an error to be thrown!
ventuz://templates/<sceneidentity>/<AnimationDataItem>/ ventuz://templates/<sceneidentity>/<AnimationDataItem>/<AnimationDataItem>/.../Examples:
ventuz://templates/scene1/Animation1/ ventuz://templates/scene1/DataGroup.Animation.DataItem/ ventuz://templates/folder|scene3/DataGroup.Animation.DataItem/ ventuz://templates/folder|scene3/DataGroup.Animation.DataItem/DataGroup.DataItem/
Two Animations bound to a DataModel as /DataGroup/Animation1 /DataGroup_Animation1 would result in an identical name for their sub template hosts: ventuz://templates/scene1/DataGroup_Animation1/. The Scene Model Validator will cause an error to be thrown!
ventuz://templates/<scene_identity>/Scene ventuz://templates/<scene_identity>/<Animation_DataItem>/<TemplateName>Examples:
ventuz://templates/scene1/Animation1/Template1 ventuz://templates/scene1/Animation1/Template2 ventuz://templates/scene1/Animation1/Animation2/Template3
The Scene Template has always the reserved name "Scene". This name cannot be changed by the user. Other Scene template may be added in the future (Global, Constant, etc
All templates defined in a template host must be unique. If multiple Animation Nodes are grouped all Present States must have a unique name across all animations within that group. Otherwise an error will be thrown.
".group.group.item"
"$DataModelname.group.group.item"
"TemplateName.group.group.item"
Examples:
.Text1 Animation1/Template1.Line1.Text Animation1/Template1.Line1.Color Animation1/Animation2/$Group2.Headline.Text
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 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.
<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>
{ "@": "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" } } }
VlREMSAfdmVudHV6Oi8vdGVtcGxhdGVzL2luZ2FtZS9TY2VuZaARTG93ZXJUaGly ZF9DZW50ZXIgM3ZlbnR1ejovL3RlbXBsYXRlcy9pbmdhbWUvTG93ZXJUaGlyZF9D ZW50ZXIvTlMyTEFkZGEKRmlyc3QgTGluZQlGaXJzdExpbmVhCkFkZG9uIFRleHQI Rmlyc3RBZGRhC1NlY29uZCBMaW5lClNlY29uZExpbmVhMHZlbnR1ejovL3NjZW5l cy9Bc3NldHMvbG9nb3MvRnJhbmtmdXJ0U25ha2VzLnZ6cwhWaXN1YWwwMWEqdmVu dHV6Oi8vaW1hZ2VzL0Fzc2V0cy9zcG9uc29ybG9nb3MvSEgucG5nCFZpc3VhbDAy /6AKVXBwZXJUaGlyZCAvdmVudHV6Oi8vdGVtcGxhdGVzL2luZ2FtZS9VcHBlclRo aXJkL1Njb3JlYm9hcmSgBkJhbm5lciBCdmVudHV6Oi8vdGVtcGxhdGVzL2luZ2Ft ZS9VcHBlclRoaXJkL1Njb3JlYm9hcmRfQmFubmVyL0Jhbm5lcjJMQWRkYQpGaXJz dCBMaW5lCEZpc3RMaW5lYQpBZGRvbiBUZXh0CEZpcnN0QWRkYQtTZWNvbmQgTGlu ZQpTZWNvbmRMaW5lYSN2ZW50dXo6Ly9zY2VuZXMvQXNzZXRzL2xvZ29zL0hQLnZ6 cwZWaXN1YWz/////