Show TOC

Step 4: Adding a Scene TreeLocate this document in the navigation structure

In this step, you will be adding a sap.ui.vk.SceneTree control to your 3D Viewer application.

Caution

The controls in the sap.ui.vk library are currently flagged as experimental. For more information, see Compatibility Rules.

The following sap.ui.vk controls are introduced in this step:
  • SceneTree control
  • ViewStateManager control

We will use the SceneTree control to create a tree structure that displays the hierarchy of the nodes for the loaded model. We will then use the ViewStateManager control to link the Scene Tree with the model loaded into the Viewport, so that we can visually associate a selection in the scene with its corresponding node as displayed in the Scene Tree.

The content in this step builds on the code from Step 3: 3D Viewer Using the Viewport Control, and code changes performed in this step of the tutorial are done in relation to the files in Step 3: 3D Viewer Using the Viewport Control.

Preview
Figure 1: Viewer application with a Viewport and a Scene Tree
Coding

You can view and download all files in the Explored app in the Demo Kit under 3D Viewer - Step 4 - Viewport with Scene Tree .

index.html

Update the index.html file to reference the viewportScenetree namespace, which will be the namespace we'll use for the sample application in this step.

#!html<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
    <script id="sap-ui-bootstrap"
        src="../../../../../../../../../resources/sap-ui-core.js"
        data-sap-ui-libs="sap.ui.vk, sap.m"
        data-sap-ui-theme="sap_bluecrystal"
        data-sap-ui-bindingSyntax="complex"
        data-sap-ui-resourceroots='{
            "viewportScenetree": "./"
        }'>
    </script>
    <script>
    sap.ui.getCore().attachInit(function(){
        new sap.m.Shell({
            app: new sap.ui.core.ComponentContainer({
                name : "viewportScenetree"
            })
        }).placeAt("content");
    });
    </script>
    </head>
    <body id="content" class="sapUiBody">
    </body>
</html>

Component.js

Update the Component.js file to reference the namespace specified for this application.

#!jssap.ui.define([
    "sap/ui/core/UIComponent"
], function (UIComponent) {
    "use strict";

    return UIComponent.extend("viewportScenetree.Component", {
        metadata: {
            manifest: "json"
        },
        init: function () {
            // call the init function of the parent
            UIComponent.prototype.init.apply(this, arguments);
        }
    });
});

i18n.properties

Update the page title to say "Viewport with Scene Tree".

#!properties# Page Descriptor
pageTitle=Viewport with Scene Tree

manifest.json

Update the manifest.json file so that it references the correct files.

#!js{
    "_version": "1.1.0",
    "sap.app": {
        "_version": "1.1.0",
        "id": "viewportScenetree",
        "type": "application",
        "i18n": "i18n/i18n.properties",
        "title": "{{appTitle}}",
        "description": "{{appDescription}}",
        "applicationVersion": {
            "version": "1.0.0"
        },
    },
    "sap.ui": {
        "_version": "1.1.0",
        "technology": "UI5",
        "deviceTypes": {
            "desktop": true,
            "tablet": true,
            "phone": true
        },
        "supportedThemes": [
        "sap_bluecrystal"
        ]
    },
    "sap.ui5": {
        "_version": "1.1.0",
        "rootView": "viewportScenetree.view.App",
        "dependencies": {
            "minUI5Version": "1.30",
            "libs": {
                "sap.m": {}
            }
        },
        "models": {
            "i18n": {
                "type": "sap.ui.model.resource.ResourceModel",
                "settings": {
                    "bundleName": "viewportScenetree.i18n.i18n"
                }
            }
        }
    }
}

App.view.xml

To display the Scene Tree in your application, add the <vk:SceneTree> element. In the element's attribute's, specify the Scene Tree control's width and height on the screen, and give it an arbitrary identifier value.

#!xml<mvc:View
        controllerName="viewportScenetree.controller.App"
        xmlns="sap.m"
        xmlns:mvc="sap.ui.core.mvc"
        xmlns:vk="sap.ui.vk"
        xmlns:l="sap.ui.layout"
        xmlns:f="sap.ui.layout.form"
        xmlns:u="sap.ui.unified"
        displayBlock="true">
    <App id="viewportScenetree">
        <Page
                title="{i18n>pageTitle}">
            <vk:Viewport
                    id="viewport"
                    width="100%"
                    height="25%"/>
            <vk:SceneTree
                    id="scenetree"
                    width="100%"
                    height="25%"/>
        </Page>
    </App>
</mvc:View>

App.controller.js

For the most part, the code in the App.controller.js file will be the same as the content of the App.controller.js file for the application in Step 3: 3D Viewer Using the Viewport Control. The highlighted sections in the following code block indicate the additions and changes made in the code to incorporate a Scene Tree in the 3D Viewer application.

#!jssap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/model/json/JSONModel",
    "sap/ui/vk/ContentResource",
], function (Controller, JSONModel, ContentResource) {
    "use strict";

    var contentResource = new sap.ui.vk.ContentResource({
        source: "/models/boxTestModel.vds",
        sourceType: "vds",
        id: "abc123"
    });
    return Controller.extend("viewportScenetree.controller.App",{
        onInit: function() {
            var mainScene;
            jQuery.sap.require("sap.ui.vk.GraphicsCore");
            var graphicsCore = new sap.ui.vk.GraphicsCore({},{
                antialias: true,
                alpha: true,
                premultipliedAlpha: false
            });
            var view = this.getView();
            var viewport = view.byId("viewport");
            var sceneTree = view.byId("scenetree");
            viewport.setGraphicsCore(graphicsCore);
            graphicsCore.loadContentResourcesAsync([contentResource], function(sourcesFailedToLoad){
                if (sourcesFailedToLoad){
                    jQuery.sap.log.error("Some of content resources cannot be loaded.");
                } else {
                    var scene = graphicsCore.buildSceneTree([contentResource]);
                    if (scene){
                        mainScene = scene;
                        viewport.setScene(mainScene);
                        var viewStateManager = graphicsCore.createViewStateManager(mainScene.getDefaultNodeHierarchy());
                        viewport.setViewStateManager(viewStateManager);
                        sceneTree.setScene(mainScene, viewStateManager);
                    } else {
                        jQuery.sap.log.error("Failed to build the scene tree.");
                    }
                }
            });
        }
    });
});

Let us look at the changes in more detail.

The following code line adds a new Scene Tree object.

#!jsvar sceneTree = view.byId("scenetree");

We create a new object called viewStateManager that gets the node hierarchy of the resource that's loaded into the scene. Then, we associate the created viewStateManager object with our viewport. We also associate the nodes in the viewStateManager object, as well as the resource loaded into the main scene with the Scene Tree.

#!jsvar viewStateManager = graphicsCore.createViewStateManager(mainScene.getDefaultNodeHierarchy());
viewport.setViewStateManager(viewStateManager);
sceneTree.setScene(mainScene, viewStateManager);

Finally, we changed the message for the condition that determines whether the viewport and the scene tree loaded successfully or not.

#!jsjQuery.sap.log.error("Failed to build the scene tree.");
API Reference