Die Position, Rotation und den Zoom zwischen zwei 3D Objekten zu interpolieren ist auf den ersten Blick sehr einfach. Beim genauen hinsehen, ist das Ganze aber doch nicht so trivial, wie zuerst angenommen, da die Interpolation zwischen den Matrizen der Objekte erfolgen muss.
Das Ganze funktioniert in etwa so:
- Umrechnung der Quell- und Zielmatrizen in Quaternions
- Berechnung des Interpolations-Quaternions anhand der SLERP (spherical linear interpolation) Formel
- Umrechnung des Interpolations-Quaternions in eine Interpolations-Matrix
- Anwendung der Interpolations-Matrix auf das zu interpolierende 3D Objekt
Da sich SLERP ein bisschen anhört wie eine Droge aus Fallout und ich mit Quaternions auch nicht viel anfangen konnte, bin ich nach weiterem googeln auf das hier gestoßen.
Daraus habe ich eine Util Klasse erstellt, die 3 statische Methoden bereistellt:
// Berechnung der Interpolation zwischen zwei Quaternions
public static function slerp( qa:Quaternion, qb:Quaternion, alpha:Number ):Quaternion;
// Umwandlung eines Quaternions ind eine Matrix
public static function quaternion2Matrix(quat:Quaternion):MatrixAway3D;
// Umwandlung einer Matrix in ein Quaternion
public static function createFromMatrix(matrix:MatrixAway3D ):Quaternion;
Das Ganze kann dann so verwendet werden:
// Umrechnung der Source- und Target-Matrix in Quaternions
var sourceQuat : Quaternion = QuaternionUtilsAway3D.createFromMatrix(sourceMatrix);
var targetQuat : Quaternion = QuaternionUtilsAway3D.createFromMatrix(targetMatrix);
// Berchnung der Interpolation
// 0.15 bzw. 15% legt hier den Wert der Interpolation fest. Wird das Ganze innerhalb eines Loops aufgerufen, nähert sich der Wert jeweils um den festgelegten Prozentsatz an das Ziel an.
var currentQuat : Quaternion = QuaternionUtilsAway3D.slerp(sourceQuat, targetQuat, 0.15);
// Das Interpolations-Quaternion wird wieder in eine Matrix umgerechnet, auf die Matrix des zu Zielobjects kopiert und angewandt
targetMatrix.copy3x3(QuaternionUtilsAway3D.quaternion2Matrix(currentQuat));
this.transform = targetMatrix;
Es ist nicht ohne weiteres möglich, den Abstand der vertikalen Scrollbar zum DataGrid zu ändern. Nach einem Experiment mit einer transparenten Column zwischen den eigentlichen Daten und der Scrollbar, habe ich die DataGrid Komponente extended und einen eigenen Style für den besagten Abstand eingebaut.
In der ExtendedDataGrid Klasse sieht das dann so aus:
// Neuen Style anlegen
Style(name="verticalScrollbarMargin",type="Number",inherit="no")]
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
...
// Der neue Style wird zum normalen ABstand addiert
this.verticalScrollBar.move(this.verticalScrollBar.x + getStyle("verticalScrollbarMargin"), viewMetrics.top + hh);
...
}
Jetzt kann man der neue Style für das ExtendedDataGrid per CSS gesetzt werden:
.extendedDataGrid {
vertical-scrollbar-margin: 100;
}

Da das DataGrid in unserem Beispiel einen transparenten Header hat, muss noch ein leerer Skin erstellt und eingebunden werden. Damit der Hintergrund auch wirklich transparent wird, sollte der Wert von contentBackgroundAlpha im DataGrid auf 0 gesetzt werden.
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
</s:Group>
<components:ExtendedDataGrid headerBackgroundSkin="{EmptySkin}"
headerSeparatorSkin="{EmptySkin}"
contentBackgroundAlpha="0"
dataProvider="{countries}">
Auf der Suche nach der Möglichkeit, in Flex eigene Compiler-Argumente auszulesen, bin ich auf diesen Artikel gestoßen: http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_21.html
Hier wird sehr gut beschrieben, wie man eigene Argumente an den Flex-Compiler übergeben kann und wie diese dann innerhalb der Flex-Anwendung als Konstante verfügbar sind.
Zuerst ergänzt man im Flashbuilder/Flexbuilder in den Projekteinstellungen unter “Flex Compiler” den gewünschten Wert unter “Zusätzliche Compiler-Argument”. Eigene Argumente werden dabei mit -define hinzugefügt.
Beispiel:
-define+=CONFIG::MY_CONSTANT,”‘This is a String’”
Die Definition muss dabei im Format
NAMESPACE::NAME,VALUE
übergeben werden.

Innerhalb der Flex-Anwendung steht das Compiler-Argument dann in Application als Konstante zur Verfügung und kann ausgelesen werden.
So sieht die Ausgabe aus (Beispiel-Source):

Der konkrete Anwendungsfall war jedoch nicht eine statische Übergabe von Compiler-Argumenten sondern die Übergabe der aktuellen SVN-Revision beim Build per ANT.