Ressource Objekt Typen

Diese Seite gibt einen Überblick über die verschiedenen Typen von Ressourcenobjekten, die von der Murl Engine importiert und verwendet werden können. Die einzelnen Typen werden beschrieben und mögliche Eingabedateiformate behandelt.

Die folgenden Abschnitte beinhalten typspezifische Informationen darüber, wie man verschiedene Ressourcenobjekte definiert und parametrisiert. Diese Ressourcenobjekte müssen üblicherweise in logische Ressourcen-Pakete gruppiert werden, damit diese von der Murl Engine benutzt werden können. Ein Grundverständnis über die Erstellung solcher Pakete sollte bereits vorhanden sein. Weitere Details dazu befinden sich im Cube V2 Tutorial und in der Beschreibung der XML Ressourcen-Pakete.

Die folgende Liste zeigt die verschiedenen Typen der Ressourcenobjekte, die im weiteren Verlauf näher erklärt werden:

Graph-Ressourcen

Da der Szenengraph ein zentraler Bestandteil der Murl Engine ist, ist es notwendig irgendwo den Inhalt dieses Szenegraphen zu definieren. Neben der Möglichkeit diesen vom Programmcode zu generieren, bieten XML-Graphen-Ressourcendateien einen einfachen Weg, um die Struktur eines Szenegraphen festzulegen.

Graph-Ressourcen sind in der Form von Resource::IGraph Objekten verfügbar, wenn sie vom Code aus aufgerufen werden.

XML-Graphen

XML-Graphen-Ressourcendateien sind durch ihr <Graph> Wurzelelement gekennzeichnet. Innerhalb dieses Elements ist es möglich, die Knoten im aktuellen Szenegraphen hierarchisch zu definieren, indem man Knotenelemente mit typspezifischen Tags und Attributen erstellt.

Die Murl Engine bietet eine Vielzahl von verschiedenen Knotenklassen, die instanziiert werden können. Eine Liste aller verfügbaren Knoten mit Graph::Node als Basisklasse befindet sich unter Murl::Graph Node Classes in der API Referenz. Die API Dokumentation dieser Knoten beinhaltet auch einen Abschnitt "XML Elements", der genau beschreibt welche Tags und Attribute zu verwenden sind. Weitere Informationen über verfügbare Tags und deren Attribute befinden sich unter XML Graph Node Tags und XML Graph Node Attributes.

Das folgende Beispiel zeigt den Inhalt einer XML-Datei eines einfachen Szenegraphen:

<?xml version="1.0" ?>

<Graph>
    <View id="view"/>
    <PerspectiveCamera viewId="view" fieldOfViewX="2">
        <FixedProgram id="prog"/>
        <Material programId="prog">
            <PlaneGeometry posZ="-1"/>
        </Material>
    </PerspectiveCamera>
</Graph>

Weitere Beispiele befinden sich im Cube V2 und in anderen Tutorials.

Hinweis: Es ist auch möglich, den Namespace eines Graphenknotens für seinen Tag zu definieren (ausgenommen dem top level Namespace Murl), z.B. ein Material Knoten kann auch wie folgt festgelegt werden:

    <Graph::Material programId="prog">
        <PlaneGeometry posZ="-1"/>
    </Graph::Material>

Solange nur mit den vordefinierten Standard-Knoten der Murl Engine gearbeitet wird, ist dies nicht notwendig. Wenn aber beispielsweise eine eigene Materialklasse mit demselben Namen erstellt wird (siehe Erstellen eigener Graphenknoten), ist es unter Umständen erforderlich, den Namespace dieses Knotens anzugeben, z.B.

    <MyApp::Material programId="prog"/>

Außerdem, werden möglicherweise Bibliotheken für die Murl Engine als Add-on veröffentlicht, die diesen Schritt erfordern.

Wird der Namespace für ein Tag nicht angegeben, sucht die Engine nach einen Knoten mit diesem Namen und verwendet den ersten passenden Knoten für das Erstellen der Instanz. Es ist sichergestellt, dass alle Knoten, die unter XML Graph Node Tags gelistet sind, zuerst registriert und daher auch zuerst gefunden werden. Das bedeutet, dass, wenn man z.B. ein <Material> Element definiert, wird immer ein Murl::Graph::Material Knoten erstellt, auch wenn man später ein eigenes MyApp::Material registriert (außer man macht die Registrierung des Murl::Graph::Material Knotens manuell rückgängig, was jedoch nur mit großer Sorgfalt gemacht werden sollte).

Mit XML-Graphendateien ist es auch möglich, eigene Attribute zu definieren. Diese werden evaluiert, sobald ein (Sub-)Graph aus einer solchen Datei instanziiert wird. Weitere Details befinden sich unter Instanzen und Referenzen.

Bild- bzw. Grafikressourcen

Grafikressourcen haben die folgenden Eigenschaften, wenn sie mittels eines <Resource> Elements in einer package.xml Datei erstellt wurden:

  • outputStreamFormat: Dieses Attribut akzeptiert eine der verfügbaren IEnums::VideoStreamFormat Enumerationsstringwerte, welche das Grafikformat definiert, in welchem die Grafik im Package gespeichert ist (derzeit nur PNG und WEBP). Das heißt, es ist möglich, z.B. eine PNG-Grafik zu einer WEBP-Grafik zum Ladezeitpunkt zu konvertieren:
    <Resource id="img1" fileName="test.png" outputStreamFormat="WEBP"/>
    
    Beachte: Wenn das binäre .murlpkg Package mittels des Resource Packer Tools erstellt wird, wird diese Konvertierung nur einmal durchgeführt und die Grafikdaten innerhalb der .murlpkg Datei werden in diesem Fall als WEBP-Grafik gespeichert. Wird dieses Attribut nicht definiert, wird das Eingabeformat benutzt und es erfolgt keine Konvertierung.
  • outputPixelFormat: Dieses Attribut definiert bei Verwendung des PNG- oder WEBP-Ausgabeformats jenes Pixelformat, das für die gespeicherte Grafik benutzt wird. Die derzeit vefügbaren Werte aus der IEnums::PixelFormat Enumeration sind "R8_G8_B8" und "R8_G8_B8_A8".
  • outputCompressionType: Wenn WEBP als Ausgabeformat ausgewählt wird, definiert dieses Attribut den internen Kompressionstyp der auszugebenden Grafik aus der IEnums::CompressionType Enumeration. Die derzeit verfügbaren Werte sind "LOSSLESS" und "LOSSY".
  • outputCompressionQuality: Dies betrifft auch nur das WEBP-Ausgabeformat und definiert einen Qualitätsfaktor, der für die Kodierung verwendet wird. Die möglichen Werte befinden sich im Bereich 0–100, wobei ein höherer Wert eine bessere Qualität, aber auch eine größere Dateigröße, bedeutet.

Grafikressourcen sind in Form von Resource::IImage Objekten verfügbar, wenn sie vom Code aus aufgerufen werden.

PNG-, WEBP- und DDS-Grafiken

PNG- und WEBP-Grafiken können direkt verwendet werden, indem man ihren Dateinamen in einem <Resource> Element mittels des fileName Attributes definiert. Mit wenigen Einschränkungen gilt das auch für DDS-Grafiken (DirectDraw Surface). Alle drei dieser Formate können Alphakanal-Informationen (Transparenz) speichern. Transparente bzw. fast-transparente Pixel mit "falschen" Farbinformationen können bei der Skalierung von Bildern zu Farbfehlern führen. Diese falschen Farbinformationen werden oft durch Grafikmanipulationsprogrammen, wie beispielsweise GIMP oder Photoshop verursacht, die die Hintergrund-Mattierung nicht richtig verarbeiten.

Es gibt zwei Attribute, die zum Ladezeitpunkt der Grafik eine Art "Korrekturschritt" durchführen können:

  • matteColor: Dieses Attribut kann zur Definition eines Matte-Farbwertes verwendet werden, der auf alle (fast-)transparenten Pixel wirkt, d.h. mit einem Alphawert nahe Null.
  • matteThreshold: Dieses Attribut definiert den Schwellenwert für die Transparenz im Bereich 0–255. Das matteColor Attribut wird auf jeden Pixel angewandt, bei dem der Alphawert gleich oder kleiner als der angegebenen Schwellenwert ist, d.h. ein Schwellenwert von 2 berücksichtigt nur Pixel mit einem Alphawert von 0, 1 oder 2. Der Standardschwellenwert ist auf 8 festgelegt. Definiert man dieses Attribut ohne matteColor, so hat das keine Auswirkung und die Angabe wird ignoriert.
Zu beachten
Beide Attribute haben keine Auswirkung, wenn die Eingabegrafik keinen Alphakanal besitzt.

JPG-Grafiken

Genau wie PNG-, WEBP- und DDS-Grafiken, können auch JPG-Grafiken direkt mittels des fileName Attributs eines Ressourcenelements benutzt werden. JPG-Grafiken können keine Alphainformationen speichern, erreichen dafür aber eine hohe Komprimierung auf Basis einer verlustbehafteten Komprimierungsverfahrens. Wird beides benötigt, empfiehlt es sich, die Grafiken im immer beliebter werdenden WEBP-Format zu speichern.

PVR-Grafiken

PVR- (oder, genauer gesagt, PVRTC-) Grafiken sind speziell komprimierte Textur-Grafikdaten, die von der GPU direkt benutzt werden können, ohne das diese vorher im Speicher dekomprimiert werden müssen. PVR-Grafiken haben eine hohe Kompressionsrate und benötigen im Vergleich zu anderen Formaten nur einen Bruchteil des Speicherplatzes.

Dieses Format wird jedoch nur von bestimmten Grafikprozessoren unterstützt, z.B PowerVR Chips von Imagination Technologies (imgtec.com), die üblicherweise in Mobilgeräten zu finden sind.

Wenn man sich für PVR-Grafiken entscheidet, muss zuvor sichergestellt werden, dass diese Grafiken nur auf jenen Mobilgeräten benutzt werden, die sie auch unterstützen. Das bedeutet, dass man für alle anderen Geräte eine Ersatzgrafik zur Verfügung stellen sollte, z.B. indem man zwei Ressourcen, welche dieselbe ID aber unterschiedliche Bedingungen haben, verwenden:

<Resource id="img1" fileName="test.pvr" includeForGpus="POWERVR"/>
<Resource id="img1" fileName="test.png"/>

Auf der oben erwähnten Website kann man im Developer-Bereich das PowerVR SDK Toolkit finden, mit dem man PVRTC-Grafiken erstellen und konvertieren kann.

Zu beachten
PVR-Grafiken können zum Ladezeitpunkt nicht in ein anderes Format konvertiert werden.

XML-Grafiken

XML-Grafiken sind eine Besonderheit der Murl Engine. Mit ihnen ist es möglich, andere bereits vorhandene Grafiken sinnvoll zu einer neuen Grafik zu kombinieren.

Bei der Implementierung von fortgeschrittenen Rendertechniken ist es häufig erwünscht, dass verschiedene pixelbasierte Informationen in eine einzige 4-Komponententexturgrafik (rot, grün, blau und Alpha) gespeichert werden. Dies ist üblicherweise viel effizienter als separate Texturen von einem GPU-Shader aufzurufen.

Angenommen, man möchte die folgenden Spezialtexturen in einem Relief-Shader benutzen:

  • Eine Normal Map, die den X-Wert eines Normalvektors im roten, den Y-Wert im grünen und den Z-Wert im blauen Farbkanal beinhaltet.
  • Eine Height Map in Graustufen, welche die Höheninformation enthält
  • Eine Specular Map, welche die Reflexionseigenschaft ("Glossiness“) für jeden Pixel definiert und im grünen Kanal gespeichert ist

Somit stehen dem Shader fünf relevante Komponenten zur Verfügung. Lässt man die Y-Komponente der Normal Map weg (welche leicht zur Laufzeit aus den anderen beiden Komponenten berechnet werden kann), erhält man nur mehr vier Komponenten, welche in einer einzigen RGBA-Grafik gespeichert werden können. Die X-Komponente der Normal Map soll nun im roten Kanal gespeichert werden, die Z-Komponente im grünen Kanal, die Höheninformation aus der Height Map im blauen Kanal und die Glossiness im Alphakanal.

Für die Definition der XML-Grafik erstellen wir eine XML-Datei:

<?xml version="1.0" ?>

<Image sizeX="256" sizeY="256">

  <!-- Define input images -->
  <Source id="nrmmap" imageFileName="normal_map.png"/>
  <Source id="hgtmap" imageFileName="height_map.png"/>
  <Source id="spcmap" imageFileName="specular_map.png"/>

  <!-- Red and green channels receive normal X (red) and Z (blue) -->
  <Destination destinationComponent="RED" sourceId="nrmmap" sourceComponent="RED"/>
  <Destination destinationComponent="GREEN" sourceId="nrmmap" sourceComponent="BLUE"/>

  <!-- Blue channel receives height map (gray scale, any component we like) -->
  <Destination destinationComponent="BLUE" sourceId="hgtmap" sourceComponent="RED"/>

  <!-- Alpha channel receives green channel from specular map -->
  <Destination destinationComponent="ALPHA" sourceId="spcmap" sourceComponent="GREEN"/>

</Image>

Die einzelnen Dateien, die mittels des imageFileName Attributes definiert sind, werden relativ zur XML-Grafikdatei verwiesen. Möchte man die neue XML-Grafik in einem Ressourcenpackage benutzen, genügt es zu schreiben:

<Resource id="img1" fileName="combo_image.xml"/>

Dabei wird für diesen Fall angenommen, dass sich die package.xml, combo_image.xml und PNG-Dateien alle im selben Verzeichnis befinden.

Zu beachten
Die einzelnen Eingabegrafiken müssen nicht notwendigerweise dieselbe Größe aufweisen. Durch die Verwendung der Attribute sizeX und sizeY des <Image> Elementes, wird in diesem Beispiel die Größe der Ausgabegrafik auf 256 x 256 Pixel festgelegt. Ist das sizeX Attribut nicht vorhanden, müssen alle Eingabegrafiken dieselbe Breite haben und auch die auszugebende Grafik erhält infolge diese Breite. Dasselbe gilt für das sizeY Attribut und die Höhe der Grafik.

Werden nicht alle vier Kanäle ("RED", "GREEN", "BLUE" und "ALPHA") als destinationComponent genutzt, werden die ausgelassenen Kanäle in der Ausgabegrafik auf null (schwarz) gesetzt.

Die matteColor und matteThreshold Attribute können auch auf XML-Grafiken angewandt werden (als Nachbearbeitungsschritt nachdem alle Kanäle kombiniert wurden). Weitere Informationen zu diesen beiden Attributen finden sich im oberen Teil dieses Guides.

Atlas-Ressourcen

Grundsätzlich ist ein Atlas-Ressourcen-Objekt eine Menge von einem oder mehreren Rechtecken. Jedes Rechteck speichert die folgenden 32-Bit-Gleitkommawerte:

  • Start- und Endkoordinate des Bildschirms in X-Richtung
  • Start- und Endkoordinate des Bildschirms in Y-Richtung
  • Start- und Endkoordinaten der Textur in X-Richtung
  • Start- und Endkoordinaten der Textur in Y-Richtung

Somit speichert jedes Rechteck acht einzelne Werte. Die Rechtecke sind mit dem Index 0 bis (n-1) indiziert.

Ein Atlas und seine Rechtecke haben an sich keine konkrete Bedeutung und können für viele Zwecke eingesetzt werden. Beispielsweise werden sie dazu verwendet, um rechteckige Bereiche eines Graph::FlatTexture Objektes auszuwählen und diese dann mit einem Graph::PlaneSequenceGeometry Objekt zu rendern. Eine genauere Erklärung findet sich im Tutorial #08: Animated Images.

Atlas-Ressourcen sind in Form von Resource::IAtlas Objekten verfügbar, wenn sie vom Code aus aufgerufen werden.

XML-Atlas

XML-Atlas-Ressourcendateien sind durch ihr <Atlas> Wurzelelement gekennzeichnet. Einzelne Rechtecke können als direkte Kinder des Wurzelelements definiert werden, indem man das <Rectangle> Element benutzt. Dieses akzeptiert die folgenden Attributkombinationen, um die Bildschirmkoordinaten in X-Richtung zu definieren:

  • coordX1 und coordX2: im Bereich von X1 bis X2
  • coordX1 und coordSizeX: im Bereich von X1 bis (X1 + SizeX)
  • coordSizeX und coordX2: im Bereich von (X2 - SizeX) bis X2
  • coordOffsetX und coordSizeX: im Bereich von (OffsetX - SizeX / 2) bis (OffsetX + SizeX / 2)

Ersetzt man "X" mit "Y", gelten dieselben Regeln für die Bildschirmkoordinaten in Y-Richtung. Um Texturkoordinaten zu definieren, werden die folgenden Attributkombinationen in X-Richtung akzeptiert:

  • texCoordX1 und texCoordX2: im Bereich von X1 bis X2
  • texCoordX1 und texCoordSizeX: im Bereich von X1 bis (X1 + SizeX)
  • texCoordSizeX und texCoordX2: im Bereich von (X2 - SizeX) bis X2
  • texCoordOffsetX und texCoordSizeX: im Bereich von (OffsetX - SizeX / 2) bis (OffsetX + SizeX / 2)

Wieder gilt dasselbe auch für die Y-Richtung. Hier ein einfaches Beispiel einer XML-Atlas-Datei:

<?xml version="1.0" ?>

<Atlas>
    
    <Rectangle texCoordX1="0"   texCoordY1="0" texCoordX2="64"  texCoordY2="64"/>
    <Rectangle texCoordX1="64"  texCoordY1="0" texCoordX2="128" texCoordY2="64"/>
    <Rectangle texCoordX1="128" texCoordY1="0" texCoordX2="192" texCoordY2="64"/>
    <Rectangle texCoordX1="192" texCoordY1="0" texCoordX2="256" texCoordY2="64"/>
    <Rectangle texCoordX1="256" texCoordY1="0" texCoordX2="320" texCoordY2="64"/>
    <Rectangle texCoordX1="320" texCoordY1="0" texCoordX2="384" texCoordY2="64"/>
    <Rectangle texCoordX1="384" texCoordY1="0" texCoordX2="448" texCoordY2="64"/>
    <Rectangle texCoordX1="448" texCoordY1="0" texCoordX2="512" texCoordY2="64"/>
    
</Atlas>
Zu beachten
Der Bereich der angegebenen Texturkoordinaten ist nicht eingeschränkt. Im oben gezeigten Beispiel haben alle Texturkoordinaten Integerwerte. Um diese Werte nun zum Rendern (einer nicht-wiederholten Texturgrafik) nutzen zu können, müssen diese Werte zuerst in "GPU-freundliche" Werte normalisiert werden. Für Graph::PlaneSequenceGeometry Knoten, wird dies durch das Setzen einer Texturreferenzgröße mittels seiner textureSizeX und textureSizeY Attribute bewerkstelligt. Weitere Informationen dazu sind im Tutorial #08: Animated Images zu finden.

Font-Ressourcen

Font-Ressourcen ermöglichen das Rendern von bitmap fonts mit der Murl Engine. Eine Font-Ressource selbst beinhaltet dabei jedoch keine Bitmap- oder Grafikdaten, sondern sie definiert lediglich, wo in einer Grafikressource eine bestimmte Glyphen-Grafik für ein bestimmtes Unicodezeichen gefunden werden kann. Das heißt, eine Font-Ressource ist nur in Kombination mit einer passenden Grafik sinnvoll nutzbar.

Font-Ressourcen sind Atlas-Ressourcen sehr ähnlich. Eine Font-Ressource speichert ebenfalls einzelne Rechtecke, welche die Bildschirm- und Texturkoordinaten beinhalten, liefert aber zusätzliche Informationen über den Unicodeindex und die korrekte Textausrichtung am Bildschirm.

Font-Ressourcen sind in Form von Resource::IFont Objekten verfügbar, wenn sie vom Code aus aufgerufen werden.

Native Fonts

Native Fonts sind derzeit der einzig verfügbare Typ von Font-Ressourcen. Dabei handelt es sich um Binärdateien mit der Dateierweiterung .murl. Um solch eine Datei zu erstellen, kann der Font Converter benutzt werden. Dieser erstellt eine native .murl Font-Ressource mit einer dazugehörigen Grafik, die alle notwendigen Glyphen-Grafiken enthält.

Eine detaillierte Erklärung, wie Bitmap-Fonts erstellt und verwendet werden können, befindet sich in Tutorial #01: Bitmap Fonts.

Animationsressourcen

Animationsressourcen bieten die Möglichkeit, verschiedene Eigenschaften von Graphenknoten, wie beispielsweise Position, Rotation, Farbe des Materials oder Lautstärke, automatisiert zu modifizieren. Animationen sind aus einzelnen Key-Frames aufgebaut, wobei jedes Key-Frame eine bestimmte Eigenschaft zu einem bestimmten Zeitpunkt definiert. Zusätzlich definiert jedes Key-Frame eine Interpolationsart, welche für die Berechnung des tatsächlichen Eigenschaftenwerts zwischen zwei aufeinanderfolgenden Key-Frames verwendet wird.

Animationsressourcen sind in Form von Resource::IAnimation Objekten verfügbar, wenn sie vom Code aus aufgerufen werden.

Beachte, dass es zusäztlich zu den Resource::IAnimation Objekten auch Logic::Animation Objekte wie Logic::AnimationReal, Logic::AnimationUInt32, Logic::AnimationVector etc. gibt, die für rein code-basierte Animationen verwendet werden können.

Key Types und Instanzen

Animation Keys werden von der Resource::IAnimation::Raw::Key Basisstruktur abgeleitet und sind für eine Vielzahl von verschiedenen Typen verfügbar.

Scalar Keys

Der BoolKey Typ repräsentiert einen einzelnen Boolean-Wert (true/false). Die folgenden Properties können mit Boolean-Keys gesteuert werden:

Beispiel XML-Animation:

    <VisibleKey time="0.0" value="false"/>
    <ActiveKey  time="0.0" value="false"/>

Der IntegerKey Typ repräsentiert einen vorzeichenbehafteten 32 Bit Integer Wert. Derzeit können die folgenden zwei Properties von Integer-Keys gesteuert werden:

Beispiel XML-Animation:

    <IndexKey       time="0.0" value="31"/>
    <DepthOrderKey  time="0.0" value="2"/>

Der FloatKey Typ definiert einen einzigen 32Bit Gleitkommawert. Folgendes Property kann durch Float-Keys gesteuert werden:

Beispiel XML-Animation:

    <VolumeKey time="0.0" value="1.0"/>

Color Keys

Der ColorKey Typ enthält vier verschiedene 32-Bit-Gleitkommawerte, einen für jede verfügbare Farbkomponente (rot, grün, blau und Alpha). Die Werte befinden sich üblicherweise im Bereich von 0.0 (keine Intensität) bis 1.0 (volle Intensität). Für spezielle Zwecke sind jedoch auch Werte außerhalb dieses Bereichs möglich. Die folgenden Properties können von Color-Keys gesteuert werden:

Zu beachten
Light Knoten haben keine Emissive-Color-Komponente, somit hat dieses Property nur bei FixedParameters einen Effekt.

Beispiel XML-Animation:

    <AmbientColorKey  time="0.0" color="1.00f, 1.00f, 1.00f, 1.00f"/>
    <DiffuseColorKey  time="0.0" color="1.00f, 1.00f, 1.00f, 1.00f"/>
    <SpecularColorKey time="5.0" color="1.00f, 1.00f, 1.00f, 1.00f"/>
    <EmissiveColorKey time="5.0" color="0.00f, 0.00f, 0.00f, 0.00f"/>

Transform Keys

Der PositionKey Typ definiert eine Position im dreidimensionalen Raum mit je einem 32-Bit-Gleitkommawert für jede der drei verfügbaren Achsen (X, Y und Z):

  • PositionKey Instanzen manipulieren direkt die Positionskomponenten der Transformations-Matrix über das Graph::ITransformable Interface und die GetTransform() Methode. Verfügbare Knotenklassen können dem hierarchischen Organigramm auf der Referenzseite entnommen werden.

Beispiel XML-Animation:

    <PositionKey time="0" posX="0" posY="0" posZ="-16.547734"/>

Der AxisAngleKey Typ repräsentiert eine Rotation im dreidimensionalen Raum, wobei drei einzelne 32-Bit-Gleitkommawerte die Rotationsachse mittels der X, Y und Z Komponenten und ein vierter Wert den Rotationswinkel in Radianten definieren. Die Achse wird auf die Einheitslänge normalisiert.

  • AxisAngleKey Instanzen manipulieren direkt die Rotationskomponenten der Transformations-Matrix über das Graph::ITransformable Interface und die GetTransform() Methode. Verfügbare Knotenklassen können dem hierarchischen Organigramm auf der Referenzseite entnommen werden.

Beispiel XML-Animation:

    <RotationKey time="0.0" axisX="1" axisY="0" axisZ="0" angle="45deg"/>

Der EulerAngleKey Typ bietet eine alternative Möglichkeit um eine Rotation im dreidimensionalen Raum zudefinieren, wobei drei einzelne 32-Bit-Gleitkommawerte die Eulerwinkel um die drei Hauptachsen X, Y und Z definieren. Optional kann auch noch die Rotationsreihenfolge mit dem parameter rotationOrder angegeben werden. Achtung: AxisAngleKeys, EulerAngleKeys und QuaternionKeys können nicht innerhalb einer Animations Ressource gemischt werden.

  • EulerAngleKey Instanzen manipulieren direkt die Rotationskomponenten der Transformations-Matrix über das Graph::ITransformable Interface und die GetTransform() Methode. Verfügbare Knotenklassen können dem hierarchischen Organigramm auf der Referenzseite entnommen werden.

Beispiel XML-Animation:

    <RotationKey time="0.0" angleX="12deg" angleY="45deg" angleZ="0deg" rotationOrder="ZYX"/>

Der QuaternionKey Typ bietet eine alternative Möglichkeit um eine Rotation im dreidimensionalen Raum zu definieren. Vier einzelne 32-Bit-Gleitkommawerte, je ein Wert für jede Quaternion Kompenente (Realteil R, und Imaginärteile I, J und K), bestimmen die Rotation. Achtung: AxisAngleKeys, EulerAngleKeys und QuaternionKeys können nicht innerhalb einer Animations Ressource gemischt werden.

  • QuaternionKey Instanzen manipulieren direkt die Rotationskomponenten der Transformations-Matrix über das Graph::ITransformable Interface und die GetTransform() Methode. Verfügbare Knotenklassen können dem hierarchischen Organigramm auf der Referenzseite entnommen werden.

Beispiel XML-Animation:

    <RotationKey time="0.0" quatR="0.0" quatI="0.0" quatJ="1.0" quatZ="0.0"/>

Der ScalingKey Typ definiert einen Skalierungsfaktor im dreidimensionalen Raum, wobei wieder je ein 32-Bit-Gleitkommawert für jede der drei verfügbaren Achsen (X, Y und Z) verwendet wird:

  • ScalingKey Instanzen manipulieren Knoten über das Graph::IScalable Interface und die SetScaleFactor(const Vector&) Methode. Verfügbare Knotenklassen können dem hierarchischen Organigramm auf der Referenzseite entnommen werden.

Beispiel XML-Animation:

    <ScalingKey time="0.0" scaleZ="0.001" scaleY="0.001" scaleX="0.001" interpolation="SMOOTHSTEP_OUT"/>

XML-Animationen

XML-Animations-Ressourcendateien sind durch ihr <Animation> Wurzelelement gekennzeichnet und können zum Definieren von Animation-Keys verwendet werden. Dieses Wurzelelement akzeptiert zwei Attribute:

  • startTime und
  • endTime

Diese Attribute definieren die tatsächliche Zeit der Animation, wenn diese von einem Graph::Timeline Knoten angesteuert wird. Beide Attribute erwarten eine Zeitangabe in Sekunden.

Einzelne Key-Frame Elemente können als direkte Kinder des Wurzelelements definiert werden. Für jede der oben beschriebenen Key-Instanzen gibt es einen passenden XML-Tag, welcher zur Erstellung eines Key-Frame Elements verwendet werden kann. Alle Key-Frame-Elemente haben die folgenden zwei Attribute gemeinsam:

  • Das time Attribut definiert den Zeitstempel des Key-Frame Elements in Sekunden.
  • Das interpolation Attribut kann dazu benutzt werden, um die tatsächliche Interpolationsart festzulegen, welche die Werte zwischen dem Key-Frame-Element und seinem Nachfolger berechnet (d.h. im nächsten Key-Frame-Element desselben Typs). Verfügbare Stringwerte können in der Murl::IEnums::Interpolation Enumeration nachgeschlagen werden.
Zu beachten
Wenn das interpolation Attribut nicht definiert ist, wird ein Standardwert benutzt, der vom verwendeten Key-Frame Elementtyp abhängt (siehe unten für weitere Details).

Folgende Key-Frame-Tags und –Elementen sind verfügbar und können in einer XML-Animationsressource verwendet werden:

Boolean Keys

Boolean-Key-Elemente sind über die folgenden Elemente verfügbar. Die standardmäßige Interpolationsart ist dabei "CONSTANT":

Sie stellen ein einziges Attribute zur Verfügung:

  • value kann mit einem der Stringwerte "1", "true" oder "yes" auf true gesetzt werden bzw. mit den Stringwerten "0", "false" oder "no" auf false gesetzt werden. (case insensitive)

Integer Keys

Es gibt zwei Integer-Key-Elemente, deren standardmäßige Interpolationsart auf "LINEAR" gesetzt ist:

Integer-Key-Elemente besitzen ebenso ein einziges Attribut:

  • value akzeptiert einen Stringwert der einen vorzeichenbehafteten Integerwert im Bereich von "-2147483648" bis "2147483647" repräsentiert.

Floating-point Keys

Auch diese Keys haben nur ein Key-Frame-Element, dessen standardmäßige Interpolationsart auf "LINEAR" gesetzt ist:

Gleitkomma-Key-Frame-Elemente besitzen ebenso value als einziges Attribut:

  • value akzeptiert eine Stringwert, der einen 32-Bit-Gleitkommawert repräsentiert.

Color Keys

Es gibt vier Farbkey Elemente, deren standardmäßige Interpolationsart auf "LINEAR" gesetzt ist:

Ein einziges Attribut wird akzeptiert:

  • color erwartet einen String der einen Farbwert repräsentiert. Die folgende Tabelle beinhaltet verschiedene Möglichkeiten für die Farbwertangabe. Alle Beispiele zeigen einen Farbwert mit 0% rot, 50% grün, 75% blau und 100% Alpha:
    Suffix Range Type Example Format
    f 0.0 – 1.0 floating-point "0f, 0.50f, 0.75f, 1f" RGBA / RGB
    i 0 – 255 integer "0i, 128i, 191i, 255i" RGBA / RGB
    h 00 – FF 8 bit hex int "0h, 80h, BFh, FFh" RGBA / RGB
    h 0 – FFFFFFFF 32 bit hex int "FF0080BFh" ARGB / RGB

Position Keys

Es gibt genau ein Key Element und dessen standardmäßige Interpolationsart ist auf "LINEAR" gesetzt:

Position-Key-Elemente akzeptieren die folgenden Attribute:

  • posX akzeptiert einen 32-Bit-Gleitkommawert als String für die X-Koordinate im dreidimensionalen Raum.
  • posY akzeptiert dasselbe für die Y Koordinate.
  • posZ akzeptiert dasselbe für die Z Koordinate.

Rotation Keys (AxisAngle, EulerAngle und Quaternion)

Es ist genau ein Key Element verfügbar, dessen standardmäßige Interpolationsart auf "LINEAR" gesetzt ist:

Rotation-Key-Elemente akzeptieren folgende Attributgruppe, um die Rotation im Euler Winkel Format zu definieren:

  • angleX akzeptiert einen 32-Bit-Gleitkommawert als String für den Rotationswinkel um die X Achse in Radianten oder Grad (Endung 'rad' bzw. 'deg'). Die Rotation wird im Uhrzeigersinn für die gegebene Achse durchführt.
  • angleY akzeptiert dasselbe für die Y Achse.
  • angleZ akzeptiert dasselbe für die Z Achse.
  • rotationOrder akzeptiert einen IEnums::RotationOrder Enumerationsstringwert zum Festlegen der Reihenfolge der Achsenrotation, der Vorgabewert ist "ZYX".

Rotation-Key-Elemente akzeptieren folgende Attributgruppe, um die Rotation im axis/angle Format zu definieren:

  • axisX akzeptiert einen 32-Bit-Gleitkommawert als String für die X-Koordinate der normalisierten Rotationsachse im dreidimensionalen Raum.
  • axisY akzeptiert dasselbe für die Y Achse.
  • axisZ akzeptiert dasselbe für die Z Achse.
  • angle akzeptiert einen 32-Bit-Gleitkommawert als String für den Rotationswinkel in Radianten oder Grad (Endung 'rad' bzw. 'deg'). Die Rotation wird im Uhrzeigersinn für die gegebene Achse durchführt.

Alternativ kann auch die folgende Attributgruppe zur Definition der Rotation als quaternion verwendet werden:

  • quatR akzeptiert einen 32-Bit-Gleitkommawert als String für die R-Komponente des Quaternions.
  • quatI akzeptiert dasselbe für die I Komponente.
  • quatJ akzeptiert dasselbe für die J Komponente.
  • quatK akzeptiert dasselbe für die K Komponente.
Zu beachten
Es kann immer nur eine Gruppe pro Key Element und Animation verwendet werden.

Scaling Keys

Auch hier ist genau ein Key Element verfügbar, dessen standardmäßige Interpolationsart auf "LINEAR" gesetzt ist:

Scaling-Key-Elemente akzeptieren die folgenden Attribute:

  • scaleX erwartet einen 32-Bit-Gleitkommawert für den Skalierungsfaktor in X-Richtung.
  • scaleY erwartet dasselbe für die Y-Richtung.
  • scaleZ erwartet dasselbe für die Z-Richtung.

Unter XML Animation Resource Tags befindet sich eine Liste von Knoten und deren dazugehörigen Animation-Keys zusammen mit der standardmäßig festgelegten Interpolationsart.

Das folgende Beispiel zeigt eine vollständige XML-Animationsdatei, die sowohl Diffuse-Color-Keys als auch Scaling-Keys enthält:

<?xml version="1.0" ?>

<Animation startTime="0.0" endTime="0.5">

    <DiffuseColorKey time="0.0"  color="0.3f, 1.0f, 1.0f, 1.0f"/>
    <DiffuseColorKey time="0.25" color="128i, 128i, 128i, 128i"/>
    <DiffuseColorKey time="0.5"  color="ffffffffh"/>

    <ScalingKey time="0.0"  scaleX="1.0" scaleY="1.0" scaleZ="1.0"/>
    <ScalingKey time="0.25" scaleX="0.9" scaleY="0.9" scaleZ="1.0"/>
    <ScalingKey time="0.5"  scaleX="1.0" scaleY="1.0" scaleZ="1.0"/>

</Animation>

Verwendung

Eine Möglichkeit eine Animationsressource auf einen Graphenknoten anzuwenden ist, diese über einen Graph::IAnimationTimeController zu referenzieren. Dies erfolgt z.B. von einer XML-Graph-Ressourcendatei aus:

    <PlaneGeometry controller.animationResourceId="MyPackage:MyMoveAnim1"/>

Wie oben ersichtlich, wirken die verschiedenen Key-Instanzen auf verschiedenen Eigenschaften der jeweiligen Knotenschnittstellen. Wenn eine Animationsressource verschiedene Key-Instanz-Typen für verschiedene Eigenschaften beinhaltet und diese Animation auf einem Knoten angewendet wird, der nicht alle dieser Eigenschaften implementiert, werden nur die relevanten Keys für die Steuerung dieses Knotens verwendet. Beispiel: Wenn eine Animation, die sowohl Volume- als auch Diffuse-Color-Keys enthält, mit einem Graph::Light Knoten verbunden wird, wird nur der Diffuse-Color-Key verwendet und der Volume-Key wird ignoriert.

Folglich kann dieses Verhalten beispielsweise dazu benutzt werden, um verschiedene Key-Instanzen in eine einzige Animation zu verpacken, welche dann für mehrere verschiedene Knoten benutzt wird. Jeder dieser Knoten berücksichtigt dabei nur jene Animationsdaten, die für ihn selbst relevant sind.

Standardmäßig werden vom IAnimationTimeController alle Keys angewendet, die sich in einer Animation befinden und die für den jeweiligen verbundenen Knoten relevant sind. Das heißt, wenn beispielsweise eine Animation Ambient-, Diffuse und Specular-Color-Keys enthält und diese Animation in einem Graph::Light Knoten verwendet wird, manipuliert der Controller immer alle drei Eigenschaften. Dieses Verhalten kann jedoch verändert werden, um den Controller auf ein Sub-Set der jeweiligen Animation-Key-Instances zu beschränken. Um das Anwenden der Ambient-Color-Eigenschaft zu verhindern und nur die Diffuse- und Specular-Color-Keys zu verwenden, reicht in diesem Fall folgende Angabe:

    <Light 
        controller.animationResourceId="MyPackage:ColorAnim1"
        controller.animationKeys="DIFFUSE_COLOR,SPECULAR_COLOR"
    />

Offensichtlich akzeptiert das controller.animationKeys Attribut eine durch Kommas getrennte Aufzählung von IEnums::AnimationKey Enumerationsstringwerten, welche die zu verwendenden Key-Typen definiert.

Das Tutorial #08: Animated Images enthält weitere nützliche Informationen über die Erstellung und Verwendung von Animationsressourcen.

Soundressourcen

Derzeit unterstützt die Murl Engine zwei Soundformate: Microsoft/IBM WAVE (.wav) und OGG-Vorbis (.ogg). Beide Formate können direkt benutzt werden, indem man ihren Dateinamen in einem <Resource> Element mittels des fileName Attributs definiert.

Soundressourcen sind in Form von Resource::IAudio Objekten verfügbar, wenn sie vom Code aus aufgerufen werden.

Meshressourcen

Coming soon!

Shaderressourcen

Coming soon!

Binärressourcen

Häufig ist es notwendig, andere Ressourcen in ein Package einzufügen, z.B. eine einfache Textdatei, eine eigene Binärdatei oder eine HTML-Datei. Auch wenn man beispielsweise eine DDS-Grafikdatei einbindet, wird diese Grafik zum Ladezeitpunkt des Packages intern in eine PNG-Datei umgewandelt. Dies erfolgt meist zu Optimierungszwecken, ist jedoch nicht immer erwünscht.

In beiden Fällen kann solch eine Ressource in Binärform eingefügt werden, d.h. es wird Byte für Byte direkt in das Package kopiert. Dafür muss die Ressource innerhalb der package.xml Datei wie folgt definiert werden:

<Resource type="BINARY" id="MyTextResource" fileName="test.txt"/>
<Resource type="BINARY" id="MyBinaryImageResource" fileName="image.dds"/>

Binärressourcen sind in Form von Resource::IBinary Objekten verfügbar, wenn sie direkt vom Code aus aufgerufen werden.

Text Resources

Anders als alle bisher beschriebenen Ressourcen stellen Textressourcen keinen Bezug zu anderen Dateien her. Stattdessen wird ein Text direkt als String innerhalb einer package.xml Datei definiert. Dazu benutzt man ein <Text> Element mit dem value Attribut:

<Text id="MyFirstText" value="This is my first resource text string!"/>

Hinweis: Die folgenden Zeichen, die im XML-Syntax eine besondere Bedeutung haben, müssen als XML-Entities definiert werden:

Character XML-Entity
------------------------
" &quot;
' &apos;
< &lt;
> &gt;
& &amp;

Über das Resource::ICollection Objekt kann die Textressource im Code erreicht werden.

Beispiel:

const String& GetResourceText(const Logic::IState* state, const String& resourceId)
{
    const Resource::ICollection* resourceCollection = state->GetResourceCollection();
    if (resourceCollection != 0)
    {
        const Resource::IText* textResource = resourceCollection->GetText(resourceId);
        if (textResource != 0)
        {
            return textResource->GetValue();
        }
    }
    return Util::StaticEmptyString();
}

String text1 = GetResourceText(state, "package_main:MyFirstText");

Das Logic::IState Objekt stellt diese Methode bereits zur Verfügung.

Beispiel:

String text1 = state->GetResourceText("package_main:MyFirstText");


Copyright © 2011-2018 Spraylight GmbH.