@hology/core 0.0.272 → 0.0.274

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 (104) hide show
  1. package/dist/effects/sequence/sequence-player.js +1 -1
  2. package/dist/effects/vfx/gpu-sprite-runtime.js +1 -1
  3. package/dist/effects/vfx/gpu-vfx-world-service.js +1 -1
  4. package/dist/effects/vfx/rates.d.ts +2 -0
  5. package/dist/effects/vfx/rates.js +1 -1
  6. package/dist/effects/vfx/vfx-actor.d.ts +2 -1
  7. package/dist/effects/vfx/vfx-actor.js +1 -1
  8. package/dist/effects/vfx/vfx-asset.d.ts +10 -1
  9. package/dist/effects/vfx/vfx-backend-partition.d.ts +8 -0
  10. package/dist/effects/vfx/vfx-backend-partition.js +4 -0
  11. package/dist/effects/vfx/vfx-materializer.js +1 -1
  12. package/dist/effects/vfx/vfx-render-preparation.js +1 -1
  13. package/dist/effects/vfx/vfx-renderers.d.ts +27 -2
  14. package/dist/effects/vfx/vfx-renderers.js +1 -1
  15. package/dist/gameplay/actors/builtin/components/character/character-animation.d.ts +2 -0
  16. package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
  17. package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +19 -0
  18. package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
  19. package/dist/gameplay/actors/builtin/water-spline-volume-actor.d.ts +10 -0
  20. package/dist/gameplay/actors/builtin/water-spline-volume-actor.js +1 -1
  21. package/dist/gameplay/actors/builtin/water-volume-actor.d.ts +3 -1
  22. package/dist/gameplay/actors/builtin/water-volume-actor.js +1 -1
  23. package/dist/gameplay/actors/camera/first-person-camera-component.js +1 -1
  24. package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +7 -0
  25. package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
  26. package/dist/gameplay/ai/behavior-tree/move.d.ts +5 -0
  27. package/dist/gameplay/ai/behavior-tree/move.js +1 -1
  28. package/dist/gameplay/ai/behavior-tree/move.test.d.ts +2 -0
  29. package/dist/gameplay/ai/behavior-tree/move.test.js +4 -0
  30. package/dist/gameplay/animation/root-motion.js +1 -1
  31. package/dist/gameplay/input/input-service.d.ts +9 -1
  32. package/dist/gameplay/input/input-service.js +1 -1
  33. package/dist/gameplay/services/physics/physics-system.d.ts +2 -0
  34. package/dist/gameplay/services/physics/physics-system.js +1 -1
  35. package/dist/gameplay/services/render.d.ts +4 -1
  36. package/dist/gameplay/services/render.js +1 -1
  37. package/dist/gameplay/services/world.d.ts +5 -0
  38. package/dist/rendering/node-material-webgpu-resolver.js +1 -1
  39. package/dist/rendering/webgpu-experimental-backend.d.ts +4 -2
  40. package/dist/rendering/webgpu-experimental-backend.js +1 -1
  41. package/dist/rendering.d.ts +17 -2
  42. package/dist/rendering.js +1 -1
  43. package/dist/scene/asset-resource-loader.d.ts +4 -0
  44. package/dist/scene/asset-resource-loader.js +1 -1
  45. package/dist/scene/collision/collision-shape-import.js +1 -1
  46. package/dist/scene/collision/rapier-shape.js +1 -1
  47. package/dist/scene/landscape/landscape-geometry.d.ts +24 -0
  48. package/dist/scene/landscape/landscape-geometry.js +4 -0
  49. package/dist/scene/landscape/landscape-manager.d.ts +1 -0
  50. package/dist/scene/landscape/landscape-manager.js +1 -1
  51. package/dist/scene/materializer.d.ts +7 -1
  52. package/dist/scene/materializer.js +1 -1
  53. package/dist/scene/scene-data-service.d.ts +2 -1
  54. package/dist/scene/scene-data-service.js +1 -1
  55. package/dist/scene/sky.d.ts +2 -0
  56. package/dist/scene/sky.js +1 -1
  57. package/dist/shader/graph/compiler.js +1 -1
  58. package/dist/shader/graph/registry.js +1 -1
  59. package/dist/shader/parameter.js +1 -1
  60. package/dist/shader/sprite-shader.js +1 -1
  61. package/dist/shader-nodes/depth.d.ts +6 -4
  62. package/dist/shader-nodes/depth.js +1 -1
  63. package/dist/shader-nodes/index.d.ts +2 -1
  64. package/dist/shader-nodes/index.js +1 -1
  65. package/dist/shader-nodes/surface-reflection.d.ts +9 -0
  66. package/dist/shader-nodes/surface-reflection.js +4 -0
  67. package/dist/shader-nodes/water-volume.d.ts +6 -2
  68. package/dist/shader-nodes/water-volume.js +1 -1
  69. package/dist/test/asset-resource-loader-texture-array.test.js +1 -1
  70. package/dist/test/character-movement-solve.test.js +1 -1
  71. package/dist/test/collision-shape-import.test.js +1 -1
  72. package/dist/test/first-person-camera-component.test.js +1 -1
  73. package/dist/test/frame-stats.test.js +1 -1
  74. package/dist/test/gpu-sprite-compiler.test.js +1 -1
  75. package/dist/test/input.test.js +1 -1
  76. package/dist/test/landscape-geometry.test.d.ts +2 -0
  77. package/dist/test/landscape-geometry.test.js +4 -0
  78. package/dist/test/material-assignment.test.js +1 -1
  79. package/dist/test/materializer-dynamic-transform.test.js +1 -1
  80. package/dist/test/materializer-prefetch.test.js +1 -1
  81. package/dist/test/net-character-movement.test.js +1 -1
  82. package/dist/test/node-material-webgpu-resolver.test.js +1 -1
  83. package/dist/test/parameter-definition.test.js +1 -1
  84. package/dist/test/physics-hitstop.test.d.ts +2 -0
  85. package/dist/test/physics-hitstop.test.js +4 -0
  86. package/dist/test/physics-ray-object.test.js +1 -1
  87. package/dist/test/post-process-effect.test.js +1 -1
  88. package/dist/test/rapier-trimesh.test.d.ts +2 -0
  89. package/dist/test/rapier-trimesh.test.js +4 -0
  90. package/dist/test/sequence-animation-retiming.test.js +1 -1
  91. package/dist/test/sequence-vfx.test.js +1 -1
  92. package/dist/test/surface-reflection.test.d.ts +2 -0
  93. package/dist/test/surface-reflection.test.js +4 -0
  94. package/dist/test/vfx-backend-partition.test.d.ts +2 -0
  95. package/dist/test/vfx-backend-partition.test.js +4 -0
  96. package/dist/test/vfx-playback-transform.test.js +1 -1
  97. package/dist/test/vfx-render-preparation.test.js +1 -1
  98. package/dist/test/water-spline-volume-actor.test.js +1 -1
  99. package/dist/utils/mesh.d.ts +1 -1
  100. package/dist/utils/mesh.js +1 -1
  101. package/dist/utils/three/frame-stats.d.ts +8 -0
  102. package/dist/utils/three/frame-stats.js +1 -1
  103. package/package.json +2 -2
  104. 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{canCrossFadeFromAnimationAction as i}from"../../../../animation/animation-action.js";import{RootMotionClip as s}from"../../../../animation/root-motion.js";import{inject as r}from"../../../../inject.js";import{ViewController as n}from"../../../../services/render.js";import{AnimationMixer as a,Bone as l,Object3D as h,LoopOnce as c,Raycaster as d,Vector3 as p,SkinnedMesh as u,Skeleton as f,Quaternion as g,Matrix4 as m,MathUtils as k,ArrowHelper as y,Group as S}from"three";import{getCharacterMovementLike as I}from"./character-movement-like.js";import{CCDIKSolver as P}from"three/addons/animation/CCDIKSolver.js";import{World as w}from"../../../../services/world.js";import{PhysicsSystem as v,RayTestResult as b}from"../../../../services/physics/physics-system.js";import{ArrayMap as x}from"../../../../../utils/collections.js";import{getAnimationClipRigId as L,getAnimationRigChainBoneNames as B,getAnimationRigDataFromObject as R,getAnimationRigIdFromObject as F,setAnimationClipRigId as A}from"../../../../animation/retarget.js";import{FootContactAnchor as D,getAnimationFootContacts as C,isFootInContact as M,setAnimationFootContacts as T}from"../../../../animation/foot-contact.js";const W=new p(0,-1,0),O=new p(0,1,0),q=new p(1,1,1),U=new g,V=new p,E=new p,H=new p,N=new p,z=new p,j=new g,Q=new g,G=new g,_=new g,$=new m,K=new m,Y=new p(1,0,0),J=new p(0,1,0),X=new p(0,0,1);function Z(){return{point:new p,normal:new p,hasNormal:!1}}const tt=["mixamorigHips","Hips","hips","Pelvis","pelvis"],et={upper:["LeftUpLeg","leftUpLeg","left_up_leg"],lower:["LeftLeg","leftLeg","left_leg"],foot:["LeftFoot","leftFoot","left_foot"]},ot={upper:["RightUpLeg","rightUpLeg","right_up_leg"],lower:["RightLeg","rightLeg","right_leg"],foot:["RightFoot","rightFoot","right_foot"]},it=["left","right"];let st=class extends e{constructor(){super(...arguments),this.viewController=r(n),this.poseProcessors=new x,this.transitionProcessors=[],this.managedActions=[],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.sequenceAnimationControlled=!1,this.sequenceAnimationReleasePending=!1,this.sequenceAnimationReleaseFrames=0,this.externalControlActive=!1,this.world=r(w),this.physicsSystem=r(v),this._footIkEnabled=!1,this.footIkMoving=!1,this.footIkLocomotionEnabled=!1,this.footIkLocomotionActive=!0,this.footIkMaxPlantTurnAngleDeg=35,this.footIkMaxPlantDrift=.18,this.footIkMaxPlantPelvisDrop=.12,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.ikPelvisDescendantStack=[],this.ikWorldUpdateNodes=[],this.footIkStateReset=!0,this.footIkUsingContacts=!1,this.footIkLastRootPosition=new p,this.footIkHasRootSample=!1,this.ikPreSolvePelvisPosition=new p,this.footIkPoseApplied=!1,this.footIkAnimationPoseCaptured=!1,this.footIkContactTransitionTime=0,this.footIkTransitionLeftContact=!1,this.footIkTransitionRightContact=!1,this.ikLegState={left:{anchor:new D,contactRequested:!1,targetPosition:new p,normal:new p(0,1,0),forward:new p(0,0,1),pitch:0,contactOffset:0,planted:!1,lastFootWorldPos:new p,hasLastFootSample:!1,weight:0,top:!1},right:{anchor:new D,contactRequested:!1,targetPosition:new p,normal:new p(0,1,0),forward:new p(0,0,1),pitch:0,contactOffset:0,planted:!1,lastFootWorldPos:new p,hasLastFootSample:!1,weight:0,top:!1}},this.ikWarnedMissingBones=!1,this.raycaster=new d,this.raycastIntersections=[],this.footIkRayTo=new p,this.footIkRayTestResult=new b,this.footIkRayTestOptions={debug:!1,excludeTriggers:!0,resolveActor:!1,collisionFilter:-2},this.footIkHits={center:Z(),toe:Z(),heel:Z(),side:Z()},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 g,lower:new g,foot:new g,footWorld:new g},right:{upper:new g,lower:new g,foot:new g,footWorld:new g}},this.ikSolveScratch={hip:new p,knee:new p,foot:new p,direction:new p,animatedDirection:new p,pole:new p,kneeTarget:new p,target:new p,currentDirection:new p,desiredDirection:new p,rotation:new g},this.getFullBodyClip=lt(t=>t.uuid,t=>rt(this.fullBodyMask,t)),this.getUpperBodyClip=lt(t=>t.uuid,t=>rt(this.upperBodyMask,t))}get isSequenceControlled(){return this.externalControlActive||this.sequenceAnimationControlled||this.sequenceAnimationReleasePending}get hasUpperBodyOverride(){return this.upperBodyOverride}get footIkEnabled(){return this._footIkEnabled}set footIkEnabled(t){this._footIkEnabled!==t&&(this.restoreFootIkPose(),this._footIkEnabled=t,null!=this.ikRoot&&(this.disposeFootIkDebug(),this.initializeFootIk(this.ikRoot,this.ikRootBone),this.syncFootIkDebug()))}onInit(){this.viewController.onUpdate(this.actor).subscribe(t=>this.updateInternal(t)),this.characterMovement=I(this.actor),this.footIkRayTestOptions.excludeActor=this.actor}onEndPlay(){this.restoreFootIkPose(),this.resetFootIkContacts(),this.disposeFootIkDebug()}raycastDownFirstValid(t,e,o){const i=this.world.scene;this.raycaster.set(t,W),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(W,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&&(ct(t,e)||ct(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 u||!0===e.isSkinnedMesh)return!0;e=e.parent}return!1}getRootMotionAction(){if(this.fullBodyAction.getClip()instanceof s)return this.fullBodyAction}getFullBodyAction(){return this.fullBodyAction}getFullBodySourceClip(){const t=this.fullBodyClip;return null!=t&&this.fullBodyAction?.getClip()===this.getFullBodyClip(t)?t:void 0}setup(t,e,o){this.restoreFootIkPose(),null!=e&&(this.upperBodyMask=nt(e),this.fullBodyMask=function(t,e){const o=new Set(nt(e).map(t=>t.uuid)),i=[];return t.traverse(t=>{(t instanceof l||t.isBone)&&!o.has(t.uuid)&&i.push(t)}),i}(ht(t),e)),null!=this.mixer&&this.mixer.stopAllAction(),this.mixer=new a(t),this.managedActions.length=0,this.animationRigId=F(t),this.animationRigData=R(t),this.ikRoot=t,this.ikRootBone=o,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))}}addTransitionProcessor(t){const e=this.transitionProcessors.findIndex(e=>e.id===t.id);return e>=0&&this.transitionProcessors.splice(e,1),this.transitionProcessors.push(t),()=>{const e=this.transitionProcessors.indexOf(t);e>=0&&this.transitionProcessors.splice(e,1)}}preparePoseTransition(t,e,o){if(0===this.transitionProcessors.length)return!1;const i=this.fullBodyAction,s=this.getFullBodySourceClip();if(null==i||null==s||i.getClip().uuid===e.uuid||this.isSequenceControlled||o.sequenceControlled||this.upperBodyOverride)return!1;const r=this.transitionContext??(this.transitionContext={});r.animation=this,r.source=i,r.sourceClip=s,r.targetClip=t,r.targetPoseClip=e,r.targetTimeScale=this.getPlaybackTimeScale(e,o.timeScale??1),r.options=o;for(const t of this.transitionProcessors)if(t.prepare(r))return!0;return!1}runPoseProcessors(t,e){if(0===this.poseProcessors.size||null==this.mixer||!this.poseProcessors.present(t))return;const o=this.mixer.getRoot();if(!(o instanceof h))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){if(null==this.mixer)return;if(this.externalControlActive)return;this.restoreFootIkPose(),this.upperBodyTimer+=t*(this.upperBodyAction?.timeScale??1),this.fullBodyTimer+=t*(this.fullBodyAction?.timeScale??1);let e=!1;this.sequenceAnimationReleasePending&&(this.sequenceAnimationReleaseFrames>0?(e=!0,this.sequenceAnimationReleaseFrames--):(this.sequenceAnimationReleasePending=!1,this.currentFullBodyPriority=-1,this.sequenceAnimationControlled=!1,this.overrideFadeTime=null,this.fullBodyTimer=0)),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.sequenceAnimationControlled&&!this.sequenceAnimationReleasePending&&this.fullBodyAction&&this.fullBodyAction.loop===c&&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),e||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.captureFootIkAnimationPose(),this.runPoseProcessors("beforeIk",t),this.updateFootIk(t),this.runPoseProcessors("afterIk",t)}initializeFootIk(t,e){if(this.resetFootIkContacts(),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.ikWorldUpdateNodes.length=0,this.footIkStateReset=!0,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=B(this.animationRigData,"leftLeg"),r=B(this.animationRigData,"rightLeg"),n=this.resolveLegBoneRefs(i,this.leftLegIkBones,et,s),a=this.resolveLegBoneRefs(i,this.rightLegIkBones,ot,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.rebuildFootIkWorldUpdateNodes(),this.ikLegState.left.targetPosition.copy(n.foot.getWorldPosition(V)),this.ikLegState.right.targetPosition.copy(a.foot.getWorldPosition(V)),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=!1,this.ikLegState.right.planted=!1,this.ikLegState.left.lastFootWorldPos.copy(n.foot.getWorldPosition(V)),this.ikLegState.right.lastFootWorldPos.copy(a.foot.getWorldPosition(V)),this.ikLegState.left.hasLastFootSample=!1,this.ikLegState.right.hasLastFootSample=!1;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??ht(t);if(null==p)return;let u=i.getBoneByName("_IKTargetLeftFoot"),g=i.getBoneByName("_IKTargetRightFoot"),k=!1;if(null==u&&(u=new l,u.name="_IKTargetLeftFoot",p.add(u),k=!0),null==g&&(g=new l,g.name="_IKTargetRightFoot",p.add(g),k=!0),this.setBoneWorldPosition(u,n.foot.getWorldPosition(V)),this.setBoneWorldPosition(g,a.foot.getWorldPosition(V)),k||i.bones.indexOf(u)<0||i.bones.indexOf(g)<0){const e=i.bones.slice(),o=i.boneInverses.map(t=>t.clone());e.indexOf(u)<0&&(e.push(u),o.push((new m).copy(u.matrixWorld).invert())),e.indexOf(g)<0&&(e.push(g),o.push((new m).copy(g.matrixWorld).invert()));const s=new f(e,o);t.traverse(t=>{const e=t;!0===e.isSkinnedMesh&&e.skeleton===i&&e.bind(s,e.bindMatrix)})}this.ikTargetBones={left:u,right:g},this.rebuildFootIkWorldUpdateNodes();const y=o.skeleton.bones,S={target:y.indexOf(u),effector:y.indexOf(n.foot),links:[{index:y.indexOf(n.lower)},{index:y.indexOf(n.upper)}],iteration:8},I={target:y.indexOf(g),effector:y.indexOf(a.foot),links:[{index:y.indexOf(a.lower)},{index:y.indexOf(a.upper)}],iteration:8};if(S.target<0||S.effector<0||S.links.some(t=>t.index<0)||I.target<0||I.effector<0||I.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 P(o,[S,I])}findFirstSkinnedMesh(t){let e;return t.traverse(t=>{null==e&&(t instanceof u||!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,...tt].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(V),o=t.lower.getWorldPosition(E),i=t.foot.getWorldPosition(H),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(V.copy(e).applyMatrix4($.copy(o.matrixWorld).invert())),t.quaternion.copy(U),t.scale.copy(q),t.updateMatrixWorld(!0)}syncFootIkDebug(){this.footIkDebug&&null!=this.ikRoot?(null!=this.ikDebugRoot&&null!=this.ikDebugLegs||(this.ikDebugRoot=new S,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 S;o.name=t,o.userData.footIkDebug=!0;const i=this.createDebugArrow(e),s=this.createDebugArrow(e),r=this.createDebugArrow(e),n=this.createDebugArrow(e),a=this.createDebugArrow(65280),l=this.createDebugArrow(6750054),h=this.createDebugArrow(16711935),c=this.createDebugArrow(16776960),d=this.createDebugArrow(16737792);return o.add(i,s,r,n,a,l,h,c,d),{root:o,rayCenter:i,rayToe:s,rayHeel:r,raySide:n,hitNormal:a,footUp:l,footToTarget:h,solveUpper:c,solveLower:d}}createDebugArrow(t){const e=new y(O,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){V.subVectors(o,e);const i=V.length();i<1e-6?t.visible=!1:(t.visible=!0,t.position.copy(e),t.setDirection(V.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.footIkUsingContacts=!1,this.footIkLocomotionEnabled){const e=this.fullBodyAction,o=e?.getClip(),i=C(o);if(!this.footIkLocomotionActive||this.isSequenceControlled||null==i||null==e||e.getEffectiveWeight()<.65||!Number.isFinite(t)||t<0)return this.resetFootIkContacts(),void this.resetDebugVisibility();(this.footIkContactClip!==o||t>.2)&&(this.resetFootIkContacts(),this.footIkContactClip=o);const s=this.actor.object.getWorldPosition(V),r=(this.movementSpeed??0)*Math.max(0,t);this.footIkHasRootSample&&this.footIkLastRootPosition.distanceToSquared(s)>(1+r)**2&&(this.resetFootIkContacts(),this.footIkContactClip=o),this.footIkLastRootPosition.copy(s),this.footIkHasRootSample=!0,this.footIkUsingContacts=!0;const n=e.loop!==c;this.footIkContactTransitionTime=Math.max(0,this.footIkContactTransitionTime-t),this.ikLegState.left.contactRequested=this.footIkContactTransitionTime>0?this.footIkTransitionLeftContact:M(i.left,e.time,o.duration,n),this.ikLegState.right.contactRequested=this.footIkContactTransitionTime>0?this.footIkTransitionRightContact:M(i.right,e.time,o.duration,n)}if(!this.footIkUsingContacts&&!this.footIkMoving&&(this.movementSpeed??0)>.01)return this.footIkStateReset||(this.syncFootIkWorldMatrices(),this.resetFootIkState(),this.footIkStateReset=!0),void this.resetDebugVisibility();this.syncFootIkWorldMatrices(),this.footIkStateReset=!1;const e=this.characterMovement?.isGrounded??!0;if(this.footIkSimpleTiltOnly)return 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);if(null==this.ikLegLengths||null==this.ikTargetBones||null==this.ikSkinnedMesh||null==this.ikSolver)return this.updatePelvisOffset(t,!1),void this.resetDebugVisibility();if(this.footIkUsingContacts&&null!=this.ikPelvisBone&&this.ikPreSolvePelvisPosition.copy(this.ikPelvisBone.position),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.footIkUsingContacts&&!this.footIkAnimationPoseCaptured&&this.getCurrentWorldQuaternion(this.ikBoneRefs.left.foot,this.ikPreSolve.left.footWorld),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),this.footIkUsingContacts&&!this.footIkAnimationPoseCaptured&&this.getCurrentWorldQuaternion(this.ikBoneRefs.right.foot,this.ikPreSolve.right.footWorld),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.footIkUsingContacts?(this.ikLegState.left.weight>.001&&this.solveTwoBoneLeg("left",this.ikBoneRefs.left,this.ikLegState.left.targetPosition),this.ikLegState.right.weight>.001&&this.solveTwoBoneLeg("right",this.ikBoneRefs.right,this.ikLegState.right.targetPosition)):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.footIkUsingContacts){this.syncFootIkWorldMatrices();for(const t of it){const e=this.ikBoneRefs[t].foot,o=this.getCurrentWorldQuaternion(e.parent,j);e.quaternion.copy(o.invert().multiply(this.ikPreSolve[t].footWorld))}this.footIkPoseApplied=!0}this.applySimpleFootPitch("left",this.ikBoneRefs.left.foot,this.ikLegState.left),this.applySimpleFootPitch("right",this.ikBoneRefs.right.foot,this.ikLegState.right)}resetFootIkState(){if(null!=this.ikBoneRefs){for(const t of it){const e=this.ikBoneRefs[t],o=this.ikLegState[t],i=V.setFromMatrixPosition(e.foot.matrixWorld);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,o.anchor.reset()}this.ikPelvisOffsetY=0}}resetFootIkContacts(){for(const t of it){const e=this.ikLegState[t];e.anchor.reset(),e.contactRequested=!1,e.planted=!1,e.weight=0,e.hasLastFootSample=!1}this.footIkContactClip=void 0,this.footIkHasRootSample=!1,this.ikPelvisOffsetY=0,this.footIkContactTransitionTime=0}preserveFootIkContacts(t,e){this.footIkEnabled&&this.footIkLocomotionEnabled&&e>0&&(this.footIkContactClip=t,this.footIkTransitionLeftContact=this.ikLegState.left.anchor.locked,this.footIkTransitionRightContact=this.ikLegState.right.anchor.locked,this.footIkContactTransitionTime=e)}restoreFootIkPose(){if(this.footIkPoseApplied&&null!=this.ikBoneRefs){for(const t of it){const e=this.ikBoneRefs[t],o=this.ikPreSolve[t];e.upper.quaternion.copy(o.upper),e.lower.quaternion.copy(o.lower),e.foot.quaternion.copy(o.foot)}this.ikPelvisBone?.position.copy(this.ikPreSolvePelvisPosition),this.footIkPoseApplied=!1}}captureFootIkAnimationPose(){this.footIkAnimationPoseCaptured=!1,this.footIkEnabled&&this.footIkLocomotionEnabled&&this.footIkLocomotionActive&&!this.isSequenceControlled&&null!=this.ikBoneRefs&&null!=C(this.fullBodyAction?.getClip())&&(this.syncFootIkWorldMatrices(),this.getCurrentWorldQuaternion(this.ikBoneRefs.left.foot,this.ikPreSolve.left.footWorld),this.getCurrentWorldQuaternion(this.ikBoneRefs.right.foot,this.ikPreSolve.right.footWorld),this.footIkAnimationPoseCaptured=!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 it){const e=this.ikBoneRefs[t],i=this.ikLegLengths[t],s=this.ikLegState[t];if(!s.planted)continue;const r=V.setFromMatrixPosition(e.upper.matrixWorld),n=.998*i.total,a=this.computeRequiredPelvisDrop(r,s.targetPosition,n);if(a>0){const e="left"===t?"right":"left";this.ikLegState[e].top=!0}o=Math.min(o,-a)}const t=this.footIkUsingContacts?Math.min(this.footIkPelvisMaxOffsetDown,this.footIkMaxPlantPelvisDrop):this.footIkPelvisMaxOffsetDown;o=k.clamp(o,-t,this.footIkPelvisMaxOffsetUp)}const i=1-Math.exp(-this.footIkPelvisLerpSpeed*t);this.ikPelvisOffsetY=k.lerp(this.ikPelvisOffsetY,o,i);const s=E.setFromMatrixPosition(this.ikPelvisBone.matrixWorld),r=H.copy(s).addScaledVector(O,this.ikPelvisOffsetY);null==this.ikPelvisBone.parent?this.ikPelvisBone.position.copy(r):this.ikPelvisBone.position.copy(r.applyMatrix4($.copy(this.ikPelvisBone.parent.matrixWorld).invert())),this.updatePelvisWorldTranslation(s)}updatePelvisWorldTranslation(t){const e=this.ikPelvisBone;if(null==e)return;e.updateMatrix(),null==e.parent?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(e.parent.matrixWorld,e.matrix),e.matrixWorldNeedsUpdate=!1;const o=e.matrixWorld.elements,i=o[12]-t.x,s=o[13]-t.y,r=o[14]-t.z;if(0===i&&0===s&&0===r)return;const n=this.ikPelvisDescendantStack;n.length=0;for(let t=0;t<e.children.length;t++)n.push(e.children[t]);for(;n.length>0;){const t=n.pop(),e=t.matrixWorld.elements;e[12]+=i,e[13]+=s,e[14]+=r,t.matrixWorldNeedsUpdate=!1;for(let e=0;e<t.children.length;e++)n.push(t.children[e])}}rebuildFootIkWorldUpdateNodes(){const t=this.ikRoot,e=this.ikBoneRefs;if(null==t||null==e)return void(this.ikWorldUpdateNodes.length=0);const o=new Set,i=[this.ikPelvisBone,e.left.upper,e.left.lower,e.left.foot,e.right.upper,e.right.lower,e.right.foot,this.ikTargetBones?.left,this.ikTargetBones?.right];for(const e of i){let i=e;for(;null!=i&&(o.add(i),i!==t);)i=i.parent??void 0}this.ikWorldUpdateNodes.length=0,t.traverse(t=>{o.has(t)&&this.ikWorldUpdateNodes.push(t)})}syncFootIkWorldMatrices(){const t=this.ikRoot;if(null!=t){t.updateWorldMatrix(!0,!1);for(const e of this.ikWorldUpdateNodes)e!==t&&(e.matrixAutoUpdate&&e.updateMatrix(),e.matrixWorldAutoUpdate&&(null==e.parent?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(e.parent.matrixWorld,e.matrix)),e.matrixWorldNeedsUpdate=!1)}}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(E),h=H.copy(n.upLocal).applyQuaternion(this.getCurrentWorldQuaternion(o,j)).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=$.copy(t.boneInverses[i]).invert(),n=K.copy(r).multiply(s),d=V.setFromMatrixPosition(n),p=N.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;if(this.footIkUsingContacts)return t.contactRequested;const n=this.footIkPlantReleaseExtension,a=this.footIkPlantAttachExtension,l=this.footIkPlantReleaseLift,h=this.footIkPlantAttachLift;return t.planted?!(i>this.footIkPlantReleaseUpSpeed&&(s<n||r>l)):s>=a&&r<=h||i<=0&&s>=n}computeLegExtensionRatio(t,e){const o=V.setFromMatrixPosition(t.upper.matrixWorld),i=E.setFromMatrixPosition(t.foot.matrixWorld),s=o.distanceTo(i);return e.total<=1e-6?1:k.clamp(s/e.total,0,1.2)}computeRequiredPelvisDrop(t,e,o){const i=N.subVectors(t,e),s=i.length();if(s<=o+1e-6)return 0;const r=i.dot(O),n=o*o-Math.max(s*s-r*r,0);if(n<=0)return s-o;const a=Math.sqrt(n),l=r-a,h=r+a;return l>=0?l:h>=0?h:0}updateLegTiltSimple(t,e,o,i,s){const r=this.footIkScratch,n=this.footIkHits,a=r.footWorldPos.setFromMatrixPosition(e.matrixWorld),l=this.computeFootVerticalSpeed(o,a,s),h=this.resolveFootAxes(t,e,this.footIkAxesScratch),c=this.resolveGroundSampleAxes(t,e,h,this.footIkSampleAxesScratch),d=r.centerRayStart.copy(a).addScaledVector(O,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),y=this.getFirstGroundHit(u,n.heel),S=this.getFirstGroundHit(f,n.side),I=r.desiredNormal.set(0,1,0),P=r.desiredForward.copy(c.forward);let w=0,v=0,b=this.footIkWeightOutSpeed;const x=null!=g||null!=m||null!=y;let L=a.y;null!=g?L=g.point.y:null!=m&&null!=y?L=.5*(m.point.y+y.point.y):null!=m?L=m.point.y:null!=y&&(L=y.point.y);const B=this.ikBoneRefs?.[t],R=this.ikLegLengths?.[t],F=null!=B&&null!=R?this.computeLegExtensionRatio(B,R):1,A=Math.max(0,a.y-L,a.y-o.targetPosition.y),D=this.shouldPlantFoot(o,!this.footIkRequireGrounded||i,x,l,F,A);D?this.computeDesiredGroundNormal(c,g,m,y,S,I)&&(this.computeDesiredFootForward(c.forward,c.right,I,m,y,P),w=this.computeDesiredPitchAngle(m,y,c.forward),v=1,b=this.footIkWeightInSpeed):this.computeDesiredFootForward(c.forward,c.right,I,null,null,P);const C=1-Math.exp(-this.footIkPositionLerpSpeed*s),M=1-Math.exp(-b*s);o.normal.lerp(I,C).normalize(),o.forward.lerp(P,C).normalize(),o.pitch=k.lerp(o.pitch,w,C),o.weight=k.lerp(o.weight,v,M),o.planted=D&&v>.001,this.updateFootSample(o,a),this.applySimpleFootPitch(t,e,o),this.footIkDebug&&this.updateLegDebug(t,{footWorldPos:a,centerRayStart:d,toeRayStart:p,heelRayStart:u,sideRayStart:f,centerHit:g,toeHit:m,heelHit:y,sideHit:S,desiredNormal:o.normal,desiredTargetPos:r.footWorldPos,weight:o.weight})}updateLegIkTarget(t,e,o,i,s,r,n){const a=this.footIkScratch,l=this.footIkHits,h=e.foot,c=a.footWorldPos.setFromMatrixPosition(h.matrixWorld);if(this.footIkUsingContacts&&!s.contactRequested)return s.anchor.reset(),s.planted=!1,s.weight*=Math.exp(-this.footIkWeightOutSpeed*n),s.pitch*=Math.exp(-this.footIkRotationLerpSpeed*n),s.weight<=.001?s.targetPosition.copy(c):s.targetPosition.lerp(c,1-Math.exp(-this.footIkPositionLerpSpeed*n)),this.clampDesiredFootTarget(e,o,c,s.targetPosition),this.updateFootSample(s,c),this.setBoneWorldPosition(i,s.targetPosition),void(null!=this.ikDebugLegs&&(this.ikDebugLegs[t].root.visible=!1));const d=this.computeFootVerticalSpeed(s,c,n),p=this.resolveFootAxes(t,h,this.footIkAxesScratch),u=this.resolveGroundSampleAxes(t,h,p,this.footIkSampleAxesScratch),f=this.footIkUsingContacts&&s.anchor.locked&&s.contactRequested?s.anchor.position:c,g=a.centerRayStart.copy(f).addScaledVector(O,this.footIkRayStartHeight),m=a.toeRayStart.copy(g).addScaledVector(u.forward,this.footIkForwardSampleDistance),y=a.heelRayStart.copy(g).addScaledVector(u.forward,-this.footIkForwardSampleDistance),S=a.sideRayStart.copy(g).addScaledVector(u.right,this.footIkSideSampleDistance),I=this.getFirstGroundHit(g,l.center),P=this.getFirstGroundHit(m,l.toe),w=this.getFirstGroundHit(y,l.heel),v=this.getFirstGroundHit(S,l.side),b=a.desiredTargetPos.copy(c),x=a.desiredNormal.set(0,1,0),L=a.desiredForward.copy(u.forward);let B=0,R=0,F=this.footIkWeightOutSpeed;const A=null!=I||null!=P||null!=w;let D=c.y;null!=I?D=I.point.y:null!=P&&null!=w?D=.5*(P.point.y+w.point.y):null!=P?D=P.point.y:null!=w&&(D=w.point.y);const C=this.computeLegExtensionRatio(e,o),M=Math.max(0,c.y-D,c.y-s.targetPosition.y),T=this.shouldPlantFoot(s,!this.footIkRequireGrounded||r,A,d,C,M);if(T){if(b.copy(c),this.computeDesiredGroundNormal(u,I,P,w,v,x)){this.computeDesiredFootForward(u.forward,u.right,x,P,w,L),B=this.computeDesiredPitchAngle(P,w,u.forward);const t=Math.max(0,Math.sin(B))*this.footIkForwardSampleDistance*.45,e=Math.max(this.footIkFootOffset+this.footIkExtraClearance,s.contactOffset);b.y=D+e+t,s.top&&!this.footIkUsingContacts&&(b.y-=this.ikPelvisOffsetY/2),R=1,F=this.footIkWeightInSpeed}}else this.computeDesiredFootForward(u.forward,u.right,x,null,null,L),b.copy(c),this.footIkUsingContacts||(b.y+=this.footIkFootOffset);if(this.footIkUsingContacts){const t=z.setFromMatrixPosition(e.upper.matrixWorld),i=this.footIkPelvisEnabled?Math.min(this.footIkMaxPlantPelvisDrop,this.footIkPelvisMaxOffsetDown):0;s.anchor.locked&&Math.abs(b.y-s.anchor.position.y)>.08&&s.anchor.release();s.anchor.update(s.contactRequested,(!this.footIkRequireGrounded||r)&&null!=I&&R>0,c,b,u.forward,t,.995*o.total,i,Math.min(this.footIkMaxPlantDrift,this.footIkMaxHorizontalOffset),k.degToRad(this.footIkMaxPlantTurnAngleDeg))?b.copy(s.anchor.position):(b.copy(c),R=0,F=this.footIkWeightOutSpeed)}const W=1-Math.exp(-this.footIkPositionLerpSpeed*n),q=1-Math.exp(-F*n);this.footIkUsingContacts&&s.anchor.locked?s.targetPosition.copy(b):s.targetPosition.lerp(b,W),this.clampDesiredFootTarget(e,o,c,s.targetPosition),s.normal.lerp(x,W).normalize(),s.forward.lerp(L,W).normalize(),s.pitch=k.lerp(s.pitch,B,W),s.weight=k.lerp(s.weight,R,q),s.planted=T&&R>.001,this.updateFootSample(s,c),this.setBoneWorldPosition(i,s.targetPosition),this.footIkDebug&&this.updateLegDebug(t,{footWorldPos:c,centerRayStart:g,toeRayStart:m,heelRayStart:y,sideRayStart:S,centerHit:I,toeHit:P,heelHit:w,sideHit:v,desiredNormal:x,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(W,this.footIkRayLength),a=e.toeHit?.point??r.debugRayEndB.copy(e.toeRayStart).addScaledVector(W,this.footIkRayLength),l=e.heelHit?.point??r.debugRayEndC.copy(e.heelRayStart).addScaledVector(W,this.footIkRayLength),h=e.sideHit?.point??r.debugRayEndD.copy(e.sideRayStart).addScaledVector(W,this.footIkRayLength);this.setDebugArrow(o.rayCenter,e.centerRayStart,n),this.setDebugArrow(o.rayToe,e.toeRayStart,a),this.setDebugArrow(o.rayHeel,e.heelRayStart,l),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.getCurrentWorldDirection(this.actor.object,N);n.addScaledVector(O,-n.dot(O)),n.lengthSq()<1e-8&&n.copy(s.forward).addScaledVector(O,-s.forward.dot(O)),n.lengthSq()<1e-8&&n.set(0,0,1),n.normalize();const a=z.crossVectors(O,n);return a.lengthSq()<1e-8?a.copy(s.right):a.normalize(),a.dot(s.right)<0&&a.multiplyScalar(-1),r.forward.copy(n),r.right.copy(a),r}computeDesiredGroundNormal(t,e,o,i,s,r){const n=this.computeAverageHitNormal(e,o,i,s,N);let a=!1,l=0,h=0;if(null!=o&&null!=i){const e=E.subVectors(o.point,i.point).dot(t.forward);Math.abs(e)>1e-5&&(l=(o.point.y-i.point.y)/e,a=!0)}if(null!=s&&null!=e){const o=H.subVectors(s.point,e.point).dot(t.right);Math.abs(o)>1e-5&&(h=(s.point.y-e.point.y)/o,a=!0)}if(a&&(r.copy(O),r.addScaledVector(t.forward,-l),r.addScaledVector(t.right,-h),r.lengthSq()>1e-8?r.normalize():a=!1),a)null!=n&&r.dot(n)<0&&r.multiplyScalar(-1);else{if(null==n)return!1;r.copy(n),a=!0}return r.dot(O)<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.getCurrentWorldDirection(this.actor.object,N)),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=N.copy(this.getCurrentWorldDirection(this.actor.object,N));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=E.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=k.degToRad(this.footIkMaxSlopeAngleDeg);return k.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=j.copy(e.quaternion),a=Q.setFromAxisAngle(i.rightLocal,s*r);e.quaternion.copy(n.multiply(a))}resolveLocalPitchSign(t){const e=G.setFromAxisAngle(t.rightLocal,.15);return H.copy(t.upLocal).applyQuaternion(e).sub(t.upLocal).dot(t.forwardLocal)>=0?1:-1}clampDesiredFootTarget(t,e,o,i){const s=E.subVectors(i,o),r=s.dot(O),n=H.copy(s).addScaledVector(O,-r),a=n.length();a>this.footIkMaxHorizontalOffset&&a>1e-6&&n.multiplyScalar(this.footIkMaxHorizontalOffset/a);const l=k.clamp(r,-this.footIkMaxVerticalOffsetDown,this.footIkMaxVerticalOffsetUp);if(i.copy(o),i.add(n),i.addScaledVector(O,l),this.footIkPelvisEnabled)return;const h=t.upper.getWorldPosition(V).clone(),c=E.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=this.ikSolveScratch,s=i.hip.setFromMatrixPosition(e.upper.matrixWorld),r=i.knee.setFromMatrixPosition(e.lower.matrixWorld),n=i.foot.setFromMatrixPosition(e.foot.matrixWorld),a=s.distanceTo(r),l=r.distanceTo(n);if(a<1e-5||l<1e-5)return;const h=i.direction.subVectors(o,s),c=h.length();if(c<1e-5)return;const d=Math.abs(a-l)+1e-5,p=a+l-1e-5,u=k.clamp(c,d,p),f=h.multiplyScalar(1/c),g=i.animatedDirection.subVectors(n,s).normalize(),m=i.pole.subVectors(r,s);m.addScaledVector(g,-m.dot(g)),m.lengthSq()<a*a*1e-4&&(this.getCurrentWorldDirection(this.actor.object,m),m.addScaledVector(g,-m.dot(g)),m.lengthSq()<1e-8&&(Math.abs(g.x)<.9?m.set(1,0,0):m.set(0,1,0),m.addScaledVector(g,-m.dot(g)))),m.normalize(),i.rotation.setFromUnitVectors(g,f),m.applyQuaternion(i.rotation);const y=(u*u+a*a-l*l)/(2*u),S=Math.max(a*a-y*y,0),I=Math.sqrt(S),P=i.kneeTarget.copy(s).addScaledVector(f,y).addScaledVector(m,I),w=i.target.copy(s).addScaledVector(f,u);this.rotateBoneToward(e.upper,s,r,P),e.upper.updateMatrixWorld(!0);const v=r.setFromMatrixPosition(e.lower.matrixWorld),b=n.setFromMatrixPosition(e.foot.matrixWorld);this.rotateBoneToward(e.lower,v,b,w),e.lower.updateMatrixWorld(!0),this.updateSolveDebug(t,s,P,w)}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=this.ikSolveScratch.currentDirection.subVectors(o,e),r=this.ikSolveScratch.desiredDirection.subVectors(i,e);if(s.lengthSq()<1e-10||r.lengthSq()<1e-10)return;if(s.normalize(),r.normalize(),s.dot(r)>1-1e-10)return;const n=this.ikSolveScratch.rotation.setFromUnitVectors(s,r),a=this.getCurrentWorldQuaternion(t,j),l=Q.copy(n).multiply(a);if(null==t.parent)return void t.quaternion.copy(l);const h=this.getCurrentWorldQuaternion(t.parent,G),c=_.copy(h).invert().multiply(l);t.quaternion.copy(c)}detectFootAxisBasis(t){const e=this.getCurrentWorldQuaternion(t,j),o=this.getCurrentWorldDirection(this.actor.object,V);o.lengthSq()<1e-6&&o.set(0,0,1),o.normalize();const i=[{local:Y.clone(),world:Y.clone().applyQuaternion(e)},{local:J.clone(),world:J.clone().applyQuaternion(e)},{local:X.clone(),world:X.clone().applyQuaternion(e)}];i.push({local:Y.clone().multiplyScalar(-1),world:Y.clone().multiplyScalar(-1).applyQuaternion(e)}),i.push({local:J.clone().multiplyScalar(-1),world:J.clone().multiplyScalar(-1).applyQuaternion(e)}),i.push({local:X.clone().multiplyScalar(-1),world:X.clone().multiplyScalar(-1).applyQuaternion(e)});let s=i[0],r=-1/0;for(const t of i){const e=t.world.dot(O);e>r&&(r=e,s=t)}let n=i[0],a=-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>a&&(a=e,n=t)}n.world.dot(o)<0&&(n={local:n.local.clone().multiplyScalar(-1),world:n.world.clone().multiplyScalar(-1)});const l=s.local.clone().normalize(),h=n.local.clone().normalize(),c=l.clone().cross(h).normalize();return{upLocal:l,forwardLocal:c.clone().cross(l).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=this.getCurrentWorldQuaternion(e,j);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}getCurrentWorldQuaternion(t,e){return t.matrixWorld.decompose(z,e,N),e}getCurrentWorldDirection(t,e){const o=t.matrixWorld.elements;return e.set(o[8],o[9],o[10]).normalize()}clampSlopeNormal(t){const e=k.clamp(t.dot(O),-1,1),o=Math.acos(e),i=k.degToRad(this.footIkMaxSlopeAngleDeg);if(o<=i||o<1e-5)return;const s=i/o;t.lerpVectors(O,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){j.copy(t.quaternion),t.quaternion.copy(e).slerp(j,o)}alignFootToGroundNormal(t,e,o,i){if(o.weight<=.001||null==e.parent)return;const s=this.ikFootAxes?.[t]??this.detectFootAxisBasis(e),r=V.copy(o.normal).normalize(),n=E.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 a=H.crossVectors(r,n);if(a.lengthSq()<1e-8)return;a.normalize(),n.copy(N.crossVectors(a,r)).normalize(),$.makeBasis(s.rightLocal,s.upLocal,s.forwardLocal),j.setFromRotationMatrix($),K.makeBasis(a,r,n),Q.setFromRotationMatrix(K);const l=G.copy(Q).multiply(_.copy(j).invert()),h=this.getCurrentWorldQuaternion(e.parent,_),c=Q.copy(h).invert().multiply(l),d=(1-Math.exp(-this.footIkRotationLerpSpeed*i))*o.weight;e.quaternion.slerp(c,k.clamp(d,0,1))}getMixer(){return this.mixer}evaluateExternalPose(t=0){null!=this.mixer&&(this.restoreFootIkPose(),this.runPoseProcessors("beforeMixer",t),this.mixer.update(t),this.runPoseProcessors("afterMixer",t),this.captureFootIkAnimationPose(),this.runPoseProcessors("beforeIk",t),this.updateFootIk(t),this.runPoseProcessors("afterIk",t))}beginExternalControl(){this.externalControlActive=!0}endExternalControl(){this.externalControlActive=!1}stopSequenceAnimation(){this.currentFullBodyPriority=-1,this.externalControlActive=!1,this.sequenceAnimationControlled=!1,this.sequenceAnimationReleasePending=!1,this.sequenceAnimationReleaseFrames=0,this.upperBodyOverride=!1,this.overrideFadeTimeUpper=null,this.fullBodyTimer=0}requestSequenceAnimationRelease(){this.externalControlActive=!1,this.sequenceAnimationControlled=!1,this.currentFullBodyPriority=-1,this.sequenceAnimationReleasePending=!0,this.sequenceAnimationReleaseFrames=1,this.upperBodyOverride=!1,this.overrideFadeTimeUpper=null}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={}){at(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 this.managedActions.indexOf(o)<0&&this.managedActions.push(o),o.setLoop(c,1),o.clampWhenFinished=!0,o.timeScale=e.timeScale??1,o.reset(),o.play(),this.fullBodyAction=o,this.externalControlActive=!0,o}syncMovementSpeed(t){null!=t&&(t.timeScale=this.getPlaybackTimeScale(t.getClip(),t.timeScale))}getPlaybackTimeScale(t,e){if(!(t instanceof s&&t.fixedInPlace&&null!=this.movementSpeed))return e;const o=this.mixer.getRoot(),i=o instanceof h?o.scale.x:1;return t.duration/t.displacement*this.movementSpeed/i}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={}){at(null!=this.mixer,"Can't play animation before setup is called"),this.assertClipRigCompatible(t);const o=e.priority??1;if(o<this.currentFullBodyPriority)return;this.currentFullBodyPriority=o,this.fullBodyTimer=0,e.sequenceControlled&&(this.sequenceAnimationControlled=!0,this.sequenceAnimationReleasePending=!1,this.sequenceAnimationReleaseFrames=0);const i=this.getFullBodyClip(t);if(this.preparePoseTransition(t,i,e)){for(const t of this.managedActions)t.stop();this.managedActions.length=0,this.fullBodyAction=null,this.upperBodyAction=null}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,i,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=L(t);if(e===this.animationRigId||null==e&&null==this.animationRigId)return;const o=`${t.uuid}|${e??""}|${this.animationRigId??""}`;if(!dt.has(o)){if(dt.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 s=o?.fadeTime??this.fadeTime;if(null!=t&&t.getClip().uuid===e.uuid)return t.isRunning()||!1!==o.loop||!t.clampWhenFinished||o.sequenceControlled?(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(c,1),t.clampWhenFinished=!0)),t):t;if(i(t)){const i=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,i.crossFadeTo(r,s,!1),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(c,1),t.clampWhenFinished=!0),this.managedActions.indexOf(t)<0&&this.managedActions.push(t),t}};st=t([o({inEditor:!0})],st);export{st as CharacterAnimationComponent};function rt(t,e){if(null==t)return e;const o=e.clone();A(o,L(e)),T(o,C(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 nt(t){return t.flatMap(t=>function(t){const e=[];return t.traverse(t=>{e.push(t)}),e}(t)).filter(t=>t instanceof l)}function at(t,e){if(!1===t||"function"==typeof t&&!1===t())throw new Error(e)}function lt(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 ht(t){let e;return t.traverse(t=>{(t instanceof l||t.isBone)&&null==e&&(e=t)}),e}function ct(t,e){let o=e;for(;null!=o;){if(o===t)return!0;o=o.parent}return!1}const dt=new Set;/*
1
+ import{__decorate as t}from"tslib";import{ActorComponent as e,Component as o}from"../../../component.js";import{canCrossFadeFromAnimationAction as i}from"../../../../animation/animation-action.js";import{RootMotionClip as s}from"../../../../animation/root-motion.js";import{inject as r}from"../../../../inject.js";import{ViewController as n}from"../../../../services/render.js";import{AnimationMixer as a,Bone as l,Object3D as h,LoopOnce as c,Raycaster as d,Vector3 as p,SkinnedMesh as u,Skeleton as f,Quaternion as g,Matrix4 as m,MathUtils as k,ArrowHelper as y,Group as S}from"three";import{getCharacterMovementLike as I}from"./character-movement-like.js";import{CCDIKSolver as P}from"three/addons/animation/CCDIKSolver.js";import{World as w}from"../../../../services/world.js";import{PhysicsSystem as v,RayTestResult as b}from"../../../../services/physics/physics-system.js";import{ArrayMap as x}from"../../../../../utils/collections.js";import{getAnimationClipRigId as L,getAnimationRigChainBoneNames as B,getAnimationRigDataFromObject as R,getAnimationRigIdFromObject as F,setAnimationClipRigId as A}from"../../../../animation/retarget.js";import{FootContactAnchor as D,getAnimationFootContacts as C,isFootInContact as M,setAnimationFootContacts as T}from"../../../../animation/foot-contact.js";const W=new p(0,-1,0),O=new p(0,1,0),q=new p(1,1,1),U=new g,V=new p,E=new p,H=new p,N=new p,z=new p,j=new g,Q=new g,G=new g,_=new g,$=new m,K=new m,Y=new p(1,0,0),J=new p(0,1,0),X=new p(0,0,1);function Z(){return{point:new p,normal:new p,hasNormal:!1}}const tt=["mixamorigHips","Hips","hips","Pelvis","pelvis"],et={upper:["LeftUpLeg","leftUpLeg","left_up_leg"],lower:["LeftLeg","leftLeg","left_leg"],foot:["LeftFoot","leftFoot","left_foot"]},ot={upper:["RightUpLeg","rightUpLeg","right_up_leg"],lower:["RightLeg","rightLeg","right_leg"],foot:["RightFoot","rightFoot","right_foot"]},it=["left","right"];let st=class extends e{constructor(){super(...arguments),this.viewController=r(n),this.poseProcessors=new x,this.transitionProcessors=[],this.managedActions=[],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.sequenceAnimationControlled=!1,this.sequenceAnimationReleasePending=!1,this.sequenceAnimationReleaseFrames=0,this.externalControlActive=!1,this.world=r(w),this.physicsSystem=r(v),this._footIkEnabled=!1,this.footIkMoving=!1,this.footIkLocomotionEnabled=!1,this.footIkLocomotionActive=!0,this.footIkMaxPlantTurnAngleDeg=35,this.footIkMaxPlantDrift=.18,this.footIkMaxPlantPelvisDrop=.12,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.ikPelvisDescendantStack=[],this.ikWorldUpdateNodes=[],this.footIkStateReset=!0,this.footIkUsingContacts=!1,this.footIkLastRootPosition=new p,this.footIkHasRootSample=!1,this.ikPreSolvePelvisPosition=new p,this.footIkPoseApplied=!1,this.footIkAnimationPoseCaptured=!1,this.footIkContactTransitionTime=0,this.footIkTransitionLeftContact=!1,this.footIkTransitionRightContact=!1,this.ikLegState={left:{anchor:new D,contactRequested:!1,targetPosition:new p,normal:new p(0,1,0),forward:new p(0,0,1),pitch:0,contactOffset:0,planted:!1,lastFootWorldPos:new p,hasLastFootSample:!1,weight:0,top:!1},right:{anchor:new D,contactRequested:!1,targetPosition:new p,normal:new p(0,1,0),forward:new p(0,0,1),pitch:0,contactOffset:0,planted:!1,lastFootWorldPos:new p,hasLastFootSample:!1,weight:0,top:!1}},this.ikWarnedMissingBones=!1,this.raycaster=new d,this.raycastIntersections=[],this.footIkRayTo=new p,this.footIkRayTestResult=new b,this.footIkRayTestOptions={debug:!1,excludeTriggers:!0,resolveActor:!1,collisionFilter:-2},this.footIkHits={center:Z(),toe:Z(),heel:Z(),side:Z()},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 g,lower:new g,foot:new g,footWorld:new g},right:{upper:new g,lower:new g,foot:new g,footWorld:new g}},this.ikSolveScratch={hip:new p,knee:new p,foot:new p,direction:new p,animatedDirection:new p,pole:new p,kneeTarget:new p,target:new p,currentDirection:new p,desiredDirection:new p,rotation:new g},this.getFullBodyClip=lt(t=>t.uuid,t=>rt(this.fullBodyMask,t)),this.getUpperBodyClip=lt(t=>t.uuid,t=>rt(this.upperBodyMask,t))}get isSequenceControlled(){return this.externalControlActive||this.sequenceAnimationControlled||this.sequenceAnimationReleasePending}get hasUpperBodyOverride(){return this.upperBodyOverride}get footIkEnabled(){return this._footIkEnabled}set footIkEnabled(t){this._footIkEnabled!==t&&(this.restoreFootIkPose(),this._footIkEnabled=t,null!=this.ikRoot&&(this.disposeFootIkDebug(),this.initializeFootIk(this.ikRoot,this.ikRootBone),this.syncFootIkDebug()))}onInit(){this.viewController.onUpdate(this.actor).subscribe(t=>this.updateInternal(t)),this.characterMovement=I(this.actor),this.footIkRayTestOptions.excludeActor=this.actor}onEndPlay(){this.restoreFootIkPose(),this.resetFootIkContacts(),this.disposeFootIkDebug()}raycastDownFirstValid(t,e,o){const i=this.world.scene;this.raycaster.set(t,W),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(W,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&&(ct(t,e)||ct(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 u||!0===e.isSkinnedMesh)return!0;e=e.parent}return!1}getRootMotionAction(){if(this.fullBodyAction.getClip()instanceof s)return this.fullBodyAction}getFullBodyAction(){return this.fullBodyAction}getFullBodySourceClip(){const t=this.fullBodyClip;return null!=t&&this.fullBodyAction?.getClip()===this.getFullBodyClip(t)?t:void 0}setup(t,e,o){this.restoreFootIkPose(),null!=e&&(this.upperBodyMask=nt(e),this.fullBodyMask=function(t,e){const o=new Set(nt(e).map(t=>t.uuid)),i=[];return t.traverse(t=>{(t instanceof l||t.isBone)&&!o.has(t.uuid)&&i.push(t)}),i}(ht(t),e)),null!=this.mixer&&this.mixer.stopAllAction(),this.mixer=new a(t),this.managedActions.length=0,this.animationRigId=F(t),this.animationRigData=R(t),this.ikRoot=t,this.ikRootBone=o,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))}}addTransitionProcessor(t){const e=this.transitionProcessors.findIndex(e=>e.id===t.id);return e>=0&&this.transitionProcessors.splice(e,1),this.transitionProcessors.push(t),()=>{const e=this.transitionProcessors.indexOf(t);e>=0&&this.transitionProcessors.splice(e,1)}}preparePoseTransition(t,e,o){if(0===this.transitionProcessors.length)return!1;const i=this.fullBodyAction,s=this.getFullBodySourceClip();if(null==i||null==s||i.getClip().uuid===e.uuid||this.isSequenceControlled||o.sequenceControlled||this.upperBodyOverride)return!1;const r=this.transitionContext??(this.transitionContext={});r.animation=this,r.source=i,r.sourceClip=s,r.targetClip=t,r.targetPoseClip=e,r.targetTimeScale=this.getPlaybackTimeScale(e,o.timeScale??1),r.options=o;for(const t of this.transitionProcessors)if(t.prepare(r))return!0;return!1}runPoseProcessors(t,e){if(0===this.poseProcessors.size||null==this.mixer||!this.poseProcessors.present(t))return;const o=this.mixer.getRoot();if(!(o instanceof h))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){if(null==this.mixer)return;if(this.externalControlActive)return;this.restoreFootIkPose(),this.upperBodyTimer+=t*(this.upperBodyAction?.timeScale??1),this.fullBodyTimer+=t*(this.fullBodyAction?.timeScale??1);let e=!1;this.sequenceAnimationReleasePending&&(this.sequenceAnimationReleaseFrames>0?(e=!0,this.sequenceAnimationReleaseFrames--):(this.sequenceAnimationReleasePending=!1,this.currentFullBodyPriority=-1,this.sequenceAnimationControlled=!1,this.overrideFadeTime=null,this.fullBodyTimer=0)),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.sequenceAnimationControlled&&!this.sequenceAnimationReleasePending&&this.fullBodyAction&&this.fullBodyAction.loop===c&&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),e||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.captureFootIkAnimationPose(),this.runPoseProcessors("beforeIk",t),this.updateFootIk(t),this.runPoseProcessors("afterIk",t)}initializeFootIk(t,e){if(this.resetFootIkContacts(),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.ikWorldUpdateNodes.length=0,this.footIkStateReset=!0,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=B(this.animationRigData,"leftLeg"),r=B(this.animationRigData,"rightLeg"),n=this.resolveLegBoneRefs(i,this.leftLegIkBones,et,s),a=this.resolveLegBoneRefs(i,this.rightLegIkBones,ot,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.rebuildFootIkWorldUpdateNodes(),this.ikLegState.left.targetPosition.copy(n.foot.getWorldPosition(V)),this.ikLegState.right.targetPosition.copy(a.foot.getWorldPosition(V)),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=!1,this.ikLegState.right.planted=!1,this.ikLegState.left.lastFootWorldPos.copy(n.foot.getWorldPosition(V)),this.ikLegState.right.lastFootWorldPos.copy(a.foot.getWorldPosition(V)),this.ikLegState.left.hasLastFootSample=!1,this.ikLegState.right.hasLastFootSample=!1;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??ht(t);if(null==p)return;let u=i.getBoneByName("_IKTargetLeftFoot"),g=i.getBoneByName("_IKTargetRightFoot"),k=!1;if(null==u&&(u=new l,u.name="_IKTargetLeftFoot",p.add(u),k=!0),null==g&&(g=new l,g.name="_IKTargetRightFoot",p.add(g),k=!0),this.setBoneWorldPosition(u,n.foot.getWorldPosition(V)),this.setBoneWorldPosition(g,a.foot.getWorldPosition(V)),k||i.bones.indexOf(u)<0||i.bones.indexOf(g)<0){const e=i.bones.slice(),o=i.boneInverses.map(t=>t.clone());e.indexOf(u)<0&&(e.push(u),o.push((new m).copy(u.matrixWorld).invert())),e.indexOf(g)<0&&(e.push(g),o.push((new m).copy(g.matrixWorld).invert()));const s=new f(e,o);t.traverse(t=>{const e=t;!0===e.isSkinnedMesh&&e.skeleton===i&&e.bind(s,e.bindMatrix)})}this.ikTargetBones={left:u,right:g},this.rebuildFootIkWorldUpdateNodes();const y=o.skeleton.bones,S={target:y.indexOf(u),effector:y.indexOf(n.foot),links:[{index:y.indexOf(n.lower)},{index:y.indexOf(n.upper)}],iteration:8},I={target:y.indexOf(g),effector:y.indexOf(a.foot),links:[{index:y.indexOf(a.lower)},{index:y.indexOf(a.upper)}],iteration:8};if(S.target<0||S.effector<0||S.links.some(t=>t.index<0)||I.target<0||I.effector<0||I.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 P(o,[S,I])}findFirstSkinnedMesh(t){let e;return t.traverse(t=>{null==e&&(t instanceof u||!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,...tt].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(V),o=t.lower.getWorldPosition(E),i=t.foot.getWorldPosition(H),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(V.copy(e).applyMatrix4($.copy(o.matrixWorld).invert())),t.quaternion.copy(U),t.scale.copy(q),t.updateMatrixWorld(!0)}syncFootIkDebug(){this.footIkDebug&&null!=this.ikRoot?(null!=this.ikDebugRoot&&null!=this.ikDebugLegs||(this.ikDebugRoot=new S,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 S;o.name=t,o.userData.footIkDebug=!0;const i=this.createDebugArrow(e),s=this.createDebugArrow(e),r=this.createDebugArrow(e),n=this.createDebugArrow(e),a=this.createDebugArrow(65280),l=this.createDebugArrow(6750054),h=this.createDebugArrow(16711935),c=this.createDebugArrow(16776960),d=this.createDebugArrow(16737792);return o.add(i,s,r,n,a,l,h,c,d),{root:o,rayCenter:i,rayToe:s,rayHeel:r,raySide:n,hitNormal:a,footUp:l,footToTarget:h,solveUpper:c,solveLower:d}}createDebugArrow(t){const e=new y(O,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){V.subVectors(o,e);const i=V.length();i<1e-6?t.visible=!1:(t.visible=!0,t.position.copy(e),t.setDirection(V.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.footIkUsingContacts=!1,this.footIkLocomotionEnabled){const e=this.fullBodyAction,o=e?.getClip(),i=C(o);if(!this.footIkLocomotionActive||this.isSequenceControlled||null==i||null==e||e.getEffectiveWeight()<.65||!Number.isFinite(t)||t<0)return this.resetFootIkContacts(),void this.resetDebugVisibility();(this.footIkContactClip!==o||t>.2)&&(this.resetFootIkContacts(),this.footIkContactClip=o);const s=this.actor.object.getWorldPosition(V),r=(this.movementSpeed??0)*Math.max(0,t);this.footIkHasRootSample&&this.footIkLastRootPosition.distanceToSquared(s)>(1+r)**2&&(this.resetFootIkContacts(),this.footIkContactClip=o),this.footIkLastRootPosition.copy(s),this.footIkHasRootSample=!0,this.footIkUsingContacts=!0;const n=e.loop!==c;this.footIkContactTransitionTime=Math.max(0,this.footIkContactTransitionTime-t),this.ikLegState.left.contactRequested=this.footIkContactTransitionTime>0?this.footIkTransitionLeftContact:M(i.left,e.time,o.duration,n),this.ikLegState.right.contactRequested=this.footIkContactTransitionTime>0?this.footIkTransitionRightContact:M(i.right,e.time,o.duration,n)}if(!this.footIkUsingContacts&&!this.footIkMoving&&(this.movementSpeed??0)>.01)return this.footIkStateReset||(this.syncFootIkWorldMatrices(),this.resetFootIkState(),this.footIkStateReset=!0),void this.resetDebugVisibility();this.syncFootIkWorldMatrices(),this.footIkStateReset=!1;const e=this.characterMovement?.isGrounded??!0;if(this.footIkSimpleTiltOnly)return 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);if(null==this.ikLegLengths||null==this.ikTargetBones||null==this.ikSkinnedMesh||null==this.ikSolver)return this.updatePelvisOffset(t,!1),void this.resetDebugVisibility();if(this.footIkUsingContacts&&null!=this.ikPelvisBone&&this.ikPreSolvePelvisPosition.copy(this.ikPelvisBone.position),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.footIkUsingContacts&&!this.footIkAnimationPoseCaptured&&this.getCurrentWorldQuaternion(this.ikBoneRefs.left.foot,this.ikPreSolve.left.footWorld),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),this.footIkUsingContacts&&!this.footIkAnimationPoseCaptured&&this.getCurrentWorldQuaternion(this.ikBoneRefs.right.foot,this.ikPreSolve.right.footWorld),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.footIkUsingContacts?(this.ikLegState.left.weight>.001&&this.solveTwoBoneLeg("left",this.ikBoneRefs.left,this.ikLegState.left.targetPosition),this.ikLegState.right.weight>.001&&this.solveTwoBoneLeg("right",this.ikBoneRefs.right,this.ikLegState.right.targetPosition)):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.footIkUsingContacts){this.syncFootIkWorldMatrices();for(const t of it){const e=this.ikBoneRefs[t].foot,o=this.getCurrentWorldQuaternion(e.parent,j);e.quaternion.copy(o.invert().multiply(this.ikPreSolve[t].footWorld))}this.footIkPoseApplied=!0}this.applySimpleFootPitch("left",this.ikBoneRefs.left.foot,this.ikLegState.left),this.applySimpleFootPitch("right",this.ikBoneRefs.right.foot,this.ikLegState.right)}resetFootIkState(){if(null!=this.ikBoneRefs){for(const t of it){const e=this.ikBoneRefs[t],o=this.ikLegState[t],i=V.setFromMatrixPosition(e.foot.matrixWorld);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,o.anchor.reset()}this.ikPelvisOffsetY=0}}resetFootIkContacts(){for(const t of it){const e=this.ikLegState[t];e.anchor.reset(),e.contactRequested=!1,e.planted=!1,e.weight=0,e.hasLastFootSample=!1}this.footIkContactClip=void 0,this.footIkHasRootSample=!1,this.ikPelvisOffsetY=0,this.footIkContactTransitionTime=0}preserveFootIkContacts(t,e){this.footIkEnabled&&this.footIkLocomotionEnabled&&e>0&&(this.footIkContactClip=t,this.footIkTransitionLeftContact=this.ikLegState.left.anchor.locked,this.footIkTransitionRightContact=this.ikLegState.right.anchor.locked,this.footIkContactTransitionTime=e)}restoreFootIkPose(){if(this.footIkPoseApplied&&null!=this.ikBoneRefs){for(const t of it){const e=this.ikBoneRefs[t],o=this.ikPreSolve[t];e.upper.quaternion.copy(o.upper),e.lower.quaternion.copy(o.lower),e.foot.quaternion.copy(o.foot)}this.ikPelvisBone?.position.copy(this.ikPreSolvePelvisPosition),this.footIkPoseApplied=!1}}captureFootIkAnimationPose(){this.footIkAnimationPoseCaptured=!1,this.footIkEnabled&&this.footIkLocomotionEnabled&&this.footIkLocomotionActive&&!this.isSequenceControlled&&null!=this.ikBoneRefs&&null!=C(this.fullBodyAction?.getClip())&&(this.syncFootIkWorldMatrices(),this.getCurrentWorldQuaternion(this.ikBoneRefs.left.foot,this.ikPreSolve.left.footWorld),this.getCurrentWorldQuaternion(this.ikBoneRefs.right.foot,this.ikPreSolve.right.footWorld),this.footIkAnimationPoseCaptured=!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 it){const e=this.ikBoneRefs[t],i=this.ikLegLengths[t],s=this.ikLegState[t];if(!s.planted)continue;const r=V.setFromMatrixPosition(e.upper.matrixWorld),n=.998*i.total,a=this.computeRequiredPelvisDrop(r,s.targetPosition,n);if(a>0){const e="left"===t?"right":"left";this.ikLegState[e].top=!0}o=Math.min(o,-a)}const t=this.footIkUsingContacts?Math.min(this.footIkPelvisMaxOffsetDown,this.footIkMaxPlantPelvisDrop):this.footIkPelvisMaxOffsetDown;o=k.clamp(o,-t,this.footIkPelvisMaxOffsetUp)}const i=1-Math.exp(-this.footIkPelvisLerpSpeed*t);this.ikPelvisOffsetY=k.lerp(this.ikPelvisOffsetY,o,i);const s=E.setFromMatrixPosition(this.ikPelvisBone.matrixWorld),r=H.copy(s).addScaledVector(O,this.ikPelvisOffsetY);null==this.ikPelvisBone.parent?this.ikPelvisBone.position.copy(r):this.ikPelvisBone.position.copy(r.applyMatrix4($.copy(this.ikPelvisBone.parent.matrixWorld).invert())),this.updatePelvisWorldTranslation(s)}updatePelvisWorldTranslation(t){const e=this.ikPelvisBone;if(null==e)return;e.updateMatrix(),null==e.parent?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(e.parent.matrixWorld,e.matrix),e.matrixWorldNeedsUpdate=!1;const o=e.matrixWorld.elements,i=o[12]-t.x,s=o[13]-t.y,r=o[14]-t.z;if(0===i&&0===s&&0===r)return;const n=this.ikPelvisDescendantStack;n.length=0;for(let t=0;t<e.children.length;t++)n.push(e.children[t]);for(;n.length>0;){const t=n.pop(),e=t.matrixWorld.elements;e[12]+=i,e[13]+=s,e[14]+=r,t.matrixWorldNeedsUpdate=!1;for(let e=0;e<t.children.length;e++)n.push(t.children[e])}}rebuildFootIkWorldUpdateNodes(){const t=this.ikRoot,e=this.ikBoneRefs;if(null==t||null==e)return void(this.ikWorldUpdateNodes.length=0);const o=new Set,i=[this.ikPelvisBone,e.left.upper,e.left.lower,e.left.foot,e.right.upper,e.right.lower,e.right.foot,this.ikTargetBones?.left,this.ikTargetBones?.right];for(const e of i){let i=e;for(;null!=i&&(o.add(i),i!==t);)i=i.parent??void 0}this.ikWorldUpdateNodes.length=0,t.traverse(t=>{o.has(t)&&this.ikWorldUpdateNodes.push(t)})}syncFootIkWorldMatrices(){const t=this.ikRoot;if(null!=t){t.updateWorldMatrix(!0,!1);for(const e of this.ikWorldUpdateNodes)e!==t&&(e.matrixAutoUpdate&&e.updateMatrix(),e.matrixWorldAutoUpdate&&(null==e.parent?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(e.parent.matrixWorld,e.matrix)),e.matrixWorldNeedsUpdate=!1)}}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(E),h=H.copy(n.upLocal).applyQuaternion(this.getCurrentWorldQuaternion(o,j)).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=$.copy(t.boneInverses[i]).invert(),n=K.copy(r).multiply(s),d=V.setFromMatrixPosition(n),p=N.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;if(this.footIkUsingContacts)return t.contactRequested;const n=this.footIkPlantReleaseExtension,a=this.footIkPlantAttachExtension,l=this.footIkPlantReleaseLift,h=this.footIkPlantAttachLift;return t.planted?!(i>this.footIkPlantReleaseUpSpeed&&(s<n||r>l)):s>=a&&r<=h||i<=0&&s>=n}computeLegExtensionRatio(t,e){const o=V.setFromMatrixPosition(t.upper.matrixWorld),i=E.setFromMatrixPosition(t.foot.matrixWorld),s=o.distanceTo(i);return e.total<=1e-6?1:k.clamp(s/e.total,0,1.2)}computeRequiredPelvisDrop(t,e,o){const i=N.subVectors(t,e),s=i.length();if(s<=o+1e-6)return 0;const r=i.dot(O),n=o*o-Math.max(s*s-r*r,0);if(n<=0)return s-o;const a=Math.sqrt(n),l=r-a,h=r+a;return l>=0?l:h>=0?h:0}updateLegTiltSimple(t,e,o,i,s){const r=this.footIkScratch,n=this.footIkHits,a=r.footWorldPos.setFromMatrixPosition(e.matrixWorld),l=this.computeFootVerticalSpeed(o,a,s),h=this.resolveFootAxes(t,e,this.footIkAxesScratch),c=this.resolveGroundSampleAxes(t,e,h,this.footIkSampleAxesScratch),d=r.centerRayStart.copy(a).addScaledVector(O,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),y=this.getFirstGroundHit(u,n.heel),S=this.getFirstGroundHit(f,n.side),I=r.desiredNormal.set(0,1,0),P=r.desiredForward.copy(c.forward);let w=0,v=0,b=this.footIkWeightOutSpeed;const x=null!=g||null!=m||null!=y;let L=a.y;null!=g?L=g.point.y:null!=m&&null!=y?L=.5*(m.point.y+y.point.y):null!=m?L=m.point.y:null!=y&&(L=y.point.y);const B=this.ikBoneRefs?.[t],R=this.ikLegLengths?.[t],F=null!=B&&null!=R?this.computeLegExtensionRatio(B,R):1,A=Math.max(0,a.y-L,a.y-o.targetPosition.y),D=this.shouldPlantFoot(o,!this.footIkRequireGrounded||i,x,l,F,A);D?this.computeDesiredGroundNormal(c,g,m,y,S,I)&&(this.computeDesiredFootForward(c.forward,c.right,I,m,y,P),w=this.computeDesiredPitchAngle(m,y,c.forward),v=1,b=this.footIkWeightInSpeed):this.computeDesiredFootForward(c.forward,c.right,I,null,null,P);const C=1-Math.exp(-this.footIkPositionLerpSpeed*s),M=1-Math.exp(-b*s);o.normal.lerp(I,C).normalize(),o.forward.lerp(P,C).normalize(),o.pitch=k.lerp(o.pitch,w,C),o.weight=k.lerp(o.weight,v,M),o.planted=D&&v>.001,this.updateFootSample(o,a),this.applySimpleFootPitch(t,e,o),this.footIkDebug&&this.updateLegDebug(t,{footWorldPos:a,centerRayStart:d,toeRayStart:p,heelRayStart:u,sideRayStart:f,centerHit:g,toeHit:m,heelHit:y,sideHit:S,desiredNormal:o.normal,desiredTargetPos:r.footWorldPos,weight:o.weight})}updateLegIkTarget(t,e,o,i,s,r,n){const a=this.footIkScratch,l=this.footIkHits,h=e.foot,c=a.footWorldPos.setFromMatrixPosition(h.matrixWorld);if(this.footIkUsingContacts&&!s.contactRequested)return s.anchor.reset(),s.planted=!1,s.weight*=Math.exp(-this.footIkWeightOutSpeed*n),s.pitch*=Math.exp(-this.footIkRotationLerpSpeed*n),s.weight<=.001?s.targetPosition.copy(c):s.targetPosition.lerp(c,1-Math.exp(-this.footIkPositionLerpSpeed*n)),this.clampDesiredFootTarget(e,o,c,s.targetPosition),this.updateFootSample(s,c),this.setBoneWorldPosition(i,s.targetPosition),void(null!=this.ikDebugLegs&&(this.ikDebugLegs[t].root.visible=!1));const d=this.computeFootVerticalSpeed(s,c,n),p=this.resolveFootAxes(t,h,this.footIkAxesScratch),u=this.resolveGroundSampleAxes(t,h,p,this.footIkSampleAxesScratch),f=this.footIkUsingContacts&&s.anchor.locked&&s.contactRequested?s.anchor.position:c,g=a.centerRayStart.copy(f).addScaledVector(O,this.footIkRayStartHeight),m=a.toeRayStart.copy(g).addScaledVector(u.forward,this.footIkForwardSampleDistance),y=a.heelRayStart.copy(g).addScaledVector(u.forward,-this.footIkForwardSampleDistance),S=a.sideRayStart.copy(g).addScaledVector(u.right,this.footIkSideSampleDistance),I=this.getFirstGroundHit(g,l.center),P=this.getFirstGroundHit(m,l.toe),w=this.getFirstGroundHit(y,l.heel),v=this.getFirstGroundHit(S,l.side),b=a.desiredTargetPos.copy(c),x=a.desiredNormal.set(0,1,0),L=a.desiredForward.copy(u.forward);let B=0,R=0,F=this.footIkWeightOutSpeed;const A=null!=I||null!=P||null!=w;let D=c.y;null!=I?D=I.point.y:null!=P&&null!=w?D=.5*(P.point.y+w.point.y):null!=P?D=P.point.y:null!=w&&(D=w.point.y);const C=this.computeLegExtensionRatio(e,o),M=Math.max(0,c.y-D,c.y-s.targetPosition.y),T=this.shouldPlantFoot(s,!this.footIkRequireGrounded||r,A,d,C,M);if(T){if(b.copy(c),this.computeDesiredGroundNormal(u,I,P,w,v,x)){this.computeDesiredFootForward(u.forward,u.right,x,P,w,L),B=this.computeDesiredPitchAngle(P,w,u.forward);const t=Math.max(0,Math.sin(B))*this.footIkForwardSampleDistance*.45,e=Math.max(this.footIkFootOffset+this.footIkExtraClearance,s.contactOffset);b.y=D+e+t,s.top&&!this.footIkUsingContacts&&(b.y-=this.ikPelvisOffsetY/2),R=1,F=this.footIkWeightInSpeed}}else this.computeDesiredFootForward(u.forward,u.right,x,null,null,L),b.copy(c),this.footIkUsingContacts||(b.y+=this.footIkFootOffset);if(this.footIkUsingContacts){const t=z.setFromMatrixPosition(e.upper.matrixWorld),i=this.footIkPelvisEnabled?Math.min(this.footIkMaxPlantPelvisDrop,this.footIkPelvisMaxOffsetDown):0;s.anchor.locked&&Math.abs(b.y-s.anchor.position.y)>.08&&s.anchor.release();s.anchor.update(s.contactRequested,(!this.footIkRequireGrounded||r)&&null!=I&&R>0,c,b,u.forward,t,.995*o.total,i,Math.min(this.footIkMaxPlantDrift,this.footIkMaxHorizontalOffset),k.degToRad(this.footIkMaxPlantTurnAngleDeg))?b.copy(s.anchor.position):(b.copy(c),R=0,F=this.footIkWeightOutSpeed)}const W=1-Math.exp(-this.footIkPositionLerpSpeed*n),q=1-Math.exp(-F*n);this.footIkUsingContacts&&s.anchor.locked?s.targetPosition.copy(b):s.targetPosition.lerp(b,W),this.clampDesiredFootTarget(e,o,c,s.targetPosition),s.normal.lerp(x,W).normalize(),s.forward.lerp(L,W).normalize(),s.pitch=k.lerp(s.pitch,B,W),s.weight=k.lerp(s.weight,R,q),s.planted=T&&R>.001,this.updateFootSample(s,c),this.setBoneWorldPosition(i,s.targetPosition),this.footIkDebug&&this.updateLegDebug(t,{footWorldPos:c,centerRayStart:g,toeRayStart:m,heelRayStart:y,sideRayStart:S,centerHit:I,toeHit:P,heelHit:w,sideHit:v,desiredNormal:x,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(W,this.footIkRayLength),a=e.toeHit?.point??r.debugRayEndB.copy(e.toeRayStart).addScaledVector(W,this.footIkRayLength),l=e.heelHit?.point??r.debugRayEndC.copy(e.heelRayStart).addScaledVector(W,this.footIkRayLength),h=e.sideHit?.point??r.debugRayEndD.copy(e.sideRayStart).addScaledVector(W,this.footIkRayLength);this.setDebugArrow(o.rayCenter,e.centerRayStart,n),this.setDebugArrow(o.rayToe,e.toeRayStart,a),this.setDebugArrow(o.rayHeel,e.heelRayStart,l),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.getCurrentWorldDirection(this.actor.object,N);n.addScaledVector(O,-n.dot(O)),n.lengthSq()<1e-8&&n.copy(s.forward).addScaledVector(O,-s.forward.dot(O)),n.lengthSq()<1e-8&&n.set(0,0,1),n.normalize();const a=z.crossVectors(O,n);return a.lengthSq()<1e-8?a.copy(s.right):a.normalize(),a.dot(s.right)<0&&a.multiplyScalar(-1),r.forward.copy(n),r.right.copy(a),r}computeDesiredGroundNormal(t,e,o,i,s,r){const n=this.computeAverageHitNormal(e,o,i,s,N);let a=!1,l=0,h=0;if(null!=o&&null!=i){const e=E.subVectors(o.point,i.point).dot(t.forward);Math.abs(e)>1e-5&&(l=(o.point.y-i.point.y)/e,a=!0)}if(null!=s&&null!=e){const o=H.subVectors(s.point,e.point).dot(t.right);Math.abs(o)>1e-5&&(h=(s.point.y-e.point.y)/o,a=!0)}if(a&&(r.copy(O),r.addScaledVector(t.forward,-l),r.addScaledVector(t.right,-h),r.lengthSq()>1e-8?r.normalize():a=!1),a)null!=n&&r.dot(n)<0&&r.multiplyScalar(-1);else{if(null==n)return!1;r.copy(n),a=!0}return r.dot(O)<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.getCurrentWorldDirection(this.actor.object,N)),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=N.copy(this.getCurrentWorldDirection(this.actor.object,N));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=E.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=k.degToRad(this.footIkMaxSlopeAngleDeg);return k.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=j.copy(e.quaternion),a=Q.setFromAxisAngle(i.rightLocal,s*r);e.quaternion.copy(n.multiply(a))}resolveLocalPitchSign(t){const e=G.setFromAxisAngle(t.rightLocal,.15);return H.copy(t.upLocal).applyQuaternion(e).sub(t.upLocal).dot(t.forwardLocal)>=0?1:-1}clampDesiredFootTarget(t,e,o,i){const s=E.subVectors(i,o),r=s.dot(O),n=H.copy(s).addScaledVector(O,-r),a=n.length();a>this.footIkMaxHorizontalOffset&&a>1e-6&&n.multiplyScalar(this.footIkMaxHorizontalOffset/a);const l=k.clamp(r,-this.footIkMaxVerticalOffsetDown,this.footIkMaxVerticalOffsetUp);if(i.copy(o),i.add(n),i.addScaledVector(O,l),this.footIkPelvisEnabled)return;const h=t.upper.getWorldPosition(V).clone(),c=E.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=this.ikSolveScratch,s=i.hip.setFromMatrixPosition(e.upper.matrixWorld),r=i.knee.setFromMatrixPosition(e.lower.matrixWorld),n=i.foot.setFromMatrixPosition(e.foot.matrixWorld),a=s.distanceTo(r),l=r.distanceTo(n);if(a<1e-5||l<1e-5)return;const h=i.direction.subVectors(o,s),c=h.length();if(c<1e-5)return;const d=Math.abs(a-l)+1e-5,p=a+l-1e-5,u=k.clamp(c,d,p),f=h.multiplyScalar(1/c),g=i.animatedDirection.subVectors(n,s).normalize(),m=i.pole.subVectors(r,s);m.addScaledVector(g,-m.dot(g)),m.lengthSq()<a*a*1e-4&&(this.getCurrentWorldDirection(this.actor.object,m),m.addScaledVector(g,-m.dot(g)),m.lengthSq()<1e-8&&(Math.abs(g.x)<.9?m.set(1,0,0):m.set(0,1,0),m.addScaledVector(g,-m.dot(g)))),m.normalize(),i.rotation.setFromUnitVectors(g,f),m.applyQuaternion(i.rotation);const y=(u*u+a*a-l*l)/(2*u),S=Math.max(a*a-y*y,0),I=Math.sqrt(S),P=i.kneeTarget.copy(s).addScaledVector(f,y).addScaledVector(m,I),w=i.target.copy(s).addScaledVector(f,u);this.rotateBoneToward(e.upper,s,r,P),e.upper.updateMatrixWorld(!0);const v=r.setFromMatrixPosition(e.lower.matrixWorld),b=n.setFromMatrixPosition(e.foot.matrixWorld);this.rotateBoneToward(e.lower,v,b,w),e.lower.updateMatrixWorld(!0),this.updateSolveDebug(t,s,P,w)}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=this.ikSolveScratch.currentDirection.subVectors(o,e),r=this.ikSolveScratch.desiredDirection.subVectors(i,e);if(s.lengthSq()<1e-10||r.lengthSq()<1e-10)return;if(s.normalize(),r.normalize(),s.dot(r)>1-1e-10)return;const n=this.ikSolveScratch.rotation.setFromUnitVectors(s,r),a=this.getCurrentWorldQuaternion(t,j),l=Q.copy(n).multiply(a);if(null==t.parent)return void t.quaternion.copy(l);const h=this.getCurrentWorldQuaternion(t.parent,G),c=_.copy(h).invert().multiply(l);t.quaternion.copy(c)}detectFootAxisBasis(t){const e=this.getCurrentWorldQuaternion(t,j),o=this.getCurrentWorldDirection(this.actor.object,V);o.lengthSq()<1e-6&&o.set(0,0,1),o.normalize();const i=[{local:Y.clone(),world:Y.clone().applyQuaternion(e)},{local:J.clone(),world:J.clone().applyQuaternion(e)},{local:X.clone(),world:X.clone().applyQuaternion(e)}];i.push({local:Y.clone().multiplyScalar(-1),world:Y.clone().multiplyScalar(-1).applyQuaternion(e)}),i.push({local:J.clone().multiplyScalar(-1),world:J.clone().multiplyScalar(-1).applyQuaternion(e)}),i.push({local:X.clone().multiplyScalar(-1),world:X.clone().multiplyScalar(-1).applyQuaternion(e)});let s=i[0],r=-1/0;for(const t of i){const e=t.world.dot(O);e>r&&(r=e,s=t)}let n=i[0],a=-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>a&&(a=e,n=t)}n.world.dot(o)<0&&(n={local:n.local.clone().multiplyScalar(-1),world:n.world.clone().multiplyScalar(-1)});const l=s.local.clone().normalize(),h=n.local.clone().normalize(),c=l.clone().cross(h).normalize();return{upLocal:l,forwardLocal:c.clone().cross(l).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=this.getCurrentWorldQuaternion(e,j);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}getCurrentWorldQuaternion(t,e){return t.matrixWorld.decompose(z,e,N),e}getCurrentWorldDirection(t,e){const o=t.matrixWorld.elements;return e.set(o[8],o[9],o[10]).normalize()}clampSlopeNormal(t){const e=k.clamp(t.dot(O),-1,1),o=Math.acos(e),i=k.degToRad(this.footIkMaxSlopeAngleDeg);if(o<=i||o<1e-5)return;const s=i/o;t.lerpVectors(O,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){j.copy(t.quaternion),t.quaternion.copy(e).slerp(j,o)}alignFootToGroundNormal(t,e,o,i){if(o.weight<=.001||null==e.parent)return;const s=this.ikFootAxes?.[t]??this.detectFootAxisBasis(e),r=V.copy(o.normal).normalize(),n=E.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 a=H.crossVectors(r,n);if(a.lengthSq()<1e-8)return;a.normalize(),n.copy(N.crossVectors(a,r)).normalize(),$.makeBasis(s.rightLocal,s.upLocal,s.forwardLocal),j.setFromRotationMatrix($),K.makeBasis(a,r,n),Q.setFromRotationMatrix(K);const l=G.copy(Q).multiply(_.copy(j).invert()),h=this.getCurrentWorldQuaternion(e.parent,_),c=Q.copy(h).invert().multiply(l),d=(1-Math.exp(-this.footIkRotationLerpSpeed*i))*o.weight;e.quaternion.slerp(c,k.clamp(d,0,1))}getMixer(){return this.mixer}evaluateExternalPose(t=0){null!=this.mixer&&(this.restoreFootIkPose(),this.runPoseProcessors("beforeMixer",t),this.mixer.update(t),this.runPoseProcessors("afterMixer",t),this.captureFootIkAnimationPose(),this.runPoseProcessors("beforeIk",t),this.updateFootIk(t),this.runPoseProcessors("afterIk",t))}beginExternalControl(){this.externalControlActive=!0}endExternalControl(){this.externalControlActive=!1}stopSequenceAnimation(){this.currentFullBodyPriority=-1,this.externalControlActive=!1,this.sequenceAnimationControlled=!1,this.sequenceAnimationReleasePending=!1,this.sequenceAnimationReleaseFrames=0,this.upperBodyOverride=!1,this.overrideFadeTimeUpper=null,this.fullBodyTimer=0}requestSequenceAnimationRelease(){this.externalControlActive=!1,this.sequenceAnimationControlled=!1,this.currentFullBodyPriority=-1,this.sequenceAnimationReleasePending=!0,this.sequenceAnimationReleaseFrames=1,this.upperBodyOverride=!1,this.overrideFadeTimeUpper=null}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={}){at(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 this.managedActions.indexOf(o)<0&&this.managedActions.push(o),o.setLoop(c,1),o.clampWhenFinished=!0,o.timeScale=e.timeScale??1,o.reset(),o.play(),this.fullBodyAction=o,this.externalControlActive=!0,o}syncMovementSpeed(t){null!=t&&(t.timeScale=this.getPlaybackTimeScale(t.getClip(),t.timeScale))}getPlaybackTimeScale(t,e){if(!(t instanceof s&&t.fixedInPlace&&null!=this.movementSpeed))return e;const o=this.mixer.getRoot(),i=o instanceof h?o.scale.x:1;return t.duration/t.displacement*this.movementSpeed/i}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)}cancelUpper(t){this.upperBodyOverride&&this.upperBodyAction?.getClip()===this.getUpperBodyClip(t)&&(this.upperBodyOverride=!1,this.currentUpperBodyPriority=-1,null!=this.fullBodyClip?this.upperBodyAction=this.transition(this.upperBodyAction,this.getUpperBodyClip(this.fullBodyClip)):(this.upperBodyAction?.stop(),this.upperBodyAction=null),this.overrideFadeTimeUpper=null)}play(t,e={}){at(null!=this.mixer,"Can't play animation before setup is called"),this.assertClipRigCompatible(t);const o=e.priority??1;if(o<this.currentFullBodyPriority)return;this.currentFullBodyPriority=o,this.fullBodyTimer=0,e.sequenceControlled&&(this.sequenceAnimationControlled=!0,this.sequenceAnimationReleasePending=!1,this.sequenceAnimationReleaseFrames=0);const i=this.getFullBodyClip(t);if(this.preparePoseTransition(t,i,e)){for(const t of this.managedActions)t.stop();this.managedActions.length=0,this.fullBodyAction=null,this.upperBodyAction=null}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,i,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=L(t);if(e===this.animationRigId||null==e&&null==this.animationRigId)return;const o=`${t.uuid}|${e??""}|${this.animationRigId??""}`;if(!dt.has(o)){if(dt.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 s=o?.fadeTime??this.fadeTime;if(null!=t&&t.getClip().uuid===e.uuid)return t.isRunning()||!1!==o.loop||!t.clampWhenFinished||o.sequenceControlled?(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(c,1),t.clampWhenFinished=!0)),t):t;if(i(t)){const i=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,i.crossFadeTo(r,s,!1),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(c,1),t.clampWhenFinished=!0),this.managedActions.indexOf(t)<0&&this.managedActions.push(t),t}};st=t([o({inEditor:!0})],st);export{st as CharacterAnimationComponent};function rt(t,e){if(null==t)return e;const o=e.clone();A(o,L(e)),T(o,C(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 nt(t){return t.flatMap(t=>function(t){const e=[];return t.traverse(t=>{e.push(t)}),e}(t)).filter(t=>t instanceof l)}function at(t,e){if(!1===t||"function"==typeof t&&!1===t())throw new Error(e)}function lt(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 ht(t){let e;return t.traverse(t=>{(t instanceof l||t.isBone)&&null==e&&(e=t)}),e}function ct(t,e){let o=e;for(;null!=o;){if(o===t)return!0;o=o.parent}return!1}const dt=new Set;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -60,6 +60,14 @@ export declare class CharacterMovementComponent extends ActorComponent {
60
60
  maxSpeedBackwards: number;
61
61
  maxSpeedSprint: number;
62
62
  maxSpeedCrouch: number;
63
+ swimmingEnabled: boolean;
64
+ maxSpeedSwimming: number;
65
+ /** Fraction of standing capsule height below the water surface while swimming. */
66
+ swimmingImmersion: number;
67
+ swimmingSurfaceResponse: number;
68
+ swimmingMaxVerticalSpeed: number;
69
+ /** Separate entry/exit depths prevent mode flickering at the waterline. */
70
+ swimmingDepthHysteresis: number;
63
71
  /** Enables crouch-press sliding without changing the existing steep-slope controller behavior. */
64
72
  slideEnabled: boolean;
65
73
  slideMinStartSpeed: number;
@@ -151,6 +159,10 @@ export declare class CharacterMovementComponent extends ActorComponent {
151
159
  private readonly groundRayTestOptions;
152
160
  private readonly physicsSystem;
153
161
  private readonly netService;
162
+ private readonly world;
163
+ private readonly waterVolumes;
164
+ private readonly waterProbe;
165
+ private swimmingSurfaceHeight;
154
166
  private readonly state;
155
167
  private readonly movementModes;
156
168
  private readonly savedMoves;
@@ -190,6 +202,10 @@ export declare class CharacterMovementComponent extends ActorComponent {
190
202
  registerMovementMode(strategy: NetCharacterMovementModeStrategy): void;
191
203
  applyImpulse(impulse: Vector3): void;
192
204
  getEffectiveGravity(): number;
205
+ /** Surface currently supporting swimming, in world units; null outside swimming. */
206
+ get swimmingWaterSurfaceHeight(): number | null;
207
+ /** Water surface intersecting the character while wading or swimming. */
208
+ get waterContactSurfaceHeight(): number | null;
193
209
  get isGrounded(): boolean;
194
210
  setRootMotionAction(action: AnimationAction, options?: RootMotionActionOptions): void;
195
211
  /**
@@ -215,6 +231,9 @@ export declare class CharacterMovementComponent extends ActorComponent {
215
231
  private performSubstep;
216
232
  private updateRotation;
217
233
  private applyMovement;
234
+ private getSwimmingDepth;
235
+ private updateWaterMovementMode;
236
+ private updateSwimmingMode;
218
237
  private updateModeAfterMove;
219
238
  private applyImpulseToVelocity;
220
239
  private sendSavedMoves;
@@ -1,4 +1,4 @@
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 l}from"../../../../animation/root-motion.js";import{inject as c}from"../../../../inject.js";import{ActionInput as d,AxisInput as u,RotationInput as m}from"../../../../input/index.js";import{NetRole as p}from"../../../../net/service/net-actor-role.js";import{RunOnClient as v,RunOnNotOwner as y,RunOnServer as g}from"../../../../net/service/rpc-decorator.js";import{NetService as S}from"../../../../net/service/net-service.js";import{PhysicsSystem as M,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 R}from"../../../component.js";import{CharacterMovementMode as A}from"./modes.js";import{calculateRootMotionTargetApproachCorrection as D,constrainRootMotionTargetApproach as q,warpRootMotionTargetApproach as b}from"./root-motion-constraint.js";import{DEFAULT_MAX_CLIENT_TIME_AHEAD as z,DEFAULT_LARGE_CORRECTION_THRESHOLD as k,DEFAULT_MAX_COMBINED_MOVE_DELTA_TIME as P,DEFAULT_MAX_MOVE_DELTA_TIME as I,DEFAULT_MAX_MOVES_PER_PACKET as G,DEFAULT_MAX_REPLAYED_MOVES as O,DEFAULT_MAX_SERVER_MOVES_PER_TICK as j,DEFAULT_MAX_SAVED_MOVES as Y,DEFAULT_MAX_SERVER_MOVE_DELTA_TIME_SCALAR as N,DEFAULT_MAX_SERVER_MOVE_TIME_BUDGET as F,DEFAULT_MAX_SUBSTEP_DELTA_TIME as V,DEFAULT_MOVE_SEND_INTERVAL as H,DEFAULT_SIMULATED_INTERPOLATION_DELAY as E,DEFAULT_SIMULATED_STATE_INTERVAL as U,DEFAULT_SMALL_CORRECTION_TOLERANCE as X,DEFAULT_TELEPORT_SNAP_THRESHOLD as L,MOVE_FLAG_CROUCH as B,MOVE_FLAG_JUMP as Z,MOVE_FLAG_ROOT_MOTION as W,MOVE_FLAG_SLIDE_START as $,MOVE_FLAG_SPRINT as Q,MOVE_FLAG_SPRINT_START as J,SNAPSHOT_FLAG_CROUCH_SUPPRESSED as K,SNAPSHOT_FLAG_CROUCHING as _,NetCharacterProxySmoother as tt,NetCharacterSavedMoveBuffer as et,accrueNetCharacterServerMoveTime as it,createNetCharacterMovementSnapshot as ot,createNetCharacterServerMoveTimingState as st,consumeNetCharacterServerMoveTime as nt,decodeNetCharacterMoveBatch as rt,decodeNetCharacterOwnerAck as at,decodeNetCharacterOwnerCorrection as ht,decodeNetCharacterSimulatedState as lt,encodeNetCharacterMoveBatch as ct,encodeNetCharacterOwnerAck as dt,encodeNetCharacterOwnerCorrection as ut,encodeNetCharacterSimulatedState as mt,validateNetCharacterMove as pt}from"./net-character-movement-protocol.js";import{NetMode as vt}from"../../../../net/net-session.js";import{setSlideJumpVelocity as yt,shouldContinueSlide as gt,shouldStartSlide as St,updateSlideVelocity as Mt,updateSlideVelocityFromDisplacement as ft}from"./character-slide.js";export*from"./net-character-movement-protocol.js";const xt=131070,Tt=new h(0,1,0),Ct=new h,wt=new h,Rt=new h,At=new h,Dt=new h,qt=new h,bt=new h,zt=new h,kt=new h,Pt=new h,It=new h,Gt=new h,Ot=new h,jt=new h,Yt=new h(0,1,0),Nt=new h(0,-.05,0),Ft=new h,Vt=new a,Ht=new s.Euler,Et=new h,Ut=new h,Xt=new h,Lt=new h,Bt=new i.CharacterCollision;let Zt=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()}teleport(t,e=this.actor.rotation.y){this.state.position.copy(t),this.state.velocity.set(0,0,0),this.state.yaw=e,this.actor.position.copy(t),this.actor.rotation.y=e,this.rotationInput.rotation.y=e,this.physicsSystem.setPosition(this.actor,t),this.physicsSystem.setRotation(this.actor,this.actor.quaternion),this.physicsSystem.flushModifiedBodyPositionsToColliders()}constructor(){super(),this.isDefaultCharacterMovementComponent=!0,this.directionInput=new u,this.jumpInput=new d,this.sprintInput=new d,this.crouchInput=new d,this.rotationInput=new m,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.maxSpeedCrouch=4,this.slideEnabled=!1,this.slideMinStartSpeed=8,this.slideMinExitSpeed=4,this.slideDeceleration=3,this.slideGravityScale=1,this.slideSteeringRate=2,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.movementInputEnabled=!0,this.rotateToMovementDirection=!1,this.smoothRotation=!0,this.rotationSpeed=40,this.maxRotationSpeed=100,this.impulseDamping=2,this.moveSendInterval=H,this.simulatedStateInterval=U,this.maxSavedMoves=Y,this.maxReplayedMoves=O,this.maxServerMovesPerTick=j,this.maxMovesPerPacket=G,this.maxMoveDeltaTime=I,this.maxCombinedMoveDeltaTime=P,this.maxServerMoveDeltaTimeScalar=N,this.maxClientTimeAhead=z,this.maxServerMoveTimeBudget=F,this.maxSubstepDeltaTime=V,this.fallGraceTime=.1,this.correctionToleranceSq=X*X,this.largeCorrectionThreshold=k,this.teleportSnapThreshold=L,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.slideDirection=new h,this.slideSurfaceNormal=new h(0,1,0),this.mode=A.walking,this.isSprinting=!1,this.isCrouching=!1,this.isSliding=!1,this.pressedJump=!1,this.rayTestResult=new f,this.groundRayTestOptions={debug:!1,excludeTriggers:!0,excludeActor:void 0,resolveActor:!1},this.physicsSystem=c(M),this.netService=c(S),this.state={sequence:0,position:new h,velocity:new h,yaw:0,lookYaw:0,mode:A.walking,grounded:!1,currentSpeed:0,fallGraceTime:0,prevInputDirection:new h,prevRotateToMovementDirection:!1},this.movementModes=new Map,this.savedMoves=new et(Y),this.serverMoveTiming=st(),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:wt,platformVelocity:At,outVelocity:Rt,rootMotionActive:!1,startedSprinting:!1},this.proxySmoother=new tt(E,L),this.proxySample=ot(),this.pendingSnapshot=ot(),this.impulse=new h,this.prevRootMotionPos=new h,this.rootMotionOptions={},this.rootMotionTargetConstraints=new Set,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.previousCrouchInput=!1,this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.initialized=!1,this.cc=this.physicsSystem.getCharacterController(.1),this.cc.enableSnapToGround(.1),this.cc.enableAutostep(0,.1,!1),this.registerMovementMode(Wt),this.registerMovementMode($t),this.registerMovementMode({mode:A.sliding,update:t=>this.updateSlidingMode(t)})}onInit(){this.groundRayTestOptions.excludeActor=this.actor,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 l){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)}}addRootMotionTargetConstraint(t,e,i=0){const o={targetPosition:t,minimumHorizontalDistance:Math.max(0,e),maximumAddedHorizontalDistance:Math.max(0,i),initialHorizontalDistance:Math.hypot(t.x-this.actor.position.x,t.z-this.actor.position.z),addedHorizontalDistance:0,requestedProgress:0};this.rootMotionTargetConstraints.add(o);let s=!1;return{setProgress:t=>{o.requestedProgress=Math.max(o.requestedProgress,Math.min(1,Math.max(0,t)))},dispose:()=>{s||(s=!0,this.rootMotionTargetConstraints.delete(o))}}}serverMove(t){const e=rt(t);if(e.ok)for(const t of e.value.moves)pt(t,this.lastServerReceivedSequence,this.maxMoveDeltaTime)&&(this.lastServerReceivedSequence=t.sequence,this.serverMoveQueue.push(t))}clientMoveAck(t){const e=at(t);e.ok&&this.actor.netRole===p.autonomousProxy&&(this.savedMoves.ack(e.value.sequence),this.sprintPolicy?.ack?.(e.value.sequence,!1))}clientMoveCorrection(t){const e=ht(t);e.ok&&this.actor.netRole===p.autonomousProxy&&(this.debugCorrections&&(null==this.correctionDebug&&(this.correctionDebug=new _t(ee(this.actor.object))),this.correctionDebug.update(this.state.position,e.value.snapshot)),this.applyCorrection(e.value.snapshot))}simulatedState(t){const e=lt(t);e.ok&&this.actor.netRole===p.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!==p.simulatedProxy?this.enabled&&(e!==p.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,ie),this.resetToggleCrouchAfterSlide(e);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.state.mode,o=this.createMoveFromInput(t,++this.nextMoveSequence);this.performMove(o,ie),this.resetToggleCrouchAfterSlide(i),e!==vt.none&&this.sendSimulatedState(t,!1)}resetToggleCrouchAfterSlide(t){t===A.sliding&&this.state.mode!==A.sliding&&"toggle"===this.crouchInput.mode&&this.crouchInput.activated&&this.crouchInput.setActivated(!1)}tickRemoteAuthority(t){it(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=Xt.copy(this.actor.position);let n=!1;for(let t=0;t<o;t++){const t=this.serverMoveQueue.shift();if(null==t)break;if(!pt(t,this.lastServerProcessedSequence,this.maxMoveDeltaTime)){console.log("Net: Invalid move",t),this.sendOwnerCorrection(!0),e=!0;continue}const i=nt(this.serverMoveTiming,t,{maxMoveDeltaTime:this.maxMoveDeltaTime,maxServerMoveDeltaTimeScalar:this.maxServerMoveDeltaTimeScalar,maxClientTimeAhead:this.maxClientTimeAhead});if(i<0){this.sendOwnerCorrection(!0),e=!0;continue}const o=Jt(t,this.authoritativeMoveScratch);o.dt=i,o.rootMotionX=0,o.rootMotionY=0,o.rootMotionZ=0,o.flags&=~W,this.performMove(o,{immediate:!0,savedRootMotion:!1}),n=!0,this.lastServerProcessedSequence=o.sequence;const s=Kt(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(dt(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);Lt.subVectors(t,e);const i=Lt.lengthSq();i>1e-8&&(i>this.listenServerNoSmoothUpdateDistance*this.listenServerNoSmoothUpdateDistance?this.visualSmoothingOffset.set(0,0,0):(i>this.listenServerMaxSmoothUpdateDistance*this.listenServerMaxSmoothUpdateDistance&&Lt.setLength(this.listenServerMaxSmoothUpdateDistance),this.visualSmoothingOffset.add(Lt)))}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===p.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(bt);const a=this.crouchInput.activated,h=a&&!this.previousCrouchInput;this.previousCrouchInput=a;const l=this.movementInputEnabled&&!a&&this.sprintInput.activated,c=l&&!this.previousSprintInput;this.previousSprintInput=l;const d=(this.movementInputEnabled&&this.jumpInput.activated?Z:0)|(l?Q:0)|(a?B:0)|(this.movementInputEnabled&&h&&this.slideEnabled?$:0)|(c?J:0)|(bt.lengthSq()>0?W:0),u=function(t,e){e.set(t.x,0,t.y),e.lengthSq()>1&&e.normalize();return e}(this.directionInput.vector,Et);this.movementInputEnabled||u.set(0,0,0);const m=this.inputMoveScratch;return m.sequence=e>>>0,m.clientTime=s,m.dt=n,m.inputX=u.x,m.inputY=u.z,m.yaw=this.rotationInput.rotation.y,m.flags=d,m.clientX=this.state.position.x,m.clientY=this.state.position.y,m.clientZ=this.state.position.z,m.rootMotionX=bt.x,m.rootMotionY=bt.y,m.rootMotionZ=bt.z,m}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&Q)&&0===(t.flags&B);this.sprintPolicy?.update?.(i,t.sequence,s),Gt.set(e.savedRootMotion?t.rootMotionX:0,e.savedRootMotion?t.rootMotionY:0,e.savedRootMotion?t.rootMotionZ:0),e.savedRootMotion||this.sampleRootMotion(Gt);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),Gt,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=Gt.lengthSq()>0?t.flags|W:t.flags&~W,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;const r=null!=this.rootMotionAction&&this.rootMotionAction.enabled,a=i.lengthSq()>0,h=!r&&0!==(t.flags&Z),l=r||a;this.updateCrouchState(t,n,l,h),this.pressedJump=h,this.isSprinting=!1,this.updateRotation(t,e,r,a),this.resolvePlatformVelocity(At);const c=this.movementModeContext,d=this.movementModes.get(this.state.mode);if(null!=d){c.move=t,c.deltaTime=e,c.rootMotionActive=l,c.startedSprinting=n&&!l&&0===(t.flags&B)&&0!==(t.flags&J);const i=d.update(c);"number"==typeof i&&(this.state.mode=i)}else Rt.set(0,0,0);if(a){zt.copy(i).multiplyScalar(o).applyQuaternion(this.actor.quaternion),kt.copy(zt).divideScalar(e),this.state.mode===A.walking?(Rt.x=kt.x+At.x,Rt.z=kt.z+At.z):(Rt.x=kt.x,Rt.z=kt.z);const t=Math.sqrt(kt.x*kt.x+kt.z*kt.z);t>.4&&(this.state.currentSpeed=t)}if(this.applyImpulseToVelocity(Rt,e),h&&this.isSprinting){const t=Math.max(0,this.maxSpeedSprint),e=Qt(Rt);if(e>t){const i=t/e;Rt.x*=i,Rt.z*=i,this.state.velocity.x*=i,this.state.velocity.z*=i}}this.state.mode===A.walking&&this.state.velocity.copy(Rt),this.applyMovement(Rt,e,s),this.state.mode===A.sliding&&(ft(this.state.velocity,qt,At,this.slideSurfaceNormal,e),this.state.currentSpeed=Qt(this.state.velocity)),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.updateModeAfterMove(Rt,e),this.state.mode===A.sliding&&this.state.velocity.length()<Math.max(0,this.slideMinExitSpeed)&&(this.state.mode=A.walking)}updateRotation(t,e,i,o){Ct.set(-t.inputX,0,t.inputY),Ct.lengthSq()>1&&Ct.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(Ht.set(0,t.yaw,0)),n=0,this.state.lookYaw=t.yaw,this.state.prevRotateToMovementDirection=this.rotateToMovementDirection),wt.set(0,0,0),i)this.state.lookYaw=t.yaw;else if(this.rotateToMovementDirection){if(Ct.lengthSq()>0&&this.state.mode!==A.falling){const i=Ht.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,o=Math.atan2(Ct.x,Ct.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(Ht.set(0,i+o,0))}else this.actor.object.quaternion.setFromEuler(Ht.set(0,s,0));this.state.prevInputDirection.lerp(Ct,e*this.rotationSpeed),this.state.lookYaw+=n,wt.copy(this.actor.object.getWorldDirection(Et).normalize())}}else o||(this.state.lookYaw=t.yaw,this.actor.object.quaternion.setFromEuler(Ht.set(0,t.yaw,0)),Ct.lengthSq()>0&&wt.copy(Ct).applyAxisAngle(Tt,t.yaw).normalize())}applyMovement(t,e,i){if(t.lengthSq()>0||!this.state.grounded)if(Dt.copy(t).multiplyScalar(e),this.state.grounded&&((o=this.state.mode)===A.walking||o===A.sliding)){if(this.state.mode===A.walking&&this.rayTestResult.distance<=this.cc.offset()&&(Dt.y=Math.max(0,At.y*e)),qt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Dt,this.getCollisionGroup())),this.cc.computedCollision(0,Bt),null!=Bt.normal1){const t=Et.copy(Bt.normal1);if(Math.acos(r.clamp(t.dot(Tt),-1,1))>this.cc.maxSlopeClimbAngle()){const t=.016*this.getEffectiveGravity()*.5;Dt.y!==t&&(Dt.y=t,qt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Dt,this.getCollisionGroup())))}}}else qt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Dt,this.getCollisionGroup()));else qt.set(0,0,0);var o;this.suppressUncrouchLift&&(this.suppressUncrouchLift=!1,this.state.grounded&&this.state.mode===A.walking&&Dt.y<=1e-6&&qt.y>0&&(qt.y=0)),this.state.position.add(qt),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);Ft.set(e.normal2.x,e.normal2.y,e.normal2.z);const i=Ft.angleTo(Tt);Ft.set(e.normal1.x,e.normal1.y,e.normal1.z);const o=Ft.angleTo(Tt);if(i<100)return!1;return o>t.minSlopeSlideAngle()}(this.cc);!this.state.grounded||i?this.state.mode!==A.falling&&(this.state.fallGraceTime+=e,this.state.fallGraceTime>this.fallGraceTime+1e-6&&(this.state.mode=A.falling,this.state.velocity.copy(t))):this.state.velocity.y<=0&&(this.state.mode===A.falling&&(this.state.mode=A.walking),this.state.mode!==A.sliding&&(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(ct(i))}sendOwnerCorrection(t){const e=this.toSnapshot(this.pendingSnapshot);t&&(e.horizontalSpeed=this.horizontalSpeed),this.sprintPolicy?.ack?.(e.sequence,!0),this.clientMoveCorrection(ut(e))}sendSimulatedState(t,e){this.simulatedStateAccumulator+=t,!e&&this.simulatedStateAccumulator<this.simulatedStateInterval||(this.simulatedStateAccumulator=0,this.simulatedState(mt(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(Ht.set(0,t.yaw,0)),this.crouchSuppressedUntilRelease=0!==(t.flags&K),this.setCrouching(0!==(t.flags&_)||t.mode===A.sliding),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=Ht.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,t.mode=this.state.mode,t.flags=(this.isCrouching?_:0)|(this.crouchSuppressedUntilRelease?K:0),t.horizontalSpeed=this.state.currentSpeed,t}syncPublicState(){this.velocity.copy(this.state.velocity),this.mode=this.state.mode,this.horizontalSpeed=this.state.currentSpeed,this.isSliding=this.state.mode===A.sliding,this.isSliding?(this.resolveGroundNormal(this.slideSurfaceNormal),this.slideDirection.copy(this.state.velocity).projectOnPlane(this.slideSurfaceNormal),this.slideDirection.lengthSq()>1e-8?this.slideDirection.normalize():this.slideDirection.set(0,0,0)):(this.slideDirection.set(0,0,0),this.slideSurfaceNormal.copy(Tt))}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 l))return t;const e=this.rootMotionInterpolant;this.resetRootMotion&&(this.prevRootMotionPos.fromArray(e.evaluate(0)),this.resetRootMotion=!1),It.fromArray(e.evaluate(this.rootMotionAction.time)),t.subVectors(It,this.prevRootMotionPos),this.prevRootMotionPos.copy(It);if((this.rootMotionRootBone??this.rootMotionAction.getRoot()).getWorldScale(Pt),t.multiply(Pt),this.rootMotionTargetConstraints.size>0){zt.copy(t).applyQuaternion(this.actor.quaternion);for(const t of this.rootMotionTargetConstraints)if(t.requestedProgress>0&&t.addedHorizontalDistance<t.maximumAddedHorizontalDistance){const e=r.lerp(t.initialHorizontalDistance,t.minimumHorizontalDistance,t.requestedProgress),i=Math.min(D(zt,this.actor.position,t.targetPosition,e),t.maximumAddedHorizontalDistance-t.addedHorizontalDistance);t.addedHorizontalDistance+=b(zt,this.actor.position,t.targetPosition,t.minimumHorizontalDistance,i)}else q(zt,this.actor.position,t.targetPosition,t.minimumHorizontalDistance);t.copy(zt).applyQuaternion(Vt.copy(this.actor.quaternion).invert())}return 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===vt.none||e!==p.authority||t>=vt.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=xt,i}updateCrouchState(t,e,i,o){if(!(0!==(t.flags&B)))return this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.state.mode===A.sliding&&(this.state.mode=A.walking),void this.tryUncrouch();if(this.state.mode===A.sliding&&(!this.slideEnabled||i))return this.slideOnLandingRequested=!1,this.state.mode=A.walking,void(this.crouchSuppressedUntilRelease||this.setCrouching(!0));if(this.state.mode===A.sliding&&o)return this.crouchSuppressedUntilRelease=!0,this.slideOnLandingRequested=!1,void this.tryUncrouch();if(this.crouchSuppressedUntilRelease)return void(this.slideOnLandingRequested=!1);if(this.setCrouching(!0),!this.slideEnabled||i)return void(this.slideOnLandingRequested=!1);if(this.state.mode===A.falling)return void(this.slideOnLandingRequested=!0);this.resolveGroundNormal(Ut);const s=this.slideOnLandingRequested&&this.state.mode===A.walking&&this.state.grounded,n=e&&0!==(t.flags&$)||s;s&&(this.slideOnLandingRequested=!1);const r=Qt(this.state.velocity);this.state.mode===A.walking&&St(this.slideEnabled,n,this.state.grounded,this.isWalkableSlideSurface(Ut),i,r,this.slideMinStartSpeed)&&(this.state.mode=A.sliding,this.slideSurfaceNormal.copy(Ut),this.state.velocity.projectOnPlane(this.slideSurfaceNormal),this.state.currentSpeed=Qt(this.state.velocity))}updateSlidingMode(t){const e=t.state,i=t.move;this.resolveGroundNormal(this.slideSurfaceNormal);const o=this.isWalkableSlideSurface(this.slideSurfaceNormal),s=e.velocity.length();if(!e.grounded||!o)return e.mode=A.falling,$t.update(t),A.falling;if(this.slideEnabled&&0!==(i.flags&B)&&!t.rootMotionActive&&0!==(i.flags&Z))return yt(t.outVelocity,e.velocity,this.jumpVelocity),e.velocity.copy(t.outVelocity),e.currentSpeed=Qt(e.velocity),A.falling;if(!gt(this.slideEnabled,0!==(i.flags&B),e.grounded,o,t.rootMotionActive,s,this.slideMinExitSpeed))return e.mode=A.walking,Wt.update(t),A.walking;const n=Mt(e.velocity,e.velocity,this.slideSurfaceNormal,t.rotatedDirection,this.getEffectiveGravity(),t.deltaTime,this.slideDeceleration,this.slideGravityScale,this.slideSteeringRate);if(e.currentSpeed=Qt(e.velocity),n<Math.max(0,this.slideMinExitSpeed))return e.mode=A.walking,Wt.update(t),A.walking;t.outVelocity.copy(e.velocity).add(t.platformVelocity)}tryUncrouch(){this.isCrouching&&this.canUncrouch()&&this.setCrouching(!1)&&(this.suppressUncrouchLift=!0,this.state.fallGraceTime=0)}resolveGroundNormal(t){return!this.rayTestResult.hasHit||this.rayTestResult.hitNormal.lengthSq()<=1e-8?t.copy(Tt):(t.copy(this.rayTestResult.hitNormal).normalize(),t.dot(Tt)<0&&t.multiplyScalar(-1),t)}isWalkableSlideSurface(t){return t.dot(Tt)>=Math.cos(this.cc.maxSlopeClimbAngle())}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){Nt.y=-Math.max(.05,this.cc.snapToGroundDistance()),this.physicsSystem.rayTest(Ot.addVectors(t,Yt.set(0,this.offset,0)),jt.addVectors(t,Nt),this.rayTestResult,this.groundRayTestOptions)}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:xt}};t([T(),e("design:type",Number)],Zt.prototype,"colliderHeight",void 0),t([T(),e("design:type",Number)],Zt.prototype,"colliderRadius",void 0),t([T(),e("design:type",Number)],Zt.prototype,"crouchColliderHeight",void 0),t([T({optional:!0}),e("design:type",Number)],Zt.prototype,"crouchColliderRadius",void 0),t([g(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Zt.prototype,"serverMove",null),t([v(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Zt.prototype,"clientMoveAck",null),t([v(!0),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Zt.prototype,"clientMoveCorrection",null),t([y(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Zt.prototype,"simulatedState",null),Zt=t([R({inEditor:!1}),e("design:paramtypes",[])],Zt);export{Zt as CharacterMovementComponent};const Wt={mode:A.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&B)&&0!==(i.flags&Q)&&!r&&0!==s.lengthSq()&&(e.sprintPolicy?.canSprint()??!0),l=(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(l,o.currentSpeed),c=e.groundAccelerationRate;if(h&&t.startedSprinting&&e.sprintStartBoostSpeed>0){const t=e.normalizedDirection?1:n;a=Math.max(a,l+e.sprintStartBoostSpeed*t),c=e.sprintStartBoostDamping}else h&&!r&&e.sprintStartBoostSpeed>0&&o.currentSpeed>l&&(a=o.currentSpeed,c=e.sprintStartBoostDamping);o.currentSpeed=function(t,e,i,o){return e+(t-e)*Math.exp(-i*o)}(a,l,c,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,l,c,t.deltaTime))}else o.currentSpeed=0,t.outVelocity.set(0,0,0);if(0!==(i.flags&Z))return o.mode=A.falling,o.velocity.copy(t.outVelocity),o.velocity.y=e.jumpVelocity,A.falling;t.outVelocity.y=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.add(t.platformVelocity)}},$t={mode:A.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(Tt,r.euclideanModulo(o.yaw-i.lookYaw+Math.PI,2*Math.PI)-Math.PI)}};function Qt(t){return Math.sqrt(t.x*t.x+t.z*t.z)}function Jt(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 Kt(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 _t{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();te.position.copy(t),te.setDirection(s),te.setLength(o);const n=ee(this.scene);n.add(te),setTimeout(()=>{n.remove(te)},1e3)}}const te=new n(new h(0,1,0),new h,1,16711680);function ee(t){return null==t.parent?t:ee(t.parent)}const ie={immediate:!1,savedRootMotion:!0};/*
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 l}from"../../../../animation/root-motion.js";import{inject as c}from"../../../../inject.js";import{ActionInput as m,AxisInput as d,RotationInput as u}from"../../../../input/index.js";import{NetRole as p}from"../../../../net/service/net-actor-role.js";import{RunOnClient as g,RunOnNotOwner as y,RunOnServer as v}from"../../../../net/service/rpc-decorator.js";import{NetService as S}from"../../../../net/service/net-service.js";import{PhysicsSystem as M,RayTestResult as f}from"../../../../services/physics/physics-system.js";import{CapsuleCollisionShape as w}from"../../../../../scene/collision/collision-shape.js";import{Parameter as x}from"../../../../../shader/parameter.js";import{PhysicsBodyType as T}from"../../../../services/physics/physics-system.js";import{ActorComponent as C,Component as R}from"../../../component.js";import{CharacterMovementMode as A}from"./modes.js";import{calculateRootMotionTargetApproachCorrection as b,constrainRootMotionTargetApproach as D,warpRootMotionTargetApproach as q}from"./root-motion-constraint.js";import{DEFAULT_MAX_CLIENT_TIME_AHEAD as P,DEFAULT_LARGE_CORRECTION_THRESHOLD as z,DEFAULT_MAX_COMBINED_MOVE_DELTA_TIME as k,DEFAULT_MAX_MOVE_DELTA_TIME as I,DEFAULT_MAX_MOVES_PER_PACKET as j,DEFAULT_MAX_REPLAYED_MOVES as O,DEFAULT_MAX_SERVER_MOVES_PER_TICK as G,DEFAULT_MAX_SAVED_MOVES as V,DEFAULT_MAX_SERVER_MOVE_DELTA_TIME_SCALAR as H,DEFAULT_MAX_SERVER_MOVE_TIME_BUDGET as Y,DEFAULT_MAX_SUBSTEP_DELTA_TIME as N,DEFAULT_MOVE_SEND_INTERVAL as F,DEFAULT_SIMULATED_INTERPOLATION_DELAY as E,DEFAULT_SIMULATED_STATE_INTERVAL as U,DEFAULT_SMALL_CORRECTION_TOLERANCE as X,DEFAULT_TELEPORT_SNAP_THRESHOLD as L,MOVE_FLAG_CROUCH as B,MOVE_FLAG_JUMP as Z,MOVE_FLAG_ROOT_MOTION as W,MOVE_FLAG_SLIDE_START as $,MOVE_FLAG_SPRINT as Q,MOVE_FLAG_SPRINT_START as J,SNAPSHOT_FLAG_CROUCH_SUPPRESSED as K,SNAPSHOT_FLAG_CROUCHING as _,NetCharacterProxySmoother as tt,NetCharacterSavedMoveBuffer as et,accrueNetCharacterServerMoveTime as it,createNetCharacterMovementSnapshot as ot,createNetCharacterServerMoveTimingState as st,consumeNetCharacterServerMoveTime as nt,decodeNetCharacterMoveBatch as rt,decodeNetCharacterOwnerAck as at,decodeNetCharacterOwnerCorrection as ht,decodeNetCharacterSimulatedState as lt,encodeNetCharacterMoveBatch as ct,encodeNetCharacterOwnerAck as mt,encodeNetCharacterOwnerCorrection as dt,encodeNetCharacterSimulatedState as ut,validateNetCharacterMove as pt}from"./net-character-movement-protocol.js";import{NetMode as gt}from"../../../../net/net-session.js";import{World as yt}from"../../../../services/world.js";import{WaterVolume as vt}from"../../water-volume-actor.js";import{WaterSplineVolume as St}from"../../water-spline-volume-actor.js";import{setSlideJumpVelocity as Mt,shouldContinueSlide as ft,shouldStartSlide as wt,updateSlideVelocity as xt,updateSlideVelocityFromDisplacement as Tt}from"./character-slide.js";export*from"./net-character-movement-protocol.js";const Ct=131070,Rt=new h(0,1,0),At=new h,bt=new h,Dt=new h,qt=new h,Pt=new h,zt=new h,kt=new h,It=new h,jt=new h,Ot=new h,Gt=new h,Vt=new h,Ht=new h,Yt=new h,Nt=new h(0,1,0),Ft=new h(0,-.05,0),Et=new h,Ut=new a,Xt=new s.Euler,Lt=new h,Bt=new h,Zt=new h,Wt=new h,$t=new i.CharacterCollision;let Qt=class extends C{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()}teleport(t,e=this.actor.rotation.y){this.state.position.copy(t),this.state.velocity.set(0,0,0),this.state.yaw=e,this.actor.position.copy(t),this.actor.rotation.y=e,this.rotationInput.rotation.y=e,this.physicsSystem.setPosition(this.actor,t),this.physicsSystem.setRotation(this.actor,this.actor.quaternion),this.physicsSystem.flushModifiedBodyPositionsToColliders()}constructor(){super(),this.isDefaultCharacterMovementComponent=!0,this.directionInput=new d,this.jumpInput=new m,this.sprintInput=new m,this.crouchInput=new m,this.rotationInput=new u,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.maxSpeedCrouch=4,this.swimmingEnabled=!0,this.maxSpeedSwimming=3,this.swimmingImmersion=.7,this.swimmingSurfaceResponse=6,this.swimmingMaxVerticalSpeed=4,this.swimmingDepthHysteresis=.1,this.slideEnabled=!1,this.slideMinStartSpeed=8,this.slideMinExitSpeed=4,this.slideDeceleration=3,this.slideGravityScale=1,this.slideSteeringRate=2,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.movementInputEnabled=!0,this.rotateToMovementDirection=!1,this.smoothRotation=!0,this.rotationSpeed=40,this.maxRotationSpeed=100,this.impulseDamping=2,this.moveSendInterval=F,this.simulatedStateInterval=U,this.maxSavedMoves=V,this.maxReplayedMoves=O,this.maxServerMovesPerTick=G,this.maxMovesPerPacket=j,this.maxMoveDeltaTime=I,this.maxCombinedMoveDeltaTime=k,this.maxServerMoveDeltaTimeScalar=H,this.maxClientTimeAhead=P,this.maxServerMoveTimeBudget=Y,this.maxSubstepDeltaTime=N,this.fallGraceTime=.1,this.correctionToleranceSq=X*X,this.largeCorrectionThreshold=z,this.teleportSnapThreshold=L,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.slideDirection=new h,this.slideSurfaceNormal=new h(0,1,0),this.mode=A.walking,this.isSprinting=!1,this.isCrouching=!1,this.isSliding=!1,this.pressedJump=!1,this.rayTestResult=new f,this.groundRayTestOptions={debug:!1,excludeTriggers:!0,excludeActor:void 0,resolveActor:!1},this.physicsSystem=c(M),this.netService=c(S),this.world=c(yt),this.waterVolumes=[],this.waterProbe=new h,this.swimmingSurfaceHeight=0,this.state={sequence:0,position:new h,velocity:new h,yaw:0,lookYaw:0,mode:A.walking,grounded:!1,currentSpeed:0,fallGraceTime:0,prevInputDirection:new h,prevRotateToMovementDirection:!1},this.movementModes=new Map,this.savedMoves=new et(V),this.serverMoveTiming=st(),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:bt,platformVelocity:qt,outVelocity:Dt,rootMotionActive:!1,startedSprinting:!1},this.proxySmoother=new tt(E,L),this.proxySample=ot(),this.pendingSnapshot=ot(),this.impulse=new h,this.prevRootMotionPos=new h,this.rootMotionOptions={},this.rootMotionTargetConstraints=new Set,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.previousCrouchInput=!1,this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.initialized=!1,this.cc=this.physicsSystem.getCharacterController(.1),this.cc.enableSnapToGround(.1),this.cc.enableAutostep(0,.1,!1),this.registerMovementMode(Jt),this.registerMovementMode(Kt),this.registerMovementMode({mode:A.swimming,update:t=>this.updateSwimmingMode(t)}),this.registerMovementMode({mode:A.sliding,update:t=>this.updateSlidingMode(t)})}onInit(){for(const t of this.world.actors)(t instanceof vt||t instanceof St)&&this.waterVolumes.push(t);this.world.actorAdded.pipe(o(this.disposed)).subscribe(t=>{(t instanceof vt||t instanceof St)&&this.waterVolumes.push(t)}),this.world.actorRemoved.pipe(o(this.disposed)).subscribe(t=>{const e=this.waterVolumes.indexOf(t);e>=0&&this.waterVolumes.splice(e,1)}),this.groundRayTestOptions.excludeActor=this.actor,this.configureCharacterController(),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:T.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 swimmingWaterSurfaceHeight(){return this.state.mode===A.swimming?this.swimmingSurfaceHeight:null}get waterContactSurfaceHeight(){if(this.state.mode===A.swimming)return this.swimmingSurfaceHeight;this.waterProbe.copy(this.state.position),this.waterProbe.y+=.01;const t=this.state.position.y+this.getColliderHeight(this.isCrouching)+2*this.getColliderRadius(this.isCrouching);let e=null;for(const i of this.waterVolumes){const o=i.getWaterSurfaceHeight(this.waterProbe);null!=o&&o>=this.waterProbe.y&&o<=t&&(null==e||o>e)&&(e=o)}return e}get isGrounded(){return this.state.mode!==A.swimming&&(this.rayTestResult.hasHit||this.cc.computedGrounded())}setRootMotionAction(t,e={}){const i=t?.getClip();if(i instanceof l){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)}}addRootMotionTargetConstraint(t,e,i=0){const o={targetPosition:t,minimumHorizontalDistance:Math.max(0,e),maximumAddedHorizontalDistance:Math.max(0,i),initialHorizontalDistance:Math.hypot(t.x-this.actor.position.x,t.z-this.actor.position.z),addedHorizontalDistance:0,requestedProgress:0};this.rootMotionTargetConstraints.add(o);let s=!1;return{setProgress:t=>{o.requestedProgress=Math.max(o.requestedProgress,Math.min(1,Math.max(0,t)))},dispose:()=>{s||(s=!0,this.rootMotionTargetConstraints.delete(o))}}}serverMove(t){const e=rt(t);if(e.ok)for(const t of e.value.moves)pt(t,this.lastServerReceivedSequence,this.maxMoveDeltaTime)&&(this.lastServerReceivedSequence=t.sequence,this.serverMoveQueue.push(t))}clientMoveAck(t){const e=at(t);e.ok&&this.actor.netRole===p.autonomousProxy&&(this.savedMoves.ack(e.value.sequence),this.sprintPolicy?.ack?.(e.value.sequence,!1))}clientMoveCorrection(t){const e=ht(t);e.ok&&this.actor.netRole===p.autonomousProxy&&(this.debugCorrections&&(null==this.correctionDebug&&(this.correctionDebug=new se(re(this.actor.object))),this.correctionDebug.update(this.state.position,e.value.snapshot)),this.applyCorrection(e.value.snapshot))}simulatedState(t){const e=lt(t);e.ok&&this.actor.netRole===p.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!==p.simulatedProxy?this.enabled&&(e!==p.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,ae),this.resetToggleCrouchAfterSlide(e);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.state.mode,o=this.createMoveFromInput(t,++this.nextMoveSequence);this.performMove(o,ae),this.resetToggleCrouchAfterSlide(i),e!==gt.none&&this.sendSimulatedState(t,!1)}resetToggleCrouchAfterSlide(t){t===A.sliding&&this.state.mode!==A.sliding&&"toggle"===this.crouchInput.mode&&this.crouchInput.activated&&this.crouchInput.setActivated(!1)}tickRemoteAuthority(t){it(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(!pt(t,this.lastServerProcessedSequence,this.maxMoveDeltaTime)){console.log("Net: Invalid move",t),this.sendOwnerCorrection(!0),e=!0;continue}const i=nt(this.serverMoveTiming,t,{maxMoveDeltaTime:this.maxMoveDeltaTime,maxServerMoveDeltaTimeScalar:this.maxServerMoveDeltaTimeScalar,maxClientTimeAhead:this.maxClientTimeAhead});if(i<0){this.sendOwnerCorrection(!0),e=!0;continue}const o=ie(t,this.authoritativeMoveScratch);o.dt=i,o.rootMotionX=0,o.rootMotionY=0,o.rootMotionZ=0,o.flags&=~W,this.performMove(o,{immediate:!0,savedRootMotion:!1}),n=!0,this.lastServerProcessedSequence=o.sequence;const s=oe(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(mt(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);Wt.subVectors(t,e);const i=Wt.lengthSq();i>1e-8&&(i>this.listenServerNoSmoothUpdateDistance*this.listenServerNoSmoothUpdateDistance?this.visualSmoothingOffset.set(0,0,0):(i>this.listenServerMaxSmoothUpdateDistance*this.listenServerMaxSmoothUpdateDistance&&Wt.setLength(this.listenServerMaxSmoothUpdateDistance),this.visualSmoothingOffset.add(Wt)))}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===p.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(kt);const a=this.crouchInput.activated,h=a&&!this.previousCrouchInput;this.previousCrouchInput=a;const l=this.movementInputEnabled&&!a&&this.sprintInput.activated,c=l&&!this.previousSprintInput;this.previousSprintInput=l;const m=(this.movementInputEnabled&&this.jumpInput.activated?Z:0)|(l?Q:0)|(a?B:0)|(this.movementInputEnabled&&h&&this.slideEnabled?$:0)|(c?J:0)|(kt.lengthSq()>0?W:0),d=function(t,e){e.set(t.x,0,t.y),e.lengthSq()>1&&e.normalize();return e}(this.directionInput.vector,Lt);this.movementInputEnabled||d.set(0,0,0);const u=this.inputMoveScratch;return u.sequence=e>>>0,u.clientTime=s,u.dt=n,u.inputX=d.x,u.inputY=d.z,u.yaw=this.rotationInput.rotation.y,u.flags=m,u.clientX=this.state.position.x,u.clientY=this.state.position.y,u.clientZ=this.state.position.z,u.rootMotionX=kt.x,u.rootMotionY=kt.y,u.rootMotionZ=kt.z,u}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&Q)&&0===(t.flags&B);this.sprintPolicy?.update?.(i,t.sequence,s),Vt.set(e.savedRootMotion?t.rootMotionX:0,e.savedRootMotion?t.rootMotionY:0,e.savedRootMotion?t.rootMotionZ:0),e.savedRootMotion||this.sampleRootMotion(Vt);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),Vt,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=Vt.lengthSq()>0?t.flags|W:t.flags&~W,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.updateWaterMovementMode();const r=null!=this.rootMotionAction&&this.rootMotionAction.enabled,a=i.lengthSq()>0,h=!r&&0!==(t.flags&Z),l=r||a;this.updateCrouchState(t,n,l,h),this.pressedJump=h,this.isSprinting=!1,this.updateRotation(t,e,r,a),this.resolvePlatformVelocity(qt);const c=this.movementModeContext,m=this.movementModes.get(this.state.mode);if(null!=m){c.move=t,c.deltaTime=e,c.rootMotionActive=l,c.startedSprinting=n&&!l&&0===(t.flags&B)&&0!==(t.flags&J);const i=m.update(c);"number"==typeof i&&(this.state.mode=i)}else Dt.set(0,0,0);if(a){It.copy(i).multiplyScalar(o).applyQuaternion(this.actor.quaternion),jt.copy(It).divideScalar(e),this.state.mode===A.walking?(Dt.x=jt.x+qt.x,Dt.z=jt.z+qt.z):(Dt.x=jt.x,Dt.z=jt.z);const t=Math.sqrt(jt.x*jt.x+jt.z*jt.z);t>.4&&(this.state.currentSpeed=t)}if(this.applyImpulseToVelocity(Dt,e),h&&this.isSprinting){const t=Math.max(0,this.maxSpeedSprint),e=_t(Dt);if(e>t){const i=t/e;Dt.x*=i,Dt.z*=i,this.state.velocity.x*=i,this.state.velocity.z*=i}}this.state.mode!==A.walking&&this.state.mode!==A.swimming||this.state.velocity.copy(Dt),this.applyMovement(Dt,e,s),this.state.mode===A.sliding&&(Tt(this.state.velocity,zt,qt,this.slideSurfaceNormal,e),this.state.currentSpeed=_t(this.state.velocity)),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.updateModeAfterMove(Dt,e),this.state.mode===A.sliding&&this.state.velocity.length()<Math.max(0,this.slideMinExitSpeed)&&(this.state.mode=A.walking)}updateRotation(t,e,i,o){At.set(-t.inputX,0,t.inputY),At.lengthSq()>1&&At.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(Xt.set(0,t.yaw,0)),n=0,this.state.lookYaw=t.yaw,this.state.prevRotateToMovementDirection=this.rotateToMovementDirection),bt.set(0,0,0),i)this.state.lookYaw=t.yaw;else if(this.rotateToMovementDirection){if(At.lengthSq()>0&&this.state.mode!==A.falling){const i=Xt.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,o=Math.atan2(At.x,At.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(Xt.set(0,i+o,0))}else this.actor.object.quaternion.setFromEuler(Xt.set(0,s,0));this.state.prevInputDirection.lerp(At,e*this.rotationSpeed),this.state.lookYaw+=n,bt.copy(this.actor.object.getWorldDirection(Lt).normalize())}}else o||(this.state.lookYaw=t.yaw,this.actor.object.quaternion.setFromEuler(Xt.set(0,t.yaw,0)),At.lengthSq()>0&&bt.copy(At).applyAxisAngle(Rt,t.yaw).normalize())}applyMovement(t,e,i){if(t.lengthSq()>0||!this.state.grounded)if(Pt.copy(t).multiplyScalar(e),this.state.grounded&&((o=this.state.mode)===A.walking||o===A.sliding)){if(this.state.mode===A.walking&&this.rayTestResult.distance<=this.cc.offset()&&(Pt.y=Math.max(0,qt.y*e)),zt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Pt,this.getCollisionGroup())),null!=this.cc.computedCollision(0,$t)){const t=Lt.copy($t.normal1);if(Math.acos(r.clamp(t.dot(Rt),-1,1))>this.cc.maxSlopeClimbAngle()){const t=.016*this.getEffectiveGravity()*.5;Pt.y!==t&&(Pt.y=t,zt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Pt,this.getCollisionGroup())))}}}else{const t=this.state.mode===A.swimming,e=t?this.cc.snapToGroundDistance():null;t&&this.cc.disableSnapToGround(),zt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Pt,this.getCollisionGroup())),t&&null!=e&&this.cc.enableSnapToGround(e)}else zt.set(0,0,0);var o;this.suppressUncrouchLift&&(this.suppressUncrouchLift=!1,this.state.grounded&&this.state.mode===A.walking&&Pt.y<=1e-6&&zt.y>0&&(zt.y=0)),this.state.position.add(zt),i?(this.actor.position.copy(this.state.position),this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()):this.physicsSystem.setNextKinematicPosition(this.actor,this.state.position)}getSwimmingDepth(){return(this.getColliderHeight(!1)+2*this.getColliderRadius(!1))*this.swimmingImmersion}updateWaterMovementMode(){const t=this.state.mode===A.swimming;if(this.state.mode===A.falling&&this.state.velocity.y>0)return;if(!t&&this.state.mode!==A.walking&&this.state.mode!==A.falling&&this.state.mode!==A.sliding)return;let e=null;if(this.swimmingEnabled){this.waterProbe.copy(this.state.position),this.waterProbe.y+=this.getSwimmingDepth()+(t?-1:1)*this.swimmingDepthHysteresis;for(const t of this.waterVolumes){const i=t.getWaterSurfaceHeight(this.waterProbe);null!=i&&(null==e||i>e)&&(e=i)}}null!=e?(this.swimmingSurfaceHeight=e,this.state.mode=A.swimming,this.state.grounded=!1,this.state.fallGraceTime=0,t||(this.state.currentSpeed=Math.min(this.state.currentSpeed,this.maxSpeedSwimming),this.state.velocity.y=0)):t&&(this.state.mode=A.falling,this.state.fallGraceTime=0)}updateSwimmingMode(t){const e=t.state,i=Math.min(1,Math.hypot(t.move.inputX,t.move.inputY)),o=t.rotatedDirection.lengthSq()>0?this.maxSpeedSwimming*(this.normalizedDirection?1:i):0,s=Math.min(e.currentSpeed,this.maxSpeedSwimming);if(e.currentSpeed=o>0?te(s,o,this.groundAccelerationRate,t.deltaTime):0,t.outVelocity.copy(t.rotatedDirection).multiplyScalar(ee(s,o,this.groundAccelerationRate,t.deltaTime)),!t.rootMotionActive&&0!==(t.move.flags&Z))return t.outVelocity.y=this.jumpVelocity,e.velocity.copy(t.outVelocity),e.mode=A.falling,e.grounded=!1,void(e.fallGraceTime=0);const n=this.swimmingSurfaceHeight-this.getSwimmingDepth()-e.position.y;t.outVelocity.y=r.clamp(n*(1-Math.exp(-this.swimmingSurfaceResponse*t.deltaTime))/t.deltaTime,-this.swimmingMaxVerticalSpeed,this.swimmingMaxVerticalSpeed)}updateModeAfterMove(t,e){if(this.state.mode===A.swimming)return;const i=function(t){if(0===t.numComputedCollisions())return!1;const e=t.computedCollision(0);Et.set(e.normal2.x,e.normal2.y,e.normal2.z);const i=Et.angleTo(Rt);Et.set(e.normal1.x,e.normal1.y,e.normal1.z);const o=Et.angleTo(Rt);if(i<100)return!1;return o>t.minSlopeSlideAngle()}(this.cc);!this.state.grounded||i?this.state.mode!==A.falling&&(this.state.fallGraceTime+=e,this.state.fallGraceTime>this.fallGraceTime+1e-6&&(this.state.mode=A.falling,this.state.velocity.copy(t))):this.state.velocity.y<=0&&(this.state.mode===A.falling&&(this.state.mode=A.walking),this.state.mode!==A.sliding&&(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(ct(i))}sendOwnerCorrection(t){const e=this.toSnapshot(this.pendingSnapshot);t&&(e.horizontalSpeed=this.horizontalSpeed),this.sprintPolicy?.ack?.(e.sequence,!0),this.clientMoveCorrection(dt(e))}sendSimulatedState(t,e){this.simulatedStateAccumulator+=t,!e&&this.simulatedStateAccumulator<this.simulatedStateInterval||(this.simulatedStateAccumulator=0,this.simulatedState(ut(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(Xt.set(0,t.yaw,0)),this.crouchSuppressedUntilRelease=0!==(t.flags&K),this.setCrouching(0!==(t.flags&_)||t.mode===A.sliding),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=Xt.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,t.mode=this.state.mode,t.flags=(this.isCrouching?_:0)|(this.crouchSuppressedUntilRelease?K:0),t.horizontalSpeed=this.state.currentSpeed,t}syncPublicState(){this.velocity.copy(this.state.velocity),this.mode=this.state.mode,this.horizontalSpeed=this.state.currentSpeed,this.isSliding=this.state.mode===A.sliding,this.isSliding?(this.resolveGroundNormal(this.slideSurfaceNormal),this.slideDirection.copy(this.state.velocity).projectOnPlane(this.slideSurfaceNormal),this.slideDirection.lengthSq()>1e-8?this.slideDirection.normalize():this.slideDirection.set(0,0,0)):(this.slideDirection.set(0,0,0),this.slideSurfaceNormal.copy(Rt))}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 l))return t;const e=this.rootMotionInterpolant;this.resetRootMotion&&(this.prevRootMotionPos.fromArray(e.evaluate(0)),this.resetRootMotion=!1),Gt.fromArray(e.evaluate(this.rootMotionAction.time)),t.subVectors(Gt,this.prevRootMotionPos),this.prevRootMotionPos.copy(Gt);if((this.rootMotionRootBone??this.rootMotionAction.getRoot()).getWorldScale(Ot),t.multiply(Ot),this.rootMotionTargetConstraints.size>0){It.copy(t).applyQuaternion(this.actor.quaternion);for(const t of this.rootMotionTargetConstraints)if(t.requestedProgress>0&&t.addedHorizontalDistance<t.maximumAddedHorizontalDistance){const e=r.lerp(t.initialHorizontalDistance,t.minimumHorizontalDistance,t.requestedProgress),i=Math.min(b(It,this.actor.position,t.targetPosition,e),t.maximumAddedHorizontalDistance-t.addedHorizontalDistance);t.addedHorizontalDistance+=q(It,this.actor.position,t.targetPosition,t.minimumHorizontalDistance,i)}else D(It,this.actor.position,t.targetPosition,t.minimumHorizontalDistance);t.copy(It).applyQuaternion(Ut.copy(this.actor.quaternion).invert())}return 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===gt.none||e!==p.authority||t>=gt.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 w(t,e);return i.offset.y=this.getCapsuleOffsetY(t,e),i.collisionGroup=Ct,i}updateCrouchState(t,e,i,o){if(this.state.mode===A.swimming)return this.slideOnLandingRequested=!1,void this.tryUncrouch();if(!(0!==(t.flags&B)))return this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.state.mode===A.sliding&&(this.state.mode=A.walking),void this.tryUncrouch();if(this.state.mode===A.sliding&&(!this.slideEnabled||i))return this.slideOnLandingRequested=!1,this.state.mode=A.walking,void(this.crouchSuppressedUntilRelease||this.setCrouching(!0));if(this.state.mode===A.sliding&&o)return this.crouchSuppressedUntilRelease=!0,this.slideOnLandingRequested=!1,void this.tryUncrouch();if(this.crouchSuppressedUntilRelease)return void(this.slideOnLandingRequested=!1);if(this.setCrouching(!0),!this.slideEnabled||i)return void(this.slideOnLandingRequested=!1);if(this.state.mode===A.falling)return void(this.slideOnLandingRequested=!0);this.resolveGroundNormal(Bt);const s=this.slideOnLandingRequested&&this.state.mode===A.walking&&this.state.grounded,n=e&&0!==(t.flags&$)||s;s&&(this.slideOnLandingRequested=!1);const r=_t(this.state.velocity);this.state.mode===A.walking&&wt(this.slideEnabled,n,this.state.grounded,this.isWalkableSlideSurface(Bt),i,r,this.slideMinStartSpeed)&&(this.state.mode=A.sliding,this.slideSurfaceNormal.copy(Bt),this.state.velocity.projectOnPlane(this.slideSurfaceNormal),this.state.currentSpeed=_t(this.state.velocity))}updateSlidingMode(t){const e=t.state,i=t.move;this.resolveGroundNormal(this.slideSurfaceNormal);const o=this.isWalkableSlideSurface(this.slideSurfaceNormal),s=e.velocity.length();if(!e.grounded||!o)return e.mode=A.falling,Kt.update(t),A.falling;if(this.slideEnabled&&0!==(i.flags&B)&&!t.rootMotionActive&&0!==(i.flags&Z))return Mt(t.outVelocity,e.velocity,this.jumpVelocity),e.velocity.copy(t.outVelocity),e.currentSpeed=_t(e.velocity),A.falling;if(!ft(this.slideEnabled,0!==(i.flags&B),e.grounded,o,t.rootMotionActive,s,this.slideMinExitSpeed))return e.mode=A.walking,Jt.update(t),A.walking;const n=xt(e.velocity,e.velocity,this.slideSurfaceNormal,t.rotatedDirection,this.getEffectiveGravity(),t.deltaTime,this.slideDeceleration,this.slideGravityScale,this.slideSteeringRate);if(e.currentSpeed=_t(e.velocity),n<Math.max(0,this.slideMinExitSpeed))return e.mode=A.walking,Jt.update(t),A.walking;t.outVelocity.copy(e.velocity).add(t.platformVelocity)}tryUncrouch(){this.isCrouching&&this.canUncrouch()&&this.setCrouching(!1)&&(this.suppressUncrouchLift=!0,this.state.fallGraceTime=0)}resolveGroundNormal(t){return!this.rayTestResult.hasHit||this.rayTestResult.hitNormal.lengthSq()<=1e-8?t.copy(Rt):(t.copy(this.rayTestResult.hitNormal).normalize(),t.dot(Rt)<0&&t.multiplyScalar(-1),t)}isWalkableSlideSurface(t){return t.dot(Rt)>=Math.cos(this.cc.maxSlopeClimbAngle())}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){Ft.y=-Math.max(.05,this.cc.snapToGroundDistance()),this.groundRayTestOptions.collisionFilter=this.getCollisionGroup(),this.physicsSystem.rayTest(Ht.addVectors(t,Nt.set(0,this.offset,0)),Yt.addVectors(t,Ft),this.rayTestResult,this.groundRayTestOptions)}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:Ct}};t([x({group:"Swimming"}),e("design:type",Object)],Qt.prototype,"swimmingEnabled",void 0),t([x({group:"Swimming",range:[0,20]}),e("design:type",Object)],Qt.prototype,"maxSpeedSwimming",void 0),t([x({group:"Swimming",range:[.1,1]}),e("design:type",Object)],Qt.prototype,"swimmingImmersion",void 0),t([x({group:"Swimming",range:[0,20]}),e("design:type",Object)],Qt.prototype,"swimmingSurfaceResponse",void 0),t([x({group:"Swimming",range:[0,20]}),e("design:type",Object)],Qt.prototype,"swimmingMaxVerticalSpeed",void 0),t([x({group:"Swimming",range:[0,1]}),e("design:type",Object)],Qt.prototype,"swimmingDepthHysteresis",void 0),t([x(),e("design:type",Number)],Qt.prototype,"colliderHeight",void 0),t([x(),e("design:type",Number)],Qt.prototype,"colliderRadius",void 0),t([x(),e("design:type",Number)],Qt.prototype,"crouchColliderHeight",void 0),t([x({optional:!0}),e("design:type",Number)],Qt.prototype,"crouchColliderRadius",void 0),t([v(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Qt.prototype,"serverMove",null),t([g(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Qt.prototype,"clientMoveAck",null),t([g(!0),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Qt.prototype,"clientMoveCorrection",null),t([y(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Qt.prototype,"simulatedState",null),Qt=t([R({inEditor:!1}),e("design:paramtypes",[])],Qt);export{Qt as CharacterMovementComponent};const Jt={mode:A.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&B)&&0!==(i.flags&Q)&&!r&&0!==s.lengthSq()&&(e.sprintPolicy?.canSprint()??!0),l=(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(l,o.currentSpeed),c=e.groundAccelerationRate;if(h&&t.startedSprinting&&e.sprintStartBoostSpeed>0){const t=e.normalizedDirection?1:n;a=Math.max(a,l+e.sprintStartBoostSpeed*t),c=e.sprintStartBoostDamping}else h&&!r&&e.sprintStartBoostSpeed>0&&o.currentSpeed>l&&(a=o.currentSpeed,c=e.sprintStartBoostDamping);o.currentSpeed=te(a,l,c,t.deltaTime),t.outVelocity.copy(s).multiplyScalar(ee(a,l,c,t.deltaTime))}else o.currentSpeed=0,t.outVelocity.set(0,0,0);if(0!==(i.flags&Z))return o.mode=A.falling,o.velocity.copy(t.outVelocity),o.velocity.y=e.jumpVelocity,A.falling;t.outVelocity.y=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.add(t.platformVelocity)}},Kt={mode:A.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(Rt,r.euclideanModulo(o.yaw-i.lookYaw+Math.PI,2*Math.PI)-Math.PI)}};function _t(t){return Math.sqrt(t.x*t.x+t.z*t.z)}function te(t,e,i,o){return e+(t-e)*Math.exp(-i*o)}function ee(t,e,i,o){const s=i*o;return s<=1e-6?t:e+(t-e)*(1-Math.exp(-s))/s}function ie(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 oe(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 se{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();ne.position.copy(t),ne.setDirection(s),ne.setLength(o);const n=re(this.scene);n.add(ne),setTimeout(()=>{n.remove(ne)},1e3)}}const ne=new n(new h(0,1,0),new h,1,16711680);function re(t){return null==t.parent?t:re(t.parent)}const ae={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
  */
@@ -9,6 +9,14 @@ export declare class WaterSplineVolume extends BaseActor implements NavigationAr
9
9
  private readonly surface;
10
10
  private readonly editorVisual;
11
11
  readonly underwater: WaterPostProcessSettings;
12
+ private waterSections;
13
+ private waterSurfaceTriangles;
14
+ private waterSplineData?;
15
+ private waterWidth;
16
+ private waterDepth;
17
+ private waterSampleDistance;
18
+ private readonly waterSectionsMatrix;
19
+ private updateWaterSections;
12
20
  width: number;
13
21
  depth: number;
14
22
  showSurface: boolean;
@@ -17,6 +25,8 @@ export declare class WaterSplineVolume extends BaseActor implements NavigationAr
17
25
  surfaceWidthSubdivisions: number;
18
26
  applySceneParameters(parameters: Record<string, unknown>, changedParameters: ReadonlySet<string>): boolean;
19
27
  containsWaterPoint(point: Vector3): boolean;
28
+ /** World-space surface height above a point inside the volume, or null outside. */
29
+ getWaterSurfaceHeight(point: Vector3): number | null;
20
30
  getNavigationAreaModifiers(): NavigationAreaModifier[];
21
31
  }
22
32
  export { createWaterSplineSurfaceGeometry } from '../../../navigation/water-spline-geometry.js';
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{createCrossSections as i,createSurfaceGeometry as s,createVolumeGeometry as r}from"../../../navigation/water-spline-geometry.js";import{BufferGeometry as a,EdgesGeometry as o,Group as n,DoubleSide as h,LineBasicMaterial as l,LineSegments as u,Mesh as c,MeshBasicMaterial as p,Material as d,Matrix4 as f,Vector3 as m}from"three";import{takeUntil as g}from"rxjs";import{NavigationArea as b}from"../../ai/navigation-areas.js";import{Parameter as y}from"../../../shader/parameter.js";import{Actor as w,BaseActor as S}from"../actor.js";import{ActorComponent as v,Component as M,attach as x}from"../component.js";import{SplineComponent as z}from"./components/spline-component.js";import{WaterPostProcessSettings as W}from"./components/water-post-process-settings.js";const j=1477586;let D=class extends v{constructor(){super(...arguments),this.fallbackMaterial=new p({color:j,transparent:!0,opacity:.65,side:h}),this.surface=new c(new a,this.fallbackMaterial),this.initialized=!1}onInit(){this.initialized=!0,this.surface.name="Water Surface",this.actor.object.add(this.surface),this.actor.spline.changed.pipe(g(this.disposed)).subscribe(()=>this.rebuild()),this.setMaterial(this.actor.surfaceMaterial),this.rebuild()}setMaterial(e){this.surface.material=e??this.fallbackMaterial}rebuild(){if(!this.initialized)return;const e=this.surface.geometry;this.surface.geometry=s(this.actor.spline,this.actor.width,this.actor.surfaceSampleDistance,this.actor.surfaceWidthSubdivisions),this.surface.visible=this.actor.showSurface,e.dispose()}onEndPlay(){this.surface.geometry.dispose(),this.fallbackMaterial.dispose(),this.surface.removeFromParent()}};D=e([M({inEditor:!0})],D);let N=class extends v{constructor(){super(...arguments),this.visual=new n,this.fillMaterial=new p({color:j,transparent:!0,opacity:.18,depthWrite:!1}),this.edgeMaterial=new l({color:3520767}),this.fill=new c(new a,this.fillMaterial),this.edges=new u(new a,this.edgeMaterial),this.initialized=!1}onInit(){this.initialized=!0,this.visual.name="Water Spline Volume Visualization",this.visual.userData.isEditorVisualization=!0,this.fill.frustumCulled=!1,this.edges.frustumCulled=!1,this.visual.add(this.fill,this.edges),this.actor.object.add(this.visual),this.actor.spline.changed.pipe(g(this.disposed)).subscribe(()=>this.rebuild()),this.rebuild()}rebuild(){if(!this.initialized)return;const e=r(this.actor.spline,this.actor.width,this.actor.depth,this.actor.showSurface,this.actor.surfaceSampleDistance),t=0===e.getAttribute("position").count?new a:new o(e,20),i=this.fill.geometry,s=this.edges.geometry;this.fill.geometry=e,this.edges.geometry=t,i.dispose(),s.dispose(),this.visual.updateMatrixWorld(!0)}onEndPlay(){this.fill.geometry.dispose(),this.edges.geometry.dispose(),this.fillMaterial.dispose(),this.edgeMaterial.dispose(),this.visual.removeFromParent()}};N=e([M({inEditor:!0,editorOnly:!0})],N);let T=class extends S{constructor(){super(...arguments),this.spline=x(z),this.surface=x(D),this.editorVisual=x(N),this.underwater=x(W),this.width=5,this.depth=2,this.showSurface=!0,this.surfaceSampleDistance=1,this.surfaceWidthSubdivisions=1}applySceneParameters(e,t){if(![...t].every(e=>["width","depth","showSurface","surfaceMaterial","surfaceSampleDistance","surfaceWidthSubdivisions"].includes(e)))return!1;const i=t.has("width")?e.width:this.width,s=t.has("depth")?e.depth:this.depth;if("number"!=typeof i||!Number.isFinite(i)||i<=0)return!1;if("number"!=typeof s||!Number.isFinite(s)||s<=0)return!1;if(t.has("showSurface")&&"boolean"!=typeof e.showSurface)return!1;if(t.has("surfaceMaterial")&&null!=e.surfaceMaterial&&!(e.surfaceMaterial instanceof d))return!1;const r=t.has("surfaceSampleDistance")?e.surfaceSampleDistance:this.surfaceSampleDistance,a=t.has("surfaceWidthSubdivisions")?e.surfaceWidthSubdivisions:this.surfaceWidthSubdivisions;return!("number"!=typeof r||!Number.isFinite(r)||r<=0)&&(!("number"!=typeof a||!Number.isFinite(a)||a<1)&&(this.width=i,this.depth=s,t.has("showSurface")&&(this.showSurface=e.showSurface),t.has("surfaceMaterial")&&(this.surfaceMaterial=e.surfaceMaterial,this.surface.setMaterial(this.surfaceMaterial)),this.surfaceSampleDistance=r,this.surfaceWidthSubdivisions=Math.round(a),this.editorVisual.rebuild(),this.surface.rebuild(),!0))}containsWaterPoint(e){this.object.updateWorldMatrix(!0,!1);const t=P.copy(e).applyMatrix4(F.copy(this.object.matrixWorld).invert()),s=i(this.spline,this.width,this.depth,this.surfaceSampleDistance);for(let e=1;e<s.length;e++){const i=s[e-1],r=s[e];if(V(t,i.leftTop,i.rightTop,r.rightTop,r.leftTop,this.depth))return!0}return!1}getNavigationAreaModifiers(){const e=i(this.spline,this.width,this.depth);if(e.length<2)return[];this.object.updateWorldMatrix(!0,!1);const t=this.object.matrixWorld,s=[];for(let i=1;i<e.length;i++){const r=e[i-1],a=e[i],o=[r.leftTop,r.rightTop,a.rightTop,a.leftTop,r.leftBottom,r.rightBottom,a.rightBottom,a.leftBottom].map(e=>e.clone().applyMatrix4(t));s.push({area:b.Water,vertices:o.slice(0,4).map(e=>e.toArray()),minHeight:Math.min(...o.map(e=>e.y)),maxHeight:Math.max(...o.map(e=>e.y))})}return s}};e([y({range:[.01,1e3]}),t("design:type",Number)],T.prototype,"width",void 0),e([y({range:[.01,1e3]}),t("design:type",Number)],T.prototype,"depth",void 0),e([y({group:"Surface"}),t("design:type",Boolean)],T.prototype,"showSurface",void 0),e([y({type:d,group:"Surface",requires:{showSurface:!0},help:"Optional. Uses a translucent debug material when unset."}),t("design:type",d)],T.prototype,"surfaceMaterial",void 0),e([y({range:[.1,100],group:"Surface",requires:{showSurface:!0},help:"Target spacing in world units between sections along the spline."}),t("design:type",Number)],T.prototype,"surfaceSampleDistance",void 0),e([y({range:[1,64],stepSize:1,group:"Surface",requires:{showSurface:!0},help:"Subdivisions across the water. Increase for vertex displacement and detailed bank effects."}),t("design:type",Number)],T.prototype,"surfaceWidthSubdivisions",void 0),T=e([w({typeId:"WaterSplineVolume",icon:"ripple"})],T);export{T as WaterSplineVolume};export{createWaterSplineSurfaceGeometry}from"../../../navigation/water-spline-geometry.js";const F=new f,P=new m;function V(e,t,i,s,r,a){const o=k(e,t,i,s)??k(e,t,s,r);return null!=o&&e.y<=o&&e.y>=o-a}function k(e,t,i,s){const r=(i.z-s.z)*(t.x-s.x)+(s.x-i.x)*(t.z-s.z);if(Math.abs(r)<1e-8)return null;const a=((i.z-s.z)*(e.x-s.x)+(s.x-i.x)*(e.z-s.z))/r,o=((s.z-t.z)*(e.x-s.x)+(t.x-s.x)*(e.z-s.z))/r,n=1-a-o;return a>=0&&o>=0&&n>=0?a*t.y+o*i.y+n*s.y:null}/*
1
+ import{__decorate as t,__metadata as e}from"tslib";import{createCrossSections as i,createSurfaceGeometry as s,createVolumeGeometry as r}from"../../../navigation/water-spline-geometry.js";import{BufferGeometry as a,EdgesGeometry as o,Group as n,DoubleSide as h,LineBasicMaterial as l,LineSegments as c,Mesh as u,MeshBasicMaterial as p,Material as d,Matrix4 as f,Vector3 as m}from"three";import{takeUntil as w}from"rxjs";import{NavigationArea as g}from"../../ai/navigation-areas.js";import{Parameter as S}from"../../../shader/parameter.js";import{Actor as y,BaseActor as b}from"../actor.js";import{ActorComponent as M,Component as x,attach as v}from"../component.js";import{SplineComponent as W}from"./components/spline-component.js";import{WaterPostProcessSettings as D}from"./components/water-post-process-settings.js";const z=1477586;let j=class extends M{constructor(){super(...arguments),this.fallbackMaterial=new p({color:z,transparent:!0,opacity:.65,side:h}),this.surface=new u(new a,this.fallbackMaterial),this.initialized=!1}onInit(){this.initialized=!0,this.surface.name="Water Surface",this.actor.object.add(this.surface),this.actor.spline.changed.pipe(w(this.disposed)).subscribe(()=>this.rebuild()),this.setMaterial(this.actor.surfaceMaterial),this.rebuild()}setMaterial(t){this.surface.material=t??this.fallbackMaterial}rebuild(){if(!this.initialized)return;const t=this.surface.geometry;this.surface.geometry=s(this.actor.spline,this.actor.width,this.actor.surfaceSampleDistance,this.actor.surfaceWidthSubdivisions),this.surface.visible=this.actor.showSurface,t.dispose()}onEndPlay(){this.surface.geometry.dispose(),this.fallbackMaterial.dispose(),this.surface.removeFromParent()}};j=t([x({inEditor:!0})],j);let N=class extends M{constructor(){super(...arguments),this.visual=new n,this.fillMaterial=new p({color:z,transparent:!0,opacity:.18,depthWrite:!1}),this.edgeMaterial=new l({color:3520767}),this.fill=new u(new a,this.fillMaterial),this.edges=new c(new a,this.edgeMaterial),this.initialized=!1}onInit(){this.initialized=!0,this.visual.name="Water Spline Volume Visualization",this.visual.userData.isEditorVisualization=!0,this.fill.frustumCulled=!1,this.edges.frustumCulled=!1,this.visual.add(this.fill,this.edges),this.actor.object.add(this.visual),this.actor.spline.changed.pipe(w(this.disposed)).subscribe(()=>this.rebuild()),this.rebuild()}rebuild(){if(!this.initialized)return;const t=r(this.actor.spline,this.actor.width,this.actor.depth,this.actor.showSurface,this.actor.surfaceSampleDistance),e=0===t.getAttribute("position").count?new a:new o(t,20),i=this.fill.geometry,s=this.edges.geometry;this.fill.geometry=t,this.edges.geometry=e,i.dispose(),s.dispose(),this.visual.updateMatrixWorld(!0)}onEndPlay(){this.fill.geometry.dispose(),this.edges.geometry.dispose(),this.fillMaterial.dispose(),this.edgeMaterial.dispose(),this.visual.removeFromParent()}};N=t([x({inEditor:!0,editorOnly:!0})],N);let T=class extends b{constructor(){super(...arguments),this.spline=v(W),this.surface=v(j),this.editorVisual=v(N),this.underwater=v(D),this.waterSections=[],this.waterSurfaceTriangles=[],this.waterWidth=NaN,this.waterDepth=NaN,this.waterSampleDistance=NaN,this.waterSectionsMatrix=new f,this.width=5,this.depth=2,this.showSurface=!0,this.surfaceSampleDistance=1,this.surfaceWidthSubdivisions=1}updateWaterSections(){const t=this.spline.splineData!==this.waterSplineData||this.width!==this.waterWidth||this.depth!==this.waterDepth||this.surfaceSampleDistance!==this.waterSampleDistance;if(t&&(this.waterSplineData=this.spline.splineData,this.waterWidth=this.width,this.waterDepth=this.depth,this.waterSampleDistance=this.surfaceSampleDistance,this.waterSections=i(this.spline,this.width,this.depth,this.surfaceSampleDistance)),this.object.updateWorldMatrix(!0,!1),t||!this.waterSectionsMatrix.equals(this.object.matrixWorld)){this.waterSectionsMatrix.copy(this.object.matrixWorld),this.waterSurfaceTriangles.length=0;for(const t of this.waterSections)this.waterSurfaceTriangles.push(t.leftTop.clone().applyMatrix4(this.waterSectionsMatrix),t.rightTop.clone().applyMatrix4(this.waterSectionsMatrix))}}applySceneParameters(t,e){if(![...e].every(t=>["width","depth","showSurface","surfaceMaterial","surfaceSampleDistance","surfaceWidthSubdivisions"].includes(t)))return!1;const i=e.has("width")?t.width:this.width,s=e.has("depth")?t.depth:this.depth;if("number"!=typeof i||!Number.isFinite(i)||i<=0)return!1;if("number"!=typeof s||!Number.isFinite(s)||s<=0)return!1;if(e.has("showSurface")&&"boolean"!=typeof t.showSurface)return!1;if(e.has("surfaceMaterial")&&null!=t.surfaceMaterial&&!(t.surfaceMaterial instanceof d))return!1;const r=e.has("surfaceSampleDistance")?t.surfaceSampleDistance:this.surfaceSampleDistance,a=e.has("surfaceWidthSubdivisions")?t.surfaceWidthSubdivisions:this.surfaceWidthSubdivisions;return!("number"!=typeof r||!Number.isFinite(r)||r<=0)&&(!("number"!=typeof a||!Number.isFinite(a)||a<1)&&(this.width=i,this.depth=s,e.has("showSurface")&&(this.showSurface=t.showSurface),e.has("surfaceMaterial")&&(this.surfaceMaterial=t.surfaceMaterial,this.surface.setMaterial(this.surfaceMaterial)),this.surfaceSampleDistance=r,this.surfaceWidthSubdivisions=Math.round(a),this.editorVisual.rebuild(),this.surface.rebuild(),!0))}containsWaterPoint(t){this.updateWaterSections();const e=F.copy(t).applyMatrix4(P.copy(this.object.matrixWorld).invert()),i=this.waterSections;for(let t=1;t<i.length;t++){const s=i[t-1],r=i[t];if(V(e,s.leftTop,s.rightTop,r.rightTop,r.leftTop,this.depth))return!0}return!1}getWaterSurfaceHeight(t){if(!this.containsWaterPoint(t))return null;const e=this.waterSurfaceTriangles;let i=null;for(let s=2;s<e.length;s+=2){const r=e[s-2],a=e[s-1],o=e[s+1],n=e[s],h=k(t,r,a,o)??k(t,r,o,n);null!=h&&h>=t.y&&(null==i||h>i)&&(i=h)}return i}getNavigationAreaModifiers(){const t=i(this.spline,this.width,this.depth);if(t.length<2)return[];this.object.updateWorldMatrix(!0,!1);const e=this.object.matrixWorld,s=[];for(let i=1;i<t.length;i++){const r=t[i-1],a=t[i],o=[r.leftTop,r.rightTop,a.rightTop,a.leftTop,r.leftBottom,r.rightBottom,a.rightBottom,a.leftBottom].map(t=>t.clone().applyMatrix4(e));s.push({area:g.Water,vertices:o.slice(0,4).map(t=>t.toArray()),minHeight:Math.min(...o.map(t=>t.y)),maxHeight:Math.max(...o.map(t=>t.y))})}return s}};t([S({range:[.01,1e3]}),e("design:type",Number)],T.prototype,"width",void 0),t([S({range:[.01,1e3]}),e("design:type",Number)],T.prototype,"depth",void 0),t([S({group:"Surface"}),e("design:type",Boolean)],T.prototype,"showSurface",void 0),t([S({type:d,group:"Surface",requires:{showSurface:!0},help:"Optional. Uses a translucent debug material when unset."}),e("design:type",d)],T.prototype,"surfaceMaterial",void 0),t([S({range:[.1,100],group:"Surface",requires:{showSurface:!0},help:"Target spacing in world units between sections along the spline."}),e("design:type",Number)],T.prototype,"surfaceSampleDistance",void 0),t([S({range:[1,64],stepSize:1,group:"Surface",requires:{showSurface:!0},help:"Subdivisions across the water. Increase for vertex displacement and detailed bank effects."}),e("design:type",Number)],T.prototype,"surfaceWidthSubdivisions",void 0),T=t([y({typeId:"WaterSplineVolume",icon:"ripple"})],T);export{T as WaterSplineVolume};export{createWaterSplineSurfaceGeometry}from"../../../navigation/water-spline-geometry.js";const P=new f,F=new m;function V(t,e,i,s,r,a){const o=k(t,e,i,s)??k(t,e,s,r);return null!=o&&t.y<=o&&t.y>=o-a}function k(t,e,i,s){const r=(i.z-s.z)*(e.x-s.x)+(s.x-i.x)*(e.z-s.z);if(Math.abs(r)<1e-8)return null;const a=((i.z-s.z)*(t.x-s.x)+(s.x-i.x)*(t.z-s.z))/r,o=((s.z-e.z)*(t.x-s.x)+(e.x-s.x)*(t.z-s.z))/r,n=1-a-o;return a>=0&&o>=0&&n>=0?a*e.y+o*i.y+n*s.y:null}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,5 +1,5 @@
1
1
  import { Material, Matrix4, Vector3 } from 'three';
2
- import { BaseActor } from '../../index.js';
2
+ import { BaseActor } from '../actor.js';
3
3
  import { type NavigationAreaContributor, type NavigationAreaModifier } from '../../ai/navigation-areas.js';
4
4
  import { WaterPostProcessSettings, type WaterPostProcessVolume } from './components/water-post-process-settings.js';
5
5
  /** A semantic box of water. Its top face is the future water surface. */
@@ -13,6 +13,8 @@ export declare class WaterVolume extends BaseActor implements NavigationAreaCont
13
13
  applySceneParameters(parameters: Record<string, unknown>, changed: ReadonlySet<string>): boolean;
14
14
  getNavigationAreaModifiers(): NavigationAreaModifier[];
15
15
  containsWaterPoint(point: Vector3): boolean;
16
+ /** World-space surface height above a point inside the volume, or null outside. */
17
+ getWaterSurfaceHeight(point: Vector3): number | null;
16
18
  getWaterPostProcessWorldToLocal(target: Matrix4): Matrix4;
17
19
  isWaterPostProcessRelevant(cameraPosition: Vector3, transitionDistance: number): boolean;
18
20
  }