-
Notifications
You must be signed in to change notification settings - Fork 8
Asset transforms
The nodes of the asset tree specify the object properties and the geometric transforms that translate, rotate, and scale these objects. Generally, the objects are in the leafs of the tree; the transformations are stored in a branch node. The branch node can store multiple transformations of each type.
The combination of transforms is applied to all of the objects beneath that node in the order specified in the node. The information specified in a transform node is written into a PBRT file by piWrite. Remember that the order of the transformations matters, most importantly the order of the scale transformations.
To help the user understand the impact of the transformations we added recipe.set() and recipe.get() methods that ask for the 'world position', which accounts for the combination of all the transformations defined for an asset.
Consider a scene with a single colored cube. thisR = piRecipeDefault('scene name','coloredCube');
The cube has six sides and each is represented as a leaf in the asset tree. All the sides are all underneath a branch node. We can visualize the tree organization with the command thisR.show;
, which brings up an interactive window.
Clicking on one of the nodes in the window prints the node struct into your command window. Here is the result of clicking on the 0003ID_Cube_B node
--------Selected Node-----------
struct with fields:
type: 'branch'
name: '0003ID_Cube_B'
size: [1×1 struct]
scale: {[1.0000 1.0000 1.0000]}
translation: {[3×1 double]}
rotation: {[4×3 double]}
concattransform: []
motion: []
transorder: 'TRS'
We can read the node from the tree with a thisR.get() command. To read a node, we can use either the whole name - including the ID - or just the part of the name after the 'XXXXID_' string.
nodeName = 'Cube_B'; % Notice that this is the part after the XXXXID_ component of the name.
thisNode = thisR.get('asset',nodeName);
The name of the node in this case did not use the ID. This is convenient because the value of the ID of the node change as we edit the assets. For example, we might insert another node. But the part after the ID should say the same.
A branch node can specify multiple translations, rotations and scales. The parameters for each of these is stored in a cell array with the corresponding name. Here is a branch node after we have applied several transforms.
>> thisR.get('node',assetName)
ans =
struct with fields:
type: 'branch'
name: '0003ID_Cube_B'
size: [1×1 struct]
scale: {[1.0000 1.0000 1.0000] [1.3000 1.3000 1.3000]}
translation: {[3×1 double] [3×1 double]}
rotation: {[4×3 double]}
concattransform: []
motion: []
transorder: 'TRSTS'
>>
Each of the slots (translation, rotation, scale) is a cell array. Each cell entry specifies the parameters for one operation. The order of operations is specified in the slot 'transorder'. In this example, we apply a 'TRSTS' order (S for scale, T for translate, R for rotate). There are two translate and two scale operations, and thus the cell arrays for translation and scale have two entries.
To apply a translation to a branch node, we use the command
thisR.set('node', thisNode.name, 'translate', [0.3, 0.3, 0]); % X,Y,Z Units are meters
As a convenience, we can set the position of an object to a specific place in the image, not just translate it. To do this use
thisR.set('node',thisNode.name,'world position',[1, 2, 1.3]);
To visualize object positions use piAssetGeometry(thisR)
.
To print a list of the positions and other object properties use thisR.show('objects')
.
>> thisR.show('objects');
material positions (m) sizes (m)
__________________ ___________________ __________________
0004ID_001_Cube_O {'YellowMaterial'} {'0.41 -0.11 3.06'} {'0.65 0.00 0.65'}
0005ID_002_Cube_O {'GreenMaterial' } {'0.41 -0.11 3.06'} {'0.00 0.65 0.65'}
0006ID_003_Cube_O {'BlueMaterial' } {'0.41 -0.11 3.06'} {'0.65 0.65 0.00'}
0007ID_004_Cube_O {'RedMaterial' } {'0.41 -0.11 3.06'} {'0.00 0.65 0.65'}
0008ID_005_Cube_O {'PurpleMaterial'} {'0.41 -0.11 3.06'} {'0.65 0.65 0.00'}
0009ID_006_Cube_O {'CyanMaterial' } {'0.41 -0.11 3.06'} {'0.65 0.00 0.65'}
Rotations are applied to an object in its own coordinate frame. The rotation angles are specified in degrees (positive is counter clockwise).
thisR.set('node', thisNode.name, 'translate', [0 0 45]); % X,Y,Z Units are deg
The scale transformation applies to all actions below this branch, meaning both the object size and the translation size. It is best to have the scale be last because it applies to both size and translation. That's how PBRT works.
thisR.set('node', thisNode.name, 'scale', [1.5 1.5 1.5]); % X,Y,Z factors
The node.transorder defines the sequence of transformations that will be printed in the PBRT file.
ISET3d development is led by Brian Wandell's Vistalab group at Stanford University and supported by contributors from other research institutions and industry.