Tutorial #12: Aligner

This tutorial describes how to automatically align objects utilizing the Graph::Aligner node.

ContainerAlignment

Independently from the Aligner graph node, several graph nodes (e.g. PlaneGeometry or TextGeometry) allow the adjustment of their anchor point via the containerAlignmentX and containerAlignmentY attributes. By default the anchor point is in the center.

Valid values are listed in the enums IEnums::AlignmentX and IEnums::AlignmentY:

  • UNDEFINED
  • LEFT (or BOTTOM for Y)
  • CENTER (default)
  • RIGHT (or TOP for Y)
  • NEGATIVE
  • POSITIVE

As an example we place three planes on the same position 0/0/0 and change merely the parameter containerAlignmentX and containerAlignmentY (as well as the color parameter).

<!-- blue plane -->
<PlaneGeometry id="box_plane_01"
               posX="0" posY="0" scaleFactor="100"
               parametersSlot="0" materialSlot="2"/>
<!-- red plane -->
<PlaneGeometry id="box_plane_02"
               posX="0" posY="0" scaleFactor="100"
               parametersSlot="1" materialSlot="2"
               containerAlignmentX="LEFT" containerAlignmentY="TOP"/>
<!-- green plane -->
<PlaneGeometry id="box_plane_03"
               posX="0" posY="0" scaleFactor="100"
               parametersSlot="2" materialSlot="2"
               containerAlignmentX="RIGHT" containerAlignmentY="BOTTOM"/>

As result we get three planes which are differently positioned according to their alignment specification. The anchor world position is the same for all three planes (0/0/0) but the anchor point on the planes differ. For the blue plane the anchor point is in the center, for the red plane it is top left and for the green plane it is bottom right.

tut0112_v1.png
containerAlignment

Aligner Graph Node

The Aligner graph node allows to automatically arrange objects along one dedicated main axis. The Aligner node calculates the bounding box of its child nodes (or sub graphs) and arranges them consecutively. As a first example let us arrange three PlaneGeometry objects along the Y axis.

<Aligner id="aligner01"
         axis="Y" posX="-200" >
    <!-- blue plane -->
    <PlaneGeometry scaleFactor="100" parametersSlot="0" materialSlot="2"/>
    <!-- red plane -->
    <PlaneGeometry scaleFactor="100" parametersSlot="1" materialSlot="2"
                   containerAlignmentX="LEFT" containerAlignmentY="TOP"/>
    <!-- green plane -->
    <PlaneGeometry scaleFactor="100" parametersSlot="2" materialSlot="2"
                   containerAlignmentX="RIGHT" containerAlignmentY="BOTTOM"/>
</Aligner>

We move the center of the Aligner node to the left at position -200/0/0. The PlaneGeometry objects will be arranged along the Y axis automatically. The other coordinate values (X/Z) remain unchanged.

tut0112_v2.png
Aligner

The attribute objectAlignment can be used to also adjust the other coordinate values (in our case X and Z). For example, specifying the parameter objectAlignmentX="LEFT" causes an object alignment along the left margin.

To illustrate that feature, we create a new Aligner node and specify the objectAlignmentX attribute. By specifying posY="150" and containerAlignmentY="TOP" the upper boundary of the Aligner node is placed to position 150. The parameter order="DESCENDING" causes a descending order.

<Aligner id="aligner02"
     axis="Y"  posX="-350" posY="150" containerAlignmentY="TOP"
     objectAlignmentX="LEFT" 
     order="DESCENDING">
    <!-- blue plane -->
    <PlaneGeometry scaleFactor="100" parametersSlot="0" materialSlot="2"/>
    <!-- red plane -->
    <PlaneGeometry scaleFactor="100" parametersSlot="1" materialSlot="2"
                   containerAlignmentX="LEFT" containerAlignmentY="TOP"/>
    <!-- green plane -->
    <PlaneGeometry scaleFactor="100" parametersSlot="2" materialSlot="2"
                   containerAlignmentX="RIGHT" containerAlignmentY="BOTTOM"/>
</Aligner>
tut0112_v3.png
Aligner objectAlignment

The attribute spacing can be used to define a distance between the aligned object and the attribute padding defines an outer border for the Aligner node.

<Aligner id="aligner03"
         axis="Y" posX="250" posY="250" containerAlignmentY="TOP"
         containerSizeX="200" order="DESCENDING" spacing="20">
    <TextGeometry
    materialSlot="4" systemFontName="SansBold"
    fontSize="20"
    textColor="255i, 255i, 255i, 255i"
    backgroundColor="0i, 0i, 0i, 0i"
    text="Line 1 centered"
    enableWordWrapping="yes"
    containerSizeX="200"
    textAlignmentX="CENTER"
    />
    <TextGeometry
    materialSlot="4" systemFontName="SansBold"
    fontSize="20"
    textColor="255i, 255i, 255i, 255i"
    backgroundColor="0i, 0i, 0i, 0i"
    text="A auto wrapped text line"
    enableWordWrapping="yes"
    containerSizeX="200"
    textAlignmentX="CENTER"
    />
    <TextGeometry
    materialSlot="4" systemFontName="SansBold"
    fontSize="20"
    textColor="255i, 255i, 255i, 255i"
    backgroundColor="0i, 0i, 0i, 0i"
    text="A manually&#10;wrapped line"
    enableWordWrapping="yes"
    containerSizeX="200"
    textAlignmentX="CENTER"
    />
    <TextGeometry
    materialSlot="4" systemFontName="SansBold"
    fontSize="20"
    textColor="255i, 255i, 255i, 255i"
    backgroundColor="0i, 0i, 0i, 0i"
    text="Left aligned text"
    enableWordWrapping="yes"
    containerSizeX="200"
    textAlignmentX="LEFT"
    />
    <TextGeometry
    materialSlot="4" systemFontName="SansBold"
    fontSize="20"
    textColor="255i, 255i, 255i, 255i"
    backgroundColor="0i, 0i, 0i, 0i"
    text="Right aligned text"
    enableWordWrapping="yes"
    containerSizeX="200"
    textAlignmentX="RIGHT"
    />
    <Node>
        <PlaneGeometry scaleFactor="100" parametersSlot="0" materialSlot="2" containerAlignmentY="TOP"/>
        <PlaneGeometry scaleFactor="100" parametersSlot="1" materialSlot="2"
        containerAlignmentX="LEFT" />
        <PlaneGeometry posX="25" posY="-25" scaleFactor="100" parametersSlot="2" materialSlot="2"
                       containerAlignmentX="RIGHT" containerAlignmentY="BOTTOM"/>
    </Node>
</Aligner>
tut0112_v4.png
Aligner spacing

The final size of the Aligner can be queried with the method GetBoundingVolume(). The request should be done in the OnFinishTick() method and not in the OnProcessTick() method because the automatic alignment of the Aligner objects is performed after the method OnProcessTick() has been executed. Hence a request in the OnProcessTick() method would return the values of the previous frame.

void App::AlignerLogic::OnFinishTick(const Logic::IState* state)
{
    // Size
    if (mPrintBoundingValues)
    {
        const Graph::IBoundingVolume* boundingVolume = mAligner->GetBoundingVolume();
        const Graph::Box& box = boundingVolume->GetInnerLocalBox();
        const Graph::Vector& min = box.GetMinimum();
        const Graph::Vector& max = box.GetMaximum();
        Debug::Trace("From OnFinishTick:");
        Debug::Trace("  Bounding X %f / %f", min.x, max.x);
        Debug::Trace("  Bounding Y %f / %f", min.y, max.y);
        Debug::Trace("  Bounding Z %f / %f", min.z, max.z);
        mPrintBoundingValues = false;
    }
}

The result for the Aligner aligner03 and the first frame is:

From OnProcessTick:
Bounding X 0.000000 / 0.000000
Bounding Y 0.000000 / 0.000000
Bounding Z 0.000000 / 0.000000
From OnFinishTick:
Bounding X -100.000000 / 100.000000
Bounding Y -450.000000 / 0.000000
Bounding Z 0.000000 / 0.000000

For all further frames the call in the method OnProcessTick() and the call in the method OnFinishTick() return the same values. This is because the child nodes of the Aligner do not change and therefore the IBoundingVolume stays the same. The IBoundingVolume for another frame can be printed out by pressing the key P:

From OnProcessTick:
Bounding X -100.000000 / 100.000000
Bounding Y -450.000000 / 0.000000
Bounding Z 0.000000 / 0.000000
From OnFinishTick:
Bounding X -100.000000 / 100.000000
Bounding Y -450.000000 / 0.000000
Bounding Z 0.000000 / 0.000000

We can optically verify the calculated IBoundingVolume with a PlaneGeometry node:

<PlaneGeometry posX="250" posY="250" containerAlignmentY="TOP"
                scaleFactorX="200" scaleFactorY="450"
                parametersSlot="3" materialSlot="2" depthOrder="-1" />
tut0112_v5.png
Aligner


Copyright © 2011-2024 Spraylight GmbH.