"use strict"; (function (global) { function bounceInsideWorld(obj, worldRef, opts = {}) { if (!obj || !worldRef) return false; const p = Math.max(opts.padding ?? 28, CONFIG.worldPadding || 30); const bx = opts.bounceX ?? opts.bounce ?? 0.72; const by = opts.bounceY ?? opts.bounce ?? 0.72; const spinBounce = opts.spinBounce ?? -0.72; let bounced = false; if (obj.x < p) { obj.x = p; obj.vx = Math.abs(obj.vx || 0) * bx; bounced = true; } if (obj.x > worldRef.w - p) { obj.x = worldRef.w - p; obj.vx = -Math.abs(obj.vx || 0) * bx; bounced = true; } if (obj.y < p) { obj.y = p; obj.vy = Math.abs(obj.vy || 0) * by; bounced = true; } if (obj.y > worldRef.h - p) { obj.y = worldRef.h - p; obj.vy = -Math.abs(obj.vy || 0) * by; bounced = true; } if (bounced && Number.isFinite(obj.spinVelocity)) obj.spinVelocity *= spinBounce; return bounced; } function applyKinematicItemMotion(item, worldRef, dt, opts = {}) { if (!item || !worldRef) return 0; const stopSpeed = opts.stopSpeed ?? 0.05; const speed = Math.hypot(item.vx || 0, item.vy || 0); item.prevX = item.x; item.prevY = item.y; if (speed <= stopSpeed) { item.vx = 0; item.vy = 0; if (Number.isFinite(item.spinVelocity)) { item.spinVelocity *= Math.pow(opts.spinRestDamp ?? 0.08, dt); item.spin = (item.spin || 0) + (item.spinVelocity || 0) * dt; } return speed; } item.x += (item.vx || 0) * dt; item.y += (item.vy || 0) * dt; bounceInsideWorld(item, worldRef, opts); const friction = Math.pow(opts.frictionBase ?? 0.68, dt * (opts.frictionRate ?? 1)); item.vx *= friction; item.vy *= friction; if (opts.spin !== false) { item.spin = (item.spin || 0) + (item.spinVelocity || 0) * dt + (item.vx || 0) * dt / Math.max(7, item.r || 16); item.spinVelocity = (item.spinVelocity || 0) * Math.pow(opts.spinFrictionBase ?? 0.38, dt); } if (Math.hypot(item.vx || 0, item.vy || 0) < (opts.zeroBelow ?? 0)) { item.vx = 0; item.vy = 0; if (Number.isFinite(item.spinVelocity)) item.spinVelocity *= 0.3; } worldRef.drawListDirty = true; return speed; } global.TarinaiPhysics = { bounceInsideWorld, applyKinematicItemMotion }; })(typeof window !== "undefined" ? window : globalThis);