21 KiB
Animations-Testseite mit Waffen-Dummies — Entwurf
Datum: 2026-09-17
Zusammenhang: Der Nutzer hat zwei Packs mitgegeben, ~/Downloads/MotionLibrary_Weapons.zip (Mocap) und ~/Downloads/ASISWeaponsPack.zip (Waffen), mit dem Auftrag: „Mach eine neue Branch. In der du Character spawnst. Die aus diesem Animationen-Pack die Animationen einfach in einer Loop ausführen. Und man kann sich die angucken. Man soll aber selbst auch mit einem Charakter rumlaufen können. Und man soll […] die Waffe, die ich dir mitgebe, falls es eine Animation gibt, die passt zu der Waffe, […] diese Waffe in der Hand halten, also die Dummies, die dann da rumstehen."
Baut auf: src/characters/index.js (Mannequin ual.glb, PLAYER_MODEL_BASE), src/world/sky.js und src/world/shadows.js (Himmel, Licht, Kaskadenschatten), tools/assets/places.mjs (Aufbereitung mit gltf-transform, WebP, meshopt).
Ziel
Eine eigene Seite animationen.html. Darauf stehen 13 Mannequin-Dummies und spielen die 11 Mocap-Clips in Dauerschleife. Acht von ihnen halten eine Waffe aus dem Pack, die zu ihrem Clip passt. Der Nutzer läuft mit seiner eigenen Figur zwischen ihnen herum.
Befund (gemessen)
Animationen
| Punkt | Wert |
|---|---|
| Dateien | 11 × FBX 7.7 binär, zusammen 13,2 MB. Kein Mesh, nur Skelett, ein Clip und die Producer-Kameras von MotionBuilder. |
| Skelett | 24 Knochen mit Xsens-MVN-Namen: Reference, Hips, Spine–Spine3, Neck, Head, je Seite Shoulder, Arm, ForeArm, Hand, UpLeg, Leg, Foot, ToeBase. Keine Finger. |
| Einheit, Achsen | cm, Y oben, Blick nach +Z, links des Darstellers bei +X |
| Ruhepose | T-Pose, jede Knochen-Weltdrehung 0° |
| Spuren | Hips.position und 23 × .quaternion, 120 fps, Zeitstempel auf ms gerundet (Abstände 7–9 ms) |
| Frame 0 | die T-Pose selbst, 8 ms vor Frame 1, mit dem die Bewegung beginnt |
| Hüfthöhe der Ruhepose | je Aufnahmetag verschieden: 0,909 m (14.07.) und 0,900 m (15.07.) |
| Clip (aus dem Dateinamen) | Dauer | Drift netto | weiteste Abweichung nach Driftabzug | Hüfte am Anfang | Naht: Blickwinkel / größte Knochenabweichung |
|---|---|---|---|---|---|
hunter_bowArrow_tk01 |
77,65 s | 2,17 m | 3,13 m | −2° | 72° / 91° |
leftHandThrow_grenade_tk01 |
6,65 s | 0,06 m | 0,21 m | −44° | 7° / 15° |
leftHandThrow_grenade_tk02 |
4,30 s | 0,06 m | 0,18 m | −38° | 0° / 7° |
taunt_shootSelfInHead_tk01 |
7,83 s | 0,09 m | 0,16 m | −17° | 1° / 15° |
taunt_shootSelfInHead_tk02 |
6,71 s | 0,04 m | 0,42 m | −16° | −6° / 13° |
stabTwist_Knife_tk01 |
8,48 s | 0,37 m | 0,19 m | −28° | −1° / 15° |
stabTwist_Knife_tk02 |
6,27 s | 0,08 m | 0,20 m | −25° | −3° / 17° |
idle_loadGun-Hand_tk01 |
6,56 s | 0,01 m | 0,05 m | −19° | 2° / 19° |
idle_loadGun-Hand_tk02 |
5,89 s | 0,02 m | 0,03 m | −18° | 0° / 18° |
idle_loadGun-Rifle_tk04 |
7,75 s | 0,01 m | 0,02 m | −10° | 1° / 16° |
idle_loadGun-Rifle_tk05 |
6,13 s | 0,02 m | 0,02 m | −24° | 2° / 14° |
Drift und Naht sind ab Frame 1 gemessen. „Hüfte am Anfang" ist der Winkel des Hüft-Vorwärtsvektors gegen +Z in der Waagrechten.
Mannequin (public/models/ual.glb)
| Punkt | Wert |
|---|---|
| Aufbau | Armature → Mannequin (Skinned Mesh, 13 743 Dreiecke, 2 Primitive, keine Texturen) und root (−90° um X, Blender-Z-oben) → pelvis … |
| Skelett | 65 Knochen mit Unreal-Namen. Je Hand 15 Fingerknochen und 5 Blattknochen. 53 Clips. |
| Ruhepose | T-Pose, Blick nach +Z, links bei +X, 1,83 m hoch, pelvis bei 0,917 m |
| Spielfigur | Der Controller skaliert das Modell auf playerCapsuleHeight (180) × scale (PlayerController.ts, Zeilen 438–476). Mit PLAYER_MODEL_BASE.scale = 0,005 ist die Figur laut Code 0,9 Welteinheiten hoch, nicht 1,83. |
Finger in Pistol_Idle_Loop, Frame 0 |
beide Hände gekrümmt, gegen die Ruhepose: Zeigefinger 45° (rechts) / 41° (links), Mittelfinger 63° / 48°, rechter Daumen 41° |
Finger in Idle_Loop, Frame 0 |
locker gekrümmt: Zeige- und Mittelfinger 77°, Daumen 26° |
Höhen der Wirbelsäule im Vergleich (Ruhepose, m):
| MVN | Höhe | Mannequin | Höhe |
|---|---|---|---|
Hips |
0,900 | pelvis |
0,917 |
Spine |
0,995 | spine_01 |
1,051 |
Spine1 |
1,095 | spine_02 |
1,174 |
Spine2 |
1,187 | — | — |
Spine3 |
1,279 | spine_03 |
1,315 |
Neck |
1,411 | neck_01 |
1,488 |
Head |
1,506 | Head |
1,569 |
Waffen
| Waffe | Quelle im Pack | Eckpunkte (nicht indiziert) | Länge | Texturen |
|---|---|---|---|---|
| Pistole | Pistol/SM_Pistol.fbx |
8 592, zwei UV-Sätze | 0,19 m | T_/N_ 2048 px, M_ 512 px |
| AK47 | AK47_Option2(Same Socketing)/SM_AK47.fbx |
15 534 | 0,87 m | T_/N_ 2048 px, M_ 1024 px |
| M4 | M4 Carbine/SM_M4_Carbine.fbx |
17 403 | 0,86 m | T_/N_ 2048 px, M_ 1024 px |
| 870 Shotgun | 870 Shotgun/SM_870_Shotgun.fbx |
7 812 | 1,00 m | T_/N_/M_ 2048 px |
| L96 | L96 Sniper Rifle/SM_L96_Sniper_Rifle.fbx |
21 318 | 1,17 m | T_ 2048 px RGBA (Alpha überall 255), N_ 2048 px, M_ 1024 px |
- Knoten:
- Jede Datei hat genau ein Mesh mit einem Material.
- Die Pistole trägt den Knotenmaßstab 100 auf Eckpunkten, die schon in Metern liegen.
- Die L96 trägt die Knotendrehung (180°, 0°, 180°).
- Die übrigen haben keine Knotentransformation.
- Der Ursprung liegt am Griff, bei der M4 zum Beispiel zwischen x −0,30 und 0,56.
- AK47 „Option 1 (Different Socketing)": 25 Skinned Meshes an den Knochen
Root,TriggerundMagazine, Lambert-Material, anderer Griffpunkt, Texturen in 4096 px. Wird nicht verwendet. - Normalmaps: schon im OpenGL-Format. Bei allen fünf Waffen ist ∂R/∂y negativ mit ∂G/∂x korreliert (−0,09 bis −0,42). Bei DirectX-Karten wäre die Korrelation positiv.
- Masken
M_*.tga:- TGA Typ 2 (unkomprimiert), 32 Bit, kein ID-Feld, Ursprung unten links, TGA-2.0-Fußzeile.
- R, G und B sind gleich (ein Grauwert), dazu kommt Alpha.
- AK47, Median je Fläche: Holz Grau 0,85 / Alpha 0,22, Metall Grau 0,95 / Alpha 0,70.
- Daraus folgt: Grau = Rauheit, Alpha = Metall. Der Alphakanal trennt Holz von Metall, der Grauwert nicht.
- Lizenz: In keinem der beiden Zips liegt eine Lizenzdatei.
Welche Waffe zu welchem Clip passt
- Pistole:
idle_loadGun-Hand,taunt_shootSelfInHead - Gewehr (AK47, M4):
idle_loadGun-Rifle - Messer, Granate, Bogen: Diese Waffen sind nicht im Pack.
- 870 und L96: Für sie gibt es keinen eigenen Clip.
Entscheidungen des Nutzers
| Frage | Entscheidung |
|---|---|
| Ort | Eigene Testseite. Verworfen: eine Reihe Dummies in der Welt am Startpunkt. |
| Shotgun und L96 | Sie kommen dazu, mit den beiden Gewehr-Nachladeclips. |
| Weg | Umbau vorab mit Node-Skripten. Verworfen: FBX im Browser parsen und übertragen, sowie SkeletonUtils.retargetClip statt eigener Übertragung. |
| Entwurf Abschnitt 1–3 | bestätigt (Seite, Aufstellung und Panel; Umbau, Griff und Finger; Tests, Branch und Lizenz) |
| Arbeitsweise | Arbeitsbaum .claude/worktrees/animationen, Branch leonida/animationen von lokalem main (ee49fd7, 24 Commits vor origin/main). Auf leonida/strassen arbeitet parallel eine andere Sitzung. |
Testseite
Seite und Szene
- Einstieg:
animationen.htmlim Wurzelverzeichnis nebenindex.htmllädtsrc/showroom/main.js. Lokal ist die Seite unterhttp://localhost:5173/animationen.htmlerreichbar. vite.config.js:build.rollupOptions.inputnennt beide Seiten, damitnpm run buildauch die Testseite baut.- Licht: Renderer, Tonemapping, Kamera, Nebel,
createSkyundcreateSunShadowswie insrc/main.js, mit denselben Werten für Sonne, Himmelslicht und Kuppelhelligkeit (dort lokale Konstanten, hier mit Verweis übernommen). - Boden: eine Ebene von 200 × 200 Welteinheiten bei y = 0 mit der Textur
concrete_pavementauspublic/textures(Diffuse,nor_gl,arm). Sie ist der einzige Collider der Spielfigur und muss schon beiplayer.initstehen. Deshalb hängt sie nicht anstage(siehe Maßstab) und ist für jeden Maßstab groß genug. Die Kachel misst 1,8 Mannequin-Meter (Poly Haven misstconcrete_pavementmit 1,8 × 1,8 m).texture.repeatwird nachplayer.initgesetzt. - Nicht auf der Seite: Stadt, Streaming, Fahrzeuge, Minimap, Figurenwahl.
Maßstab
Die Spielfigur hat nicht die 1,83 m des Mannequins (siehe Befund). Die Aufstellung hängt deshalb an einer Gruppe stage. Sie bekommt nach player.init den Weltmaßstab des Spielermodells (player.playerModel.getWorldScale), ausgelesen und nicht nachgerechnet. Alle Maße unten sind Mannequin-Meter: Dummies, Waffen, Schilder, Abstände und der Startpunkt. Welteinheit = Mannequin-Meter × Maßstab. Dummies und Spielfigur sind damit gleich groß.
Spielfigur
- Modell:
ual.glbmitplayerControllerundPLAYER_MODEL_BASEaussrc/characters/index.js, wie im Spiel. Laufen, Sprinten, Springen und Kamera verhalten sich wie gewohnt. - Start: bei (0 | 8) Mannequin-Metern vor Reihe 1, mit Blick nach −Z auf die Dummies.
player.initbeginnt über dem Ursprung, danach setztplayer.resetdie Figur auf 8 × Maßstab.
Aufstellung (src/showroom/lineup.js)
Reine Daten und reine Funktionen, ohne Browser testbar.
| Reihe, Platz | Clip | Schild | Waffe | Hand |
|---|---|---|---|---|
| 1, 1 | idle_loadGun-Hand_tk01 |
Pistole nachladen · Take 1 | Pistole | r |
| 1, 2 | idle_loadGun-Hand_tk02 |
Pistole nachladen · Take 2 | Pistole | r |
| 1, 3 | taunt_shootSelfInHead_tk01 |
Taunt: Schuss in den Kopf · Take 1 | Pistole | r |
| 1, 4 | taunt_shootSelfInHead_tk02 |
Taunt: Schuss in den Kopf · Take 2 | Pistole | r |
| 1, 5 | idle_loadGun-Rifle_tk04 |
Gewehr nachladen · Take 4 | AK47 | r |
| 1, 6 | idle_loadGun-Rifle_tk05 |
Gewehr nachladen · Take 5 | M4 | r |
| 1, 7 | idle_loadGun-Rifle_tk04 |
Gewehr nachladen · Take 4 | 870 Shotgun | r |
| 1, 8 | idle_loadGun-Rifle_tk05 |
Gewehr nachladen · Take 5 | L96 | r |
| 2, 1 | stabTwist_Knife_tk01 |
Messerstich mit Drehung · Take 1 | — | — |
| 2, 2 | stabTwist_Knife_tk02 |
Messerstich mit Drehung · Take 2 | — | — |
| 2, 3 | leftHandThrow_grenade_tk01 |
Granate werfen (links) · Take 1 | — | — |
| 2, 4 | leftHandThrow_grenade_tk02 |
Granate werfen (links) · Take 2 | — | — |
| 2, 5 | hunter_bowArrow_tk01 |
Bogenschütze · Take 1 | — | — |
- Reihe 1: bei z = 0, acht Plätze bei x = −12,25 + 3,5 · i.
- Reihe 2: bei z = −8. Die ersten vier Plätze liegen wie in Reihe 1 (x = −12,25 bis −1,75), der Bogenschütze steht bei x = 8,75. Zum nächsten Dummy hat er damit 8 m Abstand, genug für seine 3,13 m Wanderung.
- Blickrichtung: Alle Dummies schauen nach +Z zur Spielfigur. Die Clips sind darauf ausgerichtet (siehe Umbau, Schritt 3), die Dummies werden also nicht gedreht.
- Schild: ein Canvas-Sprite 2,2 m über dem Platz (nicht am Dummy, damit es beim Bogenschützen stehen bleibt). Es zeigt den Text aus der Spalte „Schild" und darunter die Waffe oder „ohne Waffe".
- „Hand": Vorgabe ist
r. Hält ein Darsteller die Waffe sichtbar links, zum Beispiel weil die rechte Hand nachlädt, wird der Eintrag im Browser auflgesetzt und dies im Bericht festgehalten.
Dummies (src/showroom/dummies.js)
- Laden:
ual.glbeinmal,weapons-mocap.glbund die Waffen mitGLTFLoadersamtMeshoptDecoder, wiesrc/world/places.js. - Je Dummy:
SkeletonUtils.clonedes Mannequins, Schatten an.- Ein eigener
AnimationMixermit zwei Aktionen:- der Mocap-Clip mit
LoopRepeat, - die Fingerhaltung als konstanter Clip, nur mit den
.quaternion-Spuren der Fingerknochen aus dem ersten Frame. Dummies mit Waffe bekommen sie für beide Hände ausPistol_Idle_Loop, Dummies ohne Waffe ausIdle_Loop.
- der Mocap-Clip mit
- Beide Aktionen bewegen verschiedene Knochen, keine Gewichtung nötig.
- Waffe: Kind des Handknochens (
hand_roderhand_l), mit dem Griff der Waffe ausWEAPONS(Position in m, Drehung in Grad, Reihenfolge XYZ). - Jedes Bild:
mixer.update(delta · Tempo), außer bei Pause.
Panel (lil-gui)
- Tempo: 0 bis 2 in Schritten von 0,05, Vorgabe 1.
- Pause: an/aus.
- Griff:
- Waffe auswählen.
- Position x/y/z von −0,3 bis 0,3 m, Drehung x/y/z von −180° bis 180°.
- Wirkt sofort auf alle Dummies mit dieser Waffe.
- „Werte ausgeben" schreibt den Griff als JSON in die Konsole, zum Übernehmen in
WEAPONS.
Umbau der Animationen (tools/assets/motions.mjs)
node tools/assets/motions.mjs <Ordner mit den 11 FBX> -> public/models/motions/weapons-mocap.glb
tools/assets/fbx.mjs lädt FBX in Node mit dem FBXLoader von three.js. Dazu setzt es die Browser-Platzhalter, die der Loader braucht (self, window, document.createElementNS), und blendet die Kamerawarnungen aus. Die Rechenschritte sind reine, exportierte Funktionen:
- Clip-Name:
/^\d{8}_s\d+_(.+)_ERJA-mvn\d+\.fbx$/liefert zum Beispielidle_loadGun-Hand_tk01. - Abtasten:
- D ist die Zeit von Frame 1 bis zum Clipende, n = round(D · 30) + 1.
- Der Quellclip läuft in einem
AnimationMixerund wird an n gleichmäßig verteilten Zeitpunkten von Frame 1 bis zum Ende abgelesen, im Abstand D/(n−1), also etwa 1/30 s. - Je Zeitpunkt werden die Weltdrehung jedes zugeordneten Knochens und die Weltposition von
Hipsabgelesen. - Die Zeiten des neuen Clips laufen von 0 bis D. Frame 0 (T-Pose) fällt dadurch weg.
- Blickrichtung: Der Hüft-Vorwärtsvektor des ersten Bilds zeigt in der Waagrechten um θ neben +Z. Alle Weltdrehungen und Hüftpositionen des Clips werden um −θ um die Hochachse gedreht.
- Ort:
- Die waagrechte Hüftposition des ersten Bilds wird zu 0.
- Die Drift wird linear abgezogen: Bild i verliert i/(n−1) · (Ende − Anfang), in x und z.
- Ende und Anfang stehen danach am selben Punkt. Die Höhe bleibt unverändert.
- Übertragen:
- Zuordnung MVN → Mannequin:
Hips→pelvis,Spine→spine_01,Spine1→spine_02,Spine3→spine_03,Neck→neck_01,Head→Head. Je Seite außerdemShoulder→clavicle,Arm→upperarm,ForeArm→lowerarm,Hand→hand,UpLeg→thigh,Leg→calf,Foot→foot,ToeBase→ball. - Die Zuordnung folgt der gemessenen Höhe.
Spine2hat kein Gegenstück, ihre Drehung geht über die Weltdrehung inspine_03ein. - Weltdrehung Mannequin = Weltdrehung MVN · Ruhe-Weltdrehung Mannequin. Das gilt, weil beide Skelette in derselben T-Pose mit gleichem Blick ruhen und jede MVN-Ruhe-Weltdrehung 0° ist.
- Lokale Drehung = (Weltdrehung Elternknochen)⁻¹ · Weltdrehung. Eltern ohne Zuordnung (
root,Armature) gehen mit ihrer Ruhepose ein. - Hüfte: Position in m = Position in cm / 100 · (0,917 / Hüfthöhe der Datei), umgerechnet in den Raum von
root. - Finger, Blattknochen und
rootbekommen keine Spur.
- Zuordnung MVN → Mannequin:
- Schleife schließen:
- Naht = größte Abweichung der Weltdrehung zwischen letztem und erstem Bild über alle Knochen.
- Überblendzeit b = Naht / 90 °/s, begrenzt auf 0,25 s bis 1,5 s. Das ergibt 1,01 s für den Bogenschützen und 0,25 s für alle übrigen.
- In den letzten b Sekunden werden alle lokalen Drehungen (slerp) und die Hüftposition (lerp) mit dem Gewicht smoothstep((t − (T − b)) / b) zum ersten Bild gezogen. Das letzte Bild ist dann gleich dem ersten.
- Schreiben:
- gltf-transform-Dokument mit der Knotenhierarchie von
ual.glb(Namen und Ruhe-TRS, ohne Mesh und Skin). - Je Clip eine Animation mit gemeinsamem Zeit-Accessor, 22 Drehungskanälen und einem Translationskanal (
pelvis), alle LINEAR und als Float32. - Keine Kompression, geschätzt 1,6 MB (144 s × 30 Bilder × 91 Werte × 4 Byte).
- gltf-transform-Dokument mit der Knotenhierarchie von
Die Clips binden über Knotennamen an die Knochen eines geklonten Mannequins.
Umbau der Waffen (tools/assets/weapons.mjs)
node tools/assets/weapons.mjs <Ordner WeaponsPack> -> public/models/weapons/{pistol,ak47,m4,shotgun870,l96}.glb
- Geometrie:
- Positionen, Normalen und der erste UV-Satz kommen aus dem Mesh von
FBXLoader. - Die Knotendrehung wird angewendet, der Knotenmaßstab nicht. Die Eckpunkte liegen schon in Metern (siehe Befund).
- Längenprüfung: Pistole 0,15–0,25 m, Gewehre 0,7–1,3 m, sonst bricht das Skript mit Meldung ab.
- UV: v → 1 − v, weil FBX den Ursprung unten links hat und glTF oben links.
- Danach
weld()und meshopt wie inplaces.mjs.
- Positionen, Normalen und der erste UV-Satz kommen aus dem Mesh von
- Material (glTF metallicRoughness):
- Grundfarbe aus
T_(sRGB, Alpha verworfen). - Normalmap aus
N_, unverändert. metallicRoughnessTexturewird neu zusammengesetzt: G = Grauwert der Maske (Rauheit), B = Alpha der Maske (Metall), R = 255.- Beide Faktoren stehen auf 1.
- Grundfarbe aus
- TGA: eigener Leser
readTga(buffer)→{ width, height, data }in RGBA mit oberster Zeile zuerst. Er kann nur Typ 2 mit 32 Bit, bei allem anderen bricht er mit Meldung ab. Der Ursprung kommt aus Bit 5 von Byte 17. - Texturen:
sharp→ WebP mit höchstens 1024 px Kantenlänge, die 512-px-Maske der Pistole bleibt 512 px. Qualität 80, Normalmaps 92, wieplaces.mjs. - AK47: nur „Option 2".
Griff einpassen
- Werkzeug: Die Griffwerte in
WEAPONSentstehen im Browser mit dem Panel. - Ansicht: Nahaufnahme von der Seite und von oben an einer Stelle des Clips, an der die Hand ruhig die Waffe hält.
- Ziel: Das Griffstück liegt in der Handfläche, der Lauf zeigt entlang der Hand nach vorn, und die Waffe steckt nicht im Unterarm.
- Vorgehen: Das Pack verspricht für Pistole, M4, 870, L96 und AK47 (Option 2) denselben Griffpunkt. Zuerst wird die Pistole eingepasst, ihr Wert ist dann der Startwert der übrigen. Jede Waffe bekommt trotzdem ihren eigenen Eintrag.
Tests
tests/motions.test.js:clipIdliest alle 11 Dateinamen richtig.- MVN in Ruhepose ergibt die Ruhepose des Mannequins, in lokalen Drehungen auf 1e-6.
- Eine Weltdrehung von 90° am linken Oberarm kommt als Weltdrehung von
upperarm_lan (· Ruhe-Weltdrehung). - Eine Drehung an
Spine3dreht Schlüsselbein und Arm in der Welt mit, deren lokale Drehung bleibt gleich. - Hüfte: cm → m, Faktor 0,917 / Hüfthöhe, Raum von
root. - Blickrichtung: Nach Schritt 3 zeigt die Hüfte im ersten Bild nach +Z.
- Ort: Das erste Bild steht bei x = z = 0, das letzte ebenso.
- Abtastung: n = round(D · 30) + 1 Zeiten von 0 bis D in gleichem Abstand, das erste Bild entspricht Frame 1 der Quelle.
- Schleife: Letztes und erstes Bild sind gleich. Die Überblendzeit hält die Grenzen 0,25 s und 1,5 s ein.
tests/weapons.test.js:readTgaliest eine künstliche 2 × 2-Datei richtig, mit Ursprung unten und oben.- Typ 10 (RLE) und 24 Bit werden abgelehnt.
- Maske → metallicRoughness: G = Grau, B = Alpha, R = 255.
- UV: v → 1 − v.
- Die Längenprüfung schlägt bei falscher Einheit an (Pistole mal 100).
tests/showroom.test.js:- 13 Dummies. Jeder Clip existiert in
weapons-mocap.glb, jede Waffe hat eine Datei inpublic/models/weapons/und einen Griff. - Kein Platz näher als 3,5 m an einem anderen. Um den Bogenschützen sind mindestens 4 m frei.
- Jede Waffen-GLB hat ein Mesh, meshopt, WebP-Texturen bis 1024 px und liegt in den Längengrenzen.
- 13 Dummies. Jeder Clip existiert in
- Browser:
animationen.htmllädt ohne Konsolenfehler, alle 13 Mixer laufen.- Übersichtsbild und Nahaufnahme je Waffe.
- Schleifennaht: Die Knochendrehungen eines Dummys ein Bild vor und ein Bild nach dem Rücksprung liegen nicht weiter auseinander als zwei benachbarte Bilder mitten im Clip, gemessen an den Knochen mit der größten Naht vor dem Umbau.
- Die Spielfigur läuft per Tastatur, ihre Position ändert sich.
- Bildzeit mit allen Dummies.
- Maskenbelegung auf Sicht: Das Holz der AK47 glänzt nicht metallisch.
- Gesamt:
npm testgrün,npm run buildbaut beide Seiten,index.htmllädt weiter wie bisher.
Fehlerfälle und Risiken
- Maskenbelegung falsch: Glänzt Holz metallisch oder wirkt Metall stumpf wie Kunststoff, werden Grau und Alpha getauscht und neu gebaut. Die Browserprüfung oben fängt das.
- Proportionen:
- Der Darsteller ist kleiner als das Mannequin, der Kopf liegt bei 1,506 m statt 1,569 m.
- Beim Taunt kann die Pistole in den Kopf ragen, die Hände können sich durchdringen, die Füße ein paar Zentimeter schweben oder einsinken.
- Es gibt keine IK. Auffälliges wird im Gespräch entschieden.
- Linke Hand am Gewehr: Sie ist nicht an den Handschutz gebunden und liegt dort, wo die Mocap-Daten sie hinlegen.
- Blickrichtung: Nach Schritt 3 schauen die Hüften nach vorn. Der Granatwurf mit −44° Anfangsdrehung zielt danach entsprechend schräg.
- Bogenschütze: Er wandert bis 3,13 m (× Maßstab) von seinem Platz und dreht sich dabei. Die Überblendung am Ende dauert 1 s.
- Node-Platzhalter für
FBXLoader: Sie hängen an three 0.184.0 (inpackage.jsonfest). Ein Update kann den Umbau brechen, die erzeugten GLBs bleiben davon unberührt. - Lizenz: Die Zips enthalten keine Lizenzdatei. Die erzeugten GLBs werden wie die übrigen Modelle versioniert (Remote
git.webklar.com), die Zips selbst nicht (*.zipin.gitignore).
Nicht Teil dieser Arbeit
- Dummies in der Leonida-Welt.
- Waffen für die Spielfigur (Tragen, Zielen, Schießen).
- IK für Hände oder Füße.
- Kollision mit Dummies.
- Superhero-Figuren oder Frisuren als Dummies.
- AK47 „Option 1".
- Eigene Modelle für Messer, Granate und Bogen.