Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | 28x 28x 28x 28x 28x 28x 28x 28x 28x 8115x 8115x 1x 8114x 8087x 27x 2x 28x 3x 2x 1x 1x 8x 8x 8x 8x 8x 8x 1x 1x | /**
* Fighting Stance Guard Poses for Eight Trigram System
*
* Defines default guard positions for all 8 trigram stances (팔괘).
* Each guard pose includes arm positions, torso rotation, weight distribution,
* and breathing animation parameters for authentic Korean martial arts stance representation.
*
* Based on COMBAT_ARCHITECTURE.md and game-design.md specifications:
* - ☰ 건 (Geon/Heaven): High guard with strong forward presence
* - ☱ 태 (Tae/Lake): Fluid mid-guard with adaptive positioning
* - ☲ 리 (Li/Fire): Aggressive forward guard
* - ☳ 진 (Jin/Thunder): Explosive ready stance
* - ☴ 손 (Son/Wind): Continuous motion guard
* - ☵ 감 (Gam/Water): Flowing defensive guard
* - ☶ 간 (Gan/Mountain): Solid defensive posture
* - ☷ 곤 (Gon/Earth): Grounded low guard
*
* @module systems/animation/StanceGuardPoses
* @category Animation
* @korean 자세방어포즈
*/
import * as THREE from "three";
import { TrigramStance } from "../../types/common";
import type {
StanceGuardAnimationConfig,
StanceGuardPose,
} from "../../types/skeletal";
import { mirrorGuardPose } from "../../types/skeletal";
import type { StanceLaterality } from "../trigram/types";
/**
* ☰ 건 (Geon) - Heaven: High guard with strong forward presence
*
* Traditional Taekwondo Ap Seogi (앞서기) - Walking Stance
* - Both hands raised high (shoulder level or above)
* - Ready to deliver powerful overhead strikes
* - Weight slightly forward for aggressive positioning
* - Breathing emphasizes chest expansion for power generation
*
* **Leg Position (Ap Seogi)**:
* - Feet shoulder-width apart (0.5m)
* - Front leg slightly bent, ready to step
* - Back leg providing power base
* - Natural, mobile stance for quick movement
*
* Combat Application:
* - Direct frontal bone-breaking strikes
* - High mobility (+15% movement speed from game-design.md)
* - Bone-break attacks (+10% startup time)
*
* ENHANCED: Proper boxing-style guard - elbows tight, hands protect chin/temple
*
* @korean 건괘방어포즈
*/
export const GEON_HIGH_GUARD_POSE: StanceGuardPose = {
leftArm: {
shoulder: new THREE.Euler(-0.7, 0.35, 0.25), // Elbow forward, close to body
elbow: new THREE.Euler(0, 0, -1.7), // Tight bend - fist near face
wrist: new THREE.Euler(0.25, 0.1, 0), // Fist at chin level
},
rightArm: {
shoulder: new THREE.Euler(-0.7, -0.35, -0.25), // Mirror - close to body
elbow: new THREE.Euler(0, 0, 1.7), // Tight bend - fist near face
wrist: new THREE.Euler(0.25, -0.1, 0), // Fist at chin level
},
torso: new THREE.Euler(0.12, 0, 0), // Slight forward lean - chin tucked
// NEW: Ap Seogi (Walking Stance) - Natural, mobile leg position
leftLeg: {
hip: new THREE.Euler(0.1, 0.05, 0), // Slight forward, minimal rotation
knee: new THREE.Euler(0.2, 0, 0), // 20° bend - ready to move
ankle: new THREE.Euler(-0.1, 0, 0), // Slight dorsiflexion
},
rightLeg: {
hip: new THREE.Euler(0.05, -0.05, 0), // Slightly back
knee: new THREE.Euler(0.15, 0, 0), // 15° bend - stable base
ankle: new THREE.Euler(-0.08, 0, 0), // Natural position
},
pelvis: new THREE.Euler(0.05, 0, 0), // Slight forward tilt
stanceWidth: 0.5, // Shoulder width - mobile
weight: "forward",
breathingRange: {
min: 0.98, // Slight chest expansion
max: 1.02, // Exhale contraction
},
};
/**
* ☱ 태 (Tae) - Lake: Fluid mid-guard with adaptive positioning
*
* Traditional Taekwondo Ap Koobi Seogi (앞굽이) - Front Stance
* - Hands at mid-level (chest height)
* - Ready for joint manipulation and throws
* - Weight forward for reach (+15% reach from game-design.md)
* - Breathing flows smoothly for continuous adaptation
*
* **Leg Position (Ap Koobi Seogi)**:
* - Deep front lunge, front knee over toes
* - Back leg straight, heel down
* - 70% weight forward, powerful reach
* - Wide stance (0.9m) for stability
*
* Combat Application:
* - Joint locks and throwing techniques
* - +15% reach for throws/sweeps
* - +10% takedown damage
*
* ENHANCED: Lead hand parries, rear hand protects chin - grappling ready
*
* @korean 태괘방어포즈
*/
export const TAE_FLUID_GUARD_POSE: StanceGuardPose = {
leftArm: {
shoulder: new THREE.Euler(-0.35, 0.5, 0.35), // Lead hand forward/mid, elbow in
elbow: new THREE.Euler(0, 0, -1.3), // Moderately bent - parrying
wrist: new THREE.Euler(0.15, 0.2, 0), // Open hand ready to grip
},
rightArm: {
shoulder: new THREE.Euler(-0.65, -0.3, -0.3), // Rear hand close to chin
elbow: new THREE.Euler(0, 0, 1.6), // Tight bend - protecting face
wrist: new THREE.Euler(0.2, -0.15, 0), // Fist at chin level
},
torso: new THREE.Euler(0.12, 0.15, 0), // Forward, slight rotation
// NEW: Ap Koobi Seogi (Front Stance) - Deep lunge position
leftLeg: {
hip: new THREE.Euler(0.4, 0.1, 0), // Forward, knee over toes
knee: new THREE.Euler(0.9, 0, 0), // ~0.9 rad (~52°) deep bend - POWER
ankle: new THREE.Euler(-0.2, 0, 0), // Dorsiflexed, stable
},
rightLeg: {
hip: new THREE.Euler(-0.1, -0.1, 0), // Extended back
knee: new THREE.Euler(0.1, 0, 0), // Nearly straight - locked
ankle: new THREE.Euler(-0.05, 0, 0), // Heel planted
},
pelvis: new THREE.Euler(0.1, 0, 0), // Forward tilt for reach
stanceWidth: 0.9, // Wide for stability
weight: "forward",
breathingRange: {
min: 0.97, // Smooth inhale
max: 1.03, // Full exhale for fluid motion
},
};
/**
* ☲ 리 (Li) - Fire: Aggressive forward guard
*
* Traditional Taekwondo Juchum Seogi (주춤) - Horse Stance
* - Hands forward in striking position
* - Ready for precise nerve strikes
* - Weight neutral but low center of gravity
* - Breathing controlled for precision (+5% crit hit chance)
*
* **Leg Position (Juchum Seogi)**:
* - WIDE stance (1.2m) - parallel feet
* - Both knees bent deeply (horse riding position)
* - Low center of gravity for stability
* - Equal weight distribution
*
* Combat Application:
* - Precise vital point strikes
* - +15% stability vs. vital strikes
* - +10% knockdown resistance
*
* ENHANCED: Peekaboo guard - both hands high protecting face, aggressive stance
*
* @korean 리괘방어포즈
*/
export const LI_FIRE_GUARD_POSE: StanceGuardPose = {
leftArm: {
shoulder: new THREE.Euler(-0.75, 0.25, 0.35), // Elbow forward, hand near cheek
elbow: new THREE.Euler(0, 0, -1.75), // Tight bend - fist at face
wrist: new THREE.Euler(0.2, 0.15, 0), // Fist protecting cheekbone
},
rightArm: {
shoulder: new THREE.Euler(-0.75, -0.25, -0.35), // Mirror - both protecting face
elbow: new THREE.Euler(0, 0, 1.75), // Tight bend - fist at face
wrist: new THREE.Euler(0.2, -0.15, 0), // Fist protecting cheekbone
},
torso: new THREE.Euler(0.1, 0.2, 0), // Slight rotation, chin tucked
// NEW: Juchum Seogi (Horse Stance) - Wide, low, stable
leftLeg: {
hip: new THREE.Euler(0, 0.15, 0.2), // Outward rotation, wide
knee: new THREE.Euler(0.8, 0, 0), // ~0.8 rad (~46°) deep bend - LOW
ankle: new THREE.Euler(-0.15, 0, 0), // Flexed for stability
},
rightLeg: {
hip: new THREE.Euler(0, -0.15, -0.2), // Outward rotation, wide
knee: new THREE.Euler(0.8, 0, 0), // ~0.8 rad (~46°) deep bend - LOW
ankle: new THREE.Euler(-0.15, 0, 0), // Flexed for stability
},
pelvis: new THREE.Euler(0, 0, 0), // Level, stable platform
stanceWidth: 1.2, // WIDE horse stance - VERY DISTINCT
weight: "neutral",
breathingRange: {
min: 0.99, // Shallow, controlled breathing
max: 1.01, // Precision focus
},
};
/**
* ☳ 진 (Jin) - Thunder: Explosive ready stance
*
* Traditional Taekwondo Dwi Koobi Seogi (뒤굽이) - Back Stance
* - Hands chambered for explosive release
* - Ready for shocking nerve strikes
* - Weight back but explosive forward (+15% shock damage)
* - Breathing deep for power generation
*
* **Leg Position (Dwi Koobi Seogi)**:
* - 70% weight on back leg
* - Front leg light, ready to kick or step
* - Back knee bent deeply, coiled spring
* - Moderate width (0.7m) for mobility
*
* Combat Application:
* - Nerve strike warfare
* - +15% shock damage on nerve strikes
* - -30 consciousness on head hits
*
* ENHANCED: Chambered guard - fists at ribs ready to explode, elbows protect body
*
* @korean 진괘방어포즈
*/
export const JIN_THUNDER_GUARD_POSE: StanceGuardPose = {
leftArm: {
shoulder: new THREE.Euler(-0.6, 0.2, 0.45), // Elbow tight to ribs
elbow: new THREE.Euler(0, 0, -1.9), // Very tight - fist at chest
wrist: new THREE.Euler(0.3, 0.1, 0), // Chambered at solar plexus
},
rightArm: {
shoulder: new THREE.Euler(-0.6, -0.2, -0.45), // Mirror - ribs protected
elbow: new THREE.Euler(0, 0, 1.9), // Very tight - fist at chest
wrist: new THREE.Euler(0.3, -0.1, 0), // Chambered at solar plexus
},
torso: new THREE.Euler(-0.1, 0, 0), // Slight backward lean - coiled
// NEW: Dwi Koobi Seogi (Back Stance) - Weight back, coiled
leftLeg: {
hip: new THREE.Euler(0.1, 0.05, 0), // Front leg light
knee: new THREE.Euler(0.3, 0, 0), // 30° slight bend - ready
ankle: new THREE.Euler(-0.1, 0, 0), // Light on ball of foot
},
rightLeg: {
hip: new THREE.Euler(-0.1, -0.05, 0), // Back leg loaded
knee: new THREE.Euler(0.7, 0, 0), // 70° deep bend - COILED
ankle: new THREE.Euler(-0.2, 0, 0), // Firmly planted
},
pelvis: new THREE.Euler(-0.1, 0, 0), // Tilted back for coiling
stanceWidth: 0.7, // Moderate - mobile but stable
weight: "back",
breathingRange: {
min: 0.96, // Deep inhale for power
max: 1.04, // Explosive exhale
},
};
/**
* ☴ 손 (Son) - Wind: Continuous motion guard
*
* Traditional Taekwondo Niunja Seogi (니은자) - L-Stance
* - Hands in flowing circular pattern
* - Ready for continuous pressure attacks
* - Weight neutral for lateral movement (+10% lateral)
* - Breathing rhythmic for sustained combos
*
* **Leg Position (Niunja Seogi)**:
* - L-shaped narrow stance (0.4m)
* - Front foot turned inward (L-shape)
* - Back foot pointing forward
* - Weight 50/50 for quick lateral shifts
*
* Combat Application:
* - Pressure point sequences
* - +10% chaining speed on pressure sequences
* - +10% lateral movement
*
* ENHANCED: Staggered guard - lead hand forward, rear protects chin, ready for combos
*
* @korean 손괘방어포즈
*/
export const SON_WIND_GUARD_POSE: StanceGuardPose = {
leftArm: {
shoulder: new THREE.Euler(-0.55, 0.5, 0.4), // Lead hand forward but elbow in
elbow: new THREE.Euler(0, 0, -1.4), // Moderately bent - quick combos
wrist: new THREE.Euler(0.15, 0.2, 0), // Hand near eye level
},
rightArm: {
shoulder: new THREE.Euler(-0.7, -0.3, -0.35), // Rear hand tight to face
elbow: new THREE.Euler(0, 0, 1.7), // Tight bend - chin protected
wrist: new THREE.Euler(0.2, -0.1, 0), // Fist at cheek level
},
torso: new THREE.Euler(0.05, -0.2, 0), // Slight rotation for flow
// NEW: Niunja Seogi (L-Stance) - Narrow, mobile
leftLeg: {
hip: new THREE.Euler(0, 0.3, 0), // Turned inward (L-shape)
knee: new THREE.Euler(0.4, 0, 0), // 40° moderate bend
ankle: new THREE.Euler(-0.1, 0, 0), // Flexible for movement
},
rightLeg: {
hip: new THREE.Euler(0, 0, 0), // Forward facing
knee: new THREE.Euler(0.4, 0, 0), // 40° moderate bend
ankle: new THREE.Euler(-0.1, 0, 0), // Flexible for movement
},
pelvis: new THREE.Euler(0, -0.15, 0), // Rotated for L-shape
stanceWidth: 0.4, // NARROW - highly mobile
weight: "neutral",
breathingRange: {
min: 0.985, // Rhythmic breathing
max: 1.015, // Sustained cycles
},
};
/**
* ☵ 감 (Gam) - Water: Flowing defensive guard
*
* Traditional Taekwondo Narani Seogi (나란이) - Parallel Stance
* - Hands low and flowing
* - Ready for counter-grappling and sweeps
* - Weight centered for adaptability (+10% counter speed)
* - Breathing deep and flowing
*
* **Leg Position (Narani Seogi)**:
* - Feet parallel, shoulder-width (0.5m)
* - Natural standing position
* - Slight knee bend for readiness
* - Balanced, adaptive stance
*
* Combat Application:
* - Flow-into counters
* - +10% adaptability/counter speed
* - +15 bleed on rib shots
*
* ENHANCED: Mid-level guard - hands at solar plexus, ready to parry and counter
*
* @korean 감괘방어포즈
*/
export const GAM_WATER_GUARD_POSE: StanceGuardPose = {
leftArm: {
shoulder: new THREE.Euler(-0.5, 0.4, 0.4), // Mid-level, elbow in
elbow: new THREE.Euler(0, 0, -1.5), // Bent for parrying
wrist: new THREE.Euler(0.1, 0.2, 0), // Open hand at chest
},
rightArm: {
shoulder: new THREE.Euler(-0.5, -0.4, -0.4), // Mid-level, elbow in
elbow: new THREE.Euler(0, 0, 1.5), // Bent for parrying
wrist: new THREE.Euler(0.1, -0.2, 0), // Open hand at chest
},
torso: new THREE.Euler(0, 0, 0), // Centered, no rotation
// NEW: Narani Seogi (Parallel Stance) - Natural, adaptive
leftLeg: {
hip: new THREE.Euler(0, 0, 0), // Neutral, parallel
knee: new THREE.Euler(0.25, 0, 0), // 25° slight ready bend
ankle: new THREE.Euler(-0.08, 0, 0), // Natural position
},
rightLeg: {
hip: new THREE.Euler(0, 0, 0), // Neutral, parallel
knee: new THREE.Euler(0.25, 0, 0), // 25° slight ready bend
ankle: new THREE.Euler(-0.08, 0, 0), // Natural position
},
pelvis: new THREE.Euler(0, 0, 0), // Neutral, centered
stanceWidth: 0.5, // Shoulder width - natural
weight: "neutral",
breathingRange: {
min: 0.97, // Deep, flowing inhale
max: 1.03, // Full exhale for counter
},
};
/**
* ☶ 간 (Gan) - Mountain: Solid defensive posture
*
* Traditional Taekwondo Gibo Seogi (기본) - Basic Stance
* - Arms in tight defensive position
* - Immovable blocking stance
* - Weight balanced for maximum stability (+15% block strength)
* - Breathing steady and controlled
*
* **Leg Position (Gibo Seogi)**:
* - Feet close together (0.3m) - NARROW
* - Mountain-solid, immovable
* - Knees slightly bent for shock absorption
* - Maximum stability for blocking
*
* Combat Application:
* - Impenetrable defense
* - +15% block strength
* - +10% counter-strike speed
*
* ENHANCED: High cover guard - forearms cross in front of face for maximum protection
*
* @korean 간괘방어포즈
*/
export const GAN_MOUNTAIN_GUARD_POSE: StanceGuardPose = {
leftArm: {
shoulder: new THREE.Euler(-0.85, 0.2, 0.5), // High, forearm covers face
elbow: new THREE.Euler(0, 0, -1.8), // Tight bend - forearm vertical
wrist: new THREE.Euler(0.35, 0.15, 0), // Fist near temple
},
rightArm: {
shoulder: new THREE.Euler(-0.85, -0.2, -0.5), // High, forearm covers face
elbow: new THREE.Euler(0, 0, 1.8), // Tight bend - forearm vertical
wrist: new THREE.Euler(0.35, -0.15, 0), // Fist near temple
},
torso: new THREE.Euler(0.05, 0, 0), // Slight forward - compact
// NEW: Gibo Seogi (Basic Stance) - Narrow, mountain-solid
leftLeg: {
hip: new THREE.Euler(0, 0, 0), // Close, neutral
knee: new THREE.Euler(0.2, 0, 0), // 20° slight bend - shock absorber
ankle: new THREE.Euler(-0.05, 0, 0), // Stable platform
},
rightLeg: {
hip: new THREE.Euler(0, 0, 0), // Close, neutral
knee: new THREE.Euler(0.2, 0, 0), // 20° slight bend - shock absorber
ankle: new THREE.Euler(-0.05, 0, 0), // Stable platform
},
pelvis: new THREE.Euler(0, 0, 0), // Centered, immovable
stanceWidth: 0.3, // NARROW - mountain solid
weight: "neutral",
breathingRange: {
min: 0.99, // Minimal movement
max: 1.01, // Steady control
},
};
/**
* ☷ 곤 (Gon) - Earth: Grounded low guard
*
* Traditional Taekwondo Joong Ha Seogi (중하) - Deep Stance
* - Hands low for ground control
* - Ready for throws and takedowns
* - Weight low and stable (+20% ground-control)
* - Breathing deep from diaphragm
*
* **Leg Position (Joong Ha Seogi)**:
* - VERY DEEP squat position
* - Wide stance (0.8m) for grounding
* - Knees bent 100° - DEEP
* - Low center of gravity - earth connection
*
* Combat Application:
* - Ground clinches and throws
* - +20% ground-control advantage
* - +20 bleed on takedowns
*
* ENHANCED: Low underhook guard - hands at hip level, elbows in protecting ribs
*
* @korean 곴괘방어포즈
*/
export const GON_EARTH_GUARD_POSE: StanceGuardPose = {
leftArm: {
shoulder: new THREE.Euler(-0.15, 0.35, 0.5), // Low underhook - hands at hip level
elbow: new THREE.Euler(0, 0, -1.6), // Bent tight - protects liver
wrist: new THREE.Euler(0.1, 0.15, 0), // Hands at hip/belt level
},
rightArm: {
shoulder: new THREE.Euler(-0.15, -0.35, -0.5), // Low underhook - hands at hip level
elbow: new THREE.Euler(0, 0, 1.6), // Bent tight - protects liver
wrist: new THREE.Euler(0.1, -0.15, 0), // Hands at hip/belt level
},
torso: new THREE.Euler(0.15, 0, 0), // Forward lean - wrestling ready
// NEW: Joong Ha Seogi (Deep Stance) - VERY low, grounded
leftLeg: {
hip: new THREE.Euler(0, 0.1, 0.15), // Wide, outward
knee: new THREE.Euler(1.0, 0, 0), // ~1.0 rad (~57°) VERY DEEP bend - GROUNDED
ankle: new THREE.Euler(-0.2, 0, 0), // Deep dorsiflexion
},
rightLeg: {
hip: new THREE.Euler(0, -0.1, -0.15), // Wide, outward
knee: new THREE.Euler(1.0, 0, 0), // ~1.0 rad (~57°) VERY DEEP bend - GROUNDED
ankle: new THREE.Euler(-0.2, 0, 0), // Deep dorsiflexion
},
pelvis: new THREE.Euler(-0.1, 0, 0), // Tilted forward and low
stanceWidth: 0.8, // Wide - grounded and stable
weight: "neutral",
breathingRange: {
min: 0.96, // Deep diaphragm breathing
max: 1.04, // Full power exhale
},
};
/**
* Stance Guard Animation Configurations
*
* Record mapping each trigram stance to its complete guard animation config.
* Includes 4-6 frame breathing animation at 60fps for realistic idle behavior.
*
* Using Record instead of Map for better performance with small static dataset.
*
* Integration:
* - Links to AnimationStateMachine for stance-specific idle states
* - Used by SkeletalPlayer3D for rendering guard positions
* - Integrates with StanceManager for trigram system
*
* @korean 자세방어애니메이션설정맵
*/
export const STANCE_GUARD_CONFIGS: Record<
TrigramStance,
StanceGuardAnimationConfig
> = {
[TrigramStance.GEON]: {
stance: TrigramStance.GEON,
koreanName: "건",
englishName: "Heaven",
guardPose: GEON_HIGH_GUARD_POSE,
breathingFrames: 6,
fps: 60,
loop: true,
priority: 0,
},
[TrigramStance.TAE]: {
stance: TrigramStance.TAE,
koreanName: "태",
englishName: "Lake",
guardPose: TAE_FLUID_GUARD_POSE,
breathingFrames: 6,
fps: 60,
loop: true,
priority: 0,
},
[TrigramStance.LI]: {
stance: TrigramStance.LI,
koreanName: "리",
englishName: "Fire",
guardPose: LI_FIRE_GUARD_POSE,
breathingFrames: 4,
fps: 60,
loop: true,
priority: 0,
},
[TrigramStance.JIN]: {
stance: TrigramStance.JIN,
koreanName: "진",
englishName: "Thunder",
guardPose: JIN_THUNDER_GUARD_POSE,
breathingFrames: 5,
fps: 60,
loop: true,
priority: 0,
},
[TrigramStance.SON]: {
stance: TrigramStance.SON,
koreanName: "손",
englishName: "Wind",
guardPose: SON_WIND_GUARD_POSE,
breathingFrames: 6,
fps: 60,
loop: true,
priority: 0,
},
[TrigramStance.GAM]: {
stance: TrigramStance.GAM,
koreanName: "감",
englishName: "Water",
guardPose: GAM_WATER_GUARD_POSE,
breathingFrames: 6,
fps: 60,
loop: true,
priority: 0,
},
[TrigramStance.GAN]: {
stance: TrigramStance.GAN,
koreanName: "간",
englishName: "Mountain",
guardPose: GAN_MOUNTAIN_GUARD_POSE,
breathingFrames: 4,
fps: 60,
loop: true,
priority: 0,
},
[TrigramStance.GON]: {
stance: TrigramStance.GON,
koreanName: "곤",
englishName: "Earth",
guardPose: GON_EARTH_GUARD_POSE,
breathingFrames: 5,
fps: 60,
loop: true,
priority: 0,
},
} as const;
/**
* Get guard pose for a specific trigram stance with laterality support
*
* **Korean**: 자세 방어 포즈 가져오기
*
* Returns the appropriate guard pose for the given stance and laterality.
* Right laterality returns the base pose; left laterality returns a mirrored version.
* This supports authentic Korean martial arts stance differentiation:
* - 오른발서기 (Oreun Bal Seogi): Right foot forward - base pose
* - 왼발서기 (Oenbal Seogi): Left foot forward - mirrored pose
*
* @param stance - Trigram stance identifier (e.g., "geon", "tae")
* @param laterality - Stance side: "left" or "right" (defaults to "right")
* @returns Guard pose configuration or undefined if not found
*
* @example
* ```typescript
* // Get right Heaven stance (default)
* const rightGeon = getGuardPoseForStance("geon", "right");
*
* // Get left Heaven stance (mirrored)
* const leftGeon = getGuardPoseForStance("geon", "left");
* // leftGeon now has left foot forward, left hand lead
* ```
*
* @korean 자세방어포즈가져오기
*/
export function getGuardPoseForStance(
stance: TrigramStance,
laterality: StanceLaterality = "right"
): StanceGuardPose | undefined {
const config = STANCE_GUARD_CONFIGS[stance];
if (!config?.guardPose) {
return undefined;
}
// Right laterality returns base pose
if (laterality === "right") {
return config.guardPose;
}
// Left laterality returns mirrored pose
return mirrorGuardPose(config.guardPose);
}
/**
* Get guard animation config for a specific trigram stance
*
* @param stance - Trigram stance identifier
* @returns Complete guard animation configuration or undefined if not found
*
* @korean 자세방어애니메이션설정가져오기
*/
export function getGuardConfigForStance(
stance: TrigramStance
): StanceGuardAnimationConfig | undefined {
return STANCE_GUARD_CONFIGS[stance];
}
/**
* Get all 16 stance guard poses (8 stances × 2 laterality options)
*
* **Korean**: 모든 자세 방어 포즈
*
* Returns a map of all possible stance+laterality combinations with their guard poses.
* This represents the complete set of 16 distinct guard configurations in Black Trigram.
*
* The result is cached for performance - subsequent calls return the same Map instance.
*
* Format: `"stance_laterality"` → `StanceGuardPose`
* - Example keys: "geon_left", "geon_right", "tae_left", "tae_right", etc.
*
* @returns Map of all 16 stance guard pose configurations
*
* @korean 모든자세방어포즈
*/
let cachedAllPoses: Map<string, StanceGuardPose> | null = null;
export function getAllStanceGuardPoses(): Map<string, StanceGuardPose> {
// Return cached result if available for performance
if (cachedAllPoses) {
return cachedAllPoses;
}
const allPoses = new Map<string, StanceGuardPose>();
// For each trigram stance
Object.values(TrigramStance).forEach((stance) => {
// Add right laterality (base pose)
const rightPose = getGuardPoseForStance(stance, "right");
Eif (rightPose) {
allPoses.set(`${stance}_right`, rightPose);
}
// Add left laterality (mirrored pose)
const leftPose = getGuardPoseForStance(stance, "left");
Eif (leftPose) {
allPoses.set(`${stance}_left`, leftPose);
}
});
// Cache the result
cachedAllPoses = allPoses;
return allPoses;
}
|