perceptuum 2.1 scene description v1

harrison ainsworth / hxa7241

ΑRΤΙFΕΧ at ΗΧΑ7­24­1 dot ΟR­G
2004-07-23
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

abstract

this article is a tutorial reference on the perceptuum 2.1 renderer[PH] scene format, version 1.0.

keywords

perceptuum, scene, documentation

contents

introduction

files

the scene definition is in XML[XML] file form.

it is in two parts: options and scene, both required.

the two file names must have the same first part, with partially different extensions:

  • somename.options.p2.xml
  • somename.scene.p2.xml

commonalities

both files have the same header:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<?hxa7241-XmlSerializer version='1.0' 'object serialized to xml' 'exact class match required'?>

the xml declaration must be present exactly as shown. the serializer declaration must be present, but the last two strings can be omitted (they are commentary).

blank space and comments are ignored, so can be used freely. (except in leaf content)

tag attributes are ignored. an attribute named ‘type’ can be used for commentary purposes, to help manual editing. in which case the established values for primitives are:

  • boolean
  • character
  • characters
  • std::string
  • bytesigned
  • byteunsigned
  • wordsigned
  • wordunsigned
  • dwordsigned
  • dwordunsigned
  • dwordsigned
  • dwordunsigned
  • floatingpointsingle
  • floatingpointdouble

all string content must be inside CDATA markup. example: <name type='string'><![CDATA[aluminium1]]></name>

literal color values are specified in CIE[CIE] XYZ. textures are png files, the color characteristics of which can be ordinary RGB, sRGB[SRGB], or with particular chromaticities, white color, and gamma.

all units of measurement should be assumed to be SI.

options part

conceptually, a simple fixed list of name and value pairs.

the whole xml structure must be followed exactly, just the values will be different. see the example options file.

nametypedescription
header fixed value as shown in introduction.
rendering options
  immutable options options that are fixed across different sessions of the same render. if a render is resumed these are ignored and the original ones used.
    projection defines camera geometry.
      eye position3d vectorposition of the center of projection.
        xfloat
        yfloat
        zfloat
      look direction3d vectordirection the camera is facing.
        xfloat
        yfloat
        zfloat
      up direction3d vectordirection the camera uses as upwards.
        xfloat
        yfloat
        zfloat
      widthfloatwidth of the ‘virtual’ projection screen.
      screen distancefloatdistance of the projection screen from the center of projection.
      lens diameterfloatdiameter of the thin-lens model. controls how blurry objects are that are not at the focal distance.
      focal lengthfloatfocal length of the thin-lens model. the distance from the center of projection at which objects will be in focus.
    image widthintegerimage width in pixels.
    image heightintegerimage height in pixels.
    default object colorCIE XYZcolor for empty space, where no objects can be seen.
      xfloat
      yfloat
      zfloat
  seconds between savesintegerhow regularly the renderer saves the render state to disk, in case of system failure.
  tonemap adaptation luminancefloatignored — determined automatically. use empty tag.
  emitter path numberintegernumber of samples of direct lighting made in each iteration. the more emitter area the more samples needed.
  photon map sizeintegeractually the number of photon paths made in each iteration. the number of photons stored will be some fraction of this value, maybe 1/2ish.
  lightsource emittance thresholdintegerwattage below which a lightsource is not treated as a principal lightsource (this is probably ignored at present).
  emitter path length limitintegermaximum length of an emitter path. not usually useful, use 16 as a default.
  emitter path end thresholdfloathow small a fraction of original energy (or luminance) to let the light reach before ending the path. zero sets path ending to russian roulette (stochastic), which is usually best.
  eye path length limitintegermaximum length of an eye path. not usually useful, use 16 as a default.
  eye path end thresholdfloathow small a fraction of original energy (or luminance) to let the light reach before ending the path. zero sets path ending to russian roulette (stochastic), which is usually best.
  display characteristics defines the characteristics of the display the renderer is using. these will usually be unknown, so just use defaults.
    black pointCIE XYZcolor and intensity of black. probably about 2.5ish.
      xfloat
      yfloat
      zfloat
    white pointCIE XYZcolor and intensity of white. probably about 85ish.
      xfloat
      yfloat
      zfloat
    chromaticities XYZ x x chromaticities.
      xfloatuse 0.64 as a default.
      yfloatuse 0.30 as a default.
      zfloatuse 0.15 as a default.
    chromaticities XYZ y y chromaticities.
      xfloatuse 0.33 as a default.
      yfloatuse 0.60 as a default.
      zfloatuse 0.06 as a default.
    chromaticities XYZ z z chromaticities (these may be redundant).
      xfloatuse 0.03 as a default.
      yfloatuse 0.10 as a default.
      zfloatuse 0.79 as a default.
    gamma xyz gamma for xyz. probably between 1 and 3, and all the same.
      xfloatas a default, use 1 for a panel, 2.222 for a crt.
      yfloatas a default, use 1 for a panel, 2.222 for a crt.
      zfloatas a default, use 1 for a panel, 2.222 for a crt.
  is illumination loggingboolean1 for more illumination related logging, 0 for less.
  is rasterizer loggingboolean1 for more rasterizer related logging, 0 for less.

scene part

there are a few global parameters, a series of materials, and a series of objects.

all materials and objects have string names, so they can be referred to elsewhere in the seriess. material names must be unique, object names must be unique.

outline

nametypedescription
header fixed value, as shown in introduction.
scene
  time beginfloattime point when scene starts existing. this must overlap with any moving instances times for any movement to be seen. set to zero if there are no moving instances.
  time endfloattime point when scene stops existing. this must overlap with any moving instances times for any movement to be seen. set to zero if there are no moving instances.
  medium transparencyfloatthe transparency for the default space of the scene. use default 1 as a default.
  medium refractive indexfloatthe refractive index for the default space of the scene. use default 1 as a default.
  materials a variable length series of material elements.
    element
    (...more elements...)
  objects a variable length series of object elements.
    element
    (...more elements...)

material element

conceptually, a simple fixed list of name and value pairs.

the whole xml structure must be followed exactly, just the values will be different. see the example scene file.

a material defines surface properties in a simplified generalised form. the textures override the base qualities.

nametypedescription
namestringunique across materials.
base qualities basic homogeneous properties, selectively overridden by textures.
  tangent3d vectordirection of surface tangent for anisotropic materials. projected unto the surface.
    xfloat
    yfloat
    zfloat
  reflectivity diffuseCIE xyzcolor and proportion of diffuse (matte) reflectivity. the sum of each value and its corresponding specular value must be >= 0 and < 1.
    xfloat
    yfloat
    zfloat
  reflectivity specularCIE xyzcolor and proportion of specular (shiny) reflectivity. the sum of each value and its corresponding diffuse value must be >= 0 and < 1.
    xfloat
    yfloat
    zfloat
  roughness xfloatroughness in the tangent direction, >= 0 and <= 1.
  roughness yfloatroughness in the tangent perpendicular direction, >= 0 and <= 1.
  transparencyfloathow transparent, >= 0 and <= 1.
  refractive indexfloatprobably between 1 and 2. (none of that superluminal phase velocity stuff!)
  emitted w/m2 (radiant exitance isnt that?). the wattage of a lightsource = its emitting area * this value.
    Xfloat
    Yfloat
    Zfloat
  emitted roughnessfloatignored — all emittance is perfectly diffuse. use 1.
  brdf class namestringignored (currently fixed to ward model). use empty tag.
color image namestringfile pathname of a png image, or empty.
color specular image namestringfile pathname of a png image, or empty. if either color or color specular is empty, both assume the value of the one given. if both are empty, base qualities is used.
spec diffuse image namestringfile pathname of a png image, or empty. grayscale, representing the ratio between diffuse and specular. if empty, the ratio is made from base qualities reflectivities.
roughness x image namestringfile pathname of a png image, or empty. grayscale, representing 0 to 1. if one roughness is empty, both assume the value of the one supplied, if both are empty, base qualities is used.
roughness y image namestringfile pathname of a png image, or empty. grayscale, representing 0 to 1. if one roughness is empty, both assume the value of the one supplied, if both are empty, base qualities is used.
transparency image namestringfile pathname of a png image, or empty. grayscale, representing 0 to 1. if empty, base qualities is used.
emitted image namestringfile pathname of a png image, or empty. ignored.
tangent image namestringfile pathname of a png image, or empty. grayscale, representing a height field: tangent is aligned to contours. if empty, base qualities is used.
normal image namestringfile pathname of a png image, or empty. grayscale, representing a height field.

object elements

object elements are polymorphic, each must be one of the following types:

objects

instances

the last object element in the series must be an instance type. it is the root of the scene tree.

descriptions of each type:

ObjectMesh
nametypedescription
object typestringfixed: perceptuum2::modelling::ObjectMesh
namestringunique across objects.
vertex countintegernumber of vertexs in the series. must be <= 32767.
vertex3d vector
  xfloatx position.
  yfloaty position.
  zfloatz position.
(...more vertexs...)
triangle countintegernumber of triangles in the series.
triangle
  vertex index 0integerrefers to a vertex in the vertex series.
  vertex index 1integerrefers to a vertex in the vertex series.
  vertex index 2integerrefers to a vertex in the vertex series.
  interpolate normalboolean1 to make the triangle surface appear curved.
  tx0integerpixel x position on texture image, for corner 0.
  ty0integerpixel y position on texture image, for corner 0.
  tx1integerpixel x position on texture image, for corner 1.
  ty1integerpixel y position on texture image, for corner 1.
  tx2integerpixel x position on texture image, for corner 2.
  ty2integerpixel y position on texture image, for corner 2.
(...more triangles...)
material refstringname of the material to use.

the mesh must be a single, non-intersecting, closed surface — that is to say topologically equal to a sphere, or torus, or higher genus variant.

a special interpretation of the texture coords is used for meshs of emitting material, to allow simple shaping of emittance: if the coords are zero the face does emit, if the coords are not zero the face does not emit.

ObjectMeshBlock

usable in two variants, to allow alternative texture specification.

variant 1
nametypedescription
object typestringfixed: perceptuum2::modelling::ObjectMeshBlock
namestringunique across objects.
dimensions3d vector
  xfloatwidth of block.
  yfloatheight of block.
  zfloatdepth of block.
net or facesboolean1 selects net based texture (this variant).
texture coords2d vector
  xintegerx minimum of hull of texture net, on texture image, in pixels.
  yintegery minimum of hull of texture net, on texture image, in pixels.
texture scalefloatwidth of ‘middle’ rectangle of texture net, in pixels.
material refstringname of the material to use.

a ‘t’ shaped net on the texture image is mapped to the block so the ‘middle’ rectangle fits on top.

.   -----
    | B |
-------------     ------
| L | T | R |    |\  T  \
-------------    |L\------
    | F |        \ |  F  |
    -----         \|     |
    | U |          *------
    -----

the dot shows the texture coords xy. the asterisk shows the spatial coords origin.

variant 2
nametypedescription
object typestringfixed: perceptuum2::modelling::ObjectMeshBlock
namestringunique across objects.
dimensions3d vector
  xfloatwidth of block.
  yfloatheight of block.
  zfloatdepth of block.
net or facesboolean0 selects face based texture (this variant).
texture coords2d vector
  xintegerpixel x position on texture image.
  yintegerpixel y position on texture image.
(...more texture coords...) 24 in total. each adjacent four are related:
first four is front, next back, left, right, bottom, top.
material refstringname of the material to use.

the 24 texture coords specify the pixel positions each block face corner maps from on the texture image.

a special interpretation of the texture coords is used for blocks of emitting material, to allow simple shaping of emittance: if the coords are zero the face does emit, if the coords are not zero the face does not emit.

the bottom left corner of the block is at the origin.

ObjectMeshSphere
nametypedescription
object typestringfixed: perceptuum2::modelling::ObjectMeshSphere
namestringunique across objects.
diameterfloatdiameter of sphere.
resolutionintegernumber of faces in mesh approximation, 0 to 9. even is an octahedron subdivision, odd is an icosahedron subdivision. resultant face counts for resolution: 8 20 32 80 128 320 512 1280 2048 5120.
material refstringname of the material to use.

the center of the sphere is at the origin.

ObjectMeshCylinder
nametypedescription
object typestringfixed: perceptuum2::modelling::ObjectMeshCylinder
namestringunique across objects.
diameterfloatdiameter of cylinder across height axis.
heightfloatheight of cylinder.
is curvedboolean1 for curved (cylinder), 0 for faceted (prism).
resolutionintegernumber of facets around height axis. 3 to 1000.
material refstringname of the material to use.

the center of the bottom face of the cylinder is at the origin.

ObjectInstance
nametypedescription
object typestringfixed: perceptuum2::modelling::ObjectInstance
namestringunique across objects.
sub parts a variable length series of subpart elements.
  element
    object refstringname of an object to include as a subpart in this instance.
    transform
      rotation3d vector
        xfloatrotation in degrees around x axis. applied first.
        yfloatrotation in degrees around y axis. applied second.
        zfloatrotation in degrees around z axis. applied third.
      position3d vector
        xfloattranslation in x.
        yfloattranslation in y.
        zfloattranslation in z.
  (...more elements...)

objects referred to can be of any object type, and must have been defined prior to this instance. there is a nesting limit of 8 levels.

ObjectInstanceMoving
nametypedescription
object typestringfixed: perceptuum2::modelling::ObjectInstanceMoving
namestringunique across objects.
sub parts a variable length series of subpart elements.
  element
    object refstringname of an object to include as a subpart in this instance.
    start timefloatbefore this time, the object is in its start position and rotation.
    end timefloatafter this time, the object is in its end position and rotation.
    start rotation3d vector
      xfloatrotation in degrees around x axis. applied first.
      yfloatrotation in degrees around y axis. applied second.
      zfloatrotation in degrees around z axis. applied third.
    start position3d vector
      xfloattranslation in x.
      yfloattranslation in y.
      zfloattranslation in z.
    end rotation3d vector
      xfloatrotation in degrees around x axis. applied first.
      yfloatrotation in degrees around y axis. applied second.
      zfloatrotation in degrees around z axis. applied third.
    end position3d vector
      xfloattranslation in x.
      yfloattranslation in y.
      zfloattranslation in z.
  (...more elements...)

the movement is a linear interpolation of each of position and rotation (rotation is done quaternionically).

objects referred to can be of any object type, and must have been defined prior to this instance. there is a nesting limit of 8 levels.

example files

this renders as a cornell box containing a large brass cylinder and a smaller moving glass cube.

options file

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<?hxa7241-XmlSerializer version='1.0' 'object serialized to xml' 'exact class match required'?>

<!-- all options for controlling a rendering -->
<perceptuum2__control__RenderingOptions type='perceptuum2::control::RenderingOptions'>
   <!-- options that are fixed across different sessions of the same render -->
   <immutableOptions type='perceptuum2::control::RenderingOptionsImmutable'>
      <projection type='perceptuum2::transport::Projection'>
         <!-- point in space where the eye is -->
         <eyePosition type='hxa7241::graphics::Vector3f'>
            <x type='floatingpointsingle'>0</x>
            <y type='floatingpointsingle'>0.5</y>
            <z type='floatingpointsingle'>-2.0</z>
         </eyePosition>
         <!-- the direction vector along which the eye is looking -->
         <lookDirection type='hxa7241::graphics::UnitVector3f'>
            <x type='floatingpointsingle'>0</x>
            <y type='floatingpointsingle'>0</y>
            <z type='floatingpointsingle'>1</z>
         </lookDirection>
         <!-- the direction that defines upright -->
         <upDirection type='hxa7241::graphics::UnitVector3f'>
            <x type='floatingpointsingle'>0</x>
            <y type='floatingpointsingle'>1</y>
            <z type='floatingpointsingle'>0</z>
         </upDirection>
         <!-- width of the screen in scene units -->
         <width type='floatingpointsingle'>1.0</width>
         <!-- distance of the screen from the lens in scene units -->
         <screenDistance type='floatingpointsingle'>1.5</screenDistance>
         <!-- diameter of the lens in scene units -->
         <lensDiameter type='floatingpointsingle'>0.01</lensDiameter>
         <!-- focal length of the lens in scene units -->
         <focalLength type='floatingpointsingle'>2</focalLength>
      </projection>
      <imageWidth type='dwordsigned'>250</imageWidth>
      <imageHeight type='dwordsigned'>250</imageHeight>
      <defaultObjectColor type='hxa7241::graphics::CieXyz'>
         <X type='floatingpointsingle'>0</X>
         <Y type='floatingpointsingle'>0</Y>
         <Z type='floatingpointsingle'>0</Z>
      </defaultObjectColor>
   </immutableOptions>

   <secondsBetweenSaves type='dwordsigned'>1000</secondsBetweenSaves>
   <tonemapAdaptationLuminance type='floatingpointsingle'/>
   <emitterPathNumber type='dwordsigned'>2</emitterPathNumber>
   <photonMapSize type='dwordsigned'>100000</photonMapSize>
   <!-- watts -->
   <lightsourceEmittanceThreshold type='floatingpointsingle'>10</lightsourceEmittanceThreshold>
   <emitterPathLengthLimit type='dwordsigned'>16</emitterPathLengthLimit>
   <emitterPathEndThreshold type='floatingpointsingle'>0</emitterPathEndThreshold>
   <eyePathLengthLimit type='dwordsigned'>16</eyePathLengthLimit>
   <eyePathEndThreshold type='floatingpointsingle'>0</eyePathEndThreshold>

   <displayCharacteristics type='perceptuum2::imaging::DisplayMeasures'>
      <!-- CIE XYZ -->
      <blackPoint type='hxa7241::graphics::CieXyz'>
         <X type='floatingpointsingle'>2.5</X>
         <Y type='floatingpointsingle'>2.5</Y>
         <Z type='floatingpointsingle'>2.5</Z>
      </blackPoint>
      <!-- CIE XYZ -->
      <whitePoint type='hxa7241::graphics::CieXyz'>
         <X type='floatingpointsingle'>85</X>
         <Y type='floatingpointsingle'>85</Y>
         <Z type='floatingpointsingle'>85</Z>
      </whitePoint>
      <!-- CIE xyz -->
      <chromaticitiesXyzX type='hxa7241::graphics::Vector3f'>
         <x type='floatingpointsingle'>0.64</x>
         <y type='floatingpointsingle'>0.30</y>
         <z type='floatingpointsingle'>0.15</z>
      </chromaticitiesXyzX>
      <!-- CIE xyz -->
      <chromaticitiesXyzY type='hxa7241::graphics::Vector3f'>
         <x type='floatingpointsingle'>0.33</x>
         <y type='floatingpointsingle'>0.60</y>
         <z type='floatingpointsingle'>0.06</z>
      </chromaticitiesXyzY>
      <!-- CIE xyz -->
      <chromaticitiesXyzZ type='hxa7241::graphics::Vector3f'>
         <x type='floatingpointsingle'>0.03</x>
         <y type='floatingpointsingle'>0.10</y>
         <z type='floatingpointsingle'>0.79</z>
      </chromaticitiesXyzZ>
      <!-- CIE xyz -->
      <gammaXyz type='hxa7241::graphics::Vector3f'>
         <x type='floatingpointsingle'>1.0</x>
         <y type='floatingpointsingle'>1.0</y>
         <z type='floatingpointsingle'>1.0</z>
      </gammaXyz>
   </displayCharacteristics>

   <isIlluminationLogging type='boolean'>1</isIlluminationLogging>
   <isRasterizerLogging type='boolean'>1</isRasterizerLogging>
</perceptuum2__control__RenderingOptions>

scene file

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<?hxa7241-XmlSerializer version='1.0' 'object serialized to xml' 'exact class match required'?>

<!-- the geometrical and material description of a renderable subject -->
<perceptuum2__modelling__Scene type='perceptuum2::modelling::Scene'>
   <timeBegin type='floatingpointsingle'>0</timeBegin>
   <timeEnd type='floatingpointsingle'>1</timeEnd>
   <!-- 0-1 -->
   <mediumTransparency type='floatingpointsingle'>1</mediumTransparency>
   <mediumRefractiveIndex type='floatingpointsingle'>1</mediumRefractiveIndex>
   <!-- some material definitions -->

   <materials type='std::deque'>
      <!-- luminaire emitter -->
      <element type='perceptuum2::modelling::Material'>
         <name type='string'><![CDATA[emitter]]></name>
         <baseQualities type='perceptuum2::modelling::Qualities'>
            <tangent type='hxa7241::utility::UnitVector3f'>
               <x type='floatingpointsingle'>0</x>
               <y type='floatingpointsingle'>0</y>
               <z type='floatingpointsingle'>0</z>
            </tangent>
            <reflectivityDiffuse type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.75</X>
               <Y type='floatingpointsingle'>0.75</Y>
               <Z type='floatingpointsingle'>0.75</Z>
            </reflectivityDiffuse>
            <reflectivitySpecular type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.0</X>
               <Y type='floatingpointsingle'>0.0</Y>
               <Z type='floatingpointsingle'>0.0</Z>
            </reflectivitySpecular>
            <roughnessX type='floatingpointsingle'>1</roughnessX>
            <roughnessY type='floatingpointsingle'>1</roughnessY>
            <transparency type='floatingpointsingle'>0</transparency>
            <refractiveIndex type='floatingpointsingle'>1</refractiveIndex>
            <emitted type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>2500</X><!-- makes 100w for luminaire -->
               <Y type='floatingpointsingle'>2500</Y>
               <Z type='floatingpointsingle'>2500</Z>
            </emitted>
            <emittedRoughness type='floatingpointsingle'>1</emittedRoughness>
            <brdfClassName type='string'><![CDATA[]]></brdfClassName>
         </baseQualities>
         <colorImageName type='string'/>
         <colorSpecImageName type='string'/>
         <specDiffImageName type='string'/>
         <roughnessXImageName type='string'/>
         <roughnessYImageName type='string'/>
         <transparencyImageName type='string'/>
         <emittedImageName type='string'/>
         <tangentImageName type='string'/>
         <normalImageName type='string'/>
      </element>
      <!-- walls -->
      <element type='perceptuum2::modelling::Material'>
         <name type='string'><![CDATA[wallwhitediffuse]]></name>
         <baseQualities type='perceptuum2::modelling::Qualities'>
            <tangent type='hxa7241::utility::UnitVector3f'>
               <x type='floatingpointsingle'>0</x>
               <y type='floatingpointsingle'>0</y>
               <z type='floatingpointsingle'>0</z>
            </tangent>
            <reflectivityDiffuse type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.75</X>
               <Y type='floatingpointsingle'>0.75</Y>
               <Z type='floatingpointsingle'>0.75</Z>
            </reflectivityDiffuse>
            <reflectivitySpecular type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.0</X>
               <Y type='floatingpointsingle'>0.0</Y>
               <Z type='floatingpointsingle'>0.0</Z>
            </reflectivitySpecular>
            <roughnessX type='floatingpointsingle'>1</roughnessX>
            <roughnessY type='floatingpointsingle'>1</roughnessY>
            <transparency type='floatingpointsingle'>0</transparency>
            <refractiveIndex type='floatingpointsingle'>1</refractiveIndex>
            <emitted type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0</X>
               <Y type='floatingpointsingle'>0</Y>
               <Z type='floatingpointsingle'>0</Z>
            </emitted>
            <emittedRoughness type='floatingpointsingle'>1</emittedRoughness>
            <brdfClassName type='string'><![CDATA[]]></brdfClassName>
         </baseQualities>
         <colorImageName type='string'/>
         <colorSpecImageName type='string'/>
         <specDiffImageName type='string'/>
         <roughnessXImageName type='string'/>
         <roughnessYImageName type='string'/>
         <transparencyImageName type='string'/>
         <emittedImageName type='string'/>
         <tangentImageName type='string'/>
         <normalImageName type='string'/>
      </element>
      <element type='perceptuum2::modelling::Material'>
         <name type='string'><![CDATA[wallreddiffuse]]></name>
         <baseQualities type='perceptuum2::modelling::Qualities'>
            <tangent type='hxa7241::utility::UnitVector3f'>
               <x type='floatingpointsingle'>0</x>
               <y type='floatingpointsingle'>0</y>
               <z type='floatingpointsingle'>0</z>
            </tangent>
            <reflectivityDiffuse type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.617</X>
               <Y type='floatingpointsingle'>0.480</Y>
               <Z type='floatingpointsingle'>0.403</Z>
            </reflectivityDiffuse>
            <reflectivitySpecular type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.0</X>
               <Y type='floatingpointsingle'>0.0</Y>
               <Z type='floatingpointsingle'>0.0</Z>
            </reflectivitySpecular>
            <roughnessX type='floatingpointsingle'>1</roughnessX>
            <roughnessY type='floatingpointsingle'>1</roughnessY>
            <transparency type='floatingpointsingle'>0</transparency>
            <refractiveIndex type='floatingpointsingle'>1</refractiveIndex>
            <emitted type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0</X>
               <Y type='floatingpointsingle'>0</Y>
               <Z type='floatingpointsingle'>0</Z>
            </emitted>
            <emittedRoughness type='floatingpointsingle'>1</emittedRoughness>
            <brdfClassName type='string'><![CDATA[]]></brdfClassName>
         </baseQualities>
         <colorImageName type='string'/>
         <colorSpecImageName type='string'/>
         <specDiffImageName type='string'/>
         <roughnessXImageName type='string'/>
         <roughnessYImageName type='string'/>
         <transparencyImageName type='string'/>
         <emittedImageName type='string'/>
         <tangentImageName type='string'/>
         <normalImageName type='string'/>
      </element>
      <element type='perceptuum2::modelling::Material'>
         <name type='string'><![CDATA[wallgreendiffuse]]></name>
         <baseQualities type='perceptuum2::modelling::Qualities'>
            <tangent type='hxa7241::utility::UnitVector3f'>
               <x type='floatingpointsingle'>0</x>
               <y type='floatingpointsingle'>0</y>
               <z type='floatingpointsingle'>0</z>
            </tangent>
            <reflectivityDiffuse type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.480</X>
               <Y type='floatingpointsingle'>0.617</Y>
               <Z type='floatingpointsingle'>0.403</Z>
            </reflectivityDiffuse>
            <reflectivitySpecular type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.0</X>
               <Y type='floatingpointsingle'>0.0</Y>
               <Z type='floatingpointsingle'>0.0</Z>
            </reflectivitySpecular>
            <roughnessX type='floatingpointsingle'>1</roughnessX>
            <roughnessY type='floatingpointsingle'>1</roughnessY>
            <transparency type='floatingpointsingle'>0</transparency>
            <refractiveIndex type='floatingpointsingle'>1</refractiveIndex>
            <emitted type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0</X>
               <Y type='floatingpointsingle'>0</Y>
               <Z type='floatingpointsingle'>0</Z>
            </emitted>
            <emittedRoughness type='floatingpointsingle'>1</emittedRoughness>
            <brdfClassName type='string'><![CDATA[]]></brdfClassName>
         </baseQualities>
         <colorImageName type='string'/>
         <colorSpecImageName type='string'/>
         <specDiffImageName type='string'/>
         <roughnessXImageName type='string'/>
         <roughnessYImageName type='string'/>
         <transparencyImageName type='string'/>
         <emittedImageName type='string'/>
         <tangentImageName type='string'/>
         <normalImageName type='string'/>
      </element>
      <!-- blocks -->
      <element type='perceptuum2::modelling::Material'>
         <name type='string'><![CDATA[blockbrass]]></name>
         <baseQualities type='perceptuum2::modelling::Qualities'>
            <tangent type='hxa7241::utility::UnitVector3f'>
               <x type='floatingpointsingle'>0</x>
               <y type='floatingpointsingle'>1</y>
               <z type='floatingpointsingle'>0</z>
            </tangent>
            <reflectivityDiffuse type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.169</X>
               <Y type='floatingpointsingle'>0.158</Y>
               <Z type='floatingpointsingle'>0.123</Z>
            </reflectivityDiffuse>
            <reflectivitySpecular type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.372</X>
               <Y type='floatingpointsingle'>0.347</Y>
               <Z type='floatingpointsingle'>0.271</Z>
            </reflectivitySpecular>
            <roughnessX type='floatingpointsingle'>0.05</roughnessX>
            <roughnessY type='floatingpointsingle'>0.16</roughnessY>
            <transparency type='floatingpointsingle'>0</transparency>
            <refractiveIndex type='floatingpointsingle'>1</refractiveIndex>
            <emitted type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0</X>
               <Y type='floatingpointsingle'>0</Y>
               <Z type='floatingpointsingle'>0</Z>
            </emitted>
            <emittedRoughness type='floatingpointsingle'>1</emittedRoughness>
            <brdfClassName type='string'><![CDATA[]]></brdfClassName>
         </baseQualities>
         <colorImageName type='string'/>
         <colorSpecImageName type='string'/>
         <specDiffImageName type='string'/>
         <roughnessXImageName type='string'/>
         <roughnessYImageName type='string'/>
         <transparencyImageName type='string'/>
         <emittedImageName type='string'/>
         <tangentImageName type='string'/>
         <normalImageName type='string'/>
      </element>
      <element type='perceptuum2::modelling::Material'>
         <name type='string'><![CDATA[blockglassy]]></name>
         <baseQualities type='perceptuum2::modelling::Qualities'>
            <tangent type='hxa7241::utility::UnitVector3f'>
               <x type='floatingpointsingle'>0</x>
               <y type='floatingpointsingle'>0</y>
               <z type='floatingpointsingle'>0</z>
            </tangent>
            <reflectivityDiffuse type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.01</X>
               <Y type='floatingpointsingle'>0.01</Y>
               <Z type='floatingpointsingle'>0.01</Z>
            </reflectivityDiffuse>
            <reflectivitySpecular type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0.79</X>
               <Y type='floatingpointsingle'>0.79</Y>
               <Z type='floatingpointsingle'>0.94</Z>
            </reflectivitySpecular>
            <roughnessX type='floatingpointsingle'>0.001</roughnessX>
            <roughnessY type='floatingpointsingle'>0.001</roughnessY>
            <transparency type='floatingpointsingle'>0.89</transparency>
            <refractiveIndex type='floatingpointsingle'>1.52</refractiveIndex>
            <emitted type='hxa7241::graphics::CieXyz'>
               <X type='floatingpointsingle'>0</X>
               <Y type='floatingpointsingle'>0</Y>
               <Z type='floatingpointsingle'>0</Z>
            </emitted>
            <emittedRoughness type='floatingpointsingle'>1</emittedRoughness>
            <brdfClassName type='string'><![CDATA[]]></brdfClassName>
         </baseQualities>
         <colorImageName type='string'/>
         <colorSpecImageName type='string'/>
         <specDiffImageName type='string'/>
         <roughnessXImageName type='string'/>
         <roughnessYImageName type='string'/>
         <transparencyImageName type='string'/>
         <emittedImageName type='string'/>
         <tangentImageName type='string'/>
         <normalImageName type='string'/>
      </element>
   </materials>

   <!-- some object definitions -->
   <objects type='std::deque'>
      <!-- luminaire -->
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectMeshBlock]]></objectType>
         <name type='string'><![CDATA[luminaire]]></name>
         <dimensions type='hxa7241::utility::UnitVector3f'>
            <x type='floatingpointsingle'>0.2</x>
            <y type='floatingpointsingle'>0.01</y>
            <z type='floatingpointsingle'>0.2</z>
         </dimensions>
         <netOrFaces type='boolean'>0</netOrFaces>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>1</x>
            <y type='wordsigned'>1</y>
         </textureCoords>
         <materialRef type='string'><![CDATA[emitter]]></materialRef>
      </element>

      <!-- box -->
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectMeshBlock]]></objectType>
         <name type='string'><![CDATA[wallleft]]></name>
         <dimensions type='hxa7241::utility::UnitVector3f'>
            <x type='floatingpointsingle'>1.0</x>
            <y type='floatingpointsingle'>0.01</y>
            <z type='floatingpointsingle'>1.0</z>
         </dimensions>
         <netOrFaces type='boolean'>1</netOrFaces>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureScale type='floatingpointsingle'>0</textureScale>
         <materialRef type='string'><![CDATA[wallreddiffuse]]></materialRef>
      </element>
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectMeshBlock]]></objectType>
         <name type='string'><![CDATA[wallright]]></name>
         <dimensions type='hxa7241::utility::UnitVector3f'>
            <x type='floatingpointsingle'>1.0</x>
            <y type='floatingpointsingle'>0.01</y>
            <z type='floatingpointsingle'>1.0</z>
         </dimensions>
         <netOrFaces type='boolean'>1</netOrFaces>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureScale type='floatingpointsingle'>0</textureScale>
         <materialRef type='string'><![CDATA[wallgreendiffuse]]></materialRef>
      </element>
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectMeshBlock]]></objectType>
         <name type='string'><![CDATA[wallback]]></name>
         <dimensions type='hxa7241::utility::UnitVector3f'>
            <x type='floatingpointsingle'>1.0</x>
            <y type='floatingpointsingle'>0.01</y>
            <z type='floatingpointsingle'>1.0</z>
         </dimensions>
         <netOrFaces type='boolean'>1</netOrFaces>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureScale type='floatingpointsingle'>0</textureScale>
         <materialRef type='string'><![CDATA[wallwhitediffuse]]></materialRef>
      </element>
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectMeshBlock]]></objectType>
         <name type='string'><![CDATA[floor]]></name>
         <dimensions type='hxa7241::utility::UnitVector3f'>
            <x type='floatingpointsingle'>1.0</x>
            <y type='floatingpointsingle'>0.01</y>
            <z type='floatingpointsingle'>1.0</z>
         </dimensions>
         <netOrFaces type='boolean'>1</netOrFaces>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureScale type='floatingpointsingle'>0</textureScale>
         <materialRef type='string'><![CDATA[wallwhitediffuse]]></materialRef>
      </element>
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectMeshBlock]]></objectType>
         <name type='string'><![CDATA[ceiling]]></name>
         <dimensions type='hxa7241::utility::UnitVector3f'>
            <x type='floatingpointsingle'>1.0</x>
            <y type='floatingpointsingle'>0.01</y>
            <z type='floatingpointsingle'>1.0</z>
         </dimensions>
         <netOrFaces type='boolean'>1</netOrFaces>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureScale type='floatingpointsingle'>0</textureScale>
         <materialRef type='string'><![CDATA[wallwhitediffuse]]></materialRef>
      </element>

      <!-- blocks -->
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectMeshCylinder]]></objectType>
         <name type='string'><![CDATA[cylinderlarge]]></name>
         <diameter type='floatingpointsingle'>0.339</diameter>
         <height type='floatingpointsingle'>0.6</height>
         <isCurved type='boolean'>1</isCurved>
         <resolution type='dwordsigned'>16</resolution>
         <materialRef type='string'><![CDATA[blockbrass]]></materialRef>
      </element>
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectMeshBlock]]></objectType>
         <name type='string'><![CDATA[blocksmall]]></name>
         <dimensions type='hxa7241::utility::UnitVector3f'>
            <x type='floatingpointsingle'>0.3</x>
            <y type='floatingpointsingle'>0.3</y>
            <z type='floatingpointsingle'>0.3</z>
         </dimensions>
         <netOrFaces type='boolean'>1</netOrFaces>
         <textureCoords type='hxa7241::graphics::Vector2'>
            <x type='wordsigned'>0</x>
            <y type='wordsigned'>0</y>
         </textureCoords>
         <textureScale type='floatingpointsingle'>0</textureScale>
         <materialRef type='string'><![CDATA[blockglassy]]></materialRef>
      </element>

      <!-- tilted block -->
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectInstance]]></objectType>
         <name type='string'><![CDATA[blocksmalltilted]]></name>
         <subParts type='std::deque'>
            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[blocksmall]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>30</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>-20</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>0</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0</z>
                  </position>
               </transform>
            </element>
         </subParts>
      </element>
      <!-- moving block -->
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectInstanceMoving]]></objectType>
         <name type='string'><![CDATA[blocksmallmoving]]></name>
         <subParts type='std::deque'>
            <element type='perceptuum2::modelling::ObjectInstanceMoving::Motion'>
               <objectRef type='string'><![CDATA[blocksmalltilted]]></objectRef>
               <startTime type='floatingpointsingle'>0</startTime>
               <endTime type='floatingpointsingle'>1</endTime>
               <startRotation type='hxa7241::graphics::Vector3f'>
                  <x type='floatingpointsingle'>0</x>
                  <y type='floatingpointsingle'>-20</y>
                  <z type='floatingpointsingle'>0</z>
               </startRotation>
               <startPosition type='hxa7241::graphics::Vector3f'>
                  <x type='floatingpointsingle'>0</x>
                  <y type='floatingpointsingle'>0</y>
                  <z type='floatingpointsingle'>0</z>
               </startPosition>
               <endRotation type='hxa7241::graphics::Vector3f'>
                  <x type='floatingpointsingle'>0</x>
                  <y type='floatingpointsingle'>20</y>
                  <z type='floatingpointsingle'>0</z>
               </endRotation>
               <endPosition type='hxa7241::graphics::Vector3f'>
                  <x type='floatingpointsingle'>0</x>
                  <y type='floatingpointsingle'>0</y>
                  <z type='floatingpointsingle'>0</z>
               </endPosition>
            </element>
         </subParts>
      </element>

      <!-- the root object -->
      <element type='perceptuum2::modelling::ObjectInstantiator'>
         <objectType type='string'><![CDATA[perceptuum2::modelling::ObjectInstance]]></objectType>
         <name type='string'><![CDATA[root]]></name>
         <subParts type='std::deque'>
            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[luminaire]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>0</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>-0.1</x>
                     <y type='floatingpointsingle'>0.99</y>
                     <z type='floatingpointsingle'>-0.1</z>
                  </position>
               </transform>
            </element>

            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[floor]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>0</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>-0.5</x>
                     <y type='floatingpointsingle'>-0.01</y>
                     <z type='floatingpointsingle'>-0.5</z>
                  </position>
               </transform>
            </element>
            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[ceiling]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>180</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>-0.5</x>
                     <y type='floatingpointsingle'>1.01</y>
                     <z type='floatingpointsingle'>0.5</z>
                  </position>
               </transform>
            </element>

            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[wallleft]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>90</x>
                     <y type='floatingpointsingle'>90</y>
                     <z type='floatingpointsingle'>0</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>-0.51</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>-0.5</z>
                  </position>
               </transform>
            </element>
            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[wallright]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>90</x>
                     <y type='floatingpointsingle'>-90</y>
                     <z type='floatingpointsingle'>0</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>0.51</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0.5</z>
                  </position>
               </transform>
            </element>
            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[wallback]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>90</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>-0.5</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0.51</z>
                  </position>
               </transform>
            </element>

            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[cylinderlarge]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>0</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>-0.1695</x>
                     <y type='floatingpointsingle'>0</y>
                     <z type='floatingpointsingle'>0</z>
                  </position>
               </transform>
            </element>
            <element type='perceptuum2::modelling::ObjectInstance::SubPart'>
               <objectRef type='string'><![CDATA[blocksmallmoving]]></objectRef>
               <transform type='hxa7241::graphics::Transplace'>
                  <rotation type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>0</x>
                     <y type='floatingpointsingle'>45</y>
                     <z type='floatingpointsingle'>0</z>
                  </rotation>
                  <position type='hxa7241::graphics::Vector3f'>
                     <x type='floatingpointsingle'>0.18</x>
                     <y type='floatingpointsingle'>0.01</y>
                     <z type='floatingpointsingle'>-0.30</z>
                  </position>
               </transform>
            </element>
         </subParts>
      </element>
   </objects>
</perceptuum2__modelling__Scene>

implementation background

a general xml parsing library isnt used. the basic idea is a simple object serialization: each tag structure matches a class, its nested tag structures matching the members, and so on hierarchically like a class, the terminal values matching the primitive values of the object.

that concept its stretched a little to handle class polymorphism.

each class that needs serialization implements four (non-member) functions, the main streaming operator ones simply calling read or write for each member. the serializer class calls the streaming function of the object passed to it — in a pseudo-recursive fashion — until primitives are reached, which are written by the serializer. type matching is partly done with templates, so its less intrusive to the client class.

for example, main/control/RenderingOptions:

SerializerOut& perceptuum2::control::operator<<( SerializerOut& out, const RenderingOptions& obj )
{
    out.write( "immutableOptions",           obj.immutableOptions_m,
        "options that are fixed across different sessions of the same render" );

    out.write( "secondsBetweenSaves",        obj.secondsBetweenSaves_m );
    out.write( "tonemapAdaptationLuminance", obj.tonemapAdaptationLuminance_m, "cd/m2" );

    /// ... all the other members ...

    return out;
}


SerializerIn& perceptuum2::control::operator>>( SerializerIn& in, RenderingOptions& obj )
{
    in.read( "immutableOptions",           obj.immutableOptions_m );

    in.read( "secondsBetweenSaves",        obj.secondsBetweenSaves_m );
    in.read( "tonemapAdaptationLuminance", obj.tonemapAdaptationLuminance_m );

    /// ... all the other members ...

    return in;
}


const char* RenderingOptions::CLASS_NAME()
{
    static const char CLASS_NAME[] = "perceptuum2::control::RenderingOptions";
    return CLASS_NAME;
}


const char* RenderingOptions::CLASS_DESCRIPTION()
{
    static const char CLASS_DESCRIPTION[] = "all options for controlling a rendering";
    return CLASS_DESCRIPTION;
}

primary code class:

  • utility/XmlSerializerIn

secondary code classes:

  • utility/XmlSerializerOut
  • utility/SerializerIn
  • utility/SerializerOut

references