@zephyr3d/scene 0.8.2 → 0.9.1
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.
- package/dist/animation/animationset.js +473 -60
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_system.js +2516 -0
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -0
- package/dist/animation/fixed_geometry_cache_track.js +138 -0
- package/dist/animation/fixed_geometry_cache_track.js.map +1 -0
- package/dist/animation/geometry_cache_utils.js +120 -0
- package/dist/animation/geometry_cache_utils.js.map +1 -0
- package/dist/animation/ik_modifier.js +9 -1
- package/dist/animation/ik_modifier.js.map +1 -1
- package/dist/animation/joint_dynamics/collision.js +469 -0
- package/dist/animation/joint_dynamics/collision.js.map +1 -0
- package/dist/animation/joint_dynamics/constraints.js +329 -0
- package/dist/animation/joint_dynamics/constraints.js.map +1 -0
- package/dist/animation/joint_dynamics/controller.js +699 -0
- package/dist/animation/joint_dynamics/controller.js.map +1 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +393 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -0
- package/dist/animation/joint_dynamics/solver.js +794 -0
- package/dist/animation/joint_dynamics/solver.js.map +1 -0
- package/dist/animation/joint_dynamics/types.js +19 -0
- package/dist/animation/joint_dynamics/types.js.map +1 -0
- package/dist/animation/joint_dynamics/vrm_spring_bone.js +46 -0
- package/dist/animation/joint_dynamics/vrm_spring_bone.js.map +1 -0
- package/dist/animation/joint_dynamics_modifier.js +51 -0
- package/dist/animation/joint_dynamics_modifier.js.map +1 -0
- package/dist/animation/pca_geometry_cache_track.js +222 -0
- package/dist/animation/pca_geometry_cache_track.js.map +1 -0
- package/dist/animation/skeleton.js +2011 -139
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skeleton_modifier.js +3 -5
- package/dist/animation/skeleton_modifier.js.map +1 -1
- package/dist/animation/spring/multi_chain_spring_system.js +2 -0
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_chain.js +3 -2
- package/dist/animation/spring/spring_chain.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +35 -5
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +1 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_system.js +325 -28
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring2/collision.js +469 -0
- package/dist/animation/spring2/collision.js.map +1 -0
- package/dist/animation/spring2/constraints.js +329 -0
- package/dist/animation/spring2/constraints.js.map +1 -0
- package/dist/animation/spring2/controller.js +434 -0
- package/dist/animation/spring2/controller.js.map +1 -0
- package/dist/animation/spring2/math.js +16 -0
- package/dist/animation/spring2/math.js.map +1 -0
- package/dist/animation/spring2/solver.js +624 -0
- package/dist/animation/spring2/solver.js.map +1 -0
- package/dist/animation/spring2/spring_system.js +118 -0
- package/dist/animation/spring2/spring_system.js.map +1 -0
- package/dist/animation/spring2/types.js +19 -0
- package/dist/animation/spring2/types.js.map +1 -0
- package/dist/animation/spring_modifier.js +17 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/engine.js +42 -15
- package/dist/app/engine.js.map +1 -1
- package/dist/app/runtimescript.js +132 -1
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/screen.js +3 -3
- package/dist/app/screen.js.map +1 -1
- package/dist/app/scriptingsystem.js +69 -37
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +14 -3
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +2 -1
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/zabc/zabc_loader.js +570 -0
- package/dist/asset/loaders/zabc/zabc_loader.js.map +1 -0
- package/dist/asset/model.js +192 -0
- package/dist/asset/model.js.map +1 -1
- package/dist/camera/base.js +26 -7
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +146 -24
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/fps.js +2 -2
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +2 -2
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +11728 -8535
- package/dist/index.js +29 -8
- package/dist/index.js.map +1 -1
- package/dist/material/lambert.js +1 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +9 -3
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +54 -7
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +17 -7
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +7 -2
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +108 -16
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +209 -14
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +24 -12
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +11 -8
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +72 -5
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/pbrblueprint.js +148 -1
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js +115 -2
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/shader/helper.js +10 -4
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/water.js +2 -2
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/coloradjust.js +145 -0
- package/dist/posteffect/coloradjust.js.map +1 -0
- package/dist/posteffect/taa.js +68 -32
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/cluster_light.js +17 -12
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/deferredlightpass.js +510 -0
- package/dist/render/deferredlightpass.js.map +1 -0
- package/dist/render/deferredshadowlightpass.js +428 -0
- package/dist/render/deferredshadowlightpass.js.map +1 -0
- package/dist/render/drawable.js.map +1 -1
- package/dist/render/drawable_mixin.js +21 -12
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/envlight.js +20 -22
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/gbufferpass.js +50 -0
- package/dist/render/gbufferpass.js.map +1 -0
- package/dist/render/lightpass.js +1 -2
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/primitive.js +1 -1
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/render_queue.js +3 -2
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +5 -358
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/executor.js +15 -12
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +144 -88
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/history_resource_manager.js +178 -0
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -0
- package/dist/render/rendergraph/rendergraph.js +12 -1
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/types.js +2 -2
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/sky.js +26 -9
- package/dist/render/sky.js.map +1 -1
- package/dist/scene/basesprite.js +4 -3
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +4 -4
- package/dist/scene/environment.js +7 -4
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/light.js +184 -18
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +30 -0
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/particlesys.js +3 -2
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/raycast_visitor.js +29 -3
- package/dist/scene/raycast_visitor.js.map +1 -1
- package/dist/scene/scene.js +86 -19
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +87 -31
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/script_attachment.js +59 -0
- package/dist/scene/script_attachment.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +3 -2
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +4 -3
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +3 -2
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/shadow.js +2 -2
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shadow/shadowmapper.js +74 -4
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shapes/box.js +163 -0
- package/dist/shapes/box.js.map +1 -1
- package/dist/shapes/capsule.js +216 -0
- package/dist/shapes/capsule.js.map +1 -0
- package/dist/shapes/cylinder.js +91 -0
- package/dist/shapes/cylinder.js.map +1 -1
- package/dist/shapes/plane.js +32 -0
- package/dist/shapes/plane.js.map +1 -1
- package/dist/shapes/tetrahedron.js +211 -0
- package/dist/shapes/tetrahedron.js.map +1 -1
- package/dist/shapes/torus.js +173 -0
- package/dist/shapes/torus.js.map +1 -1
- package/dist/utility/blueprint/common/math.js +111 -1
- package/dist/utility/blueprint/common/math.js.map +1 -1
- package/dist/utility/blueprint/material/inputs.js +235 -1
- package/dist/utility/blueprint/material/inputs.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +154 -10
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +273 -19
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/serialization/json.js +12 -2
- package/dist/utility/serialization/json.js.map +1 -1
- package/dist/utility/serialization/manager.js +30 -11
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +250 -7
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -2
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +154 -2
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/cloth_script.js +834 -0
- package/dist/utility/serialization/scene/cloth_script.js.map +1 -0
- package/dist/utility/serialization/scene/common.js +7 -0
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +120 -4
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +453 -1
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +4 -2
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +298 -10
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +4 -2
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +100 -3
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +130 -3
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/script.js +66 -0
- package/dist/utility/serialization/scene/script.js.map +1 -0
- package/dist/utility/serialization/scene/spring_script.js +596 -0
- package/dist/utility/serialization/scene/spring_script.js.map +1 -0
- package/dist/utility/serialization/scene/sprite.js +5 -3
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +4 -2
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +4 -2
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/values.js +5 -1
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solver.js","sources":["../../../src/animation/spring2/solver.ts"],"sourcesContent":["// Core physics simulation 閳?direct port of JobExecuteSimulation from SPCRJointDynamicsJob.cs\r\n\r\nimport { Quaternion, Vector3, Matrix4x4, degree2radian, radian2degree } from '@zephyr3d/base';\r\nimport { clamp01, smoothStep } from './math';\r\nimport {\r\n EPSILON,\r\n ConstraintType,\r\n type PointR,\r\n type PointRW,\r\n type Constraint,\r\n type ColliderR,\r\n type ColliderRW,\r\n type GrabberR,\r\n type GrabberRW,\r\n type AngleLimitConfig,\r\n type FlatPlane\r\n} from './types';\r\nimport {\r\n pushoutFromSphere,\r\n pushoutFromCapsule,\r\n pushInFromSphere,\r\n pushInFromCapsule,\r\n collisionDetection,\r\n checkSurfaceCollision,\r\n type CollisionResult,\r\n type LineCollisionResult,\r\n type SurfaceCheckResult\r\n} from './collision';\r\n\r\nconst AXIS_Y = new Vector3(0, 1, 0);\r\nconst VEC3_ONE = new Vector3(1, 1, 1);\r\nconst _computeCapsuleAxis = new Vector3();\r\nconst _computeCapsuleHalfDir = new Vector3();\r\nconst _applySystemTransformOffset = new Vector3();\r\nconst _applySystemTransformRotated = new Vector3();\r\nconst _broadPhaseSegmentDir = new Vector3();\r\nconst _broadPhaseToCenter = new Vector3();\r\nconst _broadPhaseClosestPoint = new Vector3();\r\nconst _broadPhaseDelta = new Vector3();\r\n\r\n/** Parameters for a single simulation step */\r\nexport interface SimulationParams {\r\n /** If true, skip force integration (only apply root motion and output positions) */\r\n isPaused: boolean;\r\n /** Frame delta time in seconds (will be subdivided by subSteps) */\r\n stepTime: number;\r\n /** Number of substeps per frame. Higher = more stable simulation */\r\n subSteps: number;\r\n /** Current root bone world position */\r\n rootPosition: Vector3;\r\n /** Previous frame's root bone world position (for root motion limiting) */\r\n previousRootPosition: Vector3;\r\n /** Max root slide distance per substep. -1 = no limit */\r\n rootSlideLimit: number;\r\n /** Current root bone world rotation */\r\n rootRotation: Quaternion;\r\n /** Previous frame's root bone world rotation */\r\n previousRootRotation: Quaternion;\r\n /** Max root rotation angle (degrees) per substep. -1 = no limit */\r\n rootRotateLimit: number;\r\n /** Global wind force vector */\r\n windForce: Vector3;\r\n /** Enable triangle-based surface collision */\r\n enableSurfaceCollision: boolean;\r\n /** Triangle indices for surface collision (6 per quad: 2 triangles 鑴?3 indices) */\r\n surfaceConstraints: number[];\r\n /** Number of constraint relaxation iterations per substep */\r\n relaxation: number;\r\n /** Upper limit for horizontal/shear shrink power */\r\n constraintShrinkLimit: number;\r\n /** Blend ratio between physics and animation [0-1]. 0 = full physics */\r\n blendRatio: number;\r\n /** Enable sinusoidal fake wave on leaf bones */\r\n isFakeWave: boolean;\r\n /** Fake wave speed (frequency accumulation rate) */\r\n fakeWaveSpeed: number;\r\n /** Fake wave global amplitude */\r\n fakeWavePower: number;\r\n /** Current fake wave phase counter (accumulated across frames) */\r\n fakeWaveCounter: number;\r\n /** Global scale multiplier for all collider radii */\r\n collisionScale: number;\r\n /** Enable broad-phase pruning before precise collision checks */\r\n enableBroadPhase: boolean;\r\n}\r\n\r\n/**\r\n * Run the full simulation step. Mutates pointsRW and collidersRW in place.\r\n * Returns { positionsToTransform, fakeWaveCounter }.\r\n */\r\nexport function simulate(\r\n params: SimulationParams,\r\n pointsR: readonly PointR[],\r\n pointsRW: PointRW[],\r\n constraints: readonly Constraint[],\r\n collidersR: readonly ColliderR[],\r\n collidersRW: ColliderRW[],\r\n grabbersR: readonly GrabberR[],\r\n grabbersRW: readonly GrabberRW[],\r\n movableLimitTargets: readonly Vector3[],\r\n flatPlanes: readonly FlatPlane[]\r\n): { positionsToTransform: Vector3[]; fakeWaveCounter: number } {\r\n const pointCount = pointsR.length;\r\n const positionsToTransform: Vector3[] = new Array(pointCount);\r\n\r\n let subSteps = params.subSteps;\r\n if (params.isPaused) {\r\n subSteps = 1;\r\n }\r\n\r\n let fakeWaveFreq = params.fakeWaveCounter;\r\n\r\n // Root slide offset\r\n let rootSlideOffset = Vector3.zero();\r\n const rootDeltaSlide = Vector3.sub(params.rootPosition, params.previousRootPosition);\r\n const rootDeltaSlideLen = rootDeltaSlide.magnitude;\r\n if (params.rootSlideLimit >= 0 && rootDeltaSlideLen > params.rootSlideLimit) {\r\n rootSlideOffset = Vector3.scale(\r\n rootDeltaSlide,\r\n (1.0 - params.rootSlideLimit / rootDeltaSlideLen) / subSteps\r\n );\r\n }\r\n\r\n // Root rotation offset\r\n let rootRotationOffset = Quaternion.identity();\r\n const rootDeltaRot = Quaternion.multiply(\r\n params.rootRotation,\r\n Quaternion.inverse(params.previousRootRotation)\r\n );\r\n let rotateAngle = Math.acos(Math.max(-1, Math.min(1, rootDeltaRot.w))) * 2.0 * (180 / Math.PI);\r\n if (rotateAngle > 180) {\r\n rotateAngle -= 360;\r\n }\r\n\r\n if (params.rootRotateLimit >= 0 && Math.abs(rotateAngle) > params.rootRotateLimit) {\r\n let rotateAxis = new Vector3();\r\n if (!isFinite(rotateAxis.x) || !isFinite(rotateAxis.y) || !isFinite(rotateAxis.z)) {\r\n rotateAxis = Vector3.axisPY();\r\n }\r\n let angle = rotateAngle > 0 ? rotateAngle - params.rootRotateLimit : rotateAngle + params.rootRotateLimit;\r\n angle /= subSteps;\r\n rootRotationOffset = Quaternion.fromAxisAngle(rotateAxis, degree2radian(angle));\r\n }\r\n\r\n if (params.isPaused) {\r\n rootSlideOffset = rootDeltaSlide;\r\n rootRotationOffset = rootDeltaRot;\r\n }\r\n\r\n const stepTime = params.stepTime / subSteps;\r\n\r\n for (let iSubStep = 1; iSubStep <= subSteps; iSubStep++) {\r\n const stepDelta = iSubStep / subSteps;\r\n const stepTime_x2_half = stepTime * stepTime * 0.5;\r\n\r\n colliderUpdate(collidersR, collidersRW, stepDelta, params.collisionScale);\r\n pointUpdatePass1(\r\n pointsR,\r\n pointsRW,\r\n stepDelta,\r\n stepTime_x2_half,\r\n rootSlideOffset,\r\n rootRotationOffset,\r\n params.rootPosition,\r\n params.windForce,\r\n params.isPaused,\r\n grabbersR,\r\n grabbersRW,\r\n movableLimitTargets,\r\n flatPlanes\r\n );\r\n\r\n if (!params.isPaused) {\r\n fakeWaveFreq += params.fakeWaveSpeed * stepTime;\r\n\r\n if (params.enableSurfaceCollision) {\r\n surfaceCollision(pointsRW, collidersR, collidersRW, params.surfaceConstraints);\r\n }\r\n\r\n for (let iRelax = params.relaxation - 1; iRelax >= 0; --iRelax) {\r\n constraintUpdate(\r\n pointsR,\r\n pointsRW,\r\n constraints,\r\n collidersR,\r\n collidersRW,\r\n params.constraintShrinkLimit,\r\n params.enableBroadPhase\r\n );\r\n }\r\n }\r\n\r\n pointUpdatePass2(\r\n pointsR,\r\n pointsRW,\r\n positionsToTransform,\r\n stepDelta,\r\n fakeWaveFreq,\r\n params.blendRatio,\r\n params.isFakeWave,\r\n params.fakeWavePower\r\n );\r\n }\r\n\r\n return { positionsToTransform, fakeWaveCounter: fakeWaveFreq };\r\n}\r\n\r\n// 閳光偓閳光偓 Collider interpolation 閳光偓閳光偓\r\n\r\nfunction computeCapsule(\r\n pos: Vector3,\r\n rot: Quaternion,\r\n height: number,\r\n head: Vector3,\r\n direction: Vector3\r\n): void {\r\n rot.transform(Vector3.scale(AXIS_Y, height, _computeCapsuleAxis), direction);\r\n Vector3.scale(direction, 0.5, _computeCapsuleHalfDir);\r\n Vector3.sub(pos, _computeCapsuleHalfDir, head);\r\n}\r\n\r\nfunction colliderUpdate(\r\n collidersR: readonly ColliderR[],\r\n collidersRW: ColliderRW[],\r\n stepDelta: number,\r\n collisionScale: number\r\n) {\r\n const curPos = new Vector3();\r\n const curDir = new Quaternion();\r\n const corner = new Vector3();\r\n const center = new Vector3();\r\n const tailCorner = new Vector3();\r\n const tailCenter = new Vector3();\r\n for (let i = 0; i < collidersR.length; i++) {\r\n const colR = collidersR[i];\r\n const colRW = collidersRW[i];\r\n colRW.radius = colR.radius * collisionScale;\r\n\r\n Vector3.lerp(colRW.positionPreviousTransform, colRW.positionCurrentTransform, stepDelta, curPos);\r\n Quaternion.slerp(colRW.directionPreviousTransform, colRW.directionCurrentTransform, stepDelta, curDir);\r\n\r\n computeCapsule(curPos, curDir, colR.height, colRW.positionCurrent, colRW.directionCurrent);\r\n if (colR.height > EPSILON) {\r\n Vector3.scale(colRW.directionCurrent, 0.5, _computeCapsuleHalfDir);\r\n Vector3.add(colRW.positionCurrent, _computeCapsuleHalfDir, colRW.boundsCenter);\r\n colRW.boundsRadius =\r\n Math.sqrt(colRW.directionCurrent.magnitudeSq) * 0.5 +\r\n Math.max(colRW.radius, colRW.radius * colR.radiusTailScale);\r\n } else {\r\n colRW.boundsCenter.set(colRW.positionCurrent);\r\n colRW.boundsRadius = colRW.radius;\r\n }\r\n\r\n // Update local bounds\r\n Vector3.scale(VEC3_ONE, colR.radius, corner);\r\n colRW.worldToLocal.transformPointAffine(colRW.positionCurrent, center);\r\n Vector3.sub(center, corner, colRW.localBoundsMin);\r\n Vector3.add(center, corner, colRW.localBoundsMax);\r\n\r\n if (colR.height > EPSILON) {\r\n Vector3.scale(VEC3_ONE, colR.radius * colR.radiusTailScale, tailCorner);\r\n Vector3.add(colRW.positionCurrent, colRW.directionCurrent, tailCenter);\r\n colRW.worldToLocal.transformPointAffine(tailCenter, tailCenter);\r\n colRW.localBoundsMin.setXYZ(\r\n Math.min(colRW.localBoundsMin.x, tailCenter.x - tailCorner.x),\r\n Math.min(colRW.localBoundsMin.y, tailCenter.y - tailCorner.y),\r\n Math.min(colRW.localBoundsMin.z, tailCenter.z - tailCorner.z)\r\n );\r\n colRW.localBoundsMax.setXYZ(\r\n Math.max(colRW.localBoundsMax.x, tailCenter.x + tailCorner.x),\r\n Math.max(colRW.localBoundsMax.y, tailCenter.y + tailCorner.y),\r\n Math.max(colRW.localBoundsMax.z, tailCenter.z + tailCorner.z)\r\n );\r\n }\r\n }\r\n}\r\n\r\n// 閳光偓閳光偓 Apply root motion transform 閳光偓閳光偓\r\n\r\nfunction applySystemTransform(\r\n point: Vector3,\r\n pivot: Vector3,\r\n slideOffset: Vector3,\r\n rotOffset: Quaternion,\r\n result?: Vector3\r\n): Vector3 {\r\n const rotated = rotOffset.transform(\r\n Vector3.sub(point, pivot, _applySystemTransformOffset),\r\n result || _applySystemTransformRotated\r\n );\r\n Vector3.add(rotated, pivot, rotated);\r\n return Vector3.add(rotated, slideOffset, rotated);\r\n}\r\n\r\nfunction pointMayCollideBroadPhase(point: Vector3, colRW: ColliderRW, padding = 0): boolean {\r\n const radius = colRW.boundsRadius + padding;\r\n const delta = Vector3.sub(point, colRW.boundsCenter, _broadPhaseDelta);\r\n return delta.magnitudeSq <= radius * radius;\r\n}\r\n\r\nfunction segmentMayCollideBroadPhase(point1: Vector3, point2: Vector3, colRW: ColliderRW): boolean {\r\n const segmentDir = Vector3.sub(point2, point1, _broadPhaseSegmentDir);\r\n const lenSq = segmentDir.magnitudeSq;\r\n if (lenSq <= EPSILON) {\r\n return pointMayCollideBroadPhase(point1, colRW);\r\n }\r\n const toCenter = Vector3.sub(colRW.boundsCenter, point1, _broadPhaseToCenter);\r\n const t = clamp01(Vector3.dot(toCenter, segmentDir) / lenSq);\r\n const closestPoint = Vector3.scale(segmentDir, t, _broadPhaseClosestPoint);\r\n Vector3.add(point1, closestPoint, closestPoint);\r\n const delta = Vector3.sub(colRW.boundsCenter, closestPoint, _broadPhaseDelta);\r\n return delta.magnitudeSq <= colRW.boundsRadius * colRW.boundsRadius;\r\n}\r\n\r\n// 閳光偓閳光偓 Pass 1: Verlet integration + forces 閳光偓閳光偓\r\n\r\nfunction pointUpdatePass1(\r\n pointsR: readonly PointR[],\r\n pointsRW: PointRW[],\r\n stepDelta: number,\r\n stepTime_x2_half: number,\r\n rootSlideOffset: Vector3,\r\n rootRotationOffset: Quaternion,\r\n rootPosition: Vector3,\r\n windForce: Vector3,\r\n isPaused: boolean,\r\n grabbersR: readonly GrabberR[],\r\n grabbersRW: readonly GrabberRW[],\r\n movableLimitTargets: readonly Vector3[],\r\n flatPlanes: readonly FlatPlane[]\r\n) {\r\n const currentTransformPos = new Vector3();\r\n const moveDir = new Vector3();\r\n const extForce = new Vector3();\r\n const displacement = new Vector3();\r\n const restore = new Vector3();\r\n const tempVec0 = new Vector3();\r\n const tempVec1 = new Vector3();\r\n const planeOffset = new Vector3();\r\n for (let index = 0; index < pointsR.length; index++) {\r\n const ptR = pointsR[index];\r\n const ptRW = pointsRW[index];\r\n\r\n Vector3.lerp(\r\n ptRW.positionPreviousTransform,\r\n ptRW.positionCurrentTransform,\r\n stepDelta,\r\n currentTransformPos\r\n );\r\n\r\n if (ptR.weight <= EPSILON) {\r\n ptRW.positionPrevious.set(ptRW.positionCurrent);\r\n ptRW.positionCurrent.set(currentTransformPos);\r\n } else {\r\n applySystemTransform(\r\n ptRW.positionPrevious,\r\n rootPosition,\r\n rootSlideOffset,\r\n rootRotationOffset,\r\n ptRW.positionPrevious\r\n );\r\n applySystemTransform(\r\n ptRW.positionCurrent,\r\n rootPosition,\r\n rootSlideOffset,\r\n rootRotationOffset,\r\n ptRW.positionCurrent\r\n );\r\n\r\n displacement.setXYZ(0, 0, 0);\r\n if (!isPaused) {\r\n Vector3.sub(ptRW.positionCurrent, ptRW.positionPrevious, moveDir);\r\n Vector3.scale(windForce, ptR.windForceScale / ptR.mass, extForce);\r\n Vector3.add(ptR.gravity, extForce, extForce);\r\n Vector3.scale(extForce, stepTime_x2_half, extForce);\r\n\r\n Vector3.add(moveDir, extForce, displacement);\r\n Vector3.scale(displacement, ptR.resistance, displacement);\r\n Vector3.scale(displacement, 1.0 - clamp01(ptRW.friction * ptR.frictionScale), displacement);\r\n }\r\n\r\n ptRW.positionPrevious.set(ptRW.positionCurrent);\r\n Vector3.add(ptRW.positionCurrent, displacement, ptRW.positionCurrent);\r\n ptRW.friction = 0;\r\n\r\n if (!isPaused) {\r\n // Hardness restore\r\n if (ptR.hardness > 0) {\r\n Vector3.sub(currentTransformPos, ptRW.positionCurrent, restore);\r\n Vector3.scale(restore, ptR.hardness, restore);\r\n Vector3.add(ptRW.positionCurrent, restore, ptRW.positionCurrent);\r\n }\r\n // Force fade ratio\r\n if (ptR.forceFadeRatio > 0) {\r\n Vector3.lerp(ptRW.positionCurrent, currentTransformPos, ptR.forceFadeRatio, ptRW.positionCurrent);\r\n }\r\n // Grabber\r\n if (ptRW.grabberIndex !== -1) {\r\n const grR = grabbersR[ptRW.grabberIndex];\r\n const grRW = grabbersRW[ptRW.grabberIndex];\r\n if (grRW.enabled === 0) {\r\n ptRW.grabberIndex = -1;\r\n } else {\r\n Vector3.sub(ptRW.positionCurrent, grRW.position, tempVec0);\r\n Vector3.normalize(tempVec0, tempVec0);\r\n Vector3.scale(tempVec0, ptRW.grabberDistance, tempVec1);\r\n Vector3.add(grRW.position, tempVec1, tempVec1);\r\n Vector3.sub(tempVec1, ptRW.positionCurrent, tempVec0);\r\n Vector3.scale(tempVec0, grR.force, tempVec0);\r\n Vector3.add(ptRW.positionCurrent, tempVec0, ptRW.positionCurrent);\r\n }\r\n } else {\r\n let nearIndex = -1;\r\n let sqrNearRange = 1000 * 1000;\r\n for (let ig = 0; ig < grabbersR.length; ig++) {\r\n const grRW = grabbersRW[ig];\r\n if (grRW.enabled !== 0) {\r\n const sqrLen = Vector3.sub(grRW.position, ptRW.positionCurrent, tempVec0).magnitudeSq;\r\n if (sqrLen < grabbersR[ig].radius * grabbersR[ig].radius && sqrLen < sqrNearRange) {\r\n sqrNearRange = sqrLen;\r\n nearIndex = ig;\r\n }\r\n }\r\n }\r\n if (nearIndex !== -1) {\r\n ptRW.grabberIndex = nearIndex;\r\n ptRW.grabberDistance = Math.sqrt(sqrNearRange) / 2.0;\r\n }\r\n }\r\n // Movable limit\r\n if (ptR.movableLimitIndex !== -1) {\r\n const target = movableLimitTargets[ptR.movableLimitIndex];\r\n const move = Vector3.sub(ptRW.positionCurrent, target, tempVec0);\r\n const moveLen = move.magnitude;\r\n if (moveLen > ptR.movableLimitRadius) {\r\n Vector3.scale(move, ptR.movableLimitRadius / moveLen, move);\r\n Vector3.add(target, move, ptRW.positionCurrent);\r\n }\r\n }\r\n }\r\n\r\n // Flat plane collision\r\n for (let i = 0; i < flatPlanes.length; i++) {\r\n const fp = flatPlanes[i];\r\n const dist = Vector3.dot(fp.normal, ptRW.positionCurrent) + fp.distance;\r\n if (dist < 0) {\r\n Vector3.scale(fp.normal, dist, planeOffset);\r\n Vector3.sub(ptRW.positionCurrent, planeOffset, ptRW.positionCurrent);\r\n ptRW.friction = 0.3;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n// 閳光偓閳光偓 Surface collision (triangle-based cloth collision) 閳光偓閳光偓\r\n\r\nfunction surfaceCollision(\r\n pointsRW: PointRW[],\r\n collidersR: readonly ColliderR[],\r\n collidersRW: ColliderRW[],\r\n surfaceConstraints: readonly number[]\r\n) {\r\n const surfaceResult: SurfaceCheckResult = {\r\n hit: false,\r\n intersectionPoint: new Vector3(),\r\n pushOut: new Vector3(),\r\n pointOnCollider: new Vector3(),\r\n radius: 0\r\n };\r\n const triCenter = new Vector3();\r\n const pushDir = new Vector3();\r\n const centerToPt = new Vector3();\r\n const intersectToPt = new Vector3();\r\n const pushVec = new Vector3();\r\n for (let index = 0; index < surfaceConstraints.length; index += 6) {\r\n for (let i = 0; i < collidersR.length; i++) {\r\n const colR = collidersR[i];\r\n const colRW = collidersRW[i];\r\n if (colRW.enabled === 0) {\r\n continue;\r\n }\r\n\r\n const colliderPos = colRW.positionCurrent;\r\n\r\n for (let j = 0; j < 6; j += 3) {\r\n const idxA = surfaceConstraints[index + j + 0];\r\n const idxB = surfaceConstraints[index + j + 1];\r\n const idxC = surfaceConstraints[index + j + 2];\r\n\r\n const rwA = pointsRW[idxA];\r\n const rwB = pointsRW[idxB];\r\n const rwC = pointsRW[idxC];\r\n\r\n const result = checkSurfaceCollision(\r\n rwA.positionCurrent,\r\n rwB.positionCurrent,\r\n rwC.positionCurrent,\r\n colliderPos,\r\n colR,\r\n colRW,\r\n surfaceResult\r\n );\r\n\r\n if (result.hit) {\r\n triCenter.setXYZ(\r\n (rwA.positionCurrent.x + rwB.positionCurrent.x + rwC.positionCurrent.x) / 3,\r\n (rwA.positionCurrent.y + rwB.positionCurrent.y + rwC.positionCurrent.y) / 3,\r\n (rwA.positionCurrent.z + rwB.positionCurrent.z + rwC.positionCurrent.z) / 3\r\n );\r\n const pushMag = result.pushOut.magnitude;\r\n if (pushMag < EPSILON) {\r\n continue;\r\n }\r\n Vector3.scale(result.pushOut, 1 / pushMag, pushDir);\r\n\r\n for (let k = 0; k < 3; k++) {\r\n const idxR = surfaceConstraints[index + j + k];\r\n const rwPt = pointsRW[idxR];\r\n Vector3.sub(rwPt.positionCurrent, triCenter, centerToPt);\r\n Vector3.sub(rwPt.positionCurrent, result.intersectionPoint, intersectToPt);\r\n const intersectLen = intersectToPt.magnitude;\r\n let rate = intersectLen > EPSILON ? centerToPt.magnitude / intersectLen : 0;\r\n rate = clamp01(Math.abs(rate));\r\n Vector3.scale(pushDir, (result.radius - pushMag) * rate, pushVec);\r\n Vector3.add(rwPt.positionCurrent, pushVec, rwPt.positionCurrent);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n// 閳光偓閳光偓 Constraint relaxation 閳光偓閳光偓\r\n\r\nfunction constraintUpdate(\r\n pointsR: readonly PointR[],\r\n pointsRW: PointRW[],\r\n constraints: readonly Constraint[],\r\n collidersR: readonly ColliderR[],\r\n collidersRW: ColliderRW[],\r\n constraintShrinkLimit: number,\r\n enableBroadPhase: boolean\r\n) {\r\n const direction = new Vector3();\r\n const dirN = new Vector3();\r\n const disp = new Vector3();\r\n const scaledDisp = new Vector3();\r\n const pointResultA: CollisionResult = { hit: false, point: new Vector3() };\r\n const pointResultB: CollisionResult = { hit: false, point: new Vector3() };\r\n const lineResult: LineCollisionResult = {\r\n hit: false,\r\n pointOnLine: new Vector3(),\r\n pointOnCollider: new Vector3(),\r\n radius: 0\r\n };\r\n const pushout = new Vector3();\r\n const segment = new Vector3();\r\n const pointToA = new Vector3();\r\n const pointToB = new Vector3();\r\n const pushN = new Vector3();\r\n const pushVec = new Vector3();\r\n for (let index = 0; index < constraints.length; index++) {\r\n const c = constraints[index];\r\n const ptRA = pointsR[c.indexA];\r\n const ptRB = pointsR[c.indexB];\r\n const weightA = ptRA.weight;\r\n const weightB = ptRB.weight;\r\n if (weightA <= EPSILON && weightB <= EPSILON) {\r\n continue;\r\n }\r\n\r\n const rwA = pointsRW[c.indexA];\r\n const rwB = pointsRW[c.indexB];\r\n\r\n Vector3.sub(rwB.positionCurrent, rwA.positionCurrent, direction);\r\n const distance = direction.magnitude;\r\n\r\n let shrinkLen = c.length;\r\n let stretchLen = shrinkLen;\r\n if (\r\n c.type === ConstraintType.Structural_Horizontal ||\r\n c.type === ConstraintType.Bending_Horizontal ||\r\n c.type === ConstraintType.Shear\r\n ) {\r\n stretchLen += ptRA.sliderJointLength + ptRB.sliderJointLength;\r\n }\r\n\r\n let force = 0;\r\n if (distance <= shrinkLen) {\r\n force = distance - shrinkLen;\r\n } else if (distance >= stretchLen) {\r\n force = distance - stretchLen;\r\n }\r\n\r\n const isShrink = force >= 0;\r\n let power = 0;\r\n switch (c.type) {\r\n case ConstraintType.Structural_Vertical:\r\n power = isShrink\r\n ? ptRA.structuralShrinkVertical + ptRB.structuralShrinkVertical\r\n : ptRA.structuralStretchVertical + ptRB.structuralStretchVertical;\r\n break;\r\n case ConstraintType.Structural_Horizontal:\r\n power = isShrink\r\n ? Math.min(constraintShrinkLimit, ptRA.structuralShrinkHorizontal + ptRB.structuralShrinkHorizontal)\r\n : ptRA.structuralStretchHorizontal + ptRB.structuralStretchHorizontal;\r\n break;\r\n case ConstraintType.Shear:\r\n power = isShrink\r\n ? Math.min(constraintShrinkLimit, ptRA.shearShrink + ptRB.shearShrink)\r\n : ptRA.shearStretch + ptRB.shearStretch;\r\n break;\r\n case ConstraintType.Bending_Vertical:\r\n power = isShrink\r\n ? ptRA.bendingShrinkVertical + ptRB.bendingShrinkVertical\r\n : ptRA.bendingStretchVertical + ptRB.bendingStretchVertical;\r\n break;\r\n case ConstraintType.Bending_Horizontal:\r\n power = isShrink\r\n ? Math.min(constraintShrinkLimit, ptRA.bendingShrinkHorizontal + ptRB.bendingShrinkHorizontal)\r\n : ptRA.bendingStretchHorizontal + ptRB.bendingStretchHorizontal;\r\n break;\r\n }\r\n\r\n if (power > 0) {\r\n if (distance > EPSILON) {\r\n Vector3.scale(direction, 1 / distance, dirN);\r\n } else {\r\n dirN.setXYZ(0, 0, 0);\r\n }\r\n Vector3.scale(dirN, force * power, disp);\r\n const wAB = weightA + weightB;\r\n Vector3.scale(disp, weightA / wAB, scaledDisp);\r\n Vector3.add(rwA.positionCurrent, scaledDisp, rwA.positionCurrent);\r\n Vector3.scale(disp, weightB / wAB, scaledDisp);\r\n Vector3.sub(rwB.positionCurrent, scaledDisp, rwB.positionCurrent);\r\n }\r\n\r\n // Per-constraint collision\r\n if (c.isCollision !== 0) {\r\n let friction = 0;\r\n for (let i = 0; i < collidersR.length; i++) {\r\n const colRW = collidersRW[i];\r\n if (colRW.enabled === 0) {\r\n continue;\r\n }\r\n const colR = collidersR[i];\r\n const canPointA =\r\n !enableBroadPhase ||\r\n colR.isInverseCollider ||\r\n pointMayCollideBroadPhase(rwA.positionCurrent, colRW, ptRA.pointRadius);\r\n const canPointB =\r\n !enableBroadPhase ||\r\n colR.isInverseCollider ||\r\n pointMayCollideBroadPhase(rwB.positionCurrent, colRW, ptRB.pointRadius);\r\n const canLine =\r\n !colR.isInverseCollider &&\r\n (!enableBroadPhase || segmentMayCollideBroadPhase(rwA.positionCurrent, rwB.positionCurrent, colRW));\r\n\r\n if (!canPointA && !canPointB && !canLine) {\r\n continue;\r\n }\r\n\r\n if (colR.height > EPSILON) {\r\n if (colR.isInverseCollider) {\r\n if (ptRA.applyInvertCollision === 1 && canPointA) {\r\n const res = pushInFromCapsule(colR, colRW, rwA.positionCurrent, pointResultA);\r\n if (res.hit) {\r\n rwA.positionCurrent.set(res.point);\r\n friction = Math.max(friction, colR.friction * 0.25);\r\n }\r\n }\r\n if (ptRB.applyInvertCollision === 1 && canPointB) {\r\n const res = pushInFromCapsule(colR, colRW, rwB.positionCurrent, pointResultB);\r\n if (res.hit) {\r\n rwB.positionCurrent.set(res.point);\r\n friction = Math.max(friction, colR.friction * 0.25);\r\n }\r\n }\r\n } else {\r\n if (canPointA) {\r\n const res = pushoutFromCapsule(colR, colRW, rwA.positionCurrent, ptRA, pointResultA);\r\n if (res.hit) {\r\n rwA.positionCurrent.set(res.point);\r\n friction = Math.max(friction, colR.friction * 0.25);\r\n }\r\n }\r\n if (canPointB) {\r\n const res = pushoutFromCapsule(colR, colRW, rwB.positionCurrent, ptRB, pointResultB);\r\n if (res.hit) {\r\n rwB.positionCurrent.set(res.point);\r\n friction = Math.max(friction, colR.friction * 0.25);\r\n }\r\n }\r\n }\r\n } else {\r\n if (colR.isInverseCollider) {\r\n if (ptRA.applyInvertCollision === 1 && canPointA) {\r\n const res = pushInFromSphere(\r\n colRW.positionCurrent,\r\n colRW.radius,\r\n rwA.positionCurrent,\r\n pointResultA\r\n );\r\n if (res.hit) {\r\n rwA.positionCurrent.set(res.point);\r\n friction = Math.max(friction, colR.friction * 0.25);\r\n }\r\n }\r\n if (ptRB.applyInvertCollision === 1 && canPointB) {\r\n const res = pushInFromSphere(\r\n colRW.positionCurrent,\r\n colRW.radius,\r\n rwB.positionCurrent,\r\n pointResultB\r\n );\r\n if (res.hit) {\r\n rwB.positionCurrent.set(res.point);\r\n friction = Math.max(friction, colR.friction * 0.25);\r\n }\r\n }\r\n } else {\r\n if (canPointA) {\r\n const res = pushoutFromSphere(\r\n colRW.positionCurrent,\r\n colRW.radius,\r\n ptRA.pointRadius,\r\n rwA.positionCurrent,\r\n pointResultA\r\n );\r\n if (res.hit) {\r\n rwA.positionCurrent.set(res.point);\r\n friction = Math.max(friction, colR.friction * 0.25);\r\n }\r\n }\r\n if (canPointB) {\r\n const res = pushoutFromSphere(\r\n colRW.positionCurrent,\r\n colRW.radius,\r\n ptRB.pointRadius,\r\n rwB.positionCurrent,\r\n pointResultB\r\n );\r\n if (res.hit) {\r\n rwB.positionCurrent.set(res.point);\r\n friction = Math.max(friction, colR.friction * 0.25);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Line segment collision\r\n if (!colR.isInverseCollider && canLine) {\r\n const lineRes = collisionDetection(\r\n colR,\r\n colRW,\r\n rwA.positionCurrent,\r\n rwB.positionCurrent,\r\n lineResult\r\n );\r\n if (lineRes.hit) {\r\n Vector3.sub(lineRes.pointOnLine, lineRes.pointOnCollider, pushout);\r\n const pushDist = pushout.magnitude;\r\n if (pushDist > EPSILON) {\r\n const ptDist = Vector3.sub(rwB.positionCurrent, rwA.positionCurrent, segment).magnitude * 0.5;\r\n const rateP1 =\r\n ptDist > EPSILON\r\n ? clamp01(\r\n Vector3.sub(lineRes.pointOnLine, rwA.positionCurrent, pointToA).magnitude / ptDist\r\n )\r\n : 0;\r\n const rateP2 =\r\n ptDist > EPSILON\r\n ? clamp01(\r\n Vector3.sub(lineRes.pointOnLine, rwB.positionCurrent, pointToB).magnitude / ptDist\r\n )\r\n : 0;\r\n Vector3.scale(pushout, 1 / pushDist, pushN);\r\n Vector3.scale(pushN, Math.max(lineRes.radius - pushDist, 0), pushVec);\r\n if (weightA > EPSILON) {\r\n Vector3.scale(pushVec, rateP2, scaledDisp);\r\n Vector3.add(rwA.positionCurrent, scaledDisp, rwA.positionCurrent);\r\n }\r\n if (weightB > EPSILON) {\r\n Vector3.scale(pushVec, rateP1, scaledDisp);\r\n Vector3.add(rwB.positionCurrent, scaledDisp, rwB.positionCurrent);\r\n }\r\n\r\n const dotUp = Vector3.dot(AXIS_Y, Vector3.normalize(pushout, pushN));\r\n friction = Math.max(friction, colR.friction * clamp01(dotUp));\r\n }\r\n }\r\n }\r\n }\r\n rwA.friction = Math.max(friction, rwA.friction);\r\n rwB.friction = Math.max(friction, rwB.friction);\r\n }\r\n }\r\n}\r\n\r\n// 閳光偓閳光偓 Pass 2: blend + fake wave 閳光偓閳光偓\r\n\r\nfunction pointUpdatePass2(\r\n pointsR: readonly PointR[],\r\n pointsRW: PointRW[],\r\n positionsToTransform: Vector3[],\r\n stepDelta: number,\r\n fakeWaveFreq: number,\r\n blendRatio: number,\r\n isFakeWave: boolean,\r\n fakeWavePower: number\r\n) {\r\n let freq = fakeWaveFreq;\r\n const curTransformPos = new Vector3();\r\n const fakeWindOffset = new Vector3();\r\n for (let index = 0; index < pointsR.length; index++) {\r\n const ptR = pointsR[index];\r\n const ptRW = pointsRW[index];\r\n\r\n Vector3.lerp(ptRW.positionPreviousTransform, ptRW.positionCurrentTransform, stepDelta, curTransformPos);\r\n const blend = smoothStep(0, 1, Math.max(ptR.forceFadeRatio, blendRatio));\r\n Vector3.lerp(ptRW.positionCurrent, curTransformPos, blend, ptRW.positionToTransform);\r\n\r\n if (isFakeWave && ptR.child === -1 && ptR.parent !== -1) {\r\n const A = pointsRW[ptR.parent].positionToTransform;\r\n const B = ptRW.positionToTransform;\r\n const mAxis = Matrix4x4.lookAt(A, B, AXIS_Y);\r\n // Column 1 = up axis of the look-at matrix\r\n const col1 = mAxis.getCol(1).xyz();\r\n Vector3.lerp(ptRW.fakeWindDirection, col1, 0.5, ptRW.fakeWindDirection);\r\n\r\n freq += ptR.fakeWaveFreq;\r\n const power = Math.sin(freq) * fakeWavePower * ptR.fakeWavePower;\r\n Vector3.scale(ptRW.fakeWindDirection, power, fakeWindOffset);\r\n Vector3.add(ptRW.positionToTransform, fakeWindOffset, ptRW.positionToTransform);\r\n }\r\n\r\n positionsToTransform[index] = ptRW.positionToTransform.clone();\r\n }\r\n}\r\n\r\n// 閳光偓閳光偓 Apply simulation result to transforms 閳光偓閳光偓\r\n\r\nexport interface ApplyResultOutput {\r\n position: Vector3;\r\n rotation: Quaternion;\r\n localRotation: Quaternion;\r\n}\r\n\r\nexport function applyResult(\r\n pointsR: readonly PointR[],\r\n pointsRW: PointRW[],\r\n positionsToTransform: readonly Vector3[],\r\n blendRatio: number,\r\n // Current transform rotations (world and local) read from engine\r\n transformRotations: readonly Quaternion[],\r\n transformLocalRotations: readonly Quaternion[]\r\n): ApplyResultOutput[] {\r\n const results: ApplyResultOutput[] = new Array(pointsR.length);\r\n\r\n for (let index = 0; index < pointsR.length; index++) {\r\n const ptR = pointsR[index];\r\n const ptRW = pointsRW[index];\r\n let worldRot = transformRotations[index];\r\n let localRot = transformLocalRotations[index];\r\n\r\n if (ptR.weight >= EPSILON) {\r\n // Dynamic point\r\n if (ptR.parent !== -1) {\r\n const direction = Vector3.sub(ptRW.positionToTransform, positionsToTransform[ptR.parent]);\r\n const realLen = direction.magnitude;\r\n if (realLen > EPSILON) {\r\n ptRW.directionPrevious = direction;\r\n } else {\r\n ptRW.positionToTransform = Vector3.add(positionsToTransform[ptR.parent], ptRW.directionPrevious);\r\n }\r\n }\r\n const pos = ptRW.positionToTransform;\r\n // SetRotation with blendRatio=0 for dynamic points\r\n // Step 1: Reset localRotation 閳?initialLocalRotation (blendRatio=0 閳?fully initial)\r\n localRot = ptR.initialLocalRotation.clone();\r\n\r\n // Step 2: Recompute worldRot from the new localRot\r\n // In C#, setting localRotation immediately updates the world rotation.\r\n // worldRot = parentWorldRot * localRot\r\n // We approximate: the parent's current world rotation is in transformRotations[ptR.parent]\r\n if (ptR.parent !== -1) {\r\n // Use the parent's OUTPUT rotation (already computed if parent index < current index)\r\n const parentRot = results[ptR.parent] ? results[ptR.parent].rotation : transformRotations[ptR.parent];\r\n worldRot = Quaternion.multiply(parentRot, localRot);\r\n } else {\r\n worldRot = localRot.clone();\r\n }\r\n\r\n // Step 3: Aim toward child using updated worldRot\r\n if (ptR.child !== -1) {\r\n const childDir = Vector3.sub(positionsToTransform[ptR.child], ptRW.positionToTransform);\r\n if (childDir.magnitudeSq > EPSILON) {\r\n const aimVec = worldRot.transform(ptR.boneAxis);\r\n const aimRot = Quaternion.unitVectorToUnitVector(aimVec, childDir);\r\n worldRot = Quaternion.multiply(aimRot, worldRot);\r\n }\r\n }\r\n results[index] = {\r\n position: pos,\r\n rotation: worldRot,\r\n localRotation: localRot\r\n };\r\n } else {\r\n // Fixed point 閳?follow transform, blend rotation\r\n const childBlend =\r\n ptR.child !== -1 ? Math.max(pointsR[ptR.child].forceFadeRatio, blendRatio) : blendRatio;\r\n\r\n // Step 1: Blend localRotation\r\n localRot = Quaternion.slerp(ptR.initialLocalRotation, localRot, childBlend);\r\n\r\n // Step 2: Recompute worldRot from blended localRot\r\n if (ptR.parent !== -1) {\r\n const parentRot = results[ptR.parent] ? results[ptR.parent].rotation : transformRotations[ptR.parent];\r\n worldRot = Quaternion.multiply(parentRot, localRot);\r\n } else {\r\n worldRot = localRot.clone();\r\n }\r\n\r\n // Step 3: Aim toward child with blend\r\n if (ptR.child !== -1) {\r\n const childDir = Vector3.sub(positionsToTransform[ptR.child], ptRW.positionToTransform);\r\n if (childDir.magnitudeSq > EPSILON) {\r\n const aimVec = worldRot.transform(ptR.boneAxis);\r\n const aimRot = Quaternion.unitVectorToUnitVector(aimVec, childDir);\r\n worldRot = Quaternion.slerp(Quaternion.multiply(aimRot, worldRot), worldRot, childBlend);\r\n }\r\n }\r\n results[index] = {\r\n position: ptRW.positionCurrentTransform,\r\n rotation: worldRot,\r\n localRotation: localRot\r\n };\r\n }\r\n }\r\n\r\n return results;\r\n}\r\n\r\n// 閳光偓閳光偓 Angle limiting (post-simulation) 閳光偓閳光偓\r\n\r\nexport function applyAngleLimits(\r\n pointsR: readonly PointR[],\r\n pointsRW: PointRW[],\r\n config: AngleLimitConfig\r\n): void {\r\n if (config.angleLimit < 0) {\r\n return;\r\n }\r\n\r\n for (let index = 0; index < pointsR.length; index++) {\r\n const ptR = pointsR[index];\r\n if (ptR.parent === -1) {\r\n continue;\r\n }\r\n const ptRW = pointsRW[index];\r\n\r\n const ptRp = pointsR[ptR.parent];\r\n const ptRWp = pointsRW[ptR.parent];\r\n\r\n const superParentPos = ptRp.parent !== -1 ? pointsRW[ptRp.parent].positionCurrent : ptRWp.positionCurrent;\r\n\r\n const boneDir = Vector3.sub(ptRW.positionCurrent, ptRWp.positionCurrent);\r\n let parentBoneDir = Vector3.sub(ptRWp.positionCurrent, superParentPos);\r\n\r\n if (parentBoneDir.magnitude === 0 || config.limitFromRoot) {\r\n parentBoneDir = Vector3.sub(ptRW.positionCurrentTransform, ptRWp.positionCurrentTransform);\r\n }\r\n\r\n const angle = Vector3.angleBetween(parentBoneDir, boneDir);\r\n const remaining = radian2degree(angle) - config.angleLimit;\r\n\r\n if (remaining > 0) {\r\n const axis = Vector3.cross(parentBoneDir, boneDir);\r\n const rotated = Quaternion.fromAxisAngle(axis, degree2radian(-remaining)).transform(boneDir);\r\n ptRW.positionCurrent = Vector3.add(ptRWp.positionCurrent, rotated);\r\n }\r\n }\r\n}\r\n"],"names":["AXIS_Y","Vector3","VEC3_ONE","_computeCapsuleAxis","_computeCapsuleHalfDir","_applySystemTransformOffset","_applySystemTransformRotated","_broadPhaseSegmentDir","_broadPhaseToCenter","_broadPhaseClosestPoint","_broadPhaseDelta","simulate","params","pointsR","pointsRW","constraints","collidersR","collidersRW","grabbersR","grabbersRW","movableLimitTargets","flatPlanes","pointCount","length","positionsToTransform","Array","subSteps","isPaused","fakeWaveFreq","fakeWaveCounter","rootSlideOffset","zero","rootDeltaSlide","sub","rootPosition","previousRootPosition","rootDeltaSlideLen","magnitude","rootSlideLimit","scale","rootRotationOffset","Quaternion","identity","rootDeltaRot","multiply","rootRotation","inverse","previousRootRotation","rotateAngle","Math","acos","max","min","w","PI","rootRotateLimit","abs","rotateAxis","isFinite","x","y","z","axisPY","angle","fromAxisAngle","degree2radian","stepTime","iSubStep","stepDelta","stepTime_x2_half","colliderUpdate","collisionScale","pointUpdatePass1","windForce","fakeWaveSpeed","enableSurfaceCollision","surfaceCollision","surfaceConstraints","iRelax","relaxation","constraintUpdate","constraintShrinkLimit","enableBroadPhase","pointUpdatePass2","blendRatio","isFakeWave","fakeWavePower","computeCapsule","pos","rot","height","head","direction","transform","curPos","curDir","corner","center","tailCorner","tailCenter","i","colR","colRW","radius","lerp","positionPreviousTransform","positionCurrentTransform","slerp","directionPreviousTransform","directionCurrentTransform","positionCurrent","directionCurrent","EPSILON","add","boundsCenter","boundsRadius","sqrt","magnitudeSq","radiusTailScale","set","worldToLocal","transformPointAffine","localBoundsMin","localBoundsMax","setXYZ","applySystemTransform","point","pivot","slideOffset","rotOffset","result","rotated","pointMayCollideBroadPhase","padding","delta","segmentMayCollideBroadPhase","point1","point2","segmentDir","lenSq","toCenter","t","clamp01","dot","closestPoint","currentTransformPos","moveDir","extForce","displacement","restore","tempVec0","tempVec1","planeOffset","index","ptR","ptRW","weight","positionPrevious","windForceScale","mass","gravity","resistance","friction","frictionScale","hardness","forceFadeRatio","grabberIndex","grR","grRW","enabled","position","normalize","grabberDistance","force","nearIndex","sqrNearRange","ig","sqrLen","movableLimitIndex","target","move","moveLen","movableLimitRadius","fp","dist","normal","distance","surfaceResult","hit","intersectionPoint","pushOut","pointOnCollider","triCenter","pushDir","centerToPt","intersectToPt","pushVec","colliderPos","j","idxA","idxB","idxC","rwA","rwB","rwC","checkSurfaceCollision","pushMag","k","idxR","rwPt","intersectLen","rate","dirN","disp","scaledDisp","pointResultA","pointResultB","lineResult","pointOnLine","pushout","segment","pointToA","pointToB","pushN","c","ptRA","indexA","ptRB","indexB","weightA","weightB","shrinkLen","stretchLen","type","ConstraintType","Structural_Horizontal","Bending_Horizontal","Shear","sliderJointLength","isShrink","power","Structural_Vertical","structuralShrinkVertical","structuralStretchVertical","structuralShrinkHorizontal","structuralStretchHorizontal","shearShrink","shearStretch","Bending_Vertical","bendingShrinkVertical","bendingStretchVertical","bendingShrinkHorizontal","bendingStretchHorizontal","wAB","isCollision","canPointA","isInverseCollider","pointRadius","canPointB","canLine","applyInvertCollision","res","pushInFromCapsule","pushoutFromCapsule","pushInFromSphere","pushoutFromSphere","lineRes","collisionDetection","pushDist","ptDist","rateP1","rateP2","dotUp","freq","curTransformPos","fakeWindOffset","blend","smoothStep","positionToTransform","child","parent","A","B","mAxis","Matrix4x4","lookAt","col1","getCol","xyz","fakeWindDirection","sin","clone","applyResult","transformRotations","transformLocalRotations","results","worldRot","localRot","realLen","directionPrevious","initialLocalRotation","parentRot","rotation","childDir","aimVec","boneAxis","aimRot","unitVectorToUnitVector","localRotation","childBlend","applyAngleLimits","config","angleLimit","ptRp","ptRWp","superParentPos","boneDir","parentBoneDir","limitFromRoot","angleBetween","remaining","radian2degree","axis","cross"],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Quaternion } from '@zephyr3d/base';
|
|
2
|
+
import { SpringSystemController } from './controller.js';
|
|
3
|
+
|
|
4
|
+
const _quat = new Quaternion();
|
|
5
|
+
function createTransformAccess(obj) {
|
|
6
|
+
return {
|
|
7
|
+
getWorldPosition () {
|
|
8
|
+
return obj.getWorldPosition();
|
|
9
|
+
},
|
|
10
|
+
getWorldRotation () {
|
|
11
|
+
const q = new Quaternion();
|
|
12
|
+
obj.worldMatrix.decompose(null, q, null);
|
|
13
|
+
return q;
|
|
14
|
+
},
|
|
15
|
+
getLocalPosition () {
|
|
16
|
+
return obj.position.clone();
|
|
17
|
+
},
|
|
18
|
+
getLocalRotation () {
|
|
19
|
+
return obj.rotation.clone();
|
|
20
|
+
},
|
|
21
|
+
getLocalScale () {
|
|
22
|
+
return obj.scale.clone();
|
|
23
|
+
},
|
|
24
|
+
setWorldPosition (p) {
|
|
25
|
+
if (obj.parent) {
|
|
26
|
+
obj.position = obj.parent.invWorldMatrix.transformPointAffine(p);
|
|
27
|
+
} else {
|
|
28
|
+
obj.position.set(p);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
setWorldRotation (q) {
|
|
32
|
+
// Convert world rotation to local: localRot = inverse(parentWorldRot) * worldRot
|
|
33
|
+
if (obj.parent) {
|
|
34
|
+
obj.parent.worldMatrix.decompose(null, _quat, null);
|
|
35
|
+
Quaternion.multiply(Quaternion.inverse(_quat), q, obj.rotation);
|
|
36
|
+
} else {
|
|
37
|
+
obj.rotation.set(q);
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
setLocalPosition (p) {
|
|
41
|
+
obj.position.set(p);
|
|
42
|
+
},
|
|
43
|
+
setLocalRotation (q) {
|
|
44
|
+
obj.rotation.set(q);
|
|
45
|
+
},
|
|
46
|
+
setLocalScale (s) {
|
|
47
|
+
obj.scale.set(s);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Physics engine for spring-based particle simulation
|
|
53
|
+
* Uses Verlet integration and iterative constraint solving
|
|
54
|
+
*
|
|
55
|
+
* @public
|
|
56
|
+
*/ class SpringSystem2 {
|
|
57
|
+
_controller;
|
|
58
|
+
constructor(options, chainConfig, colliders, grabbers, flatPlanes){
|
|
59
|
+
const rootPoints = [];
|
|
60
|
+
const boneNodes = [];
|
|
61
|
+
const pointTransforms = [];
|
|
62
|
+
let index = 0;
|
|
63
|
+
for (const chain of chainConfig.chains){
|
|
64
|
+
const chainNodes = this.collectChainNodes(chain.start, chain.end);
|
|
65
|
+
for(let i = 0; i < chainNodes.length; i++){
|
|
66
|
+
const node = chainNodes[i];
|
|
67
|
+
const boneNode = {
|
|
68
|
+
index: index++,
|
|
69
|
+
position: node.getWorldPosition(),
|
|
70
|
+
children: [],
|
|
71
|
+
isFixed: i === 0,
|
|
72
|
+
depth: i
|
|
73
|
+
};
|
|
74
|
+
boneNodes.push(boneNode);
|
|
75
|
+
pointTransforms.push(createTransformAccess(node));
|
|
76
|
+
if (i > 0) {
|
|
77
|
+
boneNodes[boneNodes.length - 2].children.push(boneNode);
|
|
78
|
+
}
|
|
79
|
+
if (i === 0) {
|
|
80
|
+
rootPoints.push(boneNode);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const systemRoot = createTransformAccess(chainConfig.systemRoot);
|
|
85
|
+
this._controller = new SpringSystemController(options);
|
|
86
|
+
this._controller.initialize(systemRoot, rootPoints, pointTransforms, colliders, grabbers, flatPlanes);
|
|
87
|
+
}
|
|
88
|
+
get controller() {
|
|
89
|
+
return this._controller;
|
|
90
|
+
}
|
|
91
|
+
collectChainNodes(start, end) {
|
|
92
|
+
if (!start.isParentOf(end)) {
|
|
93
|
+
throw new Error('Invalid chain: end node must be a descendant of start node');
|
|
94
|
+
}
|
|
95
|
+
const nodes = [];
|
|
96
|
+
let current = end;
|
|
97
|
+
for(;;){
|
|
98
|
+
nodes.unshift(current);
|
|
99
|
+
if (current === start) {
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
current = current.parent;
|
|
103
|
+
}
|
|
104
|
+
return nodes;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Updates the physics simulation
|
|
108
|
+
* @param deltaTime - Time step in seconds
|
|
109
|
+
*/ update(deltaTime) {
|
|
110
|
+
// Clamp deltaTime to prevent instability
|
|
111
|
+
const dt = Math.min(deltaTime, 0.033); // Max 30 FPS
|
|
112
|
+
// simulation
|
|
113
|
+
this._controller.step(dt);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export { SpringSystem2, createTransformAccess };
|
|
118
|
+
//# sourceMappingURL=spring_system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spring_system.js","sources":["../../../src/animation/spring2/spring_system.ts"],"sourcesContent":["import type { Vector3 } from '@zephyr3d/base';\r\nimport { Quaternion } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../../scene';\r\nimport type { ControllerConfig } from './controller';\r\nimport { SpringSystemController } from './controller';\r\nimport type { BoneNode, ColliderR, GrabberR, TransformAccess } from './types';\r\n\r\nconst _quat = new Quaternion();\r\n\r\nexport function createTransformAccess(obj: SceneNode): TransformAccess {\r\n return {\r\n getWorldPosition(): Vector3 {\r\n return obj.getWorldPosition();\r\n },\r\n getWorldRotation(): Quaternion {\r\n const q = new Quaternion();\r\n obj.worldMatrix.decompose(null, q, null);\r\n return q;\r\n },\r\n getLocalPosition(): Vector3 {\r\n return obj.position.clone();\r\n },\r\n getLocalRotation(): Quaternion {\r\n return obj.rotation.clone();\r\n },\r\n getLocalScale(): Vector3 {\r\n return obj.scale.clone();\r\n },\r\n setWorldPosition(p: Vector3): void {\r\n if (obj.parent) {\r\n obj.position = obj.parent.invWorldMatrix.transformPointAffine(p);\r\n } else {\r\n obj.position.set(p);\r\n }\r\n },\r\n setWorldRotation(q: Quaternion): void {\r\n // Convert world rotation to local: localRot = inverse(parentWorldRot) * worldRot\r\n if (obj.parent) {\r\n obj.parent.worldMatrix.decompose(null, _quat, null);\r\n Quaternion.multiply(Quaternion.inverse(_quat), q, obj.rotation);\r\n } else {\r\n obj.rotation.set(q);\r\n }\r\n },\r\n setLocalPosition(p: Vector3): void {\r\n obj.position.set(p);\r\n },\r\n setLocalRotation(q: Quaternion): void {\r\n obj.rotation.set(q);\r\n },\r\n setLocalScale(s: Vector3): void {\r\n obj.scale.set(s);\r\n }\r\n };\r\n}\r\n\r\nexport type SpringChainConfig = {\r\n systemRoot: SceneNode;\r\n chains: { start: SceneNode; end: SceneNode }[];\r\n};\r\n\r\n/**\r\n * Physics engine for spring-based particle simulation\r\n * Uses Verlet integration and iterative constraint solving\r\n *\r\n * @public\r\n */\r\nexport class SpringSystem2 {\r\n private _controller: SpringSystemController;\r\n constructor(\r\n options: ControllerConfig,\r\n chainConfig: SpringChainConfig,\r\n colliders: { r: ColliderR; transform: TransformAccess }[],\r\n grabbers: {\r\n r: GrabberR;\r\n transform: TransformAccess;\r\n enabled: boolean;\r\n }[],\r\n flatPlanes: { up: Vector3; position: Vector3 }[]\r\n ) {\r\n const rootPoints: BoneNode[] = [];\r\n const boneNodes: BoneNode[] = [];\r\n const pointTransforms: TransformAccess[] = [];\r\n let index = 0;\r\n for (const chain of chainConfig.chains) {\r\n const chainNodes = this.collectChainNodes(chain.start, chain.end);\r\n for (let i = 0; i < chainNodes.length; i++) {\r\n const node = chainNodes[i];\r\n const boneNode = {\r\n index: index++,\r\n position: node.getWorldPosition(),\r\n children: [],\r\n isFixed: i === 0, // Fix the first bone in the chain\r\n depth: i\r\n };\r\n boneNodes.push(boneNode);\r\n pointTransforms.push(createTransformAccess(node));\r\n if (i > 0) {\r\n boneNodes[boneNodes.length - 2].children.push(boneNode);\r\n }\r\n if (i === 0) {\r\n rootPoints.push(boneNode);\r\n }\r\n }\r\n }\r\n const systemRoot = createTransformAccess(chainConfig.systemRoot);\r\n this._controller = new SpringSystemController(options);\r\n this._controller.initialize(systemRoot, rootPoints, pointTransforms, colliders, grabbers, flatPlanes);\r\n }\r\n\r\n get controller() {\r\n return this._controller;\r\n }\r\n\r\n private collectChainNodes(start: SceneNode, end: SceneNode): SceneNode[] {\r\n if (!start.isParentOf(end)) {\r\n throw new Error('Invalid chain: end node must be a descendant of start node');\r\n }\r\n const nodes: SceneNode[] = [];\r\n let current: SceneNode = end;\r\n for (;;) {\r\n nodes.unshift(current);\r\n if (current === start) {\r\n break;\r\n }\r\n current = current.parent!;\r\n }\r\n return nodes;\r\n }\r\n /**\r\n * Updates the physics simulation\r\n * @param deltaTime - Time step in seconds\r\n */\r\n update(deltaTime: number): void {\r\n // Clamp deltaTime to prevent instability\r\n const dt = Math.min(deltaTime, 0.033); // Max 30 FPS\r\n // simulation\r\n this._controller.step(dt);\r\n }\r\n}\r\n"],"names":["_quat","Quaternion","createTransformAccess","obj","getWorldPosition","getWorldRotation","q","worldMatrix","decompose","getLocalPosition","position","clone","getLocalRotation","rotation","getLocalScale","scale","setWorldPosition","p","parent","invWorldMatrix","transformPointAffine","set","setWorldRotation","multiply","inverse","setLocalPosition","setLocalRotation","setLocalScale","s","SpringSystem2","_controller","options","chainConfig","colliders","grabbers","flatPlanes","rootPoints","boneNodes","pointTransforms","index","chain","chains","chainNodes","collectChainNodes","start","end","i","length","node","boneNode","children","isFixed","depth","push","systemRoot","SpringSystemController","initialize","controller","isParentOf","Error","nodes","current","unshift","update","deltaTime","dt","Math","min","step"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Data structure definitions — direct port of C# structs from SPCRJointDynamicsJob.cs
|
|
2
|
+
const EPSILON = 0.001;
|
|
3
|
+
/** Constraint topology type */ var ConstraintType = /*#__PURE__*/ function(ConstraintType) {
|
|
4
|
+
/** Parent-child bone pairs along vertical chains */ ConstraintType[ConstraintType["Structural_Vertical"] = 0] = "Structural_Vertical";
|
|
5
|
+
/** Same-depth bones across adjacent chains */ ConstraintType[ConstraintType["Structural_Horizontal"] = 1] = "Structural_Horizontal";
|
|
6
|
+
/** Diagonal cross-bracing between adjacent chains */ ConstraintType[ConstraintType["Shear"] = 2] = "Shear";
|
|
7
|
+
/** Skip-one vertical (grandparent→grandchild) for bending resistance */ ConstraintType[ConstraintType["Bending_Vertical"] = 3] = "Bending_Vertical";
|
|
8
|
+
/** Skip-one horizontal across chains for bending resistance */ ConstraintType[ConstraintType["Bending_Horizontal"] = 4] = "Bending_Horizontal";
|
|
9
|
+
return ConstraintType;
|
|
10
|
+
}({});
|
|
11
|
+
/** Collider surface force direction (used for surface/triangle collision) */ var ColliderForce = /*#__PURE__*/ function(ColliderForce) {
|
|
12
|
+
/** No surface force */ ColliderForce[ColliderForce["Off"] = 0] = "Off";
|
|
13
|
+
/** Push surface outward from collider */ ColliderForce[ColliderForce["Push"] = 1] = "Push";
|
|
14
|
+
/** Pull surface inward toward collider */ ColliderForce[ColliderForce["Pull"] = 2] = "Pull";
|
|
15
|
+
return ColliderForce;
|
|
16
|
+
}({});
|
|
17
|
+
|
|
18
|
+
export { ColliderForce, ConstraintType, EPSILON };
|
|
19
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../src/animation/spring2/types.ts"],"sourcesContent":["// Data structure definitions — direct port of C# structs from SPCRJointDynamicsJob.cs\r\n\r\nimport type { Matrix4x4, Quaternion, Vector3 } from '@zephyr3d/base';\r\n\r\nexport const EPSILON = 0.001;\r\n\r\n/** Constraint topology type */\r\nexport const enum ConstraintType {\r\n /** Parent-child bone pairs along vertical chains */\r\n Structural_Vertical = 0,\r\n /** Same-depth bones across adjacent chains */\r\n Structural_Horizontal = 1,\r\n /** Diagonal cross-bracing between adjacent chains */\r\n Shear = 2,\r\n /** Skip-one vertical (grandparent→grandchild) for bending resistance */\r\n Bending_Vertical = 3,\r\n /** Skip-one horizontal across chains for bending resistance */\r\n Bending_Horizontal = 4\r\n}\r\n\r\n/** Collider surface force direction (used for surface/triangle collision) */\r\nexport const enum ColliderForce {\r\n /** No surface force */\r\n Off = 0,\r\n /** Push surface outward from collider */\r\n Push = 1,\r\n /** Pull surface inward toward collider */\r\n Pull = 2\r\n}\r\n\r\n/**\r\n * Read-only per-point physics parameters.\r\n * Set once at initialization, immutable during simulation.\r\n * Constraint scale values are pre-multiplied by 0.5 (summed between two points in solver).\r\n */\r\nexport interface PointR {\r\n /** Index of parent point in the hierarchy (-1 = root, no parent) */\r\n parent: number;\r\n /** Index of first child point (-1 = leaf, no child) */\r\n child: number;\r\n /** Whether this point responds to inverse colliders (0 or 1) */\r\n applyInvertCollision: number;\r\n /** Index into movableLimitTargets array (-1 = no limit) */\r\n movableLimitIndex: number;\r\n /** Max distance from movable limit target (sphere constraint radius) */\r\n movableLimitRadius: number;\r\n /** 0 = fixed (follows animation), 1 = dynamic (simulated) */\r\n weight: number;\r\n /** Mass of the point, affects wind force scaling */\r\n mass: number;\r\n /** Velocity damping factor [0-1]. Higher = less damping, more movement */\r\n resistance: number;\r\n /** Restore-to-animation strength [0-1]. Higher = stiffer, pulls toward animated pose */\r\n hardness: number;\r\n /** Multiplier for accumulated friction from collisions */\r\n frictionScale: number;\r\n /** Extra slack length added to horizontal/shear constraint stretch limits */\r\n sliderJointLength: number;\r\n /** Distance to parent point (used for angle limiting) */\r\n parentLength: number;\r\n /** Structural vertical constraint shrink stiffness (×0.5, summed with other point) */\r\n structuralShrinkVertical: number;\r\n /** Structural vertical constraint stretch stiffness */\r\n structuralStretchVertical: number;\r\n /** Structural horizontal constraint shrink stiffness */\r\n structuralShrinkHorizontal: number;\r\n /** Structural horizontal constraint stretch stiffness */\r\n structuralStretchHorizontal: number;\r\n /** Shear constraint shrink stiffness */\r\n shearShrink: number;\r\n /** Shear constraint stretch stiffness */\r\n shearStretch: number;\r\n /** Bending vertical constraint shrink stiffness */\r\n bendingShrinkVertical: number;\r\n /** Bending vertical constraint stretch stiffness */\r\n bendingStretchVertical: number;\r\n /** Bending horizontal constraint shrink stiffness */\r\n bendingShrinkHorizontal: number;\r\n /** Bending horizontal constraint stretch stiffness */\r\n bendingStretchHorizontal: number;\r\n /** Wind force multiplier (scaled by depth rate) */\r\n windForceScale: number;\r\n /** Fake wave amplitude multiplier for leaf bones */\r\n fakeWavePower: number;\r\n /** Fake wave frequency offset for leaf bones */\r\n fakeWaveFreq: number;\r\n /** Blend ratio toward animation pose [0-1]. Used for fade in/out */\r\n forceFadeRatio: number;\r\n /** Collision radius of this point (used in sphere/capsule pushout) */\r\n pointRadius: number;\r\n /** Gravity vector applied to this point (scaled by depth curve) */\r\n gravity: Vector3;\r\n /** Local-space direction from this bone to its first child (for rotation calculation) */\r\n boneAxis: Vector3;\r\n /** Initial local scale captured at init (for transform reset) */\r\n initialLocalScale: Vector3;\r\n /** Initial local rotation captured at init (for rotation blending) */\r\n initialLocalRotation: Quaternion;\r\n /** Initial local position captured at init (for transform reset) */\r\n initialLocalPosition: Vector3;\r\n}\r\n\r\n/**\r\n * Mutable per-point simulation state.\r\n * Updated every substep during simulation.\r\n */\r\nexport interface PointRW {\r\n /** Final output position to write back to the transform */\r\n positionToTransform: Vector3;\r\n /** Current frame's animated world position (read from transform) */\r\n positionCurrentTransform: Vector3;\r\n /** Previous frame's animated world position */\r\n positionPreviousTransform: Vector3;\r\n /** Current simulated world position (Verlet integration state) */\r\n positionCurrent: Vector3;\r\n /** Previous simulated world position (Verlet integration state) */\r\n positionPrevious: Vector3;\r\n /** Previous frame's bone direction (fallback when direction is zero-length) */\r\n directionPrevious: Vector3;\r\n /** Interpolated wind direction for fake wave effect */\r\n fakeWindDirection: Vector3;\r\n /** Index of the grabber currently holding this point (-1 = not grabbed) */\r\n grabberIndex: number;\r\n /** Distance maintained from grabber center when grabbed */\r\n grabberDistance: number;\r\n /** Accumulated friction from collisions this frame (reset each substep) */\r\n friction: number;\r\n}\r\n\r\n/** Distance constraint between two points */\r\nexport interface Constraint {\r\n /** Whether collision detection runs for this constraint's bone pair (0 or 1) */\r\n isCollision: number;\r\n /** Constraint topology type */\r\n type: ConstraintType;\r\n /** Index of first connected point */\r\n indexA: number;\r\n /** Index of second connected point */\r\n indexB: number;\r\n /** Rest length — the target distance between the two points */\r\n length: number;\r\n}\r\n\r\n/** Read-only collider shape parameters (set at init) */\r\nexport interface ColliderR {\r\n /** Base radius of the collider sphere (or capsule head) */\r\n radius: number;\r\n /** Scale factor for capsule tail radius relative to head (1.0 = uniform) */\r\n radiusTailScale: number;\r\n /** Capsule height. 0 = sphere collider, >0 = capsule collider */\r\n height: number;\r\n /** Friction coefficient applied on collision contact */\r\n friction: number;\r\n /** If true, keeps points INSIDE the collider (e.g. muscle volume) */\r\n isInverseCollider: boolean;\r\n /** Surface force direction for triangle/surface collision */\r\n forceType: ColliderForce;\r\n}\r\n\r\n/** Mutable collider runtime state (updated each frame) */\r\nexport interface ColliderRW {\r\n /** Current interpolated head position (for this substep) */\r\n positionCurrent: Vector3;\r\n /** Current interpolated capsule direction vector (head→tail) */\r\n directionCurrent: Vector3;\r\n /** World-space broad-phase center for current collider */\r\n boundsCenter: Vector3;\r\n /** World-space broad-phase radius for current collider */\r\n boundsRadius: number;\r\n /** This frame's world position (read from transform) */\r\n positionCurrentTransform: Vector3;\r\n /** Previous frame's world position */\r\n positionPreviousTransform: Vector3;\r\n /** This frame's world rotation (read from transform) */\r\n directionCurrentTransform: Quaternion;\r\n /** Previous frame's world rotation */\r\n directionPreviousTransform: Quaternion;\r\n /** World-to-local matrix for AABB bounds computation */\r\n worldToLocal: Matrix4x4;\r\n /** Local-space AABB min corner */\r\n localBoundsMin: Vector3;\r\n /** Local-space AABB max corner */\r\n localBoundsMax: Vector3;\r\n /** Scaled radius for current frame (base radius × collisionScale) */\r\n radius: number;\r\n /** Whether this collider is active (0 = disabled, 1 = enabled) */\r\n enabled: number;\r\n}\r\n\r\n/** Read-only grabber parameters (set at init) */\r\nexport interface GrabberR {\r\n /** Grab activation radius — points within this distance can be grabbed */\r\n radius: number;\r\n /** Pull strength toward grabber [0-1]. 1 = snap to grabber, 0 = no pull */\r\n force: number;\r\n}\r\n\r\n/** Mutable grabber runtime state (updated each frame) */\r\nexport interface GrabberRW {\r\n /** Whether this grabber is active (0 = disabled, 1 = enabled) */\r\n enabled: number;\r\n /** Current world position of the grabber */\r\n position: Vector3;\r\n}\r\n\r\n/** Angle limiting configuration for post-simulation bone angle clamping */\r\nexport interface AngleLimitConfig {\r\n /** Max angle in degrees between parent and child bone. Negative = disabled */\r\n angleLimit: number;\r\n /** If true, measure angle from original transform orientation instead of simulated parent */\r\n limitFromRoot: boolean;\r\n}\r\n\r\n/** Flat plane limiter — infinite plane that points cannot pass through */\r\nexport interface FlatPlane {\r\n /** Plane normal (points toward the \"allowed\" side) */\r\n normal: Vector3;\r\n /** Signed distance from origin (plane equation: dot(normal, point) + distance = 0) */\r\n distance: number;\r\n}\r\n\r\n/**\r\n * Input point data for low-level initialization (mirrors C# Point struct).\r\n * Used when bypassing the Controller and calling the solver directly.\r\n */\r\nexport interface PointInit {\r\n /** Parent point index (-1 = no parent) */\r\n parent: number;\r\n /** Child point index (-1 = no child) */\r\n child: number;\r\n /** Index into movable limit targets array (-1 = none) */\r\n movableLimitIndex: number;\r\n /** Whether to respond to inverse colliders (0 or 1) */\r\n applyInvertCollision: number;\r\n /** Movable limit sphere radius */\r\n movableLimitRadius: number;\r\n /** 0 = fixed, 1 = dynamic */\r\n weight: number;\r\n /** Point mass */\r\n mass: number;\r\n /** Velocity damping [0-1] */\r\n resistance: number;\r\n /** Restore-to-animation stiffness [0-1] */\r\n hardness: number;\r\n /** Friction scale multiplier */\r\n frictionScale: number;\r\n /** Extra slack for horizontal/shear stretch */\r\n sliderJointLength: number;\r\n /** Fake wave amplitude */\r\n fakeWavePower: number;\r\n /** Fake wave frequency offset */\r\n fakeWaveFreq: number;\r\n /** Distance to parent point */\r\n parentLength: number;\r\n /** Structural vertical shrink stiffness */\r\n structuralShrinkVertical: number;\r\n /** Structural vertical stretch stiffness */\r\n structuralStretchVertical: number;\r\n /** Structural horizontal shrink stiffness */\r\n structuralShrinkHorizontal: number;\r\n /** Structural horizontal stretch stiffness */\r\n structuralStretchHorizontal: number;\r\n /** Shear shrink stiffness */\r\n shearShrink: number;\r\n /** Shear stretch stiffness */\r\n shearStretch: number;\r\n /** Bending vertical shrink stiffness */\r\n bendingShrinkVertical: number;\r\n /** Bending vertical stretch stiffness */\r\n bendingStretchVertical: number;\r\n /** Bending horizontal shrink stiffness */\r\n bendingShrinkHorizontal: number;\r\n /** Bending horizontal stretch stiffness */\r\n bendingStretchHorizontal: number;\r\n /** Wind force multiplier */\r\n windForceScale: number;\r\n /** Collision radius */\r\n pointRadius: number;\r\n /** Gravity vector */\r\n gravity: Vector3;\r\n /** Local-space bone axis direction */\r\n boneAxis: Vector3;\r\n /** Initial world position */\r\n position: Vector3;\r\n /** Initial direction */\r\n direction: Vector3;\r\n}\r\n\r\n/**\r\n * Engine-agnostic transform read/write interface.\r\n * Implement this to bridge the solver with any rendering engine (Three.js, Babylon, custom).\r\n */\r\nexport interface TransformAccess {\r\n /** Read world-space position */\r\n getWorldPosition(): Vector3;\r\n /** Read world-space rotation */\r\n getWorldRotation(): Quaternion;\r\n /** Read local-space position (relative to parent) */\r\n getLocalPosition(): Vector3;\r\n /** Read local-space rotation (relative to parent) */\r\n getLocalRotation(): Quaternion;\r\n /** Read local scale */\r\n getLocalScale(): Vector3;\r\n /** Write world-space position (implementation must convert to local if parented) */\r\n setWorldPosition(p: Vector3): void;\r\n /** Write world-space rotation (implementation must convert to local if parented) */\r\n setWorldRotation(q: Quaternion): void;\r\n /** Write local-space position */\r\n setLocalPosition(p: Vector3): void;\r\n /** Write local-space rotation */\r\n setLocalRotation(q: Quaternion): void;\r\n /** Write local scale */\r\n setLocalScale(s: Vector3): void;\r\n}\r\n\r\n/**\r\n * Bone hierarchy node for constraint building.\r\n * Represents a single bone in the tree structure passed to buildConstraints().\r\n */\r\nexport interface BoneNode {\r\n /** Unique index of this bone (must match the position in the pointTransforms array) */\r\n index: number;\r\n /** World-space position at initialization time (used for rest-length calculation) */\r\n position: Vector3;\r\n /** Child nodes in the hierarchy */\r\n children: BoneNode[];\r\n /** If true, this point is fixed (weight=0, follows animation) — typically depth=0 roots */\r\n isFixed: boolean;\r\n /** Depth in the hierarchy (0 = root, increments per level) */\r\n depth: number;\r\n /** Whether to include in surface collision triangle generation (default: true) */\r\n useForSurfaceCollision?: boolean;\r\n /** Local-space direction to first child. Auto-computed from transforms if omitted */\r\n boneAxis?: Vector3;\r\n}\r\n"],"names":["EPSILON","ConstraintType","ColliderForce"],"mappings":"AAAA;AAIO,MAAMA,UAAU;AAEvB,gCACO,IAAWC,cAAAA,iBAAAA,SAAAA,cAAAA,EAAAA;yDACkC,cAAA,CAAA,cAAA,CAAA,qBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,qBAAA;mDAEN,cAAA,CAAA,cAAA,CAAA,uBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,uBAAA;0DAEO,cAAA,CAAA,cAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;6EAEmB,cAAA,CAAA,cAAA,CAAA,kBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,kBAAA;oEAET,cAAA,CAAA,cAAA,CAAA,oBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,oBAAA;AAT7CA,IAAAA,OAAAA,cAAAA;AAWjB,CAAA,CAAA,EAAA;AAED,8EACO,IAAWC,aAAAA,iBAAAA,SAAAA,aAAAA,EAAAA;4BACK,aAAA,CAAA,aAAA,CAAA,KAAA,CAAA,GAAA,CAAA,CAAA,GAAA,KAAA;8CAEkB,aAAA,CAAA,aAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAA;+CAEC,aAAA,CAAA,aAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAA;AALxBA,IAAAA,OAAAA,aAAAA;AAOjB,CAAA,CAAA,EAAA;;;;"}
|
|
@@ -6,16 +6,20 @@ import { SkeletonModifier } from './skeleton_modifier.js';
|
|
|
6
6
|
* Integrates spring-based physics simulation into the skeleton post-processing pipeline.
|
|
7
7
|
* The spring system is updated each frame and results are blended with the base animation.
|
|
8
8
|
*
|
|
9
|
+
* @deprecated Use the new {@link JointDynamicsModifier} class instead.
|
|
10
|
+
*
|
|
9
11
|
* @public
|
|
10
12
|
*/ class SpringModifier extends SkeletonModifier {
|
|
11
13
|
_springSystem;
|
|
14
|
+
_weight;
|
|
12
15
|
/**
|
|
13
16
|
* Create a spring post-processor.
|
|
14
17
|
*
|
|
15
18
|
* @param springSystem - The spring system to integrate
|
|
16
19
|
* @param weight - Blend weight [0-1] (default: 1.0)
|
|
17
20
|
*/ constructor(springSystem, weight = 1.0){
|
|
18
|
-
super(
|
|
21
|
+
super();
|
|
22
|
+
this._weight = weight;
|
|
19
23
|
this._springSystem = springSystem;
|
|
20
24
|
}
|
|
21
25
|
/**
|
|
@@ -39,6 +43,18 @@ import { SkeletonModifier } from './skeleton_modifier.js';
|
|
|
39
43
|
*/ reset() {
|
|
40
44
|
this._springSystem.reset();
|
|
41
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Get the blend weight for this processor.
|
|
48
|
+
* @returns The current blend weight (0-1)
|
|
49
|
+
*/ _getWeight() {
|
|
50
|
+
return this._weight;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Set the blend weight for this processor.
|
|
54
|
+
* @param value - New blend weight (0-1)
|
|
55
|
+
*/ _setWeight(value) {
|
|
56
|
+
this._weight = Math.max(0, Math.min(1, value));
|
|
57
|
+
}
|
|
42
58
|
}
|
|
43
59
|
|
|
44
60
|
export { SpringModifier };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spring_modifier.js","sources":["../../src/animation/spring_modifier.ts"],"sourcesContent":["import { SkeletonModifier } from './skeleton_modifier';\r\nimport type { Skeleton } from './skeleton';\r\nimport type { SpringSystem } from './spring/spring_system';\r\n\r\n/**\r\n * Post-processor wrapper for spring physics systems.\r\n *\r\n * Integrates spring-based physics simulation into the skeleton post-processing pipeline.\r\n * The spring system is updated each frame and results are blended with the base animation.\r\n *\r\n * @public\r\n */\r\nexport class SpringModifier extends SkeletonModifier {\r\n private _springSystem: SpringSystem;\r\n\r\n /**\r\n * Create a spring post-processor.\r\n *\r\n * @param springSystem - The spring system to integrate\r\n * @param weight - Blend weight [0-1] (default: 1.0)\r\n */\r\n constructor(springSystem: SpringSystem, weight: number = 1.0) {\r\n super(
|
|
1
|
+
{"version":3,"file":"spring_modifier.js","sources":["../../src/animation/spring_modifier.ts"],"sourcesContent":["import { SkeletonModifier } from './skeleton_modifier';\r\nimport type { Skeleton } from './skeleton';\r\nimport type { SpringSystem } from './spring/spring_system';\r\n\r\n/**\r\n * Post-processor wrapper for spring physics systems.\r\n *\r\n * Integrates spring-based physics simulation into the skeleton post-processing pipeline.\r\n * The spring system is updated each frame and results are blended with the base animation.\r\n *\r\n * @deprecated Use the new {@link JointDynamicsModifier} class instead.\r\n *\r\n * @public\r\n */\r\nexport class SpringModifier extends SkeletonModifier {\r\n private _springSystem: SpringSystem;\r\n private _weight: number;\r\n\r\n /**\r\n * Create a spring post-processor.\r\n *\r\n * @param springSystem - The spring system to integrate\r\n * @param weight - Blend weight [0-1] (default: 1.0)\r\n */\r\n constructor(springSystem: SpringSystem, weight: number = 1.0) {\r\n super();\r\n this._weight = weight;\r\n this._springSystem = springSystem;\r\n }\r\n\r\n /**\r\n * Get the spring system.\r\n */\r\n get springSystem(): SpringSystem {\r\n return this._springSystem;\r\n }\r\n\r\n /**\r\n * Apply spring physics to skeleton joints.\r\n */\r\n apply(_skeleton: Skeleton, deltaTime: number): void {\r\n if (!this._enabled || this._weight <= 0) {\r\n return;\r\n }\r\n\r\n // Update spring physics simulation\r\n this._springSystem.update(deltaTime);\r\n\r\n // Apply results to scene nodes with blending\r\n this._springSystem.applyToNodes(this._weight);\r\n }\r\n\r\n /**\r\n * Reset the spring system to initial state.\r\n */\r\n reset(): void {\r\n this._springSystem.reset();\r\n }\r\n\r\n /**\r\n * Get the blend weight for this processor.\r\n * @returns The current blend weight (0-1)\r\n */\r\n protected _getWeight(): number {\r\n return this._weight;\r\n }\r\n\r\n /**\r\n * Set the blend weight for this processor.\r\n * @param value - New blend weight (0-1)\r\n */\r\n protected _setWeight(value: number): void {\r\n this._weight = Math.max(0, Math.min(1, value));\r\n }\r\n}\r\n"],"names":["SpringModifier","SkeletonModifier","_springSystem","_weight","springSystem","weight","apply","_skeleton","deltaTime","_enabled","update","applyToNodes","reset","_setWeight","value","Math","max","min"],"mappings":";;AAIA;;;;;;;;;IAUO,MAAMA,cAAuBC,SAAAA,gBAAAA,CAAAA;IAC1BC,aAA4B;IAC5BC,OAAgB;AAExB;;;;;AAKC,MACD,WAAYC,CAAAA,YAA0B,EAAEC,MAAAA,GAAiB,GAAG,CAAE;QAC5D,KAAK,EAAA;QACL,IAAI,CAACF,OAAO,GAAGE,MAAAA;QACf,IAAI,CAACH,aAAa,GAAGE,YAAAA;AACvB;AAEA;;AAEC,MACD,IAAIA,YAA6B,GAAA;QAC/B,OAAO,IAAI,CAACF,aAAa;AAC3B;AAEA;;AAEC,MACDI,KAAMC,CAAAA,SAAmB,EAAEC,SAAiB,EAAQ;QAClD,IAAI,CAAC,IAAI,CAACC,QAAQ,IAAI,IAAI,CAACN,OAAO,IAAI,CAAG,EAAA;AACvC,YAAA;AACF;;AAGA,QAAA,IAAI,CAACD,aAAa,CAACQ,MAAM,CAACF,SAAAA,CAAAA;;AAG1B,QAAA,IAAI,CAACN,aAAa,CAACS,YAAY,CAAC,IAAI,CAACR,OAAO,CAAA;AAC9C;AAEA;;AAEC,MACDS,KAAc,GAAA;QACZ,IAAI,CAACV,aAAa,CAACU,KAAK,EAAA;AAC1B;AAEA;;;AAGC,MACD,UAA+B,GAAA;QAC7B,OAAO,IAAI,CAACT,OAAO;AACrB;AAEA;;;MAIUU,UAAWC,CAAAA,KAAa,EAAQ;QACxC,IAAI,CAACX,OAAO,GAAGY,IAAKC,CAAAA,GAAG,CAAC,CAAGD,EAAAA,IAAAA,CAAKE,GAAG,CAAC,CAAGH,EAAAA,KAAAA,CAAAA,CAAAA;AACzC;AACF;;;;"}
|
package/dist/app/engine.js
CHANGED
|
@@ -3,6 +3,7 @@ import { ScriptingSystem } from './scriptingsystem.js';
|
|
|
3
3
|
import { ResourceManager } from '../utility/serialization/manager.js';
|
|
4
4
|
import '../render/primitive.js';
|
|
5
5
|
import { BoxShape } from '../shapes/box.js';
|
|
6
|
+
import { CapsuleShape } from '../shapes/capsule.js';
|
|
6
7
|
import { CylinderShape } from '../shapes/cylinder.js';
|
|
7
8
|
import { TorusShape } from '../shapes/torus.js';
|
|
8
9
|
import { PlaneShape } from '../shapes/plane.js';
|
|
@@ -110,6 +111,13 @@ import { ScreenAdapter } from './screen.js';
|
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
/**
|
|
114
|
+
* Loads a runtime script class from file
|
|
115
|
+
* @param module - file path
|
|
116
|
+
* @returns The runtime script class or null
|
|
117
|
+
*/ async loadRuntimeScriptClass(module) {
|
|
118
|
+
return await this._scriptingSystem.loadRuntimeScriptClass(module);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
113
121
|
* Attaches a script module to the given host, if enabled.
|
|
114
122
|
*
|
|
115
123
|
* When disabled, this method resolves to `null` without side effects.
|
|
@@ -118,8 +126,8 @@ import { ScreenAdapter } from './screen.js';
|
|
|
118
126
|
* @param host - Host object to attach the script to.
|
|
119
127
|
* @param module - Module identifier to resolve and load.
|
|
120
128
|
* @returns The `RuntimeScript<T>` instance, or `null` if disabled or on failure.
|
|
121
|
-
*/ async attachScript(host, module) {
|
|
122
|
-
return this._enabled ? await this._scriptingSystem.attachScript(host, module) : null;
|
|
129
|
+
*/ async attachScript(host, module, config) {
|
|
130
|
+
return this._enabled ? await this._scriptingSystem.attachScript(host, module, config) : null;
|
|
123
131
|
}
|
|
124
132
|
/**
|
|
125
133
|
* Detaches a script from a host, by module ID or instance, if enabled.
|
|
@@ -230,6 +238,7 @@ import { ScreenAdapter } from './screen.js';
|
|
|
230
238
|
'/primitives/plane.zmsh': PlaneShape,
|
|
231
239
|
'/primitives/torus.zmsh': TorusShape,
|
|
232
240
|
'/primitives/tetrahedron.zmsh': TetrahedronShape,
|
|
241
|
+
'/primitives/capsule.zmsh': CapsuleShape,
|
|
233
242
|
'/materials/unlit.zmtl': UnlitMaterial,
|
|
234
243
|
'/materials/lambert.zmtl': LambertMaterial,
|
|
235
244
|
'/materials/blinnphong.zmtl': BlinnMaterial,
|
|
@@ -264,28 +273,46 @@ import { ScreenAdapter } from './screen.js';
|
|
|
264
273
|
try {
|
|
265
274
|
const scene = await this._resourceManager.loadScene(path);
|
|
266
275
|
if (scene) {
|
|
267
|
-
|
|
276
|
+
const sceneScripts = scene.scripts.length > 0 ? scene.scripts : scene.script ? [
|
|
277
|
+
{
|
|
278
|
+
script: scene.script,
|
|
279
|
+
config: scene.scriptConfig
|
|
280
|
+
}
|
|
281
|
+
] : [];
|
|
282
|
+
for (const attachment of sceneScripts){
|
|
283
|
+
if (!attachment.script) {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
268
286
|
try {
|
|
269
|
-
await this.attachScript(scene,
|
|
287
|
+
await this.attachScript(scene, attachment.script, attachment.config ?? null);
|
|
270
288
|
} catch (err) {
|
|
271
289
|
console.error(`Attach script failed: ${err}`);
|
|
272
290
|
}
|
|
273
291
|
}
|
|
274
|
-
const
|
|
275
|
-
const scripts = [];
|
|
292
|
+
const nodes = [];
|
|
276
293
|
scene.rootNode.iterate((node)=>{
|
|
277
|
-
|
|
278
|
-
scripts.push(node.script);
|
|
279
|
-
P.push(this.attachScript(node, node.script));
|
|
280
|
-
}
|
|
294
|
+
nodes.push(node);
|
|
281
295
|
});
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
296
|
+
const attachTasks = nodes.map(async (node)=>{
|
|
297
|
+
const attachments = node.scripts.length > 0 ? node.scripts : node.script ? [
|
|
298
|
+
{
|
|
299
|
+
script: node.script,
|
|
300
|
+
config: node.scriptConfig
|
|
301
|
+
}
|
|
302
|
+
] : [];
|
|
303
|
+
for (const attachment of attachments){
|
|
304
|
+
if (!attachment.script) {
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
await this.attachScript(node, attachment.script, attachment.config ?? null);
|
|
309
|
+
} catch (err) {
|
|
310
|
+
console.error(`Attach script failed: ${err}`);
|
|
287
311
|
}
|
|
288
312
|
}
|
|
313
|
+
});
|
|
314
|
+
if (attachTasks.length > 0) {
|
|
315
|
+
await Promise.allSettled(attachTasks);
|
|
289
316
|
}
|
|
290
317
|
}
|
|
291
318
|
return scene;
|