Dokumentation | GOTHIC |
ZenGin: 3D-Modelle | |
Autor: Dieter Hildebrandt | Version: 15.Juli 2001 |
Inhalt:
|
1. 3DS-MAX Animationen & MeshesEin Model ist ganz allgemein definiert als eine Hierarchie von Bones/Nodes/Knoten (Skelett), ein oder mehreren Meshes, die diesen Bones zugeordnet sind, und einem dazugehörigem Satz von Animationen. Bones-Hierarchie, Meshes und Animationen werden mit 3DS-MAX erstellt. Damit die ZenGin ein solches Model verwenden kann, muss es mit einem speziellen Exporter aus 3DS-MAX exportiert werden (das MAX-Plugin "zenexp.dle"). Derart exportierte Dateien haben die Dateiendung ".ASC" und sollten, damit sie von ZenGin eingelesen werden können, in einem Unterverzeichnis von "GOTHIC\_WORK\DATA\ANIMS\" abgelegt werden. Bones-Hierarchie, Meshes und Animationen werden schliesslich in "Model-Script-Files" (.MDS) aufgeführt, um einen Model-Prototype zu definieren. Die Engine liest .MDS Files und importiert/konvertiert dabei die angegebenen aus 3DS-MAX exportierten .ASC-Files in interne Repräsentationen. Die Spezifikation der .MDS Files ist einem folgenden Kapitel zu entnehmen. Bei der Erstellung von Bones-Hierarchien, Meshes und Animationen, die in die Engine importiert werden sollen, sind folgende Punkte zu beachten:
Der 3DS-MAX-ASCII Exporter wird verwendet, um sowohl Mesh-Geometrien als auch Animationen zu exportieren. Es darf allerdings nur jeweils die Geometrie oder die Animation in ein einzelnes .ASC File exportiert werden (siehe dazu auch die MDS Spezifikation). Beachte: die Hierarchie der Bones wird immer exportiert. Folgende Exporter-Einstellungen sind sowohl beim Mesh- als auch bei Animation-Export zu aktivieren (nicht aufgeführte Checkboxes sind jeweils zu deaktivieren):
Folgende Exporter-Einstellungen sind exklusiv bei Mesh-Export zu wählen:
Folgende Exporter-Einstellungen sind exklusiv bei Animations-Export zu wählen:
2. MDS-FormatEin Model-Script hat beispielhaft den folgenden Aufbau: Model ("Player") { meshAndTree ("Hum_Body_Naked0.ASC" DONT_USE_MESH) registerMesh ("Hum_Body_Naked0.ASC") registerMesh ("Hum_Body_CookSmith.ASC") aniEnum { modelTag ("DEF_HIT_LIMB" "zs_RightHand") ani ("s_stand" 1 "s_stand" 0.5 0.5 M. "stand_pause2.asc" F 0 -1) ani ("t_strafe_l" 1 "s_stand" 0.1 0.1 M. "Strafe_Left.asc" F 0 -1) aniBlend("t_stand_2_run" "s_run") aniSync ("t_run_2_walk" "s_walk") aniAlias ("t_strafe_r" 1 "s_stand" 0.1 0.1 M. "t_strafe_l" R) aniBatch ("t_1h_slash1") { *aniBatch ("t_1h_slash1_top") *aniBatch ("t_1h_slash1_bot") } ani ("t_1h_shield_ready" 5 "" 0.2 0.2 .. "shield_ready.asc" F 0 -1) { *eventSwapMesh(13 "zs_Shield" "zs_LeftArm") } ... } } Die Abschnitte im Einzelnen: 'meshAndTree'Als erstes Argument ist eine .ASC Datei anzugeben, die für das zu definierende Model sowohl das komplette Skelett in neutraler Pose, als auch ein Mesh enthält. Bei dem Export aus 3DS-MAX heraus läßt sich innerhalb eines Dialogs einstellen, was die zu exportierende Datei enthalten soll. Als zweites Argument ist das Schlüßelwort "DONT_USE_MESH" optional anzugeben. Falls es vorhanden ist, hat eine neu erzeugte Instanz des Models im Spiel per Default kein Mesh angelegt. Das trifft i.A. für Models zu, die Charaktere und Monster definieren, und denen verschiedene Meshes angelegt werden können, wobei die Auswahl per Befehl in Skripten erfolgt. Wenn allerdings jede erzeugte Instanz des Models immer dasselbe Mesh tragen soll, ist das Schlüßelwort nicht anzugeben. Das Mesh wird in diesem Fall aus der Datei genommen, die als erstes Argument bei "meshAndTree" genannt ist. 'registerMesh'Falls dem Model zur Laufzeit verschiedene Meshes angelegt werden sollen (z.B. verschiedene Rüstungen/Uniformen bei Menschen), müßen diese per "registerMesh" an dieser Stelle bekannt gemacht werden. Als Argument ist eine .ASC Datei anzugeben, die das zu registrierende Mesh samt Skelett enthält. 2.1 'aniEnum'Die abzuspielenden Anis mitsamt einiger Parameter werden aufgezählt. Dabei gibt es verschiedene Möglichkeiten eine Ani zu definieren. Für die Programm-Spiel-Logik gibt es allerdings keinen Unterschied zwischen diesen. 2.1.1 'ani'Beispiel: ani ("s_stand" 1 "s_stand" 0.5 0.5 M. "pause.asc" F 0 -1) Syntax: ani (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ASC_NAME ANI_DIR START_FRAME END_FRAME) Im Einzelnen: ANI_NAMEDer Ani-Name. Hierbei gibt es gewisse Konventionen. Anis werden in verschiedene Gruppen eingeteilt, wobei die Zugehörigkeit am Namen zu erkennen ist: Prefix "s_": eine State-Ani (Zustand) Prefix "t_": eine Transition-Ani (Zustands-Uebergang) ... [to be continued] ... LAYERLayer dieser Animation (von 1 bis 9999999..). NEXT_ANIAni, die abgespielt werden soll, falls die gerade definierte Ani beendet worden ist. State-Anis ("s_") haben i.A. sich selbst als NEXT_ANI. Trans-Anis ("t_") haben i.A. eine Zustands-Ani ("s_") als NEXT_ANI. Occas-Anis haben i.A. keine NEXT_ANI (""). BLEND_INZeit in sec, die vergeht, bis der Einfluss dieser Ani von 0% auf 100% angewachsen. Z.B.: Bei einem BLEND_IN von 0.75 Sekunde ist zum Zeitpunkt t=0sec (Start der Ani im Frame 0) der Einfluss dieser Ani 0%, bei t=0.5 ist der Einfluss 66%, bei t=.75 100%, bei t=1 100%. BLEND_OUTZeit in sec, die vergeht, bis der Einfluss dieser Ani von 100% (oder dem aktuellen Wert) auf 0% gesunken ist. Anzumerken ist hierbei, dass das Herunterregeln des Einflusses erst beginnt, sobald der letzte Frame der Ani abgespielt worden ist (END_FRAME). FLAGSDas FLAGS-Feld ist im Grunde ein String, in dem jedes mögliche Flag durch einen Buchstaben repräsentiert ist. Falls allerdings keine Flags gesetzt sind, muss hier ein "." stehen. Überflüssige "." in dem FLAGS-String werden überlesen.
ASC_NAME3ds-max ASCII Name. ANI_DIRAbspielrichtung, in der die gerade definierte Ani abgespielt werden soll. Moegliche Werte: "R" = Reverse, "F" = Forward. START_FRAME / END_FRAME-1 bedeutet: Ani bis zum Ende einlesen 2.1.2 'aniAlias'Beispiel: aniAlias ("t_strafe_r" 1 "s_stand" 0.1 0.1 M. "t_strafe_l" R) Syntax: aniAlias (ANI_NAME LAYER NEXT_ANI BLEND_IN BLEND_OUT FLAGS ALIAS_NAME ANI_DIR) Mit 'aniAlias' wird eine Ani definiert, die dasselbe Datenmaterial einer bereits über 'ani' definierten Ani verwendet. Obwohl dieselben Animations-Daten verwendet werden, kann diese neue Ani mit unterschiedlichen Parametern versehen werden. Sinnvolles Beispiel (siehe oben): 'ani' "t_strafe_l", 'aniAlias' "t_strafe_r", wobei sich die ANI_DIR unterscheidet. ALIAS_NAMEName der Ani, dessen Datenmaterial dieser neu definierten Ani zugrunde liegen soll. 2.1.3 'aniBlend'aniBlend ( "t_stand_2_run" "s_run" ) aniBlend ( ANI_NAME NEXT_ANI ) Mit 'aniBlend' werden (Transition-) Anis definiert, die sich aus dem dynamischen Überblenden zweier (State-) Anis ergeben. D.h. für diese Anis liegt kein konkretes Datenmaterial aus einer ASC-Datei vor, sondern diese Ani wird zur Laufzeit durch Überblenden zweier State-Anis durch Interpolation erzeugt. Die Blend-In und -Out Werte werden dabei aus den angegebenen Anis genommen. NEXT_ANIDie 'Folge-Ani', in die weich übergeblendet werden soll. 2.1.4 'aniSync'Beispiel: aniSync ( "t_run_2_walk" "s_walk" ) Syntax: aniSync ( ANI_NAME NEXT_ANI ) Ähnlich dem 'aniBlend', nur dass die die NEXT_ANI nicht beim Frame 0 gestartet wird, sondern relativ zur aktuellen State-Ani desselben Layers. Beispiel: ani "s_walk", aniSync "t_walk_2_run", ani "s_run". Gerade aktiv ist im Layer 1 die Ani "s_walk" die gerade zu 45% abgespielt ist. Ein Starten der Ani "t_walk_2_run" bewirkt dann, dass die Ani "s_run" sofort gestartet wird, und zwar nicht bei Frame 0, sondern bei dem Frame der 45% ihrer Länge enstpricht. Hiermit ist es moeglich verschiedene Bewegungs-Anis smooth ineinander zu blenden, ohne dass sich die Beine allzusehr unlogisch verhalten. Vorraussetzung ist hierbei, dass alle Anis, die so ineinander geblendet werden sollen, von den Beinstellungen zueinander passen. Z.B., dass alle Walk/Run-Anis mit demselben Bein starten.. 2.1.5 'aniBatch'Beispiel: aniBatch ("t_1h_slash1") { *aniBatch ("t_1h_slash1_top") *aniBatch ("t_1h_slash1_bot") } Syntax. aniBatch (ANI_NAME) { *aniBatch (BATCH_ANI_NAME) [...] } Mit 'aniBatch' ist es möglich, beliebig viele Anis zu einer einzigen Ani zusammenzufassen. Wird z.B. bezogen auf das obige Beispiel die Ani "t_1h_slash1" gestartet, so startet die Model-Engine intern die beiden Anis "t_1h_slash1_top" und "t_1h_slash1_bot" zeitgleich. Gedacht war dieses Feature, um nachträglich noch auf elegante Weise eine Ober-/Unterkörper-Trennung der Anis bewerkstelligen zu können. Indem mann wie in dem Beispiel oben die 1h_slash Ani in Top und Bottom aufteilt, ist es möglich, diese auch separat zu verwenden. Bei einem slash aus dem Stand würden über 'aniBatch' sowohl Ober- als auch Unterkoerper abgespielt werden, bei einem Slash aus dem Gehen würde dann nur die Slash-Ani fuer den Oberkörper abgespielt werden, während der Unterkörper weiterhin von der Gehen-Ani kontrolliert wird. Status: unbenutzt, ungetestet. 2.1.6 Ani-Event-BlockEin Ani-Event-Block ist optional und folgt - falls vorhanden - immer einer Ani-Definition. Ein Ani-Event ist eine Aktion, die während des Abspielens einer Ani zu einem bestimmten Zeitpunkt (per Frame festgelegt) ausgeführt wird. Ein Beispiel: { *eventHeading (5 F 0.0 1.0 0.0 90.0) *eventSwapMesh (-1 "zs_LongSword" "zs_RightHand") *eventSound (10 "step.wav" 1.0) ... } Bisher implementierte Ani-Events:
2.2 BemerkungenZu beachten:
|