@hology/core 0.0.211 → 0.0.213

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/dist/effects/sequence/index.d.ts +1 -0
  2. package/dist/effects/sequence/index.js +1 -1
  3. package/dist/effects/sequence/sequence-action.d.ts +5 -0
  4. package/dist/effects/sequence/sequence-actor.d.ts +7 -0
  5. package/dist/effects/sequence/sequence-actor.js +1 -1
  6. package/dist/effects/sequence/sequence-animation-retiming.js +1 -1
  7. package/dist/effects/sequence/sequence-data.d.ts +9 -0
  8. package/dist/effects/sequence/sequence-data.js +1 -1
  9. package/dist/effects/sequence/sequence-player.d.ts +12 -1
  10. package/dist/effects/sequence/sequence-player.js +1 -1
  11. package/dist/effects/sequence/sequence-transform.d.ts +10 -0
  12. package/dist/effects/sequence/sequence-transform.js +4 -0
  13. package/dist/effects/sequence/sequence-value-lane.d.ts +2 -0
  14. package/dist/effects/sequence/sequence-value-lane.js +1 -1
  15. package/dist/effects/vfx/initializsers.d.ts +8 -1
  16. package/dist/effects/vfx/initializsers.js +1 -1
  17. package/dist/effects/vfx/vfx-actor.d.ts +5 -0
  18. package/dist/effects/vfx/vfx-actor.js +1 -1
  19. package/dist/effects/vfx/vfx-asset.d.ts +2 -1
  20. package/dist/effects/vfx/vfx-asset.js +1 -1
  21. package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
  22. package/dist/effects/vfx/vfx-defs.d.ts +10 -1
  23. package/dist/effects/vfx/vfx-defs.js +1 -1
  24. package/dist/effects/vfx/vfx-materializer.js +1 -1
  25. package/dist/effects/vfx/vfx-renderers.d.ts +2 -0
  26. package/dist/effects/vfx/vfx-renderers.js +1 -1
  27. package/dist/gameplay/actors/actor.d.ts +21 -1
  28. package/dist/gameplay/actors/actor.js +1 -1
  29. package/dist/gameplay/actors/builtin/components/character/character-animation.d.ts +3 -0
  30. package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
  31. package/dist/gameplay/actors/builtin/components/character/character-movement-like.d.ts +25 -0
  32. package/dist/gameplay/actors/builtin/components/character/character-movement-like.js +4 -0
  33. package/dist/gameplay/actors/builtin/components/character/character-movement-policy.d.ts +26 -0
  34. package/dist/gameplay/actors/builtin/components/character/character-movement-policy.js +4 -0
  35. package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +158 -55
  36. package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
  37. package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.d.ts +128 -0
  38. package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.js +4 -0
  39. package/dist/gameplay/actors/builtin/components/character/old-character-movement.d.ts +100 -0
  40. package/dist/gameplay/actors/builtin/components/character/old-character-movement.js +4 -0
  41. package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
  42. package/dist/gameplay/actors/builtin/components/index.js +1 -1
  43. package/dist/gameplay/actors/builtin/components/mesh-component.d.ts +1 -0
  44. package/dist/gameplay/actors/builtin/components/mesh-component.js +1 -1
  45. package/dist/gameplay/actors/builtin/components/tween-component.js +1 -1
  46. package/dist/gameplay/actors/builtin/navmesh-actor.d.ts +2 -0
  47. package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
  48. package/dist/gameplay/actors/builtin/trigger-volume.d.ts +3 -3
  49. package/dist/gameplay/actors/builtin/trigger-volume.js +1 -1
  50. package/dist/gameplay/actors/camera/camera-component.d.ts +1 -3
  51. package/dist/gameplay/actors/camera/camera-component.js +1 -1
  52. package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +3 -0
  53. package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
  54. package/dist/gameplay/actors/component.d.ts +3 -0
  55. package/dist/gameplay/actors/component.js +1 -1
  56. package/dist/gameplay/actors/controller/actor-controller.d.ts +16 -0
  57. package/dist/gameplay/actors/controller/actor-controller.js +4 -0
  58. package/dist/gameplay/actors/factory.d.ts +3 -0
  59. package/dist/gameplay/actors/factory.js +1 -1
  60. package/dist/gameplay/actors/index.d.ts +4 -0
  61. package/dist/gameplay/actors/index.js +1 -1
  62. package/dist/gameplay/actors/internal/component-init.js +1 -1
  63. package/dist/gameplay/actors/type-registry.d.ts +10 -0
  64. package/dist/gameplay/actors/type-registry.js +4 -0
  65. package/dist/gameplay/ai/behavior-tree/move.d.ts +2 -2
  66. package/dist/gameplay/animation/retarget.d.ts +50 -0
  67. package/dist/gameplay/animation/retarget.js +4 -0
  68. package/dist/gameplay/animation/root-motion.js +1 -1
  69. package/dist/gameplay/event-graph/actor-transform-properties.d.ts +6 -0
  70. package/dist/gameplay/event-graph/actor-transform-properties.js +4 -0
  71. package/dist/gameplay/event-graph/asset-actor-types.d.ts +3 -0
  72. package/dist/gameplay/event-graph/asset-actor-types.js +4 -0
  73. package/dist/gameplay/event-graph/asset-references.d.ts +12 -0
  74. package/dist/gameplay/event-graph/asset-references.js +4 -0
  75. package/dist/gameplay/event-graph/compiler.d.ts +107 -0
  76. package/dist/gameplay/event-graph/compiler.js +4 -0
  77. package/dist/gameplay/event-graph/decorators.d.ts +74 -0
  78. package/dist/gameplay/event-graph/decorators.js +4 -0
  79. package/dist/gameplay/event-graph/document-compiler.d.ts +107 -0
  80. package/dist/gameplay/event-graph/document-compiler.js +4 -0
  81. package/dist/gameplay/event-graph/event-graph-demo.d.ts +2 -0
  82. package/dist/gameplay/event-graph/event-graph-demo.js +4 -0
  83. package/dist/gameplay/event-graph/graph.d.ts +106 -0
  84. package/dist/gameplay/event-graph/graph.js +4 -0
  85. package/dist/gameplay/event-graph/index.d.ts +13 -0
  86. package/dist/gameplay/event-graph/index.js +4 -0
  87. package/dist/gameplay/event-graph/model.d.ts +71 -0
  88. package/dist/gameplay/event-graph/model.js +4 -0
  89. package/dist/gameplay/event-graph/nodes/execution-nodes.d.ts +115 -0
  90. package/dist/gameplay/event-graph/nodes/execution-nodes.js +4 -0
  91. package/dist/gameplay/event-graph/nodes/gameplay-nodes.d.ts +208 -0
  92. package/dist/gameplay/event-graph/nodes/gameplay-nodes.js +4 -0
  93. package/dist/gameplay/event-graph/nodes/index.d.ts +4 -0
  94. package/dist/gameplay/event-graph/nodes/index.js +4 -0
  95. package/dist/gameplay/event-graph/nodes/value-nodes.d.ts +53 -0
  96. package/dist/gameplay/event-graph/nodes/value-nodes.js +4 -0
  97. package/dist/gameplay/event-graph/registry.d.ts +33 -0
  98. package/dist/gameplay/event-graph/registry.js +4 -0
  99. package/dist/gameplay/event-graph/runtime-assets.d.ts +21 -0
  100. package/dist/gameplay/event-graph/runtime-assets.js +4 -0
  101. package/dist/gameplay/event-graph/runtime.d.ts +160 -0
  102. package/dist/gameplay/event-graph/runtime.js +4 -0
  103. package/dist/gameplay/event-graph/type-inference.d.ts +41 -0
  104. package/dist/gameplay/event-graph/type-inference.js +4 -0
  105. package/dist/gameplay/event-graph/types.d.ts +77 -0
  106. package/dist/gameplay/event-graph/types.js +4 -0
  107. package/dist/gameplay/index.d.ts +17 -2
  108. package/dist/gameplay/index.js +1 -1
  109. package/dist/gameplay/initiate.d.ts +4 -0
  110. package/dist/gameplay/initiate.js +1 -1
  111. package/dist/gameplay/input/input.d.ts +22 -17
  112. package/dist/gameplay/input/input.js +1 -1
  113. package/dist/gameplay/net/browser/index.d.ts +147 -0
  114. package/dist/gameplay/net/browser/index.js +4 -0
  115. package/dist/gameplay/net/index.d.ts +7 -0
  116. package/dist/gameplay/net/index.js +4 -0
  117. package/dist/gameplay/net/net-connection.d.ts +25 -0
  118. package/dist/gameplay/net/net-connection.js +4 -0
  119. package/dist/gameplay/net/net-session.d.ts +70 -0
  120. package/dist/gameplay/net/net-session.js +4 -0
  121. package/dist/gameplay/net/service/net-actor-role.d.ts +12 -0
  122. package/dist/gameplay/net/service/net-actor-role.js +4 -0
  123. package/dist/gameplay/net/service/net-decorator.d.ts +29 -0
  124. package/dist/gameplay/net/service/net-decorator.js +4 -0
  125. package/dist/gameplay/net/service/net-serializer.d.ts +15 -0
  126. package/dist/gameplay/net/service/net-serializer.js +4 -0
  127. package/dist/gameplay/net/service/net-service.d.ts +171 -0
  128. package/dist/gameplay/net/service/net-service.js +4 -0
  129. package/dist/gameplay/net/service/net-utils.d.ts +8 -0
  130. package/dist/gameplay/net/service/net-utils.js +4 -0
  131. package/dist/gameplay/net/service/replication.d.ts +31 -0
  132. package/dist/gameplay/net/service/replication.js +4 -0
  133. package/dist/gameplay/net/service/rpc-decorator.d.ts +21 -0
  134. package/dist/gameplay/net/service/rpc-decorator.js +4 -0
  135. package/dist/gameplay/net/service/rpc.d.ts +35 -0
  136. package/dist/gameplay/net/service/rpc.js +4 -0
  137. package/dist/gameplay/services/asset-loader.d.ts +10 -2
  138. package/dist/gameplay/services/asset-loader.js +1 -1
  139. package/dist/gameplay/services/physics/physics-system.d.ts +16 -1
  140. package/dist/gameplay/services/physics/physics-system.js +1 -1
  141. package/dist/gameplay/services/world.d.ts +25 -2
  142. package/dist/gameplay/services/world.js +1 -1
  143. package/dist/rendering/color-pass.js +1 -1
  144. package/dist/rendering.d.ts +2 -0
  145. package/dist/rendering.js +1 -1
  146. package/dist/scene/asset-resource-loader.d.ts +7 -1
  147. package/dist/scene/asset-resource-loader.js +1 -1
  148. package/dist/scene/batched-mesh-2.d.ts +9 -0
  149. package/dist/scene/batched-mesh-2.js +1 -1
  150. package/dist/scene/bootstrap.d.ts +2 -0
  151. package/dist/scene/bootstrap.js +1 -1
  152. package/dist/scene/custom-param-deserialize.js +1 -1
  153. package/dist/scene/custom-param-runtime-types.js +1 -1
  154. package/dist/scene/materializer.d.ts +29 -0
  155. package/dist/scene/materializer.js +1 -1
  156. package/dist/scene/model.d.ts +114 -2
  157. package/dist/scene/model.js +1 -1
  158. package/dist/scene/objects/prefab.js +1 -1
  159. package/dist/scene/storage/storage.d.ts +1 -1
  160. package/dist/scene/storage/storage.js +1 -1
  161. package/dist/shader/builtin/standard-shader.js +1 -1
  162. package/dist/shader/builtin/toon-shader.js +1 -1
  163. package/dist/shader/builtin/unlit-shader.js +1 -1
  164. package/dist/shader/color-layer.js +1 -1
  165. package/dist/shader/graph/compiler.d.ts +3 -0
  166. package/dist/shader/graph/compiler.js +1 -1
  167. package/dist/shader/graph/model.d.ts +1 -1
  168. package/dist/shader/graph/registry.js +1 -1
  169. package/dist/shader/parameter.d.ts +1 -1
  170. package/dist/shader/parameter.js +1 -1
  171. package/dist/shader-nodes/depth.js +1 -1
  172. package/dist/shader-nodes/scene-sample.js +1 -1
  173. package/dist/test/animation-retarget.test.d.ts +2 -0
  174. package/dist/test/animation-retarget.test.js +4 -0
  175. package/dist/test/batched-mesh-2.test.d.ts +2 -0
  176. package/dist/test/batched-mesh-2.test.js +4 -0
  177. package/dist/test/browser-net-session.test.d.ts +2 -0
  178. package/dist/test/browser-net-session.test.js +4 -0
  179. package/dist/test/event-graph-generated-code.test.d.ts +2 -0
  180. package/dist/test/event-graph-generated-code.test.js +4 -0
  181. package/dist/test/event-graph-types.test.d.ts +2 -0
  182. package/dist/test/event-graph-types.test.js +4 -0
  183. package/dist/test/event-graph.test.d.ts +2 -0
  184. package/dist/test/event-graph.test.js +4 -0
  185. package/dist/test/first-person-camera-component.test.js +1 -1
  186. package/dist/test/input.test.d.ts +2 -0
  187. package/dist/test/input.test.js +4 -0
  188. package/dist/test/net-character-movement.test.d.ts +2 -0
  189. package/dist/test/net-character-movement.test.js +4 -0
  190. package/dist/test/net-property-snapshot.test.d.ts +2 -0
  191. package/dist/test/net-property-snapshot.test.js +4 -0
  192. package/dist/test/prefab-instance-params.test.js +1 -1
  193. package/dist/test/sequence-animation-retiming.test.js +1 -1
  194. package/dist/test/sequence-camera-control.test.js +1 -1
  195. package/dist/test/sequence-scene-binding.test.d.ts +2 -0
  196. package/dist/test/sequence-scene-binding.test.js +4 -0
  197. package/dist/test/sequence-transform.test.d.ts +2 -0
  198. package/dist/test/sequence-transform.test.js +4 -0
  199. package/dist/test/shader-graph.test.js +1 -1
  200. package/dist/test/vfx-random-color-initializer.test.d.ts +2 -0
  201. package/dist/test/vfx-random-color-initializer.test.js +4 -0
  202. package/dist/test/world-prefab-spawn.test.d.ts +2 -0
  203. package/dist/test/world-prefab-spawn.test.js +4 -0
  204. package/dist/utils/three/placeholder-texture.d.ts +3 -0
  205. package/dist/utils/three/placeholder-texture.js +4 -0
  206. package/package.json +18 -2
  207. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import{__decorate as t}from"tslib";import{ActorComponent as e,Component as o}from"../../../component.js";import{RootMotionClip as i}from"../../../../animation/root-motion.js";import{inject as s}from"../../../../inject.js";import{ViewController as r}from"../../../../services/render.js";import{AnimationMixer as n,Bone as l,Object3D as a,LoopOnce as h,Raycaster as c,Vector3 as p,SkinnedMesh as d,Skeleton as u,Quaternion as f,Matrix4 as g,MathUtils as y,ArrowHelper as m,Group as k}from"three";import{CharacterMovementComponent as S}from"./character-movement.js";import{CCDIKSolver as w}from"three/addons/animation/CCDIKSolver.js";import{World as b}from"../../../../services/world.js";import{PhysicsSystem as L,RayTestResult as v}from"../../../../services/physics/physics-system.js";import{ArrayMap as B}from"../../../../../utils/collections.js";const I=new p(0,-1,0),P=new p(0,1,0),x=new p(1,1,1),F=new f,D=new p,R=new p,A=new p,M=new p,T=new p,W=new f,O=new f,V=new f,C=new f,E=new g,q=new g,H=new p(1,0,0),z=new p(0,1,0),N=new p(0,0,1);function U(){return{point:new p,normal:new p,hasNormal:!1}}const j=["mixamorigHips","Hips","hips","Pelvis","pelvis"],Q={upper:["LeftUpLeg","leftUpLeg","left_up_leg"],lower:["LeftLeg","leftLeg","left_leg"],foot:["LeftFoot","leftFoot","left_foot"]},G={upper:["RightUpLeg","rightUpLeg","right_up_leg"],lower:["RightLeg","rightLeg","right_leg"],foot:["RightFoot","rightFoot","right_foot"]},_=["left","right"];let K=class extends e{constructor(){super(...arguments),this.viewController=s(r),this.poseProcessors=new B,this.stateMachines=[],this.upperStateMachines=[],this.fadeTime=.2,this.movementSpeed=null,this.upperBodyTimer=0,this.upperBodyOverride=!1,this.fullBodyTimer=0,this.currentFullBodyPriority=-1,this.currentUpperBodyPriority=-1,this.externalControlActive=!1,this.world=s(b),this.physicsSystem=s(L),this.footIkEnabled=!1,this.footIkMoving=!1,this.footIkRayStartHeight=.5,this.footIkRayLength=1.5,this.footIkRaycastMode="physics",this.footIkFootOffset=.08,this.footIkAutoContactOffset=!1,this.footIkPositionLerpSpeed=28,this.footIkRotationLerpSpeed=14,this.footIkWeightInSpeed=34,this.footIkWeightOutSpeed=30,this.footIkMaxSlopeAngleDeg=40,this.footIkForwardSampleDistance=.14,this.footIkSideSampleDistance=.08,this.footIkMaxHorizontalOffset=.22,this.footIkMaxVerticalOffsetDown=.75,this.footIkMaxVerticalOffsetUp=.2,this.footIkPelvisEnabled=!0,this.footIkPelvisBone="mixamorigHips",this.footIkPelvisLerpSpeed=24,this.footIkPelvisMaxOffsetDown=.4,this.footIkPelvisMaxOffsetUp=.08,this.footIkRequireGrounded=!0,this.footIkSimpleTiltOnly=!1,this.footIkDebug=!1,this.footIkDebugNormalLength=.25,this.footIkDebugAxisLength=.2,this.footIkExtraClearance=.01,this.footIkPlantReleaseUpSpeed=.08,this.footIkPlantReleaseExtension=.9,this.footIkPlantAttachExtension=.96,this.footIkPlantReleaseLift=.055,this.footIkPlantAttachLift=.02,this.leftLegIkBones={upperLeg:"mixamorigLeftUpLeg",lowerLeg:"mixamorigLeftLeg",foot:"mixamorigLeftFoot"},this.rightLegIkBones={upperLeg:"mixamorigRightUpLeg",lowerLeg:"mixamorigRightLeg",foot:"mixamorigRightFoot"},this.ikPelvisOffsetY=0,this.ikLegState={left:{targetPosition:new p,normal:new p(0,1,0),forward:new p(0,0,1),pitch:0,contactOffset:0,planted:!0,lastFootWorldPos:new p,hasLastFootSample:!1,weight:0,top:!1},right:{targetPosition:new p,normal:new p(0,1,0),forward:new p(0,0,1),pitch:0,contactOffset:0,planted:!0,lastFootWorldPos:new p,hasLastFootSample:!1,weight:0,top:!1}},this.ikWarnedMissingBones=!1,this.raycaster=new c,this.raycastIntersections=[],this.footIkRayTo=new p,this.footIkRayTestResult=new v,this.footIkRayTestOptions={excludeTriggers:!0,resolveActor:!1,collisionFilter:-2},this.footIkHits={center:U(),toe:U(),heel:U(),side:U()},this.footIkAxesScratch={up:new p,forward:new p,right:new p},this.footIkSampleAxesScratch={forward:new p,right:new p},this.footIkScratch={footWorldPos:new p,centerRayStart:new p,toeRayStart:new p,heelRayStart:new p,sideRayStart:new p,desiredTargetPos:new p,desiredNormal:new p,desiredForward:new p,debugRayEndA:new p,debugRayEndB:new p,debugRayEndC:new p,debugRayEndD:new p,debugRayEndE:new p,debugRayEndF:new p},this.ikPreSolve={left:{upper:new f,lower:new f,foot:new f},right:{upper:new f,lower:new f,foot:new f}},this.getFullBodyClip=X(t=>t.uuid,t=>Y(this.fullBodyMask,t)),this.getUpperBodyClip=X(t=>t.uuid,t=>Y(this.upperBodyMask,t))}onInit(){this.viewController.onUpdate(this.actor).subscribe(t=>this.updateInternal(t)),this.characterMovement=this.actor.getComponent(S),this.footIkRayTestOptions.excludeActor=this.actor}onEndPlay(){this.disposeFootIkDebug()}raycastDownFirstValid(t,e,o){const i=this.world.scene;this.raycaster.set(t,I),this.raycaster.near=0,this.raycaster.far=e,this.raycastIntersections.length=0,this.raycaster.intersectObject(i,!0,this.raycastIntersections);for(const t of this.raycastIntersections)if(!(this.isFootIkDebugObject(t.object)||this.isRelatedToActorHierarchy(t.object)||this.isSkinnedMeshObject(t.object)))return o.point.copy(t.point),null!=t.face?(o.normal.copy(t.face.normal).transformDirection(t.object.matrixWorld).normalize(),o.hasNormal=!0):o.hasNormal=!1,this.raycastIntersections.length=0,!0;return this.raycastIntersections.length=0,!1}rayTestDown(t,e,o){const i=this.footIkRayTo.copy(t).addScaledVector(I,e),s=this.physicsSystem.rayTest(t,i,this.footIkRayTestResult,this.footIkRayTestOptions);return!!s.hasHit&&(o.point.copy(s.hitPoint),o.normal.copy(s.hitNormal),o.normal.lengthSq()>1e-8?(o.normal.normalize(),o.hasNormal=!0):o.hasNormal=!1,!0)}isRelatedToActorHierarchy(t){const e=this.actor?.object;return null!=e&&null!=t&&(tt(t,e)||tt(e,t))}isFootIkDebugObject(t){let e=t;for(;null!=e;){if(!0===e.userData?.footIkDebug)return!0;e=e.parent}return!1}isSkinnedMeshObject(t){let e=t;for(;null!=e;){if(e instanceof d||!0===e.isSkinnedMesh)return!0;e=e.parent}return!1}getRootMotionAction(){if(this.fullBodyAction.getClip()instanceof i)return this.fullBodyAction}getFullBodyAction(){return this.fullBodyAction}setup(t,e,o){null!=e&&(this.upperBodyMask=$(e),this.fullBodyMask=function(t,e){const o=new Set($(e).map(t=>t.uuid)),i=[];return t.traverse(t=>{(t instanceof l||t.isBone)&&!o.has(t.uuid)&&i.push(t)}),i}(Z(t),e)),null!=this.mixer&&this.mixer.stopAllAction(),this.mixer=new n(t),this.ikRoot=t,this.disposeFootIkDebug(),this.initializeFootIk(t,o),this.syncFootIkDebug()}updateStateMachines(t){this.stateMachines.forEach(e=>{e.step(t);const o=e.current.clip;null!=o&&this.play(o,{priority:e.current.options.priority??0,loop:e.current.options.loop??!0})}),this.upperStateMachines.forEach(e=>{e.step(t);const o=e.current.clip;null!=o?this.playUpper(o,{priority:e.current.options.priority??0,loop:e.current.options.loop??!0}):this.play(this.fullBodyClip)})}addPoseProcessor(t){const e={id:t.id,phase:t.phase??"afterMixer",order:t.order??0,update:t.update};this.removePoseProcessor(e.id);const o=this.poseProcessors.get(e.phase);let i=o.findIndex(t=>t.order>e.order);return-1===i&&(i=o.length),o.splice(i,0,e),()=>{const t=o.indexOf(e);-1!==t&&(o.splice(t,1),0===o.length&&this.poseProcessors.delete(e.phase))}}removePoseProcessor(t){for(const[e,o]of this.poseProcessors.entries()){const i=o.findIndex(e=>e.id===t);if(-1!==i)return o.splice(i,1),void(0===o.length&&this.poseProcessors.delete(e))}}runPoseProcessors(t,e){if(0===this.poseProcessors.size||null==this.mixer||!this.poseProcessors.present(t))return;const o=this.mixer.getRoot();if(!(o instanceof a))return;const i=this.poseProcessorContext??(this.poseProcessorContext={deltaTime:e,phase:t,animation:this,mixer:this.mixer,root:o});i.deltaTime=e,i.phase=t,i.mixer=this.mixer,i.root=o;const s=this.poseProcessors.get(t);for(let t=0;t<s.length;t++)s[t].update(i)}updateInternal(t){null!=this.mixer&&(this.externalControlActive||(this.upperBodyTimer+=t*(this.upperBodyAction?.timeScale??1),this.fullBodyTimer+=t*(this.fullBodyAction?.timeScale??1),this.upperBodyAction&&this.upperBodyOverride&&this.upperBodyAction.getClip().duration-2*(this.overrideFadeTimeUpper??this.fadeTime)<this.upperBodyTimer&&(this.upperBodyOverride=!1,null!=this.fullBodyClip&&this.transition(this.upperBodyAction,this.getUpperBodyClip(this.fullBodyClip)),this.upperBodyAction=null,this.overrideFadeTimeUpper=null),this.fullBodyAction&&this.fullBodyAction.loop===h&&this.fullBodyAction.getClip().duration-2*(this.overrideFadeTime??this.fadeTime)<this.fullBodyTimer&&(this.currentFullBodyPriority=-1,this.overrideFadeTime=null),null!=this.characterMovement&&(this.movementSpeed=this.characterMovement.horizontalSpeed),this.updateStateMachines(t),this.syncMovementSpeed(this.fullBodyAction),this.upperBodyOverride||this.syncMovementSpeed(this.upperBodyAction),this.runPoseProcessors("beforeMixer",t),this.mixer.update(t),this.runPoseProcessors("afterMixer",t),this.runPoseProcessors("beforeIk",t),this.updateFootIk(t),this.runPoseProcessors("afterIk",t)))}initializeFootIk(t,e){if(this.ikSolver=null,this.ikSkinnedMesh=null,this.ikBoneRefs=null,this.ikLegLengths=null,this.ikPelvisBone=null,this.ikPelvisOffsetY=0,this.ikFootAxes=null,this.ikTargetBones=null,this.ikWarnedMissingBones=!1,this.ikLegState.left.weight=0,this.ikLegState.right.weight=0,!this.footIkEnabled)return;const o=this.findFirstSkinnedMesh(t);if(null==o||null==o.skeleton)return;this.ikSkinnedMesh=o,t.updateWorldMatrix(!0,!0);const i=o.skeleton,s=this.resolveLegBoneRefs(i,this.leftLegIkBones,Q),r=this.resolveLegBoneRefs(i,this.rightLegIkBones,G);if(null==s||null==r)return void(this.ikWarnedMissingBones||(this.ikWarnedMissingBones=!0,console.warn(`[CharacterAnimationComponent] Foot IK disabled: missing leg bones. Left=${this.leftLegIkBones.upperLeg}/${this.leftLegIkBones.lowerLeg}/${this.leftLegIkBones.foot}, Right=${this.rightLegIkBones.upperLeg}/${this.rightLegIkBones.lowerLeg}/${this.rightLegIkBones.foot}`)));this.ikBoneRefs={left:s,right:r},this.ikLegLengths={left:this.computeLegLengths(s),right:this.computeLegLengths(r)},this.ikFootAxes={left:this.detectFootAxisBasis(s.foot),right:this.detectFootAxisBasis(r.foot)},this.ikPelvisBone=this.resolvePelvisBone(i,s,r),this.ikLegState.left.targetPosition.copy(s.foot.getWorldPosition(D)),this.ikLegState.right.targetPosition.copy(r.foot.getWorldPosition(D)),this.ikLegState.left.normal.set(0,1,0),this.ikLegState.right.normal.set(0,1,0),this.ikLegState.left.pitch=0,this.ikLegState.right.pitch=0,this.ikLegState.left.contactOffset=this.estimateFootContactOffset(i,"left",s.foot),this.ikLegState.right.contactOffset=this.estimateFootContactOffset(i,"right",r.foot),this.ikLegState.left.planted=!0,this.ikLegState.right.planted=!0,this.ikLegState.left.lastFootWorldPos.copy(s.foot.getWorldPosition(D)),this.ikLegState.right.lastFootWorldPos.copy(r.foot.getWorldPosition(D)),this.ikLegState.left.hasLastFootSample=!0,this.ikLegState.right.hasLastFootSample=!0;const n=this.resolveFootAxes("left",s.foot),a=this.resolveFootAxes("right",r.foot);this.ikLegState.left.forward.copy(n.forward),this.ikLegState.right.forward.copy(a.forward);const h=e??Z(t);if(null==h)return;let c=i.getBoneByName("_IKTargetLeftFoot"),p=i.getBoneByName("_IKTargetRightFoot"),d=!1;if(null==c&&(c=new l,c.name="_IKTargetLeftFoot",h.add(c),d=!0),null==p&&(p=new l,p.name="_IKTargetRightFoot",h.add(p),d=!0),this.setBoneWorldPosition(c,s.foot.getWorldPosition(D)),this.setBoneWorldPosition(p,r.foot.getWorldPosition(D)),d||i.bones.indexOf(c)<0||i.bones.indexOf(p)<0){const t=i.bones.slice(),e=i.boneInverses.map(t=>t.clone());t.indexOf(c)<0&&(t.push(c),e.push((new g).copy(c.matrixWorld).invert())),t.indexOf(p)<0&&(t.push(p),e.push((new g).copy(p.matrixWorld).invert())),o.bind(new u(t,e),o.bindMatrix)}this.ikTargetBones={left:c,right:p};const f=o.skeleton.bones,y={target:f.indexOf(c),effector:f.indexOf(s.foot),links:[{index:f.indexOf(s.lower)},{index:f.indexOf(s.upper)}],iteration:8},m={target:f.indexOf(p),effector:f.indexOf(r.foot),links:[{index:f.indexOf(r.lower)},{index:f.indexOf(r.upper)}],iteration:8};if(y.target<0||y.effector<0||y.links.some(t=>t.index<0)||m.target<0||m.effector<0||m.links.some(t=>t.index<0))return console.warn("[CharacterAnimationComponent] Foot IK disabled: failed to resolve IK indexes in skeleton."),void(this.ikSolver=null);this.ikSolver=new w(o,[y,m])}findFirstSkinnedMesh(t){let e;return t.traverse(t=>{null==e&&(t instanceof d||!0===t.isSkinnedMesh)&&(e=t)}),e}resolveLegBoneRefs(t,e,o){const i=this.findBoneByNames(t,[e.upperLeg,...o.upper]),s=this.findBoneByNames(t,[e.lowerLeg,...o.lower]),r=this.findBoneByNames(t,[e.foot,...o.foot]);if(null!=i&&null!=s&&null!=r)return{upper:i,lower:s,foot:r}}findBoneByNames(t,e){for(const o of e){const e=t.getBoneByName(o);if(null!=e)return e}}resolvePelvisBone(t,e,o){const i=this.findBoneByNames(t,[this.footIkPelvisBone,...j]);if(null!=i)return i;const s=e.upper.parent,r=o.upper.parent;return null!=s&&s===r&&(s instanceof l||!0===s.isBone)||null!=s&&(s instanceof l||!0===s.isBone)?s:void 0}computeLegLengths(t){const e=t.upper.getWorldPosition(D),o=t.lower.getWorldPosition(R),i=t.foot.getWorldPosition(A),s=e.distanceTo(o),r=o.distanceTo(i);return{upper:s,lower:r,total:s+r}}setBoneWorldPosition(t,e){const o=t.parent;null==o?t.position.copy(e):t.position.copy(o.worldToLocal(D.copy(e))),t.quaternion.copy(F),t.scale.copy(x),t.updateMatrixWorld(!0)}syncFootIkDebug(){this.footIkDebug&&null!=this.ikRoot?(null!=this.ikDebugRoot&&null!=this.ikDebugLegs||(this.ikDebugRoot=new k,this.ikDebugRoot.name="FootIKDebug",this.ikDebugRoot.userData.footIkDebug=!0,this.ikDebugLegs={left:this.createDebugLeg("LeftFootIK",53503),right:this.createDebugLeg("RightFootIK",16755200)},this.ikDebugRoot.add(this.ikDebugLegs.left.root,this.ikDebugLegs.right.root),this.world.scene.add(this.ikDebugRoot)),this.ikDebugRoot.visible=!0):null!=this.ikDebugRoot&&(this.ikDebugRoot.visible=!1)}disposeFootIkDebug(){null!=this.ikDebugRoot&&(this.ikDebugRoot.removeFromParent(),this.ikDebugRoot.clear()),this.ikDebugRoot=null,this.ikDebugLegs=null}createDebugLeg(t,e){const o=new k;o.name=t,o.userData.footIkDebug=!0;const i=this.createDebugArrow(e),s=this.createDebugArrow(e),r=this.createDebugArrow(e),n=this.createDebugArrow(e),l=this.createDebugArrow(65280),a=this.createDebugArrow(6750054),h=this.createDebugArrow(16711935),c=this.createDebugArrow(16776960),p=this.createDebugArrow(16737792);return o.add(i,s,r,n,l,a,h,c,p),{root:o,rayCenter:i,rayToe:s,rayHeel:r,raySide:n,hitNormal:l,footUp:a,footToTarget:h,solveUpper:c,solveLower:p}}createDebugArrow(t){const e=new m(P,new p,.001,t);return e.userData.footIkDebug=!0,e.traverse(t=>{t.userData.footIkDebug=!0,t.raycast=()=>{}}),e.visible=!1,e}setDebugArrow(t,e,o){D.subVectors(o,e);const i=D.length();i<1e-6?t.visible=!1:(t.visible=!0,t.position.copy(e),t.setDirection(D.multiplyScalar(1/i)),t.setLength(i,Math.min(.08,.25*i),Math.min(.05,.2*i)))}resetDebugVisibility(){null!=this.ikDebugLegs&&(this.ikDebugLegs.left.rayCenter.visible=!1,this.ikDebugLegs.left.rayToe.visible=!1,this.ikDebugLegs.left.rayHeel.visible=!1,this.ikDebugLegs.left.raySide.visible=!1,this.ikDebugLegs.left.hitNormal.visible=!1,this.ikDebugLegs.left.footUp.visible=!1,this.ikDebugLegs.left.footToTarget.visible=!1,this.ikDebugLegs.left.solveUpper.visible=!1,this.ikDebugLegs.left.solveLower.visible=!1,this.ikDebugLegs.right.rayCenter.visible=!1,this.ikDebugLegs.right.rayToe.visible=!1,this.ikDebugLegs.right.rayHeel.visible=!1,this.ikDebugLegs.right.raySide.visible=!1,this.ikDebugLegs.right.hitNormal.visible=!1,this.ikDebugLegs.right.footUp.visible=!1,this.ikDebugLegs.right.footToTarget.visible=!1,this.ikDebugLegs.right.solveUpper.visible=!1,this.ikDebugLegs.right.solveLower.visible=!1)}updateFootIk(t){if(this.syncFootIkDebug(),!this.footIkEnabled||null==this.ikBoneRefs||null==this.ikRoot)return void this.resetDebugVisibility();if(!this.footIkMoving&&(this.movementSpeed??0)>.01)return this.resetFootIkState(),void this.resetDebugVisibility();this.ikRoot.updateWorldMatrix(!0,!0);const e=this.characterMovement?.isGrounded??!0;return this.footIkSimpleTiltOnly?(this.updatePelvisOffset(t,!1),this.updateLegTiltSimple("left",this.ikBoneRefs.left.foot,this.ikLegState.left,e,t),void this.updateLegTiltSimple("right",this.ikBoneRefs.right.foot,this.ikLegState.right,e,t)):null==this.ikLegLengths||null==this.ikTargetBones||null==this.ikSkinnedMesh||null==this.ikSolver?(this.updatePelvisOffset(t,!1),void this.resetDebugVisibility()):(this.updateLegIkTarget("left",this.ikBoneRefs.left,this.ikLegLengths.left,this.ikTargetBones.left,this.ikLegState.left,e,t),this.updateLegIkTarget("right",this.ikBoneRefs.right,this.ikLegLengths.right,this.ikTargetBones.right,this.ikLegState.right,e,t),this.updatePelvisOffset(t,!0),this.setBoneWorldPosition(this.ikTargetBones.left,this.ikLegState.left.targetPosition),this.setBoneWorldPosition(this.ikTargetBones.right,this.ikLegState.right.targetPosition),this.ikPreSolve.left.upper.copy(this.ikBoneRefs.left.upper.quaternion),this.ikPreSolve.left.lower.copy(this.ikBoneRefs.left.lower.quaternion),this.ikPreSolve.left.foot.copy(this.ikBoneRefs.left.foot.quaternion),this.ikPreSolve.right.upper.copy(this.ikBoneRefs.right.upper.quaternion),this.ikPreSolve.right.lower.copy(this.ikBoneRefs.right.lower.quaternion),this.ikPreSolve.right.foot.copy(this.ikBoneRefs.right.foot.quaternion),null!=this.ikDebugLegs&&(this.ikDebugLegs.left.solveUpper.visible=!1,this.ikDebugLegs.left.solveLower.visible=!1,this.ikDebugLegs.right.solveUpper.visible=!1,this.ikDebugLegs.right.solveLower.visible=!1),this.ikSolver.update(),this.blendLegAfterSolve(this.ikBoneRefs.left,this.ikPreSolve.left,this.ikLegState.left.weight),this.blendLegAfterSolve(this.ikBoneRefs.right,this.ikPreSolve.right,this.ikLegState.right.weight),this.applySimpleFootPitch("left",this.ikBoneRefs.left.foot,this.ikLegState.left),void this.applySimpleFootPitch("right",this.ikBoneRefs.right.foot,this.ikLegState.right))}resetFootIkState(){if(null!=this.ikBoneRefs){for(const t of _){const e=this.ikBoneRefs[t],o=this.ikLegState[t],i=e.foot.getWorldPosition(D);o.targetPosition.copy(i),o.lastFootWorldPos.copy(i),o.hasLastFootSample=!0,o.weight=0,o.normal.set(0,1,0);const s=this.resolveFootAxes(t,e.foot,this.footIkAxesScratch);o.forward.copy(s.forward),o.pitch=0,this.footIkAutoContactOffset?o.contactOffset=Math.max(o.contactOffset,this.footIkFootOffset+this.footIkExtraClearance):o.contactOffset=this.footIkFootOffset+this.footIkExtraClearance,o.planted=!1}this.ikPelvisOffsetY=0}}updatePelvisOffset(t,e){if(null==this.ikPelvisBone)return;let o=0;if(e&&this.footIkPelvisEnabled&&null!=this.ikBoneRefs&&null!=this.ikLegLengths){this.ikLegState.left.top=!1,this.ikLegState.right.top=!1;for(const t of _){const e=this.ikBoneRefs[t],i=this.ikLegLengths[t],s=this.ikLegState[t];if(!s.planted)continue;const r=e.upper.getWorldPosition(D),n=.998*i.total,l=this.computeRequiredPelvisDrop(r,s.targetPosition,n);if(l>0){const e="left"===t?"right":"left";this.ikLegState[e].top=!0}o=Math.min(o,-l)}o=y.clamp(o,-this.footIkPelvisMaxOffsetDown,this.footIkPelvisMaxOffsetUp)}const i=1-Math.exp(-this.footIkPelvisLerpSpeed*t);this.ikPelvisOffsetY=y.lerp(this.ikPelvisOffsetY,o,i);const s=this.ikPelvisBone.getWorldPosition(R),r=A.copy(s).addScaledVector(P,this.ikPelvisOffsetY);null==this.ikPelvisBone.parent?this.ikPelvisBone.position.copy(r):this.ikPelvisBone.position.copy(this.ikPelvisBone.parent.worldToLocal(r)),this.ikPelvisBone.updateMatrixWorld(!0)}computeFootVerticalSpeed(t,e,o){return!t.hasLastFootSample||o<=1e-6?0:(e.y-t.lastFootWorldPos.y)/o}updateFootSample(t,e){t.lastFootWorldPos.copy(e),t.hasLastFootSample=!0}estimateFootContactOffset(t,e,o){const i=this.footIkFootOffset+this.footIkExtraClearance;if(!this.footIkAutoContactOffset)return i;const s=t.bones.indexOf(o);if(s<0)return i;const r=t.boneInverses[s];if(null==r)return i;const n=this.ikFootAxes?.[e]??this.detectFootAxisBasis(o),a=o.getWorldPosition(R),h=A.copy(n.upLocal).applyQuaternion(o.getWorldQuaternion(W)).normalize();let c=0;return o.traverse(e=>{if(!(e instanceof l)||e===o)return;const i=t.bones.indexOf(e);if(i<0)return;const s=E.copy(t.boneInverses[i]).invert(),n=q.copy(r).multiply(s),p=D.setFromMatrixPosition(n),d=M.copy(p).applyMatrix4(o.matrixWorld).sub(a);c=Math.min(c,d.dot(h))}),Math.max(i,-c+this.footIkExtraClearance)}shouldPlantFoot(t,e,o,i,s,r){if(!e||!o)return!1;const n=this.footIkPlantReleaseExtension,l=this.footIkPlantAttachExtension,a=this.footIkPlantReleaseLift,h=this.footIkPlantAttachLift;return t.planted?!(i>this.footIkPlantReleaseUpSpeed&&(s<n||r>a)):s>=l&&r<=h||i<=0&&s>=n}computeLegExtensionRatio(t,e){const o=t.upper.getWorldPosition(D),i=t.foot.getWorldPosition(R),s=o.distanceTo(i);return e.total<=1e-6?1:y.clamp(s/e.total,0,1.2)}computeRequiredPelvisDrop(t,e,o){const i=M.subVectors(t,e),s=i.length();if(s<=o+1e-6)return 0;const r=i.dot(P),n=o*o-Math.max(s*s-r*r,0);if(n<=0)return s-o;const l=Math.sqrt(n),a=r-l,h=r+l;return a>=0?a:h>=0?h:0}updateLegTiltSimple(t,e,o,i,s){const r=this.footIkScratch,n=this.footIkHits,l=e.getWorldPosition(r.footWorldPos),a=this.computeFootVerticalSpeed(o,l,s),h=this.resolveFootAxes(t,e,this.footIkAxesScratch),c=this.resolveGroundSampleAxes(t,e,h,this.footIkSampleAxesScratch),p=r.centerRayStart.copy(l).addScaledVector(P,this.footIkRayStartHeight),d=r.toeRayStart.copy(p).addScaledVector(c.forward,this.footIkForwardSampleDistance),u=r.heelRayStart.copy(p).addScaledVector(c.forward,-this.footIkForwardSampleDistance),f=r.sideRayStart.copy(p).addScaledVector(c.right,this.footIkSideSampleDistance),g=this.getFirstGroundHit(p,n.center),m=this.getFirstGroundHit(d,n.toe),k=this.getFirstGroundHit(u,n.heel),S=this.getFirstGroundHit(f,n.side),w=r.desiredNormal.set(0,1,0),b=r.desiredForward.copy(c.forward);let L=0,v=0,B=this.footIkWeightOutSpeed;const I=null!=g||null!=m||null!=k;let x=l.y;null!=g?x=g.point.y:null!=m&&null!=k?x=.5*(m.point.y+k.point.y):null!=m?x=m.point.y:null!=k&&(x=k.point.y);const F=this.ikBoneRefs?.[t],D=this.ikLegLengths?.[t],R=null!=F&&null!=D?this.computeLegExtensionRatio(F,D):1,A=Math.max(0,l.y-x,l.y-o.targetPosition.y),M=this.shouldPlantFoot(o,!this.footIkRequireGrounded||i,I,a,R,A);M?this.computeDesiredGroundNormal(c,g,m,k,S,w)&&(this.computeDesiredFootForward(c.forward,c.right,w,m,k,b),L=this.computeDesiredPitchAngle(m,k,c.forward),v=1,B=this.footIkWeightInSpeed):this.computeDesiredFootForward(c.forward,c.right,w,null,null,b);const T=1-Math.exp(-this.footIkPositionLerpSpeed*s),W=1-Math.exp(-B*s);o.normal.lerp(w,T).normalize(),o.forward.lerp(b,T).normalize(),o.pitch=y.lerp(o.pitch,L,T),o.weight=y.lerp(o.weight,v,W),o.planted=M&&v>.001,this.updateFootSample(o,l),this.applySimpleFootPitch(t,e,o),this.updateLegDebug(t,{footWorldPos:l,centerRayStart:p,toeRayStart:d,heelRayStart:u,sideRayStart:f,centerHit:g,toeHit:m,heelHit:k,sideHit:S,desiredNormal:o.normal,desiredTargetPos:r.footWorldPos,weight:o.weight})}updateLegIkTarget(t,e,o,i,s,r,n){const l=this.footIkScratch,a=this.footIkHits,h=e.foot,c=h.getWorldPosition(l.footWorldPos),p=this.computeFootVerticalSpeed(s,c,n),d=this.resolveFootAxes(t,h,this.footIkAxesScratch),u=this.resolveGroundSampleAxes(t,h,d,this.footIkSampleAxesScratch),f=l.centerRayStart.copy(c).addScaledVector(P,this.footIkRayStartHeight),g=l.toeRayStart.copy(f).addScaledVector(u.forward,this.footIkForwardSampleDistance),m=l.heelRayStart.copy(f).addScaledVector(u.forward,-this.footIkForwardSampleDistance),k=l.sideRayStart.copy(f).addScaledVector(u.right,this.footIkSideSampleDistance),S=this.getFirstGroundHit(f,a.center),w=this.getFirstGroundHit(g,a.toe),b=this.getFirstGroundHit(m,a.heel),L=this.getFirstGroundHit(k,a.side),v=l.desiredTargetPos.copy(c),B=l.desiredNormal.set(0,1,0),I=l.desiredForward.copy(u.forward);let x=0,F=0,D=this.footIkWeightOutSpeed;const R=null!=S||null!=w||null!=b;let A=c.y;null!=S?A=S.point.y:null!=w&&null!=b?A=.5*(w.point.y+b.point.y):null!=w?A=w.point.y:null!=b&&(A=b.point.y);const M=this.computeLegExtensionRatio(e,o),T=Math.max(0,c.y-A,c.y-s.targetPosition.y),W=this.shouldPlantFoot(s,!this.footIkRequireGrounded||r,R,p,M,T);if(W){if(v.copy(c),this.computeDesiredGroundNormal(u,S,w,b,L,B)){this.computeDesiredFootForward(u.forward,u.right,B,w,b,I),x=this.computeDesiredPitchAngle(w,b,u.forward);const t=Math.max(0,Math.sin(x))*this.footIkForwardSampleDistance*.45,e=Math.max(this.footIkFootOffset+this.footIkExtraClearance,s.contactOffset);v.y=A+e+t,s.top&&(v.y-=this.ikPelvisOffsetY/2),F=1,D=this.footIkWeightInSpeed}}else this.computeDesiredFootForward(u.forward,u.right,B,null,null,I),v.copy(c),v.y+=this.footIkFootOffset;this.clampDesiredFootTarget(e,o,c,v);const O=1-Math.exp(-this.footIkPositionLerpSpeed*n),V=1-Math.exp(-D*n);s.targetPosition.lerp(v,O),s.normal.lerp(B,O).normalize(),s.forward.lerp(I,O).normalize(),s.pitch=y.lerp(s.pitch,x,O),s.weight=y.lerp(s.weight,F,V),s.planted=W&&F>.001,this.updateFootSample(s,c),this.setBoneWorldPosition(i,s.targetPosition),this.updateLegDebug(t,{footWorldPos:c,centerRayStart:f,toeRayStart:g,heelRayStart:m,sideRayStart:k,centerHit:S,toeHit:w,heelHit:b,sideHit:L,desiredNormal:B,desiredTargetPos:s.targetPosition,weight:s.weight})}updateLegDebug(t,e){if(!this.footIkDebug||null==this.ikDebugLegs||null==this.ikBoneRefs)return;const o=this.ikDebugLegs[t],i=this.ikBoneRefs[t],s=this.resolveFootAxes(t,i.foot,this.footIkAxesScratch),r=this.footIkScratch,n=e.centerHit?.point??r.debugRayEndA.copy(e.centerRayStart).addScaledVector(I,this.footIkRayLength),l=e.toeHit?.point??r.debugRayEndB.copy(e.toeRayStart).addScaledVector(I,this.footIkRayLength),a=e.heelHit?.point??r.debugRayEndC.copy(e.heelRayStart).addScaledVector(I,this.footIkRayLength),h=e.sideHit?.point??r.debugRayEndD.copy(e.sideRayStart).addScaledVector(I,this.footIkRayLength);this.setDebugArrow(o.rayCenter,e.centerRayStart,n),this.setDebugArrow(o.rayToe,e.toeRayStart,l),this.setDebugArrow(o.rayHeel,e.heelRayStart,a),this.setDebugArrow(o.raySide,e.sideRayStart,h);const c=e.centerHit?.point??e.toeHit?.point??e.heelHit?.point??e.sideHit?.point??e.footWorldPos;this.setDebugArrow(o.hitNormal,c,r.debugRayEndE.copy(c).addScaledVector(e.desiredNormal,this.footIkDebugNormalLength)),this.setDebugArrow(o.footUp,e.footWorldPos,r.debugRayEndF.copy(e.footWorldPos).addScaledVector(s.up,this.footIkDebugAxisLength*(.15+e.weight))),this.setDebugArrow(o.footToTarget,e.footWorldPos,e.desiredTargetPos)}getFirstGroundHit(t,e){return"physics"===this.footIkRaycastMode?this.rayTestDown(t,this.footIkRayLength,e)?e:null:"physicsThenRender"===this.footIkRaycastMode?this.rayTestDown(t,this.footIkRayLength,e)||this.raycastDownFirstValid(t,this.footIkRayLength,e)?e:null:this.raycastDownFirstValid(t,this.footIkRayLength,e)?e:null}resolveGroundSampleAxes(t,e,o,i){const s=o??this.resolveFootAxes(t,e),r=i??{forward:new p,right:new p},n=this.actor.object.getWorldDirection(M);n.addScaledVector(P,-n.dot(P)),n.lengthSq()<1e-8&&n.copy(s.forward).addScaledVector(P,-s.forward.dot(P)),n.lengthSq()<1e-8&&n.set(0,0,1),n.normalize();const l=T.crossVectors(P,n);return l.lengthSq()<1e-8?l.copy(s.right):l.normalize(),l.dot(s.right)<0&&l.multiplyScalar(-1),r.forward.copy(n),r.right.copy(l),r}computeDesiredGroundNormal(t,e,o,i,s,r){const n=this.computeAverageHitNormal(e,o,i,s,M);let l=!1,a=0,h=0;if(null!=o&&null!=i){const e=R.subVectors(o.point,i.point).dot(t.forward);Math.abs(e)>1e-5&&(a=(o.point.y-i.point.y)/e,l=!0)}if(null!=s&&null!=e){const o=A.subVectors(s.point,e.point).dot(t.right);Math.abs(o)>1e-5&&(h=(s.point.y-e.point.y)/o,l=!0)}if(l&&(r.copy(P),r.addScaledVector(t.forward,-a),r.addScaledVector(t.right,-h),r.lengthSq()>1e-8?r.normalize():l=!1),l)null!=n&&r.dot(n)<0&&r.multiplyScalar(-1);else{if(null==n)return!1;r.copy(n),l=!0}return r.dot(P)<0&&r.multiplyScalar(-1),this.clampSlopeNormal(r),!0}computeAverageHitNormal(t,e,o,i,s){s.set(0,0,0);let r=0;return null!=t&&t.hasNormal&&(s.add(t.normal),r++),null!=e&&e.hasNormal&&(s.add(e.normal),r++),null!=o&&o.hasNormal&&(s.add(o.normal),r++),null!=i&&i.hasNormal&&(s.add(i.normal),r++),0===r||s.lengthSq()<1e-8?null:(s.multiplyScalar(1/r).normalize(),s)}computeDesiredFootForward(t,e,o,i,s,r){null!=i&&null!=s?r.subVectors(i.point,s.point):r.copy(t),r.addScaledVector(o,-r.dot(o)),r.lengthSq()<1e-8&&(r.copy(this.actor.object.getWorldDirection(M)),r.addScaledVector(o,-r.dot(o))),r.lengthSq()<1e-8&&r.crossVectors(o,e),r.lengthSq()<1e-8&&r.set(0,0,1),r.normalize();const n=M.copy(this.actor.object.getWorldDirection(M));n.addScaledVector(o,-n.dot(o)),n.lengthSq()<1e-8&&(n.copy(t),n.addScaledVector(o,-n.dot(o))),n.lengthSq()>1e-8&&n.normalize(),r.dot(n)<0&&r.multiplyScalar(-1)}computeDesiredPitchAngle(t,e,o){if(null==t||null==e)return 0;const i=R.subVectors(t.point,e.point),s=Math.abs(i.dot(o));if(s<1e-5)return 0;const r=t.point.y-e.point.y,n=y.degToRad(this.footIkMaxSlopeAngleDeg);return y.clamp(-Math.atan2(r,s),-n,n)}applySimpleFootPitch(t,e,o){if(null==e.parent||o.weight<=.001)return;const i=this.ikFootAxes?.[t]??this.detectFootAxisBasis(e),s=o.pitch*o.weight;if(Math.abs(s)<=1e-5)return;const r=this.resolveLocalPitchSign(i),n=W.copy(e.quaternion),l=O.setFromAxisAngle(i.rightLocal,s*r);e.quaternion.copy(n.multiply(l))}resolveLocalPitchSign(t){const e=V.setFromAxisAngle(t.rightLocal,.15);return A.copy(t.upLocal).applyQuaternion(e).sub(t.upLocal).dot(t.forwardLocal)>=0?1:-1}clampDesiredFootTarget(t,e,o,i){const s=R.subVectors(i,o),r=s.dot(P),n=A.copy(s).addScaledVector(P,-r),l=n.length();l>this.footIkMaxHorizontalOffset&&l>1e-6&&n.multiplyScalar(this.footIkMaxHorizontalOffset/l);const a=y.clamp(r,-this.footIkMaxVerticalOffsetDown,this.footIkMaxVerticalOffsetUp);if(i.copy(o),i.add(n),i.addScaledVector(P,a),this.footIkPelvisEnabled)return;const h=t.upper.getWorldPosition(D).clone(),c=R.subVectors(i,h),p=c.length(),d=.995*e.total;p>d&&p>1e-6&&i.copy(h).addScaledVector(c,d/p)}solveTwoBoneLeg(t,e,o){const i=e.upper.getWorldPosition(D).clone(),s=e.lower.getWorldPosition(R).clone(),r=e.foot.getWorldPosition(A).clone(),n=i.distanceTo(s),l=s.distanceTo(r);if(n<1e-5||l<1e-5)return;const a=(new p).subVectors(o,i),h=a.length();if(h<1e-5)return;const c=Math.abs(n-l)+1e-4,d=n+l-1e-4,u=y.clamp(h,c,d),f=a.multiplyScalar(1/h),g=(new p).subVectors(s,i).normalize(),m=(new p).subVectors(r,s).normalize(),k=(new p).crossVectors(g,m);k.lengthSq()<1e-8&&(k.copy(this.actor.object.getWorldDirection(D).cross(P)),k.lengthSq()<1e-8&&k.set(1,0,0)),k.normalize();const S=(u*u+n*n-l*l)/(2*u),w=Math.max(n*n-S*S,0),b=Math.sqrt(w),L=(new p).copy(i).addScaledVector(f,S);let v=(new p).crossVectors(k,f);v.lengthSq()<1e-8&&(v=(new p).crossVectors(f,P),v.lengthSq()<1e-8&&(v=new p(1,0,0))),v.normalize();const B=(new p).copy(L).addScaledVector(v,b),I=(new p).copy(L).addScaledVector(v,-b),x=(new p).subVectors(s,L).dot(v)>=0?B:I;this.rotateBoneToward(e.upper,i,s,x),e.upper.updateMatrixWorld(!0);const F=e.lower.getWorldPosition(R),M=e.foot.getWorldPosition(A);this.rotateBoneToward(e.lower,F,M,o),e.lower.updateMatrixWorld(!0),this.updateSolveDebug(t,i,x,o)}updateSolveDebug(t,e,o,i){if(!this.footIkDebug||null==this.ikDebugLegs)return;const s=this.ikDebugLegs[t];this.setDebugArrow(s.solveUpper,e,o),this.setDebugArrow(s.solveLower,o,i)}rotateBoneToward(t,e,o,i){const s=(new p).subVectors(o,e),r=(new p).subVectors(i,e);if(s.lengthSq()<1e-10||r.lengthSq()<1e-10)return;if(s.normalize(),r.normalize(),s.dot(r)>.9999)return;const n=(new f).setFromUnitVectors(s,r),l=t.getWorldQuaternion(W),a=O.copy(n).multiply(l);if(null==t.parent)return void t.quaternion.copy(a);const h=t.parent.getWorldQuaternion(V),c=C.copy(h).invert().multiply(a);t.quaternion.copy(c)}detectFootAxisBasis(t){const e=t.getWorldQuaternion(W),o=this.actor.object.getWorldDirection(D);o.lengthSq()<1e-6&&o.set(0,0,1),o.normalize();const i=[{local:H.clone(),world:H.clone().applyQuaternion(e)},{local:z.clone(),world:z.clone().applyQuaternion(e)},{local:N.clone(),world:N.clone().applyQuaternion(e)}];i.push({local:H.clone().multiplyScalar(-1),world:H.clone().multiplyScalar(-1).applyQuaternion(e)}),i.push({local:z.clone().multiplyScalar(-1),world:z.clone().multiplyScalar(-1).applyQuaternion(e)}),i.push({local:N.clone().multiplyScalar(-1),world:N.clone().multiplyScalar(-1).applyQuaternion(e)});let s=i[0],r=-1/0;for(const t of i){const e=t.world.dot(P);e>r&&(r=e,s=t)}let n=i[0],l=-1/0;for(const t of i){if(Math.abs(t.world.dot(s.world))>.6)continue;const e=Math.abs(t.world.dot(o));e>l&&(l=e,n=t)}n.world.dot(o)<0&&(n={local:n.local.clone().multiplyScalar(-1),world:n.world.clone().multiplyScalar(-1)});const a=s.local.clone().normalize(),h=n.local.clone().normalize(),c=a.clone().cross(h).normalize();return{upLocal:a,forwardLocal:c.clone().cross(a).normalize(),rightLocal:c}}resolveFootAxes(t,e,o){const i=this.ikFootAxes?.[t]??this.detectFootAxisBasis(e),s=o??{up:new p,forward:new p,right:new p},r=e.getWorldQuaternion(W);return s.up.copy(i.upLocal).applyQuaternion(r).normalize(),s.forward.copy(i.forwardLocal).applyQuaternion(r).normalize(),s.right.copy(i.rightLocal).applyQuaternion(r).normalize(),s}clampSlopeNormal(t){const e=y.clamp(t.dot(P),-1,1),o=Math.acos(e),i=y.degToRad(this.footIkMaxSlopeAngleDeg);if(o<=i||o<1e-5)return;const s=i/o;t.lerpVectors(P,t,s).normalize()}blendLegAfterSolve(t,e,o){if(!(o>=.999)){if(o<=.001)return t.upper.quaternion.copy(e.upper),t.lower.quaternion.copy(e.lower),void t.foot.quaternion.copy(e.foot);this.blendBoneQuaternion(t.upper,e.upper,o),this.blendBoneQuaternion(t.lower,e.lower,o),this.blendBoneQuaternion(t.foot,e.foot,o)}}blendBoneQuaternion(t,e,o){W.copy(t.quaternion),t.quaternion.copy(e).slerp(W,o)}alignFootToGroundNormal(t,e,o,i){if(o.weight<=.001||null==e.parent)return;const s=this.ikFootAxes?.[t]??this.detectFootAxisBasis(e),r=D.copy(o.normal).normalize(),n=R.copy(o.forward);if(n.addScaledVector(r,-n.dot(r)),n.lengthSq()<1e-8){const o=this.resolveFootAxes(t,e);n.copy(o.forward).addScaledVector(r,-o.forward.dot(r))}if(n.lengthSq()<1e-8)return;n.normalize();const l=A.crossVectors(r,n);if(l.lengthSq()<1e-8)return;l.normalize(),n.copy(M.crossVectors(l,r)).normalize(),E.makeBasis(s.rightLocal,s.upLocal,s.forwardLocal),W.setFromRotationMatrix(E),q.makeBasis(l,r,n),O.setFromRotationMatrix(q);const a=V.copy(O).multiply(C.copy(W).invert()),h=e.parent.getWorldQuaternion(C),c=O.copy(h).invert().multiply(a),p=(1-Math.exp(-this.footIkRotationLerpSpeed*i))*o.weight;e.quaternion.slerp(c,y.clamp(p,0,1))}getMixer(){return this.mixer}beginExternalControl(){this.externalControlActive=!0}endExternalControl(){this.externalControlActive=!1}stopSequenceAnimation(){this.currentFullBodyPriority=-1,this.externalControlActive=!1,null==this.fullBodyAction||this.fullBodyAction.isRunning()||(this.fullBodyAction=null),null==this.upperBodyAction||this.upperBodyAction.isRunning()||(this.upperBodyAction=null),this.fullBodyTimer=0}cancelRootMotionAction(t){null!=t&&this.fullBodyAction!==t||(this.currentFullBodyPriority=-1,this.externalControlActive=!1,this.fullBodyAction?.stop(),this.fullBodyAction=null,this.fullBodyTimer=0)}beginExternalAnimationControl(t,e={}){J(null!=this.mixer,"Can't begin external control before setup is called"),this.mixer.stopAllAction(),this.currentFullBodyPriority=99,this.fullBodyTimer=0;const o=this.mixer.clipAction(t);return o.setLoop(h,1),o.clampWhenFinished=!0,o.timeScale=e.timeScale??1,o.reset(),o.play(),this.fullBodyAction=o,this.externalControlActive=!0,o}syncMovementSpeed(t){if(null!=t){const e=t.getClip();if(e instanceof i&&e.fixedInPlace&&null!=this.movementSpeed){t.timeScale=e.duration/e.displacement*this.movementSpeed;const o=this.mixer.getRoot();o instanceof a&&(t.timeScale/=o.scale.x)}}}playStateMachine(t){this.stateMachines.push(t)}playUpperStateMachine(t){this.upperStateMachines.push(t)}removeStateMachine(t){const e=this.stateMachines.indexOf(t);e>=0&&this.stateMachines.splice(e,1)}removeUpperStateMachine(t){const e=this.upperStateMachines.indexOf(t);e>=0&&this.upperStateMachines.splice(e,1)}playUpper(t,e={}){const o=e?.priority??1;o<this.currentUpperBodyPriority||(this.currentUpperBodyPriority=o,this.upperBodyAction=this.transition(this.upperBodyAction,this.getUpperBodyClip(t),e),this.upperBodyAction.timeScale=e?.timeScale??1,this.upperBodyTimer=0,this.upperBodyOverride=!0,this.overrideFadeTimeUpper=e.fadeTime)}play(t,e={}){J(null!=this.mixer,"Can't play animation before setup is called");const o=e.priority??1;o<this.currentFullBodyPriority||(this.currentFullBodyPriority=o,this.fullBodyTimer=0,this.upperBodyOverride||(this.upperBodyAction=this.transition(this.upperBodyAction,this.getUpperBodyClip(t),e),this.upperBodyAction.timeScale=e?.timeScale??1),this.fullBodyClip=t,this.fullBodyAction=this.transition(this.fullBodyAction,this.getFullBodyClip(t),e),this.fullBodyAction.timeScale=e?.timeScale??1,this.fullBodyAction.getClip().uuid==this.upperBodyAction.getClip().uuid&&this.upperBodyAction.syncWith(this.fullBodyAction),this.overrideFadeTime=e.fadeTime)}onActionDone(t){return new Promise(e=>{const o=i=>{i.action===t&&(e(i.action),this.mixer.removeEventListener("finished",o))};this.mixer.addEventListener("finished",o)})}transition(t,e,o={}){const i=o?.fadeTime??this.fadeTime;if(null!=t&&t.getClip().uuid===e.uuid)return!t.isRunning()&&!1===o.loop&&t.clampWhenFinished||t.isRunning()||(t.reset(),null!=o.offset&&(t.time=o.offset),t.enabled=!0,t.weight=1,t.setEffectiveWeight(1),t.setEffectiveTimeScale(1),t.play(),!1===o.loop&&(t.setLoop(h,1),t.clampWhenFinished=!0)),t;if(t&&t.isRunning()){const s=t,r=this.mixer.clipAction(e);r.reset(),null!=o.offset&&(r.time=o.offset),r.play(),r.enabled=!0,r.setEffectiveTimeScale(1),r.weight=1,s.crossFadeTo(r,i,!0),t=r}else(t=this.mixer.clipAction(e)).reset(),null!=o.offset&&(t.time=o.offset),t.enabled=!0,t.weight=1,t.setEffectiveWeight(1),t.setEffectiveTimeScale(1),t.play();return!1===o.loop&&(t.setLoop(h,1),t.clampWhenFinished=!0),t}};K=t([o({inEditor:!0})],K);export{K as CharacterAnimationComponent};function Y(t,e){if(null==t)return e;const o=e.clone(),i=new Set(t.map(t=>t.name));return o.tracks=o.tracks.filter(t=>i.has(t.name.split(".")[0])),o}function $(t){return t.flatMap(t=>function(t){const e=[];return t.traverse(t=>{e.push(t)}),e}(t)).filter(t=>t instanceof l)}function J(t,e){if(!1===t||"function"==typeof t&&!1===t())throw new Error(e)}function X(t,e){const o=new Map;return(i,...s)=>{const r=t(i);return o.has(r)||o.set(r,e(i,...s)),o.get(r)}}function Z(t){let e;return t.traverse(t=>{(t instanceof l||t.isBone)&&null==e&&(e=t)}),e}function tt(t,e){let o=e;for(;null!=o;){if(o===t)return!0;o=o.parent}return!1}/*
1
+ import{__decorate as t}from"tslib";import{ActorComponent as e,Component as o}from"../../../component.js";import{RootMotionClip as i}from"../../../../animation/root-motion.js";import{inject as s}from"../../../../inject.js";import{ViewController as r}from"../../../../services/render.js";import{AnimationMixer as n,Bone as l,Object3D as a,LoopOnce as h,Raycaster as c,Vector3 as d,SkinnedMesh as p,Skeleton as u,Quaternion as f,Matrix4 as g,MathUtils as y,ArrowHelper as m,Group as k}from"three";import{getCharacterMovementLike as S}from"./character-movement-like.js";import{CCDIKSolver as w}from"three/addons/animation/CCDIKSolver.js";import{World as b}from"../../../../services/world.js";import{PhysicsSystem as L,RayTestResult as v}from"../../../../services/physics/physics-system.js";import{ArrayMap as I}from"../../../../../utils/collections.js";import{getAnimationClipRigId as B,getAnimationRigChainBoneNames as P,getAnimationRigDataFromObject as x,getAnimationRigIdFromObject as R,setAnimationClipRigId as D}from"../../../../animation/retarget.js";const F=new d(0,-1,0),A=new d(0,1,0),M=new d(1,1,1),T=new f,W=new d,O=new d,V=new d,C=new d,E=new d,q=new f,H=new f,z=new f,N=new f,U=new g,j=new g,G=new d(1,0,0),Q=new d(0,1,0),$=new d(0,0,1);function _(){return{point:new d,normal:new d,hasNormal:!1}}const K=["mixamorigHips","Hips","hips","Pelvis","pelvis"],Y={upper:["LeftUpLeg","leftUpLeg","left_up_leg"],lower:["LeftLeg","leftLeg","left_leg"],foot:["LeftFoot","leftFoot","left_foot"]},J={upper:["RightUpLeg","rightUpLeg","right_up_leg"],lower:["RightLeg","rightLeg","right_leg"],foot:["RightFoot","rightFoot","right_foot"]},X=["left","right"];let Z=class extends e{constructor(){super(...arguments),this.viewController=s(r),this.poseProcessors=new I,this.stateMachines=[],this.upperStateMachines=[],this.fadeTime=.2,this.movementSpeed=null,this.upperBodyTimer=0,this.upperBodyOverride=!1,this.fullBodyTimer=0,this.currentFullBodyPriority=-1,this.currentUpperBodyPriority=-1,this.externalControlActive=!1,this.world=s(b),this.physicsSystem=s(L),this.footIkEnabled=!1,this.footIkMoving=!1,this.footIkRayStartHeight=.5,this.footIkRayLength=1.5,this.footIkRaycastMode="physics",this.footIkFootOffset=.08,this.footIkAutoContactOffset=!1,this.footIkPositionLerpSpeed=28,this.footIkRotationLerpSpeed=14,this.footIkWeightInSpeed=34,this.footIkWeightOutSpeed=30,this.footIkMaxSlopeAngleDeg=40,this.footIkForwardSampleDistance=.14,this.footIkSideSampleDistance=.08,this.footIkMaxHorizontalOffset=.22,this.footIkMaxVerticalOffsetDown=.75,this.footIkMaxVerticalOffsetUp=.2,this.footIkPelvisEnabled=!0,this.footIkPelvisBone="mixamorigHips",this.footIkPelvisLerpSpeed=24,this.footIkPelvisMaxOffsetDown=.4,this.footIkPelvisMaxOffsetUp=.08,this.footIkRequireGrounded=!0,this.footIkSimpleTiltOnly=!1,this.footIkDebug=!1,this.footIkDebugNormalLength=.25,this.footIkDebugAxisLength=.2,this.footIkExtraClearance=.01,this.footIkPlantReleaseUpSpeed=.08,this.footIkPlantReleaseExtension=.9,this.footIkPlantAttachExtension=.96,this.footIkPlantReleaseLift=.055,this.footIkPlantAttachLift=.02,this.leftLegIkBones={upperLeg:"mixamorigLeftUpLeg",lowerLeg:"mixamorigLeftLeg",foot:"mixamorigLeftFoot"},this.rightLegIkBones={upperLeg:"mixamorigRightUpLeg",lowerLeg:"mixamorigRightLeg",foot:"mixamorigRightFoot"},this.ikPelvisOffsetY=0,this.ikLegState={left:{targetPosition:new d,normal:new d(0,1,0),forward:new d(0,0,1),pitch:0,contactOffset:0,planted:!0,lastFootWorldPos:new d,hasLastFootSample:!1,weight:0,top:!1},right:{targetPosition:new d,normal:new d(0,1,0),forward:new d(0,0,1),pitch:0,contactOffset:0,planted:!0,lastFootWorldPos:new d,hasLastFootSample:!1,weight:0,top:!1}},this.ikWarnedMissingBones=!1,this.raycaster=new c,this.raycastIntersections=[],this.footIkRayTo=new d,this.footIkRayTestResult=new v,this.footIkRayTestOptions={excludeTriggers:!0,resolveActor:!1,collisionFilter:-2},this.footIkHits={center:_(),toe:_(),heel:_(),side:_()},this.footIkAxesScratch={up:new d,forward:new d,right:new d},this.footIkSampleAxesScratch={forward:new d,right:new d},this.footIkScratch={footWorldPos:new d,centerRayStart:new d,toeRayStart:new d,heelRayStart:new d,sideRayStart:new d,desiredTargetPos:new d,desiredNormal:new d,desiredForward:new d,debugRayEndA:new d,debugRayEndB:new d,debugRayEndC:new d,debugRayEndD:new d,debugRayEndE:new d,debugRayEndF:new d},this.ikPreSolve={left:{upper:new f,lower:new f,foot:new f},right:{upper:new f,lower:new f,foot:new f}},this.getFullBodyClip=it(t=>t.uuid,t=>tt(this.fullBodyMask,t)),this.getUpperBodyClip=it(t=>t.uuid,t=>tt(this.upperBodyMask,t))}onInit(){this.viewController.onUpdate(this.actor).subscribe(t=>this.updateInternal(t)),this.characterMovement=S(this.actor),this.footIkRayTestOptions.excludeActor=this.actor}onEndPlay(){this.disposeFootIkDebug()}raycastDownFirstValid(t,e,o){const i=this.world.scene;this.raycaster.set(t,F),this.raycaster.near=0,this.raycaster.far=e,this.raycastIntersections.length=0,this.raycaster.intersectObject(i,!0,this.raycastIntersections);for(const t of this.raycastIntersections)if(!(this.isFootIkDebugObject(t.object)||this.isRelatedToActorHierarchy(t.object)||this.isSkinnedMeshObject(t.object)))return o.point.copy(t.point),null!=t.face?(o.normal.copy(t.face.normal).transformDirection(t.object.matrixWorld).normalize(),o.hasNormal=!0):o.hasNormal=!1,this.raycastIntersections.length=0,!0;return this.raycastIntersections.length=0,!1}rayTestDown(t,e,o){const i=this.footIkRayTo.copy(t).addScaledVector(F,e),s=this.physicsSystem.rayTest(t,i,this.footIkRayTestResult,this.footIkRayTestOptions);return!!s.hasHit&&(o.point.copy(s.hitPoint),o.normal.copy(s.hitNormal),o.normal.lengthSq()>1e-8?(o.normal.normalize(),o.hasNormal=!0):o.hasNormal=!1,!0)}isRelatedToActorHierarchy(t){const e=this.actor?.object;return null!=e&&null!=t&&(rt(t,e)||rt(e,t))}isFootIkDebugObject(t){let e=t;for(;null!=e;){if(!0===e.userData?.footIkDebug)return!0;e=e.parent}return!1}isSkinnedMeshObject(t){let e=t;for(;null!=e;){if(e instanceof p||!0===e.isSkinnedMesh)return!0;e=e.parent}return!1}getRootMotionAction(){if(this.fullBodyAction.getClip()instanceof i)return this.fullBodyAction}getFullBodyAction(){return this.fullBodyAction}setup(t,e,o){null!=e&&(this.upperBodyMask=et(e),this.fullBodyMask=function(t,e){const o=new Set(et(e).map(t=>t.uuid)),i=[];return t.traverse(t=>{(t instanceof l||t.isBone)&&!o.has(t.uuid)&&i.push(t)}),i}(st(t),e)),null!=this.mixer&&this.mixer.stopAllAction(),this.mixer=new n(t),this.animationRigId=R(t),this.animationRigData=x(t),this.ikRoot=t,this.disposeFootIkDebug(),this.initializeFootIk(t,o),this.syncFootIkDebug()}updateStateMachines(t){this.stateMachines.forEach(e=>{e.step(t);const o=e.current.clip;null!=o&&this.play(o,{priority:e.current.options.priority??0,loop:e.current.options.loop??!0})}),this.upperStateMachines.forEach(e=>{e.step(t);const o=e.current.clip;null!=o?this.playUpper(o,{priority:e.current.options.priority??0,loop:e.current.options.loop??!0}):this.play(this.fullBodyClip)})}addPoseProcessor(t){const e={id:t.id,phase:t.phase??"afterMixer",order:t.order??0,update:t.update};this.removePoseProcessor(e.id);const o=this.poseProcessors.get(e.phase);let i=o.findIndex(t=>t.order>e.order);return-1===i&&(i=o.length),o.splice(i,0,e),()=>{const t=o.indexOf(e);-1!==t&&(o.splice(t,1),0===o.length&&this.poseProcessors.delete(e.phase))}}removePoseProcessor(t){for(const[e,o]of this.poseProcessors.entries()){const i=o.findIndex(e=>e.id===t);if(-1!==i)return o.splice(i,1),void(0===o.length&&this.poseProcessors.delete(e))}}runPoseProcessors(t,e){if(0===this.poseProcessors.size||null==this.mixer||!this.poseProcessors.present(t))return;const o=this.mixer.getRoot();if(!(o instanceof a))return;const i=this.poseProcessorContext??(this.poseProcessorContext={deltaTime:e,phase:t,animation:this,mixer:this.mixer,root:o});i.deltaTime=e,i.phase=t,i.mixer=this.mixer,i.root=o;const s=this.poseProcessors.get(t);for(let t=0;t<s.length;t++)s[t].update(i)}updateInternal(t){null!=this.mixer&&(this.externalControlActive||(this.upperBodyTimer+=t*(this.upperBodyAction?.timeScale??1),this.fullBodyTimer+=t*(this.fullBodyAction?.timeScale??1),this.upperBodyAction&&this.upperBodyOverride&&this.upperBodyAction.getClip().duration-2*(this.overrideFadeTimeUpper??this.fadeTime)<this.upperBodyTimer&&(this.upperBodyOverride=!1,null!=this.fullBodyClip&&this.transition(this.upperBodyAction,this.getUpperBodyClip(this.fullBodyClip)),this.upperBodyAction=null,this.overrideFadeTimeUpper=null),this.fullBodyAction&&this.fullBodyAction.loop===h&&this.fullBodyAction.getClip().duration-2*(this.overrideFadeTime??this.fadeTime)<this.fullBodyTimer&&(this.currentFullBodyPriority=-1,this.overrideFadeTime=null),null!=this.characterMovement&&(this.movementSpeed=this.characterMovement.horizontalSpeed),this.updateStateMachines(t),this.syncMovementSpeed(this.fullBodyAction),this.upperBodyOverride||this.syncMovementSpeed(this.upperBodyAction),this.runPoseProcessors("beforeMixer",t),this.mixer.update(t),this.runPoseProcessors("afterMixer",t),this.runPoseProcessors("beforeIk",t),this.updateFootIk(t),this.runPoseProcessors("afterIk",t)))}initializeFootIk(t,e){if(this.ikSolver=null,this.ikSkinnedMesh=null,this.ikBoneRefs=null,this.ikLegLengths=null,this.ikPelvisBone=null,this.ikPelvisOffsetY=0,this.ikFootAxes=null,this.ikTargetBones=null,this.ikWarnedMissingBones=!1,this.ikLegState.left.weight=0,this.ikLegState.right.weight=0,!this.footIkEnabled)return;const o=this.findFirstSkinnedMesh(t);if(null==o||null==o.skeleton)return;this.ikSkinnedMesh=o,t.updateWorldMatrix(!0,!0);const i=o.skeleton,s=P(this.animationRigData,"leftLeg"),r=P(this.animationRigData,"rightLeg"),n=this.resolveLegBoneRefs(i,this.leftLegIkBones,Y,s),a=this.resolveLegBoneRefs(i,this.rightLegIkBones,J,r);if(null==n||null==a)return void(this.ikWarnedMissingBones||(this.ikWarnedMissingBones=!0,console.warn(`[CharacterAnimationComponent] Foot IK disabled: missing leg bones. Left=${this.leftLegIkBones.upperLeg}/${this.leftLegIkBones.lowerLeg}/${this.leftLegIkBones.foot}, Right=${this.rightLegIkBones.upperLeg}/${this.rightLegIkBones.lowerLeg}/${this.rightLegIkBones.foot}`)));this.ikBoneRefs={left:n,right:a},this.ikLegLengths={left:this.computeLegLengths(n),right:this.computeLegLengths(a)},this.ikFootAxes={left:this.detectFootAxisBasis(n.foot),right:this.detectFootAxisBasis(a.foot)};const h=this.animationRigData?.bones.find(t=>t.id===this.animationRigData?.pelvisBoneId)?.name;this.ikPelvisBone=this.resolvePelvisBone(i,n,a,h),this.ikLegState.left.targetPosition.copy(n.foot.getWorldPosition(W)),this.ikLegState.right.targetPosition.copy(a.foot.getWorldPosition(W)),this.ikLegState.left.normal.set(0,1,0),this.ikLegState.right.normal.set(0,1,0),this.ikLegState.left.pitch=0,this.ikLegState.right.pitch=0,this.ikLegState.left.contactOffset=this.estimateFootContactOffset(i,"left",n.foot),this.ikLegState.right.contactOffset=this.estimateFootContactOffset(i,"right",a.foot),this.ikLegState.left.planted=!0,this.ikLegState.right.planted=!0,this.ikLegState.left.lastFootWorldPos.copy(n.foot.getWorldPosition(W)),this.ikLegState.right.lastFootWorldPos.copy(a.foot.getWorldPosition(W)),this.ikLegState.left.hasLastFootSample=!0,this.ikLegState.right.hasLastFootSample=!0;const c=this.resolveFootAxes("left",n.foot),d=this.resolveFootAxes("right",a.foot);this.ikLegState.left.forward.copy(c.forward),this.ikLegState.right.forward.copy(d.forward);const p=e??st(t);if(null==p)return;let f=i.getBoneByName("_IKTargetLeftFoot"),y=i.getBoneByName("_IKTargetRightFoot"),m=!1;if(null==f&&(f=new l,f.name="_IKTargetLeftFoot",p.add(f),m=!0),null==y&&(y=new l,y.name="_IKTargetRightFoot",p.add(y),m=!0),this.setBoneWorldPosition(f,n.foot.getWorldPosition(W)),this.setBoneWorldPosition(y,a.foot.getWorldPosition(W)),m||i.bones.indexOf(f)<0||i.bones.indexOf(y)<0){const t=i.bones.slice(),e=i.boneInverses.map(t=>t.clone());t.indexOf(f)<0&&(t.push(f),e.push((new g).copy(f.matrixWorld).invert())),t.indexOf(y)<0&&(t.push(y),e.push((new g).copy(y.matrixWorld).invert())),o.bind(new u(t,e),o.bindMatrix)}this.ikTargetBones={left:f,right:y};const k=o.skeleton.bones,S={target:k.indexOf(f),effector:k.indexOf(n.foot),links:[{index:k.indexOf(n.lower)},{index:k.indexOf(n.upper)}],iteration:8},b={target:k.indexOf(y),effector:k.indexOf(a.foot),links:[{index:k.indexOf(a.lower)},{index:k.indexOf(a.upper)}],iteration:8};if(S.target<0||S.effector<0||S.links.some(t=>t.index<0)||b.target<0||b.effector<0||b.links.some(t=>t.index<0))return console.warn("[CharacterAnimationComponent] Foot IK disabled: failed to resolve IK indexes in skeleton."),void(this.ikSolver=null);this.ikSolver=new w(o,[S,b])}findFirstSkinnedMesh(t){let e;return t.traverse(t=>{null==e&&(t instanceof p||!0===t.isSkinnedMesh)&&(e=t)}),e}resolveLegBoneRefs(t,e,o,i=[]){const s=this.findBoneByNames(t,[i[0],e.upperLeg,...o.upper].filter(t=>null!=t)),r=this.findBoneByNames(t,[i.at(-2),e.lowerLeg,...o.lower].filter(t=>null!=t)),n=this.findBoneByNames(t,[i.at(-1),e.foot,...o.foot].filter(t=>null!=t));if(null!=s&&null!=r&&null!=n)return{upper:s,lower:r,foot:n}}findBoneByNames(t,e){for(const o of e){const e=t.getBoneByName(o);if(null!=e)return e}}resolvePelvisBone(t,e,o,i){const s=this.findBoneByNames(t,[i,this.footIkPelvisBone,...K].filter(t=>null!=t));if(null!=s)return s;const r=e.upper.parent,n=o.upper.parent;return null!=r&&r===n&&(r instanceof l||!0===r.isBone)||null!=r&&(r instanceof l||!0===r.isBone)?r:void 0}computeLegLengths(t){const e=t.upper.getWorldPosition(W),o=t.lower.getWorldPosition(O),i=t.foot.getWorldPosition(V),s=e.distanceTo(o),r=o.distanceTo(i);return{upper:s,lower:r,total:s+r}}setBoneWorldPosition(t,e){const o=t.parent;null==o?t.position.copy(e):t.position.copy(o.worldToLocal(W.copy(e))),t.quaternion.copy(T),t.scale.copy(M),t.updateMatrixWorld(!0)}syncFootIkDebug(){this.footIkDebug&&null!=this.ikRoot?(null!=this.ikDebugRoot&&null!=this.ikDebugLegs||(this.ikDebugRoot=new k,this.ikDebugRoot.name="FootIKDebug",this.ikDebugRoot.userData.footIkDebug=!0,this.ikDebugLegs={left:this.createDebugLeg("LeftFootIK",53503),right:this.createDebugLeg("RightFootIK",16755200)},this.ikDebugRoot.add(this.ikDebugLegs.left.root,this.ikDebugLegs.right.root),this.world.scene.add(this.ikDebugRoot)),this.ikDebugRoot.visible=!0):null!=this.ikDebugRoot&&(this.ikDebugRoot.visible=!1)}disposeFootIkDebug(){null!=this.ikDebugRoot&&(this.ikDebugRoot.removeFromParent(),this.ikDebugRoot.clear()),this.ikDebugRoot=null,this.ikDebugLegs=null}createDebugLeg(t,e){const o=new k;o.name=t,o.userData.footIkDebug=!0;const i=this.createDebugArrow(e),s=this.createDebugArrow(e),r=this.createDebugArrow(e),n=this.createDebugArrow(e),l=this.createDebugArrow(65280),a=this.createDebugArrow(6750054),h=this.createDebugArrow(16711935),c=this.createDebugArrow(16776960),d=this.createDebugArrow(16737792);return o.add(i,s,r,n,l,a,h,c,d),{root:o,rayCenter:i,rayToe:s,rayHeel:r,raySide:n,hitNormal:l,footUp:a,footToTarget:h,solveUpper:c,solveLower:d}}createDebugArrow(t){const e=new m(A,new d,.001,t);return e.userData.footIkDebug=!0,e.traverse(t=>{t.userData.footIkDebug=!0,t.raycast=()=>{}}),e.visible=!1,e}setDebugArrow(t,e,o){W.subVectors(o,e);const i=W.length();i<1e-6?t.visible=!1:(t.visible=!0,t.position.copy(e),t.setDirection(W.multiplyScalar(1/i)),t.setLength(i,Math.min(.08,.25*i),Math.min(.05,.2*i)))}resetDebugVisibility(){null!=this.ikDebugLegs&&(this.ikDebugLegs.left.rayCenter.visible=!1,this.ikDebugLegs.left.rayToe.visible=!1,this.ikDebugLegs.left.rayHeel.visible=!1,this.ikDebugLegs.left.raySide.visible=!1,this.ikDebugLegs.left.hitNormal.visible=!1,this.ikDebugLegs.left.footUp.visible=!1,this.ikDebugLegs.left.footToTarget.visible=!1,this.ikDebugLegs.left.solveUpper.visible=!1,this.ikDebugLegs.left.solveLower.visible=!1,this.ikDebugLegs.right.rayCenter.visible=!1,this.ikDebugLegs.right.rayToe.visible=!1,this.ikDebugLegs.right.rayHeel.visible=!1,this.ikDebugLegs.right.raySide.visible=!1,this.ikDebugLegs.right.hitNormal.visible=!1,this.ikDebugLegs.right.footUp.visible=!1,this.ikDebugLegs.right.footToTarget.visible=!1,this.ikDebugLegs.right.solveUpper.visible=!1,this.ikDebugLegs.right.solveLower.visible=!1)}updateFootIk(t){if(this.syncFootIkDebug(),!this.footIkEnabled||null==this.ikBoneRefs||null==this.ikRoot)return void this.resetDebugVisibility();if(!this.footIkMoving&&(this.movementSpeed??0)>.01)return this.resetFootIkState(),void this.resetDebugVisibility();this.ikRoot.updateWorldMatrix(!0,!0);const e=this.characterMovement?.isGrounded??!0;return this.footIkSimpleTiltOnly?(this.updatePelvisOffset(t,!1),this.updateLegTiltSimple("left",this.ikBoneRefs.left.foot,this.ikLegState.left,e,t),void this.updateLegTiltSimple("right",this.ikBoneRefs.right.foot,this.ikLegState.right,e,t)):null==this.ikLegLengths||null==this.ikTargetBones||null==this.ikSkinnedMesh||null==this.ikSolver?(this.updatePelvisOffset(t,!1),void this.resetDebugVisibility()):(this.updateLegIkTarget("left",this.ikBoneRefs.left,this.ikLegLengths.left,this.ikTargetBones.left,this.ikLegState.left,e,t),this.updateLegIkTarget("right",this.ikBoneRefs.right,this.ikLegLengths.right,this.ikTargetBones.right,this.ikLegState.right,e,t),this.updatePelvisOffset(t,!0),this.setBoneWorldPosition(this.ikTargetBones.left,this.ikLegState.left.targetPosition),this.setBoneWorldPosition(this.ikTargetBones.right,this.ikLegState.right.targetPosition),this.ikPreSolve.left.upper.copy(this.ikBoneRefs.left.upper.quaternion),this.ikPreSolve.left.lower.copy(this.ikBoneRefs.left.lower.quaternion),this.ikPreSolve.left.foot.copy(this.ikBoneRefs.left.foot.quaternion),this.ikPreSolve.right.upper.copy(this.ikBoneRefs.right.upper.quaternion),this.ikPreSolve.right.lower.copy(this.ikBoneRefs.right.lower.quaternion),this.ikPreSolve.right.foot.copy(this.ikBoneRefs.right.foot.quaternion),null!=this.ikDebugLegs&&(this.ikDebugLegs.left.solveUpper.visible=!1,this.ikDebugLegs.left.solveLower.visible=!1,this.ikDebugLegs.right.solveUpper.visible=!1,this.ikDebugLegs.right.solveLower.visible=!1),this.ikSolver.update(),this.blendLegAfterSolve(this.ikBoneRefs.left,this.ikPreSolve.left,this.ikLegState.left.weight),this.blendLegAfterSolve(this.ikBoneRefs.right,this.ikPreSolve.right,this.ikLegState.right.weight),this.applySimpleFootPitch("left",this.ikBoneRefs.left.foot,this.ikLegState.left),void this.applySimpleFootPitch("right",this.ikBoneRefs.right.foot,this.ikLegState.right))}resetFootIkState(){if(null!=this.ikBoneRefs){for(const t of X){const e=this.ikBoneRefs[t],o=this.ikLegState[t],i=e.foot.getWorldPosition(W);o.targetPosition.copy(i),o.lastFootWorldPos.copy(i),o.hasLastFootSample=!0,o.weight=0,o.normal.set(0,1,0);const s=this.resolveFootAxes(t,e.foot,this.footIkAxesScratch);o.forward.copy(s.forward),o.pitch=0,this.footIkAutoContactOffset?o.contactOffset=Math.max(o.contactOffset,this.footIkFootOffset+this.footIkExtraClearance):o.contactOffset=this.footIkFootOffset+this.footIkExtraClearance,o.planted=!1}this.ikPelvisOffsetY=0}}updatePelvisOffset(t,e){if(null==this.ikPelvisBone)return;let o=0;if(e&&this.footIkPelvisEnabled&&null!=this.ikBoneRefs&&null!=this.ikLegLengths){this.ikLegState.left.top=!1,this.ikLegState.right.top=!1;for(const t of X){const e=this.ikBoneRefs[t],i=this.ikLegLengths[t],s=this.ikLegState[t];if(!s.planted)continue;const r=e.upper.getWorldPosition(W),n=.998*i.total,l=this.computeRequiredPelvisDrop(r,s.targetPosition,n);if(l>0){const e="left"===t?"right":"left";this.ikLegState[e].top=!0}o=Math.min(o,-l)}o=y.clamp(o,-this.footIkPelvisMaxOffsetDown,this.footIkPelvisMaxOffsetUp)}const i=1-Math.exp(-this.footIkPelvisLerpSpeed*t);this.ikPelvisOffsetY=y.lerp(this.ikPelvisOffsetY,o,i);const s=this.ikPelvisBone.getWorldPosition(O),r=V.copy(s).addScaledVector(A,this.ikPelvisOffsetY);null==this.ikPelvisBone.parent?this.ikPelvisBone.position.copy(r):this.ikPelvisBone.position.copy(this.ikPelvisBone.parent.worldToLocal(r)),this.ikPelvisBone.updateMatrixWorld(!0)}computeFootVerticalSpeed(t,e,o){return!t.hasLastFootSample||o<=1e-6?0:(e.y-t.lastFootWorldPos.y)/o}updateFootSample(t,e){t.lastFootWorldPos.copy(e),t.hasLastFootSample=!0}estimateFootContactOffset(t,e,o){const i=this.footIkFootOffset+this.footIkExtraClearance;if(!this.footIkAutoContactOffset)return i;const s=t.bones.indexOf(o);if(s<0)return i;const r=t.boneInverses[s];if(null==r)return i;const n=this.ikFootAxes?.[e]??this.detectFootAxisBasis(o),a=o.getWorldPosition(O),h=V.copy(n.upLocal).applyQuaternion(o.getWorldQuaternion(q)).normalize();let c=0;return o.traverse(e=>{if(!(e instanceof l)||e===o)return;const i=t.bones.indexOf(e);if(i<0)return;const s=U.copy(t.boneInverses[i]).invert(),n=j.copy(r).multiply(s),d=W.setFromMatrixPosition(n),p=C.copy(d).applyMatrix4(o.matrixWorld).sub(a);c=Math.min(c,p.dot(h))}),Math.max(i,-c+this.footIkExtraClearance)}shouldPlantFoot(t,e,o,i,s,r){if(!e||!o)return!1;const n=this.footIkPlantReleaseExtension,l=this.footIkPlantAttachExtension,a=this.footIkPlantReleaseLift,h=this.footIkPlantAttachLift;return t.planted?!(i>this.footIkPlantReleaseUpSpeed&&(s<n||r>a)):s>=l&&r<=h||i<=0&&s>=n}computeLegExtensionRatio(t,e){const o=t.upper.getWorldPosition(W),i=t.foot.getWorldPosition(O),s=o.distanceTo(i);return e.total<=1e-6?1:y.clamp(s/e.total,0,1.2)}computeRequiredPelvisDrop(t,e,o){const i=C.subVectors(t,e),s=i.length();if(s<=o+1e-6)return 0;const r=i.dot(A),n=o*o-Math.max(s*s-r*r,0);if(n<=0)return s-o;const l=Math.sqrt(n),a=r-l,h=r+l;return a>=0?a:h>=0?h:0}updateLegTiltSimple(t,e,o,i,s){const r=this.footIkScratch,n=this.footIkHits,l=e.getWorldPosition(r.footWorldPos),a=this.computeFootVerticalSpeed(o,l,s),h=this.resolveFootAxes(t,e,this.footIkAxesScratch),c=this.resolveGroundSampleAxes(t,e,h,this.footIkSampleAxesScratch),d=r.centerRayStart.copy(l).addScaledVector(A,this.footIkRayStartHeight),p=r.toeRayStart.copy(d).addScaledVector(c.forward,this.footIkForwardSampleDistance),u=r.heelRayStart.copy(d).addScaledVector(c.forward,-this.footIkForwardSampleDistance),f=r.sideRayStart.copy(d).addScaledVector(c.right,this.footIkSideSampleDistance),g=this.getFirstGroundHit(d,n.center),m=this.getFirstGroundHit(p,n.toe),k=this.getFirstGroundHit(u,n.heel),S=this.getFirstGroundHit(f,n.side),w=r.desiredNormal.set(0,1,0),b=r.desiredForward.copy(c.forward);let L=0,v=0,I=this.footIkWeightOutSpeed;const B=null!=g||null!=m||null!=k;let P=l.y;null!=g?P=g.point.y:null!=m&&null!=k?P=.5*(m.point.y+k.point.y):null!=m?P=m.point.y:null!=k&&(P=k.point.y);const x=this.ikBoneRefs?.[t],R=this.ikLegLengths?.[t],D=null!=x&&null!=R?this.computeLegExtensionRatio(x,R):1,F=Math.max(0,l.y-P,l.y-o.targetPosition.y),M=this.shouldPlantFoot(o,!this.footIkRequireGrounded||i,B,a,D,F);M?this.computeDesiredGroundNormal(c,g,m,k,S,w)&&(this.computeDesiredFootForward(c.forward,c.right,w,m,k,b),L=this.computeDesiredPitchAngle(m,k,c.forward),v=1,I=this.footIkWeightInSpeed):this.computeDesiredFootForward(c.forward,c.right,w,null,null,b);const T=1-Math.exp(-this.footIkPositionLerpSpeed*s),W=1-Math.exp(-I*s);o.normal.lerp(w,T).normalize(),o.forward.lerp(b,T).normalize(),o.pitch=y.lerp(o.pitch,L,T),o.weight=y.lerp(o.weight,v,W),o.planted=M&&v>.001,this.updateFootSample(o,l),this.applySimpleFootPitch(t,e,o),this.updateLegDebug(t,{footWorldPos:l,centerRayStart:d,toeRayStart:p,heelRayStart:u,sideRayStart:f,centerHit:g,toeHit:m,heelHit:k,sideHit:S,desiredNormal:o.normal,desiredTargetPos:r.footWorldPos,weight:o.weight})}updateLegIkTarget(t,e,o,i,s,r,n){const l=this.footIkScratch,a=this.footIkHits,h=e.foot,c=h.getWorldPosition(l.footWorldPos),d=this.computeFootVerticalSpeed(s,c,n),p=this.resolveFootAxes(t,h,this.footIkAxesScratch),u=this.resolveGroundSampleAxes(t,h,p,this.footIkSampleAxesScratch),f=l.centerRayStart.copy(c).addScaledVector(A,this.footIkRayStartHeight),g=l.toeRayStart.copy(f).addScaledVector(u.forward,this.footIkForwardSampleDistance),m=l.heelRayStart.copy(f).addScaledVector(u.forward,-this.footIkForwardSampleDistance),k=l.sideRayStart.copy(f).addScaledVector(u.right,this.footIkSideSampleDistance),S=this.getFirstGroundHit(f,a.center),w=this.getFirstGroundHit(g,a.toe),b=this.getFirstGroundHit(m,a.heel),L=this.getFirstGroundHit(k,a.side),v=l.desiredTargetPos.copy(c),I=l.desiredNormal.set(0,1,0),B=l.desiredForward.copy(u.forward);let P=0,x=0,R=this.footIkWeightOutSpeed;const D=null!=S||null!=w||null!=b;let F=c.y;null!=S?F=S.point.y:null!=w&&null!=b?F=.5*(w.point.y+b.point.y):null!=w?F=w.point.y:null!=b&&(F=b.point.y);const M=this.computeLegExtensionRatio(e,o),T=Math.max(0,c.y-F,c.y-s.targetPosition.y),W=this.shouldPlantFoot(s,!this.footIkRequireGrounded||r,D,d,M,T);if(W){if(v.copy(c),this.computeDesiredGroundNormal(u,S,w,b,L,I)){this.computeDesiredFootForward(u.forward,u.right,I,w,b,B),P=this.computeDesiredPitchAngle(w,b,u.forward);const t=Math.max(0,Math.sin(P))*this.footIkForwardSampleDistance*.45,e=Math.max(this.footIkFootOffset+this.footIkExtraClearance,s.contactOffset);v.y=F+e+t,s.top&&(v.y-=this.ikPelvisOffsetY/2),x=1,R=this.footIkWeightInSpeed}}else this.computeDesiredFootForward(u.forward,u.right,I,null,null,B),v.copy(c),v.y+=this.footIkFootOffset;this.clampDesiredFootTarget(e,o,c,v);const O=1-Math.exp(-this.footIkPositionLerpSpeed*n),V=1-Math.exp(-R*n);s.targetPosition.lerp(v,O),s.normal.lerp(I,O).normalize(),s.forward.lerp(B,O).normalize(),s.pitch=y.lerp(s.pitch,P,O),s.weight=y.lerp(s.weight,x,V),s.planted=W&&x>.001,this.updateFootSample(s,c),this.setBoneWorldPosition(i,s.targetPosition),this.updateLegDebug(t,{footWorldPos:c,centerRayStart:f,toeRayStart:g,heelRayStart:m,sideRayStart:k,centerHit:S,toeHit:w,heelHit:b,sideHit:L,desiredNormal:I,desiredTargetPos:s.targetPosition,weight:s.weight})}updateLegDebug(t,e){if(!this.footIkDebug||null==this.ikDebugLegs||null==this.ikBoneRefs)return;const o=this.ikDebugLegs[t],i=this.ikBoneRefs[t],s=this.resolveFootAxes(t,i.foot,this.footIkAxesScratch),r=this.footIkScratch,n=e.centerHit?.point??r.debugRayEndA.copy(e.centerRayStart).addScaledVector(F,this.footIkRayLength),l=e.toeHit?.point??r.debugRayEndB.copy(e.toeRayStart).addScaledVector(F,this.footIkRayLength),a=e.heelHit?.point??r.debugRayEndC.copy(e.heelRayStart).addScaledVector(F,this.footIkRayLength),h=e.sideHit?.point??r.debugRayEndD.copy(e.sideRayStart).addScaledVector(F,this.footIkRayLength);this.setDebugArrow(o.rayCenter,e.centerRayStart,n),this.setDebugArrow(o.rayToe,e.toeRayStart,l),this.setDebugArrow(o.rayHeel,e.heelRayStart,a),this.setDebugArrow(o.raySide,e.sideRayStart,h);const c=e.centerHit?.point??e.toeHit?.point??e.heelHit?.point??e.sideHit?.point??e.footWorldPos;this.setDebugArrow(o.hitNormal,c,r.debugRayEndE.copy(c).addScaledVector(e.desiredNormal,this.footIkDebugNormalLength)),this.setDebugArrow(o.footUp,e.footWorldPos,r.debugRayEndF.copy(e.footWorldPos).addScaledVector(s.up,this.footIkDebugAxisLength*(.15+e.weight))),this.setDebugArrow(o.footToTarget,e.footWorldPos,e.desiredTargetPos)}getFirstGroundHit(t,e){return"physics"===this.footIkRaycastMode?this.rayTestDown(t,this.footIkRayLength,e)?e:null:"physicsThenRender"===this.footIkRaycastMode?this.rayTestDown(t,this.footIkRayLength,e)||this.raycastDownFirstValid(t,this.footIkRayLength,e)?e:null:this.raycastDownFirstValid(t,this.footIkRayLength,e)?e:null}resolveGroundSampleAxes(t,e,o,i){const s=o??this.resolveFootAxes(t,e),r=i??{forward:new d,right:new d},n=this.actor.object.getWorldDirection(C);n.addScaledVector(A,-n.dot(A)),n.lengthSq()<1e-8&&n.copy(s.forward).addScaledVector(A,-s.forward.dot(A)),n.lengthSq()<1e-8&&n.set(0,0,1),n.normalize();const l=E.crossVectors(A,n);return l.lengthSq()<1e-8?l.copy(s.right):l.normalize(),l.dot(s.right)<0&&l.multiplyScalar(-1),r.forward.copy(n),r.right.copy(l),r}computeDesiredGroundNormal(t,e,o,i,s,r){const n=this.computeAverageHitNormal(e,o,i,s,C);let l=!1,a=0,h=0;if(null!=o&&null!=i){const e=O.subVectors(o.point,i.point).dot(t.forward);Math.abs(e)>1e-5&&(a=(o.point.y-i.point.y)/e,l=!0)}if(null!=s&&null!=e){const o=V.subVectors(s.point,e.point).dot(t.right);Math.abs(o)>1e-5&&(h=(s.point.y-e.point.y)/o,l=!0)}if(l&&(r.copy(A),r.addScaledVector(t.forward,-a),r.addScaledVector(t.right,-h),r.lengthSq()>1e-8?r.normalize():l=!1),l)null!=n&&r.dot(n)<0&&r.multiplyScalar(-1);else{if(null==n)return!1;r.copy(n),l=!0}return r.dot(A)<0&&r.multiplyScalar(-1),this.clampSlopeNormal(r),!0}computeAverageHitNormal(t,e,o,i,s){s.set(0,0,0);let r=0;return null!=t&&t.hasNormal&&(s.add(t.normal),r++),null!=e&&e.hasNormal&&(s.add(e.normal),r++),null!=o&&o.hasNormal&&(s.add(o.normal),r++),null!=i&&i.hasNormal&&(s.add(i.normal),r++),0===r||s.lengthSq()<1e-8?null:(s.multiplyScalar(1/r).normalize(),s)}computeDesiredFootForward(t,e,o,i,s,r){null!=i&&null!=s?r.subVectors(i.point,s.point):r.copy(t),r.addScaledVector(o,-r.dot(o)),r.lengthSq()<1e-8&&(r.copy(this.actor.object.getWorldDirection(C)),r.addScaledVector(o,-r.dot(o))),r.lengthSq()<1e-8&&r.crossVectors(o,e),r.lengthSq()<1e-8&&r.set(0,0,1),r.normalize();const n=C.copy(this.actor.object.getWorldDirection(C));n.addScaledVector(o,-n.dot(o)),n.lengthSq()<1e-8&&(n.copy(t),n.addScaledVector(o,-n.dot(o))),n.lengthSq()>1e-8&&n.normalize(),r.dot(n)<0&&r.multiplyScalar(-1)}computeDesiredPitchAngle(t,e,o){if(null==t||null==e)return 0;const i=O.subVectors(t.point,e.point),s=Math.abs(i.dot(o));if(s<1e-5)return 0;const r=t.point.y-e.point.y,n=y.degToRad(this.footIkMaxSlopeAngleDeg);return y.clamp(-Math.atan2(r,s),-n,n)}applySimpleFootPitch(t,e,o){if(null==e.parent||o.weight<=.001)return;const i=this.ikFootAxes?.[t]??this.detectFootAxisBasis(e),s=o.pitch*o.weight;if(Math.abs(s)<=1e-5)return;const r=this.resolveLocalPitchSign(i),n=q.copy(e.quaternion),l=H.setFromAxisAngle(i.rightLocal,s*r);e.quaternion.copy(n.multiply(l))}resolveLocalPitchSign(t){const e=z.setFromAxisAngle(t.rightLocal,.15);return V.copy(t.upLocal).applyQuaternion(e).sub(t.upLocal).dot(t.forwardLocal)>=0?1:-1}clampDesiredFootTarget(t,e,o,i){const s=O.subVectors(i,o),r=s.dot(A),n=V.copy(s).addScaledVector(A,-r),l=n.length();l>this.footIkMaxHorizontalOffset&&l>1e-6&&n.multiplyScalar(this.footIkMaxHorizontalOffset/l);const a=y.clamp(r,-this.footIkMaxVerticalOffsetDown,this.footIkMaxVerticalOffsetUp);if(i.copy(o),i.add(n),i.addScaledVector(A,a),this.footIkPelvisEnabled)return;const h=t.upper.getWorldPosition(W).clone(),c=O.subVectors(i,h),d=c.length(),p=.995*e.total;d>p&&d>1e-6&&i.copy(h).addScaledVector(c,p/d)}solveTwoBoneLeg(t,e,o){const i=e.upper.getWorldPosition(W).clone(),s=e.lower.getWorldPosition(O).clone(),r=e.foot.getWorldPosition(V).clone(),n=i.distanceTo(s),l=s.distanceTo(r);if(n<1e-5||l<1e-5)return;const a=(new d).subVectors(o,i),h=a.length();if(h<1e-5)return;const c=Math.abs(n-l)+1e-4,p=n+l-1e-4,u=y.clamp(h,c,p),f=a.multiplyScalar(1/h),g=(new d).subVectors(s,i).normalize(),m=(new d).subVectors(r,s).normalize(),k=(new d).crossVectors(g,m);k.lengthSq()<1e-8&&(k.copy(this.actor.object.getWorldDirection(W).cross(A)),k.lengthSq()<1e-8&&k.set(1,0,0)),k.normalize();const S=(u*u+n*n-l*l)/(2*u),w=Math.max(n*n-S*S,0),b=Math.sqrt(w),L=(new d).copy(i).addScaledVector(f,S);let v=(new d).crossVectors(k,f);v.lengthSq()<1e-8&&(v=(new d).crossVectors(f,A),v.lengthSq()<1e-8&&(v=new d(1,0,0))),v.normalize();const I=(new d).copy(L).addScaledVector(v,b),B=(new d).copy(L).addScaledVector(v,-b),P=(new d).subVectors(s,L).dot(v)>=0?I:B;this.rotateBoneToward(e.upper,i,s,P),e.upper.updateMatrixWorld(!0);const x=e.lower.getWorldPosition(O),R=e.foot.getWorldPosition(V);this.rotateBoneToward(e.lower,x,R,o),e.lower.updateMatrixWorld(!0),this.updateSolveDebug(t,i,P,o)}updateSolveDebug(t,e,o,i){if(!this.footIkDebug||null==this.ikDebugLegs)return;const s=this.ikDebugLegs[t];this.setDebugArrow(s.solveUpper,e,o),this.setDebugArrow(s.solveLower,o,i)}rotateBoneToward(t,e,o,i){const s=(new d).subVectors(o,e),r=(new d).subVectors(i,e);if(s.lengthSq()<1e-10||r.lengthSq()<1e-10)return;if(s.normalize(),r.normalize(),s.dot(r)>.9999)return;const n=(new f).setFromUnitVectors(s,r),l=t.getWorldQuaternion(q),a=H.copy(n).multiply(l);if(null==t.parent)return void t.quaternion.copy(a);const h=t.parent.getWorldQuaternion(z),c=N.copy(h).invert().multiply(a);t.quaternion.copy(c)}detectFootAxisBasis(t){const e=t.getWorldQuaternion(q),o=this.actor.object.getWorldDirection(W);o.lengthSq()<1e-6&&o.set(0,0,1),o.normalize();const i=[{local:G.clone(),world:G.clone().applyQuaternion(e)},{local:Q.clone(),world:Q.clone().applyQuaternion(e)},{local:$.clone(),world:$.clone().applyQuaternion(e)}];i.push({local:G.clone().multiplyScalar(-1),world:G.clone().multiplyScalar(-1).applyQuaternion(e)}),i.push({local:Q.clone().multiplyScalar(-1),world:Q.clone().multiplyScalar(-1).applyQuaternion(e)}),i.push({local:$.clone().multiplyScalar(-1),world:$.clone().multiplyScalar(-1).applyQuaternion(e)});let s=i[0],r=-1/0;for(const t of i){const e=t.world.dot(A);e>r&&(r=e,s=t)}let n=i[0],l=-1/0;for(const t of i){if(Math.abs(t.world.dot(s.world))>.6)continue;const e=Math.abs(t.world.dot(o));e>l&&(l=e,n=t)}n.world.dot(o)<0&&(n={local:n.local.clone().multiplyScalar(-1),world:n.world.clone().multiplyScalar(-1)});const a=s.local.clone().normalize(),h=n.local.clone().normalize(),c=a.clone().cross(h).normalize();return{upLocal:a,forwardLocal:c.clone().cross(a).normalize(),rightLocal:c}}resolveFootAxes(t,e,o){const i=this.ikFootAxes?.[t]??this.detectFootAxisBasis(e),s=o??{up:new d,forward:new d,right:new d},r=e.getWorldQuaternion(q);return s.up.copy(i.upLocal).applyQuaternion(r).normalize(),s.forward.copy(i.forwardLocal).applyQuaternion(r).normalize(),s.right.copy(i.rightLocal).applyQuaternion(r).normalize(),s}clampSlopeNormal(t){const e=y.clamp(t.dot(A),-1,1),o=Math.acos(e),i=y.degToRad(this.footIkMaxSlopeAngleDeg);if(o<=i||o<1e-5)return;const s=i/o;t.lerpVectors(A,t,s).normalize()}blendLegAfterSolve(t,e,o){if(!(o>=.999)){if(o<=.001)return t.upper.quaternion.copy(e.upper),t.lower.quaternion.copy(e.lower),void t.foot.quaternion.copy(e.foot);this.blendBoneQuaternion(t.upper,e.upper,o),this.blendBoneQuaternion(t.lower,e.lower,o),this.blendBoneQuaternion(t.foot,e.foot,o)}}blendBoneQuaternion(t,e,o){q.copy(t.quaternion),t.quaternion.copy(e).slerp(q,o)}alignFootToGroundNormal(t,e,o,i){if(o.weight<=.001||null==e.parent)return;const s=this.ikFootAxes?.[t]??this.detectFootAxisBasis(e),r=W.copy(o.normal).normalize(),n=O.copy(o.forward);if(n.addScaledVector(r,-n.dot(r)),n.lengthSq()<1e-8){const o=this.resolveFootAxes(t,e);n.copy(o.forward).addScaledVector(r,-o.forward.dot(r))}if(n.lengthSq()<1e-8)return;n.normalize();const l=V.crossVectors(r,n);if(l.lengthSq()<1e-8)return;l.normalize(),n.copy(C.crossVectors(l,r)).normalize(),U.makeBasis(s.rightLocal,s.upLocal,s.forwardLocal),q.setFromRotationMatrix(U),j.makeBasis(l,r,n),H.setFromRotationMatrix(j);const a=z.copy(H).multiply(N.copy(q).invert()),h=e.parent.getWorldQuaternion(N),c=H.copy(h).invert().multiply(a),d=(1-Math.exp(-this.footIkRotationLerpSpeed*i))*o.weight;e.quaternion.slerp(c,y.clamp(d,0,1))}getMixer(){return this.mixer}beginExternalControl(){this.externalControlActive=!0}endExternalControl(){this.externalControlActive=!1}stopSequenceAnimation(){this.currentFullBodyPriority=-1,this.externalControlActive=!1,null==this.fullBodyAction||this.fullBodyAction.isRunning()||(this.fullBodyAction=null),null==this.upperBodyAction||this.upperBodyAction.isRunning()||(this.upperBodyAction=null),this.fullBodyTimer=0}cancelRootMotionAction(t){null!=t&&this.fullBodyAction!==t||(this.currentFullBodyPriority=-1,this.externalControlActive=!1,this.fullBodyAction?.stop(),this.fullBodyAction=null,this.fullBodyTimer=0)}beginExternalAnimationControl(t,e={}){ot(null!=this.mixer,"Can't begin external control before setup is called"),this.assertClipRigCompatible(t),this.mixer.stopAllAction(),this.currentFullBodyPriority=99,this.fullBodyTimer=0;const o=this.mixer.clipAction(t);return o.setLoop(h,1),o.clampWhenFinished=!0,o.timeScale=e.timeScale??1,o.reset(),o.play(),this.fullBodyAction=o,this.externalControlActive=!0,o}syncMovementSpeed(t){if(null!=t){const e=t.getClip();if(e instanceof i&&e.fixedInPlace&&null!=this.movementSpeed){t.timeScale=e.duration/e.displacement*this.movementSpeed;const o=this.mixer.getRoot();o instanceof a&&(t.timeScale/=o.scale.x)}}}playStateMachine(t){this.stateMachines.push(t)}playUpperStateMachine(t){this.upperStateMachines.push(t)}removeStateMachine(t){const e=this.stateMachines.indexOf(t);e>=0&&this.stateMachines.splice(e,1)}removeUpperStateMachine(t){const e=this.upperStateMachines.indexOf(t);e>=0&&this.upperStateMachines.splice(e,1)}playUpper(t,e={}){this.assertClipRigCompatible(t);const o=e?.priority??1;o<this.currentUpperBodyPriority||(this.currentUpperBodyPriority=o,this.upperBodyAction=this.transition(this.upperBodyAction,this.getUpperBodyClip(t),e),this.upperBodyAction.timeScale=e?.timeScale??1,this.upperBodyTimer=0,this.upperBodyOverride=!0,this.overrideFadeTimeUpper=e.fadeTime)}play(t,e={}){ot(null!=this.mixer,"Can't play animation before setup is called"),this.assertClipRigCompatible(t);const o=e.priority??1;o<this.currentFullBodyPriority||(this.currentFullBodyPriority=o,this.fullBodyTimer=0,this.upperBodyOverride||(this.upperBodyAction=this.transition(this.upperBodyAction,this.getUpperBodyClip(t),e),this.upperBodyAction.timeScale=e?.timeScale??1),this.fullBodyClip=t,this.fullBodyAction=this.transition(this.fullBodyAction,this.getFullBodyClip(t),e),this.fullBodyAction.timeScale=e?.timeScale??1,this.fullBodyAction.getClip().uuid==this.upperBodyAction.getClip().uuid&&this.upperBodyAction.syncWith(this.fullBodyAction),this.overrideFadeTime=e.fadeTime)}assertClipRigCompatible(t){const e=B(t);if(e===this.animationRigId||null==e&&null==this.animationRigId)return;const o=`${t.uuid}|${e??""}|${this.animationRigId??""}`;if(!nt.has(o)){if(nt.add(o),null==e||null==this.animationRigId)return void console.warn(`Animation clip "${t.name}" or its character has no rig assigned. Playing without rig compatibility validation for legacy compatibility.`);console.warn(`Animation clip "${t.name}" targets rig ${e??"no rig"}, but this character uses rig ${this.animationRigId??"no rig"}. Generate and assign a retargeted clip for the character rig.`)}}onActionDone(t){return new Promise(e=>{const o=i=>{i.action===t&&(e(i.action),this.mixer.removeEventListener("finished",o))};this.mixer.addEventListener("finished",o)})}transition(t,e,o={}){const i=o?.fadeTime??this.fadeTime;if(null!=t&&t.getClip().uuid===e.uuid)return!t.isRunning()&&!1===o.loop&&t.clampWhenFinished||t.isRunning()||(t.reset(),null!=o.offset&&(t.time=o.offset),t.enabled=!0,t.weight=1,t.setEffectiveWeight(1),t.setEffectiveTimeScale(1),t.play(),!1===o.loop&&(t.setLoop(h,1),t.clampWhenFinished=!0)),t;if(t&&t.isRunning()){const s=t,r=this.mixer.clipAction(e);r.reset(),null!=o.offset&&(r.time=o.offset),r.play(),r.enabled=!0,r.setEffectiveTimeScale(1),r.weight=1,s.crossFadeTo(r,i,!0),t=r}else(t=this.mixer.clipAction(e)).reset(),null!=o.offset&&(t.time=o.offset),t.enabled=!0,t.weight=1,t.setEffectiveWeight(1),t.setEffectiveTimeScale(1),t.play();return!1===o.loop&&(t.setLoop(h,1),t.clampWhenFinished=!0),t}};Z=t([o({inEditor:!0})],Z);export{Z as CharacterAnimationComponent};function tt(t,e){if(null==t)return e;const o=e.clone();D(o,B(e));const i=new Set(t.map(t=>t.name));return o.tracks=o.tracks.filter(t=>i.has(t.name.split(".")[0])),o}function et(t){return t.flatMap(t=>function(t){const e=[];return t.traverse(t=>{e.push(t)}),e}(t)).filter(t=>t instanceof l)}function ot(t,e){if(!1===t||"function"==typeof t&&!1===t())throw new Error(e)}function it(t,e){const o=new Map;return(i,...s)=>{const r=t(i);return o.has(r)||o.set(r,e(i,...s)),o.get(r)}}function st(t){let e;return t.traverse(t=>{(t instanceof l||t.isBone)&&null==e&&(e=t)}),e}function rt(t,e){let o=e;for(;null!=o;){if(o===t)return!0;o=o.parent}return!1}const nt=new Set;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -0,0 +1,25 @@
1
+ import type { AnimationAction, Vector3 } from "three";
2
+ import type { ActionInput, AxisInput, RotationInput } from "../../../../../gameplay/input/index.js";
3
+ import type { BaseActor } from "../../../actor.js";
4
+ import type { RootMotionActionOptions } from "./old-character-movement.js";
5
+ import type { CharacterMovementMode } from "./modes.js";
6
+ export type CharacterMovementLike = {
7
+ readonly actor: BaseActor;
8
+ readonly directionInput: AxisInput;
9
+ readonly jumpInput: ActionInput;
10
+ readonly sprintInput: ActionInput;
11
+ readonly crouchInput?: ActionInput;
12
+ readonly rotationInput: RotationInput;
13
+ horizontalSpeed: number;
14
+ readonly velocity: Vector3;
15
+ mode: CharacterMovementMode;
16
+ enabled: boolean;
17
+ allowRootMotionJumpCancel: boolean;
18
+ isGrounded: boolean;
19
+ isCrouching?: boolean;
20
+ applyImpulse(impulse: Vector3): void;
21
+ setRootMotionAction(action: AnimationAction, options?: RootMotionActionOptions): void;
22
+ readonly isDefaultCharacterMovementComponent?: boolean;
23
+ };
24
+ export declare function getCharacterMovementLike(actor: BaseActor): CharacterMovementLike | undefined;
25
+ //# sourceMappingURL=character-movement-like.d.ts.map
@@ -0,0 +1,4 @@
1
+ export function getCharacterMovementLike(n){let o;const e=Array.isArray(n.attachedComponents)?n.attachedComponents:[];for(const u of[...Object.values(n),...e])if(t(u)){if(!0===u.isDefaultCharacterMovementComponent)return u;o??(o=u)}return o}function t(t){const n=t;return null!=n&&null!=n.directionInput&&null!=n.jumpInput&&null!=n.sprintInput&&null!=n.rotationInput&&"function"==typeof n.setRootMotionAction&&"function"==typeof n.applyImpulse}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,26 @@
1
+ export interface SprintPolicy {
2
+ /**
3
+ * Advances policy-owned predicted state once per simulated move.
4
+ */
5
+ update?(deltaTime: number, sequence: number, sprintRequested: boolean): void;
6
+ /**
7
+ * Called by movement modes before applying sprint movement.
8
+ * This is evaluated independently during client prediction and server simulation.
9
+ */
10
+ canSprint(): boolean;
11
+ /**
12
+ * Called by a movement mode after it actually applies sprint movement.
13
+ * A move may be simulated and committed in multiple substeps with the same sequence.
14
+ */
15
+ commitSprint(deltaTime: number, sequence: number): void;
16
+ /**
17
+ * Notifies the policy that authoritative movement accepted this sequence.
18
+ * On the server this can publish policy-owned authoritative state to the owner.
19
+ */
20
+ ack?(sequence: number, corrected: boolean): void;
21
+ /**
22
+ * Restores policy-owned predicted state before movement replays saved moves.
23
+ */
24
+ restore?(sequence: number): void;
25
+ }
26
+ //# sourceMappingURL=character-movement-policy.d.ts.map
@@ -0,0 +1,4 @@
1
+ export{};/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -1,23 +1,64 @@
1
- import * as THREE from 'three';
2
- import { AnimationAction, Vector3 } from 'three';
3
- import { ActionInput, AxisInput, RotationInput } from '../../../../../gameplay/input/index.js';
4
- import { ActorComponent } from '../../../component.js';
5
- import { CharacterMovementMode } from './modes.js';
1
+ import * as THREE from "three";
2
+ import { AnimationAction, Vector3 } from "three";
3
+ import { ActionInput, AxisInput, RotationInput } from "../../../../input/index.js";
4
+ import { ActorComponent } from "../../../component.js";
5
+ import { CharacterMovementMode } from "./modes.js";
6
+ import type { RootMotionActionOptions } from "./old-character-movement.js";
7
+ import { type NetCharacterMove } from "./net-character-movement-protocol.js";
8
+ import type { SprintPolicy } from "./character-movement-policy.js";
9
+ export * from "./net-character-movement-protocol.js";
10
+ export type { SprintPolicy } from "./character-movement-policy.js";
11
+ export type NetCharacterMovementModeContext = {
12
+ component: CharacterMovementComponent;
13
+ state: NetCharacterMovementRuntimeState;
14
+ move: NetCharacterMove;
15
+ deltaTime: number;
16
+ rotatedDirection: Vector3;
17
+ platformVelocity: Vector3;
18
+ outVelocity: Vector3;
19
+ rootMotionActive: boolean;
20
+ startedSprinting: boolean;
21
+ };
22
+ export type NetCharacterMovementModeStrategy = {
23
+ mode: CharacterMovementMode;
24
+ update: (context: NetCharacterMovementModeContext) => CharacterMovementMode | void;
25
+ };
26
+ export type NetCharacterMovementRuntimeState = {
27
+ sequence: number;
28
+ position: Vector3;
29
+ velocity: Vector3;
30
+ yaw: number;
31
+ lookYaw: number;
32
+ mode: CharacterMovementMode;
33
+ grounded: boolean;
34
+ currentSpeed: number;
35
+ fallGraceTime: number;
36
+ prevInputDirection: Vector3;
37
+ prevRotateToMovementDirection: boolean;
38
+ };
6
39
  export declare class CharacterMovementComponent extends ActorComponent {
40
+ readonly isDefaultCharacterMovementComponent = true;
7
41
  readonly directionInput: AxisInput;
8
42
  readonly jumpInput: ActionInput;
9
43
  readonly sprintInput: ActionInput;
44
+ readonly crouchInput: ActionInput;
10
45
  readonly rotationInput: RotationInput;
11
46
  horizontalSpeed: number;
12
47
  maxSpeed: number;
13
48
  maxSpeedBackwards: number;
14
49
  maxSpeedSprint: number;
50
+ maxSpeedCrouch: number;
51
+ sprintStartBoostSpeed: number;
52
+ sprintStartBoostDamping: number;
15
53
  jumpVelocity: number;
16
54
  fallingMovementControl: number;
17
55
  fallingReorientation: boolean;
56
+ groundAccelerationRate: number;
18
57
  gravityOverride: number;
19
58
  colliderHeight: number;
20
59
  colliderRadius: number;
60
+ crouchColliderHeight: number;
61
+ crouchColliderRadius: number;
21
62
  jumpInAir: boolean;
22
63
  mass: number;
23
64
  allowSliding: boolean;
@@ -25,9 +66,44 @@ export declare class CharacterMovementComponent extends ActorComponent {
25
66
  maxSlopeClimbAngle: number;
26
67
  applyImpulsesToDynamicBodies: boolean;
27
68
  normalizedDirection: boolean;
28
- /** Collide with other characters */
29
69
  characterCollision: boolean;
30
70
  allowRootMotionJumpCancel: boolean;
71
+ enabled: boolean;
72
+ rotateToMovementDirection: boolean;
73
+ smoothRotation: boolean;
74
+ rotationSpeed: number;
75
+ maxRotationSpeed: number;
76
+ impulseDamping: number;
77
+ moveSendInterval: number;
78
+ simulatedStateInterval: number;
79
+ maxSavedMoves: number;
80
+ maxReplayedMoves: number;
81
+ maxServerMovesPerTick: number;
82
+ maxMovesPerPacket: number;
83
+ maxMoveDeltaTime: number;
84
+ maxCombinedMoveDeltaTime: number;
85
+ maxServerMoveDeltaTimeScalar: number;
86
+ maxClientTimeAhead: number;
87
+ maxServerMoveTimeBudget: number;
88
+ maxSubstepDeltaTime: number;
89
+ fallGraceTime: number;
90
+ correctionToleranceSq: number;
91
+ largeCorrectionThreshold: number;
92
+ teleportSnapThreshold: number;
93
+ listenServerSmoothing: boolean;
94
+ listenServerSmoothLocationTime: number;
95
+ listenServerMaxSmoothUpdateDistance: number;
96
+ listenServerNoSmoothUpdateDistance: number;
97
+ sprintPolicy?: SprintPolicy;
98
+ debugCorrections: boolean;
99
+ private correctionDebug?;
100
+ private suppressUncrouchLift;
101
+ readonly velocity: THREE.Vector3;
102
+ readonly visualSmoothingOffset: THREE.Vector3;
103
+ mode: CharacterMovementMode;
104
+ isSprinting: boolean;
105
+ isCrouching: boolean;
106
+ pressedJump: boolean;
31
107
  get autoStepMinWidth(): number;
32
108
  set autoStepMinWidth(minWidth: number);
33
109
  get autoStepDynamicObjects(): boolean;
@@ -40,61 +116,88 @@ export declare class CharacterMovementComponent extends ActorComponent {
40
116
  get offset(): number;
41
117
  set normalNudgeFactor(factor: number);
42
118
  get normalNudgeFactor(): number;
43
- /**
44
- * Flag for if it should be moving the character.
45
- * Can be useful to turn of if under certain circumstances the all
46
- * inputs should be ignored.
47
- */
48
- enabled: boolean;
49
- readonly velocity: THREE.Vector3;
50
- mode: CharacterMovementMode;
51
- isSprinting: boolean;
52
- pressedJump: boolean;
53
- private cc;
54
- private rayTestResult;
55
- private physicsSystem;
56
- constructor();
57
- private resetRootMotion;
119
+ private readonly cc;
120
+ private readonly rayTestResult;
121
+ private readonly physicsSystem;
122
+ private readonly netService;
123
+ private readonly state;
124
+ private readonly movementModes;
125
+ private readonly savedMoves;
126
+ private readonly serverMoveTiming;
127
+ private readonly serverMoveQueue;
128
+ private readonly inputMoveScratch;
129
+ private readonly authoritativeMoveScratch;
130
+ private readonly movementModeContext;
131
+ private readonly proxySmoother;
132
+ private readonly proxySample;
133
+ private readonly pendingSnapshot;
134
+ private readonly impulse;
135
+ private readonly prevRootMotionPos;
136
+ private rootMotionAction;
58
137
  private rootMotionInterpolant;
59
138
  private rootMotionRootBone;
60
139
  private rootMotionOptions;
61
- /**
62
- * Makes the character rotate to the direction of movement input instead
63
- * of strafing or walking backwards
64
- */
65
- rotateToMovementDirection: boolean;
66
- /** Makes the character rotate smoothly to the desired direction */
67
- smoothRotation: boolean;
68
- rotationSpeed: number;
69
- maxRotationSpeed: number;
70
- private impulse;
71
- /**
72
- * The damping factor used to slow down impulses over time
73
- */
74
- impulseDamping: number;
75
- onInit(): void | Promise<void>;
76
- /**
77
- * Add an instant velocity to the character which can be used to
78
- * launch the character or push it.
79
- * @param impulse
80
- */
140
+ private resetRootMotion;
141
+ private nextMoveSequence;
142
+ private clientMoveTime;
143
+ private lastSentClientMoveTime;
144
+ private moveSendAccumulator;
145
+ private simulatedStateAccumulator;
146
+ private proxyTime;
147
+ private lastServerProcessedSequence;
148
+ private lastServerReceivedSequence;
149
+ private lastAutonomousMoveFlags;
150
+ private previousSprintInput;
151
+ private initialized;
152
+ constructor();
153
+ onInit(): void;
154
+ onLateUpdate(deltaTime: number): void;
155
+ registerMovementMode(strategy: NetCharacterMovementModeStrategy): void;
81
156
  applyImpulse(impulse: Vector3): void;
82
- private debugDirection;
83
- private rootMotionAction;
84
- setRootMotionAction(action: AnimationAction, options?: RootMotionActionOptions): void;
85
- private clearRootMotionAction;
86
- private getWallDirection;
87
- private moveTo;
88
157
  getEffectiveGravity(): number;
89
- private checkGrounded;
90
158
  get isGrounded(): boolean;
159
+ setRootMotionAction(action: AnimationAction, options?: RootMotionActionOptions): void;
160
+ serverMove(payload: Uint8Array): void;
161
+ clientMoveAck(payload: Uint8Array): void;
162
+ clientMoveCorrection(payload: Uint8Array): void;
163
+ simulatedState(payload: Uint8Array): void;
164
+ private tick;
165
+ private tickAutonomousProxy;
166
+ private tickAuthority;
167
+ private tickRemoteAuthority;
168
+ private tickSimulatedProxy;
169
+ private accumulateListenServerVisualSmoothing;
170
+ private updateVisualSmoothing;
171
+ private shouldSmoothListenServerRemoteAuthority;
172
+ private createMoveFromInput;
173
+ private performMove;
174
+ private performSubstep;
175
+ private updateRotation;
176
+ private applyMovement;
177
+ private updateModeAfterMove;
178
+ private applyImpulseToVelocity;
179
+ private sendSavedMoves;
180
+ private sendOwnerCorrection;
181
+ private sendSimulatedState;
182
+ private applyCorrection;
183
+ private applySnapshot;
184
+ private toSnapshot;
185
+ private syncPublicState;
186
+ private sampleRootMotion;
187
+ private clearRootMotionAction;
188
+ private isRemoteControlledAuthority;
189
+ private configureCharacterController;
190
+ private initializeStateFromActor;
91
191
  private createCollisionShape;
92
- private step;
93
- private performMovement;
94
- private arrowHelper;
192
+ private updateCrouchState;
193
+ private setCrouching;
194
+ private canUncrouch;
195
+ private syncColliderShape;
196
+ private getColliderHeight;
197
+ private getColliderRadius;
198
+ private getCapsuleOffsetY;
199
+ private checkGrounded;
200
+ private resolvePlatformVelocity;
201
+ private getCollisionGroup;
95
202
  }
96
- export type RootMotionActionOptions = {
97
- cancelWithJump?: boolean;
98
- onJumpCancel?: () => void;
99
- };
100
203
  //# sourceMappingURL=character-movement.d.ts.map
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as o}from"tslib";import i from"@dimforge/rapier3d-simd-compat";import{takeUntil as e}from"rxjs";import*as s from"three";import{ArrowHelper as n,MathUtils as r,Vector3 as a}from"three";import{RootMotionClip as c}from"../../../../../gameplay/animation/root-motion.js";import{ActionInput as h,AxisInput as l,RotationInput as p}from"../../../../../gameplay/input/index.js";import{PhysicsSystem as m,RayTestResult as u}from"../../../../../gameplay/services/physics/physics-system.js";import{CapsuleCollisionShape as d}from"../../../../../scene/collision/collision-shape.js";import{PhysicsBodyType as y}from"../../../../services/physics/physics-system.js";import{ActorComponent as g,Component as f}from"../../../component.js";import{CharacterMovementMode as M}from"./modes.js";import{inject as S}from"../../../../../gameplay/inject.js";import{Parameter as v}from"../../../../../shader/parameter.js";const w=new a,x=new a,A=1/30,b=131070;let I=class extends g{get autoStepMinWidth(){return this.cc.autostepMinWidth()}set autoStepMinWidth(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),t,this.cc.autostepIncludesDynamicBodies())}get autoStepDynamicObjects(){return this.cc.autostepIncludesDynamicBodies()}set autoStepDynamicObjects(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),this.cc.autostepMinWidth(),t)}get autoStepMaxHeight(){return this.cc.autostepMaxHeight()}set autoStepMaxHeight(t){this.cc.enableAutostep(t,this.cc.autostepMinWidth(),this.cc.autostepIncludesDynamicBodies())}get snapToGround(){return this.cc.snapToGroundDistance()}set snapToGround(t){this.cc.enableSnapToGround(t)}set offset(t){this.cc.setOffset(t)}get offset(){return this.cc.offset()}set normalNudgeFactor(t){this.cc.setNormalNudgeFactor(t)}get normalNudgeFactor(){return this.cc.normalNudgeFactor()}constructor(){super(),this.directionInput=new l,this.jumpInput=new h,this.sprintInput=new h,this.rotationInput=new p,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.jumpVelocity=7,this.fallingMovementControl=.5,this.fallingReorientation=!1,this.gravityOverride=null,this.colliderHeight=2,this.colliderRadius=.5,this.jumpInAir=!1,this.mass=50,this.allowSliding=!0,this.minSlopeSlideAngle=r.degToRad(70),this.maxSlopeClimbAngle=r.degToRad(70),this.applyImpulsesToDynamicBodies=!0,this.normalizedDirection=!0,this.characterCollision=!1,this.allowRootMotionJumpCancel=!1,this.enabled=!0,this.velocity=new a,this.mode=M.walking,this.isSprinting=!1,this.pressedJump=!1,this.rayTestResult=new u,this.physicsSystem=S(m),this.resetRootMotion=!1,this.rootMotionOptions={},this.rotateToMovementDirection=!1,this.smoothRotation=!0,this.rotationSpeed=40,this.maxRotationSpeed=100,this.impulse=new a,this.impulseDamping=2;const t=this.cc=this.physicsSystem.getCharacterController(.1);t.enableSnapToGround(.1),t.enableAutostep(0,.1,!1)}onInit(){const t=this.cc;t.setApplyImpulsesToDynamicBodies(this.applyImpulsesToDynamicBodies),t.setMinSlopeSlideAngle(this.minSlopeSlideAngle),t.setMaxSlopeClimbAngle(this.maxSlopeClimbAngle),t.setCharacterMass(this.mass),t.setSlideEnabled(this.allowSliding),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:y.kinematic,continousCollisionDetection:!1,friction:0,restitution:.5,ignoreForNavMesh:!0}),this.rotationInput.rotation.copy(this.actor.rotation);let o=this.rotationInput.rotation.y;const i=new a,n=new a,h=new a,l=new a,p=new a,m=new a,u=new a;let d=0,g=null;const f=new a,S=new a,v=new a,I=new a,R=new a,z=new a,C=new a,D=this.characterCollision?null:b;let E=this.rotateToMovementDirection;this.physicsSystem.beforeStep.pipe(e(this.disposed)).subscribe(e=>{if(this.checkGrounded(e),!this.enabled)return;if(S.set(0,0,0),null==this.rootMotionAction||this.rootMotionAction.isRunning()||this.clearRootMotionAction(this.rootMotionAction),null!=this.rootMotionAction&&this.rootMotionOptions.cancelWithJump&&this.jumpInput.activated&&(this.isGrounded||this.jumpInAir)){const t=this.rootMotionAction,o=this.rootMotionOptions.onJumpCancel;this.clearRootMotionAction(t),t.stop(),o?.()}if(null!=this.rootMotionAction){if(this.rootMotionAction.getClip()instanceof c){const t=this.rootMotionInterpolant;this.resetRootMotion&&(f.fromArray(t.evaluate(0)),this.resetRootMotion=!1),z.fromArray(t.evaluate(this.rootMotionAction.time)),S.subVectors(z,f),f.copy(z);(this.rootMotionRootBone??this.rootMotionAction.getRoot()).getWorldScale(R),S.multiply(R)}}e>A&&(e=A);const y=null!=this.rootMotionAction&&this.rootMotionAction.enabled,b=y&&0!==S.lengthSq();this.pressedJump=!y&&this.jumpInput.activated,this.isSprinting=!y&&this.sprintInput.activated;const H=E!==this.rotateToMovementDirection;let B=r.euclideanModulo(this.rotationInput.rotation.y-o+Math.PI,2*Math.PI)-Math.PI;H&&(this.actor.object.quaternion.setFromEuler(F.set(0,this.rotationInput.rotation.y,0)),E?this.actor.object.quaternion.setFromEuler(F.set(0,this.rotationInput.rotation.y,0)):(B=0,o=this.rotationInput.rotation.y),E=this.rotateToMovementDirection),h.copy(this.actor.position),l.set(-this.directionInput.vector.x,0,this.directionInput.vector.y).normalize();const N=!this.rotateToMovementDirection&&l.z<0?this.maxSpeedBackwards:(this.isSprinting?this.maxSpeedSprint:this.maxSpeed)*(this.normalizedDirection?1:Math.min(1,this.directionInput.vector.length()));if(u.set(0,0,0),y)o=this.rotationInput.rotation.y;else if(this.rotateToMovementDirection&&!y){if(l.lengthSq()>0&&this.mode!=M.falling){const t=this.smoothRotation,i=F.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,s=Math.atan2(l.x,l.z),n=.99*this.rotationInput.rotation.y+s;if(t){r.clamp(.5*l.dot(p)+.5,.001,1);const t=r.euclideanModulo(n-i+Math.PI,2*Math.PI)-Math.PI;let o=r.clamp(t*this.rotationSpeed*e,-this.maxRotationSpeed*e,this.maxRotationSpeed*e);Math.abs(o)>Math.abs(t)&&(o=t),this.actor.object.quaternion.setFromEuler(F.set(0,i+o,0))}else this.actor.object.quaternion.setFromEuler(F.set(0,n,0));p.lerp(l,e*this.rotationSpeed),o+=B,u.copy(this.actor.object.getWorldDirection(k).normalize())}}else b||(o+=B,this.actor.object.quaternion.multiply(q.setFromEuler(F.set(0,B,0))),l.lengthSq()>0&&u.copy(l).applyQuaternion(this.actor.object.quaternion).normalize());if(C.set(0,0,0),this.rayTestResult.hasHit&&null!=this.rayTestResult.actor&&this.physicsSystem.getLinearVelocity(this.rayTestResult.actor,C),this.mode===M.walking?(0!==u.lengthSq()?(d=Math.min(N,d),d=r.lerp(d,N,4*e)):d=0,m.copy(u).multiplyScalar(d),this.pressedJump&&(this.mode=M.falling,this.velocity.copy(m),this.velocity.y=this.jumpVelocity),m.y=e*this.getEffectiveGravity(),m.add(C)):this.mode===M.falling&&(this.pressedJump&&this.jumpInAir&&(this.mode=M.falling,this.velocity.copy(m),this.velocity.y=this.jumpVelocity),this.velocity.y+=e*this.getEffectiveGravity(),m.copy(this.velocity),m.addScaledVector(u,this.fallingMovementControl),this.fallingReorientation&&m.applyAxisAngle(new a(0,1,0),B)),b&&(v.copy(S).applyQuaternion(this.actor.quaternion),I.copy(v).divideScalar(e),this.mode===M.walking?(m.x=I.x+C.x,m.z=I.z+C.z):(m.x=I.x,m.z=I.z),l.lengthSq()>0)){const t=Math.sqrt(I.x*I.x+I.z*I.z);t>.4&&(d=t)}if(this.impulse.lengthSq()>.1){const t=Math.min(1,this.impulse.length()/5);m.x=r.lerp(m.x,this.impulse.x,t),m.z=r.lerp(m.z,this.impulse.z,t),m.y+=this.impulse.y;const o=Math.exp(-this.impulseDamping*e);this.impulse.x*=o,this.impulse.y>0?this.impulse.y+=e*this.getEffectiveGravity():this.impulse.y*=o,this.impulse.z*=o}else this.impulse.set(0,0,0);if(n.copy(m).normalize(),i.copy(m),m.length()>0||!this.isGrounded){if(w.copy(m).multiplyScalar(e),this.isGrounded&&this.mode===M.walking&&(this.rayTestResult.distance>t.offset()||(w.y=Math.max(0,C.y*e)),this.physicsSystem.getActorComputedMovement(this.actor,t,w,D),t.computedCollision(0,G),null!=G&&null!=G.normal1)){const o=(new s.Vector3).copy(G.normal1);Math.acos(o.dot(T))>t.maxSlopeClimbAngle()&&(w.y=.016*this.getEffectiveGravity()*.5)}x.copy(this.physicsSystem.getActorComputedMovement(this.actor,t,w,D))}else x.set(0,0,0);this.physicsSystem.setNextKinematicTranslation(this.actor,x);let O=function(t){if(t.numComputedCollisions()>0){const o=t.computedCollision(0);j.x=o.normal2.x,j.y=o.normal2.y,j.z=o.normal2.z;const i=j.angleTo(T);j.x=o.normal1.x,j.y=o.normal1.y,j.z=o.normal1.z;const e=j.angleTo(T);return!(i<100)&&e>t.minSlopeSlideAngle()}return!1}(t);this.isGrounded&&!O||this.mode!==M.falling&&(null==g?g=performance.now():performance.now()-g>100&&(this.mode=M.falling,this.velocity.copy(i))),this.isGrounded&&this.velocity.y<=0&&(this.mode,M.falling,this.mode=M.walking,this.velocity.y=0,g=null),this.mode,M.walking,this.horizontalSpeed=d})}applyImpulse(t){this.impulse.add(t)}debugDirection(){const t=new n(w,this.actor.position,1,65280);this.actor.object.parent.add(t),setTimeout(()=>{t.removeFromParent()},30);const o=new n(x,this.actor.position,1,16711680);this.actor.object.parent.add(o),setTimeout(()=>{o.removeFromParent()},30)}setRootMotionAction(t,o={}){const i=t?.getClip();if(i instanceof c){this.rootMotionAction=t,this.rootMotionOptions=o,this.resetRootMotion=!0;const e=[];this.rootMotionInterpolant=i.motionTrack.InterpolantFactoryMethodSmooth(e);const n=s.PropertyBinding.parseTrackName(i.motionTrack.name);this.rootMotionRootBone=this.actor.object.getObjectByName(n.nodeName)}}clearRootMotionAction(t){null!=t&&this.rootMotionAction!==t||(this.rootMotionAction=null,this.rootMotionOptions={},this.resetRootMotion=!1)}getWallDirection(t,o){const i=t.clone().negate().cross(T);return i.dot(o)<0?i.negate():i}moveTo(t){this.actor.position.copy(t),this.physicsSystem.updateActorTransform(this.actor)}getEffectiveGravity(){return this.gravityOverride??this.physicsSystem.getGravity().y}checkGrounded(t){this.colliderHeight,this.colliderRadius;D.y=-.05,this.physicsSystem.rayTest(R.addVectors(this.actor.position,C.set(0,this.offset,0)),z.addVectors(this.actor.position,D),this.rayTestResult,{excludeActor:this.actor,excludeTriggers:!0})}get isGrounded(){return this.rayTestResult.hasHit||this.cc.computedGrounded()}createCollisionShape(){const t=new d(this.colliderHeight,this.colliderRadius);return t.offset.y=this.colliderRadius+this.colliderHeight/2+this.offset,t.collisionGroup=b,t}step(t){}performMovement(t){}arrowHelper(t,o,i){const e=new n(t.clone().normalize(),o,1,i);this.actor.object.parent.add(e),setTimeout(()=>{e.removeFromParent()},30)}};t([v(),o("design:type",Number)],I.prototype,"colliderHeight",void 0),t([v(),o("design:type",Number)],I.prototype,"colliderRadius",void 0),I=t([f({inEditor:!1}),o("design:paramtypes",[])],I);export{I as CharacterMovementComponent};const T=new a(0,1,0),j=new a;const R=new a,z=new a,C=new a(0,1,0),D=new a(0,-.1,0),G=(new a(0,-1,0),new i.CharacterCollision),q=new s.Quaternion,F=new s.Euler,k=new s.Vector3;/*
1
+ import{__decorate as t,__metadata as e}from"tslib";import i from"@dimforge/rapier3d-simd-compat";import{takeUntil as o}from"rxjs";import*as s from"three";import{ArrowHelper as n,MathUtils as r,Quaternion as a,Vector3 as h}from"three";import{RootMotionClip as c}from"../../../../animation/root-motion.js";import{inject as l}from"../../../../inject.js";import{ActionInput as u,AxisInput as p,RotationInput as m}from"../../../../input/index.js";import{NetRole as d}from"../../../../net/service/net-actor-role.js";import{RunOnClient as v,RunOnNotOwner as y,RunOnServer as S}from"../../../../net/service/rpc-decorator.js";import{NetService as M}from"../../../../net/service/net-service.js";import{PhysicsSystem as g,RayTestResult as f}from"../../../../services/physics/physics-system.js";import{CapsuleCollisionShape as x}from"../../../../../scene/collision/collision-shape.js";import{Parameter as T}from"../../../../../shader/parameter.js";import{PhysicsBodyType as C}from"../../../../services/physics/physics-system.js";import{ActorComponent as w,Component as A}from"../../../component.js";import{CharacterMovementMode as R}from"./modes.js";import{DEFAULT_MAX_CLIENT_TIME_AHEAD as D,DEFAULT_LARGE_CORRECTION_THRESHOLD as q,DEFAULT_MAX_COMBINED_MOVE_DELTA_TIME as b,DEFAULT_MAX_MOVE_DELTA_TIME as k,DEFAULT_MAX_MOVES_PER_PACKET as P,DEFAULT_MAX_REPLAYED_MOVES as I,DEFAULT_MAX_SERVER_MOVES_PER_TICK as z,DEFAULT_MAX_SAVED_MOVES as j,DEFAULT_MAX_SERVER_MOVE_DELTA_TIME_SCALAR as Y,DEFAULT_MAX_SERVER_MOVE_TIME_BUDGET as F,DEFAULT_MAX_SUBSTEP_DELTA_TIME as G,DEFAULT_MOVE_SEND_INTERVAL as O,DEFAULT_SIMULATED_INTERPOLATION_DELAY as V,DEFAULT_SIMULATED_STATE_INTERVAL as X,DEFAULT_SMALL_CORRECTION_TOLERANCE as B,DEFAULT_TELEPORT_SNAP_THRESHOLD as N,MOVE_FLAG_CROUCH as H,MOVE_FLAG_JUMP as Z,MOVE_FLAG_ROOT_MOTION as U,MOVE_FLAG_SPRINT as L,MOVE_FLAG_SPRINT_START as E,SNAPSHOT_FLAG_CROUCHING as $,NetCharacterProxySmoother as Q,NetCharacterSavedMoveBuffer as W,accrueNetCharacterServerMoveTime as J,createNetCharacterMovementSnapshot as K,createNetCharacterServerMoveTimingState as _,consumeNetCharacterServerMoveTime as tt,decodeNetCharacterMoveBatch as et,decodeNetCharacterOwnerAck as it,decodeNetCharacterOwnerCorrection as ot,decodeNetCharacterSimulatedState as st,encodeNetCharacterMoveBatch as nt,encodeNetCharacterOwnerAck as rt,encodeNetCharacterOwnerCorrection as at,encodeNetCharacterSimulatedState as ht,validateNetCharacterMove as ct}from"./net-character-movement-protocol.js";import{NetMode as lt}from"../../../../net/net-session.js";export*from"./net-character-movement-protocol.js";const ut=131070,pt=new h(0,1,0),mt=new h,dt=new h,vt=new h,yt=new h,St=new h,Mt=new h,gt=new h,ft=new h,xt=new h,Tt=new h,Ct=new h,wt=new h,At=new h,Rt=new h,Dt=new h(0,1,0),qt=new h(0,-.05,0),bt=new h,kt=new a,Pt=new s.Euler,It=new h,zt=new h,jt=new h,Yt=new i.CharacterCollision;let Ft=class extends w{get autoStepMinWidth(){return this.cc.autostepMinWidth()}set autoStepMinWidth(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),t,this.cc.autostepIncludesDynamicBodies())}get autoStepDynamicObjects(){return this.cc.autostepIncludesDynamicBodies()}set autoStepDynamicObjects(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),this.cc.autostepMinWidth(),t)}get autoStepMaxHeight(){return this.cc.autostepMaxHeight()}set autoStepMaxHeight(t){this.cc.enableAutostep(t,this.cc.autostepMinWidth(),this.cc.autostepIncludesDynamicBodies())}get snapToGround(){return this.cc.snapToGroundDistance()}set snapToGround(t){this.cc.enableSnapToGround(t)}set offset(t){this.cc.setOffset(t)}get offset(){return this.cc.offset()}set normalNudgeFactor(t){this.cc.setNormalNudgeFactor(t)}get normalNudgeFactor(){return this.cc.normalNudgeFactor()}constructor(){super(),this.isDefaultCharacterMovementComponent=!0,this.directionInput=new p,this.jumpInput=new u,this.sprintInput=new u,this.crouchInput=new u,this.rotationInput=new m,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.maxSpeedCrouch=4,this.sprintStartBoostSpeed=0,this.sprintStartBoostDamping=6,this.jumpVelocity=7,this.fallingMovementControl=.5,this.fallingReorientation=!1,this.groundAccelerationRate=4,this.gravityOverride=null,this.colliderHeight=2,this.colliderRadius=.5,this.crouchColliderHeight=1,this.crouchColliderRadius=null,this.jumpInAir=!1,this.mass=50,this.allowSliding=!0,this.minSlopeSlideAngle=r.degToRad(70),this.maxSlopeClimbAngle=r.degToRad(70),this.applyImpulsesToDynamicBodies=!0,this.normalizedDirection=!0,this.characterCollision=!1,this.allowRootMotionJumpCancel=!1,this.enabled=!0,this.rotateToMovementDirection=!1,this.smoothRotation=!0,this.rotationSpeed=40,this.maxRotationSpeed=100,this.impulseDamping=2,this.moveSendInterval=O,this.simulatedStateInterval=X,this.maxSavedMoves=j,this.maxReplayedMoves=I,this.maxServerMovesPerTick=z,this.maxMovesPerPacket=P,this.maxMoveDeltaTime=k,this.maxCombinedMoveDeltaTime=b,this.maxServerMoveDeltaTimeScalar=Y,this.maxClientTimeAhead=D,this.maxServerMoveTimeBudget=F,this.maxSubstepDeltaTime=G,this.fallGraceTime=.1,this.correctionToleranceSq=B*B,this.largeCorrectionThreshold=q,this.teleportSnapThreshold=N,this.listenServerSmoothing=!0,this.listenServerSmoothLocationTime=.04,this.listenServerMaxSmoothUpdateDistance=1,this.listenServerNoSmoothUpdateDistance=2.5,this.debugCorrections=!0,this.suppressUncrouchLift=!1,this.velocity=new h,this.visualSmoothingOffset=new h,this.mode=R.walking,this.isSprinting=!1,this.isCrouching=!1,this.pressedJump=!1,this.rayTestResult=new f,this.physicsSystem=l(g),this.netService=l(M),this.state={sequence:0,position:new h,velocity:new h,yaw:0,lookYaw:0,mode:R.walking,grounded:!1,currentSpeed:0,fallGraceTime:0,prevInputDirection:new h,prevRotateToMovementDirection:!1},this.movementModes=new Map,this.savedMoves=new W(j),this.serverMoveTiming=_(),this.serverMoveQueue=[],this.inputMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.authoritativeMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.movementModeContext={component:this,state:this.state,move:this.inputMoveScratch,deltaTime:0,rotatedDirection:dt,platformVelocity:yt,outVelocity:vt,rootMotionActive:!1,startedSprinting:!1},this.proxySmoother=new Q(V,N),this.proxySample=K(),this.pendingSnapshot=K(),this.impulse=new h,this.prevRootMotionPos=new h,this.rootMotionOptions={},this.resetRootMotion=!1,this.nextMoveSequence=0,this.clientMoveTime=0,this.lastSentClientMoveTime=0,this.moveSendAccumulator=0,this.simulatedStateAccumulator=0,this.proxyTime=0,this.lastServerProcessedSequence=0,this.lastServerReceivedSequence=0,this.lastAutonomousMoveFlags=0,this.previousSprintInput=!1,this.initialized=!1,this.cc=this.physicsSystem.getCharacterController(.1),this.cc.enableSnapToGround(.1),this.cc.enableAutostep(0,.1,!1),this.registerMovementMode(Gt),this.registerMovementMode(Ot)}onInit(){this.configureCharacterController(),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:C.kinematic,continousCollisionDetection:!1,friction:0,restitution:.5,ignoreForNavMesh:!0}),this.rotationInput.rotation.copy(this.actor.rotation),this.initializeStateFromActor(),this.initialized=!0,this.physicsSystem.beforeStep.pipe(o(this.disposed)).subscribe(t=>this.tick(t))}onLateUpdate(t){this.updateVisualSmoothing(t)}registerMovementMode(t){this.movementModes.set(t.mode,t)}applyImpulse(t){this.impulse.add(t)}getEffectiveGravity(){return this.gravityOverride??this.physicsSystem.getGravity().y}get isGrounded(){return this.rayTestResult.hasHit||this.cc.computedGrounded()}setRootMotionAction(t,e={}){const i=t?.getClip();if(i instanceof c){this.rootMotionAction=t,this.rootMotionOptions=e,this.resetRootMotion=!0;const o=[];this.rootMotionInterpolant=i.motionTrack.InterpolantFactoryMethodSmooth(o);const n=s.PropertyBinding.parseTrackName(i.motionTrack.name);this.rootMotionRootBone=this.actor.object.getObjectByName(n.nodeName)}}serverMove(t){const e=et(t);if(e.ok)for(const t of e.value.moves)ct(t,this.lastServerReceivedSequence,this.maxMoveDeltaTime)&&(this.lastServerReceivedSequence=t.sequence,this.serverMoveQueue.push(t))}clientMoveAck(t){const e=it(t);e.ok&&this.actor.netRole===d.autonomousProxy&&(this.savedMoves.ack(e.value.sequence),this.sprintPolicy?.ack?.(e.value.sequence,!1))}clientMoveCorrection(t){const e=ot(t);e.ok&&this.actor.netRole===d.autonomousProxy&&(this.debugCorrections&&(null==this.correctionDebug&&(this.correctionDebug=new Bt(Ht(this.actor.object))),this.correctionDebug.update(this.state.position,e.value.snapshot)),this.applyCorrection(e.value.snapshot))}simulatedState(t){const e=st(t);e.ok&&this.actor.netRole===d.simulatedProxy&&this.proxySmoother.push(e.value,this.proxyTime)}tick(t){if(!this.initialized)return;t=Math.min(.1,t);const e=this.actor.netRole,i=this.netService.mode;e!==d.simulatedProxy?this.enabled&&(e!==d.autonomousProxy?this.isRemoteControlledAuthority(i,e)?this.tickRemoteAuthority(t):this.tickAuthority(t,i):this.tickAutonomousProxy(t)):this.tickSimulatedProxy(t)}tickAutonomousProxy(t){const e=this.state.mode,i=this.lastAutonomousMoveFlags,o=this.createMoveFromInput(t,++this.nextMoveSequence,{quantizeClientTime:!0});this.performMove(o,Zt);const s=this.state.mode!==e||o.flags!==i;this.lastAutonomousMoveFlags=o.flags,this.savedMoves.capacity=this.maxSavedMoves,this.savedMoves.maxCombinedDeltaTime=Math.min(this.maxCombinedMoveDeltaTime,this.maxMoveDeltaTime),this.savedMoves.push(o),this.sendSavedMoves(t,s)}tickAuthority(t,e){const i=this.createMoveFromInput(t,++this.nextMoveSequence);this.performMove(i,Zt),e!==lt.none&&this.sendSimulatedState(t,!1)}tickRemoteAuthority(t){J(this.serverMoveTiming,t,this.maxServerMoveTimeBudget);let e=!1;const i=Number.isFinite(this.maxServerMovesPerTick)?Math.max(1,Math.floor(this.maxServerMovesPerTick)):this.serverMoveQueue.length,o=Math.min(this.serverMoveQueue.length,i),s=zt.copy(this.actor.position);let n=!1;for(let t=0;t<o;t++){const t=this.serverMoveQueue.shift();if(null==t)break;if(!ct(t,this.lastServerProcessedSequence,this.maxMoveDeltaTime)){console.log("Net: Invalid move",t),this.sendOwnerCorrection(!0),e=!0;continue}const i=tt(this.serverMoveTiming,t,{maxMoveDeltaTime:this.maxMoveDeltaTime,maxServerMoveDeltaTimeScalar:this.maxServerMoveDeltaTimeScalar,maxClientTimeAhead:this.maxClientTimeAhead});if(i<0){this.sendOwnerCorrection(!0),e=!0;continue}const o=Vt(t,this.authoritativeMoveScratch);o.dt=i,o.rootMotionX=0,o.rootMotionY=0,o.rootMotionZ=0,o.flags&=~U,this.performMove(o,{immediate:!0,savedRootMotion:!1}),n=!0,this.lastServerProcessedSequence=o.sequence;const s=Xt(this.state,t);if(s>this.correctionToleranceSq){console.log(`Net server: Correction error: ${Math.sqrt(s)}`);const o=this.state.position.x-t.clientX,n=this.state.position.y-t.clientY,r=this.state.position.z-t.clientZ;console.log(`diff x: ${o}, y: ${n}, z: ${r}`),console.log({sequence:t.sequence,moveDt:t.dt,serverMoveDeltaTime:i,flags:t.flags,mode:this.state.mode,grounded:this.state.grounded,fallGraceTime:this.state.fallGraceTime}),this.sendOwnerCorrection(s>this.largeCorrectionThreshold*this.largeCorrectionThreshold),e=!0}}0===this.lastServerProcessedSequence||e||(this.sprintPolicy?.ack?.(this.lastServerProcessedSequence,!1),this.clientMoveAck(rt(this.lastServerProcessedSequence))),n&&this.accumulateListenServerVisualSmoothing(s,this.actor.position),this.sendSimulatedState(t,!1)}tickSimulatedProxy(t){this.proxyTime+=t,this.proxySmoother.sample(this.proxyTime,this.proxySample)&&this.applySnapshot(this.proxySample,!0)}accumulateListenServerVisualSmoothing(t,e){if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);jt.subVectors(t,e);const i=jt.lengthSq();i>1e-8&&(i>this.listenServerNoSmoothUpdateDistance*this.listenServerNoSmoothUpdateDistance?this.visualSmoothingOffset.set(0,0,0):(i>this.listenServerMaxSmoothUpdateDistance*this.listenServerMaxSmoothUpdateDistance&&jt.setLength(this.listenServerMaxSmoothUpdateDistance),this.visualSmoothingOffset.add(jt)))}updateVisualSmoothing(t){if(this.visualSmoothingOffset.lengthSq()<=1e-8)return void this.visualSmoothingOffset.set(0,0,0);if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);const e=Math.max(.001,this.listenServerSmoothLocationTime);t<e?this.visualSmoothingOffset.multiplyScalar(1-t/e):this.visualSmoothingOffset.set(0,0,0),this.visualSmoothingOffset.lengthSq()<=1e-4&&this.visualSmoothingOffset.set(0,0,0)}shouldSmoothListenServerRemoteAuthority(){return this.listenServerSmoothing&&this.actor.netRole===d.authority&&this.netService.isServer&&!this.netService.isDedicatedServer&&this.isRemoteControlledAuthority()}createMoveFromInput(t,e,i={}){const o=r.clamp(t,.001,this.maxMoveDeltaTime);this.clientMoveTime+=o;let s=this.clientMoveTime,n=o;!0===i.quantizeClientTime&&(s=Math.max(this.lastSentClientMoveTime+.001,Math.round(1e3*this.clientMoveTime)/1e3),n=r.clamp(s-this.lastSentClientMoveTime,.001,this.maxMoveDeltaTime),this.lastSentClientMoveTime=s),this.sampleRootMotion(gt);const a=this.crouchInput.activated,h=!a&&this.sprintInput.activated,c=h&&!this.previousSprintInput;this.previousSprintInput=h;const l=(this.jumpInput.activated?Z:0)|(h?L:0)|(a?H:0)|(c?E:0)|(gt.lengthSq()>0?U:0),u=function(t,e){e.set(t.x,0,t.y),e.lengthSq()>1&&e.normalize();return e}(this.directionInput.vector,It),p=this.inputMoveScratch;return p.sequence=e>>>0,p.clientTime=s,p.dt=n,p.inputX=u.x,p.inputY=u.z,p.yaw=this.rotationInput.rotation.y,p.flags=l,p.clientX=this.state.position.x,p.clientY=this.state.position.y,p.clientZ=this.state.position.z,p.rootMotionX=gt.x,p.rootMotionY=gt.y,p.rootMotionZ=gt.z,p}performMove(t,e){const i=r.clamp(t.dt,.001,this.maxMoveDeltaTime),o=Math.max(1,Math.ceil(i/this.maxSubstepDeltaTime)),s=0!==(t.flags&L)&&0===(t.flags&H);this.sprintPolicy?.update?.(i,t.sequence,s),wt.set(e.savedRootMotion?t.rootMotionX:0,e.savedRootMotion?t.rootMotionY:0,e.savedRootMotion?t.rootMotionZ:0),e.savedRootMotion||this.sampleRootMotion(wt);let n=i;const a=i/o;for(let s=0;s<o;s++){const o=i>0?a/i:1;this.performSubstep(t,Math.min(a,n),wt,o,e.immediate,0===s),n-=a}t.clientX=this.state.position.x,t.clientY=this.state.position.y,t.clientZ=this.state.position.z,t.flags=wt.lengthSq()>0?t.flags|U:t.flags&~U,this.state.sequence=t.sequence,this.syncPublicState()}performSubstep(t,e,i,o,s,n){if(e<.001)return;this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.updateCrouchState(t);const r=null!=this.rootMotionAction&&this.rootMotionAction.enabled,a=i.lengthSq()>0,h=!r&&0!==(t.flags&Z),c=r||a;this.pressedJump=h,this.isSprinting=!1,this.updateRotation(t,e,r,a),this.resolvePlatformVelocity(yt);const l=this.movementModeContext,u=this.movementModes.get(this.state.mode);if(null!=u){l.move=t,l.deltaTime=e,l.rootMotionActive=c,l.startedSprinting=n&&!c&&0===(t.flags&H)&&0!==(t.flags&E);const i=u.update(l);"number"==typeof i&&(this.state.mode=i)}else vt.set(0,0,0);if(a){ft.copy(i).multiplyScalar(o).applyQuaternion(this.actor.quaternion),xt.copy(ft).divideScalar(e),this.state.mode===R.walking?(vt.x=xt.x+yt.x,vt.z=xt.z+yt.z):(vt.x=xt.x,vt.z=xt.z);const t=Math.sqrt(xt.x*xt.x+xt.z*xt.z);t>.4&&(this.state.currentSpeed=t)}this.applyImpulseToVelocity(vt,e),this.state.mode===R.walking&&this.state.velocity.copy(vt),this.applyMovement(vt,e,s),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.updateModeAfterMove(vt,e)}updateRotation(t,e,i,o){mt.set(-t.inputX,0,t.inputY),mt.lengthSq()>1&&mt.normalize();const s=this.state.prevRotateToMovementDirection!==this.rotateToMovementDirection;let n=r.euclideanModulo(t.yaw-this.state.lookYaw+Math.PI,2*Math.PI)-Math.PI;if(s&&(this.actor.object.quaternion.setFromEuler(Pt.set(0,t.yaw,0)),this.state.prevRotateToMovementDirection||(n=0,this.state.lookYaw=t.yaw),this.state.prevRotateToMovementDirection=this.rotateToMovementDirection),dt.set(0,0,0),i)this.state.lookYaw=t.yaw;else if(this.rotateToMovementDirection){if(mt.lengthSq()>0&&this.state.mode!==R.falling){const i=Pt.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,o=Math.atan2(mt.x,mt.z),s=.99*t.yaw+o;if(this.smoothRotation){const t=r.euclideanModulo(s-i+Math.PI,2*Math.PI)-Math.PI;let o=r.clamp(t*this.rotationSpeed*e,-this.maxRotationSpeed*e,this.maxRotationSpeed*e);Math.abs(o)>Math.abs(t)&&(o=t),this.actor.object.quaternion.setFromEuler(Pt.set(0,i+o,0))}else this.actor.object.quaternion.setFromEuler(Pt.set(0,s,0));this.state.prevInputDirection.lerp(mt,e*this.rotationSpeed),this.state.lookYaw+=n,dt.copy(this.actor.object.getWorldDirection(It).normalize())}}else o||(this.state.lookYaw+=n,this.actor.object.quaternion.multiply(kt.setFromEuler(Pt.set(0,n,0))),mt.lengthSq()>0&&dt.copy(mt).applyQuaternion(this.actor.object.quaternion).normalize())}applyMovement(t,e,i){if(t.lengthSq()>0||!this.state.grounded){if(St.copy(t).multiplyScalar(e),this.state.grounded&&this.state.mode===R.walking&&(this.rayTestResult.distance<=this.cc.offset()&&(St.y=Math.max(0,yt.y*e)),this.physicsSystem.getActorComputedMovement(this.actor,this.cc,St,this.getCollisionGroup()),this.cc.computedCollision(0,Yt),null!=Yt.normal1)){const t=It.copy(Yt.normal1);Math.acos(r.clamp(t.dot(pt),-1,1))>this.cc.maxSlopeClimbAngle()&&(St.y=.016*this.getEffectiveGravity()*.5)}Mt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,St,this.getCollisionGroup()))}else Mt.set(0,0,0);this.suppressUncrouchLift&&(this.suppressUncrouchLift=!1,this.state.grounded&&this.state.mode===R.walking&&St.y<=1e-6&&Mt.y>0&&(Mt.y=0)),this.state.position.add(Mt),i?(this.actor.position.copy(this.state.position),this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()):this.physicsSystem.setNextKinematicPosition(this.actor,this.state.position)}updateModeAfterMove(t,e){const i=function(t){if(0===t.numComputedCollisions())return!1;const e=t.computedCollision(0);bt.set(e.normal2.x,e.normal2.y,e.normal2.z);const i=bt.angleTo(pt);bt.set(e.normal1.x,e.normal1.y,e.normal1.z);const o=bt.angleTo(pt);if(i<100)return!1;return o>t.minSlopeSlideAngle()}(this.cc);!this.state.grounded||i?this.state.mode!==R.falling&&(this.state.fallGraceTime+=e,this.state.fallGraceTime>this.fallGraceTime+1e-6&&(this.state.mode=R.falling,this.state.velocity.copy(t))):this.state.velocity.y<=0&&(this.state.mode=R.walking,this.state.velocity.y=0,this.state.fallGraceTime=0)}applyImpulseToVelocity(t,e){if(this.impulse.lengthSq()<=.1)return void this.impulse.set(0,0,0);const i=Math.min(1,this.impulse.length()/5);t.x=r.lerp(t.x,this.impulse.x,i),t.z=r.lerp(t.z,this.impulse.z,i),t.y+=this.impulse.y;const o=Math.exp(-this.impulseDamping*e);this.impulse.x*=o,this.impulse.y>0?this.impulse.y+=e*this.getEffectiveGravity():this.impulse.y*=o,this.impulse.z*=o}sendSavedMoves(t,e=!1){if(this.moveSendAccumulator+=t,!e&&this.moveSendAccumulator<this.moveSendInterval)return;this.moveSendAccumulator=0;const i=this.savedMoves.getMovesForSend(this.maxMovesPerPacket);0!==i.length&&this.serverMove(nt(i))}sendOwnerCorrection(t){const e=this.toSnapshot(this.pendingSnapshot);t&&(e.horizontalSpeed=this.horizontalSpeed),this.sprintPolicy?.ack?.(e.sequence,!0),this.clientMoveCorrection(at(e))}sendSimulatedState(t,e){this.simulatedStateAccumulator+=t,!e&&this.simulatedStateAccumulator<this.simulatedStateInterval||(this.simulatedStateAccumulator=0,this.simulatedState(ht(this.toSnapshot(this.pendingSnapshot))))}applyCorrection(t){this.sprintPolicy?.restore?.(t.sequence),this.savedMoves.ack(t.sequence),this.sprintPolicy?.ack?.(t.sequence,!0),this.applySnapshot(t,!0),this.savedMoves.replayAfter(t.sequence,t=>(this.performMove(t,{immediate:!0,savedRootMotion:!0}),null),this.maxReplayedMoves)}applySnapshot(t,e){this.state.sequence=t.sequence,this.state.position.set(t.x,t.y,t.z),this.state.velocity.set(t.velocityX,t.velocityY,t.velocityZ),this.state.yaw=t.yaw,this.state.lookYaw=t.yaw,this.state.mode=t.mode,this.state.currentSpeed=t.horizontalSpeed,this.state.fallGraceTime=0,this.actor.position.copy(this.state.position),this.actor.object.quaternion.setFromEuler(Pt.set(0,t.yaw,0)),this.setCrouching(0!==(t.flags&$)),e&&(this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.syncPublicState()}toSnapshot(t){return t.sequence=this.state.sequence,t.x=this.state.position.x,t.y=this.state.position.y,t.z=this.state.position.z,t.velocityX=this.state.velocity.x,t.velocityY=this.state.velocity.y,t.velocityZ=this.state.velocity.z,t.yaw=Pt.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,t.mode=this.state.mode,t.flags=this.isCrouching?$:0,t.horizontalSpeed=this.state.currentSpeed,t}syncPublicState(){this.velocity.copy(this.state.velocity),this.mode=this.state.mode,this.horizontalSpeed=this.state.currentSpeed}sampleRootMotion(t){if(t.set(0,0,0),null==this.rootMotionAction||this.rootMotionAction.isRunning()||this.clearRootMotionAction(this.rootMotionAction),null!=this.rootMotionAction&&this.rootMotionOptions.cancelWithJump&&this.jumpInput.activated&&(this.isGrounded||this.jumpInAir)){const e=this.rootMotionAction,i=this.rootMotionOptions.onJumpCancel;return this.clearRootMotionAction(e),e.stop(),i?.(),t}if(null==this.rootMotionAction)return t;if(!(this.rootMotionAction.getClip()instanceof c))return t;const e=this.rootMotionInterpolant;this.resetRootMotion&&(this.prevRootMotionPos.fromArray(e.evaluate(0)),this.resetRootMotion=!1),Ct.fromArray(e.evaluate(this.rootMotionAction.time)),t.subVectors(Ct,this.prevRootMotionPos),this.prevRootMotionPos.copy(Ct);return(this.rootMotionRootBone??this.rootMotionAction.getRoot()).getWorldScale(Tt),t.multiply(Tt),t}clearRootMotionAction(t){null!=t&&this.rootMotionAction!==t||(this.rootMotionAction=null,this.rootMotionOptions={},this.resetRootMotion=!1)}isRemoteControlledAuthority(t=this.netService.mode,e=this.actor.netRole){if(t===lt.none||e!==d.authority||t>=lt.client)return!1;return null!=this.netService.resolveActorConnection(this.actor)&&!this.netService.isLocalOwner(this.actor)}configureCharacterController(){const t=this.cc;t.setApplyImpulsesToDynamicBodies(this.applyImpulsesToDynamicBodies),t.setMinSlopeSlideAngle(this.minSlopeSlideAngle),t.setMaxSlopeClimbAngle(this.maxSlopeClimbAngle),t.setCharacterMass(this.mass),t.setSlideEnabled(this.allowSliding)}initializeStateFromActor(){this.state.position.copy(this.actor.position),this.state.velocity.set(0,0,0),this.state.yaw=this.actor.rotation.y,this.state.lookYaw=this.rotationInput.rotation.y,this.state.mode=this.mode,this.state.currentSpeed=this.horizontalSpeed,this.state.prevRotateToMovementDirection=this.rotateToMovementDirection}createCollisionShape(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1),i=new x(t,e);return i.offset.y=this.getCapsuleOffsetY(t,e),i.collisionGroup=ut,i}updateCrouchState(t){0===(t.flags&H)?this.isCrouching&&this.canUncrouch()&&this.setCrouching(!1)&&(this.suppressUncrouchLift=!0,this.state.fallGraceTime=0):this.setCrouching(!0)}setCrouching(t){return this.isCrouching!==t&&(this.isCrouching=t,this.syncColliderShape(),!0)}canUncrouch(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1);return!this.physicsSystem.hasActorCapsuleIntersection(this.actor,this.state.position,t,e,this.getCapsuleOffsetY(t,e),this.getCollisionGroup())}syncColliderShape(){const t=this.getColliderHeight(this.isCrouching),e=this.getColliderRadius(this.isCrouching);this.physicsSystem.setActorCapsuleCollider(this.actor,t,e,this.getCapsuleOffsetY(t,e))}getColliderHeight(t){const e=Number.isFinite(this.colliderHeight)?Math.max(0,this.colliderHeight):0;if(!t)return e;const i=Number.isFinite(this.crouchColliderHeight)?this.crouchColliderHeight:e;return r.clamp(i,0,e)}getColliderRadius(t){const e=Number.isFinite(this.colliderRadius)?Math.max(.001,this.colliderRadius):.001;if(!t)return e;const i=this.crouchColliderRadius??e,o=Number.isFinite(i)?i:e;return r.clamp(o,.001,e)}getCapsuleOffsetY(t,e){return e+t/2+this.offset}checkGrounded(t){qt.y=-Math.max(.05,this.cc.snapToGroundDistance()),this.physicsSystem.rayTest(At.addVectors(t,Dt.set(0,this.offset,0)),Rt.addVectors(t,qt),this.rayTestResult,{excludeActor:this.actor,excludeTriggers:!0})}resolvePlatformVelocity(t){return t.set(0,0,0),this.rayTestResult.hasHit&&null!=this.rayTestResult.actor&&this.physicsSystem.getLinearVelocity(this.rayTestResult.actor,t),t}getCollisionGroup(){return this.characterCollision?null:ut}};t([T(),e("design:type",Object)],Ft.prototype,"colliderHeight",void 0),t([T(),e("design:type",Object)],Ft.prototype,"colliderRadius",void 0),t([T(),e("design:type",Object)],Ft.prototype,"crouchColliderHeight",void 0),t([T(),e("design:type",Number)],Ft.prototype,"crouchColliderRadius",void 0),t([S(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Ft.prototype,"serverMove",null),t([v(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Ft.prototype,"clientMoveAck",null),t([v(!0),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Ft.prototype,"clientMoveCorrection",null),t([y(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Ft.prototype,"simulatedState",null),Ft=t([A({inEditor:!1}),e("design:paramtypes",[])],Ft);export{Ft as CharacterMovementComponent};const Gt={mode:R.walking,update(t){const e=t.component,i=t.move,o=t.state,s=t.rotatedDirection,n=Math.min(1,Math.sqrt(i.inputX*i.inputX+i.inputY*i.inputY)),r=!e.rotateToMovementDirection&&i.inputY<0,a=e.isCrouching,h=!t.rootMotionActive&&!a&&0===(i.flags&H)&&0!==(i.flags&L)&&!r&&0!==s.lengthSq()&&(e.sprintPolicy?.canSprint()??!0),c=(a?e.maxSpeedCrouch:r?e.maxSpeedBackwards:h?e.maxSpeedSprint:e.maxSpeed)*(e.normalizedDirection?1:n);if(0!==s.lengthSq()){e.isSprinting=h,h&&e.sprintPolicy?.commitSprint(t.deltaTime,i.sequence);let a=Math.min(c,o.currentSpeed),l=e.groundAccelerationRate;if(h&&t.startedSprinting&&e.sprintStartBoostSpeed>0){const t=e.normalizedDirection?1:n;a=Math.max(a,c+e.sprintStartBoostSpeed*t),l=e.sprintStartBoostDamping}else h&&!r&&e.sprintStartBoostSpeed>0&&o.currentSpeed>c&&(a=o.currentSpeed,l=e.sprintStartBoostDamping);o.currentSpeed=function(t,e,i,o){return e+(t-e)*Math.exp(-i*o)}(a,c,l,t.deltaTime),t.outVelocity.copy(s).multiplyScalar(function(t,e,i,o){const s=i*o;if(s<=1e-6)return t;return e+(t-e)*(1-Math.exp(-s))/s}(a,c,l,t.deltaTime))}else o.currentSpeed=0,t.outVelocity.set(0,0,0);if(0!==(i.flags&Z))return o.mode=R.falling,o.velocity.copy(t.outVelocity),o.velocity.y=e.jumpVelocity,R.falling;t.outVelocity.y=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.add(t.platformVelocity)}},Ot={mode:R.falling,update(t){const e=t.component,i=t.state,o=t.move;0!==(o.flags&Z)&&e.jumpInAir&&(i.velocity.copy(t.outVelocity),i.velocity.y=e.jumpVelocity),i.velocity.y+=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.copy(i.velocity),t.outVelocity.addScaledVector(t.rotatedDirection,e.fallingMovementControl),e.fallingReorientation&&t.outVelocity.applyAxisAngle(pt,r.euclideanModulo(o.yaw-i.lookYaw+Math.PI,2*Math.PI)-Math.PI)}};function Vt(t,e){return e.sequence=t.sequence,e.clientTime=t.clientTime,e.dt=t.dt,e.inputX=t.inputX,e.inputY=t.inputY,e.yaw=t.yaw,e.flags=t.flags,e.clientX=t.clientX,e.clientY=t.clientY,e.clientZ=t.clientZ,e.rootMotionX=t.rootMotionX,e.rootMotionY=t.rootMotionY,e.rootMotionZ=t.rootMotionZ,e}function Xt(t,e){const i=t.position.x-e.clientX,o=t.position.y-e.clientY,s=t.position.z-e.clientZ;return i*i+o*o+s*s}class Bt{constructor(t){this.scene=t,this.serverPosition=new h,this.direction=new h}update(t,e){const i=this.serverPosition.set(e.x,e.y,e.z),o=i.distanceTo(t);o>.1&&console.log(`Correction applied. Error: ${o.toFixed(3)}. Server position: (${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z.toFixed(2)}), Client position: (${t.x.toFixed(2)}, ${t.y.toFixed(2)}, ${t.z.toFixed(2)})`);const s=this.direction.copy(i).sub(t).normalize();Nt.position.copy(t),Nt.setDirection(s),Nt.setLength(o);const n=Ht(this.scene);n.add(Nt),setTimeout(()=>{n.remove(Nt)},1e3)}}const Nt=new n(new h(0,1,0),new h,1,16711680);function Ht(t){return null==t.parent?t:Ht(t.parent)}const Zt={immediate:!1,savedRootMotion:!0};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */