QTVRLingoEngine

©2000/01 Joachim Baur, Medienwerkstatt Schorndorf

 

Eine kurze Inhaltsübersicht:

 

Update vom 30.4.2001

• verbessertes Lingo (schnellere Darstellung und vor allem perspektivisch jetzt absolut korrekte Entzerrung der Panoramen).
Die beiden Korrektur-Parameter "pXcorrInit" und "pYcorrInit" aus dem "init_xx_room"-Script entfallen jetzt, da sich aus dem Panorama (bei richtiger Rechenweise ;-) selbst schon alle nötigen Daten errechnen lassen.

Das Update ist zum einen im Gesamtdownload weiter unten schon integriert, kann aber auch separat heruntergeladen werden, für diejenigen, die sich dien 3+MB Download schon einmal angetan haben - hier gleich der Link für die upgedatete "QTVRLingo"-Castlib (einfach die alte damit ersetzen, fertig):

Macintosh Version (.sit-Archiv, 10 KB)
Windows Version (.zip-Archiv, 12 KB)

 

1. Einleitung

Die QTVRLingoEngine ist eine Sammlung von Scripts, um in Director interaktive QTVR-Panoramen ohne QuickTime oder andere Xtras darzustellen

Besonders nützlich natürlich für den Einsatz im WWW, weitere Vorteile sind:

UND AUSSERDEM

Die QTVRLingoEngine kann KEINE Cubic-VRs darstellen, die seit QuickTime 5 möglich sind.
Dafür gibt's das beeindruckende ShockTimeVR von Nonoche.

 

EINE KLEINE WARNUNG NOCH ZU BEGINN:

Diese Dokumentation ist weder vollständig noch leicht verständlich ;-) Ich kann hier nur die grobe Funktionsweise aufzeigen, wer damit wirklich arbeiten will, muss sich in Lingo schon selbst zurechtfinden können... Ich hätte ja gern auch mehr und ausführlicher geschrieben, aber eben wie immer keine Zeit, weil's ja auch meine Freizeit ist. Wer mich bezahlt, kann natürlich auch die letzten Details erklärt bekommen *g*

Ich habe die QTVRLingoEngine geschrieben, weil ich als nörgelnder Grafikdesigner nie recht zufrieden mit den Einschränkungen und der Bedienungsweise von Original-QTVR-Filmen war - vor allem die "Click-and-drag"-Steuerung finde ich für QTVR-Unkundige nicht sehr intuitiv.
Also habe ich mir überlegt, wie ich externe Bedienelemente, Hintergrundanimationen, Sound, etc alles unter einen Hut bringen kann, am besten noch ohne eine QuickTime-Installation...

Um zu zeigen, was ich mit dem ganzen Gerede meine, habe ich einen Beispiel-Director-Film zusammengebastelt, in dem 2 Panoramen enthalten sind (eines 360° und eines 180°), inkl. Hotspots und einigen Animationen zum rumprobieren.

Hier gibt's die Shockwave 8-Version für den Browser:
QTVRLingoEngine_example.htm (300 KB)

Und hier kann man sich den ungeschützten Director-Movie dazu herunterladen:
Macintosh Version (.sit-Archiv, 1,3 MB)
Windows Version (.zip-Archiv, 1,5 MB)

 

2. Was kann der example.dcr?

2.1 QTVR-Steuerung

Ein Klick auf die Buttons

Pan Left Pan Right Tilt up Tilt Down Rotate Left/Right

läßt das Panorama solange drehen/kippen/rotieren, wie der entsprechende Button gedrückt ist.

Man kann natürlich auch in das QTVR klicken und mit gedrückter Maustaste ziehen, um sich im Raum zu bewegen.

Ein einzelner Klick auf diesen Button

ShowHotSpots

zeigt die im QTVR vorhandenen Hotspots als blaue Flächen an, solange die Maus gedrückt ist.
Bei einem Doppelklick bleiben die blauen Markierungen bis zu einem weiteren Doppelklick sichtbar.

SwingTo

Die "SwingTo"-Funktion ermittelt die kürzeste Entfernung zwischen der augenblicklichen Standpunkt und dem Zielpunkt (Target Pan/Tilt/FoV-Werte) und bewegt das Panorama entsprechend. Die Bewegungsfunktion ist nicht sehr elegant, kann sich gerne mal jemand anschauen, der Lust hat was schöneres einzubauen...

2.2 Darstellungsparameter

Ausser diesen Steuerungsbuttons gibt es noch drei Einstellungen die die Darstellung an sich beeinflussen:

the useFastQuads True/Flase

Die gleichnamige Director-Systemeinstellung wird umgeschaltet. Wenn die Einstellung auf "True" steht, sollte sich die "Recalc-Time" verringern, vor allem natürlich bei langsameren Maschinen.

perspective correction None/Partial/Full

Bestimmt die Art der Verzerrung, die bei der Darstellung auf das Ausgangsbild angewendet wird:

correction = none

None

stellt die Ausgangsbilder nur mit einer linearer Skalierung dar - alle Motivkanten bleiben gekrümmt und die "Tilt"-Buttons verschieben den Bildausschnitt nur nach oben oder unten.

Partial

entzerrt die Motivkanten, so dass das Panorama beim hin- und herdrehen richtig abgebildet wird. "Tilt" verändert aber auch nur den Bildausschnitt

Full

entzerrt sowohl die Motivkanten und errechnet zudem noch eine perspektivische Verzerrung (kippen) bei "Tilt" nach oben oder unten. Diese Darstellung ist die Grundeinstellung und natürlich auch am rechenintensivsten.

 

mask overlay on/off

Der Panoramadarstellung geht mit einem Verlauf in die Hintergrundfarbe über - erreicht wird das durch einen grünblauen Bitmap-Abdecker mit einem weichgezeichneten Loch in der Mitte (im Alphakanal). Wenn dieser Abdecker ausgeblendet wird (Off), kann man die verzerrten Sprite-Quads vollständig sehen.

 

2.3 Integrierte Hotspot-Funktionalitäten zum Ausprobieren

Beide Lampen im ersten Pano (grüner Raum) können unabhängig voneinander ein- und ausgeschaltet werden, indem man sie anklickt. Das Telefon läutet, wenn man in die Richtung des Schreibtisches schaut, die Lautstärke ändert sich mit der Entfernung vom Telefon. Sobald man das Telefon anklickt, hört auch das Klingeln auf. Durch die Zimmertüre gelangt man mittels einer Transition in das zweite Pano (blauer Raum). Dies ist nur ein Teilpanorama ohne Hotspot-Funktionen ausser der Türe, die zurück in den grünen Raum führt.

 

3. Wie wird das QTVR dargestellt?

Das QTVR-sourcepict wurde mittels Imaging Lingo in schmale senkrechte Streifen zerschnitten. Bei meinem Beispielfilm ist das sourcePict für den grünen Raum (360°-Panorama) 440 Pixel hoch und 1440 Pixel breit. Dieses wurde in 72 Streifen (Slices) zerlegt, jedes Slice 20 Pixel breit. Um die Slices nebeneinander auf der Bühne darzustellen, habe ich 20 Spritekanäle verwendet, jedem davon wird zur Laufzeit ein anderes Slice-Member zugeordnet.

Für jedes Panorama innerhalb des Director-Movies wird ein separates Script-Object mit eigenen Properties erzeugt, so dass es auch möglich ist, mehrere Panoramen gleichzeitig auf der Bühne zu zeigen.

Es folgt eine kurze Beschreibung des example.dir-Films:

 

3.1 Die verschiedenen Castlibs


Cast Internal Enthält alle Interface-Elemente, die der example.dir verwendet - Flash-Buttons (in denen die Rollover- und Aktiviert-Zustände bereits enthalten sind), Textfelder, etc.

Cast Slices Enthält die zerschnittenen sourcePicts der Panoramen für den grünen und den blauen Raum.
Die ersten 72 Castmember ("greenRoom 1" bis "...72") sind die Slices für den grünen Raum, die darauffolgenden 36 Bitmaps ("blueRoom 1" bis "...36") die für den blauen Raum. Der blaue Raum ist nur zur Hälfte "begehbar" (180°)
Danach kommen noch die Slices für die Animationsphasen des grünen Raums: Alle Member mit Namen "greenRoomDark" enthalten Slices eines sourcePicts, in dem die Lampen ausgeschaltet waren (die Bodenlampe belegt den Bereich von Slice Nummer 25 bis 40, die Schreibtischlampe von 56 bis 62. Alle übrigen Slices des ursprünglichen sourcepicts sind von den Lampen nicht betroffen).
Alle Bitmaps sind 20 Pixel breit und 440 Pixel hoch, mit einer Farbtiefe von 16 Bit. Für den Shockwave-Export (300KB) habe ich eine JPEG-Kompression mit einer Qualitätseinstellung von 40 gewählt.

Cast Hotspots Enthält die zerschnittenen Hotspot-sourcepicts der beiden Räume. Die Hotspot-Slices haben dieselbe Größe wie die Panorama-Slices (20 x 440 Pixel), aber nur eine Farbtiefe von 8 Bit. Welche Palette sie haben, ist dabei im Prinzip egal, aber beim importieren des Hotspot-sourcepicts muss auf jeden Fall die Option "Trim White Space" deaktiviert sein!
Vom Aufbau her kommen zuerst die 72 Hotspot-slices für den grünen Raum ("greenRoomHotspot 1" etc), dann 72 Duplikate, bei denen die Hotspot-Farben durch schwarz ersetzt wurden (und die dann konsequenterweise nur eine Farbtiefe von 1 Bit haben). Wenn zur Laufzeit der "ShowHotspots"-Button angeklickt wird, werden diese Bitmaps auf der Bühne dargestellt mit einer Transparenz von 50% und blau als Spritecolor (jede andere Farbe geht natürlich auch).

Cast QTVRLingo Die Scripts und Behaviors die benötitgt werden, um ein Panorama auf der Bühne darzustellen und zu animieren.

 

3.2 Der QTVR-Lingo-Cast

Script MovieScripts Für jedes Panorama, das auf der Bühne gezeigt werden soll, wird beim "startmovie" ein eigenes Lingo-Objekt erzeugt (eine Instanz des "QTVRLingoEngine"-Parentscripts). Die jeweilige Referenz zu diesem Objekt im Speicher muß in einer globalen Variablen gespeichert werden. Um ein QTVR-Objekt zu erzeugen, wird folgender Code verwendet:

gBlueRoom = new(script "QTVRLingoEngine")
gCurrQTVR = gBlueRoom
initTheBlueRoom
gCurrQTVR.initNode()

Der Handler "initTheBlueRoom" setzt zuerst alle dem blauen Raum eigenen Properties. Nachdem diese im Objekt definiert sind, wird dessen "initNode"-Handler aufgerufen, der einige weitere Berechnungen durchführt und die Darstellung des Panoramas vorbereitet. Das Panorama wird aber noch nicht auf der Bühne dargestellt!

Script initBlueRoomScript initGreenRoomDiese Scripte initialisieren eine ganze Reihe von Properties des QTVR-Objekts, auf das die globale Variable "gCurrQTVR" zeigt. Ich weiss, dass das nicht die "saubere" Art der Objektorientierten Programmierung ist (die Properties eines Objekts von ausserhalb zu setzen), aber aus Bequemlichkeitsgründen und weil ich ein Grafiker bin und es deshalb auch nicht besser wissen muss, habe ich es mir halt einfach gemacht ;-)

Script QTVRLingoEngine Das eigentliche "Herz" dieses ganzen Konstrukts - hier drin stehen die mathematischen Funktionen und Berechnungen, die das Panorama auf die Bühne bringen...

 

3.3 Wie das QTVR angesteuert wird

3.3.1 Ein Button wird geklickt (z.B. "Pan Left")

Das Buttonbehavior selbst bewirkt noch keine Neudarstellung/Veränderung der Panorama-Ansicht. Es wird nur ein Flag gesetzt, das die gewünschte User-Absicht kenntlich macht. Das "Pan Left"-Behavior setzt also nur das pPanFlag des gCurrQTVR-Objekts auf 1 solange die Maustaste gedrückt ist (kann man natürlich auch schon bei MouseEnter machen, dann hat man Buttons, die auf Rollover ansprechen statt auf Klicken).

3.3.2 Der "exitFrame"-Handler des "FrameLoop"-Scripts wird ausgeführt

Dieser prüft nacheinander für die verschiedenen Bewegungsrichtungen, ob das entsprechende Flag gesetzt ist und führt eventuelle Neuberechnungen aus:

checkPanning()
checkTilting()
checkZooming()
checkRotation()

Das Panorama auf der Bühne wird aber noch nicht aktualisiert!

Wenn das pSwingFlag auf 1 steht (es findet gerade eine selbstlaufende "SwingTo"-Aktion statt) werden die regulären Button-Flags ignoriert bis die Bewegung zu Ende ist.

3.3.3 Die "QTVRredraw()"-Funktion des gCurrQTVR-Objekts wird aufgerufen, falls Neuberechnungen durchgeführt wurden

Jetzt wird die Panoramadarstellung auf der Bühne aktualisiert (ähnlich wie bei einem "updatestage"-Befehl). Wenn eine der "check...()"-Funktionen einen Wert neu berechnet hat, ändert sie den Status des pRedrawFlag um einen "updateStage" des Panoramas durch die QTVRLingoEngine zu veranlassen. Je nachdem, welche Bewegungsart berechnet wurde, wird das pRedrawFlag von #none auf #spritesOnly bzw. #quadsAndSprites gesetzt.
#spritesOnly heißt dabei, das nur eine "Pan"-Bewegung vorliegt, bei der es nicht nötig ist, die Sprite-Quads neu zu berechnen, es werden nur die Sprite-Member ausgetauscht, so dass der EIndruck einer Links-/Rechts-Bewegung des Panoramas entsteht. Alle übrigen Bewegungsarten erfordern eine (prozessorintensivere) Neuberechnung der Sprite-Quads, deswegen der #quadsAndSprites-Status des pRedrawFlags.

3.3.4 Hotspots-Test

Der "CheckHSRollover"-Handler muss anhand der aktuelln Cursorposition ermitteln, ob sich die Maus über einem Hotspot-Bereich innerhalb der verzerrten und verdrehten Slice-Spritequads befindet. Dazu muss zuerst der zu diesem Panorama-Slice gehörende Hotspot-Slice gefunden werden, anschließend wird die "mapStagetoMember" -Funktion von Director verwendet, um die Koordinaten (x,y) des Pixels innerhalb der Slice-Bitmap herauszufinden, über dem sich der Cursor gerade befindet. Wenn die Farbe dieses Pixels im Hotspot-Bitmap eine andere als weiss ist, ist die Maus über einem Hotspot (dessen Nummer entspricht dem Palettenindex der Hotspotfarbe - deshalb ist es auch egal, WELCHE Palette die Hotspot-Bitmap hat)

3.3.5 "Click-and-drag"-Navigation

Damit diese Navigationsmethode funktioniert, muss das "SliceScript"-Behavior jedem der 20 slice-sprites zugewiesen werden. Dieses Behavior ruft bei mouseDown den "Trigger"-Handler des gCurrQTVR-Objekts auf. Dieser prüft zuerst, ob ein Hotspot angeklickt wurde, ansonsten dreht/kippt er das Panorama in einer repeat-Schleife solange in Richtung der Cursorposition (relativ zum Klickpunkt als Ausgangspunkt), wie die Maustaste gedrückt bleibt.

 

4. Animationen und Hotspot-Aktionen

Was mir bei den Standard-QTVR-Panoramen am meisten gefehlt hat, war eine einfache Methode, um Animationen innerhalb des Panorama-Bilds stattfinden zu lassen - nicht einfach nur überlagerte QuickTime-Sprites oder QTVR-Objekte, sondern echte Hintergrund-Animationen die mit der jeweils korrekten Perspektive mitberechnet werden, wenn der User das Panorama bewegt.

Um sowas in der QTVRLingoEngine einfach zu integrieren, arbeitet diese mit einer internen Liste (pSliceMemList), in der die Slice-Member für alle 72 Slices verwaltet werden, so daß jedes einzelne Slice jederzeit ausgetauscht werden kann.

4.1 Timergesteuerte Hintergrund-Animationen

Um timergesteuerte Animationen einzubinden (z.B. das Klingeln des Telefons), ist es am einfachsten, ein timeout()-Objekt zu erzeugen, das dann die Memberzuordnung in der pSliceMemList bei jedem Aufruf anpaßt. Das Timeout-Objekt für das Telefon wird im "DisplayNode"-FrameScript initialisiert:

timeout("telephone").new(500, #telephoneAnim)

und ruft dann den "telephoneAnim"-Handler (zu finden im "Hotspot handlers"-MovieScript) alle 500 Millisekunden auf. Dieser läßt das Telefon jeweils zu Beginn einer Animationsschleife klingeln und wechselt bei jedem Aufruf die Bitmap-Member für die Slices Nummer 63, 64 und 65 aus.
Sobald das Telefon angeklickt wird (oder der User in den blauen Raum wechselt), wird das Timeout()-Objekt gelöscht, die Animation hört auf.

4.2 Hotspotgesteuerte Aktionen und Animationen

Sobald der User einen Hotspot anklickt, wird der "hotSpotTriggerHandler" (zu finden im "Hotspot handlers"-MovieScript) vom gCurrQTVR-Objekt aufgerufen. Die Hotspot-Eigenschaften werden mit übergeben, so daß man über den hotSpotTriggerHandler jeden Hotspot frei programmieren kann.

Hotspots können auch zur Laufzeit aktiviert/deaktiviert werden, indem der "enableHS"-handler des QTVR-Object aufgerufen wird:

gCurrQTVR.enableHS(85,1) -- enables Hotspot number 85

gCurrQTVR.enableHS(85,0) -- disables Hotspot number 85

4.3 Übergänge in andere QTVRs ("nodes")

Um einen nahtlosen Übergang zu einem anderen QTVR zu erreichen., werden "BackBuffer"-Sprites eingesetzt. Deren Spritekanäle liegen unter denen der Slice-Sprites, sie werden also so lange von den Slice-Sprites verdeckt, bis diese von der Bühne genommen werden. Der "switchNodes"-Handler des aktiven QTVR-Objekts belegt diese BackBuffer-Sprites mit den Slice-Membern des neuen Raums und weist diesen dabei die Sprite-Quads des aktuellen QTVRs zu. Anschliessend springt er zu dem "goANotherNode"-Marker, an dem eine Transition die BackBuffer-Sprites aufdeckt. So wird der neue QTVR-Raum mit denselben Pan-, Tilt- und FoV-Einstellungen dargestellt wie der Raum aus dem man kommt.

 

5. Wie wird die QTVRLingoEngine für eigene Panoramen angepaßt?

Als erstes muss der "QTVRLingoEngine"-Cast in das eigene Director-Movie kopiert werden.

5.1 Anlegen der Castlibs

Die SourcePicts für Panorama und Hotspots (falls vorhanden) importieren. Im example.dir habe ich verschiedene Castlibs für die beiden SourcePict-Arten benutzt, die "Slices" und die "Hotspots". Wichtig beim Importieren:

Nachdem die SourcePicts importiert wurden, übernimmt der "sliceSourcePict"-Handler (zu finden in den "Tools"-MovieScripts der "QTVRLingoEngine"-Castlib) das Zerschneiden in einzelne Streifen mittels Imaging Lingo. Dazu muss ins Message Window die folgende Zeile eingegeben werden (für SliceCount, SrcPictMember und SrcPictCLib natürlich die entsprechenden Werte einsetzen!):

sliceSourcePict SliceCount, SrcPictMember, SrcPictCLib

als Beispiel:
sliceSourcePict 72, 1, "Slices"
zerlegt Member 1 im Cast "Slices" in 72 neue Bitmap-Slice-Member

Die Hotspot-Slices werden genauso erzeugt.

Nachdem die Hotspot-Slices erzeugt wurden, müssen noch schwarz-weisse Kopien angelegt werden, falls die "ShowHotspots"-Funktion im fertigen Projekt benutzt werden soll (falls nicht, einfach auslassen). Dazu folgendes ins Message WIndow eingeben:

createShowHSMembers FirstHSmember, HotSpotCLib, SliceCount

als Beispiel:
createShowHSMembers 147, "Hotspots", 36
erzeugt 36 neue showHotspot-slice-member, in dem die 36 hotspot-slice-members ab member 147 im Cast "Hotspots" dupliziert werden

Ein weiterer Handler erzeugt eine Liste mit allen Hotspot-Nummern, die in einem Hotspot-SourcePict vorkommen - falls eine solche Aufstellung nicht sowieso schon existiert. Der Befehl lautet:

buildHSlist

Abschließend ist zum Thema Hotspots noch zu sagen, das es natürlich problemlos möglich ist, das Hotspot-SourcePict im Director-Malfenster zu ändern oder sogar erst zu erzeugen. Dazu die "Onion Skin" -Ansicht anschalten, das Panorama-SourcePicts scheint hinter dem Hotspot-SourcePict durch und man kann beliebig in den Hotspots rummalen.
Falls noch gar kein Hotspot-SourcePict existiert, den Panorama-SourcePict-Member duplizieren, die Farbtiefe auf 8 Bit reduzieren (Palette egal) und die "Trim White Space"-Property abschalten! Dann im Malfenster "Alles auswählen" und mit Weiss füllen. Jetzt können die farbigen Hotspots reingepinselt werden.

5.2 Anlegen des Drehbuchs

Die QTVRLingoEngine erwartet drei verschiedene Gruppen von Sprite-Dummies (die im Drehbuch auch in dieser Reihenfolge angelegt sein müssen, Gruppe 1 liegt unter Gruppe 2 liegt unter Gruppe 3). Dummy bedeutet, dass den Spritekanälen irgendeinen Bitmap-Member zugewiesen wird und dieser dann ausserhalb des sichtbaren Bühnenbereichs plaziert wird.
Gruppe 1: Die Sprites für die BackBuffer-Slices (nur notwendig, wenn Übergänge zwischen verschiedenen QTVRs erfolgen sollen)
Gruppe 2: Die Sprites für die Panorama-Slices (immer notwendig)
Gruppe 3: Die Sprites für die ShowHotspot-Slices (nur notwendig, wenn die "ShowHotspots"-Funktion verwendet wird)

Alle 3 Gruppen müssen die gleiche Anzahl Sprites enthalten, Gruppen 1 und 3 können einfach weggelassen werden, wenn die entsprechenden Funktionen im Projekt nicht benötigt werden.

DAS WAR'S AUCH SCHON. Zumindest fast - noch ein paar kleine Script-Anpassungen:

Die Änderungen betreffen das "initBlueRoom"- oder "initGreenRoom"-Script. Alle Werte müssen für die eigenen Panoramen angepaßt werden (pFirstSprite, pSpriteCount, etc). Dann das geänderte Script für jedes weitere Panorama einmal duplizieren, den Handler jeweils anders nennen und die paar Werte ändern, die von QTVR zu QTVR verschieden sind (pFirstSliceMem, etc). Im "startMovie"-handler muss dann für jedes einzelne QTVR-Panorama eine Instanz des QTVRLingoEngine-Parentscripts erzeugt und der jeweilige "init..."-Handler aufgerufen werden.

 

6. Bekannte Eigenarten

6.1 Gekrümmte Motivkanten innerhalb des QTVR-Panoramas
Im Vergleich zu den völlig geraden Motivkanten, mit denen der Apple MoviePlayer Panoramen darstellt, sind die Kanten von QTVRLingo-Panoramen noch leicht in sich gekrümmt. Ich bin mir nicht sicher, ob das durch die Formeln, mit denen ich die Slices entzerre, verursacht wird oder einfach dadurch, dass ein Slice schon 20 Pixel breit ist - eine Breite von 1 Pixel wäre natürlich ideal, würde die Anzahl der benötigten Spritekanäle aber auch verzwanzigfachen.

Der Update vom 30.4. beseitgt diesen Fehler - die Formeln stimmen jetzt!

 

6.2 Die QTVRLingo-Sprites müssen im Drehbuch unter allen anderen Sprites plaziert werden
Die Slice-Sprites, die BackBuffer-Sprites und die Showhotspot-Sprites müssen alle in Spritekanälen unterhalb der restlichen Interface-Elemente plaziert werden (oder ihr z-index muss zur Laufzeit entsprechend geändert werden), ausserdem muss der Rand um den gewünschten Panorama-Bildausschnitt abgedeckt werden, so daß die verzerrten Sprite-Quads dort nicht sichtbar sind.
Eine einfache Lösung hierfür ist ein MIAW, in dem sich nur das QTVR befindet.

6.3 Rundungsdifferenzen bei der Quad-Berechnung
Beim ein- oder auszoomen ("FoV" +/-) ohne Kippen ("Tilt") des Panoramas treten bei bestimmten Zoomstufen 1 Pixel breite senkrechte Lücken zwischen einzelnen Quads auf, immer an denselben Stellen links innerhalb der QTVR-Darstellung. Die Berechnungen an sich dürften diese Lücken nicht verursachen, weil sie dann gleichzeitig auch auf der rechten Seite der QTVR-Darstellung auftreten müssten (symmetrische Berechnungen). Auch wenn ich die Sprite-Quads per "put" im Messagefenster ausgeben lasse, weisen diese keine Lücke auf... Ich tippe auf interne Rundungsdifferenzen, die bei der Darstellung der Quads auf der Bühne auftreten. Auch Änderungen bei der floatprecision brachten keinen Erfolg.
Meine Abhilfe ist es, das Pano immer ein wenig zu kippen, also statt Tilt-Werten von 1.0 (= kein Kippen) nur Werte bis 0.95 bzw. 1.05 zu verwenden.