shaderpad 1.0.0-beta.32 → 1.0.0-beta.33

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\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]; // Wrist + MCP joints of all fingers, weighted toward the 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},\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('Failed to initialize Hand Landmarker:', 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: 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[][]) {\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\t// Store standard 21 landmarks\n\t\t\t\tfor (let lmIdx = 0; lmIdx < 21; ++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; // R (X)\n\t\t\t\t\tlandmarksDataArray[dataIdx + 1] = 1 - landmark.y; // G (Inverted Y)\n\t\t\t\t\tlandmarksDataArray[dataIdx + 2] = landmark.z ?? 0; // B (Z)\n\t\t\t\t\tlandmarksDataArray[dataIdx + 3] = landmark.visibility ?? 1; // A (Visibility)\n\t\t\t\t}\n\n\t\t\t\t// Calculate and store hand center (landmark 21)\n\t\t\t\tconst handCenter = calculateBoundingBoxCenter(landmarksDataArray, handIdx, HAND_CENTER_LANDMARKS);\n\t\t\t\tconst handCenterIdx = (handIdx * LANDMARK_COUNT + 21) * 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] = handCenter[3];\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},\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);\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});\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\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 timestamp = performance.now();\n\t\t\t\t\t\tconst result = handLandmarker.detectForVideo(source, timestamp);\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.warn('Hand 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;\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\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","nHands","totalLandmarks","landmarks","lmIdx","landmark","handCenter","handCenterIdx","rowsToUpdate","processHandResults","result","textureSize","updates","source","requiredMode","timestamp","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\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});\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"]}
@@ -7,7 +7,6 @@ interface PosePluginOptions {
7
7
  minPoseDetectionConfidence?: number;
8
8
  minPosePresenceConfidence?: number;
9
9
  minTrackingConfidence?: number;
10
- outputSegmentationMasks?: boolean;
11
10
  onResults?: (results: PoseLandmarkerResult) => void;
12
11
  }
13
12
  declare function pose(config: {
@@ -7,7 +7,6 @@ interface PosePluginOptions {
7
7
  minPoseDetectionConfidence?: number;
8
8
  minPosePresenceConfidence?: number;
9
9
  minTrackingConfidence?: number;
10
- outputSegmentationMasks?: boolean;
11
10
  onResults?: (results: PoseLandmarkerResult) => void;
12
11
  }
13
12
  declare function pose(config: {
@@ -1,31 +1,61 @@
1
- "use strict";var ee=Object.create;var w=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.getPrototypeOf,ie=Object.prototype.hasOwnProperty;var se=(r,_)=>{for(var s in _)w(r,s,{get:_[s],enumerable:!0})},X=(r,_,s,M)=>{if(_&&typeof _=="object"||typeof _=="function")for(let a of ne(_))!ie.call(r,a)&&a!==s&&w(r,a,{get:()=>_[a],enumerable:!(M=te(_,a))||M.enumerable});return r};var re=(r,_,s)=>(s=r!=null?ee(oe(r)):{},X(_||!r||!r.__esModule?w(s,"default",{value:r,enumerable:!0}):s,r)),ae=r=>X(w({},"__esModule",{value:!0}),r);var ce={};se(ce,{default:()=>Te});module.exports=ae(ce);var H=33,Ee=6,u=H+Ee,t={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:H,LEFT_HAND_CENTER:H+1,RIGHT_HAND_CENTER:H+2,LEFT_FOOT_CENTER:H+3,RIGHT_FOOT_CENTER:H+4,TORSO_CENTER:H+5};function _e(r){let{textureName:_,options:s}=r,M="https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task";return function(a,z){let{injectGLSL:V,gl:k}=z,L=null,U=null,v=-1,S="VIDEO",b=new Map,B=s?.maxPoses??1,N=512,$=0,e=null,j=512,Z=512,l=document.createElement("canvas");l.width=j,l.height=Z;let G=l.getContext("2d"),p=document.createElement("canvas"),Y=p.getContext("2d");G.globalCompositeOperation=Y.globalCompositeOperation="lighten";async function q(){try{let{FilesetResolver:o,PoseLandmarker:n}=await import("@mediapipe/tasks-vision");U=await o.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"),L=await n.createFromOptions(U,{baseOptions:{modelAssetPath:s?.modelPath||M},runningMode:S,numPoses:s?.maxPoses??1,minPoseDetectionConfidence:s?.minPoseDetectionConfidence??.5,minPosePresenceConfidence:s?.minPosePresenceConfidence??.5,minTrackingConfidence:s?.minTrackingConfidence??.5,outputSegmentationMasks:s?.outputSegmentationMasks??!0})}catch(o){throw console.error("[Pose Plugin] Failed to initialize Pose Landmarker:",o),o}}function g(o,n,T){let E=1/0,i=-1/0,d=1/0,m=-1/0,R=0,c=0;for(let D of T){let I=(n*u+D)*4,f=o[I],O=o[I+1];E=Math.min(E,f),i=Math.max(i,f),d=Math.min(d,O),m=Math.max(m,O),R+=o[I+2],c+=o[I+3]}let P=(E+i)/2,A=(d+m)/2,F=R/T.length,C=c/T.length;return[P,A,F,C]}async function J(o){if(!L||!e){console.warn("[Pose Plugin] Cannot update mask: poseLandmarker or landmarksDataArray missing");return}try{G.clearRect(0,0,l.width,l.height),o&&o.length>0&&o.forEach(n=>{if(!n)return;let{width:T,height:E}=n,i=n.getAsUint8Array(),d=T*E,m=new Uint8ClampedArray(d*4);for(let c=0;c<d;c++)m[c*4+1]=i[c],m[c*4+3]=255;let R=new ImageData(m,T,E);T===l.width&&E===l.height?G.putImageData(R,0,0):(p.width!==T&&(p.width=T),p.height!==E&&(p.height=E),Y.putImageData(R,0,0),G.drawImage(p,0,0,l.width,l.height))}),a.updateTextures({u_poseMask:l})}catch(n){console.error("[Pose Plugin] Failed to generate mask texture:",n)}}function Q(o){if(!e)return;let n=o.length,T=n*u;for(let i=0;i<n;++i){let d=o[i];for(let h=0;h<H;++h){let x=d[h],y=(i*u+h)*4;e[y]=x.x,e[y+1]=1-x.y,e[y+2]=x.z??0,e[y+3]=x.visibility??1}let m=g(e,i,Array.from({length:H},(h,x)=>x)),R=(i*u+t.BODY_CENTER)*4;e[R]=m[0],e[R+1]=m[1],e[R+2]=m[2],e[R+3]=m[3];let c=g(e,i,[t.LEFT_WRIST,t.LEFT_PINKY,t.LEFT_THUMB,t.LEFT_INDEX]),P=(i*u+t.LEFT_HAND_CENTER)*4;e[P]=c[0],e[P+1]=c[1],e[P+2]=c[2],e[P+3]=c[3];let A=g(e,i,[t.RIGHT_WRIST,t.RIGHT_PINKY,t.RIGHT_THUMB,t.RIGHT_INDEX]),F=(i*u+t.RIGHT_HAND_CENTER)*4;e[F]=A[0],e[F+1]=A[1],e[F+2]=A[2],e[F+3]=A[3];let C=g(e,i,[t.LEFT_ANKLE,t.LEFT_HEEL,t.LEFT_FOOT_INDEX]),D=(i*u+t.LEFT_FOOT_CENTER)*4;e[D]=C[0],e[D+1]=C[1],e[D+2]=C[2],e[D+3]=C[3];let I=g(e,i,[t.RIGHT_ANKLE,t.RIGHT_HEEL,t.RIGHT_FOOT_INDEX]),f=(i*u+t.RIGHT_FOOT_CENTER)*4;e[f]=I[0],e[f+1]=I[1],e[f+2]=I[2],e[f+3]=I[3];let O=g(e,i,[t.LEFT_SHOULDER,t.RIGHT_SHOULDER,t.LEFT_HIP,t.RIGHT_HIP]),K=(i*u+t.TORSO_CENTER)*4;e[K]=O[0],e[K+1]=O[1],e[K+2]=O[2],e[K+3]=O[3]}let E=Math.ceil(T/N);a.updateTextures({u_poseLandmarksTex:{data:e,width:N,height:E}})}function W(o){if(!o.landmarks||!e)return;let n=o.landmarks.length;Q(o.landmarks),J(o.segmentationMasks).catch(T=>{console.warn("[Pose Plugin] Mask texture update error:",T)}),a.updateUniforms({u_nPoses:n}),s?.onResults?.(o)}a.registerHook("init",async()=>{a.initializeTexture("u_poseMask",l),a.initializeUniform("u_maxPoses","int",B),a.initializeUniform("u_nPoses","int",0);let o=B*u;$=Math.ceil(o/N);let n=N*$*4;e=new Float32Array(n),a.initializeTexture("u_poseLandmarksTex",{data:e,width:N,height:$},{internalFormat:k.RGBA32F,type:k.FLOAT,minFilter:k.NEAREST,magFilter:k.NEAREST}),await q()}),a.registerHook("updateTextures",async o=>{let n=o[_];if(!(!n||(b.get(_)!==n&&(v=-1),b.set(_,n),!L)))try{let E=n instanceof HTMLVideoElement?"VIDEO":"IMAGE";if(S!==E&&(S=E,await L.setOptions({runningMode:S})),n instanceof HTMLVideoElement){if(n.videoWidth===0||n.videoHeight===0||n.readyState<2)return;if(n.currentTime!==v){v=n.currentTime;let i=performance.now(),d=L.detectForVideo(n,i);W(d)}}else if(n instanceof HTMLImageElement||n instanceof HTMLCanvasElement){if(n.width===0||n.height===0)return;let i=L.detect(n);W(i)}}catch(E){console.error("[Pose Plugin] Pose detection error:",E)}}),a.registerHook("destroy",()=>{L&&(L.close(),L=null),U=null,b.clear(),l.remove(),e=null}),V(`
1
+ "use strict";var it=Object.create;var z=Object.defineProperty;var rt=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var nt=Object.getPrototypeOf,ot=Object.prototype.hasOwnProperty;var at=(a,t)=>{for(var e in t)z(a,e,{get:t[e],enumerable:!0})},j=(a,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of st(t))!ot.call(a,r)&&r!==e&&z(a,r,{get:()=>t[r],enumerable:!(i=rt(t,r))||i.enumerable});return a};var ht=(a,t,e)=>(e=a!=null?it(nt(a)):{},j(t||!a||!a.__esModule?z(e,"default",{value:a,enumerable:!0}):e,a)),lt=a=>j(z({},"__esModule",{value:!0}),a);var vt={};at(vt,{default:()=>Lt});module.exports=lt(vt);var ut=`#version 300 es
2
+ in vec2 aPosition;
3
+ out vec2 v_uv;
4
+ void main() {
5
+ v_uv = aPosition * 0.5 + 0.5;
6
+ gl_Position = vec4(aPosition, 0.0, 1.0);
7
+ }
8
+ `,ct=33.333333333333336,Y=Symbol("u_history");function mt(a,t){if(!t?.length)return a;let e=a.split(`
9
+ `),i=e.findLastIndex(r=>{let s=r.trimStart();return s.startsWith("precision ")||s.startsWith("#version ")})+1;return e.splice(i,0,...t),e.join(`
10
+ `)}function q(a){return a instanceof WebGLTexture?{width:0,height:0}:a instanceof HTMLVideoElement?{width:a.videoWidth,height:a.videoHeight}:a instanceof HTMLImageElement?{width:a.naturalWidth??a.width,height:a.naturalHeight??a.height}:{width:a.width,height:a.height}}function U(a){return typeof a=="symbol"?a.description??"":a}var X=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;debug;constructor(t,e={}){if(this.canvas=e.canvas||document.createElement("canvas"),!e.canvas){this.isInternalCanvas=!0;let r=this.canvas;r.style.position="fixed",r.style.inset="0",r.style.height="100dvh",r.style.width="100dvw",document.body.appendChild(r)}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.historyDepth=e.history??0,this.debug=e.debug??(typeof process<"u"&&!1),this.animationFrameId=null,this.resolutionObserver=new MutationObserver(()=>this.updateResolution()),this.resizeObserver=new ResizeObserver(()=>this.throttledHandleResize());let i=[];if(e.plugins){let r={gl:this.gl,uniforms:this.uniforms,textures:this.textures,canvas:this.canvas,reserveTextureUnit:this.reserveTextureUnit.bind(this),releaseTextureUnit:this.releaseTextureUnit.bind(this),injectGLSL:s=>{i.push(s)}};Object.defineProperty(r,"program",{get:()=>this.program,enumerable:!0,configurable:!0}),e.plugins.forEach(s=>s(this,r))}this.fragmentShaderSrc=mt(t,i),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=ut;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),i=this.createShader(this.gl.FRAGMENT_SHADER,this.fragmentShaderSrc);if(this.gl.attachShader(this.program,e),this.gl.attachShader(this.program,i),this.gl.linkProgram(this.program),this.gl.deleteShader(e),this.gl.deleteShader(i),!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,{history:this.historyDepth}),this.hooks.get("init")?.forEach(r=>r.call(this))}createShader(t,e){let i=this.gl.createShader(t);if(this.gl.shaderSource(i,e),this.gl.compileShader(i),!this.gl.getShaderParameter(i,this.gl.COMPILE_STATUS))throw console.error("Shader compilation failed:",e),console.error(this.gl.getShaderInfoLog(i)),this.gl.deleteShader(i),new Error("Shader compilation failed");return i}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+ct-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,i=this.canvas.clientHeight*t;this.isInternalCanvas&&(this.canvas.width!==e||this.canvas.height!==i)&&(this.canvas.width=e,this.canvas.height=i),this.onResize?.(e,i)}addEventListeners(){let t=this.canvas,e=(r,s)=>{if(!this.uniforms.has("u_cursor"))return;let d=t.getBoundingClientRect();this.cursorPosition[0]=(r-d.left)/d.width,this.cursorPosition[1]=1-(s-d.top)/d.height,this.updateUniforms({u_cursor:this.cursorPosition})},i=(r,s,d)=>{if(this.uniforms.has("u_click")){if(this.isMouseDown=r,r){let l=t.getBoundingClientRect(),c=s,f=d;this.clickPosition[0]=(c-l.left)/l.width,this.clickPosition[1]=1-(f-l.top)/l.height}this.updateUniforms({u_click:[...this.clickPosition,this.isMouseDown?1:0]})}};this.eventListeners.set("mousemove",r=>{let s=r;this.isTouchDevice||e(s.clientX,s.clientY)}),this.eventListeners.set("mousedown",r=>{let s=r;this.isTouchDevice||s.button===0&&(this.isMouseDown=!0,i(!0,s.clientX,s.clientY))}),this.eventListeners.set("mouseup",r=>{let s=r;this.isTouchDevice||s.button===0&&i(!1)}),this.eventListeners.set("touchmove",r=>{let s=r;s.touches.length>0&&e(s.touches[0].clientX,s.touches[0].clientY)}),this.eventListeners.set("touchstart",r=>{let s=r;this.isTouchDevice=!0,s.touches.length>0&&(e(s.touches[0].clientX,s.touches[0].clientY),i(!0,s.touches[0].clientX,s.touches[0].clientY))}),this.eventListeners.set("touchend",r=>{r.touches.length===0&&i(!1)}),this.eventListeners.forEach((r,s)=>{t.addEventListener(s,r)})}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.hooks.get("updateResolution")?.forEach(e=>e.call(this))}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)}clearHistoryTextureLayers(t){if(!t.history)return;let e=t.options?.type??this.gl.UNSIGNED_BYTE,i=e===this.gl.FLOAT?new Float32Array(t.width*t.height*4):new Uint8Array(t.width*t.height*4);this.gl.activeTexture(this.gl.TEXTURE0+t.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,t.texture);for(let r=0;r<t.history.depth;++r)this.gl.texSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,0,0,r,t.width,t.height,1,t.options?.format??this.gl.RGBA,e,i)}initializeUniform(t,e,i,r){let s=r?.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(s&&!(Array.isArray(i)&&i.length===s))throw new Error(`${t} array length mismatch: must initialize with ${s} elements.`);let d=this.gl.getUniformLocation(this.program,t);if(!d&&s&&(d=this.gl.getUniformLocation(this.program,`${t}[0]`)),!d){this.log(`${t} not found in fragment shader. Skipping initialization.`);return}let l=s?i[0]:i,c=Array.isArray(l)?l.length:1;this.uniforms.set(t,{type:e,length:c,location:d,arrayLength:s});try{this.updateUniforms({[t]:i})}catch(f){throw this.uniforms.delete(t),f}this.hooks.get("initializeUniform")?.forEach(f=>f.call(this,...arguments))}log(...t){this.debug&&console.debug(...t)}updateUniforms(t,e){this.gl.useProgram(this.program),Object.entries(t).forEach(([i,r])=>{let s=this.uniforms.get(i);if(!s){this.log(`${i} not found in fragment shader. Skipping update.`);return}let d=`uniform${s.length}${s.type.charAt(0)}`;if(s.arrayLength){if(!Array.isArray(r))throw new Error(`${i} is an array, but the value passed to updateUniforms is not an array.`);let l=r.length;if(!l)return;if(l>s.arrayLength)throw new Error(`${i} received ${l} values, but maximum length is ${s.arrayLength}.`);if(r.some(m=>(Array.isArray(m)?m.length:1)!==s.length))throw new Error(`Tried to update ${i} with some elements that are not length ${s.length}.`);let c=new(s.type==="float"?Float32Array:Int32Array)(r.flat()),f=s.location;if(e?.startIndex){let m=this.gl.getUniformLocation(this.program,`${i}[${e.startIndex}]`);if(!m)throw new Error(`${i}[${e.startIndex}] not found in fragment shader. Did you pass an invalid startIndex?`);f=m}this.gl[d+"v"](s.location,c)}else{if(Array.isArray(r)||(r=[r]),r.length!==s.length)throw new Error(`Invalid uniform value length: ${r.length}. Expected ${s.length}.`);this.gl[d](s.location,...r)}}),this.hooks.get("updateUniforms")?.forEach(i=>i.call(this,...arguments))}createTexture(t,e,i){let{width:r,height:s}=e,d=e.history?.depth??0,l=this.gl.createTexture();if(!l)throw new Error("Failed to create texture");let c=i?.unitIndex;if(typeof c!="number")try{c=this.reserveTextureUnit(t)}catch(T){throw this.gl.deleteTexture(l),T}let f=d>0,m=f?this.gl.TEXTURE_2D_ARRAY:this.gl.TEXTURE_2D;if(this.gl.activeTexture(this.gl.TEXTURE0+c),this.gl.bindTexture(m,l),this.gl.texParameteri(m,this.gl.TEXTURE_WRAP_S,i?.wrapS??this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(m,this.gl.TEXTURE_WRAP_T,i?.wrapT??this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(m,this.gl.TEXTURE_MIN_FILTER,i?.minFilter??this.gl.LINEAR),this.gl.texParameteri(m,this.gl.TEXTURE_MAG_FILTER,i?.magFilter??this.gl.LINEAR),f){let T=i?.type??this.gl.UNSIGNED_BYTE,_=i?.internalFormat??(T===this.gl.FLOAT?this.gl.RGBA32F:this.gl.RGBA8);this.gl.texStorage3D(m,1,_,r,s,d)}return{texture:l,unitIndex:c}}_initializeTexture(t,e,i){if(this.textures.has(t))throw new Error(`Texture '${U(t)}' is already initialized.`);let{history:r=0,...s}=i??{},{width:d,height:l}=q(e);if(!d||!l)throw new Error("Texture source must have valid dimensions");let c={width:d,height:l};r>0&&(c.history={depth:r,writeIndex:0});let{texture:f,unitIndex:m}=this.createTexture(t,c,s),T={texture:f,unitIndex:m,...c,options:s};r>0&&(this.initializeUniform(`${U(t)}FrameOffset`,"int",0),this.clearHistoryTextureLayers(T)),this.textures.set(t,T),this.updateTexture(t,e);let _=this.gl.getUniformLocation(this.program,U(t));_&&this.gl.uniform1i(_,m)}initializeTexture(t,e,i){this._initializeTexture(t,e,i),this.hooks.get("initializeTexture")?.forEach(r=>r.call(this,...arguments))}updateTextures(t){this.hooks.get("updateTextures")?.forEach(e=>e.call(this,...arguments)),Object.entries(t).forEach(([e,i])=>{this.updateTexture(e,i)})}updateTexture(t,e){let i=this.textures.get(t);if(!i)throw new Error(`Texture '${U(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:s}=q(e);if(!r||!s)return;let d="isPartial"in e&&e.isPartial;if(!d&&(i.width!==r||i.height!==s)){this.gl.deleteTexture(i.texture),i.width=r,i.height=s;let{texture:m}=this.createTexture(t,i,{...i.options,unitIndex:i.unitIndex});i.texture=m,i.history&&(i.history.writeIndex=0,this.clearHistoryTextureLayers(i))}let l="data"in e&&e.data,c=!l&&!i.options?.preserveY,f=this.gl.getParameter(this.gl.UNPACK_FLIP_Y_WEBGL);if(i.history){let m=t===Y;this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY,i.texture),m?this.gl.copyTexSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,0,0,i.history.writeIndex,0,0,r,s):(this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,c),this.gl.texSubImage3D(this.gl.TEXTURE_2D_ARRAY,0,0,0,i.history.writeIndex,r,s,1,i.options?.format??this.gl.RGBA,i.options?.type??this.gl.UNSIGNED_BYTE,e.data??e),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,f));let T=`${U(t)}FrameOffset`;this.updateUniforms({[T]: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);let m=i.options?.format??this.gl.RGBA,T=i.options?.type??this.gl.UNSIGNED_BYTE;if(d)this.gl.texSubImage2D(this.gl.TEXTURE_2D,0,e.x??0,e.y??0,r,s,m,T,e.data);else{let _=i.options?.internalFormat??(l?T===this.gl.FLOAT?this.gl.RGBA32F:this.gl.RGBA8:this.gl.RGBA);this.gl.texImage2D(this.gl.TEXTURE_2D,0,_,r,s,0,m,T,e.data??e)}this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,f)}}draw(t=!0){let e=this.gl;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,e.drawingBufferWidth,e.drawingBufferHeight),t&&e.clear(e.COLOR_BUFFER_BIT),e.drawArrays(e.TRIANGLES,0,6)}step(t){this.uniforms.has("u_time")&&this.updateUniforms({u_time:t}),this.uniforms.has("u_frame")&&this.updateUniforms({u_frame:this.frame}),this.draw(),this.textures.get(Y)&&this.updateTexture(Y,this.canvas),this.hooks.get("step")?.forEach(e=>e.call(this,t,this.frame)),++this.frame}play(t){this.pause();let e=i=>{i=(i-this.startTime)/1e3,this.step(i),this.animationFrameId=requestAnimationFrame(e),t&&t(i,this.frame)};this.animationFrameId=requestAnimationFrame(e)}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.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()}},Z=X;var v=33,dt=6,p=v+dt,o={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:v,LEFT_HAND_CENTER:v+1,RIGHT_HAND_CENTER:v+2,LEFT_FOOT_CENTER:v+3,RIGHT_FOOT_CENTER:v+4,TORSO_CENTER:v+5},gt=Array.from({length:v},(a,t)=>t),ft=[o.LEFT_WRIST,o.LEFT_PINKY,o.LEFT_THUMB,o.LEFT_INDEX],Tt=[o.RIGHT_WRIST,o.RIGHT_PINKY,o.RIGHT_THUMB,o.RIGHT_INDEX],Et=[o.LEFT_ANKLE,o.LEFT_HEEL,o.LEFT_FOOT_INDEX],pt=[o.RIGHT_ANKLE,o.RIGHT_HEEL,o.RIGHT_FOOT_INDEX],_t=[o.LEFT_SHOULDER,o.RIGHT_SHOULDER,o.LEFT_HIP,o.RIGHT_HIP],J={data:new Uint8Array(4),width:1,height:1};function xt(a){let{textureName:t,options:e}=a,i="https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task";return function(r,s){let{injectGLSL:d,gl:l}=s,c=null,f=null,m=-1,T="VIDEO",_=new Map,W=e?.maxPoses??1,b=512,$=0,n=null,K=new OffscreenCanvas(1,1),E=null;async function Q(){try{let{FilesetResolver:u,PoseLandmarker:h}=await import("@mediapipe/tasks-vision");f=await u.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"),c=await h.createFromOptions(f,{baseOptions:{modelAssetPath:e?.modelPath||i,delegate:"GPU"},canvas:K,runningMode:T,numPoses:e?.maxPoses??1,minPoseDetectionConfidence:e?.minPoseDetectionConfidence??.5,minPosePresenceConfidence:e?.minPosePresenceConfidence??.5,minTrackingConfidence:e?.minTrackingConfidence??.5,outputSegmentationMasks:!0})}catch(u){throw console.error("[Pose Plugin] Failed to initialize:",u),u}}function w(u,h,R){let x=1/0,g=-1/0,D=1/0,I=-1/0,y=0,A=0;for(let N of R){let L=(h*p+N)*4,P=u[L],F=u[L+1];x=Math.min(x,P),g=Math.max(g,P),D=Math.min(D,F),I=Math.max(I,F),y+=u[L+2],A+=u[L+3]}let S=(x+g)/2,O=(D+I)/2,H=y/R.length,C=A/R.length;return[S,O,H,C]}function tt(u){if(!(!u||u.length===0||!E)){for(let h=0;h<u.length;++h){let R=u[h];E.updateTextures({u_mask:R.getAsWebGLTexture()}),E.updateUniforms({u_poseIndex:(h+1)/W}),E.draw(h===0)}r.updateTextures({u_poseMask:K})}}function et(u){if(!n)return;let h=u.length,R=h*p;for(let g=0;g<h;++g){let D=u[g];for(let G=0;G<v;++G){let k=D[G],B=(g*p+G)*4;n[B]=k.x,n[B+1]=1-k.y,n[B+2]=k.z??0,n[B+3]=k.visibility??1}let I=w(n,g,gt),y=(g*p+o.BODY_CENTER)*4;n[y]=I[0],n[y+1]=I[1],n[y+2]=I[2],n[y+3]=I[3];let A=w(n,g,ft),S=(g*p+o.LEFT_HAND_CENTER)*4;n[S]=A[0],n[S+1]=A[1],n[S+2]=A[2],n[S+3]=A[3];let O=w(n,g,Tt),H=(g*p+o.RIGHT_HAND_CENTER)*4;n[H]=O[0],n[H+1]=O[1],n[H+2]=O[2],n[H+3]=O[3];let C=w(n,g,Et),N=(g*p+o.LEFT_FOOT_CENTER)*4;n[N]=C[0],n[N+1]=C[1],n[N+2]=C[2],n[N+3]=C[3];let L=w(n,g,pt),P=(g*p+o.RIGHT_FOOT_CENTER)*4;n[P]=L[0],n[P+1]=L[1],n[P+2]=L[2],n[P+3]=L[3];let F=w(n,g,_t),M=(g*p+o.TORSO_CENTER)*4;n[M]=F[0],n[M+1]=F[1],n[M+2]=F[2],n[M+3]=F[3]}let x=Math.ceil(R/b);r.updateTextures({u_poseLandmarksTex:{data:n,width:b,height:x,isPartial:!0}})}function V(u){if(!u.landmarks||!n)return;E||(E=new Z(`#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",J),E.initializeUniform("u_poseIndex","float",0));let h=u.landmarks.length;et(u.landmarks),tt(u.segmentationMasks),r.updateUniforms({u_nPoses:h}),e?.onResults?.(u)}r.registerHook("init",async()=>{r.initializeTexture("u_poseMask",J,{preserveY:!0}),r.initializeUniform("u_maxPoses","int",W),r.initializeUniform("u_nPoses","int",0);let u=W*p;$=Math.ceil(u/b);let h=b*$*4;n=new Float32Array(h),r.initializeTexture("u_poseLandmarksTex",{data:n,width:b,height:$},{internalFormat:l.RGBA32F,type:l.FLOAT,minFilter:l.NEAREST,magFilter:l.NEAREST}),await Q()}),r.registerHook("updateTextures",async u=>{let h=u[t];if(!(!h||(_.get(t)!==h&&(m=-1),_.set(t,h),!c)))try{let x=h instanceof HTMLVideoElement?"VIDEO":"IMAGE";if(T!==x&&(T=x,await c.setOptions({runningMode:T})),h instanceof HTMLVideoElement){if(h.videoWidth===0||h.videoHeight===0||h.readyState<2)return;if(h.currentTime!==m){m=h.currentTime;let g=c.detectForVideo(h,performance.now());V(g)}}else if(h instanceof HTMLImageElement||h instanceof HTMLCanvasElement){if(h.width===0||h.height===0)return;let g=c.detect(h);V(g)}}catch(x){console.error("[Pose Plugin] Detection error:",x)}}),r.registerHook("destroy",()=>{c&&(c.close(),c=null),E&&(E.destroy(),E=null),f=null,_.clear(),n=null}),d(`
2
22
  uniform int u_maxPoses;
3
23
  uniform int u_nPoses;
4
24
  uniform sampler2D u_poseLandmarksTex;
5
25
  uniform sampler2D u_poseMask;
6
26
 
7
- #define POSE_LANDMARK_LEFT_EYE ${t.LEFT_EYE}
8
- #define POSE_LANDMARK_RIGHT_EYE ${t.RIGHT_EYE}
9
- #define POSE_LANDMARK_LEFT_SHOULDER ${t.LEFT_SHOULDER}
10
- #define POSE_LANDMARK_RIGHT_SHOULDER ${t.RIGHT_SHOULDER}
11
- #define POSE_LANDMARK_LEFT_ELBOW ${t.LEFT_ELBOW}
12
- #define POSE_LANDMARK_RIGHT_ELBOW ${t.RIGHT_ELBOW}
13
- #define POSE_LANDMARK_LEFT_HIP ${t.LEFT_HIP}
14
- #define POSE_LANDMARK_RIGHT_HIP ${t.RIGHT_HIP}
15
- #define POSE_LANDMARK_LEFT_KNEE ${t.LEFT_KNEE}
16
- #define POSE_LANDMARK_RIGHT_KNEE ${t.RIGHT_KNEE}
17
- #define POSE_LANDMARK_BODY_CENTER ${t.BODY_CENTER}
18
- #define POSE_LANDMARK_LEFT_HAND_CENTER ${t.LEFT_HAND_CENTER}
19
- #define POSE_LANDMARK_RIGHT_HAND_CENTER ${t.RIGHT_HAND_CENTER}
20
- #define POSE_LANDMARK_LEFT_FOOT_CENTER ${t.LEFT_FOOT_CENTER}
21
- #define POSE_LANDMARK_RIGHT_FOOT_CENTER ${t.RIGHT_FOOT_CENTER}
22
- #define POSE_LANDMARK_TORSO_CENTER ${t.TORSO_CENTER}
27
+ #define POSE_LANDMARK_LEFT_EYE ${o.LEFT_EYE}
28
+ #define POSE_LANDMARK_RIGHT_EYE ${o.RIGHT_EYE}
29
+ #define POSE_LANDMARK_LEFT_SHOULDER ${o.LEFT_SHOULDER}
30
+ #define POSE_LANDMARK_RIGHT_SHOULDER ${o.RIGHT_SHOULDER}
31
+ #define POSE_LANDMARK_LEFT_ELBOW ${o.LEFT_ELBOW}
32
+ #define POSE_LANDMARK_RIGHT_ELBOW ${o.RIGHT_ELBOW}
33
+ #define POSE_LANDMARK_LEFT_HIP ${o.LEFT_HIP}
34
+ #define POSE_LANDMARK_RIGHT_HIP ${o.RIGHT_HIP}
35
+ #define POSE_LANDMARK_LEFT_KNEE ${o.LEFT_KNEE}
36
+ #define POSE_LANDMARK_RIGHT_KNEE ${o.RIGHT_KNEE}
37
+ #define POSE_LANDMARK_BODY_CENTER ${o.BODY_CENTER}
38
+ #define POSE_LANDMARK_LEFT_HAND_CENTER ${o.LEFT_HAND_CENTER}
39
+ #define POSE_LANDMARK_RIGHT_HAND_CENTER ${o.RIGHT_HAND_CENTER}
40
+ #define POSE_LANDMARK_LEFT_FOOT_CENTER ${o.LEFT_FOOT_CENTER}
41
+ #define POSE_LANDMARK_RIGHT_FOOT_CENTER ${o.RIGHT_FOOT_CENTER}
42
+ #define POSE_LANDMARK_TORSO_CENTER ${o.TORSO_CENTER}
23
43
 
24
44
  vec4 poseLandmark(int poseIndex, int landmarkIndex) {
25
- int i = poseIndex * ${u} + landmarkIndex;
26
- int x = i % ${N};
27
- int y = i / ${N};
45
+ int i = poseIndex * ${p} + landmarkIndex;
46
+ int x = i % ${b};
47
+ int y = i / ${b};
28
48
  return texelFetch(u_poseLandmarksTex, ivec2(x, y), 0);
29
49
  }
30
- float inBody(vec2 pos) { return texture(u_poseMask, pos).g; }`)}}var Te=_e;
50
+
51
+ vec2 poseAt(vec2 pos) {
52
+ vec4 mask = texture(u_poseMask, pos);
53
+ float poseIndex = floor(mask.b * float(u_maxPoses) + 0.5) - 1.0;
54
+ return vec2(mask.g, poseIndex);
55
+ }
56
+
57
+ float inPose(vec2 pos) {
58
+ float pose = poseAt(pos).x;
59
+ return step(0.0, pose);
60
+ }`)}}var Lt=xt;
31
61
  //# sourceMappingURL=pose.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugins/pose.ts"],"sourcesContent":["import ShaderPad, { PluginContext, TextureSource } from '../index';\nimport type { PoseLandmarker, PoseLandmarkerResult, NormalizedLandmark } from '@mediapipe/tasks-vision';\n\nexport interface PosePluginOptions {\n\tmodelPath?: string;\n\tmaxPoses?: number;\n\tminPoseDetectionConfidence?: number;\n\tminPosePresenceConfidence?: number;\n\tminTrackingConfidence?: number;\n\toutputSegmentationMasks?: boolean;\n\tonResults?: (results: PoseLandmarkerResult) => void;\n}\n\nconst STANDARD_LANDMARK_COUNT = 33; // See https://ai.google.dev/edge/mediapipe/solutions/vision/pose_landmarker#pose_landmarker_model.\nconst CUSTOM_LANDMARK_COUNT = 6;\nconst LANDMARK_COUNT = STANDARD_LANDMARK_COUNT + CUSTOM_LANDMARK_COUNT;\nconst LANDMARK_INDICES = {\n\t// Standard landmarks.\n\tLEFT_EYE: 2,\n\tRIGHT_EYE: 5,\n\tLEFT_SHOULDER: 11,\n\tRIGHT_SHOULDER: 12,\n\tLEFT_ELBOW: 13,\n\tRIGHT_ELBOW: 14,\n\tLEFT_HIP: 23,\n\tRIGHT_HIP: 24,\n\tLEFT_KNEE: 25,\n\tRIGHT_KNEE: 26,\n\tLEFT_WRIST: 15,\n\tRIGHT_WRIST: 16,\n\tLEFT_PINKY: 17,\n\tRIGHT_PINKY: 18,\n\tLEFT_INDEX: 19,\n\tRIGHT_INDEX: 20,\n\tLEFT_THUMB: 21,\n\tRIGHT_THUMB: 22,\n\tLEFT_ANKLE: 27,\n\tRIGHT_ANKLE: 28,\n\tLEFT_HEEL: 29,\n\tRIGHT_HEEL: 30,\n\tLEFT_FOOT_INDEX: 31,\n\tRIGHT_FOOT_INDEX: 32,\n\t// Custom landmarks.\n\tBODY_CENTER: STANDARD_LANDMARK_COUNT,\n\tLEFT_HAND_CENTER: STANDARD_LANDMARK_COUNT + 1,\n\tRIGHT_HAND_CENTER: STANDARD_LANDMARK_COUNT + 2,\n\tLEFT_FOOT_CENTER: STANDARD_LANDMARK_COUNT + 3,\n\tRIGHT_FOOT_CENTER: STANDARD_LANDMARK_COUNT + 4,\n\tTORSO_CENTER: STANDARD_LANDMARK_COUNT + 5,\n};\n\nfunction pose(config: { textureName: string; options?: PosePluginOptions }) {\n\tconst { textureName, options } = config;\n\tconst defaultModelPath =\n\t\t'https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task';\n\n\treturn function (shaderPad: ShaderPad, context: PluginContext) {\n\t\tconst { injectGLSL, gl } = context;\n\n\t\tlet poseLandmarker: PoseLandmarker | 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 maxPoses = options?.maxPoses ?? 1;\n\n\t\tconst LANDMARKS_TEXTURE_WIDTH = 512;\n\t\tlet landmarksTextureHeight = 0;\n\t\tlet landmarksDataArray: Float32Array | null = null;\n\n\t\tconst maskWidth = 512;\n\t\tconst maskHeight = 512;\n\t\tconst poseMaskCanvas = document.createElement('canvas');\n\t\tposeMaskCanvas.width = maskWidth;\n\t\tposeMaskCanvas.height = maskHeight;\n\t\tconst poseMaskCtx = poseMaskCanvas.getContext('2d')!;\n\t\tconst segmentationCanvas = document.createElement('canvas');\n\t\tconst segmentationCtx = segmentationCanvas.getContext('2d')!;\n\t\tposeMaskCtx.globalCompositeOperation = segmentationCtx.globalCompositeOperation = 'lighten'; // Keep the highest value of each channel.\n\n\t\tasync function initializePoseLandmarker() {\n\t\t\ttry {\n\t\t\t\tconst { FilesetResolver, PoseLandmarker } = 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\tposeLandmarker = await PoseLandmarker.createFromOptions(vision, {\n\t\t\t\t\tbaseOptions: {\n\t\t\t\t\t\tmodelAssetPath: options?.modelPath || defaultModelPath,\n\t\t\t\t\t},\n\t\t\t\t\trunningMode,\n\t\t\t\t\tnumPoses: options?.maxPoses ?? 1,\n\t\t\t\t\tminPoseDetectionConfidence: options?.minPoseDetectionConfidence ?? 0.5,\n\t\t\t\t\tminPosePresenceConfidence: options?.minPosePresenceConfidence ?? 0.5,\n\t\t\t\t\tminTrackingConfidence: options?.minTrackingConfidence ?? 0.5,\n\t\t\t\t\toutputSegmentationMasks: options?.outputSegmentationMasks ?? true,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Pose Plugin] Failed to initialize Pose Landmarker:', 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\tposeIdx: number,\n\t\t\tlandmarkIndices: 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 = (poseIdx * 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\tasync function updateMaskTexture(segmentationMasks?: any[]) {\n\t\t\tif (!poseLandmarker || !landmarksDataArray) {\n\t\t\t\tconsole.warn('[Pose Plugin] Cannot update mask: poseLandmarker or landmarksDataArray missing');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tposeMaskCtx.clearRect(0, 0, poseMaskCanvas.width, poseMaskCanvas.height);\n\n\t\t\t\t// Draw the segmentation masks.\n\t\t\t\tif (segmentationMasks && segmentationMasks.length > 0) {\n\t\t\t\t\tsegmentationMasks.forEach(mask => {\n\t\t\t\t\t\tif (!mask) return;\n\n\t\t\t\t\t\tconst { width, height } = mask;\n\t\t\t\t\t\tconst maskData = mask.getAsUint8Array();\n\t\t\t\t\t\tconst pixelCount = width * height;\n\t\t\t\t\t\tconst outputData = new Uint8ClampedArray(pixelCount * 4);\n\n\t\t\t\t\t\tfor (let i = 0; i < pixelCount; i++) {\n\t\t\t\t\t\t\toutputData[i * 4 + 1] = maskData[i]; // G (body mask)\n\t\t\t\t\t\t\toutputData[i * 4 + 3] = 255; // A (required for compositing)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rgbaMask = new ImageData(outputData, width, height);\n\n\t\t\t\t\t\t// Resize mask to canvas size if needed.\n\t\t\t\t\t\tif (width === poseMaskCanvas.width && height === poseMaskCanvas.height) {\n\t\t\t\t\t\t\tposeMaskCtx.putImageData(rgbaMask, 0, 0);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (segmentationCanvas.width !== width) segmentationCanvas.width = width;\n\t\t\t\t\t\t\tif (segmentationCanvas.height !== height) segmentationCanvas.height = height;\n\t\t\t\t\t\t\tsegmentationCtx.putImageData(rgbaMask, 0, 0);\n\t\t\t\t\t\t\tposeMaskCtx.drawImage(\n\t\t\t\t\t\t\t\tsegmentationCanvas,\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tposeMaskCanvas.width,\n\t\t\t\t\t\t\t\tposeMaskCanvas.height\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tshaderPad.updateTextures({ u_poseMask: poseMaskCanvas });\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Pose Plugin] Failed to generate mask texture:', error);\n\t\t\t}\n\t\t}\n\n\t\tfunction updateLandmarksTexture(poses: NormalizedLandmark[][]) {\n\t\t\tif (!landmarksDataArray) return;\n\n\t\t\tconst nPoses = poses.length;\n\t\t\tconst totalLandmarks = nPoses * LANDMARK_COUNT;\n\n\t\t\tfor (let poseIdx = 0; poseIdx < nPoses; ++poseIdx) {\n\t\t\t\tconst landmarks = poses[poseIdx];\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 = (poseIdx * LANDMARK_COUNT + lmIdx) * 4;\n\t\t\t\t\tlandmarksDataArray[dataIdx] = landmark.x; // R (X)\n\t\t\t\t\tlandmarksDataArray[dataIdx + 1] = 1 - landmark.y; // G (Inverted Y)\n\t\t\t\t\tlandmarksDataArray[dataIdx + 2] = landmark.z ?? 0; // B (Z)\n\t\t\t\t\tlandmarksDataArray[dataIdx + 3] = landmark.visibility ?? 1; // A (Visibility)\n\t\t\t\t}\n\n\t\t\t\t// Body center (landmark 33) - calculated from all standard landmarks\n\t\t\t\tconst bodyCenter = calculateBoundingBoxCenter(\n\t\t\t\t\tlandmarksDataArray,\n\t\t\t\t\tposeIdx,\n\t\t\t\t\tArray.from({ length: STANDARD_LANDMARK_COUNT }, (_, i) => i)\n\t\t\t\t);\n\t\t\t\tconst bodyCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.BODY_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[bodyCenterIdx] = bodyCenter[0];\n\t\t\t\tlandmarksDataArray[bodyCenterIdx + 1] = bodyCenter[1];\n\t\t\t\tlandmarksDataArray[bodyCenterIdx + 2] = bodyCenter[2];\n\t\t\t\tlandmarksDataArray[bodyCenterIdx + 3] = bodyCenter[3];\n\n\t\t\t\t// Left hand center (landmark 34) - center of pinky, thumb, wrist, index.\n\t\t\t\tconst leftHandCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, [\n\t\t\t\t\tLANDMARK_INDICES.LEFT_WRIST,\n\t\t\t\t\tLANDMARK_INDICES.LEFT_PINKY,\n\t\t\t\t\tLANDMARK_INDICES.LEFT_THUMB,\n\t\t\t\t\tLANDMARK_INDICES.LEFT_INDEX,\n\t\t\t\t]);\n\t\t\t\tconst leftHandCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.LEFT_HAND_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[leftHandCenterIdx] = leftHandCenter[0];\n\t\t\t\tlandmarksDataArray[leftHandCenterIdx + 1] = leftHandCenter[1];\n\t\t\t\tlandmarksDataArray[leftHandCenterIdx + 2] = leftHandCenter[2];\n\t\t\t\tlandmarksDataArray[leftHandCenterIdx + 3] = leftHandCenter[3];\n\n\t\t\t\t// Right hand center (landmark 35) - center of pinky, thumb, wrist, index.\n\t\t\t\tconst rightHandCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, [\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_WRIST,\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_PINKY,\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_THUMB,\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_INDEX,\n\t\t\t\t]);\n\t\t\t\tconst rightHandCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.RIGHT_HAND_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[rightHandCenterIdx] = rightHandCenter[0];\n\t\t\t\tlandmarksDataArray[rightHandCenterIdx + 1] = rightHandCenter[1];\n\t\t\t\tlandmarksDataArray[rightHandCenterIdx + 2] = rightHandCenter[2];\n\t\t\t\tlandmarksDataArray[rightHandCenterIdx + 3] = rightHandCenter[3];\n\n\t\t\t\t// Left foot center (landmark 36) - center of ankle, heel, foot index\n\t\t\t\tconst leftFootCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, [\n\t\t\t\t\tLANDMARK_INDICES.LEFT_ANKLE,\n\t\t\t\t\tLANDMARK_INDICES.LEFT_HEEL,\n\t\t\t\t\tLANDMARK_INDICES.LEFT_FOOT_INDEX,\n\t\t\t\t]);\n\t\t\t\tconst leftFootCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.LEFT_FOOT_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[leftFootCenterIdx] = leftFootCenter[0];\n\t\t\t\tlandmarksDataArray[leftFootCenterIdx + 1] = leftFootCenter[1];\n\t\t\t\tlandmarksDataArray[leftFootCenterIdx + 2] = leftFootCenter[2];\n\t\t\t\tlandmarksDataArray[leftFootCenterIdx + 3] = leftFootCenter[3];\n\n\t\t\t\t// Right foot center (landmark 37) - center of ankle, heel, foot index\n\t\t\t\tconst rightFootCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, [\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_ANKLE,\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_HEEL,\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_FOOT_INDEX,\n\t\t\t\t]);\n\t\t\t\tconst rightFootCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.RIGHT_FOOT_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[rightFootCenterIdx] = rightFootCenter[0];\n\t\t\t\tlandmarksDataArray[rightFootCenterIdx + 1] = rightFootCenter[1];\n\t\t\t\tlandmarksDataArray[rightFootCenterIdx + 2] = rightFootCenter[2];\n\t\t\t\tlandmarksDataArray[rightFootCenterIdx + 3] = rightFootCenter[3];\n\n\t\t\t\t// Torso center (landmark 38) - center of shoulders and hips\n\t\t\t\tconst torsoCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, [\n\t\t\t\t\tLANDMARK_INDICES.LEFT_SHOULDER,\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_SHOULDER,\n\t\t\t\t\tLANDMARK_INDICES.LEFT_HIP,\n\t\t\t\t\tLANDMARK_INDICES.RIGHT_HIP,\n\t\t\t\t]);\n\t\t\t\tconst torsoCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.TORSO_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[torsoCenterIdx] = torsoCenter[0];\n\t\t\t\tlandmarksDataArray[torsoCenterIdx + 1] = torsoCenter[1];\n\t\t\t\tlandmarksDataArray[torsoCenterIdx + 2] = torsoCenter[2];\n\t\t\t\tlandmarksDataArray[torsoCenterIdx + 3] = torsoCenter[3];\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_poseLandmarksTex: {\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},\n\t\t\t});\n\t\t}\n\n\t\tfunction processPoseResults(result: PoseLandmarkerResult) {\n\t\t\tif (!result.landmarks || !landmarksDataArray) return;\n\n\t\t\tconst nPoses = result.landmarks.length;\n\t\t\tupdateLandmarksTexture(result.landmarks);\n\t\t\tupdateMaskTexture(result.segmentationMasks).catch(error => {\n\t\t\t\tconsole.warn('[Pose Plugin] Mask texture update error:', error);\n\t\t\t});\n\t\t\tshaderPad.updateUniforms({ u_nPoses: nPoses });\n\n\t\t\toptions?.onResults?.(result);\n\t\t}\n\n\t\tshaderPad.registerHook('init', async () => {\n\t\t\tshaderPad.initializeTexture('u_poseMask', poseMaskCanvas);\n\t\t\tshaderPad.initializeUniform('u_maxPoses', 'int', maxPoses);\n\t\t\tshaderPad.initializeUniform('u_nPoses', 'int', 0);\n\n\t\t\tconst totalLandmarks = maxPoses * 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_poseLandmarksTex',\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 initializePoseLandmarker();\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 (!poseLandmarker) return;\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 poseLandmarker.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 timestamp = performance.now();\n\t\t\t\t\t\tconst result = poseLandmarker.detectForVideo(source, timestamp);\n\t\t\t\t\t\tprocessPoseResults(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 = poseLandmarker.detect(source);\n\t\t\t\t\tprocessPoseResults(result);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Pose Plugin] Pose detection error:', error);\n\t\t\t}\n\t\t});\n\n\t\tshaderPad.registerHook('destroy', () => {\n\t\t\tif (poseLandmarker) {\n\t\t\t\tposeLandmarker.close();\n\t\t\t\tposeLandmarker = null;\n\t\t\t}\n\t\t\tvision = null;\n\t\t\ttextureSources.clear();\n\t\t\tposeMaskCanvas.remove();\n\t\t\tlandmarksDataArray = null;\n\t\t});\n\t\t// TODO: inBody shouldn't rely on alpha. Does it? Seems so in the example.\n\t\t// Might be because putImageData ignores alpha compositing.\n\t\tinjectGLSL(`\nuniform int u_maxPoses;\nuniform int u_nPoses;\nuniform sampler2D u_poseLandmarksTex;\nuniform sampler2D u_poseMask;\n\n#define POSE_LANDMARK_LEFT_EYE ${LANDMARK_INDICES.LEFT_EYE}\n#define POSE_LANDMARK_RIGHT_EYE ${LANDMARK_INDICES.RIGHT_EYE}\n#define POSE_LANDMARK_LEFT_SHOULDER ${LANDMARK_INDICES.LEFT_SHOULDER}\n#define POSE_LANDMARK_RIGHT_SHOULDER ${LANDMARK_INDICES.RIGHT_SHOULDER}\n#define POSE_LANDMARK_LEFT_ELBOW ${LANDMARK_INDICES.LEFT_ELBOW}\n#define POSE_LANDMARK_RIGHT_ELBOW ${LANDMARK_INDICES.RIGHT_ELBOW}\n#define POSE_LANDMARK_LEFT_HIP ${LANDMARK_INDICES.LEFT_HIP}\n#define POSE_LANDMARK_RIGHT_HIP ${LANDMARK_INDICES.RIGHT_HIP}\n#define POSE_LANDMARK_LEFT_KNEE ${LANDMARK_INDICES.LEFT_KNEE}\n#define POSE_LANDMARK_RIGHT_KNEE ${LANDMARK_INDICES.RIGHT_KNEE}\n#define POSE_LANDMARK_BODY_CENTER ${LANDMARK_INDICES.BODY_CENTER}\n#define POSE_LANDMARK_LEFT_HAND_CENTER ${LANDMARK_INDICES.LEFT_HAND_CENTER}\n#define POSE_LANDMARK_RIGHT_HAND_CENTER ${LANDMARK_INDICES.RIGHT_HAND_CENTER}\n#define POSE_LANDMARK_LEFT_FOOT_CENTER ${LANDMARK_INDICES.LEFT_FOOT_CENTER}\n#define POSE_LANDMARK_RIGHT_FOOT_CENTER ${LANDMARK_INDICES.RIGHT_FOOT_CENTER}\n#define POSE_LANDMARK_TORSO_CENTER ${LANDMARK_INDICES.TORSO_CENTER}\n\nvec4 poseLandmark(int poseIndex, int landmarkIndex) {\n\tint i = poseIndex * ${LANDMARK_COUNT} + landmarkIndex;\n\tint x = i % ${LANDMARKS_TEXTURE_WIDTH};\n\tint y = i / ${LANDMARKS_TEXTURE_WIDTH};\n\treturn texelFetch(u_poseLandmarksTex, ivec2(x, y), 0);\n}\nfloat inBody(vec2 pos) { return texture(u_poseMask, pos).g; }`);\n\t};\n}\n\nexport default pose;\n"],"mappings":"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","names":["pose_exports","__export","pose_default","__toCommonJS","STANDARD_LANDMARK_COUNT","CUSTOM_LANDMARK_COUNT","LANDMARK_COUNT","LANDMARK_INDICES","pose","config","textureName","options","defaultModelPath","shaderPad","context","injectGLSL","gl","poseLandmarker","vision","lastVideoTime","runningMode","textureSources","maxPoses","LANDMARKS_TEXTURE_WIDTH","landmarksTextureHeight","landmarksDataArray","maskWidth","maskHeight","poseMaskCanvas","poseMaskCtx","segmentationCanvas","segmentationCtx","initializePoseLandmarker","FilesetResolver","PoseLandmarker","error","calculateBoundingBoxCenter","poseIdx","landmarkIndices","minX","maxX","minY","maxY","avgZ","avgVisibility","idx","dataIdx","x","y","centerX","centerY","centerZ","centerVisibility","updateMaskTexture","segmentationMasks","mask","width","height","maskData","pixelCount","outputData","i","rgbaMask","updateLandmarksTexture","poses","nPoses","totalLandmarks","landmarks","lmIdx","landmark","bodyCenter","_","bodyCenterIdx","leftHandCenter","leftHandCenterIdx","rightHandCenter","rightHandCenterIdx","leftFootCenter","leftFootCenterIdx","rightFootCenter","rightFootCenterIdx","torsoCenter","torsoCenterIdx","rowsToUpdate","processPoseResults","result","textureSize","updates","source","requiredMode","timestamp"]}
1
+ {"version":3,"sources":["../../src/plugins/pose.ts","../../src/index.ts"],"sourcesContent":["import ShaderPad, { PluginContext, TextureSource } from '../index';\nimport type { PoseLandmarker, PoseLandmarkerResult, NormalizedLandmark, MPMask } from '@mediapipe/tasks-vision';\n\nexport interface PosePluginOptions {\n\tmodelPath?: string;\n\tmaxPoses?: number;\n\tminPoseDetectionConfidence?: number;\n\tminPosePresenceConfidence?: number;\n\tminTrackingConfidence?: number;\n\tonResults?: (results: PoseLandmarkerResult) => void;\n}\n\nconst STANDARD_LANDMARK_COUNT = 33; // See https://ai.google.dev/edge/mediapipe/solutions/vision/pose_landmarker#pose_landmarker_model.\nconst CUSTOM_LANDMARK_COUNT = 6;\nconst LANDMARK_COUNT = STANDARD_LANDMARK_COUNT + CUSTOM_LANDMARK_COUNT;\nconst LANDMARK_INDICES = {\n\t// Standard landmarks.\n\tLEFT_EYE: 2,\n\tRIGHT_EYE: 5,\n\tLEFT_SHOULDER: 11,\n\tRIGHT_SHOULDER: 12,\n\tLEFT_ELBOW: 13,\n\tRIGHT_ELBOW: 14,\n\tLEFT_HIP: 23,\n\tRIGHT_HIP: 24,\n\tLEFT_KNEE: 25,\n\tRIGHT_KNEE: 26,\n\tLEFT_WRIST: 15,\n\tRIGHT_WRIST: 16,\n\tLEFT_PINKY: 17,\n\tRIGHT_PINKY: 18,\n\tLEFT_INDEX: 19,\n\tRIGHT_INDEX: 20,\n\tLEFT_THUMB: 21,\n\tRIGHT_THUMB: 22,\n\tLEFT_ANKLE: 27,\n\tRIGHT_ANKLE: 28,\n\tLEFT_HEEL: 29,\n\tRIGHT_HEEL: 30,\n\tLEFT_FOOT_INDEX: 31,\n\tRIGHT_FOOT_INDEX: 32,\n\t// Custom landmarks.\n\tBODY_CENTER: STANDARD_LANDMARK_COUNT,\n\tLEFT_HAND_CENTER: STANDARD_LANDMARK_COUNT + 1,\n\tRIGHT_HAND_CENTER: STANDARD_LANDMARK_COUNT + 2,\n\tLEFT_FOOT_CENTER: STANDARD_LANDMARK_COUNT + 3,\n\tRIGHT_FOOT_CENTER: STANDARD_LANDMARK_COUNT + 4,\n\tTORSO_CENTER: STANDARD_LANDMARK_COUNT + 5,\n};\nconst ALL_STANDARD_INDICES = Array.from({ length: STANDARD_LANDMARK_COUNT }, (_, i) => i);\nconst LEFT_HAND_INDICES = [\n\tLANDMARK_INDICES.LEFT_WRIST,\n\tLANDMARK_INDICES.LEFT_PINKY,\n\tLANDMARK_INDICES.LEFT_THUMB,\n\tLANDMARK_INDICES.LEFT_INDEX,\n];\nconst RIGHT_HAND_INDICES = [\n\tLANDMARK_INDICES.RIGHT_WRIST,\n\tLANDMARK_INDICES.RIGHT_PINKY,\n\tLANDMARK_INDICES.RIGHT_THUMB,\n\tLANDMARK_INDICES.RIGHT_INDEX,\n];\nconst LEFT_FOOT_INDICES = [LANDMARK_INDICES.LEFT_ANKLE, LANDMARK_INDICES.LEFT_HEEL, LANDMARK_INDICES.LEFT_FOOT_INDEX];\nconst RIGHT_FOOT_INDICES = [\n\tLANDMARK_INDICES.RIGHT_ANKLE,\n\tLANDMARK_INDICES.RIGHT_HEEL,\n\tLANDMARK_INDICES.RIGHT_FOOT_INDEX,\n];\nconst TORSO_INDICES = [\n\tLANDMARK_INDICES.LEFT_SHOULDER,\n\tLANDMARK_INDICES.RIGHT_SHOULDER,\n\tLANDMARK_INDICES.LEFT_HIP,\n\tLANDMARK_INDICES.RIGHT_HIP,\n];\n\nconst dummyTexture = { data: new Uint8Array(4), width: 1, height: 1 };\nfunction pose(config: { textureName: string; options?: PosePluginOptions }) {\n\tconst { textureName, options } = config;\n\tconst defaultModelPath =\n\t\t'https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task';\n\n\treturn function (shaderPad: ShaderPad, context: PluginContext) {\n\t\tconst { injectGLSL, gl } = context;\n\n\t\tlet poseLandmarker: PoseLandmarker | 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 maxPoses = options?.maxPoses ?? 1;\n\n\t\tconst LANDMARKS_TEXTURE_WIDTH = 512;\n\t\tlet landmarksTextureHeight = 0;\n\t\tlet landmarksDataArray: Float32Array | null = null;\n\n\t\t// Shared canvas for MediaPipe and maskShader (same WebGL context).\n\t\tconst sharedCanvas = new OffscreenCanvas(1, 1);\n\t\tlet maskShader: ShaderPad | null = null;\n\n\t\tasync function initializePoseLandmarker() {\n\t\t\ttry {\n\t\t\t\tconst { FilesetResolver, PoseLandmarker } = 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\tposeLandmarker = await PoseLandmarker.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: sharedCanvas,\n\t\t\t\t\trunningMode,\n\t\t\t\t\tnumPoses: options?.maxPoses ?? 1,\n\t\t\t\t\tminPoseDetectionConfidence: options?.minPoseDetectionConfidence ?? 0.5,\n\t\t\t\t\tminPosePresenceConfidence: options?.minPosePresenceConfidence ?? 0.5,\n\t\t\t\t\tminTrackingConfidence: options?.minTrackingConfidence ?? 0.5,\n\t\t\t\t\toutputSegmentationMasks: true,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Pose 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\tposeIdx: number,\n\t\t\tlandmarkIndices: 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 = (poseIdx * 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 updateMaskTexture(segmentationMasks?: MPMask[]) {\n\t\t\tif (!segmentationMasks || segmentationMasks.length === 0 || !maskShader) return;\n\t\t\tfor (let i = 0; i < segmentationMasks.length; ++i) {\n\t\t\t\tconst mask = segmentationMasks[i];\n\t\t\t\tmaskShader.updateTextures({ u_mask: mask.getAsWebGLTexture() });\n\t\t\t\tmaskShader.updateUniforms({ u_poseIndex: (i + 1) / maxPoses });\n\t\t\t\tmaskShader.draw(i === 0); // Only clear on first mask.\n\t\t\t}\n\t\t\tshaderPad.updateTextures({ u_poseMask: sharedCanvas });\n\t\t}\n\n\t\tfunction updateLandmarksTexture(poses: NormalizedLandmark[][]) {\n\t\t\tif (!landmarksDataArray) return;\n\n\t\t\tconst nPoses = poses.length;\n\t\t\tconst totalLandmarks = nPoses * LANDMARK_COUNT;\n\n\t\t\tfor (let poseIdx = 0; poseIdx < nPoses; ++poseIdx) {\n\t\t\t\tconst landmarks = poses[poseIdx];\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 = (poseIdx * 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] = landmark.visibility ?? 1;\n\t\t\t\t}\n\n\t\t\t\tconst bodyCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, ALL_STANDARD_INDICES);\n\t\t\t\tconst bodyCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.BODY_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[bodyCenterIdx] = bodyCenter[0];\n\t\t\t\tlandmarksDataArray[bodyCenterIdx + 1] = bodyCenter[1];\n\t\t\t\tlandmarksDataArray[bodyCenterIdx + 2] = bodyCenter[2];\n\t\t\t\tlandmarksDataArray[bodyCenterIdx + 3] = bodyCenter[3];\n\n\t\t\t\tconst leftHandCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, LEFT_HAND_INDICES);\n\t\t\t\tconst leftHandCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.LEFT_HAND_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[leftHandCenterIdx] = leftHandCenter[0];\n\t\t\t\tlandmarksDataArray[leftHandCenterIdx + 1] = leftHandCenter[1];\n\t\t\t\tlandmarksDataArray[leftHandCenterIdx + 2] = leftHandCenter[2];\n\t\t\t\tlandmarksDataArray[leftHandCenterIdx + 3] = leftHandCenter[3];\n\n\t\t\t\tconst rightHandCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, RIGHT_HAND_INDICES);\n\t\t\t\tconst rightHandCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.RIGHT_HAND_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[rightHandCenterIdx] = rightHandCenter[0];\n\t\t\t\tlandmarksDataArray[rightHandCenterIdx + 1] = rightHandCenter[1];\n\t\t\t\tlandmarksDataArray[rightHandCenterIdx + 2] = rightHandCenter[2];\n\t\t\t\tlandmarksDataArray[rightHandCenterIdx + 3] = rightHandCenter[3];\n\n\t\t\t\tconst leftFootCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, LEFT_FOOT_INDICES);\n\t\t\t\tconst leftFootCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.LEFT_FOOT_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[leftFootCenterIdx] = leftFootCenter[0];\n\t\t\t\tlandmarksDataArray[leftFootCenterIdx + 1] = leftFootCenter[1];\n\t\t\t\tlandmarksDataArray[leftFootCenterIdx + 2] = leftFootCenter[2];\n\t\t\t\tlandmarksDataArray[leftFootCenterIdx + 3] = leftFootCenter[3];\n\n\t\t\t\tconst rightFootCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, RIGHT_FOOT_INDICES);\n\t\t\t\tconst rightFootCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.RIGHT_FOOT_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[rightFootCenterIdx] = rightFootCenter[0];\n\t\t\t\tlandmarksDataArray[rightFootCenterIdx + 1] = rightFootCenter[1];\n\t\t\t\tlandmarksDataArray[rightFootCenterIdx + 2] = rightFootCenter[2];\n\t\t\t\tlandmarksDataArray[rightFootCenterIdx + 3] = rightFootCenter[3];\n\n\t\t\t\tconst torsoCenter = calculateBoundingBoxCenter(landmarksDataArray, poseIdx, TORSO_INDICES);\n\t\t\t\tconst torsoCenterIdx = (poseIdx * LANDMARK_COUNT + LANDMARK_INDICES.TORSO_CENTER) * 4;\n\t\t\t\tlandmarksDataArray[torsoCenterIdx] = torsoCenter[0];\n\t\t\t\tlandmarksDataArray[torsoCenterIdx + 1] = torsoCenter[1];\n\t\t\t\tlandmarksDataArray[torsoCenterIdx + 2] = torsoCenter[2];\n\t\t\t\tlandmarksDataArray[torsoCenterIdx + 3] = torsoCenter[3];\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_poseLandmarksTex: {\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 processPoseResults(result: PoseLandmarkerResult) {\n\t\t\tif (!result.landmarks || !landmarksDataArray) return;\n\n\t\t\t// IMPORTANT: maskShader and MediaPipe share a WebGL context. MediaPipe needs to run at least once before\n\t\t\t// ShaderPad is created on the same canvas, otherwise MediaPipe’s WebGL state gets corrupted.\n\t\t\tif (!maskShader) {\n\t\t\t\tmaskShader = new ShaderPad(\n\t\t\t\t\t`#version 300 es\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t\tin vec2 v_uv;\n\t\t\t\t\tout vec4 outColor;\n\t\t\t\t\tuniform sampler2D u_mask;\n\t\t\t\t\tuniform float u_poseIndex;\n\t\t\t\t\tvoid main() {\n\t\t\t\t\t\tivec2 texCoord = ivec2(v_uv * vec2(textureSize(u_mask, 0)));\n\t\t\t\t\t\tfloat confidence = texelFetch(u_mask, texCoord, 0).r;\n\t\t\t\t\t\tif (confidence < 0.01) discard;\n\t\t\t\t\t\toutColor = vec4(1.0, confidence, u_poseIndex, 1.0);\n\t\t\t\t\t}`,\n\t\t\t\t\t{ canvas: sharedCanvas }\n\t\t\t\t);\n\t\t\t\tmaskShader.initializeTexture('u_mask', dummyTexture);\n\t\t\t\tmaskShader.initializeUniform('u_poseIndex', 'float', 0);\n\t\t\t}\n\n\t\t\tconst nPoses = result.landmarks.length;\n\t\t\tupdateLandmarksTexture(result.landmarks);\n\t\t\tupdateMaskTexture(result.segmentationMasks);\n\t\t\tshaderPad.updateUniforms({ u_nPoses: nPoses });\n\n\t\t\toptions?.onResults?.(result);\n\t\t}\n\n\t\tshaderPad.registerHook('init', async () => {\n\t\t\tshaderPad.initializeTexture('u_poseMask', dummyTexture, { preserveY: true });\n\t\t\tshaderPad.initializeUniform('u_maxPoses', 'int', maxPoses);\n\t\t\tshaderPad.initializeUniform('u_nPoses', 'int', 0);\n\n\t\t\tconst totalLandmarks = maxPoses * 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_poseLandmarksTex',\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 initializePoseLandmarker();\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 (!poseLandmarker) 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 poseLandmarker.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) 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\tconst result = poseLandmarker.detectForVideo(source, performance.now());\n\t\t\t\t\t\tprocessPoseResults(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) return;\n\t\t\t\t\tconst result = poseLandmarker.detect(source);\n\t\t\t\t\tprocessPoseResults(result);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Pose Plugin] Detection error:', error);\n\t\t\t}\n\t\t});\n\n\t\tshaderPad.registerHook('destroy', () => {\n\t\t\tif (poseLandmarker) {\n\t\t\t\tposeLandmarker.close();\n\t\t\t\tposeLandmarker = null;\n\t\t\t}\n\t\t\tif (maskShader) {\n\t\t\t\tmaskShader.destroy();\n\t\t\t\tmaskShader = null;\n\t\t\t}\n\t\t\tvision = null;\n\t\t\ttextureSources.clear();\n\t\t\tlandmarksDataArray = null;\n\t\t});\n\t\tinjectGLSL(`\nuniform int u_maxPoses;\nuniform int u_nPoses;\nuniform sampler2D u_poseLandmarksTex;\nuniform sampler2D u_poseMask;\n\n#define POSE_LANDMARK_LEFT_EYE ${LANDMARK_INDICES.LEFT_EYE}\n#define POSE_LANDMARK_RIGHT_EYE ${LANDMARK_INDICES.RIGHT_EYE}\n#define POSE_LANDMARK_LEFT_SHOULDER ${LANDMARK_INDICES.LEFT_SHOULDER}\n#define POSE_LANDMARK_RIGHT_SHOULDER ${LANDMARK_INDICES.RIGHT_SHOULDER}\n#define POSE_LANDMARK_LEFT_ELBOW ${LANDMARK_INDICES.LEFT_ELBOW}\n#define POSE_LANDMARK_RIGHT_ELBOW ${LANDMARK_INDICES.RIGHT_ELBOW}\n#define POSE_LANDMARK_LEFT_HIP ${LANDMARK_INDICES.LEFT_HIP}\n#define POSE_LANDMARK_RIGHT_HIP ${LANDMARK_INDICES.RIGHT_HIP}\n#define POSE_LANDMARK_LEFT_KNEE ${LANDMARK_INDICES.LEFT_KNEE}\n#define POSE_LANDMARK_RIGHT_KNEE ${LANDMARK_INDICES.RIGHT_KNEE}\n#define POSE_LANDMARK_BODY_CENTER ${LANDMARK_INDICES.BODY_CENTER}\n#define POSE_LANDMARK_LEFT_HAND_CENTER ${LANDMARK_INDICES.LEFT_HAND_CENTER}\n#define POSE_LANDMARK_RIGHT_HAND_CENTER ${LANDMARK_INDICES.RIGHT_HAND_CENTER}\n#define POSE_LANDMARK_LEFT_FOOT_CENTER ${LANDMARK_INDICES.LEFT_FOOT_CENTER}\n#define POSE_LANDMARK_RIGHT_FOOT_CENTER ${LANDMARK_INDICES.RIGHT_FOOT_CENTER}\n#define POSE_LANDMARK_TORSO_CENTER ${LANDMARK_INDICES.TORSO_CENTER}\n\nvec4 poseLandmark(int poseIndex, int landmarkIndex) {\n\tint i = poseIndex * ${LANDMARK_COUNT} + landmarkIndex;\n\tint x = i % ${LANDMARKS_TEXTURE_WIDTH};\n\tint y = i / ${LANDMARKS_TEXTURE_WIDTH};\n\treturn texelFetch(u_poseLandmarksTex, ivec2(x, y), 0);\n}\n\nvec2 poseAt(vec2 pos) {\n\tvec4 mask = texture(u_poseMask, pos);\n\tfloat poseIndex = floor(mask.b * float(u_maxPoses) + 0.5) - 1.0;\n\treturn vec2(mask.g, poseIndex);\n}\n\t\nfloat inPose(vec2 pos) {\n\tfloat pose = poseAt(pos).x;\n\treturn step(0.0, pose);\n}`);\n\t};\n}\n\nexport default pose;\n","const DEFAULT_VERTEX_SHADER_SRC = `#version 300 es\nin vec2 aPosition;\nout vec2 v_uv;\nvoid main() {\n v_uv = aPosition * 0.5 + 0.5;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}\n`;\nconst RESIZE_THROTTLE_INTERVAL = 1000 / 30;\n\ninterface Uniform {\n\ttype: 'float' | 'int';\n\tlength: 1 | 2 | 3 | 4;\n\tlocation: WebGLUniformLocation;\n\tarrayLength?: number;\n}\n\nexport interface TextureOptions {\n\tinternalFormat?: number;\n\tformat?: number;\n\ttype?: number;\n\tminFilter?: number;\n\tmagFilter?: number;\n\twrapS?: number;\n\twrapT?: number;\n\tpreserveY?: boolean;\n}\n\ninterface Texture {\n\ttexture: WebGLTexture;\n\tunitIndex: number;\n\twidth: number;\n\theight: number;\n\thistory?: {\n\t\tdepth: number;\n\t\twriteIndex: number;\n\t};\n\toptions?: TextureOptions;\n}\n\nexport interface CustomTexture {\n\tdata: ArrayBufferView | null;\n\twidth: number;\n\theight: number;\n}\n\nexport interface PartialCustomTexture extends CustomTexture {\n\tisPartial?: boolean;\n\tx?: number;\n\ty?: number;\n}\n\nexport type TextureSource =\n\t| HTMLImageElement\n\t| HTMLVideoElement\n\t| HTMLCanvasElement\n\t| OffscreenCanvas\n\t| ImageBitmap\n\t| WebGLTexture\n\t| CustomTexture;\n\n// Custom textures allow partial updates starting from (x, y).\ntype UpdateTextureSource = Exclude<TextureSource, CustomTexture> | PartialCustomTexture;\n\nexport interface PluginContext {\n\tgl: WebGL2RenderingContext;\n\tuniforms: Map<string, Uniform>;\n\ttextures: Map<string | symbol, Texture>;\n\tget program(): WebGLProgram | null;\n\tcanvas: HTMLCanvasElement | OffscreenCanvas;\n\treserveTextureUnit: (name: string | symbol) => number;\n\treleaseTextureUnit: (name: string | symbol) => void;\n\tinjectGLSL: (code: string) => void;\n}\n\ntype Plugin = (shaderPad: ShaderPad, context: PluginContext) => void;\n\ntype LifecycleMethod =\n\t| 'init'\n\t| 'step'\n\t| 'destroy'\n\t| 'updateResolution'\n\t| 'reset'\n\t| 'initializeTexture'\n\t| 'updateTextures'\n\t| 'initializeUniform'\n\t| 'updateUniforms';\n\nexport interface Options {\n\tcanvas?: HTMLCanvasElement | OffscreenCanvas | null;\n\tplugins?: Plugin[];\n\thistory?: number;\n\tdebug?: boolean;\n}\n\ntype TextureUnitPool = {\n\tfree: number[];\n\tnext: number;\n\tmax: number;\n};\n\nconst HISTORY_TEXTURE_KEY = Symbol('u_history');\n\nfunction combineShaderCode(shader: string, injections: string[]): string {\n\tif (!injections?.length) return shader;\n\tconst lines = shader.split('\\n');\n\tconst insertAt =\n\t\tlines.findLastIndex(line => {\n\t\t\tconst trimmed = line.trimStart();\n\t\t\treturn trimmed.startsWith('precision ') || trimmed.startsWith('#version ');\n\t\t}) + 1;\n\tlines.splice(insertAt, 0, ...injections);\n\treturn lines.join('\\n');\n}\n\nfunction getSourceDimensions(source: TextureSource): { width: number; height: number } {\n\tif (source instanceof WebGLTexture) {\n\t\treturn { width: 0, height: 0 }; // Invalid - dimensions not readable.\n\t}\n\tif (source instanceof HTMLVideoElement) {\n\t\treturn { width: source.videoWidth, height: source.videoHeight };\n\t}\n\tif (source instanceof HTMLImageElement) {\n\t\treturn { width: source.naturalWidth ?? source.width, height: source.naturalHeight ?? source.height };\n\t}\n\t// CustomTexture, HTMLCanvasElement, OffscreenCanvas, ImageBitmap.\n\treturn { width: source.width, height: source.height };\n}\n\nfunction stringFrom(name: string | symbol) {\n\treturn typeof name === 'symbol' ? name.description ?? '' : name;\n}\n\nclass ShaderPad {\n\tprivate isInternalCanvas = false;\n\tprivate isTouchDevice = false;\n\tprivate gl: WebGL2RenderingContext;\n\tprivate fragmentShaderSrc: string;\n\tprivate uniforms: Map<string, Uniform> = new Map();\n\tprivate textures: Map<string | symbol, Texture> = new Map();\n\tprivate textureUnitPool: TextureUnitPool;\n\tprivate buffer: WebGLBuffer | null = null;\n\tprivate program: WebGLProgram | null = null;\n\tprivate aPositionLocation = 0;\n\tprivate animationFrameId: number | null;\n\tprivate resolutionObserver: MutationObserver;\n\tprivate resizeObserver: ResizeObserver;\n\tprivate resizeTimeout: ReturnType<typeof setTimeout> = null as unknown as ReturnType<typeof setTimeout>;\n\tprivate lastResizeTime = -Infinity;\n\tprivate eventListeners: Map<string, EventListener> = new Map();\n\tprivate frame = 0;\n\tprivate startTime = 0;\n\tprivate cursorPosition = [0.5, 0.5];\n\tprivate clickPosition = [0.5, 0.5];\n\tprivate isMouseDown = false;\n\tpublic canvas: HTMLCanvasElement | OffscreenCanvas;\n\tpublic onResize?: (width: number, height: number) => void;\n\tprivate hooks: Map<LifecycleMethod, Function[]> = new Map();\n\tprivate historyDepth: number;\n\tprivate debug: boolean;\n\n\tconstructor(fragmentShaderSrc: string, options: Options = {}) {\n\t\tthis.canvas = options.canvas || document.createElement('canvas');\n\t\tif (!options.canvas) {\n\t\t\tthis.isInternalCanvas = true;\n\t\t\tconst htmlCanvas = this.canvas as HTMLCanvasElement;\n\t\t\thtmlCanvas.style.position = 'fixed';\n\t\t\thtmlCanvas.style.inset = '0';\n\t\t\thtmlCanvas.style.height = '100dvh';\n\t\t\thtmlCanvas.style.width = '100dvw';\n\t\t\tdocument.body.appendChild(htmlCanvas);\n\t\t}\n\n\t\tthis.gl = this.canvas.getContext('webgl2', { antialias: false }) as WebGL2RenderingContext;\n\t\tif (!this.gl) {\n\t\t\tthrow new Error('WebGL2 not supported. Please use a browser that supports WebGL2.');\n\t\t}\n\n\t\tthis.textureUnitPool = {\n\t\t\tfree: [],\n\t\t\tnext: 0,\n\t\t\tmax: this.gl.getParameter(this.gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS),\n\t\t};\n\t\tthis.historyDepth = options.history ?? 0;\n\t\tthis.debug = options.debug ?? (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production');\n\t\tthis.animationFrameId = null;\n\t\tthis.resolutionObserver = new MutationObserver(() => this.updateResolution());\n\t\tthis.resizeObserver = new ResizeObserver(() => this.throttledHandleResize());\n\n\t\tconst glslInjections: string[] = [];\n\t\tif (options.plugins) {\n\t\t\tconst context: PluginContext = {\n\t\t\t\tgl: this.gl,\n\t\t\t\tuniforms: this.uniforms,\n\t\t\t\ttextures: this.textures,\n\t\t\t\tcanvas: this.canvas,\n\t\t\t\treserveTextureUnit: this.reserveTextureUnit.bind(this),\n\t\t\t\treleaseTextureUnit: this.releaseTextureUnit.bind(this),\n\t\t\t\tinjectGLSL: (code: string) => {\n\t\t\t\t\tglslInjections.push(code);\n\t\t\t\t},\n\t\t\t} as PluginContext;\n\t\t\t// Define program as a getter so it always returns the current program.\n\t\t\tObject.defineProperty(context, 'program', {\n\t\t\t\tget: () => this.program,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t\toptions.plugins.forEach(plugin => plugin(this, context));\n\t\t}\n\n\t\tthis.fragmentShaderSrc = combineShaderCode(fragmentShaderSrc, glslInjections);\n\t\tthis.init();\n\t\tif (this.canvas instanceof HTMLCanvasElement) {\n\t\t\tthis.addEventListeners();\n\t\t}\n\t}\n\n\tregisterHook(name: LifecycleMethod, fn: Function) {\n\t\tif (!this.hooks.has(name)) {\n\t\t\tthis.hooks.set(name, []);\n\t\t}\n\t\tthis.hooks.get(name)!.push(fn);\n\t}\n\n\tprivate init() {\n\t\tconst vertexShaderSrc = DEFAULT_VERTEX_SHADER_SRC;\n\n\t\tthis.program = this.gl.createProgram();\n\t\tif (!this.program) {\n\t\t\tthrow new Error('Failed to create WebGL program');\n\t\t}\n\t\tconst vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexShaderSrc);\n\t\tconst fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, this.fragmentShaderSrc);\n\n\t\tthis.gl.attachShader(this.program, vertexShader);\n\t\tthis.gl.attachShader(this.program, fragmentShader);\n\t\tthis.gl.linkProgram(this.program);\n\t\tthis.gl.deleteShader(vertexShader);\n\t\tthis.gl.deleteShader(fragmentShader);\n\n\t\tif (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {\n\t\t\tconsole.error('Program link error:', this.gl.getProgramInfoLog(this.program));\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t\tthrow new Error('Failed to link WebGL program');\n\t\t}\n\n\t\tthis.aPositionLocation = this.gl.getAttribLocation(this.program, 'aPosition');\n\t\tthis.setupBuffer();\n\n\t\tthis.gl.useProgram(this.program);\n\n\t\tif (this.canvas instanceof HTMLCanvasElement) {\n\t\t\tthis.resolutionObserver.observe(this.canvas, { attributes: true, attributeFilter: ['width', 'height'] });\n\t\t\tthis.resizeObserver.observe(this.canvas);\n\t\t}\n\n\t\tif (!this.isInternalCanvas) {\n\t\t\tthis.updateResolution();\n\t\t}\n\t\tthis.initializeUniform('u_cursor', 'float', this.cursorPosition);\n\t\tthis.initializeUniform('u_click', 'float', [...this.clickPosition, this.isMouseDown ? 1.0 : 0.0]);\n\t\tthis.initializeUniform('u_time', 'float', 0);\n\t\tthis.initializeUniform('u_frame', 'int', 0);\n\t\tif (this.historyDepth > 0) {\n\t\t\tthis._initializeTexture(HISTORY_TEXTURE_KEY, this.canvas, { history: this.historyDepth });\n\t\t}\n\n\t\tthis.hooks.get('init')?.forEach(hook => hook.call(this));\n\t}\n\n\tprivate createShader(type: number, source: string): WebGLShader {\n\t\tconst shader = this.gl.createShader(type)!;\n\t\tthis.gl.shaderSource(shader, source);\n\t\tthis.gl.compileShader(shader);\n\t\tif (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n\t\t\tconsole.error('Shader compilation failed:', source);\n\t\t\tconsole.error(this.gl.getShaderInfoLog(shader));\n\t\t\tthis.gl.deleteShader(shader);\n\t\t\tthrow new Error('Shader compilation failed');\n\t\t}\n\t\treturn shader;\n\t}\n\n\tprivate setupBuffer() {\n\t\tconst quadVertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n\n\t\tthis.buffer = this.gl.createBuffer();\n\t\tthis.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);\n\t\tthis.gl.bufferData(this.gl.ARRAY_BUFFER, quadVertices, this.gl.STATIC_DRAW);\n\t\tthis.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);\n\t\tthis.gl.enableVertexAttribArray(this.aPositionLocation);\n\t\tthis.gl.vertexAttribPointer(this.aPositionLocation, 2, this.gl.FLOAT, false, 0, 0);\n\t}\n\n\tprivate throttledHandleResize() {\n\t\tclearTimeout(this.resizeTimeout);\n\t\tconst now = performance.now();\n\t\tconst timeUntilNextResize = this.lastResizeTime + RESIZE_THROTTLE_INTERVAL - now;\n\t\tif (timeUntilNextResize <= 0) {\n\t\t\tthis.lastResizeTime = now;\n\t\t\tthis.handleResize();\n\t\t} else {\n\t\t\tthis.resizeTimeout = setTimeout(() => this.throttledHandleResize(), timeUntilNextResize);\n\t\t}\n\t}\n\n\tprivate handleResize() {\n\t\tif (!(this.canvas instanceof HTMLCanvasElement)) return;\n\t\tconst pixelRatio = window.devicePixelRatio || 1;\n\t\tconst width = this.canvas.clientWidth * pixelRatio;\n\t\tconst height = this.canvas.clientHeight * pixelRatio;\n\t\tif (this.isInternalCanvas && (this.canvas.width !== width || this.canvas.height !== height)) {\n\t\t\tthis.canvas.width = width;\n\t\t\tthis.canvas.height = height;\n\t\t}\n\t\tthis.onResize?.(width, height);\n\t}\n\n\tprivate addEventListeners() {\n\t\tconst htmlCanvas = this.canvas as HTMLCanvasElement;\n\t\tconst updateCursor = (x: number, y: number) => {\n\t\t\tif (!this.uniforms.has('u_cursor')) return;\n\t\t\tconst rect = htmlCanvas.getBoundingClientRect();\n\t\t\tthis.cursorPosition[0] = (x - rect.left) / rect.width;\n\t\t\tthis.cursorPosition[1] = 1 - (y - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\tthis.updateUniforms({ u_cursor: this.cursorPosition });\n\t\t};\n\n\t\tconst updateClick = (isMouseDown: boolean, x?: number, y?: number) => {\n\t\t\tif (!this.uniforms.has('u_click')) return;\n\t\t\tthis.isMouseDown = isMouseDown;\n\t\t\tif (isMouseDown) {\n\t\t\t\tconst rect = htmlCanvas.getBoundingClientRect();\n\t\t\t\tconst xVal = x as number;\n\t\t\t\tconst yVal = y as number;\n\t\t\t\tthis.clickPosition[0] = (xVal - rect.left) / rect.width;\n\t\t\t\tthis.clickPosition[1] = 1 - (yVal - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\t}\n\t\t\tthis.updateUniforms({ u_click: [...this.clickPosition, this.isMouseDown ? 1.0 : 0.0] });\n\t\t};\n\n\t\tthis.eventListeners.set('mousemove', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tupdateCursor(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mousedown', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tthis.isMouseDown = true;\n\t\t\t\t\tupdateClick(true, mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mouseup', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tupdateClick(false);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchmove', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchstart', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tthis.isTouchDevice = true;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t\tupdateClick(true, touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchend', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length === 0) {\n\t\t\t\tupdateClick(false);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\thtmlCanvas.addEventListener(event, listener);\n\t\t});\n\t}\n\n\tprivate updateResolution() {\n\t\tconst resolution: [number, number] = [this.gl.drawingBufferWidth, this.gl.drawingBufferHeight];\n\t\tthis.gl.viewport(0, 0, ...resolution);\n\t\tif (this.uniforms.has('u_resolution')) {\n\t\t\tthis.updateUniforms({ u_resolution: resolution });\n\t\t} else {\n\t\t\tthis.initializeUniform('u_resolution', 'float', resolution);\n\t\t}\n\t\tthis.hooks.get('updateResolution')?.forEach(hook => hook.call(this));\n\t}\n\n\tprivate reserveTextureUnit(name: string | symbol) {\n\t\tconst existing = this.textures.get(name);\n\t\tif (existing) return existing.unitIndex;\n\t\tif (this.textureUnitPool.free.length > 0) return this.textureUnitPool.free.pop()!;\n\t\tif (this.textureUnitPool.next >= this.textureUnitPool.max) {\n\t\t\tthrow new Error('Exceeded the available texture units for this device.');\n\t\t}\n\t\treturn this.textureUnitPool.next++;\n\t}\n\n\tprivate releaseTextureUnit(name: string | symbol) {\n\t\tconst existing = this.textures.get(name);\n\t\tif (existing) {\n\t\t\tthis.textureUnitPool.free.push(existing.unitIndex);\n\t\t}\n\t}\n\n\tprivate clearHistoryTextureLayers(textureInfo: Texture): void {\n\t\tif (!textureInfo.history) return;\n\n\t\tconst type = textureInfo.options?.type ?? this.gl.UNSIGNED_BYTE;\n\t\tconst transparent =\n\t\t\ttype === this.gl.FLOAT\n\t\t\t\t? new Float32Array(textureInfo.width * textureInfo.height * 4)\n\t\t\t\t: new Uint8Array(textureInfo.width * textureInfo.height * 4);\n\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + textureInfo.unitIndex);\n\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY, textureInfo.texture);\n\t\tfor (let layer = 0; layer < textureInfo.history.depth; ++layer) {\n\t\t\tthis.gl.texSubImage3D(\n\t\t\t\tthis.gl.TEXTURE_2D_ARRAY,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tlayer,\n\t\t\t\ttextureInfo.width,\n\t\t\t\ttextureInfo.height,\n\t\t\t\t1,\n\t\t\t\ttextureInfo.options?.format ?? this.gl.RGBA,\n\t\t\t\ttype,\n\t\t\t\ttransparent\n\t\t\t);\n\t\t}\n\t}\n\n\tinitializeUniform(\n\t\tname: string,\n\t\ttype: 'float' | 'int',\n\t\tvalue: number | number[] | (number | number[])[],\n\t\toptions?: { arrayLength?: number }\n\t) {\n\t\tconst arrayLength = options?.arrayLength;\n\t\tif (this.uniforms.has(name)) {\n\t\t\tthrow new Error(`${name} is already initialized.`);\n\t\t}\n\t\tif (type !== 'float' && type !== 'int') {\n\t\t\tthrow new Error(`Invalid uniform type: ${type}. Expected 'float' or 'int'.`);\n\t\t}\n\t\tif (arrayLength && !(Array.isArray(value) && value.length === arrayLength)) {\n\t\t\tthrow new Error(`${name} array length mismatch: must initialize with ${arrayLength} elements.`);\n\t\t}\n\n\t\tlet location = this.gl.getUniformLocation(this.program!, name);\n\t\tif (!location && arrayLength) {\n\t\t\tlocation = this.gl.getUniformLocation(this.program!, `${name}[0]`);\n\t\t}\n\t\tif (!location) {\n\t\t\tthis.log(`${name} not found in fragment shader. Skipping initialization.`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst probeValue = arrayLength ? (value as number[] | number[][])[0] : value;\n\t\tconst length = Array.isArray(probeValue) ? (probeValue.length as 1 | 2 | 3 | 4) : 1;\n\t\tthis.uniforms.set(name, { type, length, location, arrayLength });\n\n\t\ttry {\n\t\t\tthis.updateUniforms({ [name]: value });\n\t\t} catch (error) {\n\t\t\tthis.uniforms.delete(name);\n\t\t\tthrow error;\n\t\t}\n\t\tthis.hooks.get('initializeUniform')?.forEach(hook => hook.call(this, ...arguments));\n\t}\n\n\tprivate log(...args: any[]) {\n\t\tif (this.debug) console.debug(...args);\n\t}\n\n\tupdateUniforms(\n\t\tupdates: Record<string, number | number[] | (number | number[])[]>,\n\t\toptions?: { startIndex?: number }\n\t) {\n\t\tthis.gl.useProgram(this.program);\n\t\tObject.entries(updates).forEach(([name, value]) => {\n\t\t\tconst uniform = this.uniforms.get(name);\n\t\t\tif (!uniform) {\n\t\t\t\tthis.log(`${name} not found in fragment shader. Skipping update.`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet glFunctionName = `uniform${uniform.length}${uniform.type.charAt(0)}`; // e.g. uniform1f, uniform3i…\n\t\t\tif (uniform.arrayLength) {\n\t\t\t\tif (!Array.isArray(value)) {\n\t\t\t\t\tthrow new Error(`${name} is an array, but the value passed to updateUniforms is not an array.`);\n\t\t\t\t}\n\t\t\t\tconst nValues = value.length;\n\t\t\t\tif (!nValues) return;\n\t\t\t\tif (nValues > uniform.arrayLength) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${name} received ${nValues} values, but maximum length is ${uniform.arrayLength}.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (value.some(item => (Array.isArray(item) ? item.length : 1) !== uniform.length)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Tried to update ${name} with some elements that are not length ${uniform.length}.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst typedArray = new (uniform.type === 'float' ? Float32Array : Int32Array)(value.flat());\n\t\t\t\tlet location = uniform.location;\n\t\t\t\tif (options?.startIndex) {\n\t\t\t\t\tconst newLocation = this.gl.getUniformLocation(this.program!, `${name}[${options.startIndex}]`);\n\t\t\t\t\tif (!newLocation) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`${name}[${options.startIndex}] not found in fragment shader. Did you pass an invalid startIndex?`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tlocation = newLocation;\n\t\t\t\t}\n\t\t\t\t(this.gl as any)[glFunctionName + 'v'](uniform.location, typedArray);\n\t\t\t} else {\n\t\t\t\tif (!Array.isArray(value)) value = [value];\n\t\t\t\tif (value.length !== uniform.length) {\n\t\t\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected ${uniform.length}.`);\n\t\t\t\t}\n\t\t\t\t(this.gl as any)[glFunctionName](uniform.location, ...value);\n\t\t\t}\n\t\t});\n\t\tthis.hooks.get('updateUniforms')?.forEach(hook => hook.call(this, ...arguments));\n\t}\n\n\tprivate createTexture(\n\t\tname: string | symbol,\n\t\ttextureInfo: Pick<Texture, 'width' | 'height' | 'history'>,\n\t\toptions?: TextureOptions & { unitIndex?: number }\n\t) {\n\t\tconst { width, height } = textureInfo;\n\t\tconst historyDepth = textureInfo.history?.depth ?? 0;\n\n\t\tconst texture = this.gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow new Error('Failed to create texture');\n\t\t}\n\n\t\tlet unitIndex = options?.unitIndex;\n\t\tif (typeof unitIndex !== 'number') {\n\t\t\ttry {\n\t\t\t\tunitIndex = this.reserveTextureUnit(name);\n\t\t\t} catch (error) {\n\t\t\t\tthis.gl.deleteTexture(texture);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tconst hasHistory = historyDepth > 0;\n\t\tconst textureTarget = hasHistory ? this.gl.TEXTURE_2D_ARRAY : this.gl.TEXTURE_2D;\n\n\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + unitIndex);\n\t\tthis.gl.bindTexture(textureTarget, texture);\n\t\tthis.gl.texParameteri(textureTarget, this.gl.TEXTURE_WRAP_S, options?.wrapS ?? this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(textureTarget, this.gl.TEXTURE_WRAP_T, options?.wrapT ?? this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(textureTarget, this.gl.TEXTURE_MIN_FILTER, options?.minFilter ?? this.gl.LINEAR);\n\t\tthis.gl.texParameteri(textureTarget, this.gl.TEXTURE_MAG_FILTER, options?.magFilter ?? this.gl.LINEAR);\n\t\tif (hasHistory) {\n\t\t\tconst type = options?.type ?? this.gl.UNSIGNED_BYTE;\n\t\t\tconst internalFormat =\n\t\t\t\toptions?.internalFormat ?? (type === this.gl.FLOAT ? this.gl.RGBA32F : this.gl.RGBA8);\n\t\t\tthis.gl.texStorage3D(textureTarget, 1, internalFormat, width, height, historyDepth);\n\t\t}\n\t\treturn { texture, unitIndex };\n\t}\n\n\tprivate _initializeTexture(\n\t\tname: string | symbol,\n\t\tsource: TextureSource,\n\t\toptions?: TextureOptions & { history?: number }\n\t) {\n\t\tif (this.textures.has(name)) {\n\t\t\tthrow new Error(`Texture '${stringFrom(name)}' is already initialized.`);\n\t\t}\n\n\t\tconst { history: historyDepth = 0, ...textureOptions } = options ?? {};\n\t\tconst { width, height } = getSourceDimensions(source);\n\t\tif (!width || !height) {\n\t\t\tthrow new Error(`Texture source must have valid dimensions`);\n\t\t}\n\t\tconst textureInfo: Pick<Texture, 'width' | 'height' | 'history'> = { width, height };\n\t\tif (historyDepth > 0) {\n\t\t\ttextureInfo.history = { depth: historyDepth, writeIndex: 0 };\n\t\t}\n\t\tconst { texture, unitIndex } = this.createTexture(name, textureInfo, textureOptions);\n\t\tconst completeTextureInfo: Texture = { texture, unitIndex, ...textureInfo, options: textureOptions };\n\t\tif (historyDepth > 0) {\n\t\t\tthis.initializeUniform(`${stringFrom(name)}FrameOffset`, 'int', 0);\n\t\t\tthis.clearHistoryTextureLayers(completeTextureInfo);\n\t\t}\n\t\tthis.textures.set(name, completeTextureInfo);\n\t\tthis.updateTexture(name, source);\n\n\t\t// Set a uniform to access the texture in the fragment shader.\n\t\tconst uSampler = this.gl.getUniformLocation(this.program!, stringFrom(name));\n\t\tif (uSampler) {\n\t\t\tthis.gl.uniform1i(uSampler, unitIndex);\n\t\t}\n\t}\n\n\tinitializeTexture(name: string, source: TextureSource, options?: TextureOptions & { history?: number }) {\n\t\tthis._initializeTexture(name, source, options);\n\t\tthis.hooks.get('initializeTexture')?.forEach(hook => hook.call(this, ...arguments));\n\t}\n\n\tupdateTextures(updates: Record<string, UpdateTextureSource>) {\n\t\tthis.hooks.get('updateTextures')?.forEach(hook => hook.call(this, ...arguments));\n\t\tObject.entries(updates).forEach(([name, source]) => {\n\t\t\tthis.updateTexture(name, source);\n\t\t});\n\t}\n\n\tprivate updateTexture(name: string | symbol, source: UpdateTextureSource) {\n\t\tconst info = this.textures.get(name);\n\t\tif (!info) throw new Error(`Texture '${stringFrom(name)}' is not initialized.`);\n\n\t\tif (source instanceof WebGLTexture) {\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, source);\n\t\t\treturn;\n\t\t}\n\n\t\t// If dimensions changed, recreate the texture with new dimensions.\n\t\tconst { width, height } = getSourceDimensions(source);\n\t\tif (!width || !height) return;\n\n\t\tconst isPartial = 'isPartial' in source && source.isPartial;\n\t\tif (!isPartial && (info.width !== width || info.height !== height)) {\n\t\t\tthis.gl.deleteTexture(info.texture);\n\t\t\tinfo.width = width;\n\t\t\tinfo.height = height;\n\t\t\tconst { texture } = this.createTexture(name, info, { ...info.options, unitIndex: info.unitIndex });\n\t\t\tinfo.texture = texture;\n\t\t\tif (info.history) {\n\t\t\t\tinfo.history.writeIndex = 0;\n\t\t\t\tthis.clearHistoryTextureLayers(info);\n\t\t\t}\n\t\t}\n\n\t\t// UNPACK_FLIP_Y_WEBGL only works for DOM element sources, not typed arrays.\n\t\tconst isTypedArray = 'data' in source && source.data;\n\t\tconst shouldFlipY = !isTypedArray && !info.options?.preserveY;\n\t\tconst previousFlipY = this.gl.getParameter(this.gl.UNPACK_FLIP_Y_WEBGL);\n\n\t\tif (info.history) {\n\t\t\tconst isFramebufferHistory = name === HISTORY_TEXTURE_KEY;\n\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY, info.texture);\n\t\t\tif (isFramebufferHistory) {\n\t\t\t\tthis.gl.copyTexSubImage3D(\n\t\t\t\t\tthis.gl.TEXTURE_2D_ARRAY,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\tinfo.history.writeIndex,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\twidth,\n\t\t\t\t\theight\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, shouldFlipY);\n\t\t\t\tthis.gl.texSubImage3D(\n\t\t\t\t\tthis.gl.TEXTURE_2D_ARRAY,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\tinfo.history.writeIndex,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\t1,\n\t\t\t\t\tinfo.options?.format ?? this.gl.RGBA,\n\t\t\t\t\tinfo.options?.type ?? this.gl.UNSIGNED_BYTE,\n\t\t\t\t\t((source as PartialCustomTexture).data ?? (source as Exclude<TextureSource, CustomTexture>)) as any\n\t\t\t\t);\n\t\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);\n\t\t\t}\n\t\t\tconst frameOffsetUniformName = `${stringFrom(name)}FrameOffset`;\n\t\t\tthis.updateUniforms({ [frameOffsetUniformName]: info.history.writeIndex });\n\t\t\tinfo.history.writeIndex = (info.history.writeIndex + 1) % info.history.depth;\n\t\t} else {\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, info.texture);\n\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, shouldFlipY);\n\n\t\t\tconst format = info.options?.format ?? this.gl.RGBA;\n\t\t\tconst type = info.options?.type ?? this.gl.UNSIGNED_BYTE;\n\n\t\t\tif (isPartial) {\n\t\t\t\tthis.gl.texSubImage2D(\n\t\t\t\t\tthis.gl.TEXTURE_2D,\n\t\t\t\t\t0,\n\t\t\t\t\tsource.x ?? 0,\n\t\t\t\t\tsource.y ?? 0,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tformat,\n\t\t\t\t\ttype,\n\t\t\t\t\tsource.data\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst internalFormat =\n\t\t\t\t\tinfo.options?.internalFormat ??\n\t\t\t\t\t(isTypedArray ? (type === this.gl.FLOAT ? this.gl.RGBA32F : this.gl.RGBA8) : this.gl.RGBA);\n\t\t\t\tthis.gl.texImage2D(\n\t\t\t\t\tthis.gl.TEXTURE_2D,\n\t\t\t\t\t0,\n\t\t\t\t\tinternalFormat,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\t0,\n\t\t\t\t\tformat,\n\t\t\t\t\ttype,\n\t\t\t\t\t((source as PartialCustomTexture).data ?? (source as Exclude<TextureSource, CustomTexture>)) as any\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);\n\t\t}\n\t}\n\n\tdraw(clear = true) {\n\t\tconst gl = this.gl;\n\t\tgl.useProgram(this.program);\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n\t\tgl.vertexAttribPointer(this.aPositionLocation, 2, gl.FLOAT, false, 0, 0);\n\t\tgl.enableVertexAttribArray(this.aPositionLocation);\n\t\tgl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\t\tif (clear) gl.clear(gl.COLOR_BUFFER_BIT);\n\t\tgl.drawArrays(gl.TRIANGLES, 0, 6);\n\t}\n\n\tstep(time: number) {\n\t\tif (this.uniforms.has('u_time')) {\n\t\t\tthis.updateUniforms({ u_time: time });\n\t\t}\n\t\tif (this.uniforms.has('u_frame')) {\n\t\t\tthis.updateUniforms({ u_frame: this.frame });\n\t\t}\n\n\t\tthis.draw();\n\n\t\tif (this.textures.get(HISTORY_TEXTURE_KEY)) {\n\t\t\tthis.updateTexture(HISTORY_TEXTURE_KEY, this.canvas);\n\t\t}\n\t\tthis.hooks.get('step')?.forEach(hook => hook.call(this, time, this.frame));\n\t\t++this.frame;\n\t}\n\n\tplay(callback?: (time: number, frame: number) => void) {\n\t\tthis.pause(); // Prevent double play.\n\t\tconst loop = (time: number) => {\n\t\t\ttime = (time - this.startTime) / 1000; // Convert from milliseconds to seconds.\n\t\t\tthis.step(time);\n\t\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t\t\tif (callback) callback(time, this.frame);\n\t\t};\n\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t}\n\n\tpause() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\t}\n\n\treset() {\n\t\tthis.frame = 0;\n\t\tthis.startTime = performance.now();\n\t\tthis.textures.forEach(texture => {\n\t\t\tif (texture.history) {\n\t\t\t\ttexture.history.writeIndex = 0;\n\t\t\t\tthis.clearHistoryTextureLayers(texture);\n\t\t\t}\n\t\t});\n\t\tthis.hooks.get('reset')?.forEach(hook => hook.call(this));\n\t}\n\n\tdestroy() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\n\t\tthis.resolutionObserver.disconnect();\n\t\tthis.resizeObserver.disconnect();\n\t\tif (this.canvas instanceof HTMLCanvasElement) {\n\t\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\t\tthis.canvas.removeEventListener(event, listener);\n\t\t\t});\n\t\t}\n\n\t\tif (this.program) {\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t}\n\n\t\tthis.textures.forEach(texture => {\n\t\t\tthis.gl.deleteTexture(texture.texture);\n\t\t});\n\t\tthis.textureUnitPool.free = [];\n\t\tthis.textureUnitPool.next = 0;\n\n\t\tif (this.buffer) {\n\t\t\tthis.gl.deleteBuffer(this.buffer);\n\t\t\tthis.buffer = null;\n\t\t}\n\n\t\tthis.hooks.get('destroy')?.forEach(hook => hook.call(this));\n\n\t\tif (this.isInternalCanvas && this.canvas instanceof HTMLCanvasElement) {\n\t\t\tthis.canvas.remove();\n\t\t}\n\t}\n}\n\nexport default ShaderPad;\n"],"mappings":"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","names":["pose_exports","__export","pose_default","__toCommonJS","DEFAULT_VERTEX_SHADER_SRC","RESIZE_THROTTLE_INTERVAL","HISTORY_TEXTURE_KEY","combineShaderCode","shader","injections","lines","insertAt","line","trimmed","getSourceDimensions","source","stringFrom","name","ShaderPad","fragmentShaderSrc","options","htmlCanvas","glslInjections","context","code","plugin","fn","vertexShaderSrc","vertexShader","fragmentShader","hook","type","quadVertices","now","timeUntilNextResize","pixelRatio","width","height","updateCursor","x","y","rect","updateClick","isMouseDown","xVal","yVal","event","mouseEvent","touchEvent","listener","resolution","existing","textureInfo","transparent","layer","value","arrayLength","location","probeValue","length","error","args","updates","uniform","glFunctionName","nValues","item","typedArray","newLocation","historyDepth","texture","unitIndex","hasHistory","textureTarget","internalFormat","textureOptions","completeTextureInfo","uSampler","info","isPartial","isTypedArray","shouldFlipY","previousFlipY","isFramebufferHistory","frameOffsetUniformName","format","clear","gl","time","callback","loop","index_default","STANDARD_LANDMARK_COUNT","CUSTOM_LANDMARK_COUNT","LANDMARK_COUNT","LANDMARK_INDICES","ALL_STANDARD_INDICES","_","i","LEFT_HAND_INDICES","RIGHT_HAND_INDICES","LEFT_FOOT_INDICES","RIGHT_FOOT_INDICES","TORSO_INDICES","dummyTexture","pose","config","textureName","options","defaultModelPath","shaderPad","context","injectGLSL","gl","poseLandmarker","vision","lastVideoTime","runningMode","textureSources","maxPoses","LANDMARKS_TEXTURE_WIDTH","landmarksTextureHeight","landmarksDataArray","sharedCanvas","maskShader","initializePoseLandmarker","FilesetResolver","PoseLandmarker","error","calculateBoundingBoxCenter","poseIdx","landmarkIndices","minX","maxX","minY","maxY","avgZ","avgVisibility","idx","dataIdx","x","y","centerX","centerY","centerZ","centerVisibility","updateMaskTexture","segmentationMasks","mask","updateLandmarksTexture","poses","nPoses","totalLandmarks","landmarks","lmIdx","landmark","bodyCenter","bodyCenterIdx","leftHandCenter","leftHandCenterIdx","rightHandCenter","rightHandCenterIdx","leftFootCenter","leftFootCenterIdx","rightFootCenter","rightFootCenterIdx","torsoCenter","torsoCenterIdx","rowsToUpdate","processPoseResults","result","index_default","textureSize","updates","source","requiredMode","pose_default"]}
@@ -1,31 +1,52 @@
1
- var R=33,J=6,T=R+J,t={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:R,LEFT_HAND_CENTER:R+1,RIGHT_HAND_CENTER:R+2,LEFT_FOOT_CENTER:R+3,RIGHT_FOOT_CENTER:R+4,TORSO_CENTER:R+5};function Q(B){let{textureName:G,options:L}=B,Y="https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task";return function(c,W){let{injectGLSL:X,gl:x}=W,u=null,K=null,y=-1,h="VIDEO",w=new Map,v=L?.maxPoses??1,I=512,U=0,e=null,z=512,V=512,E=document.createElement("canvas");E.width=z,E.height=V;let M=E.getContext("2d"),f=document.createElement("canvas"),b=f.getContext("2d");M.globalCompositeOperation=b.globalCompositeOperation="lighten";async function j(){try{let{FilesetResolver:o,PoseLandmarker:n}=await import("@mediapipe/tasks-vision");K=await o.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"),u=await n.createFromOptions(K,{baseOptions:{modelAssetPath:L?.modelPath||Y},runningMode:h,numPoses:L?.maxPoses??1,minPoseDetectionConfidence:L?.minPoseDetectionConfidence??.5,minPosePresenceConfidence:L?.minPosePresenceConfidence??.5,minTrackingConfidence:L?.minTrackingConfidence??.5,outputSegmentationMasks:L?.outputSegmentationMasks??!0})}catch(o){throw console.error("[Pose Plugin] Failed to initialize Pose Landmarker:",o),o}}function O(o,n,r){let s=1/0,i=-1/0,l=1/0,_=-1/0,m=0,a=0;for(let F of r){let d=(n*T+F)*4,H=o[d],N=o[d+1];s=Math.min(s,H),i=Math.max(i,H),l=Math.min(l,N),_=Math.max(_,N),m+=o[d+2],a+=o[d+3]}let p=(s+i)/2,g=(l+_)/2,P=m/r.length,A=a/r.length;return[p,g,P,A]}async function Z(o){if(!u||!e){console.warn("[Pose Plugin] Cannot update mask: poseLandmarker or landmarksDataArray missing");return}try{M.clearRect(0,0,E.width,E.height),o&&o.length>0&&o.forEach(n=>{if(!n)return;let{width:r,height:s}=n,i=n.getAsUint8Array(),l=r*s,_=new Uint8ClampedArray(l*4);for(let a=0;a<l;a++)_[a*4+1]=i[a],_[a*4+3]=255;let m=new ImageData(_,r,s);r===E.width&&s===E.height?M.putImageData(m,0,0):(f.width!==r&&(f.width=r),f.height!==s&&(f.height=s),b.putImageData(m,0,0),M.drawImage(f,0,0,E.width,E.height))}),c.updateTextures({u_poseMask:E})}catch(n){console.error("[Pose Plugin] Failed to generate mask texture:",n)}}function q(o){if(!e)return;let n=o.length,r=n*T;for(let i=0;i<n;++i){let l=o[i];for(let D=0;D<R;++D){let C=l[D],S=(i*T+D)*4;e[S]=C.x,e[S+1]=1-C.y,e[S+2]=C.z??0,e[S+3]=C.visibility??1}let _=O(e,i,Array.from({length:R},(D,C)=>C)),m=(i*T+t.BODY_CENTER)*4;e[m]=_[0],e[m+1]=_[1],e[m+2]=_[2],e[m+3]=_[3];let a=O(e,i,[t.LEFT_WRIST,t.LEFT_PINKY,t.LEFT_THUMB,t.LEFT_INDEX]),p=(i*T+t.LEFT_HAND_CENTER)*4;e[p]=a[0],e[p+1]=a[1],e[p+2]=a[2],e[p+3]=a[3];let g=O(e,i,[t.RIGHT_WRIST,t.RIGHT_PINKY,t.RIGHT_THUMB,t.RIGHT_INDEX]),P=(i*T+t.RIGHT_HAND_CENTER)*4;e[P]=g[0],e[P+1]=g[1],e[P+2]=g[2],e[P+3]=g[3];let A=O(e,i,[t.LEFT_ANKLE,t.LEFT_HEEL,t.LEFT_FOOT_INDEX]),F=(i*T+t.LEFT_FOOT_CENTER)*4;e[F]=A[0],e[F+1]=A[1],e[F+2]=A[2],e[F+3]=A[3];let d=O(e,i,[t.RIGHT_ANKLE,t.RIGHT_HEEL,t.RIGHT_FOOT_INDEX]),H=(i*T+t.RIGHT_FOOT_CENTER)*4;e[H]=d[0],e[H+1]=d[1],e[H+2]=d[2],e[H+3]=d[3];let N=O(e,i,[t.LEFT_SHOULDER,t.RIGHT_SHOULDER,t.LEFT_HIP,t.RIGHT_HIP]),k=(i*T+t.TORSO_CENTER)*4;e[k]=N[0],e[k+1]=N[1],e[k+2]=N[2],e[k+3]=N[3]}let s=Math.ceil(r/I);c.updateTextures({u_poseLandmarksTex:{data:e,width:I,height:s}})}function $(o){if(!o.landmarks||!e)return;let n=o.landmarks.length;q(o.landmarks),Z(o.segmentationMasks).catch(r=>{console.warn("[Pose Plugin] Mask texture update error:",r)}),c.updateUniforms({u_nPoses:n}),L?.onResults?.(o)}c.registerHook("init",async()=>{c.initializeTexture("u_poseMask",E),c.initializeUniform("u_maxPoses","int",v),c.initializeUniform("u_nPoses","int",0);let o=v*T;U=Math.ceil(o/I);let n=I*U*4;e=new Float32Array(n),c.initializeTexture("u_poseLandmarksTex",{data:e,width:I,height:U},{internalFormat:x.RGBA32F,type:x.FLOAT,minFilter:x.NEAREST,magFilter:x.NEAREST}),await j()}),c.registerHook("updateTextures",async o=>{let n=o[G];if(!(!n||(w.get(G)!==n&&(y=-1),w.set(G,n),!u)))try{let s=n instanceof HTMLVideoElement?"VIDEO":"IMAGE";if(h!==s&&(h=s,await u.setOptions({runningMode:h})),n instanceof HTMLVideoElement){if(n.videoWidth===0||n.videoHeight===0||n.readyState<2)return;if(n.currentTime!==y){y=n.currentTime;let i=performance.now(),l=u.detectForVideo(n,i);$(l)}}else if(n instanceof HTMLImageElement||n instanceof HTMLCanvasElement){if(n.width===0||n.height===0)return;let i=u.detect(n);$(i)}}catch(s){console.error("[Pose Plugin] Pose detection error:",s)}}),c.registerHook("destroy",()=>{u&&(u.close(),u=null),K=null,w.clear(),E.remove(),e=null}),X(`
1
+ import{a as b}from"../chunk-RKULNJXI.mjs";var T=33,Z=6,r=T+Z,n={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:T,LEFT_HAND_CENTER:T+1,RIGHT_HAND_CENTER:T+2,LEFT_FOOT_CENTER:T+3,RIGHT_FOOT_CENTER:T+4,TORSO_CENTER:T+5},q=Array.from({length:T},(w,x)=>x),J=[n.LEFT_WRIST,n.LEFT_PINKY,n.LEFT_THUMB,n.LEFT_INDEX],Q=[n.RIGHT_WRIST,n.RIGHT_PINKY,n.RIGHT_THUMB,n.RIGHT_INDEX],ee=[n.LEFT_ANKLE,n.LEFT_HEEL,n.LEFT_FOOT_INDEX],ne=[n.RIGHT_ANKLE,n.RIGHT_HEEL,n.RIGHT_FOOT_INDEX],te=[n.LEFT_SHOULDER,n.RIGHT_SHOULDER,n.LEFT_HIP,n.RIGHT_HIP],Y={data:new Uint8Array(4),width:1,height:1};function oe(w){let{textureName:x,options:d}=w,B="https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task";return function(a,z){let{injectGLSL:W,gl:P}=z,c=null,G=null,h=-1,C="VIDEO",v=new Map,K=d?.maxPoses??1,m=512,y=0,e=null,U=new OffscreenCanvas(1,1),s=null;async function X(){try{let{FilesetResolver:o,PoseLandmarker:t}=await import("@mediapipe/tasks-vision");G=await o.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"),c=await t.createFromOptions(G,{baseOptions:{modelAssetPath:d?.modelPath||B,delegate:"GPU"},canvas:U,runningMode:C,numPoses:d?.maxPoses??1,minPoseDetectionConfidence:d?.minPoseDetectionConfidence??.5,minPosePresenceConfidence:d?.minPosePresenceConfidence??.5,minTrackingConfidence:d?.minTrackingConfidence??.5,outputSegmentationMasks:!0})}catch(o){throw console.error("[Pose Plugin] Failed to initialize:",o),o}}function N(o,t,u){let _=1/0,i=-1/0,D=1/0,l=-1/0,R=0,L=0;for(let F of u){let E=(t*r+F)*4,I=o[E],f=o[E+1];_=Math.min(_,I),i=Math.max(i,I),D=Math.min(D,f),l=Math.max(l,f),R+=o[E+2],L+=o[E+3]}let H=(_+i)/2,O=(D+l)/2,p=R/u.length,A=L/u.length;return[H,O,p,A]}function V(o){if(!(!o||o.length===0||!s)){for(let t=0;t<o.length;++t){let u=o[t];s.updateTextures({u_mask:u.getAsWebGLTexture()}),s.updateUniforms({u_poseIndex:(t+1)/K}),s.draw(t===0)}a.updateTextures({u_poseMask:U})}}function j(o){if(!e)return;let t=o.length,u=t*r;for(let i=0;i<t;++i){let D=o[i];for(let k=0;k<T;++k){let M=D[k],g=(i*r+k)*4;e[g]=M.x,e[g+1]=1-M.y,e[g+2]=M.z??0,e[g+3]=M.visibility??1}let l=N(e,i,q),R=(i*r+n.BODY_CENTER)*4;e[R]=l[0],e[R+1]=l[1],e[R+2]=l[2],e[R+3]=l[3];let L=N(e,i,J),H=(i*r+n.LEFT_HAND_CENTER)*4;e[H]=L[0],e[H+1]=L[1],e[H+2]=L[2],e[H+3]=L[3];let O=N(e,i,Q),p=(i*r+n.RIGHT_HAND_CENTER)*4;e[p]=O[0],e[p+1]=O[1],e[p+2]=O[2],e[p+3]=O[3];let A=N(e,i,ee),F=(i*r+n.LEFT_FOOT_CENTER)*4;e[F]=A[0],e[F+1]=A[1],e[F+2]=A[2],e[F+3]=A[3];let E=N(e,i,ne),I=(i*r+n.RIGHT_FOOT_CENTER)*4;e[I]=E[0],e[I+1]=E[1],e[I+2]=E[2],e[I+3]=E[3];let f=N(e,i,te),S=(i*r+n.TORSO_CENTER)*4;e[S]=f[0],e[S+1]=f[1],e[S+2]=f[2],e[S+3]=f[3]}let _=Math.ceil(u/m);a.updateTextures({u_poseLandmarksTex:{data:e,width:m,height:_,isPartial:!0}})}function $(o){if(!o.landmarks||!e)return;s||(s=new b(`#version 300 es
2
+ precision mediump float;
3
+ in vec2 v_uv;
4
+ out vec4 outColor;
5
+ uniform sampler2D u_mask;
6
+ uniform float u_poseIndex;
7
+ void main() {
8
+ ivec2 texCoord = ivec2(v_uv * vec2(textureSize(u_mask, 0)));
9
+ float confidence = texelFetch(u_mask, texCoord, 0).r;
10
+ if (confidence < 0.01) discard;
11
+ outColor = vec4(1.0, confidence, u_poseIndex, 1.0);
12
+ }`,{canvas:U}),s.initializeTexture("u_mask",Y),s.initializeUniform("u_poseIndex","float",0));let t=o.landmarks.length;j(o.landmarks),V(o.segmentationMasks),a.updateUniforms({u_nPoses:t}),d?.onResults?.(o)}a.registerHook("init",async()=>{a.initializeTexture("u_poseMask",Y,{preserveY:!0}),a.initializeUniform("u_maxPoses","int",K),a.initializeUniform("u_nPoses","int",0);let o=K*r;y=Math.ceil(o/m);let t=m*y*4;e=new Float32Array(t),a.initializeTexture("u_poseLandmarksTex",{data:e,width:m,height:y},{internalFormat:P.RGBA32F,type:P.FLOAT,minFilter:P.NEAREST,magFilter:P.NEAREST}),await X()}),a.registerHook("updateTextures",async o=>{let t=o[x];if(!(!t||(v.get(x)!==t&&(h=-1),v.set(x,t),!c)))try{let _=t instanceof HTMLVideoElement?"VIDEO":"IMAGE";if(C!==_&&(C=_,await c.setOptions({runningMode:C})),t instanceof HTMLVideoElement){if(t.videoWidth===0||t.videoHeight===0||t.readyState<2)return;if(t.currentTime!==h){h=t.currentTime;let i=c.detectForVideo(t,performance.now());$(i)}}else if(t instanceof HTMLImageElement||t instanceof HTMLCanvasElement){if(t.width===0||t.height===0)return;let i=c.detect(t);$(i)}}catch(_){console.error("[Pose Plugin] Detection error:",_)}}),a.registerHook("destroy",()=>{c&&(c.close(),c=null),s&&(s.destroy(),s=null),G=null,v.clear(),e=null}),W(`
2
13
  uniform int u_maxPoses;
3
14
  uniform int u_nPoses;
4
15
  uniform sampler2D u_poseLandmarksTex;
5
16
  uniform sampler2D u_poseMask;
6
17
 
7
- #define POSE_LANDMARK_LEFT_EYE ${t.LEFT_EYE}
8
- #define POSE_LANDMARK_RIGHT_EYE ${t.RIGHT_EYE}
9
- #define POSE_LANDMARK_LEFT_SHOULDER ${t.LEFT_SHOULDER}
10
- #define POSE_LANDMARK_RIGHT_SHOULDER ${t.RIGHT_SHOULDER}
11
- #define POSE_LANDMARK_LEFT_ELBOW ${t.LEFT_ELBOW}
12
- #define POSE_LANDMARK_RIGHT_ELBOW ${t.RIGHT_ELBOW}
13
- #define POSE_LANDMARK_LEFT_HIP ${t.LEFT_HIP}
14
- #define POSE_LANDMARK_RIGHT_HIP ${t.RIGHT_HIP}
15
- #define POSE_LANDMARK_LEFT_KNEE ${t.LEFT_KNEE}
16
- #define POSE_LANDMARK_RIGHT_KNEE ${t.RIGHT_KNEE}
17
- #define POSE_LANDMARK_BODY_CENTER ${t.BODY_CENTER}
18
- #define POSE_LANDMARK_LEFT_HAND_CENTER ${t.LEFT_HAND_CENTER}
19
- #define POSE_LANDMARK_RIGHT_HAND_CENTER ${t.RIGHT_HAND_CENTER}
20
- #define POSE_LANDMARK_LEFT_FOOT_CENTER ${t.LEFT_FOOT_CENTER}
21
- #define POSE_LANDMARK_RIGHT_FOOT_CENTER ${t.RIGHT_FOOT_CENTER}
22
- #define POSE_LANDMARK_TORSO_CENTER ${t.TORSO_CENTER}
18
+ #define POSE_LANDMARK_LEFT_EYE ${n.LEFT_EYE}
19
+ #define POSE_LANDMARK_RIGHT_EYE ${n.RIGHT_EYE}
20
+ #define POSE_LANDMARK_LEFT_SHOULDER ${n.LEFT_SHOULDER}
21
+ #define POSE_LANDMARK_RIGHT_SHOULDER ${n.RIGHT_SHOULDER}
22
+ #define POSE_LANDMARK_LEFT_ELBOW ${n.LEFT_ELBOW}
23
+ #define POSE_LANDMARK_RIGHT_ELBOW ${n.RIGHT_ELBOW}
24
+ #define POSE_LANDMARK_LEFT_HIP ${n.LEFT_HIP}
25
+ #define POSE_LANDMARK_RIGHT_HIP ${n.RIGHT_HIP}
26
+ #define POSE_LANDMARK_LEFT_KNEE ${n.LEFT_KNEE}
27
+ #define POSE_LANDMARK_RIGHT_KNEE ${n.RIGHT_KNEE}
28
+ #define POSE_LANDMARK_BODY_CENTER ${n.BODY_CENTER}
29
+ #define POSE_LANDMARK_LEFT_HAND_CENTER ${n.LEFT_HAND_CENTER}
30
+ #define POSE_LANDMARK_RIGHT_HAND_CENTER ${n.RIGHT_HAND_CENTER}
31
+ #define POSE_LANDMARK_LEFT_FOOT_CENTER ${n.LEFT_FOOT_CENTER}
32
+ #define POSE_LANDMARK_RIGHT_FOOT_CENTER ${n.RIGHT_FOOT_CENTER}
33
+ #define POSE_LANDMARK_TORSO_CENTER ${n.TORSO_CENTER}
23
34
 
24
35
  vec4 poseLandmark(int poseIndex, int landmarkIndex) {
25
- int i = poseIndex * ${T} + landmarkIndex;
26
- int x = i % ${I};
27
- int y = i / ${I};
36
+ int i = poseIndex * ${r} + landmarkIndex;
37
+ int x = i % ${m};
38
+ int y = i / ${m};
28
39
  return texelFetch(u_poseLandmarksTex, ivec2(x, y), 0);
29
40
  }
30
- float inBody(vec2 pos) { return texture(u_poseMask, pos).g; }`)}}var ee=Q;export{ee as default};
41
+
42
+ vec2 poseAt(vec2 pos) {
43
+ vec4 mask = texture(u_poseMask, pos);
44
+ float poseIndex = floor(mask.b * float(u_maxPoses) + 0.5) - 1.0;
45
+ return vec2(mask.g, poseIndex);
46
+ }
47
+
48
+ float inPose(vec2 pos) {
49
+ float pose = poseAt(pos).x;
50
+ return step(0.0, pose);
51
+ }`)}}var ae=oe;export{ae as default};
31
52
  //# sourceMappingURL=pose.mjs.map