shaderpad 1.0.0-beta.40 → 1.0.0-beta.41

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugins/hands.ts"],"sourcesContent":["import ShaderPad, { PluginContext, TextureSource } from '../index';\nimport type { HandLandmarker, HandLandmarkerResult, NormalizedLandmark } from '@mediapipe/tasks-vision';\n\nexport interface HandsPluginOptions {\n\tmodelPath?: string;\n\tmaxHands?: number;\n\tminHandDetectionConfidence?: number;\n\tminHandPresenceConfidence?: number;\n\tminTrackingConfidence?: number;\n\tonReady?: () => void;\n\tonResults?: (results: HandLandmarkerResult) => void;\n}\n\nconst STANDARD_LANDMARK_COUNT = 21; // See https://ai.google.dev/edge/mediapipe/solutions/vision/hand_landmarker#models.\nconst CUSTOM_LANDMARK_COUNT = 1;\nconst LANDMARK_COUNT = STANDARD_LANDMARK_COUNT + CUSTOM_LANDMARK_COUNT;\nconst HAND_CENTER_LANDMARKS = [0, 0, 5, 9, 13, 17] as const; // Wrist + MCP joints, weighted toward wrist.\n\nfunction hands(config: { textureName: string; options?: HandsPluginOptions }) {\n\tconst { textureName, options } = config;\n\tconst defaultModelPath =\n\t\t'https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task';\n\n\treturn function (shaderPad: ShaderPad, context: PluginContext) {\n\t\tconst { injectGLSL, gl } = context;\n\n\t\tlet handLandmarker: HandLandmarker | null = null;\n\t\tlet vision: any = null;\n\t\tlet lastVideoTime = -1;\n\t\tlet runningMode: 'IMAGE' | 'VIDEO' = 'VIDEO';\n\t\tconst textureSources = new Map<string, TextureSource>();\n\t\tconst maxHands = options?.maxHands ?? 2;\n\n\t\tconst LANDMARKS_TEXTURE_WIDTH = 512;\n\t\tlet landmarksTextureHeight = 0;\n\t\tlet landmarksDataArray: Float32Array | null = null;\n\n\t\tasync function initializeHandLandmarker() {\n\t\t\ttry {\n\t\t\t\tconst { FilesetResolver, HandLandmarker } = await import('@mediapipe/tasks-vision');\n\t\t\t\tvision = await FilesetResolver.forVisionTasks(\n\t\t\t\t\t'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm'\n\t\t\t\t);\n\n\t\t\t\thandLandmarker = await HandLandmarker.createFromOptions(vision, {\n\t\t\t\t\tbaseOptions: {\n\t\t\t\t\t\tmodelAssetPath: options?.modelPath || defaultModelPath,\n\t\t\t\t\t\tdelegate: 'GPU',\n\t\t\t\t\t},\n\t\t\t\t\tcanvas: new OffscreenCanvas(1, 1),\n\t\t\t\t\trunningMode: runningMode,\n\t\t\t\t\tnumHands: options?.maxHands ?? 2,\n\t\t\t\t\tminHandDetectionConfidence: options?.minHandDetectionConfidence ?? 0.5,\n\t\t\t\t\tminHandPresenceConfidence: options?.minHandPresenceConfidence ?? 0.5,\n\t\t\t\t\tminTrackingConfidence: options?.minTrackingConfidence ?? 0.5,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Hands Plugin] Failed to initialize:', error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tfunction calculateBoundingBoxCenter(\n\t\t\tlandmarksDataArray: Float32Array,\n\t\t\thandIdx: number,\n\t\t\tlandmarkIndices: readonly number[]\n\t\t): [number, number, number, number] {\n\t\t\tlet minX = Infinity,\n\t\t\t\tmaxX = -Infinity,\n\t\t\t\tminY = Infinity,\n\t\t\t\tmaxY = -Infinity,\n\t\t\t\tavgZ = 0,\n\t\t\t\tavgVisibility = 0;\n\n\t\t\tfor (const idx of landmarkIndices) {\n\t\t\t\tconst dataIdx = (handIdx * LANDMARK_COUNT + idx) * 4;\n\t\t\t\tconst x = landmarksDataArray[dataIdx];\n\t\t\t\tconst y = landmarksDataArray[dataIdx + 1];\n\t\t\t\tminX = Math.min(minX, x);\n\t\t\t\tmaxX = Math.max(maxX, x);\n\t\t\t\tminY = Math.min(minY, y);\n\t\t\t\tmaxY = Math.max(maxY, y);\n\t\t\t\tavgZ += landmarksDataArray[dataIdx + 2];\n\t\t\t\tavgVisibility += landmarksDataArray[dataIdx + 3];\n\t\t\t}\n\n\t\t\tconst centerX = (minX + maxX) / 2;\n\t\t\tconst centerY = (minY + maxY) / 2;\n\t\t\tconst centerZ = avgZ / landmarkIndices.length;\n\t\t\tconst centerVisibility = avgVisibility / landmarkIndices.length;\n\t\t\treturn [centerX, centerY, centerZ, centerVisibility];\n\t\t}\n\n\t\tfunction updateLandmarksTexture(hands: NormalizedLandmark[][], handedness: { categoryName: string }[][]) {\n\t\t\tif (!landmarksDataArray) return;\n\n\t\t\tconst nHands = hands.length;\n\t\t\tconst totalLandmarks = nHands * LANDMARK_COUNT;\n\n\t\t\tfor (let handIdx = 0; handIdx < nHands; ++handIdx) {\n\t\t\t\tconst landmarks = hands[handIdx];\n\t\t\t\tconst isRightHand = handedness[handIdx]?.[0]?.categoryName === 'Right';\n\t\t\t\tfor (let lmIdx = 0; lmIdx < STANDARD_LANDMARK_COUNT; ++lmIdx) {\n\t\t\t\t\tconst landmark = landmarks[lmIdx];\n\t\t\t\t\tconst dataIdx = (handIdx * LANDMARK_COUNT + lmIdx) * 4;\n\t\t\t\t\tlandmarksDataArray[dataIdx] = landmark.x;\n\t\t\t\t\tlandmarksDataArray[dataIdx + 1] = 1 - landmark.y;\n\t\t\t\t\tlandmarksDataArray[dataIdx + 2] = landmark.z ?? 0;\n\t\t\t\t\tlandmarksDataArray[dataIdx + 3] = isRightHand ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\tconst handCenter = calculateBoundingBoxCenter(landmarksDataArray, handIdx, HAND_CENTER_LANDMARKS);\n\t\t\t\tconst handCenterIdx = (handIdx * LANDMARK_COUNT + STANDARD_LANDMARK_COUNT) * 4;\n\t\t\t\tlandmarksDataArray[handCenterIdx] = handCenter[0];\n\t\t\t\tlandmarksDataArray[handCenterIdx + 1] = handCenter[1];\n\t\t\t\tlandmarksDataArray[handCenterIdx + 2] = handCenter[2];\n\t\t\t\tlandmarksDataArray[handCenterIdx + 3] = isRightHand ? 1 : 0;\n\t\t\t}\n\n\t\t\tconst rowsToUpdate = Math.ceil(totalLandmarks / LANDMARKS_TEXTURE_WIDTH);\n\t\t\tshaderPad.updateTextures({\n\t\t\t\tu_handLandmarksTex: {\n\t\t\t\t\tdata: landmarksDataArray,\n\t\t\t\t\twidth: LANDMARKS_TEXTURE_WIDTH,\n\t\t\t\t\theight: rowsToUpdate,\n\t\t\t\t\tisPartial: true,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tfunction processHandResults(result: HandLandmarkerResult) {\n\t\t\tif (!result.landmarks || !landmarksDataArray) return;\n\n\t\t\tconst nHands = result.landmarks.length;\n\t\t\tupdateLandmarksTexture(result.landmarks, result.handedness);\n\t\t\tshaderPad.updateUniforms({ u_nHands: nHands });\n\n\t\t\toptions?.onResults?.(result);\n\t\t}\n\n\t\tshaderPad.registerHook('init', async () => {\n\t\t\tshaderPad.initializeUniform('u_maxHands', 'int', maxHands);\n\t\t\tshaderPad.initializeUniform('u_nHands', 'int', 0);\n\n\t\t\tconst totalLandmarks = maxHands * LANDMARK_COUNT;\n\t\t\tlandmarksTextureHeight = Math.ceil(totalLandmarks / LANDMARKS_TEXTURE_WIDTH);\n\t\t\tconst textureSize = LANDMARKS_TEXTURE_WIDTH * landmarksTextureHeight * 4;\n\t\t\tlandmarksDataArray = new Float32Array(textureSize);\n\n\t\t\tshaderPad.initializeTexture(\n\t\t\t\t'u_handLandmarksTex',\n\t\t\t\t{\n\t\t\t\t\tdata: landmarksDataArray,\n\t\t\t\t\twidth: LANDMARKS_TEXTURE_WIDTH,\n\t\t\t\t\theight: landmarksTextureHeight,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinternalFormat: gl.RGBA32F,\n\t\t\t\t\ttype: gl.FLOAT,\n\t\t\t\t\tminFilter: gl.NEAREST,\n\t\t\t\t\tmagFilter: gl.NEAREST,\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tawait initializeHandLandmarker();\n\t\t\toptions?.onReady?.();\n\t\t});\n\n\t\tshaderPad.registerHook('updateTextures', async (updates: Record<string, TextureSource>) => {\n\t\t\tconst source = updates[textureName];\n\t\t\tif (!source) return;\n\n\t\t\tconst previousSource = textureSources.get(textureName);\n\t\t\tif (previousSource !== source) {\n\t\t\t\tlastVideoTime = -1;\n\t\t\t}\n\n\t\t\ttextureSources.set(textureName, source);\n\t\t\tif (!handLandmarker) return;\n\n\t\t\ttry {\n\t\t\t\tconst requiredMode = source instanceof HTMLVideoElement ? 'VIDEO' : 'IMAGE';\n\t\t\t\tif (runningMode !== requiredMode) {\n\t\t\t\t\trunningMode = requiredMode;\n\t\t\t\t\tawait handLandmarker.setOptions({ runningMode: runningMode });\n\t\t\t\t}\n\n\t\t\t\tif (source instanceof HTMLVideoElement) {\n\t\t\t\t\tif (source.videoWidth === 0 || source.videoHeight === 0 || source.readyState < 2) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (source.currentTime !== lastVideoTime) {\n\t\t\t\t\t\tlastVideoTime = source.currentTime;\n\t\t\t\t\t\tconst result = handLandmarker.detectForVideo(source, performance.now());\n\t\t\t\t\t\tprocessHandResults(result);\n\t\t\t\t\t}\n\t\t\t\t} else if (source instanceof HTMLImageElement || source instanceof HTMLCanvasElement) {\n\t\t\t\t\tif (source.width === 0 || source.height === 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst result = handLandmarker.detect(source);\n\t\t\t\t\tprocessHandResults(result);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Hands Plugin] Detection error:', error);\n\t\t\t}\n\t\t});\n\n\t\tshaderPad.registerHook('destroy', () => {\n\t\t\tif (handLandmarker) {\n\t\t\t\thandLandmarker.close();\n\t\t\t\thandLandmarker = null;\n\t\t\t}\n\t\t\tvision = null;\n\t\t\ttextureSources.clear();\n\t\t\tlandmarksDataArray = null;\n\t\t});\n\n\t\tinjectGLSL(`\nuniform int u_maxHands;\nuniform int u_nHands;\nuniform sampler2D u_handLandmarksTex;\n\nvec4 handLandmark(int handIndex, int landmarkIndex) {\n\tint i = handIndex * ${LANDMARK_COUNT} + landmarkIndex;\n\tint x = i % ${LANDMARKS_TEXTURE_WIDTH};\n\tint y = i / ${LANDMARKS_TEXTURE_WIDTH};\n\treturn texelFetch(u_handLandmarksTex, ivec2(x, y), 0);\n}\n\nfloat isRightHand(int handIndex) {\n\treturn handLandmark(handIndex, 0).w;\n}\n\nfloat isLeftHand(int handIndex) {\n\treturn 1.0 - handLandmark(handIndex, 0).w;\n}`);\n\t};\n}\n\nexport default hands;\n"],"mappings":"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","names":["STANDARD_LANDMARK_COUNT","CUSTOM_LANDMARK_COUNT","LANDMARK_COUNT","HAND_CENTER_LANDMARKS","hands","config","textureName","options","defaultModelPath","shaderPad","context","injectGLSL","gl","handLandmarker","vision","lastVideoTime","runningMode","textureSources","maxHands","LANDMARKS_TEXTURE_WIDTH","landmarksTextureHeight","landmarksDataArray","initializeHandLandmarker","FilesetResolver","HandLandmarker","error","calculateBoundingBoxCenter","handIdx","landmarkIndices","minX","maxX","minY","maxY","avgZ","avgVisibility","idx","dataIdx","x","y","centerX","centerY","centerZ","centerVisibility","updateLandmarksTexture","handedness","nHands","totalLandmarks","landmarks","isRightHand","lmIdx","landmark","handCenter","handCenterIdx","rowsToUpdate","processHandResults","result","textureSize","updates","source","requiredMode","hands_default"]}
1
+ {"version":3,"sources":["../../src/plugins/hands.ts"],"sourcesContent":["import ShaderPad, { PluginContext, TextureSource } from '../index';\nimport type { HandLandmarker, HandLandmarkerResult, NormalizedLandmark } from '@mediapipe/tasks-vision';\n\nexport interface HandsPluginOptions {\n\tmodelPath?: string;\n\tmaxHands?: number;\n\tminHandDetectionConfidence?: number;\n\tminHandPresenceConfidence?: number;\n\tminTrackingConfidence?: number;\n}\n\nconst STANDARD_LANDMARK_COUNT = 21; // See https://ai.google.dev/edge/mediapipe/solutions/vision/hand_landmarker#models.\nconst CUSTOM_LANDMARK_COUNT = 1;\nconst LANDMARK_COUNT = STANDARD_LANDMARK_COUNT + CUSTOM_LANDMARK_COUNT;\nconst HAND_CENTER_LANDMARKS = [0, 0, 5, 9, 13, 17] as const; // Wrist + MCP joints, weighted toward wrist.\n\nfunction hands(config: { textureName: string; options?: HandsPluginOptions }) {\n\tconst { textureName, options } = config;\n\tconst defaultModelPath =\n\t\t'https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task';\n\n\treturn function (shaderPad: ShaderPad, context: PluginContext) {\n\t\tconst { injectGLSL, gl, emitHook } = context;\n\n\t\tlet handLandmarker: HandLandmarker | null = null;\n\t\tlet vision: any = null;\n\t\tlet lastVideoTime = -1;\n\t\tlet runningMode: 'IMAGE' | 'VIDEO' = 'VIDEO';\n\t\tconst textureSources = new Map<string, TextureSource>();\n\t\tconst maxHands = options?.maxHands ?? 2;\n\n\t\tconst LANDMARKS_TEXTURE_WIDTH = 512;\n\t\tlet landmarksTextureHeight = 0;\n\t\tlet landmarksDataArray: Float32Array | null = null;\n\n\t\tasync function initializeMediaPipe() {\n\t\t\ttry {\n\t\t\t\tconst { FilesetResolver, HandLandmarker } = await import('@mediapipe/tasks-vision');\n\t\t\t\tvision = await FilesetResolver.forVisionTasks(\n\t\t\t\t\t'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm'\n\t\t\t\t);\n\t\t\t\thandLandmarker = await HandLandmarker.createFromOptions(vision, {\n\t\t\t\t\tbaseOptions: {\n\t\t\t\t\t\tmodelAssetPath: options?.modelPath || defaultModelPath,\n\t\t\t\t\t\tdelegate: 'GPU',\n\t\t\t\t\t},\n\t\t\t\t\tcanvas: new OffscreenCanvas(1, 1),\n\t\t\t\t\trunningMode,\n\t\t\t\t\tnumHands: options?.maxHands ?? 2,\n\t\t\t\t\tminHandDetectionConfidence: options?.minHandDetectionConfidence ?? 0.5,\n\t\t\t\t\tminHandPresenceConfidence: options?.minHandPresenceConfidence ?? 0.5,\n\t\t\t\t\tminTrackingConfidence: options?.minTrackingConfidence ?? 0.5,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Hands Plugin] Failed to initialize MediaPipe:', error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tconst mediaPipeInitPromise = initializeMediaPipe();\n\n\t\tfunction calculateBoundingBoxCenter(\n\t\t\tlandmarksDataArray: Float32Array,\n\t\t\thandIdx: number,\n\t\t\tlandmarkIndices: readonly number[]\n\t\t): [number, number, number, number] {\n\t\t\tlet minX = Infinity,\n\t\t\t\tmaxX = -Infinity,\n\t\t\t\tminY = Infinity,\n\t\t\t\tmaxY = -Infinity,\n\t\t\t\tavgZ = 0,\n\t\t\t\tavgVisibility = 0;\n\n\t\t\tfor (const idx of landmarkIndices) {\n\t\t\t\tconst dataIdx = (handIdx * LANDMARK_COUNT + idx) * 4;\n\t\t\t\tconst x = landmarksDataArray[dataIdx];\n\t\t\t\tconst y = landmarksDataArray[dataIdx + 1];\n\t\t\t\tminX = Math.min(minX, x);\n\t\t\t\tmaxX = Math.max(maxX, x);\n\t\t\t\tminY = Math.min(minY, y);\n\t\t\t\tmaxY = Math.max(maxY, y);\n\t\t\t\tavgZ += landmarksDataArray[dataIdx + 2];\n\t\t\t\tavgVisibility += landmarksDataArray[dataIdx + 3];\n\t\t\t}\n\n\t\t\tconst centerX = (minX + maxX) / 2;\n\t\t\tconst centerY = (minY + maxY) / 2;\n\t\t\tconst centerZ = avgZ / landmarkIndices.length;\n\t\t\tconst centerVisibility = avgVisibility / landmarkIndices.length;\n\t\t\treturn [centerX, centerY, centerZ, centerVisibility];\n\t\t}\n\n\t\tfunction updateLandmarksTexture(hands: NormalizedLandmark[][], handedness: { categoryName: string }[][]) {\n\t\t\tif (!landmarksDataArray) return;\n\n\t\t\tconst nHands = hands.length;\n\t\t\tconst totalLandmarks = nHands * LANDMARK_COUNT;\n\n\t\t\tfor (let handIdx = 0; handIdx < nHands; ++handIdx) {\n\t\t\t\tconst landmarks = hands[handIdx];\n\t\t\t\tconst isRightHand = handedness[handIdx]?.[0]?.categoryName === 'Right';\n\t\t\t\tfor (let lmIdx = 0; lmIdx < STANDARD_LANDMARK_COUNT; ++lmIdx) {\n\t\t\t\t\tconst landmark = landmarks[lmIdx];\n\t\t\t\t\tconst dataIdx = (handIdx * LANDMARK_COUNT + lmIdx) * 4;\n\t\t\t\t\tlandmarksDataArray[dataIdx] = landmark.x;\n\t\t\t\t\tlandmarksDataArray[dataIdx + 1] = 1 - landmark.y;\n\t\t\t\t\tlandmarksDataArray[dataIdx + 2] = landmark.z ?? 0;\n\t\t\t\t\tlandmarksDataArray[dataIdx + 3] = isRightHand ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\tconst handCenter = calculateBoundingBoxCenter(landmarksDataArray, handIdx, HAND_CENTER_LANDMARKS);\n\t\t\t\tconst handCenterIdx = (handIdx * LANDMARK_COUNT + STANDARD_LANDMARK_COUNT) * 4;\n\t\t\t\tlandmarksDataArray[handCenterIdx] = handCenter[0];\n\t\t\t\tlandmarksDataArray[handCenterIdx + 1] = handCenter[1];\n\t\t\t\tlandmarksDataArray[handCenterIdx + 2] = handCenter[2];\n\t\t\t\tlandmarksDataArray[handCenterIdx + 3] = isRightHand ? 1 : 0;\n\t\t\t}\n\n\t\t\tconst rowsToUpdate = Math.ceil(totalLandmarks / LANDMARKS_TEXTURE_WIDTH);\n\t\t\tshaderPad.updateTextures({\n\t\t\t\tu_handLandmarksTex: {\n\t\t\t\t\tdata: landmarksDataArray,\n\t\t\t\t\twidth: LANDMARKS_TEXTURE_WIDTH,\n\t\t\t\t\theight: rowsToUpdate,\n\t\t\t\t\tisPartial: true,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tfunction processHands(result: HandLandmarkerResult) {\n\t\t\tif (!result.landmarks || !landmarksDataArray) return;\n\n\t\t\tconst nHands = result.landmarks.length;\n\t\t\tupdateLandmarksTexture(result.landmarks, result.handedness);\n\t\t\tshaderPad.updateUniforms({ u_nHands: nHands });\n\t\t\temitHook('hands:result', result);\n\t\t}\n\n\t\tshaderPad.on('init', async () => {\n\t\t\tshaderPad.initializeUniform('u_maxHands', 'int', maxHands);\n\t\t\tshaderPad.initializeUniform('u_nHands', 'int', 0);\n\n\t\t\tconst totalLandmarks = maxHands * LANDMARK_COUNT;\n\t\t\tlandmarksTextureHeight = Math.ceil(totalLandmarks / LANDMARKS_TEXTURE_WIDTH);\n\t\t\tconst textureSize = LANDMARKS_TEXTURE_WIDTH * landmarksTextureHeight * 4;\n\t\t\tlandmarksDataArray = new Float32Array(textureSize);\n\n\t\t\tshaderPad.initializeTexture(\n\t\t\t\t'u_handLandmarksTex',\n\t\t\t\t{\n\t\t\t\t\tdata: landmarksDataArray,\n\t\t\t\t\twidth: LANDMARKS_TEXTURE_WIDTH,\n\t\t\t\t\theight: landmarksTextureHeight,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinternalFormat: gl.RGBA32F,\n\t\t\t\t\ttype: gl.FLOAT,\n\t\t\t\t\tminFilter: gl.NEAREST,\n\t\t\t\t\tmagFilter: gl.NEAREST,\n\t\t\t\t}\n\t\t\t);\n\t\t\tawait mediaPipeInitPromise;\n\t\t\temitHook('hands:ready');\n\t\t});\n\n\t\tshaderPad.on('initializeTexture', (name: string, source: TextureSource) => {\n\t\t\tif (name === textureName) detectHands(source);\n\t\t});\n\n\t\tshaderPad.on('updateTextures', (updates: Record<string, TextureSource>) => {\n\t\t\tconst source = updates[textureName];\n\t\t\tif (source) detectHands(source);\n\t\t});\n\n\t\t// `detectHands` may be called multiple times before MediaPipe is\n\t\t// initialized. This ensures we only process the last call.\n\t\tlet nDetectionCalls = 0;\n\t\tasync function detectHands(source: TextureSource) {\n\t\t\tconst callOrder = ++nDetectionCalls;\n\t\t\tawait mediaPipeInitPromise;\n\t\t\tif (callOrder !== nDetectionCalls || !handLandmarker) return;\n\n\t\t\tconst previousSource = textureSources.get(textureName);\n\t\t\tif (previousSource !== source) lastVideoTime = -1;\n\t\t\ttextureSources.set(textureName, source);\n\n\t\t\ttry {\n\t\t\t\tconst requiredMode = source instanceof HTMLVideoElement ? 'VIDEO' : 'IMAGE';\n\t\t\t\tif (runningMode !== requiredMode) {\n\t\t\t\t\trunningMode = requiredMode;\n\t\t\t\t\tawait handLandmarker.setOptions({ runningMode });\n\t\t\t\t}\n\n\t\t\t\tif (source instanceof HTMLVideoElement) {\n\t\t\t\t\tif (source.videoWidth === 0 || source.videoHeight === 0 || source.readyState < 2) return;\n\t\t\t\t\tif (source.currentTime !== lastVideoTime) {\n\t\t\t\t\t\tlastVideoTime = source.currentTime;\n\t\t\t\t\t\tprocessHands(handLandmarker.detectForVideo(source, performance.now()));\n\t\t\t\t\t}\n\t\t\t\t} else if (source instanceof HTMLImageElement || source instanceof HTMLCanvasElement) {\n\t\t\t\t\tif (source.width === 0 || source.height === 0) return;\n\t\t\t\t\tprocessHands(handLandmarker.detect(source));\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Hands Plugin] Detection error:', error);\n\t\t\t}\n\t\t}\n\n\t\tshaderPad.on('destroy', () => {\n\t\t\tif (handLandmarker) {\n\t\t\t\thandLandmarker.close();\n\t\t\t\thandLandmarker = null;\n\t\t\t}\n\t\t\tvision = null;\n\t\t\ttextureSources.clear();\n\t\t\tlandmarksDataArray = null;\n\t\t});\n\n\t\tinjectGLSL(`\nuniform int u_maxHands;\nuniform int u_nHands;\nuniform sampler2D u_handLandmarksTex;\n\nvec4 handLandmark(int handIndex, int landmarkIndex) {\n\tint i = handIndex * ${LANDMARK_COUNT} + landmarkIndex;\n\tint x = i % ${LANDMARKS_TEXTURE_WIDTH};\n\tint y = i / ${LANDMARKS_TEXTURE_WIDTH};\n\treturn texelFetch(u_handLandmarksTex, ivec2(x, y), 0);\n}\n\nfloat isRightHand(int handIndex) {\n\treturn handLandmark(handIndex, 0).w;\n}\n\nfloat isLeftHand(int handIndex) {\n\treturn 1.0 - handLandmark(handIndex, 0).w;\n}`);\n\t};\n}\n\nexport default hands;\n"],"mappings":"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","names":["STANDARD_LANDMARK_COUNT","CUSTOM_LANDMARK_COUNT","LANDMARK_COUNT","HAND_CENTER_LANDMARKS","hands","config","textureName","options","defaultModelPath","shaderPad","context","injectGLSL","gl","emitHook","handLandmarker","vision","lastVideoTime","runningMode","textureSources","maxHands","LANDMARKS_TEXTURE_WIDTH","landmarksTextureHeight","landmarksDataArray","initializeMediaPipe","FilesetResolver","HandLandmarker","error","mediaPipeInitPromise","calculateBoundingBoxCenter","handIdx","landmarkIndices","minX","maxX","minY","maxY","avgZ","avgVisibility","idx","dataIdx","x","y","centerX","centerY","centerZ","centerVisibility","updateLandmarksTexture","handedness","nHands","totalLandmarks","landmarks","isRightHand","lmIdx","landmark","handCenter","handCenterIdx","rowsToUpdate","processHands","result","textureSize","name","source","detectHands","updates","nDetectionCalls","callOrder","requiredMode","hands_default"]}
@@ -1,5 +1,4 @@
1
1
  import ShaderPad, { PluginContext } from '../index.mjs';
2
- import { PoseLandmarkerResult } from '@mediapipe/tasks-vision';
3
2
 
4
3
  interface PosePluginOptions {
5
4
  modelPath?: string;
@@ -7,8 +6,6 @@ interface PosePluginOptions {
7
6
  minPoseDetectionConfidence?: number;
8
7
  minPosePresenceConfidence?: number;
9
8
  minTrackingConfidence?: number;
10
- onReady?: () => void;
11
- onResults?: (results: PoseLandmarkerResult) => void;
12
9
  }
13
10
  declare function pose(config: {
14
11
  textureName: string;
@@ -1,5 +1,4 @@
1
1
  import ShaderPad, { PluginContext } from '../index.js';
2
- import { PoseLandmarkerResult } from '@mediapipe/tasks-vision';
3
2
 
4
3
  interface PosePluginOptions {
5
4
  modelPath?: string;
@@ -7,8 +6,6 @@ interface PosePluginOptions {
7
6
  minPoseDetectionConfidence?: number;
8
7
  minPosePresenceConfidence?: number;
9
8
  minTrackingConfidence?: number;
10
- onReady?: () => void;
11
- onResults?: (results: PoseLandmarkerResult) => void;
12
9
  }
13
10
  declare function pose(config: {
14
11
  textureName: string;
@@ -1,50 +1,49 @@
1
- "use strict";var re=Object.create;var W=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.getPrototypeOf,ae=Object.prototype.hasOwnProperty;var he=(l,t)=>{for(var e in t)W(l,e,{get:t[e],enumerable:!0})},q=(l,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of ne(t))!ae.call(l,i)&&i!==e&&W(l,i,{get:()=>t[i],enumerable:!(s=se(t,i))||s.enumerable});return l};var le=(l,t,e)=>(e=l!=null?re(oe(l)):{},q(t||!l||!l.__esModule?W(e,"default",{value:l,enumerable:!0}):e,l)),ue=l=>q(W({},"__esModule",{value:!0}),l);var Le={};he(Le,{default:()=>ve});module.exports=ue(Le);var ce=`#version 300 es
1
+ "use strict";var oe=Object.create;var K=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var ce=(l,t)=>{for(var e in t)K(l,e,{get:t[e],enumerable:!0})},ee=(l,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of he(t))!le.call(l,i)&&i!==e&&K(l,i,{get:()=>t[i],enumerable:!(r=ae(t,i))||r.enumerable});return l};var me=(l,t,e)=>(e=l!=null?oe(ue(l)):{},ee(t||!l||!l.__esModule?K(e,"default",{value:l,enumerable:!0}):e,l)),de=l=>ee(K({},"__esModule",{value:!0}),l);var Ae={};ce(Ae,{default:()=>Ie});module.exports=de(Ae);var fe=`#version 300 es
2
2
  in vec2 aPosition;
3
3
  out vec2 v_uv;
4
4
  void main() {
5
5
  v_uv = aPosition * 0.5 + 0.5;
6
6
  gl_Position = vec4(aPosition, 0.0, 1.0);
7
- }
8
- `,me=33.333333333333336,M=Symbol("u_history"),Y=Symbol("__SHADERPAD_BUFFER");function fe(l,t){if(!t?.length)return l;let e=l.split(`
9
- `),s=e.findLastIndex(i=>{let r=i.trimStart();return r.startsWith("precision ")||r.startsWith("#version ")})+1;return e.splice(s,0,...t),e.join(`
10
- `)}function Z(l){return l instanceof WebGLTexture?{width:0,height:0}:l instanceof HTMLVideoElement?{width:l.videoWidth,height:l.videoHeight}:l instanceof HTMLImageElement?{width:l.naturalWidth??l.width,height:l.naturalHeight??l.height}:{width:l.width,height:l.height}}function D(l){return typeof l=="symbol"?l.description??"":l}var V=class{isInternalCanvas=!1;isTouchDevice=!1;gl;fragmentShaderSrc;uniforms=new Map;textures=new Map;textureUnitPool;buffer=null;program=null;aPositionLocation=0;animationFrameId;resolutionObserver;resizeObserver;resizeTimeout=null;lastResizeTime=-1/0;eventListeners=new Map;frame=0;startTime=0;cursorPosition=[.5,.5];clickPosition=[.5,.5];isMouseDown=!1;canvas;onResize;hooks=new Map;historyDepth=0;textureOptions;debug;intermediateFbo=null;constructor(t,{canvas:e,plugins:s,history:i,debug:r,...h}={}){if(this.canvas=e||document.createElement("canvas"),!e){this.isInternalCanvas=!0;let g=this.canvas;g.style.position="fixed",g.style.inset="0",g.style.height="100dvh",g.style.width="100dvw",document.body.appendChild(g)}if(this.gl=this.canvas.getContext("webgl2",{antialias:!1}),!this.gl)throw new Error("WebGL2 not supported. Please use a browser that supports WebGL2.");this.textureUnitPool={free:[],next:0,max:this.gl.getParameter(this.gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS)},this.textureOptions=h;let{internalFormat:n,type:f}=h;(f===this.gl.FLOAT||f===this.gl.HALF_FLOAT||n===this.gl.RGBA16F||n===this.gl.RGBA32F||n===this.gl.R16F||n===this.gl.R32F||n===this.gl.RG16F||n===this.gl.RG32F)&&!this.gl.getExtension("EXT_color_buffer_float")&&(console.warn("EXT_color_buffer_float not supported, falling back to RGBA8"),delete this.textureOptions?.internalFormat,delete this.textureOptions?.format,delete this.textureOptions?.type),i&&(this.historyDepth=i),this.debug=r??(typeof process<"u"&&!1),this.animationFrameId=null,this.resolutionObserver=new MutationObserver(()=>this.updateResolution()),this.resizeObserver=new ResizeObserver(()=>this.throttledHandleResize());let c=[];if(s){let g={gl:this.gl,uniforms:this.uniforms,textures:this.textures,canvas:this.canvas,reserveTextureUnit:this.reserveTextureUnit.bind(this),releaseTextureUnit:this.releaseTextureUnit.bind(this),injectGLSL:_=>{c.push(_)}};Object.defineProperty(g,"program",{get:()=>this.program,enumerable:!0,configurable:!0}),s.forEach(_=>_(this,g))}this.fragmentShaderSrc=fe(t,c),this.init(),this.canvas instanceof HTMLCanvasElement&&this.addEventListeners()}registerHook(t,e){this.hooks.has(t)||this.hooks.set(t,[]),this.hooks.get(t).push(e)}init(){let t=ce;if(this.program=this.gl.createProgram(),!this.program)throw new Error("Failed to create WebGL program");let e=this.createShader(this.gl.VERTEX_SHADER,t),s=this.createShader(this.gl.FRAGMENT_SHADER,this.fragmentShaderSrc);if(this.gl.attachShader(this.program,e),this.gl.attachShader(this.program,s),this.gl.linkProgram(this.program),this.gl.deleteShader(e),this.gl.deleteShader(s),!this.gl.getProgramParameter(this.program,this.gl.LINK_STATUS))throw console.error("Program link error:",this.gl.getProgramInfoLog(this.program)),this.gl.deleteProgram(this.program),new Error("Failed to link WebGL program");this.aPositionLocation=this.gl.getAttribLocation(this.program,"aPosition"),this.setupBuffer(),this.gl.useProgram(this.program),this.canvas instanceof HTMLCanvasElement&&(this.resolutionObserver.observe(this.canvas,{attributes:!0,attributeFilter:["width","height"]}),this.resizeObserver.observe(this.canvas)),this.isInternalCanvas||this.updateResolution(),this.initializeUniform("u_cursor","float",this.cursorPosition),this.initializeUniform("u_click","float",[...this.clickPosition,this.isMouseDown?1:0]),this.initializeUniform("u_time","float",0),this.initializeUniform("u_frame","int",0),this.historyDepth>0&&(this._initializeTexture(Y,this.canvas,{...this.textureOptions}),this._initializeTexture(M,this.canvas,{history:this.historyDepth,...this.textureOptions}),this.intermediateFbo=this.gl.createFramebuffer()),this.hooks.get("init")?.forEach(i=>i.call(this))}createShader(t,e){let s=this.gl.createShader(t);if(this.gl.shaderSource(s,e),this.gl.compileShader(s),!this.gl.getShaderParameter(s,this.gl.COMPILE_STATUS))throw console.error("Shader compilation failed:",e),console.error(this.gl.getShaderInfoLog(s)),this.gl.deleteShader(s),new Error("Shader compilation failed");return s}setupBuffer(){let t=new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]);this.buffer=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.buffer),this.gl.bufferData(this.gl.ARRAY_BUFFER,t,this.gl.STATIC_DRAW),this.gl.viewport(0,0,this.gl.drawingBufferWidth,this.gl.drawingBufferHeight),this.gl.enableVertexAttribArray(this.aPositionLocation),this.gl.vertexAttribPointer(this.aPositionLocation,2,this.gl.FLOAT,!1,0,0)}throttledHandleResize(){clearTimeout(this.resizeTimeout);let t=performance.now(),e=this.lastResizeTime+me-t;e<=0?(this.lastResizeTime=t,this.handleResize()):this.resizeTimeout=setTimeout(()=>this.throttledHandleResize(),e)}handleResize(){if(!(this.canvas instanceof HTMLCanvasElement))return;let t=window.devicePixelRatio||1,e=this.canvas.clientWidth*t,s=this.canvas.clientHeight*t;this.isInternalCanvas&&(this.canvas.width!==e||this.canvas.height!==s)&&(this.canvas.width=e,this.canvas.height=s),this.onResize?.(e,s)}addEventListeners(){let t=this.canvas,e=(i,r)=>{if(!this.uniforms.has("u_cursor"))return;let h=t.getBoundingClientRect();this.cursorPosition[0]=(i-h.left)/h.width,this.cursorPosition[1]=1-(r-h.top)/h.height,this.updateUniforms({u_cursor:this.cursorPosition})},s=(i,r,h)=>{if(this.uniforms.has("u_click")){if(this.isMouseDown=i,i){let n=t.getBoundingClientRect(),f=r,d=h;this.clickPosition[0]=(f-n.left)/n.width,this.clickPosition[1]=1-(d-n.top)/n.height}this.updateUniforms({u_click:[...this.clickPosition,this.isMouseDown?1:0]})}};this.eventListeners.set("mousemove",i=>{let r=i;this.isTouchDevice||e(r.clientX,r.clientY)}),this.eventListeners.set("mousedown",i=>{let r=i;this.isTouchDevice||r.button===0&&(this.isMouseDown=!0,s(!0,r.clientX,r.clientY))}),this.eventListeners.set("mouseup",i=>{let r=i;this.isTouchDevice||r.button===0&&s(!1)}),this.eventListeners.set("touchmove",i=>{let r=i;r.touches.length>0&&e(r.touches[0].clientX,r.touches[0].clientY)}),this.eventListeners.set("touchstart",i=>{let r=i;this.isTouchDevice=!0,r.touches.length>0&&(e(r.touches[0].clientX,r.touches[0].clientY),s(!0,r.touches[0].clientX,r.touches[0].clientY))}),this.eventListeners.set("touchend",i=>{i.touches.length===0&&s(!1)}),this.eventListeners.forEach((i,r)=>{t.addEventListener(r,i)})}updateResolution(){let t=[this.gl.drawingBufferWidth,this.gl.drawingBufferHeight];this.gl.viewport(0,0,...t),this.uniforms.has("u_resolution")?this.updateUniforms({u_resolution:t}):this.initializeUniform("u_resolution","float",t),this.historyDepth>0&&(this.resizeTexture(M,...t),this.resizeTexture(Y,...t)),this.hooks.get("updateResolution")?.forEach(e=>e.call(this))}resizeTexture(t,e,s){let i=this.textures.get(t);if(!i||i.width===e&&i.height===s)return;this.gl.deleteTexture(i.texture),i.width=e,i.height=s;let{texture:r}=this.createTexture(t,i);i.texture=r,i.history&&(i.history.writeIndex=0,this.clearHistoryTextureLayers(i))}reserveTextureUnit(t){let e=this.textures.get(t);if(e)return e.unitIndex;if(this.textureUnitPool.free.length>0)return this.textureUnitPool.free.pop();if(this.textureUnitPool.next>=this.textureUnitPool.max)throw new Error("Exceeded the available texture units for this device.");return this.textureUnitPool.next++}releaseTextureUnit(t){let e=this.textures.get(t);e&&this.textureUnitPool.free.push(e.unitIndex)}resolveTextureOptions(t){let{gl:e}=this,s=t?.type??e.UNSIGNED_BYTE;return{type:s,format:t?.format??e.RGBA,internalFormat:t?.internalFormat??(s===e.FLOAT?e.RGBA32F:s===e.HALF_FLOAT?e.RGBA16F:e.RGBA8),minFilter:t?.minFilter??e.LINEAR,magFilter:t?.magFilter??e.LINEAR,wrapS:t?.wrapS??e.CLAMP_TO_EDGE,wrapT:t?.wrapT??e.CLAMP_TO_EDGE,preserveY:t?.preserveY}}clearHistoryTextureLayers(t){if(!t.history)return;let e=this.gl,{type:s,format:i}=t.options,r=t.width*t.height*4,h=s===e.FLOAT?new Float32Array(r):s===e.HALF_FLOAT?new Uint16Array(r):new Uint8Array(r);e.activeTexture(e.TEXTURE0+t.unitIndex),e.bindTexture(e.TEXTURE_2D_ARRAY,t.texture);for(let n=0;n<t.history.depth;++n)e.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,n,t.width,t.height,1,i,s,h)}initializeUniform(t,e,s,i){let r=i?.arrayLength;if(this.uniforms.has(t))throw new Error(`${t} is already initialized.`);if(e!=="float"&&e!=="int")throw new Error(`Invalid uniform type: ${e}. Expected 'float' or 'int'.`);if(r&&!(Array.isArray(s)&&s.length===r))throw new Error(`${t} array length mismatch: must initialize with ${r} elements.`);let h=this.gl.getUniformLocation(this.program,t);if(!h&&r&&(h=this.gl.getUniformLocation(this.program,`${t}[0]`)),!h){this.log(`${t} not found in fragment shader. Skipping initialization.`);return}let n=r?s[0]:s,f=Array.isArray(n)?n.length:1;this.uniforms.set(t,{type:e,length:f,location:h,arrayLength:r});try{this.updateUniforms({[t]:s})}catch(d){throw this.uniforms.delete(t),d}this.hooks.get("initializeUniform")?.forEach(d=>d.call(this,...arguments))}log(...t){this.debug&&console.debug(...t)}updateUniforms(t,e){this.gl.useProgram(this.program),Object.entries(t).forEach(([s,i])=>{let r=this.uniforms.get(s);if(!r){this.log(`${s} not found in fragment shader. Skipping update.`);return}let h=`uniform${r.length}${r.type.charAt(0)}`;if(r.arrayLength){if(!Array.isArray(i))throw new Error(`${s} is an array, but the value passed to updateUniforms is not an array.`);let n=i.length;if(!n)return;if(n>r.arrayLength)throw new Error(`${s} received ${n} values, but maximum length is ${r.arrayLength}.`);if(i.some(c=>(Array.isArray(c)?c.length:1)!==r.length))throw new Error(`Tried to update ${s} with some elements that are not length ${r.length}.`);let f=new(r.type==="float"?Float32Array:Int32Array)(i.flat()),d=r.location;if(e?.startIndex){let c=this.gl.getUniformLocation(this.program,`${s}[${e.startIndex}]`);if(!c)throw new Error(`${s}[${e.startIndex}] not found in fragment shader. Did you pass an invalid startIndex?`);d=c}this.gl[h+"v"](d,f)}else{if(Array.isArray(i)||(i=[i]),i.length!==r.length)throw new Error(`Invalid uniform value length: ${i.length}. Expected ${r.length}.`);this.gl[h](r.location,...i)}}),this.hooks.get("updateUniforms")?.forEach(s=>s.call(this,...arguments))}createTexture(t,e){let{width:s,height:i}=e,r=e.history?.depth??0,h=this.gl.createTexture();if(!h)throw new Error("Failed to create texture");let n=e.unitIndex;if(typeof n!="number")try{n=this.reserveTextureUnit(t)}catch(g){throw this.gl.deleteTexture(h),g}let f=r>0,d=f?this.gl.TEXTURE_2D_ARRAY:this.gl.TEXTURE_2D,{options:c}=e;return this.gl.activeTexture(this.gl.TEXTURE0+n),this.gl.bindTexture(d,h),this.gl.texParameteri(d,this.gl.TEXTURE_WRAP_S,c.wrapS),this.gl.texParameteri(d,this.gl.TEXTURE_WRAP_T,c.wrapT),this.gl.texParameteri(d,this.gl.TEXTURE_MIN_FILTER,c.minFilter),this.gl.texParameteri(d,this.gl.TEXTURE_MAG_FILTER,c.magFilter),f?this.gl.texStorage3D(d,1,c.internalFormat,s,i,r):t===Y&&this.gl.texImage2D(this.gl.TEXTURE_2D,0,c.internalFormat,s,i,0,c.format,c.type,null),{texture:h,unitIndex:n}}_initializeTexture(t,e,s){if(this.textures.has(t))throw new Error(`Texture '${D(t)}' is already initialized.`);let{history:i=0,...r}=s??{},{width:h,height:n}=Z(e);if(!h||!n)throw new Error("Texture source must have valid dimensions");let f={width:h,height:n,options:this.resolveTextureOptions(r)};i>0&&(f.history={depth:i,writeIndex:0});let{texture:d,unitIndex:c}=this.createTexture(t,f),g={texture:d,unitIndex:c,...f};i>0&&(this.initializeUniform(`${D(t)}FrameOffset`,"int",0),this.clearHistoryTextureLayers(g)),this.textures.set(t,g),this.updateTexture(t,e);let _=this.gl.getUniformLocation(this.program,D(t));_&&this.gl.uniform1i(_,c)}initializeTexture(t,e,s){this._initializeTexture(t,e,s),this.hooks.get("initializeTexture")?.forEach(i=>i.call(this,...arguments))}updateTextures(t,e){this.hooks.get("updateTextures")?.forEach(s=>s.call(this,...arguments)),Object.entries(t).forEach(([s,i])=>{this.updateTexture(s,i,e)})}updateTexture(t,e,s){let i=this.textures.get(t);if(!i)throw new Error(`Texture '${D(t)}' is not initialized.`);if(e instanceof WebGLTexture){this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,e);return}let{width:r,height:h}=Z(e);if(!r||!h)return;let n="isPartial"in e&&e.isPartial;n||this.resizeTexture(t,r,h);let d=!("data"in e&&e.data)&&!i.options?.preserveY,c=this.gl.getParameter(this.gl.UNPACK_FLIP_Y_WEBGL);if(i.history){if(this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture),!s?.skipHistoryWrite){this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,d),this.gl.texSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,0,0,i.history.writeIndex,r,h,1,i.options.format,i.options.type,e.data??e),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,c);let g=`${D(t)}FrameOffset`;this.updateUniforms({[g]:i.history.writeIndex}),i.history.writeIndex=(i.history.writeIndex+1)%i.history.depth}}else this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,i.texture),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,d),n?this.gl.texSubImage2D(this.gl.TEXTURE_2D,0,e.x??0,e.y??0,r,h,i.options.format,i.options.type,e.data):this.gl.texImage2D(this.gl.TEXTURE_2D,0,i.options.internalFormat,r,h,0,i.options.format,i.options.type,e.data??e),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,c)}draw(t){let e=this.gl,s=e.drawingBufferWidth,i=e.drawingBufferHeight,r=this.textures.get(M),h=this.textures.get(Y),n=r&&!t?.skipHistoryWrite;n&&(e.bindFramebuffer(e.FRAMEBUFFER,this.intermediateFbo),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,h.texture,0)),e.useProgram(this.program),e.bindBuffer(e.ARRAY_BUFFER,this.buffer),e.vertexAttribPointer(this.aPositionLocation,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(this.aPositionLocation),e.viewport(0,0,s,i),t?.skipClear||e.clear(e.COLOR_BUFFER_BIT),e.drawArrays(e.TRIANGLES,0,6),n&&(e.bindTexture(e.TEXTURE_2D_ARRAY,r.texture),e.copyTexSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,r.history.writeIndex,0,0,s,i),e.bindFramebuffer(e.READ_FRAMEBUFFER,this.intermediateFbo),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),e.blitFramebuffer(0,0,s,i,0,0,s,i,e.COLOR_BUFFER_BIT,e.NEAREST),e.bindFramebuffer(e.FRAMEBUFFER,null))}step(t,e){let s={};this.uniforms.has("u_time")&&(s.u_time=t),this.uniforms.has("u_frame")&&(s.u_frame=this.frame),this.updateUniforms(s),this.hooks.get("step")?.forEach(r=>r.call(this,t,this.frame)),this.draw(e);let i=this.textures.get(M);if(i&&!e?.skipHistoryWrite){let{writeIndex:r,depth:h}=i.history;this.updateUniforms({[`${D(M)}FrameOffset`]:r}),i.history.writeIndex=(r+1)%h}this.hooks.get("afterStep")?.forEach(r=>r.call(this,t,this.frame)),++this.frame}play(t,e){this.pause();let s=i=>{i=(i-this.startTime)/1e3;let r=e?.(i,this.frame)??void 0;this.step(i,r),this.animationFrameId=requestAnimationFrame(s),t?.(i,this.frame)};this.animationFrameId=requestAnimationFrame(s)}pause(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}reset(){this.frame=0,this.startTime=performance.now(),this.textures.forEach(t=>{t.history&&(t.history.writeIndex=0,this.clearHistoryTextureLayers(t))}),this.hooks.get("reset")?.forEach(t=>t.call(this))}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.resolutionObserver.disconnect(),this.resizeObserver.disconnect(),this.canvas instanceof HTMLCanvasElement&&this.eventListeners.forEach((t,e)=>{this.canvas.removeEventListener(e,t)}),this.program&&this.gl.deleteProgram(this.program),this.intermediateFbo&&(this.gl.deleteFramebuffer(this.intermediateFbo),this.intermediateFbo=null),this.textures.forEach(t=>{this.gl.deleteTexture(t.texture)}),this.textureUnitPool.free=[],this.textureUnitPool.next=0,this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null),this.hooks.get("destroy")?.forEach(t=>t.call(this)),this.isInternalCanvas&&this.canvas instanceof HTMLCanvasElement&&this.canvas.remove()}},J=V;var L=33,de=6,p=L+de,a={LEFT_EYE:2,RIGHT_EYE:5,LEFT_SHOULDER:11,RIGHT_SHOULDER:12,LEFT_ELBOW:13,RIGHT_ELBOW:14,LEFT_HIP:23,RIGHT_HIP:24,LEFT_KNEE:25,RIGHT_KNEE:26,LEFT_WRIST:15,RIGHT_WRIST:16,LEFT_PINKY:17,RIGHT_PINKY:18,LEFT_INDEX:19,RIGHT_INDEX:20,LEFT_THUMB:21,RIGHT_THUMB:22,LEFT_ANKLE:27,RIGHT_ANKLE:28,LEFT_HEEL:29,RIGHT_HEEL:30,LEFT_FOOT_INDEX:31,RIGHT_FOOT_INDEX:32,BODY_CENTER:L,LEFT_HAND_CENTER:L+1,RIGHT_HAND_CENTER:L+2,LEFT_FOOT_CENTER:L+3,RIGHT_FOOT_CENTER:L+4,TORSO_CENTER:L+5},Te=Array.from({length:L},(l,t)=>t),ge=[a.LEFT_WRIST,a.LEFT_PINKY,a.LEFT_THUMB,a.LEFT_INDEX],Ee=[a.RIGHT_WRIST,a.RIGHT_PINKY,a.RIGHT_THUMB,a.RIGHT_INDEX],pe=[a.LEFT_ANKLE,a.LEFT_HEEL,a.LEFT_FOOT_INDEX],_e=[a.RIGHT_ANKLE,a.RIGHT_HEEL,a.RIGHT_FOOT_INDEX],xe=[a.LEFT_SHOULDER,a.RIGHT_SHOULDER,a.LEFT_HIP,a.RIGHT_HIP],Q={data:new Uint8Array(4),width:1,height:1};function Re(l){let{textureName:t,options:e}=l,s="https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task";return function(i,r){let{injectGLSL:h,gl:n}=r,f=null,d=null,c=-1,g="VIDEO",_=new Map,X=e?.maxPoses??1,F=512,$=0,o=null,K=new OffscreenCanvas(1,1),E=null;async function ee(){try{let{FilesetResolver:m,PoseLandmarker:u}=await import("@mediapipe/tasks-vision");d=await m.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"),f=await u.createFromOptions(d,{baseOptions:{modelAssetPath:e?.modelPath||s,delegate:"GPU"},canvas:K,runningMode:g,numPoses:e?.maxPoses??1,minPoseDetectionConfidence:e?.minPoseDetectionConfidence??.5,minPosePresenceConfidence:e?.minPosePresenceConfidence??.5,minTrackingConfidence:e?.minTrackingConfidence??.5,outputSegmentationMasks:!0})}catch(m){throw console.error("[Pose Plugin] Failed to initialize:",m),m}}function O(m,u,R){let x=1/0,T=-1/0,N=1/0,b=-1/0,A=0,I=0;for(let U of R){let v=(u*p+U)*4,y=m[v],P=m[v+1];x=Math.min(x,y),T=Math.max(T,y),N=Math.min(N,P),b=Math.max(b,P),A+=m[v+2],I+=m[v+3]}let S=(x+T)/2,w=(N+b)/2,H=A/R.length,C=I/R.length;return[S,w,H,C]}function te(m){if(!(!m||m.length===0||!E)){for(let u=0;u<m.length;++u){let R=m[u];E.updateTextures({u_mask:R.getAsWebGLTexture()}),E.updateUniforms({u_poseIndex:(u+1)/X}),E.draw({skipClear:u>0}),R.close()}i.updateTextures({u_poseMask:K})}}function ie(m){if(!o)return;let u=m.length,R=u*p;for(let T=0;T<u;++T){let N=m[T];for(let G=0;G<L;++G){let B=N[G],z=(T*p+G)*4;o[z]=B.x,o[z+1]=1-B.y,o[z+2]=B.z??0,o[z+3]=B.visibility??1}let b=O(o,T,Te),A=(T*p+a.BODY_CENTER)*4;o[A]=b[0],o[A+1]=b[1],o[A+2]=b[2],o[A+3]=b[3];let I=O(o,T,ge),S=(T*p+a.LEFT_HAND_CENTER)*4;o[S]=I[0],o[S+1]=I[1],o[S+2]=I[2],o[S+3]=I[3];let w=O(o,T,Ee),H=(T*p+a.RIGHT_HAND_CENTER)*4;o[H]=w[0],o[H+1]=w[1],o[H+2]=w[2],o[H+3]=w[3];let C=O(o,T,pe),U=(T*p+a.LEFT_FOOT_CENTER)*4;o[U]=C[0],o[U+1]=C[1],o[U+2]=C[2],o[U+3]=C[3];let v=O(o,T,_e),y=(T*p+a.RIGHT_FOOT_CENTER)*4;o[y]=v[0],o[y+1]=v[1],o[y+2]=v[2],o[y+3]=v[3];let P=O(o,T,xe),k=(T*p+a.TORSO_CENTER)*4;o[k]=P[0],o[k+1]=P[1],o[k+2]=P[2],o[k+3]=P[3]}let x=Math.ceil(R/F);i.updateTextures({u_poseLandmarksTex:{data:o,width:F,height:x,isPartial:!0}})}function j(m){if(!m.landmarks||!o)return;E||(E=new J(`#version 300 es
11
- precision mediump float;
12
- in vec2 v_uv;
13
- out vec4 outColor;
14
- uniform sampler2D u_mask;
15
- uniform float u_poseIndex;
16
- void main() {
17
- ivec2 texCoord = ivec2(v_uv * vec2(textureSize(u_mask, 0)));
18
- float confidence = texelFetch(u_mask, texCoord, 0).r;
19
- if (confidence < 0.01) discard;
20
- outColor = vec4(1.0, confidence, u_poseIndex, 1.0);
21
- }`,{canvas:K}),E.initializeTexture("u_mask",Q),E.initializeUniform("u_poseIndex","float",0));let u=m.landmarks.length;ie(m.landmarks),te(m.segmentationMasks),i.updateUniforms({u_nPoses:u}),e?.onResults?.(m)}i.registerHook("init",async()=>{i.initializeTexture("u_poseMask",Q,{preserveY:!0,minFilter:n.NEAREST,magFilter:n.NEAREST}),i.initializeUniform("u_maxPoses","int",X),i.initializeUniform("u_nPoses","int",0);let m=X*p;$=Math.ceil(m/F);let u=F*$*4;o=new Float32Array(u),i.initializeTexture("u_poseLandmarksTex",{data:o,width:F,height:$},{internalFormat:n.RGBA32F,type:n.FLOAT,minFilter:n.NEAREST,magFilter:n.NEAREST}),await ee(),e?.onReady?.()}),i.registerHook("updateTextures",async m=>{let u=m[t];if(!(!u||(_.get(t)!==u&&(c=-1),_.set(t,u),!f)))try{let x=u instanceof HTMLVideoElement?"VIDEO":"IMAGE";if(g!==x&&(g=x,await f.setOptions({runningMode:g})),u instanceof HTMLVideoElement){if(u.videoWidth===0||u.videoHeight===0||u.readyState<2)return;if(u.currentTime!==c){c=u.currentTime;let T=f.detectForVideo(u,performance.now());j(T)}}else if(u instanceof HTMLImageElement||u instanceof HTMLCanvasElement){if(u.width===0||u.height===0)return;let T=f.detect(u);j(T)}}catch(x){console.error("[Pose Plugin] Detection error:",x)}}),i.registerHook("destroy",()=>{f&&(f.close(),f=null),E&&(E.destroy(),E=null),d=null,_.clear(),o=null}),h(`
7
+ }`,Te=33.333333333333336,z=Symbol("u_history"),V=Symbol("__SHADERPAD_BUFFER");function Ee(l,t){if(!t?.length)return l;let e=l.split(`
8
+ `),r=e.findLastIndex(i=>{let n=i.trimStart();return n.startsWith("precision ")||n.startsWith("#version ")})+1;return e.splice(r,0,...t),e.join(`
9
+ `)}function te(l){return l instanceof WebGLTexture?{width:0,height:0}:l instanceof HTMLVideoElement?{width:l.videoWidth,height:l.videoHeight}:l instanceof HTMLImageElement?{width:l.naturalWidth??l.width,height:l.naturalHeight??l.height}:{width:l.width,height:l.height}}function k(l){return typeof l=="symbol"?l.description??"":l}var j=class{isInternalCanvas=!1;isTouchDevice=!1;gl;uniforms=new Map;textures=new Map;textureUnitPool;buffer=null;program=null;aPositionLocation=0;animationFrameId;resolutionObserver;resizeObserver;resizeTimeout=null;lastResizeTime=-1/0;eventListeners=new Map;frame=0;startTime=0;cursorPosition=[.5,.5];clickPosition=[.5,.5];isMouseDown=!1;canvas;hooks=new Map;historyDepth=0;textureOptions;debug;intermediateFbo=null;constructor(t,{canvas:e,plugins:r,history:i,debug:n,...u}={}){if(this.canvas=e||document.createElement("canvas"),!e){this.isInternalCanvas=!0;let g=this.canvas;g.style.position="fixed",g.style.inset="0",g.style.height="100dvh",g.style.width="100dvw",document.body.appendChild(g)}let s=this.canvas.getContext("webgl2",{antialias:!1});if(!s)throw new Error("WebGL2 not supported. Please use a browser that supports WebGL2.");this.gl=s,this.textureUnitPool={free:[],next:0,max:s.getParameter(s.MAX_COMBINED_TEXTURE_IMAGE_UNITS)},this.textureOptions=u;let{internalFormat:d,type:c}=u;(c===s.FLOAT||c===s.HALF_FLOAT||d===s.RGBA16F||d===s.RGBA32F||d===s.R16F||d===s.R32F||d===s.RG16F||d===s.RG32F)&&!s.getExtension("EXT_color_buffer_float")&&(console.warn("EXT_color_buffer_float not supported, falling back to RGBA8"),delete this.textureOptions?.internalFormat,delete this.textureOptions?.format,delete this.textureOptions?.type),i&&(this.historyDepth=i),this.debug=n??(typeof process<"u"&&!1),this.animationFrameId=null,this.resolutionObserver=new MutationObserver(()=>this.updateResolution()),this.resizeObserver=new ResizeObserver(()=>this.throttledHandleResize());let p=[];r&&r.forEach(g=>g(this,{gl:s,canvas:this.canvas,injectGLSL:a=>{p.push(a)},emitHook:this.emitHook.bind(this)}));let E=this.gl.createProgram();if(!E)throw new Error("Failed to create WebGL program");this.program=E;let H=this.createShader(this.gl.VERTEX_SHADER,fe),S=this.createShader(s.FRAGMENT_SHADER,Ee(t,p));if(s.attachShader(E,H),s.attachShader(E,S),s.linkProgram(E),s.deleteShader(H),s.deleteShader(S),!s.getProgramParameter(E,s.LINK_STATUS))throw console.error("Program link error:",s.getProgramInfoLog(E)),s.deleteProgram(E),new Error("Failed to link WebGL program");this.aPositionLocation=s.getAttribLocation(E,"aPosition");let v=new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]);this.buffer=s.createBuffer(),s.bindBuffer(s.ARRAY_BUFFER,this.buffer),s.bufferData(s.ARRAY_BUFFER,v,s.STATIC_DRAW),s.viewport(0,0,s.drawingBufferWidth,s.drawingBufferHeight),s.enableVertexAttribArray(this.aPositionLocation),s.vertexAttribPointer(this.aPositionLocation,2,s.FLOAT,!1,0,0),s.useProgram(E),this.canvas instanceof HTMLCanvasElement&&(this.resolutionObserver.observe(this.canvas,{attributes:!0,attributeFilter:["width","height"]}),this.resizeObserver.observe(this.canvas)),this.isInternalCanvas||this.updateResolution(),this.initializeUniform("u_cursor","float",this.cursorPosition),this.initializeUniform("u_click","float",[...this.clickPosition,this.isMouseDown?1:0]),this.initializeUniform("u_time","float",0),this.initializeUniform("u_frame","int",0),this.historyDepth>0&&(this._initializeTexture(V,this.canvas,{...this.textureOptions}),this._initializeTexture(z,this.canvas,{history:this.historyDepth,...this.textureOptions}),this.intermediateFbo=s.createFramebuffer()),this.canvas instanceof HTMLCanvasElement&&this.addEventListeners(),this.emitHook("init")}emitHook(t,...e){this.hooks.get(t)?.forEach(r=>r.call(this,...e))}on(t,e){this.hooks.has(t)||this.hooks.set(t,[]),this.hooks.get(t).push(e)}off(t,e){let r=this.hooks.get(t);r&&r.splice(r.indexOf(e),1)}createShader(t,e){let r=this.gl.createShader(t);if(this.gl.shaderSource(r,e),this.gl.compileShader(r),!this.gl.getShaderParameter(r,this.gl.COMPILE_STATUS))throw console.error("Shader compilation failed:",e),console.error(this.gl.getShaderInfoLog(r)),this.gl.deleteShader(r),new Error("Shader compilation failed");return r}throttledHandleResize(){clearTimeout(this.resizeTimeout);let t=performance.now(),e=this.lastResizeTime+Te-t;e<=0?(this.lastResizeTime=t,this.handleResize()):this.resizeTimeout=setTimeout(()=>this.throttledHandleResize(),e)}handleResize(){if(!(this.canvas instanceof HTMLCanvasElement))return;let t=window.devicePixelRatio||1,e=this.canvas.clientWidth*t,r=this.canvas.clientHeight*t;this.isInternalCanvas&&(this.canvas.width!==e||this.canvas.height!==r)&&(this.canvas.width=e,this.canvas.height=r),this.emitHook("resize",e,r)}addEventListeners(){let t=this.canvas,e=(i,n)=>{if(!this.uniforms.has("u_cursor"))return;let u=t.getBoundingClientRect();this.cursorPosition[0]=(i-u.left)/u.width,this.cursorPosition[1]=1-(n-u.top)/u.height,this.updateUniforms({u_cursor:this.cursorPosition})},r=(i,n,u)=>{if(this.uniforms.has("u_click")){if(this.isMouseDown=i,i){let s=t.getBoundingClientRect(),d=n,c=u;this.clickPosition[0]=(d-s.left)/s.width,this.clickPosition[1]=1-(c-s.top)/s.height}this.updateUniforms({u_click:[...this.clickPosition,this.isMouseDown?1:0]})}};this.eventListeners.set("mousemove",i=>{let n=i;this.isTouchDevice||e(n.clientX,n.clientY)}),this.eventListeners.set("mousedown",i=>{let n=i;this.isTouchDevice||n.button===0&&(this.isMouseDown=!0,r(!0,n.clientX,n.clientY))}),this.eventListeners.set("mouseup",i=>{let n=i;this.isTouchDevice||n.button===0&&r(!1)}),this.eventListeners.set("touchmove",i=>{let n=i;n.touches.length>0&&e(n.touches[0].clientX,n.touches[0].clientY)}),this.eventListeners.set("touchstart",i=>{let n=i;this.isTouchDevice=!0,n.touches.length>0&&(e(n.touches[0].clientX,n.touches[0].clientY),r(!0,n.touches[0].clientX,n.touches[0].clientY))}),this.eventListeners.set("touchend",i=>{i.touches.length===0&&r(!1)}),this.eventListeners.forEach((i,n)=>{t.addEventListener(n,i)})}updateResolution(){let t=[this.gl.drawingBufferWidth,this.gl.drawingBufferHeight];this.gl.viewport(0,0,...t),this.uniforms.has("u_resolution")?this.updateUniforms({u_resolution:t}):this.initializeUniform("u_resolution","float",t),this.historyDepth>0&&(this.resizeTexture(z,...t),this.resizeTexture(V,...t)),this.emitHook("updateResolution",...t)}resizeTexture(t,e,r){let i=this.textures.get(t);if(!i||i.width===e&&i.height===r)return;this.gl.deleteTexture(i.texture),i.width=e,i.height=r;let{texture:n}=this.createTexture(t,i);i.texture=n,i.history&&(i.history.writeIndex=0,this.clearHistoryTextureLayers(i))}reserveTextureUnit(t){let e=this.textures.get(t);if(e)return e.unitIndex;if(this.textureUnitPool.free.length>0)return this.textureUnitPool.free.pop();if(this.textureUnitPool.next>=this.textureUnitPool.max)throw new Error("Exceeded the available texture units for this device.");return this.textureUnitPool.next++}releaseTextureUnit(t){let e=this.textures.get(t);e&&this.textureUnitPool.free.push(e.unitIndex)}resolveTextureOptions(t){let{gl:e}=this,r=t?.type??e.UNSIGNED_BYTE;return{type:r,format:t?.format??e.RGBA,internalFormat:t?.internalFormat??(r===e.FLOAT?e.RGBA32F:r===e.HALF_FLOAT?e.RGBA16F:e.RGBA8),minFilter:t?.minFilter??e.LINEAR,magFilter:t?.magFilter??e.LINEAR,wrapS:t?.wrapS??e.CLAMP_TO_EDGE,wrapT:t?.wrapT??e.CLAMP_TO_EDGE,preserveY:t?.preserveY}}clearHistoryTextureLayers(t){if(!t.history)return;let e=this.gl,{type:r,format:i}=t.options,n=t.width*t.height*4,u=r===e.FLOAT?new Float32Array(n):r===e.HALF_FLOAT?new Uint16Array(n):new Uint8Array(n);e.activeTexture(e.TEXTURE0+t.unitIndex),e.bindTexture(e.TEXTURE_2D_ARRAY,t.texture);for(let s=0;s<t.history.depth;++s)e.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,s,t.width,t.height,1,i,r,u)}initializeUniform(t,e,r,i){let n=i?.arrayLength;if(this.uniforms.has(t))throw new Error(`${t} is already initialized.`);if(e!=="float"&&e!=="int")throw new Error(`Invalid uniform type: ${e}. Expected 'float' or 'int'.`);if(n&&!(Array.isArray(r)&&r.length===n))throw new Error(`${t} array length mismatch: must initialize with ${n} elements.`);let u=this.gl.getUniformLocation(this.program,t);if(!u&&n&&(u=this.gl.getUniformLocation(this.program,`${t}[0]`)),!u){this.log(`${t} not in shader. Skipping initialization.`);return}let s=n?r[0]:r,d=Array.isArray(s)?s.length:1;this.uniforms.set(t,{type:e,length:d,location:u,arrayLength:n});try{this.updateUniforms({[t]:r})}catch(c){throw this.uniforms.delete(t),c}this.emitHook("initializeUniform",...arguments)}log(...t){this.debug&&console.debug(...t)}updateUniforms(t,e){this.gl.useProgram(this.program),Object.entries(t).forEach(([r,i])=>{let n=this.uniforms.get(r);if(!n){this.log(`${r} not in shader. Skipping update.`);return}let u=`uniform${n.length}${n.type.charAt(0)}`;if(n.arrayLength){if(!Array.isArray(i))throw new Error(`${r} is an array, but the value passed to updateUniforms is not an array.`);let s=i.length;if(!s)return;if(s>n.arrayLength)throw new Error(`${r} received ${s} values, but maximum length is ${n.arrayLength}.`);if(i.some(m=>(Array.isArray(m)?m.length:1)!==n.length))throw new Error(`Tried to update ${r} with some elements that are not length ${n.length}.`);let d=new(n.type==="float"?Float32Array:Int32Array)(i.flat()),c=n.location;if(e?.startIndex){let m=this.gl.getUniformLocation(this.program,`${r}[${e.startIndex}]`);if(!m)throw new Error(`${r}[${e.startIndex}] not in shader. Did you pass an invalid startIndex?`);c=m}this.gl[u+"v"](c,d)}else{if(Array.isArray(i)||(i=[i]),i.length!==n.length)throw new Error(`Invalid uniform value length: ${i.length}. Expected ${n.length}.`);this.gl[u](n.location,...i)}}),this.emitHook("updateUniforms",...arguments)}createTexture(t,e){let{width:r,height:i}=e,n=e.history?.depth??0,u=this.gl.createTexture();if(!u)throw new Error("Failed to create texture");let s=e.unitIndex;if(typeof s!="number")try{s=this.reserveTextureUnit(t)}catch(p){throw this.gl.deleteTexture(u),p}let d=n>0,c=d?this.gl.TEXTURE_2D_ARRAY:this.gl.TEXTURE_2D,{options:m}=e;return this.gl.activeTexture(this.gl.TEXTURE0+s),this.gl.bindTexture(c,u),this.gl.texParameteri(c,this.gl.TEXTURE_WRAP_S,m.wrapS),this.gl.texParameteri(c,this.gl.TEXTURE_WRAP_T,m.wrapT),this.gl.texParameteri(c,this.gl.TEXTURE_MIN_FILTER,m.minFilter),this.gl.texParameteri(c,this.gl.TEXTURE_MAG_FILTER,m.magFilter),d?this.gl.texStorage3D(c,1,m.internalFormat,r,i,n):t===V&&this.gl.texImage2D(this.gl.TEXTURE_2D,0,m.internalFormat,r,i,0,m.format,m.type,null),{texture:u,unitIndex:s}}_initializeTexture(t,e,r){if(this.textures.has(t))throw new Error(`Texture '${k(t)}' is already initialized.`);let{history:i=0,...n}=r??{},{width:u,height:s}=te(e);if(!u||!s)throw new Error("Texture source must have valid dimensions");let d={width:u,height:s,options:this.resolveTextureOptions(n)};i>0&&(d.history={depth:i,writeIndex:0});let{texture:c,unitIndex:m}=this.createTexture(t,d),p={texture:c,unitIndex:m,...d};i>0&&(this.initializeUniform(`${k(t)}FrameOffset`,"int",0),this.clearHistoryTextureLayers(p)),this.textures.set(t,p),this.updateTexture(t,e);let E=this.gl.getUniformLocation(this.program,k(t));E&&this.gl.uniform1i(E,m)}initializeTexture(t,e,r){this._initializeTexture(t,e,r),this.emitHook("initializeTexture",...arguments)}updateTextures(t,e){Object.entries(t).forEach(([r,i])=>{this.updateTexture(r,i,e)}),this.emitHook("updateTextures",...arguments)}updateTexture(t,e,r){let i=this.textures.get(t);if(!i)throw new Error(`Texture '${k(t)}' is not initialized.`);if(e instanceof WebGLTexture){this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,e);return}let{width:n,height:u}=te(e);if(!n||!u)return;let s="isPartial"in e&&e.isPartial;s||this.resizeTexture(t,n,u);let c=!("data"in e&&e.data)&&!i.options?.preserveY,m=this.gl.getParameter(this.gl.UNPACK_FLIP_Y_WEBGL);if(i.history){if(this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture),!r?.skipHistoryWrite){this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,c),this.gl.texSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,0,0,i.history.writeIndex,n,u,1,i.options.format,i.options.type,e.data??e),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,m);let p=`${k(t)}FrameOffset`;this.updateUniforms({[p]:i.history.writeIndex}),i.history.writeIndex=(i.history.writeIndex+1)%i.history.depth}}else this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,i.texture),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,c),s?this.gl.texSubImage2D(this.gl.TEXTURE_2D,0,e.x??0,e.y??0,n,u,i.options.format,i.options.type,e.data):this.gl.texImage2D(this.gl.TEXTURE_2D,0,i.options.internalFormat,n,u,0,i.options.format,i.options.type,e.data??e),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,m)}draw(t){this.emitHook("beforeDraw",...arguments);let e=this.gl,r=e.drawingBufferWidth,i=e.drawingBufferHeight,n=this.textures.get(z),u=this.textures.get(V),s=n&&!t?.skipHistoryWrite;s&&(e.bindFramebuffer(e.FRAMEBUFFER,this.intermediateFbo),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,u.texture,0)),e.useProgram(this.program),e.bindBuffer(e.ARRAY_BUFFER,this.buffer),e.vertexAttribPointer(this.aPositionLocation,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(this.aPositionLocation),e.viewport(0,0,r,i),t?.skipClear||e.clear(e.COLOR_BUFFER_BIT),e.drawArrays(e.TRIANGLES,0,6),s&&(e.bindTexture(e.TEXTURE_2D_ARRAY,n.texture),e.copyTexSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,n.history.writeIndex,0,0,r,i),e.bindFramebuffer(e.READ_FRAMEBUFFER,this.intermediateFbo),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),e.blitFramebuffer(0,0,r,i,0,0,r,i,e.COLOR_BUFFER_BIT,e.NEAREST),e.bindFramebuffer(e.FRAMEBUFFER,null)),this.emitHook("afterDraw",...arguments)}step(t,e){this.emitHook("beforeStep",...arguments);let r={};this.uniforms.has("u_time")&&(r.u_time=t),this.uniforms.has("u_frame")&&(r.u_frame=this.frame),this.updateUniforms(r),this.draw(e);let i=this.textures.get(z);if(i&&!e?.skipHistoryWrite){let{writeIndex:n,depth:u}=i.history;this.updateUniforms({[`${k(z)}FrameOffset`]:n}),i.history.writeIndex=(n+1)%u}++this.frame,this.emitHook("afterStep",...arguments)}play(t,e){this.pause();let r=i=>{i=(i-this.startTime)/1e3;let n=e?.(i,this.frame)??void 0;this.step(i,n),this.animationFrameId=requestAnimationFrame(r),t?.(i,this.frame)};this.animationFrameId=requestAnimationFrame(r),this.emitHook("play")}pause(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.emitHook("pause")}reset(){this.frame=0,this.startTime=performance.now(),this.textures.forEach(t=>{t.history&&(t.history.writeIndex=0,this.clearHistoryTextureLayers(t))}),this.emitHook("reset")}destroy(){this.emitHook("destroy"),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.resolutionObserver.disconnect(),this.resizeObserver.disconnect(),this.canvas instanceof HTMLCanvasElement&&this.eventListeners.forEach((t,e)=>{this.canvas.removeEventListener(e,t)}),this.program&&this.gl.deleteProgram(this.program),this.intermediateFbo&&(this.gl.deleteFramebuffer(this.intermediateFbo),this.intermediateFbo=null),this.textures.forEach(t=>{this.gl.deleteTexture(t.texture)}),this.textureUnitPool.free=[],this.textureUnitPool.next=0,this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null),this.isInternalCanvas&&this.canvas instanceof HTMLCanvasElement&&this.canvas.remove()}},ie=j;var F=33,pe=6,_=F+pe,h={LEFT_EYE:2,RIGHT_EYE:5,LEFT_SHOULDER:11,RIGHT_SHOULDER:12,LEFT_ELBOW:13,RIGHT_ELBOW:14,LEFT_HIP:23,RIGHT_HIP:24,LEFT_KNEE:25,RIGHT_KNEE:26,LEFT_WRIST:15,RIGHT_WRIST:16,LEFT_PINKY:17,RIGHT_PINKY:18,LEFT_INDEX:19,RIGHT_INDEX:20,LEFT_THUMB:21,RIGHT_THUMB:22,LEFT_ANKLE:27,RIGHT_ANKLE:28,LEFT_HEEL:29,RIGHT_HEEL:30,LEFT_FOOT_INDEX:31,RIGHT_FOOT_INDEX:32,BODY_CENTER:F,LEFT_HAND_CENTER:F+1,RIGHT_HAND_CENTER:F+2,LEFT_FOOT_CENTER:F+3,RIGHT_FOOT_CENTER:F+4,TORSO_CENTER:F+5},ge=Array.from({length:F},(l,t)=>t),_e=[h.LEFT_WRIST,h.LEFT_PINKY,h.LEFT_THUMB,h.LEFT_INDEX],xe=[h.RIGHT_WRIST,h.RIGHT_PINKY,h.RIGHT_THUMB,h.RIGHT_INDEX],Re=[h.LEFT_ANKLE,h.LEFT_HEEL,h.LEFT_FOOT_INDEX],ve=[h.RIGHT_ANKLE,h.RIGHT_HEEL,h.RIGHT_FOOT_INDEX],Le=[h.LEFT_SHOULDER,h.RIGHT_SHOULDER,h.LEFT_HIP,h.RIGHT_HIP],be={data:new Uint8Array(4),width:1,height:1};function Fe(l){let{textureName:t,options:e}=l,r="https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task";return function(i,n){let{injectGLSL:u,gl:s,emitHook:d}=n,c=null,m=null,p=-1,E="VIDEO",H=new Map,S=e?.maxPoses??1,v=512,g=0,a=null,B=new OffscreenCanvas(1,1),x=null;async function re(){try{let{FilesetResolver:o,PoseLandmarker:f}=await import("@mediapipe/tasks-vision");m=await o.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"),c=await f.createFromOptions(m,{baseOptions:{modelAssetPath:e?.modelPath||r,delegate:"GPU"},canvas:B,runningMode:E,numPoses:e?.maxPoses??1,minPoseDetectionConfidence:e?.minPoseDetectionConfidence??.5,minPosePresenceConfidence:e?.minPosePresenceConfidence??.5,minTrackingConfidence:e?.minTrackingConfidence??.5,outputSegmentationMasks:!0})}catch(o){throw console.error("[Pose Plugin] Failed to initialize MediaPipe:",o),o}}let q=re();function w(o,f,L){let R=1/0,T=-1/0,G=1/0,I=-1/0,A=0,y=0;for(let M of L){let b=(f*_+M)*4,P=o[b],O=o[b+1];R=Math.min(R,P),T=Math.max(T,P),G=Math.min(G,O),I=Math.max(I,O),A+=o[b+2],y+=o[b+3]}let D=(R+T)/2,C=(G+I)/2,N=A/L.length,U=y/L.length;return[D,C,N,U]}function ne(o){if(!(!o||o.length===0||!x)){for(let f=0;f<o.length;++f){let L=o[f];x.updateTextures({u_mask:L.getAsWebGLTexture()}),x.updateUniforms({u_poseIndex:(f+1)/S}),x.draw({skipClear:f>0}),L.close()}i.updateTextures({u_poseMask:B})}}function se(o){if(!a)return;let f=o.length,L=f*_;for(let T=0;T<f;++T){let G=o[T];for(let Y=0;Y<F;++Y){let X=G[Y],$=(T*_+Y)*4;a[$]=X.x,a[$+1]=1-X.y,a[$+2]=X.z??0,a[$+3]=X.visibility??1}let I=w(a,T,ge),A=(T*_+h.BODY_CENTER)*4;a[A]=I[0],a[A+1]=I[1],a[A+2]=I[2],a[A+3]=I[3];let y=w(a,T,_e),D=(T*_+h.LEFT_HAND_CENTER)*4;a[D]=y[0],a[D+1]=y[1],a[D+2]=y[2],a[D+3]=y[3];let C=w(a,T,xe),N=(T*_+h.RIGHT_HAND_CENTER)*4;a[N]=C[0],a[N+1]=C[1],a[N+2]=C[2],a[N+3]=C[3];let U=w(a,T,Re),M=(T*_+h.LEFT_FOOT_CENTER)*4;a[M]=U[0],a[M+1]=U[1],a[M+2]=U[2],a[M+3]=U[3];let b=w(a,T,ve),P=(T*_+h.RIGHT_FOOT_CENTER)*4;a[P]=b[0],a[P+1]=b[1],a[P+2]=b[2],a[P+3]=b[3];let O=w(a,T,Le),W=(T*_+h.TORSO_CENTER)*4;a[W]=O[0],a[W+1]=O[1],a[W+2]=O[2],a[W+3]=O[3]}let R=Math.ceil(L/v);i.updateTextures({u_poseLandmarksTex:{data:a,width:v,height:R,isPartial:!0}})}function Z(o){!o?.landmarks||!a||(se(o.landmarks),ne(o.segmentationMasks),i.updateUniforms({u_nPoses:o.landmarks.length}),d("pose:result",o))}i.on("init",async()=>{i.initializeUniform("u_maxPoses","int",S),i.initializeUniform("u_nPoses","int",0);let o=S*_;g=Math.ceil(o/v);let f=v*g*4;a=new Float32Array(f),i.initializeTexture("u_poseLandmarksTex",{data:a,width:v,height:g},{internalFormat:s.RGBA32F,type:s.FLOAT,minFilter:s.NEAREST,magFilter:s.NEAREST}),i.initializeTexture("u_poseMask",B,{preserveY:!0,minFilter:s.NEAREST,magFilter:s.NEAREST}),await q,x=new ie(`#version 300 es
10
+ precision mediump float;
11
+ in vec2 v_uv;
12
+ out vec4 outColor;
13
+ uniform sampler2D u_mask;
14
+ uniform float u_poseIndex;
15
+ void main() {
16
+ ivec2 texCoord = ivec2(v_uv * vec2(textureSize(u_mask, 0)));
17
+ float confidence = texelFetch(u_mask, texCoord, 0).r;
18
+ if (confidence < 0.01) discard;
19
+ outColor = vec4(1.0, confidence, u_poseIndex, 1.0);
20
+ }`,{canvas:B}),x.initializeTexture("u_mask",be),x.initializeUniform("u_poseIndex","float",0),d("pose:ready")}),i.on("initializeTexture",(o,f)=>{o===t&&Q(f)}),i.on("updateTextures",o=>{let f=o[t];f&&Q(f)});let J=0;async function Q(o){let f=++J;if(await q,f!==J||!c)return;H.get(t)!==o&&(p=-1),H.set(t,o);try{let R=o instanceof HTMLVideoElement?"VIDEO":"IMAGE";if(E!==R&&(E=R,await c.setOptions({runningMode:E})),o instanceof HTMLVideoElement){if(o.videoWidth===0||o.videoHeight===0||o.readyState<2)return;o.currentTime!==p&&(p=o.currentTime,Z(c.detectForVideo(o,performance.now())))}else if(o instanceof HTMLImageElement||o instanceof HTMLCanvasElement){if(o.width===0||o.height===0)return;Z(c.detect(o))}}catch(R){console.error("[Pose Plugin] Detection error:",R)}}i.on("destroy",()=>{c&&(c.close(),c=null),x&&(x.destroy(),x=null),m=null,H.clear(),a=null}),u(`
22
21
  uniform int u_maxPoses;
23
22
  uniform int u_nPoses;
24
23
  uniform sampler2D u_poseLandmarksTex;
25
24
  uniform sampler2D u_poseMask;
26
25
 
27
- #define POSE_LANDMARK_LEFT_EYE ${a.LEFT_EYE}
28
- #define POSE_LANDMARK_RIGHT_EYE ${a.RIGHT_EYE}
29
- #define POSE_LANDMARK_LEFT_SHOULDER ${a.LEFT_SHOULDER}
30
- #define POSE_LANDMARK_RIGHT_SHOULDER ${a.RIGHT_SHOULDER}
31
- #define POSE_LANDMARK_LEFT_ELBOW ${a.LEFT_ELBOW}
32
- #define POSE_LANDMARK_RIGHT_ELBOW ${a.RIGHT_ELBOW}
33
- #define POSE_LANDMARK_LEFT_HIP ${a.LEFT_HIP}
34
- #define POSE_LANDMARK_RIGHT_HIP ${a.RIGHT_HIP}
35
- #define POSE_LANDMARK_LEFT_KNEE ${a.LEFT_KNEE}
36
- #define POSE_LANDMARK_RIGHT_KNEE ${a.RIGHT_KNEE}
37
- #define POSE_LANDMARK_BODY_CENTER ${a.BODY_CENTER}
38
- #define POSE_LANDMARK_LEFT_HAND_CENTER ${a.LEFT_HAND_CENTER}
39
- #define POSE_LANDMARK_RIGHT_HAND_CENTER ${a.RIGHT_HAND_CENTER}
40
- #define POSE_LANDMARK_LEFT_FOOT_CENTER ${a.LEFT_FOOT_CENTER}
41
- #define POSE_LANDMARK_RIGHT_FOOT_CENTER ${a.RIGHT_FOOT_CENTER}
42
- #define POSE_LANDMARK_TORSO_CENTER ${a.TORSO_CENTER}
26
+ #define POSE_LANDMARK_LEFT_EYE ${h.LEFT_EYE}
27
+ #define POSE_LANDMARK_RIGHT_EYE ${h.RIGHT_EYE}
28
+ #define POSE_LANDMARK_LEFT_SHOULDER ${h.LEFT_SHOULDER}
29
+ #define POSE_LANDMARK_RIGHT_SHOULDER ${h.RIGHT_SHOULDER}
30
+ #define POSE_LANDMARK_LEFT_ELBOW ${h.LEFT_ELBOW}
31
+ #define POSE_LANDMARK_RIGHT_ELBOW ${h.RIGHT_ELBOW}
32
+ #define POSE_LANDMARK_LEFT_HIP ${h.LEFT_HIP}
33
+ #define POSE_LANDMARK_RIGHT_HIP ${h.RIGHT_HIP}
34
+ #define POSE_LANDMARK_LEFT_KNEE ${h.LEFT_KNEE}
35
+ #define POSE_LANDMARK_RIGHT_KNEE ${h.RIGHT_KNEE}
36
+ #define POSE_LANDMARK_BODY_CENTER ${h.BODY_CENTER}
37
+ #define POSE_LANDMARK_LEFT_HAND_CENTER ${h.LEFT_HAND_CENTER}
38
+ #define POSE_LANDMARK_RIGHT_HAND_CENTER ${h.RIGHT_HAND_CENTER}
39
+ #define POSE_LANDMARK_LEFT_FOOT_CENTER ${h.LEFT_FOOT_CENTER}
40
+ #define POSE_LANDMARK_RIGHT_FOOT_CENTER ${h.RIGHT_FOOT_CENTER}
41
+ #define POSE_LANDMARK_TORSO_CENTER ${h.TORSO_CENTER}
43
42
 
44
43
  vec4 poseLandmark(int poseIndex, int landmarkIndex) {
45
- int i = poseIndex * ${p} + landmarkIndex;
46
- int x = i % ${F};
47
- int y = i / ${F};
44
+ int i = poseIndex * ${_} + landmarkIndex;
45
+ int x = i % ${v};
46
+ int y = i / ${v};
48
47
  return texelFetch(u_poseLandmarksTex, ivec2(x, y), 0);
49
48
  }
50
49
 
@@ -57,5 +56,5 @@ vec2 poseAt(vec2 pos) {
57
56
  float inPose(vec2 pos) {
58
57
  float pose = poseAt(pos).x;
59
58
  return step(0.0, pose);
60
- }`)}}var ve=Re;
59
+ }`)}}var Ie=Fe;
61
60
  //# sourceMappingURL=pose.js.map