Tutorial #12: Aligner

Dieses Tutorial beschreibt, wie einzelne Objekte automatisiert mit dem Graph::Aligner Knoten ausgerichtet werden können.

ContainerAlignment

Ganz generell und unabhängig vom Aligner Graphenknoten kann bei einigen Objekten (wie etwa PlaneGeometry oder TextGeometry) der Ankerpunkte für die Positionierung mit den Attributen containerAlignmentX und containerAlignmentY angepasst werden. Standardmäßig liegt der Ankerpunkt immer im Zentrum.

Die gültigen Werte sind im Enum IEnums::AlignmentX bzw. IEnums::AlignmentY aufgelistet:

  • UNDEFINED
  • LEFT (oder BOTTOM für Y)
  • CENTER (default)
  • RIGHT (oder TOP für Y)
  • NEGATIVE
  • POSITIVE

Zur Veranschaulichung positionieren wir drei Planes an derselben Position 0/0/0 und ändern lediglich die Parameter containerAlignmentX und containerAlignmentY (sowie den Farbparameter).

<!-- 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"/>

Als Ergebnis erhalten wir drei Planes die entsprechend ihren Alignment-Vorgaben unterschiedlich positioniert werden. Alle drei Planes haben die gleiche Ankerposition in der virtuellen Welt (0/0/0), allerdings liegt der Ankerpunkt bei der blauen Plane im Zentrum, bei der roten links oben und bei der grünen rechts unten.

tut0112_v1.png
containerAlignment

Aligner Graphenknoten

Der Aligner Graphenknoten kann verwendet werden um Objekte entlang einer vorgegebenen Achse automatisch anordnen zu lassen. Dabei berechnet der Aligner Knoten für alle seine direkten Kindknoten (bzw. Sub-Graphen) die entsprechende Container-Größe und ordnet sie nacheinander an. Als erstes Beispiel ordnen wir drei PlaneGeometry-Objekte entlang der Y-Achse an.

<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>

Das Zentrum des Aligner Knoten legen wir nach links an die Position -200/0/0. Die PlaneGeometry Objekte werden entlang der Y-Achse des Aligners angeordnet. Die anderen Koordinatenwerte (X/Z) bleiben unverändert.

tut0112_v2.png
Aligner

Mit dem Attribut objectAlignment können auch die Koordinatenwerte der verbleibenden Achsen (in unserem Fall X/Z) angepasst werden. Beispielsweise bewirkt die Angabe objectAlignmentX="LEFT", dass alle Objekte entlang des linken Rands des Aligners ausgerichtet werden.

Zur Veranschaulichung erstellen wir einen neuen Aligner Knoten, bei dem das Attribut objectAlignmentX gesetzt ist. Durch die Angabe von posY="150" und containerAlignmentY="TOP" wird der obere Rand des Aligner an die Position 150 gelegt. Die Angabe von order="DESCENDING" bewirkt eine absteigende Anordnung.

<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

Mit dem Attribut spacing kann ein Abstand zwischen den angeordneten Objekten definiert werden und mit dem Attribut padding kann ein äußerer Rand für den Aligner festgelegt werden.

<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

Die resultierende Größe des Aligner nach dem Anordnen kann mit der Methode GetBoundingVolume() abgefragt werden. Allerdings muss die Abfrage in der Methode OnFinishTick() und nicht in der Methode OnProcessTick() erfolgen, da das Ausrichten der Objekte im Aligner erst nach erfolgter Abarbeitung von OnProcessTick() durchgeführt wird. Eine Abfrage in OnProcessTick() liefert daher immer die Werte des vorherigen Frames.

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;
    }
}

Als Ergebnis erhalten wir für den Aligner aligner03 und das erste Frame:

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

Für alle weiteren Frames liefert OnProcessTick() und OnFinishTick() dasselbe Ergebnis, da sich in unserem Beispiel die Inhalte des Aligner nicht mehr ändern und damit das IBoundingVolume gleich bleibt. Durch Drücken der Taste P kann das IBoundingVolume für ein weiteres Frame ausgegeben werden:

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

Wir können das berechnete IBoundingVolume noch optisch mit einem PlaneGeometry Knoten verifizieren:

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


Copyright © 2011-2018 Spraylight GmbH.