Skip to content

Using Assets and Models

Christian edited this page Mar 10, 2015 · 11 revisions

Note: Assets are currently a work in progress. If you find any problems please don't hesitate to file an Issue and be aware that some implementation details may change in the future.

Introduction

For this tutorial we'll be looking at the new Asset and Model format introduced in XML3D 4.7. Concretely we'll cover:

  • The motivation behind the Asset format
  • The Asset format itself
  • Instantiating an Asset with a Model tag
  • Overwriting parts of the Asset from inside your scene
  • Driving an animation in the Asset

Why use Assets?

One of the difficulties in using the HTML DOM to describe a 3D scene is the sheer number of DOM elements required for large models with many individual meshes. Not only does this impact the memory footprint of the tab, but it makes editing the HTML file a pain.

Even when storing the mesh data in an external file (as we did with our teapot in The Basics of XML3D) we still need to create a <mesh> element for each part of the object. For a simple teapot this is easy, a single <mesh> is all we need, but consider a more complex object. A car may consist of many hundreds of individual meshes each with their own material, but we'd like to be able to treat it as a single model in our scene.

For this reason Assets were introduced to XML3D. By converting our complex object to the Asset format we can introduce an instance of it into our scene with a single <model> element.

Lets start by taking a quick look at the Asset format itself.

The Asset format

Resources: TODO

The above zip archive above contains the data, textures and Asset file needed to create an instance of the Ciccio robot from the FIcontent initiative in our scene.

Lets take a closer look at the Asset file ciccio.xml:

<xml3d xmlns="http://www.xml3d.org/2009/xml3d" >
    <shader id="glassShader" script="urn:xml3d:shader:phong">
        <float3 name="emissiveColor">0.5 0.5 0.5</float3>
        <float3 name="diffuseColor">0.1936 0.636474 0.8</float3>
        <float3 name="specularColor">0.5 0.5 0.5</float3>
        <float name="shininess">0.15625</float>
        <float name="ambientIntensity">0.0</float>
        <float name="transparency">0.154467</float>
    </shader>

    <shader id="armorShader" script="urn:xml3d:shader:phong">
        <float3 name="emissiveColor">0.5 0.5 0.5</float3>
        <float name="ambientIntensity">0.1</float>
        <texture name="diffuseTexture">
            <img src="textures/Ciccio_Armor_D.png"/>
        </texture>
        <texture name="emissiveTexture">
            <img src="textures/Ciccio_Armor_EM.png"/>
        </texture>
        <texture name="normalTexture">
            <img src="textures/Ciccio_Armor_NM.png"/>
        </texture>
        <float3 name="specularColor">0.5 0.5 0.5</float3>
        <float name="shininess">0.05625</float>
        <float name="transparency">0.01</float>
    </shader>

    <asset id="ciccio" >

        <!-- shared data -->
        <assetdata name="base">
            <data src="data/ciccio-mesh.xml#shared" />
            <data src="data/ciccio-anims.xml#animation" />
        </assetdata>

        <!-- meshes -->
        <assetmesh name="armor" shader="#armorShader" includes="base" >
            <data src="data/ciccio-mesh.xml#index1" />
        </assetmesh>
        <assetmesh name="glass" shader="#glassShader" includes="base" >
            <data src="data/ciccio-mesh.xml#index2" />
        </assetmesh>
    </asset>
</xml3d>

The shader definitions should be familiar to us (although here we use a slightly more complicated Phong shader with three textures). The interesting bit begins at the <asset> tag, which defines an object that can be referenced from inside our scene with a <model> tag through its id.

Inside the <asset> element we have an <assetdata> block, which functions much like a normal <data> element. You'll notice that instead of being given an id, these elements are given a name instead. Unlike an id, which must be unique per document, the name attribute is always relative to its parent <asset> element.

Finally we have two <assetmesh> elements which define the two meshes that make up this Asset. Again, each is given a name. Each mesh references its shader through the shader attribute. We also use the includes attribute to reference the <assetdata> element "base", which includes all the mesh data that is shared by both meshes. This is semantically equivalent to:

<assetmesh name="armor" shader="#armorShader">
    <data src="data/ciccio-mesh.xml#shared" />
    <data src="data/ciccio-anims.xml#animation" />
    <data src="data/ciccio-mesh.xml#index1" />
</assetmesh>

Sharing data is more efficient and requires less resources, so it's a good idea to do it whenever possible.

Of course each <assetmesh> element can also have or reference it's own transformation through the transform attribute.

Note: <assetdata> and <assetmesh> elements may not be nested. <asset> elements, however, can be nested.

Instantiating an Asset with a Model tag

Clone this wiki locally