Virtalis Reach Help

Virtalis Reach User Guide

This document has 4 chapters.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.


This document is designed to assist Virtalis Reach users to get started and make use of the platform for the first time.Virtalis Reach is a cloud-compatible eXtended Reality (XR) platform used to create, transform and publish securely to the web for any user context. Authorised users can utilise visualisations securely by simply opening a link to a controlled platform on the web. No specialist hardware is required and there is no need to pre-install any software executable or license key.With Virtalis Reach you can: Create complex, audience specific visualisationsCreate context-specific, reusable templates that can be applied automatically, allowing you to repurpose your digital assetsInvite colleagues, partners and customers to collaborative sessions by simply sharing a linkIntegrate with PLM systems to automate the publication of updated visualisationsUse our API to automatically build complex scenes or integrate with your broader IT landscapePut visualisation at the heart of effective operations, from global distribution to automated pipelines and templates for visualisation creationVirtalis Reach Hub and Edge Servers OverviewPlease note: This section provides a high-level overview only. For more detailed information, please refer to the relevant server-specific guides.A Virtalis Reach Hub is where publishers and scene authors can upload assets, configure projects and publish visualisations to the Virtalis Reach Edge. Assets are translations of data that were uploaded to the Virtalis Reach Hub or ingested by automatic processes such as PLM integrations.A Virtalis Reach Edge is where all users access visualisations to view them. 
Read more

Sign In to Virtalis Reach

Sign inSign in to the Virtalis Reach Server using a web browser to access the URL. Use the username and password supplied by your administrator for Virtalis Reach. Depending on your configuration, you may also be able to use a single sign in.Enter your username and password and click Sign In. The Visualisations page will open, which displays the visualisations you can access.Log OutTo Log out, click the user icon (the circle containing your initials) on the right-hand side of the screen and select Log out.export REACH_DOMAIN=<the domain Virtalis Reach will be hosted on>lang=EN-US>export TLS_SECRET_NAME=<the name of the secret containing the tls cert>lang=EN-US>export REACH_NAMESPACE=<name of kubernetes namespace to deploy Virtalis Reach on>lang=EN-US>export ACR_USERNAME=<service principal id>lang=EN-US>export ACR_PASSWORD=<service principal password>lang=EN-US>export reach_licence__key=<licence xml snippet>lang=EN-US>export reach_licence__signature=<licence signature>‍
Read more


This is the Virtalis Reach home page where you use the Virtalis Reach Edge server to view and open all published visualisations you have been granted access to. Each tile represents a visualisation and each visualisation will have a parent project. Visualisations are created by publishing projects in the Virtalis Reach Hub. Refer to The Virtalis Reach Hub and Projects for further information.You can click the Copy Link icon on the lower right of a visualisation tile to copy a link to the visualisation to your clipboard. You can then paste this into an email or chat program. Please note: Only authorised users can use this link.Click a visualisation to open it. A progress bar is displayed while the visualisation is opening.Type image caption here (optional)Once opened, you can double-click a visualisation to view it in full screen mode. Press Esc to exit full screen and return to the original view.Click on the bottom left-hand corner to return to the Visualisations home page.‍NavigationYou can navigate within an open visualisation using a keyboard, mouse or, if using a Head Mounted Display (HMD), by using the controllers.Click the Help icon on the lower right of the screen for navigation and icon information.When selected/active, the tools are highlighted with a yellow background:Immersive ModeSelect the Immersive mode icon to navigate within an open visualisation using a Head Mounted Display (HMD) by using the controllers.Please note: This mode only becomes available when a HMD is connected. Orbit ModeSelect the Orbit mode icon to orbit the origin of the scene (0,0,0).‍Interaction ModesInteraction Modes allow you to use the Virtalis Reach functionality in various ways. ViewClick the View icon ( ) to interact with the scene. This is the default mode when you first open a visualisation.‍Product TreeClick the Product Tree icon ( ) to display the product structure from the asset's original CAD data. ‍‍Click the Select icon ( ) to select assemblies and highlight them in the Product Tree and 3D scene.Expand the Product Tree to display the full product structure and any metadata (if available) associated with a selected assembly. Click the View icon ( ) on the bottom of the screen to close the Product Tree.CommentCreate a CommentClick the Comment icon ( ) to create a new comment thread, review existing comments and add replies. You start a thread at a specific location and then you and your colleagues can add comments to it.Tip: You can add emojis to your comment. For example, in Windows, press Win + period (.) and select the emoji you want to add.Create a ThreadClick the Add new comment icon ( ) and then click on the object in the 3D view that you wish to comment on. A Create Thread pane will open on the right-hand side of the screen. The Title will default to the assembly name in the Product Tree of the object you selected and you can change this if required. Enter your message and click Create Thread to add your comment to the Threads pane on the left-hand side of the screen.You can click the 3D scene outside of the Create Thread pane to cancel.Respond to a CommentYou can use the Comment markers (the location that was selected in the 3D view when the comment was made) and Threads panes to aid with both locating markers and displaying what the comment author was seeing at the time of making the comment. Select a comment in the Threads pane on the left-hand side of the screen to open it in a new pane on the right-hand side of the screen. You can type a response to the comment and click Send to add your comment to the thread.View PerspectiveClick the View perspective link under the comment to navigate the camera position to the same location and orientation the comment author had when they pressed Send. Version HistoryClick the Version History icon ( ) to view the available versions of visualisations. If the visualisation has been updated, the updates will be shown along with the time and date of the update. The different versions can be opened and viewed by clicking Open next to the version.SettingsClick the Settings icon ( ) to set the following:Performance ModeSelect this option to change the target framerate that the renderer attempts to achieve. The default (performance mode off) target is 30Hz (45Hz in XR), and the renderer adjusts the levels of detail it displays based on reaching that performance requirement. When you enable performance mode, it increases this target to 60Hz across the board. What this may mean, for devices that do not have the graphics capability of rendering the current level of detail (LOD) at that frequency, is that the system drops to lower levels of detail until the frame rate stabilizes at 60Hz. For devices that are able to keep up with the faster rendering requirements, the LOD quality may not be reduced.Lighting RigSelect this option to enable or disable a basic scene lighting preset.Movement SpeedDifferent Virtalis Reach scenes can use vastly different scales - from precision parts a few millimeters across to entire processing plants spanning many kilometers. As such, a single movement speed will not be appropriate for all cases. Use the slider to adjust the movement speed. Experimental SettingsVR Snap RotationThe default behaviour when using the controller joystick to rotate is a smooth motion. When you enable VR Snap Rotation, using the joystick will rotate instantly in sharp, set intervals using the angle specified by the Snap Rotation Angle setting.Snap Rotation AngleSelect this option and use the slider to change the rotation angle when you are using snap rotation. Controller Oriented XR MovementSelect this option to base the movement direction on the controller orientation and not the HMD orientation so that when you move with the joystick in XR you move where you are pointing, instead of where you are looking.Select, Show and Hide AssembliesExpand the Product Tree to display the full product structure and any metadata (if available) associated with a selected assembly. Click the Select icon ( ) to select assemblies. The assembly will be highlighted in the Product Tree and 3D scene. You can click the View icon ( ) on the right-hand side of the Product Tree to show and hide assemblies. Fly to an AssemblySelect an assembly in the Product Tree and click the Fly to icon ( ), which will attempt to fit the models of the selected assembly into the field of view of the camera. Share and CollaborateWhen you open a visualisation you create a session. If you and another user both open the same visualisation, you will each create your own independent session. For example, you change the visibility of nodes or trigger animation (and many other things that alter the scene) it will not affect the other user's session. When either user closes their session, it is terminated and the visualisation is unchanged.When you share a session, other users can join and they will see the same virtual world, same visual state, same animations and so on. Everyone in the session can see each participant as avatars and is able to see what each participant has selected as the colour of the highlight will match the helmet colour of the person’s avatar. In the case that more than one person selects a component, the highlight colour will cycle between that of each corresponding avatar.From an open visualisation, click Invite and copy the link to share your session with others. Select Private session to prevent additional colleagues from connecting. This does not disconnect users already in the session.Select Open session to enable other users to join your session.Click Copy to copy the link to the clipboard, then paste into a chat program or email and send it to the group members you want to invite to your session. Provided that the recipient has a valid login and is a member of one of the groups that the visualisation was published for, they will appear in the session with their name shown above their avatar.Click on the bottom left-hand corner to exit the session and return to the Visualisations page.
Read more

The Virtalis Reach Hub & Edge

IntroUse the Virtalis Reach Hub to add and publish new content to a visualisation or project that you have been granted access to. Assets can be uploaded to the server, transformed and optimised. Projects are also created and assets are added to them to create visualisations.You can edit existing and create new Projects and Assets. Access the Virtalis Reach Hub by adding /hub to the Virtalis Reach web address. For example https://reach.domain/hub.Please Note: Only authorised users can access the hub and this is enabled by the server administrator. Once connected, you will see three icons on the left-hand side of the screen. These are, from top to bottom, the Projects, Library and Job Status pages. Click an icon to open the relevant page.ProjectsUse this page to configure how data is processed to create visualisations. You can select and edit a project from the list of available projects you have access to or create a new project. Click a project in the list to open it or click + New project. Refer to Create a New Project for further information.When you open a project, you can use the General, Visualisation, Access and Publication tabs to view and edit the project properties.Click Advanced to view and edit the advanced configuration options for the project.Click Syntax Reference in the advanced project configuration page to display an example project structure and project information requirements. Refer to Appendix A - JSON Template Processor Rules for further information.Click Save changes (if available) or Publish Now when you have finished editing/creating a project.Switch to the Job Status page to view the status of the jobs being processed. Once completed, to open the project click:The project in the Job Status pageThe project in the Projects page to return to the Visualisations pageIf the project was configured to publish when the source data changes, then it will be published when you initially save it.Create a New ProjectFollow the steps outlined below to create a new project.1. Project SettingsFrom the Projects page, click + New project.Enter a project name, select who can edit the project and if you want to allow scripts.When completed, click Next to open the Configure Visualisation page.2. Configure VisualisationUse this page to select and configure the assets to add to the project. Click Add asset to open a list of assets that are available in your Library. Select the asset or assets you want to add to your project. Refer to Import assets for further information. You can add multiple assets, if available, to the project. You can also add custom rules that will apply to the entire project. The rules are specified as JSON and can be used to change the property of any node within the product, for example changing the diffuse value of a specific material or removing nodes from an asset for security reasons. Refer to Appendix A - JSON Template Processor Rules for further information.Once you have selected the asset or assets, click Add.When completed, click Next to open the Share Settings page.3. Share SettingsUse this page to select the groups that can access the published visualisation. These groups are user-specific and have been added by the server administrator. When completed, click Next to open the Ready to Publish page.4. Ready to PublishUse this page to select one of the following publication schedule options from the drop-down list:Manually (default option)Daily at a specific hourWhen the source data changesSelect a publication schedule option and click Save or Save and publish. You can switch to the Job Status page to view the status of your project publication. Once completed, to open the project click:The project in the Job Status pageThe project in the Projects page to return to the Visualisations pageLibraryUse this page to browse all the assets available for use in projects. You can update existing assets or, if no assets are available, click + New asset to upload and add new assets. Import AssetsFollow the steps outlined below to import assets.1. Choose DataUse this page to upload your asset file or folder by dragging it onto the page or click to browse for your file. You can choose Visionary Render data, or, for example, some Siemens or PTC CAD formats. If the model is made up of many parts, select the radio button of the main, or header file. Once selected, the file will automatically begin to upload. When the upload is complete, click Next to open the Configure Access page.2. Configure AccessUse this page to set the groups that can access the visualisation. The groups are system and user specific and have been added by the server administrator.Once configured, click Import. The Ready for Import page will open and display the upload status. Use the Job Status page to view the status of the jobs being processed.3. Ready for ImportUse this page to view the upload status of your asset data import.When the upload is complete and has been processed into an asset, you can switch to the Projects page and add it to your project or create a new project.Job StatusUse this page to view data that has been, or is currently being, processed by Virtalis Reach.Type image caption here (optional)
Read more

Save and Publish Updates

Save and Publish UpdatesYou can create assets in Visionary Render, where you can add materials, textures, animations, event behaviours and so on to improve the scene. Refer to the Visionary Render documentation for further information.Please note: Not all of Visionary Render’s data is supported in Virtalis Reach (for example, some texture features, node types and GUI features such as billboard nodes and custom styling).Once you have finished updating an asset in Visionary Render, save it and return to the Virtalis Reach server hub. Select the Library page and, rather than adding a new asset, update the existing version.Drag and drop the updated file into the Choose Data page and select the file to upload. If the model is made up of many parts, select the radio button of the main, or header file. As the asset may have changed, you need to configure access to the different groups.Because the data has changed, and if you selected to publish your project when the source data changes when you configured the project, all projects that include this asset will publish new versions of their visualisations.If you did not select that option, you must publish the updates manually or wait for the scheduled updates to be performed.Switch to the Job Status page to view the status of the jobs being processed.Refer to Import Assets and Create a New Project for further information.
Read more

Appendix A – JSON Template Processor Rules

Appendix A - JSON Template Processor RulesIntroductionThe JSON Template Processor allows us to specify rules to apply to a Project before the Visualization is generated. There are currently three different rules you can create, and these require a “Pattern” which follows the path matching described in Appendix B - Rule Path Syntax.All of these JSON rules must be provided in an array, even if there is only one rule.ChangePropertyRuleThis rule allows you to change the value of any property of any node. The JSON looks like:[{ "Type" : "ChangePropertyRule", "Pattern" : "some-pattern", "PropertyName" : "property-name", "Value" : "newValue"}]Where some-pattern, property-name, newValue are set accordingly.Example 1: Changing diffuse colour of a material[{ "Type" : "ChangePropertyRule", "Pattern" : "/:StdMaterial;Material_1", "PropertyName" : "Diffuse", "Value" : "0.0 1.0 0.0"}]This will get all StdMaterials named ‘Material_1’ and change their Diffuse colour to green (r: 0, g:1, b:0).Example 2: Changing smoothness of all materials in a specific library[{ "Type" : "ChangePropertyRule", "Pattern" : "/:Library;MyLibrary/:StdMaterial", "PropertyName" : "Smoothness", "Value" : "1.0"}]This will change the smoothness to 1.0 for all StdMaterials in a Library named ‘MyLibrary’.Example 3: Changing diffuse colour of all materials[{ "Type" : "ChangePropertyRule", "Pattern" : "/:StdMaterial", "PropertyName" : "Diffuse", "Value" : "0.0 1.0 0.0"}]This will get all StdMaterials and change their Diffuse colour to green (r: 0, g:1, b:0).DeleteNodesRuleAllows you to delete a node, and everything beneath it in the scene tree.[{ "Type" : "DeleteNodesRule", "Pattern" : "some-pattern"}]Where some-pattern is replaced with a pattern of the node(s) to delete.Example[{ "Type" : "DeleteNodesRule", "Pattern" : "/:Assembly;LEGO/:Assembly;RedPiece"}]Deletes any Assembly nodes (and children of) called ‘RedPiece’, which are themselves a child of an Assembly called ‘LEGO’.CreateNodeRuleAllows an entirely new node to be created. The “Pattern” specifies the parent node of the newly created node. Care must be taken that the pattern matches only a single node otherwise the rule will fail.[{ "Type": "CreateNodeRule", "Pattern": "/:SceneList", "Metanode": "Assembly", "Name": "MyNewNodeName"}]Defining Multiple RulesExample[{ "Type" : "DeleteNodesRule", "Pattern" : "/:Assembly;LEGO/:Assembly;RedPiece"},{ "Type" : "ChangePropertyRule", "Pattern" : "/:Library;MyLibrary/:StdMaterial", "PropertyName" : "Smoothness", "Value" : "1.0"},{ "Type": "CreateNodeRule", "Pattern": "/:SceneList", "Metanode": "Assembly", "Name": "MyNewNodeName"}]
Read more

Appendix B – Rule Path Syntax

IntroPath matching allows the nodes of model(s) to be manipulated before being published. It can currently carry out three operations:Remove nodes (and their children).Update certain properties of a node to a different value.Remove certain properties of a node.Use the rules and syntax examples given below to change your scene before it is published.Path SyntaxIn order to easily specify which nodes you want to manipulate, provide a path attribute in all of your requests. The path is simply a list of elements separated by a forward slash. It should start with (but not end with) a slash. In between the slashes are patterns that help match nodes with certain properties. The final element in the path specifies which node to act on, for example, the node that will be deleted or have its property modified. Any others before it are just used to locate it.The operation being performed (for example, deleting a node) will be applied to all nodes that match the path, so it is important to be as specific as possible when providing a path to a node. If a car model has four wheel nodes and you only want to delete one of them, find a way to specify that particular wheel, otherwise all four will be deleted. The syntax below provides ways to do this.Matching on Prop_name By default, the value you specify will be used to try and find a match on the prop_name property./HelicopterThis will match any nodes with a prop_name value of ‘Helicopter’. Please note: The matching is case-sensitive. Matching Nodes at the End of a Longer PathYou can chain these together to match longer paths. For example, to match a node with a prop_node value of ‘SGCapture’, directly connected to one with the same property set to ‘RotorBlade’ which itself is connected to one with a value of ‘Helicopter’, you can specify:/Helicopter/RotorBlade/SGCaptureMatching on any Path-depthIf you are not concerned about how many nodes are between two others that you do want to specify, you can use an asterisk:/Helicopter/*/SGCaptureThat will match an SGCapture node regardless of whether it’s directly connected to the Helicopter node, or has one or more intermediary nodes (such as the RotorBlade node) between them.Please note: A path cannot begin with this as the first element, since it defines a relationship connecting two nodes. A path such as /*/Helicopter is invalid and will result in an error being reported. Matching on MetanodeYou can match on the node’s metanode property by adding a colon to any path element:/:Assembly/*/:SGCaptureThis will match any SGCapture metanodes (where the metanode property is ‘SGCapture’) that is in turn indirectly connected to an Assembly metanode.Matching on Metanode and Prop_nameIf you wanted to match a metanode with a certain name, you can specify the name after the metanode value (separated by a semicolon):/:Assembly/*/:Model;HelicopterWhich will match a node like this:
Read more

Appendix C – Web Canvas Support

Appendix C – Web Canvas Support Introduction The Canvas API in Virtalis Reach enables developers to incorporate HTML5 Canvas elements into their visualisations. The Virtalis Reach web viewer does this by managing a Canvas control instance, compositing the 2D renderings within the 3D view, and dispatching events such as user input. Developers control the canvas by implementing a number of JavaScript callback methods which execute when the visualisation is viewed in a web browser. Within the callback implementations the developer’s scripts can call the HTML5 Canvas APIs as needed to generate 2D graphics and also use many of the other APIs exposed by the web browser. The canvas allows a wide range of functions and features to be enabled to increase the utility of Virtalis Reach across a range of domains. Embedding web canvases within Virtalis Reach allows scenes to be enriched in a number of different dimensions. For example: Users can take advantage of rich 2D user interfaces (UIs) Slide shows or videos can be embedded in visualisations Connections to live data feeds can be established and displayed This document assumes that the reader has experience/knowledge of HTML5 Canvas, Java scripting and Lua scripting. Please note: This document includes examples of preparing visualisations using Visionary Render. Please refer to the Visionary Render documentation for further information. Embedded Canvas Elements Many visualisations, particularly those for immersive training, need to simulate complex 2D Graphical User Interfaces (GUIs) embedded within the 3D scene. This allows the visualisation to replicate widgets such as Human-Machine Interface (HMI) control panels, graphical displays, and interactive information sign boards, or have synthetic information sources such as pop-up hints, graphs, and documents. Programming all the functionality to achieve rich interactive 2D UIs from scratch in Virtalis Reach would be extremely time-consuming and it would be difficult to attain a satisfactory product for authors. The platform for the Virtalis Reach Client (Yeti) is a standard web browser, and web browsers have evolved and developed a rich feature set over many decades to support rich, interactive 2D experiences. In the broadest sense, the most sensible solution is to enable visualisations in Virtalis Reach to also use the browser’s own features. What is a Canvas? Introduced in 2005 by Apple, and later adopted by all web browsers, and then finally added to the HTML5 specification, the Canvas element: (From Wikipedia) “allows for dynamic, scriptable rendering of 2D shapes and bitmap images. It is a low level, procedural model that updates a bitmap and does not have a built-in scene graph, but through WebGL it allows 3D shapes and images to be displayed. HTML5 Canvas also helps in making 2D games.” Using a Canvas element, a web designer can create graphics panels containing many elements such as images, a subset of HTML and 2D vector graphics. Architecture Mechanism of operation The Edge server has loaded a visualisation of a 3D scene. The visualisation contains a scenegraph consisting of data elements such as: Assemblies Visuals Lua scripts Canvas Proxy Objects Canvas Proxy Objects define a Canvas element, consisting of such properties as: JavaScript code to handle canvas events Dimensions Canvas Proxy Objects are mapped to a mesh surface in the scenegraph using a material, via a texture. The visualisation is loaded into the Web browser session. In the Web browser session HTML5 Canvas elements corresponding to each Canvas Proxy Object are created. The Canvas’s JavaScript code is copied to the browser session and compiled. The texture corresponding to each Canvas element is drawn on the appropriate mesh surface The Canvas JavaScript code is evoked to handle events by the Yeti JavaScript code. Events such as: Rendering the current image Mouse move Mouse enter/leaves Mouse click Immersive hand controllers will emulate appropriate input events, for example mouse events will correspond to a finger or short laser pointer. The Canvas JavaScript code in Yeti JavaScript code may send messages in the edge server to invoke Lua script if needed. Correspondingly the Lua code in the edge server may send messages to the JavaScript code. Canvas Scripting Callbacks You deliver your JavaScript in the form of Callbacks. Callbacks are a pre-defined set of functions in a specific format that the Virtalis Reach engine utilises to validate and execute the script in a Canvas item. You are offered the following set of callbacks: init(dirty, canvasData) paint(canvas, canvasData) dataChanged(canvasData) enabledChanged(canvasData) sendLuaFunc(funcName, parameters) onMouse(canvasData, eventType, eventData) onFocus(canvasData) onBlur(canvasData) onDispose(canvasData) Init Callback Each canvas must have an init function defined. This is the only function passively called by the canvas. It is only called once the canvas is given a valid canvas ID. After that, the canvas will never call the init function again. The function is called with two parameters (init(dirty, canvasData)) dirty is a function pointer to tell the canvas that it needs to be redrawn canvasData is an object that contains all data utilised by the script The dirty method is a simple function without parameters or a returning value dirty: function(){} . You can request a re-paint action for the next frame by triggering this dirty function in the script (dirty();) Refer to canvasData for further information. init: function(dirty, canvasData) { dirty(); }, Paint Callback This callback draws the output to a Canvas item. It is driven from the init’s callback dirty function that a repaint of the Canvas item is needed. The paint callback is called with two parameters (paint(canvas, canvasData)) canvas is the HTML canvas context canvasData is an object that contains all data utilised by the script (same as init callback) paint: function(ctx, canvasData) { ctx.fillRect(0, 0, 500, 500); }, DataChanged Callback This callback is called when the data values from the server are changed. This callback enables you to update their script behaviour from Canvas items property changes. Let’s assume that you have defined a Canvas item that contains metadata with a colour value and that the script is used to colour the background of the Canvas item. When this colour value changes, the server notifies the client with the changes. Your script can then register a DataChanged callback to act on this colour change. This callback uses a single parameter (dataChanged(canvasData)) canvasData is an object that contains all data utilised by the script (same as init callback) flash: function(localContext) { localContext.flashOn = !localContext.flashOn; localContext.dirty(); }, init: function(dirty, canvasData) { canvasData.localContext.dirty = dirty; canvasData.localContext.flashOn = false; canvasData.localContext.intervalID = setInterval(this.flash, canvasData.serverCanvasProperties.period, canvasData.localContext); }, dataChanged: function(canvasData){ clearInterval(canvasData.localContext.intervalID); canvasData.localContext.intervalID = setInterval(this.flash, canvasData.serverCanvasProperties.period, canvasData.localContext); }, paint: function(ctx, canvasData) { ctx.fillStyle = canvasData.localContext.flashOn ? canvasData.serverCanvasProperties.colourA : canvasData.serverCanvasProperties.colourB; ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fill(); } EnabledChanged Callback This callback is used to act on an enable state change of a Canvas item. As with the dataChanged callback, this uses a single parameter (enabledChanged(canvasData)) canvasData is an object that contains all data utilised by the script (same as init callback) init: function(dirty, canvasData) { canvasData.localContext.dirty = dirty; canvasData.localContext.enabled = canvasData.serverCanvasProperties.enabled; }, dataChanged: function(canvasData){ canvasData.localContext.enabled = canvasData.serverCanvasProperties.enabled; }, onMouse Callback This callback is called when a mouse event happens and the canvas has focus. This function is called with three parameters (onMouse(eventData, eventType, canvasData)) eventData is the data related to the mouse event. canvasData is an object that contains all data utilised by the script (same as init callback). eventType a string representing the mouse action. The available events are mousedown, mousemove, mouseup, click and double-click. onMouse: function(eventData, eventType, cavasData){ const mousePos = [eventData.x, eventData.y]; if(eventData.button === 0){ console.log("Click"); } if(eventData.buttons & 3){ console.log("left & right mouse down"); } if(eventType === 'mousemove') { processMouseMoveEvent(); } } onFocus Callback This callback is called when the script gains focus. This function is called with one parameter (onFocus(canvasData)) canvasData is an object that contains all data utilised by the script (same as init callback) onBlur Callback This callback is called when the script loses focus. This function is called with one parameter (onBlur(canvasData)) canvasData is an object that contains all data utilised by the script (same as init callback) onDispose Callback This callback is called when the scene is left. This function is called with one parameter (onDispose(canvasData)) canvasData is an object that contains all data utilised by the script (same as init callback) Data Types canvasData canvasData is a container for the data used in our JavaScript code. It contains three different objects: serverCanvasProperties is the object received from the server and contains user defined information. This is useful if you want similar functionality for multiple canvases but want different parameters (for example, for something that flashes between two colours, the script could be the same and it just reads the user data to get the two colours). In any scripts that use serverCanvasProperties the data should be treated as read only as it will be replaced when the canvas receives an update from the server. localContext is the object storing local data for the specific Canvas item. It is always an empty object when the canvas is created and can only be modified by the script attached to that canvas. enabled enable status of the Canvas item. This value should be treated as read only as it will be overwritten when the canvas receives an update from the server. { "serverCanvasProperties": {}, "localContext": {}, "enabled": true, } eventData eventData is a container for the data used in our JavaScript code. It contains four different objects: button is the button which triggered this event (same as mouseEvent button) buttons is an integer with the value of each bit corresponding to the pressed state of a mouse button (same as mouseEvent buttons) x is the x position of the mouse pointer in the range of 0 to canvas width y is the y position of the mouse pointer in the range of 0 to canvas height { "button": 0, "buttons": 0, "x": 0, "y": 0, } Templates Simple Example init: function(dirty, canvasData) { }, paint: function(ctx, canvasData) { }, dataChanged: function(canvasData) { }, enabledChanged: function(canvasData) { }, onMouse: function(eventData, eventType, canvasData) { }, onFocus: function(canvasData) { }, onBlur: function(canvasData) { }, onDispose: function(canvasData) { }, Destructured Example You can also destructure the canvasData to its three objects for easy referencing: init: function(dirty, {serverCanvasProperties, localContext, enabled}) { }, paint: function(ctx, {serverCanvasProperties, localContext, enabled}) { }, dataChanged: function({serverCanvasProperties, localContext, enabled}) { }, enabledChanged: function({serverCanvasProperties, localContext, enabled}) { }, onMouse: function({ button, buttons, x, y}, eventType, {serverCanvasProperties, localContext, enabled}) { }, onFocus: function({serverCanvasProperties, localContext, enabled}) { }, onBlur: function({serverCanvasProperties, localContext, enabled}) { }, onDispose: function({serverCanvasProperties, localContext, enabled}) { }, Formatting All scripts are processed and placed inside a JavaScript object. Any variables that are defined are local to that script but are shared across all canvas’s that reference that script if you want a variable that is local to the canvas assign it to the canvasData.localContext. To access any other local variable or function you need to use this. to reference it. localVar: 1, localFunc: function() {}, init: function() { this.localVar++; this.localFunc(); }, Remote Lua Execution sendLuaFunc Function The sendLuaFunc function is used to request that the server’s scripting environment execute a remote procedure call of a Lua function that is currently defined in the visualisation. This enables, for example, mouse events on a canvas to trigger animation sequences. (sendLuaFunc(funcName, parameters)) funcName name of the function parameters parameters of the function in array format. Numbers (either a integer or floating point) & strings are supported. Return Value and Error Codes There is no return value from sendLuaFunc. The client code will not be notified if the requested Lua function could not be executed by the server, for example if the parameters are incorrect or the function does not exist. If unexpected behaviour occurs the servers and clients logs should be checked for diagnostic messages. Asynchronous and Out-of-Order Execution Calling sendLuaFunc results in remote procedure calls that are processed by the server asynchronously and not always in the same order as they were submitted. This means that client code after sendLuaFunc is likely to execute before the Lua function on the server has done so, which can lead to illogical outcomes if not accounted for during development. Additionally, several calls to sendLuaFunc might be executed in a different order to when they were submitted. Structure the client and server code so that the client makes few calls to sendLuaFunc which invoke self-contained server-side Lua functions, rather than developing many inter-related server functions and linking them by making many calls to sendLuaFunc. Canvases in Collaboration The client JavaScript code for a canvas executes only in the web browser of the user viewing the visualisation, a consequence of this is that during a collaborative multi-user session the canvas visualisation author is required to ensure that the canvases for all the users are displaying the expected content. This requires ensuring that changes to the visual state of a canvas are propagated to all users. For example, a canvas which displays a single button that the user can toggle between green and blue using a mouse click will not maintain a consistent visual state in a multi-user collaboration unless the scripting is used to ensure that when any user presses the button the correct colour is shown on the canvas of all the users web browsers. This can be achieved by combining remote procedure calls to Lua with the serverCanvasProperties and the DataChanged callback. The author must decouple the properties of the canvas (the document or model), from its view code (the view) and its event dispatching code (the controller). Using a Model/View/Controller pattern ensures that the state of a shared object with many views and controllers remain logical. In the example, a correct implementation would be programmed so that when any user presses the button, a remote Lua call (sendLuaFunc) is used to call a Lua function which sets the properties of the Canvas. This will then trigger the dataChanged callback for the canvas in the web browser of all the users in the collaboration. The implementation of dataChanged would then invalidate the canvas by calling dirty, and the paint implementation would draw the canvas using the server properties. By ensuring the separation of Model/View/Controller then the visualisation remains correct. Code Example This is an example of calling a Lua function called funcName from the client-side JavaScript code: init: function(dirty, canvasData) { const val = 2.3; const name = "Alice"; const parameters = [-1, 1, val, name]; this.sendLuaFunc('funcName', parameters); }, Configuring a Visionary Render Scene Visionary Render scenes store canvas information and their data in a configuration that the Virtalis Reach Client (Yeti) can recognise and create the necessary elements for a script to be executed on the canvas. It is essential to describe the information in such a structure and with the necessary information that the client needs to correctly calculate the results. Since this is a Virtalis Reach application-specific feature, there is no immediate method to create a Canvas or a Script node in the Visionary Render environment. You can, however, create these items in the scene, place them and configure them using existing nodes structured as outlined in the following sections. Canvas Script Item A canvas script item is used to pass the script (JavaScript) to the client so it can render on a Canvas node. It is a Visionary Render Metadata container (MetaGroup) node with a specific name (YETI_CANVAS_SCRIPT) and a metanode child that contains the JavaScript code. A script can be shared among multiple canvas nodes. You can create your own metadata nodes with custom names and values. The information from these is passed to the script as a JavaScript object to customise the behaviour. To define a Script item in the scene, you need to create an assembly node that contains a metagroup node (name YETI_CANVAS_SCRIPT) with a string metadata entry (called YETI_CANVAS_SCRIPT). The script data can be set to the string metadata value field. Create an assembly Add a Metadata container to the assembly Add a Metadata entry of type string to the MetaGroup Rename the MetaGroup and Metadata item names using YETI_CANVAS_SCRIPT Add your script to the Metadata value box in the properties window, as shown above Adding Custom Scripts There are two different editors accessible within Visionary Render. The first is accessible from the Scenes tree when an Assembly is selected and edits all the metadata together. This breaks new lines. The other method is to access the MetaDataString node directly from the Developer tree. This does not break new lines. Canvas Item A Canvas item contains the script that is rendered on in Virtalis Reach. The canvas is assigned a size and a resolution for the rendering output and is linked with a script node. These are the core properties that a canvas is using and Reach expects to be described so that it can create all elements for rendering a script on the canvas in reference. You can define a list of your own data used in the script through Metadata nodes in the Canvas item container (MetaGroup). A variety of different value types included in the Visionary Render context menu are supported (int/float/string/vector, and so on), as well as other types not exposed to the context menu but available on application’s scripting (arrays). Link metadata nodes are not supported. Please note: Visionary Render does not currently offer menu entries to create metadata of type Float2 and Int2 necessary to create the size and resolution properties of the Canvas. Nevertheless, these metadata nodes can be created through Lua scripting. Bring up the scripting window (Ctrl+L) and drag and drop the MetaGroup container (YETI_CANVAS_NODE) onto the Lua scripting window to get a reference to the metagroup. You then need to create two new nodes as children to the metaGroup node: vrCreateNode(‘MetaDataInt2’, ‘YETI_CANVAS_RESOLUTION’, metaGroup) vrCreateNode(‘MetaDataFloat2’, ‘YETI_CANVAS_SIZE’, metaGroup) Enter these two lines as shown in the image below. Right-click and execute the code. You can view the new properties created for you in the scenes tree. Script to create Canvas node specific properties The configuration of a Canvas item is similar to the Script node with the extra metadata nodes required. You need to create an Assembly node with a MetaGroup container (called YETI_CANVAS_NODE), the three core properties as Metadata nodes and any number of user defined metanodes: MetaDataLink for the linked script node (YETI_CANVAS_SCRIPT_LINK) MetaDataFloat2 for the canvas size (YETI_CANVAS_SIZE) MetaDataInt2 for the canvas resolution (YETI_CANVAS_RESOLUTION) Create an assembly Add a Metadata container to the assembly Add Metadata event link value A canvas node tree structure Link a script node to a canvas Canvas Proxy Item The current Canvas/Script structure provides no information to help you to understand the position or the size of a Canvas in space and accurately author your scene. Visionary Render offers a variety of objects that render in the scene and could be used as proxies to help ‘visualise’ a Canvas item in the scene. Start by creating the items in your Canvas by following the steps below: Select Canvas item and right-click to bring up the context menu and select Create > Assembly. You can rename this to, for example, something such as Proxy. Select the new Assembly, right-click to bring up the context menu and select Create > Geometry Shape > Plane. Select the Plane node and change the Position X and Y to 0.5 and -0.5 respectively. Change Rotation X to 90.0 degrees. Step 1 Create Proxy assembly Step 2 - Create Geometric Shape > Plane Steps 3 and 4 - Update plane transform Canvas item final structure Now you can select the Canvas Assembly to position the canvas in the scene and use the Proxy assembly scale to configure the size of your canvas. Make sure to pass the scale values (XY) to the YETI_CANVAS_SIZE metanode values. Sizing a proxy Set proxy’s size to canvas size property Please note: Ensure that you disable the proxy before you save your project as you do not want this proxy object to be treated inside the Virtalis Reach Client. Canvas Item Lua Script All the above steps are summarised to the Lua script below. Paste the script below inside a Lua script window in Visionary Render to create a Canvas item in the scenes branch: local parent = vrScenesNode() local canvas = vrCreateNode("Assembly", "Canvas", parent) local metagroup = vrCreateNode("MetaGroup", "YETI_CANVAS_NODE", canvas) vrCreateNode("MetaDataLink", "YETI_CANVAS_SCRIPT_LINK", metagroup) vrCreateNode("MetaDataFloat2", "YETI_CANVAS_SIZE", metagroup) vrCreateNode("MetaDataInt2", "YETI_CANVAS_RESOLUTION", metagroup) local proxy = vrCreateNode("Assembly", "Proxy", canvas) local plane = vrCreateShape("Plane", proxy) plane.Transform.Rotation.X = 90 plane.Transform.Position.X = 0.5 plane.Transform.Position.Y = -0.5 Script Examples Simple White Canvas init: function(dirty) { dirty(); }, paint: function(ctx) { ctx.fillStyle = 'white'; ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fill(); } Still Image Drawn Using HTML Canvas Commands init: function(dirty) { dirty(); }, paint: function(ctx) { ctx.lineCap = 'round'; ctx.lineJoin = 'round'; ctx.fillStyle = '#10069f'; ctx.fillRect(0, 0, 500, 500); ctx.strokeStyle = '#f1ac27'; ctx.lineWidth = 50; ctx.moveTo(30,80); ctx.lineTo(160,420); ctx.stroke(); ctx.beginPath(); ctx.strokeStyle = 'white'; ctx.moveTo(160,420); ctx.lineTo(320,80); ctx.lineTo(470,420); ctx.stroke(); }, Simple Flashing Canvas flash: function(localContext) { localContext.flashOn = !localContext.flashOn; localContext.dirty(); }, init: function(dirtyCB, {localContext}) { localContext.dirty = dirtyCB; localContext.flashOn = false; setInterval(this.flash, 1000, localContext); }, paint: function(ctx, {localContext}) { ctx.fillStyle = localContext.flashOn ? 'yellow' : 'blue'; ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fill(); } Flashing Canvas that Uses serverCanvasProperties flash: function(localContext) { localContext.flashOn = !localContext.flashOn; localContext.dirty(); }, init: function(dirtyCB, {serverCanvasProperties, localContext}) { localContext.dirty = dirtyCB; localContext.flashOn = false; localContext.intervalID = setInterval(this.flash, serverCanvasProperties.period, localContext); }, dataChanged: function({serverCanvasProperties, localContext}){ clearInterval(localContext.intervalID); localContext.intervalID = setInterval(this.flash, serverCanvasProperties.period, localContext); }, paint: function(ctx, {serverCanvasProperties, localContext}) { ctx.fillStyle = localContext.flashOn ? serverCanvasProperties.colourA : serverCanvasProperties.colourB; ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fill(); } serverCanvasProperties { "colourA":"blue", "colourB":"yellow", "period":1000 } Rendering a Video init: function(dirty, {serverCanvasProperties, localContext, enabled}) { localContext.dirty = dirty; const video = document.createElement('video'); video.setAttribute('autoplay', 'true'); video.setAttribute('loop', 'true'); video.setAttribute('src','');//replace URL with URL to video file video.setAttribute('crossOrigin','anonymous'); = -9999; = 'inherit'; localContext.thisVid = video; document.body.appendChild(video); video.addEventListener('play', function() { (function loop() { if(!localContext.thisVid.paused && !localContext.thisVid.enabled) { localContext.dirty(); setTimeout(loop, 1000/30); } })(); }, 0);; }, paint: function(ctx, {serverCanvasProperties, localContext, enabled}) { ctx.drawImage(localContext.thisVid,0,0); }, enabledChanged: function({serverCanvasProperties, localContext, enabled}) { if(enabled){; } else { localContext.thisVid.pause(); } }, onDispose: function({serverCanvasProperties, localContext, enabled}) { localContext.thisVid.remove(); }
Read more

Support and Feedback

If support is required, please visit the support portal and knowledgebase at or email Virtalis Support at is always welcomed so that we can continue to develop and improve Virtalis Reach. Please speak to your Customer Success team.
Read more


If you have questions or need additional support, we are here to help.