Zurück zur Gesamtübersicht "Physik mit Direct3D"
Wir verwenden für unsere ersten Beispiele zwei Klassen, die unser Wahlkurs bereits programmiert hat:
Die Klasse Scene3D:
Sie bietet das Rohgerüst für 3D-Szenen.
Von dieser Klasse kannst Du eigene Szene-Klassen ableiten.
Die Klasse Object3D:
Objekte dieser Klasse repräsentieren ein 3D-Modell, das durch eine x-Datei festgelegt
ist. Sie können zum Beispiel in eine 3D-Szene eingebunden und angezeigt werden.
Wir gehen von einem C++Builder-3D-Projekt aus, wie es im Kapitel Direct3D starten(III) schon erzeugt worden ist. Dieses Projekt erzeugt und vernichtet bereits ein Control3D-Objekt:
Ein globaler Zeiger
zeigt auf dieses wichtige Objekt.
Dieses Objekt ermöglicht die Steuerung von Direct3D. Wir gehen in diesem Kapitel davon aus, dass es in Deinem C++Builder-Projekt schon korrekt erzeugt und abgebaut wird.
Die Header-Datei
bietet eine weitere Klasse, die sich für eigene 3D-Projekte nutzen lässt.
Die Klasse Scene3D:
Diese Klasse Scene3D ist als Rohgerüst für eigene 3D-Szenen gedacht. In der vorliegenden Form ist sie jedoch noch nicht nutzbar. Beispielweise fehlen der Klasse jegliche Angaben darüber,welche 3D-Objekte sich in der 3D-Szene befinden sollen. Außerdem sind die Methoden init(), render(), move() in der Klasse Scene3D gar nicht ausprogrammiert.
Bedeutung der Klassenmethoden einer 3D-Szene
Wir werden von dieser Klasse eine eigene Unterklasse MyScene3D ableiten und diese nach unseren Wünschen ausgestalten.
Wir erzeugen für unsere eigene 3D-Szene eine weitere, leere Headerdatei namens
und sorgen dafür, dass sie nach den bisherigen Header-Dateien in unser Projekt eingebunden wird.
Es müssten dann folgende Include-Befehle im Projekt vorhanden sein:
#include "UnitMeinEigenesProjekt.h"
#include "UnitDirect3D_1.h"
#include "3DAnwendung.h"
#include "My3DAnwendung.h"
Wir werden nun in der Header-Datei My3DAnwendung.h eine Unterklasse MyScene3D von der Klasse Scene3D ableiten.
Diese Unterklasse MyScene3D wird eine Kamera, sowie ein 3D-Objekt beinhalten, das wir aus der Billardkugel-x-Datei einlesen werden.
Die Deklaration der abgeleiteten Klasse MyScene3D
in der Datei My3DAnwendung.h:
Die Eigenschaftsvariable cameraPos ist vom Typ
D3DXVECTOR3 (dreidimensionaler Vektor).
Folglich legt cameraPos die Raumposition der Kamera fest.
Die Eigenschaftsvariable cameraLookAt gibt die Position an, auf die die Kamera "hinschaut".
Bitte beachte, dass beide Eigenschaftsvariablen sinnvolle Startwerte benötigen. Dies kann zum Beispiel die init-Methode der Szene sicherstellen.
Der Object3D-Zeiger ball wird auf das einzige Objekt unserer Szene zeigen - eine Billardkugel.
Bitte beachte, dass mit der Deklaration von ball nur ein Zeiger auf ein 3D-Objekt existiert. Das Objekt selbst muss noch im Konstruktor der Klasse MyScene3D erzeugt und im Destruktor der Klasse MyScene3D vernichtet werden.
Hinter dieser Klassendeklaration müssen wir nun den Konstruktor, den Destruktor und die Klassenmethoden programmieren:
Der Konstruktor unserer Klasse MyScene3D:
Der Kopf dieses Konstruktors
bewirkt wegen des Anhängsels "... : Scene3D(_lpControl3D)", dass zuvor auch der
Konstruktor der Oberklasse Scene3D aufgerufen wird. (Diesen Konstruktor der Oberklasse Scene3D kannst Du in der Datei 3DAnwendung.h begutachten.)
Im Konstruktor wird dann das 3D-Objekt mittels new erzeugt und anschließend die init-Methode aufgerufen.
Der Destruktor unserer Klasse MyScene3D:
Er zerstört alle Objekte, die der Konstruktor erzeugt hatte - in unserem Falle nur die Billardkugel:
Die init-Methode unserer Klasse MyScene3D:
Diese Methode gibt den Eigenschaftsvariablen der Szene sinnvolle Startwerte.
So erhält die Kamera eine geeignete Position und einen brauchbaren Ort, auf den sie
"hinschaut."
Außerdem besitzt auch das in der Szene vorhandene 3D-Objekt drei Eigenschaftsvariablen, die korrekte Startwerte bekommen:
Eigenschaftsvariable pos
Sie legt die momentane Raumposition des Objekts fest.
Eigenschaftsvariable speed
Sie legt die momentane Geschwindigkeit des Objekts als 3D-Vektor fest.
Da die Geschwindigkeit hier eine vektorielle Größe ist, wird gleichzeitig die
Richtung der Bewegung und der Betrag der Geschwindigkeit festgelegt.
Zum Beispiel bewegt sich hier die Kugel zu Beginn nach rechts-oben:
Eigenschaftsvariable accel
Sie legt die momentane Beschleunigung des Objekts als 3D-Vektor fest.
In unserem Beispiel wirkt nur die Beschleunigung durch die Erdanziehung auf das
3D-Objekt. Folglich hat die Beschleunigung einzig einen negativen Wert in
y-Richtung. Die Beschleunigung in x- bzw. z-Richtung ist gleich
0:
Die render-Methode unserer Klasse MyScene3D:
Diese Methode benutzt relativ viele Methoden von Direct3D.
Entscheidend für eigene Projekte sind vor allem der Bereich zwischen...
..und...
Zwischen diesen beiden Methodenaufrufen zeichnest Du alle 3D-Objekte, die in der 3D-Szene vorkommen. Hierzu wäre es nützlich, wenn alle 3D-Objekte eine draw-Methode besitzen, um sich selbst zu zeichnen.
Bei Objekten der Klasse Object3D ist dies der Fall - sie haben eine draw-Methode, die das Objekt in die Zeichenfläche malt. Deshalb steht da der Aufruf:
Die move-Methode unserer Klasse MyScene3D:
Die move-Methode der 3D-Szene soll alle 3D-Objekte bewegen, die in der Szene vorkommen. Das bedeutet, dass die Position (und eventuell dessen Geschwindigkeit und/oder Beschleunigung) der 3D-Objekte auf einen neue Werte gebracht werden.
Hierzu besitzen alle Object3D-Objekte eine move-Methode. Als einzigen Parameter verlangt die move-Methode von Object3D einen float-Wert: Nämlich die Zahl der Sekunden, die seit dem letzten Aufruf der move-Methode vergangen sind. (Hier wird standardmäßig angenommen, dass die move-Methode alle 0,1s aufgerufen wird.)
Übrigens sieht die move-Methode von Object3D so aus:
Diese beiden Zuweisungen sind übrigens fast "wortgleich" die Übersetzung der physikalischen Bewegungsgleichungen:
Weiter zu "Objekte anzeigen (III)"
Zurück zur Gesamtübersicht "Physik mit Direct3D"