three-mediapipe-rig 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +254 -0
- package/dist/module.d.ts +2 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/three-mediapipe-rig.js +611 -0
- package/dist/three-mediapipe-rig.js.map +1 -0
- package/dist/tracking/BoneMapping.d.ts +54 -0
- package/dist/tracking/BoneMapping.d.ts.map +1 -0
- package/dist/tracking/FaceTracker.d.ts +40 -0
- package/dist/tracking/FaceTracker.d.ts.map +1 -0
- package/dist/tracking/HandTracker.d.ts +70 -0
- package/dist/tracking/HandTracker.d.ts.map +1 -0
- package/dist/tracking/PoseTracker.d.ts +57 -0
- package/dist/tracking/PoseTracker.d.ts.map +1 -0
- package/dist/tracking/Tracker.d.ts +36 -0
- package/dist/tracking/Tracker.d.ts.map +1 -0
- package/dist/tracking/util/cleanBoneName.d.ts +2 -0
- package/dist/tracking/util/cleanBoneName.d.ts.map +1 -0
- package/dist/tracking/util/getBoneByName.d.ts +3 -0
- package/dist/tracking/util/getBoneByName.d.ts.map +1 -0
- package/dist/tracking/util/getRootPosition.d.ts +10 -0
- package/dist/tracking/util/getRootPosition.d.ts.map +1 -0
- package/dist/tracking/util/lookAt.d.ts +11 -0
- package/dist/tracking/util/lookAt.d.ts.map +1 -0
- package/dist/tracking/util/vectorSign.d.ts +25 -0
- package/dist/tracking/util/vectorSign.d.ts.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"three-mediapipe-rig.js","sources":["../src/tracking/util/lookAt.ts","../src/tracking/Tracker.ts","../src/tracking/util/getRootPosition.ts","../src/tracking/util/cleanBoneName.ts","../src/tracking/util/getBoneByName.ts","../src/tracking/PoseTracker.ts","../src/tracking/HandTracker.ts","../src/tracking/FaceTracker.ts","../src/tracking/BoneMapping.ts","../src/tracking/TrackerManager.ts"],"sourcesContent":["import { Object3D, Quaternion, Vector3 } from \"three/webgpu\";\n\nconst poleDir = new Vector3();\nconst objectPosition = new Vector3();\n\nconst XAxis = new Vector3(1,0,0);\nconst XAxisNeg = new Vector3(-1,0,0);\nconst YAxis = new Vector3(0,1,0); \nconst YAxisNeg = new Vector3(0,-1,0); \nconst ZAxis = new Vector3(0,0,1); \nconst ZAxisNeg = new Vector3(0,0,-1); \n\nconst pole = new Vector3();\nconst lookDir = new Vector3();\n\nconst v = new Vector3();\nconst correction = new Quaternion();\nconst worldQuat = new Quaternion();\n\nexport type LookAtPoleAxis = \"+x\"|\"+y\"|\"-x\"|\"-y\"\n\n/**\n * Will point the Z axis of object at target and the X or Y axis in the general direction of the pole target\n * @param object The object to rotate\n * @param target The point to look at ( in world coord )\n * @param poleTarget The goal of the pole axis ( in world coord )\n * @param poleAxis The axis to use as the pole axis ( z is the one pointing at the target )\n */\nexport function lookAt( object:Object3D, target:Vector3, poleTarget:Vector3, poleAxis:LookAtPoleAxis = \"+x\" )\n{ \n\t//\n\t// look at target (handles parent transforms internally)\n\t// \n\tobject.lookAt(target);\n\n\tconst axis = poleAxis==\"+x\"?XAxis: poleAxis==\"-x\"?XAxisNeg: poleAxis==\"+y\"?YAxis: YAxisNeg;\n\n\tobject.getWorldPosition(objectPosition);\n\tobject.getWorldQuaternion(worldQuat);\n\n\tpoleDir.subVectors(poleTarget, objectPosition).normalize();\n\n\t// direction in which the pole axis is currently pointing (in world space)\n\tpole.copy(axis).applyQuaternion(worldQuat);\n\n\tconst currentPole = pole;\n\n\t// look direction in world space\n\tconst lookAxisDir = lookDir.copy( ZAxis ).applyQuaternion(worldQuat);\n\n\t// project desired pole direction onto the plane perpendicular to the look axis\n\tconst desiredPoleDir = poleDir.clone().addScaledVector(lookAxisDir, -poleDir.dot(lookAxisDir)).normalize();\n\n\t// signed angle between current pole and desired pole around the look axis\n\tconst cross = v.crossVectors(currentPole, desiredPoleDir);\n\tconst angle = Math.atan2(cross.dot(lookAxisDir), currentPole.dot(desiredPoleDir));\n\n\t// The correction is a spin around the look axis (local Z after lookAt).\n\t// Since lookAt aligned local Z to the target, we can apply around the local Z axis directly.\n\tcorrection.setFromAxisAngle(ZAxis, angle);\n\tobject.quaternion.multiply(correction);\n}","import * as THREE from \"three/webgpu\";\nimport {\n Landmark,\n NormalizedLandmark,\n\tDrawingUtils, \n} from \"@mediapipe/tasks-vision\"; \nimport { lookAt, LookAtPoleAxis } from \"./util/lookAt\";\n\n \n\nconst v = new THREE.Vector3();\nconst A = new THREE.Vector3();\nconst B = new THREE.Vector3();\nconst C = new THREE.Vector3();\n\nexport class Tracker<T extends Record<string, number|number[]> > {\n\tprivate objectGhost : Map<THREE.Object3D, Ghost> ;\n\treadonly root:THREE.Object3D;\n\n\t/**\n\t * per landmark index, it points to it's object3D equivalent.\n\t */\n\tprotected marks: { [name in keyof T]: Mark } = {} as { [name in keyof T]: Mark };\n\n\tconstructor( protected readonly points:T, private readonly debugConnections?:{start:number,end:number}[] ){\n\t\tthis.root = new THREE.Object3D();\n\t\tthis.objectGhost = new Map();\n\n\t\t// por each key in points\n\t\tfor( let key in this.points ){\n\t\t\tthis.marks[key] = new Mark();\n \n\t\t\tthis.root.add(this.marks[key]);\n\t\t}\n\t}\n\n\tprotected updateLandmarks( landmarks:Landmark[], debugLandmarks?:NormalizedLandmark[], debugDrawer?:DrawingUtils ) {\n\t\tfor( let key in this.points ){\n\t\t\tconst point = this.points[key];\n\t\t\tconst mark = this.marks[key];\n\t\t\tif( mark ){\n\t\t\t\tif( point instanceof Array )\n\t\t\t\t{\n\t\t\t\t\t\n\t\t\t\t\tv.copy( landmarks[ point[0] ] ) \n\t\t\t\t\tmark.position.copy( landmarks[ point[1] ] ).sub( v ).divideScalar(2).add(landmarks[ point[0] ]);\n\t\t\t\t\t\n\t\t\t\t\tif( point.length==4 )\n\t\t\t\t\t{\n\t\t\t\t\t\tv.subVectors(\n\t\t\t\t\t\t\tlandmarks[ point[3] ],\n\t\t\t\t\t\t\tlandmarks[ point[2] ]\n\t\t\t\t\t\t).divideScalar(2).add(landmarks[ point[2] ]) \n\n\t\t\t\t\t\t.sub( mark.position )\n\t\t\t\t\t\t.divideScalar(2) \n\n\t\t\t\t\t\tmark.position.add( v );\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\telse \n\t\t\t\t{\n\t\t\t\t\tmark.position.copy( landmarks[ point as number ] )\n\t\t\t\t}\n \n\t\t\t}\n\t\t}\n\n\t\tif( debugDrawer && debugLandmarks )\n\t\t{ \n\t\t\t// debugDrawer.drawLandmarks(debugLandmarks, {\n\t\t\t// \tradius: (data) =>\n\t\t\t// \t\tDrawingUtils.lerp(data.from!.z, -0.15, 0.1, 5, 1),\n\t\t\t// \tlineWidth:1\n\t\t\t// });\n\t\t\tdebugDrawer.drawConnectors(\n\t\t\t\tdebugLandmarks,\n\t\t\t\tthis.debugConnections,\n\t\t\t\t{\n\t\t\t\t\tlineWidth:1\n\t\t\t\t}\n\t\t\t); \n\t\t}\n\t}\n\n\tprotected getGhost( object:THREE.Object3D ){\n\t\tif( !this.objectGhost.has(object)) \n\t\t{\n\t\t\tconst o = new Ghost()\n\n\t\t\to.position.copy(object.position)\n\t\t\to.quaternion.copy(object.quaternion)\n\t\t\tobject.parent?.add(o);\n\n\t\t\tthis.objectGhost.set(object, o)\n\t\t} \n\t\treturn this.objectGhost.get(object)!;\n\t}\n\n\tpredict( source:TexImageSource, drawingUtils:DrawingUtils ){\n\t\tthrow new Error(\"Method 'predict' must be implemented.\");\n\t}\n\n\tsync ( delta:number, objects: [THREE.Object3D, keyof T, keyof T, LookAtPoleAxis][] ) {\n\t\tthrow new Error(\"Method 'sync' must be implemented.\"); \n\t}\n\n\ttest( key:keyof T ){\n\t\tthis.marks[key]!.position.set(1,2,3)\n\t}\n\n\tprotected syncObjects(objects: [THREE.Object3D, keyof T, keyof T,LookAtPoleAxis][], delta:number, normal:THREE.Vector3 ){\n\t\tfor( const [object, root, target, poleAxis] of objects ){\n\n\t\t\t//\n\t\t\t// position A and B where the landmarks are\n\t\t\t//\n\t\t\tthis.marks[target].getWorldPosition(B)\n\t\t\tthis.marks[root].getWorldPosition(A)\n\n\t\t\t//\n\t\t\t// calcuate the offset\n\t\t\t//\n\t\t\tconst offset = B.sub(A); // offset from root to taget in world units\n\n\t\t\t//\n\t\t\t// now position A in object position\n\t\t\t//\n\t\t\tobject.getWorldPosition(A)\n\n\t\t\t//\n\t\t\t// and displace it by the offset ( this will be the look at target )\n\t\t\t//\n\t\t\tA.add(offset);\n\n\t\t\t \n\t\t\tconst objectLookAtGoal = A;\n\t\t\tconst polePosition = object.getWorldPosition(B).sub( normal )\n\n\t\t\tconst ghost = this.getGhost(object);\n \n\n\t\t\t \n\t\t\t\tlookAt( ghost, objectLookAtGoal, polePosition, poleAxis);\n\n\t\t\t\tghost.rotateX( Math.PI/2) \n\t\t\t\n\t\t\t//ghost.rotateY( Math.PI/2)\n\n\t\t\tobject.position.lerp(ghost.position, delta * 4)\n\t\t\tobject.quaternion.slerp(ghost.quaternion, delta * 4) \n\t\t}\n\t}\n\n\tprotected getBone( rig:THREE.Object3D, name:string ){\n\t\treturn rig.getObjectByName(name.replace(/[\\.\\:]/g,\"\")) ;\n\t}\n}\n\n// const t = {\n// \tpepe:[1,2]\n// }\n// const d = new Tracker(t)\n// d.test(\"pepe\")\n\nclass Mark extends THREE.Mesh {\n\tprivate _worldPosition = new THREE.Vector3();\n\tconstructor() {\n\t\tsuper(new THREE.SphereGeometry(0.01,3,3), new THREE.MeshStandardMaterial({ color: 0xff0000, wireframe:true }));\n\t\tthis.add( new THREE.AxesHelper(0.001))\n\t}\n\n\tget worldPosition(){\n\t\tthis.getWorldPosition(this._worldPosition);\n\t\treturn this._worldPosition;\n\t}\n}\n\nclass Ghost extends THREE.Object3D { \n\tlerp( target:THREE.Object3D, delta:number, speed = 8 )\n\t{\n\t\ttarget.position.lerp(this.position, delta * speed)\n\t\ttarget.quaternion.slerp(this.quaternion, delta * speed) \n\t}\n}","import { Object3D, Vector3 } from \"three/webgpu\";\n\n\n/**\n * Gets the position of `object` relative to `root`.\n * @param out \n * @param object \n * @param root \n * @returns \n */\nexport function rootPosition( out:Vector3, object:Object3D, root:Object3D ) {\n\n\troot.worldToLocal( object.getWorldPosition(out) )\n\n\treturn out;\n}","export function cleanBoneName(name:string) {\n\treturn name.replace(/[\\.\\:]/g,\"\")\n}","import { Bone, Object3D } from \"three\";\nimport { cleanBoneName } from \"./cleanBoneName\";\n\nexport function getBoneByName(rig:Object3D, name:string) {\n\tlet bone:Bone|undefined;\n\tname = cleanBoneName(name); \n\t\n\trig.traverse( (o:Object3D) => {\n\t\tif( o.name.indexOf(name)===0 && o instanceof Bone ) bone = o as Bone;\n\t})\n\n\tif( !bone ) console.log(\"Bone not found: \", name, rig.name)\n\n\treturn bone;\n}","import {\n DrawingUtils,\n NormalizedLandmark,\n PoseLandmarker,\n} from \"@mediapipe/tasks-vision\"; \nimport * as THREE from \"three/webgpu\";\nimport { lookAt, LookAtPoleAxis } from \"./util/lookAt\";\nimport { Tracker } from \"./Tracker\";\nimport { rootPosition } from \"./util/getRootPosition\";\nimport { getBoneByName } from \"./util/getBoneByName\";\nimport { BoneMap } from \"./BoneMapping\";\n\nexport async function loadPoseTracker(vision: any, config?:Partial<PoseTrackerConfig>) {\n\tconst poseLandmarker = await PoseLandmarker.createFromOptions(vision, {\n baseOptions: { \n\t\t\tmodelAssetPath: config?.modelPath ?? \"pose_landmarker_lite.task\",\n //modelAssetPath: `https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task`,\n //modelAssetPath: \"https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_heavy/float16/latest/pose_landmarker_heavy.task\",\n delegate: \"GPU\",\n },\n runningMode: \"VIDEO\",\n numPoses: 1,\n });\n\n\treturn new PoseTracker(poseLandmarker, config);\n} \n\n/**\n * Points derived from https://ai.google.dev/static/mediapipe/images/solutions/pose_landmarks_index.png\n * If the array has 2 elements, the point is between those 2 landmarks.\n * If it has 4, the point is at the center of those 4 landmarks.\n */\nconst poseMarks = {\n\t\t\thips: [24,23],\n\t\t\tneck: [12,11],\n\t\t\tleftLeg: 23,\n\t\t\tleftKnee:25,\n\t\t\tleftArm: 11,\n\t\t\tleftElbow: 13,\n\t\t\tleftWrist: 15,\n\t\t\trightLeg: 24,\n\t\t\trightKnee: 26,\n\t\t\trightArm: 12,\n\t\t\trightElbow: 14,\n\t\t\trightWrist: 16, \n\t\t\thead: [8,7] //between the ears\n\t\t\t, mouth:[10,9]\n\t\t\t, torso: [24,23, 12,11] //at the center of the torso\n\t\t\t, leftEar: 7\n\t\t\t, rightEar: 8\n\t\t} ;\n\ntype MarkKey = keyof typeof poseMarks;\n\ntype BoneBinding = [THREE.Object3D, MarkKey, MarkKey,LookAtPoleAxis]\n\nconst A = new THREE.Vector3();\nconst B = new THREE.Vector3();\nconst C = new THREE.Vector3();\nconst D = new THREE.Vector3();\nconst E = new THREE.Vector3();\nconst lookGoal = new THREE.Vector3();\nconst poleGoal = new THREE.Vector3();\n\ntype PoseTrackerConfig = {\n\tignoreLegs:boolean\n\tmodelPath:string\n}\n\n/**\n * @see https://ai.google.dev/edge/mediapipe/solutions/vision/pose_landmarker\n */\nclass PoseTracker extends Tracker<typeof poseMarks> {\n\tprivate _leftWristNormalizedPosition!:NormalizedLandmark;\n\tprivate _rightWristNormalizedPosition!:NormalizedLandmark;\n\n\t/**\n\t * Position of the left wrist in normalized coordinates (0..1)\n\t */\n\tget leftWristNormalizedPosition() { return this._leftWristNormalizedPosition; }\n\n\t/**\n\t * Position of the right wrist in normalized coordinates (0..1)\n\t */\n\tget rightWristNormalizedPosition() { return this._rightWristNormalizedPosition; }\n\n\tconstructor(private readonly poseLandmarker:PoseLandmarker, private readonly config?:Partial<PoseTrackerConfig>){ \n\n\t\tsuper(poseMarks, PoseLandmarker.POSE_CONNECTIONS)\n\t\t\n\t\tthis.root.scale.y *= -2\n\t\tthis.root.scale.z *= -2\n\t\tthis.root.scale.x *= 2 \n\t}\n\n\toverride predict( source:TexImageSource, drawingUtils:DrawingUtils ){\n\t\tthis.poseLandmarker.detectForVideo( source, performance.now(), (result) => {\n\n\t\t\tif( result.landmarks.length==0 )\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n \n\t\t\tthis.updateLandmarks( result.worldLandmarks[0], result.landmarks[0], drawingUtils );\n\n\t\t\t\n\t\t\tthis._leftWristNormalizedPosition = result.landmarks[0][ this.points.leftWrist ];\n\t\t\tthis._rightWristNormalizedPosition = result.landmarks[0][ this.points.rightWrist ];\n\t\t} );\n\t}\n\n\t// override sync ( delta:number, objects: BoneBinding[] ) {\n\n\t// \tconst hipsPos = this.marks.hips.getWorldPosition(C); \n\n\t// \tthis.marks.rightArm.getWorldPosition(A).sub(hipsPos);\n\t// \tthis.marks.leftArm.getWorldPosition(B).sub(hipsPos); \n\n\t// \tconst torsoNormal = C.crossVectors(A,B);\n\n\t// \tthis.syncObjects(objects, delta, torsoNormal); \n\n\t// }\n\t\n\n\tbind( rig:THREE.Object3D, magging:BoneMap )\n\t{ \n\t\t \n\t\tconst map : { [key in MarkKey]?:THREE.Object3D } = {\n\t\t\t\"hips\": getBoneByName(rig, magging.hips),\n\t\t\t\"neck\": getBoneByName(rig, magging.neck),\n\t\t\t\"leftArm\": getBoneByName(rig, magging.armL),\n\t\t\t\"leftElbow\": getBoneByName(rig, magging.forearmL),\n\t\t\t\"leftWrist\": getBoneByName(rig, magging.handL),\n\t\t\t\"rightArm\": getBoneByName(rig, magging.armR),\n\t\t\t\"rightElbow\": getBoneByName(rig, magging.forearmR),\n\t\t\t\"rightWrist\": getBoneByName(rig, magging.handR),\n\t\t\t\"head\": getBoneByName(rig, magging.head), \n\t\t\t\"torso\": getBoneByName(rig, magging.torso),\n\t\t\t\"leftLeg\": getBoneByName(rig, magging.thighL),\n\t\t\t\"leftKnee\": getBoneByName(rig, magging.shinL),\n\t\t\t\"rightLeg\": getBoneByName(rig, magging.thighR),\n\t\t\t\"rightKnee\": getBoneByName(rig, magging.shinR),\n\t\t} \n\n\t\tif( this.config?.ignoreLegs ){\n\t\t\tdelete map.leftLeg\n\t\t\tdelete map.leftKnee\n\t\t\tdelete map.rightLeg\n\t\t\tdelete map.rightKnee\n\t\t}\n\n\t\tconst v = new THREE.Vector3();\n\t\tconst v2 = new THREE.Vector3();\n\n\t\tconst syncBone = ( delta:number, bone:THREE.Object3D|undefined, from:MarkKey, to:MarkKey, sideAxis:THREE.Vector3, poleAxis:LookAtPoleAxis ) => {\n\t\t\tif( !bone ) return;\n\n\t\t\tconst hipsDir = this.marks[to].getWorldPosition(v).sub(this.marks[from].getWorldPosition(v2)).normalize(); \n\n\t\t \n\t\t\trootPosition(lookGoal, bone, rig).add( hipsDir ).applyMatrix4(rig.matrixWorld) ;\n\t\t\trootPosition(poleGoal, bone, rig).add( sideAxis ).applyMatrix4(rig.matrixWorld) ; \n\n\t\t\tconst ghost = this.getGhost(bone)\n\n\t\t\tlookAt(ghost, lookGoal, poleGoal, poleAxis)\n\t\t\tghost.rotateX(Math.PI/2)\n\t\t\t \n\n\t\t\tghost.lerp(bone, delta)\n\t\t}\n\n\t\treturn {\n\t\t\tupdate: (delta:number)=>{\n \n\t\t\t\tconst sideHips = this.marks.leftLeg.getWorldPosition(A).sub(this.marks.rightLeg.getWorldPosition(B)).normalize();\n\t\t\t\tconst sideShoulders = this.marks.leftArm.getWorldPosition(B).sub(this.marks.rightArm.getWorldPosition(C)).normalize();\n\t\t\t\tconst sideHead = this.marks.leftEar.getWorldPosition(D).sub(this.marks.rightEar.getWorldPosition(E)).normalize();\n\n\t\t\t\tsyncBone(delta, map.hips, \"hips\", \"torso\", sideHips, \"+x\")\n\t\t\t\tsyncBone(delta, map.torso, \"torso\", \"neck\", sideShoulders, \"+x\")\n\t\t\t\tsyncBone(delta, map.neck, \"neck\", \"head\", sideHead, \"+x\")\n\t\t\t\tsyncBone(delta, map.head, \"neck\", \"head\", sideHead, \"+x\")\n\n\t\t\t\tsyncBone(delta, map.leftArm, \"leftArm\", \"leftElbow\", sideShoulders, \"-x\")\n\t\t\t\tsyncBone(delta, map.leftElbow, \"leftElbow\", \"leftWrist\", sideShoulders, \"-x\")\n\t\t\t\tsyncBone(delta, map.leftLeg, \"leftLeg\", \"leftKnee\", sideHips, \"-x\") \n\n\t\t\t\tsyncBone(delta, map.rightArm, \"rightArm\", \"rightElbow\", sideShoulders, \"-x\")\n\t\t\t\tsyncBone(delta, map.rightElbow, \"rightElbow\", \"rightWrist\", sideShoulders, \"-x\")\n\t\t\t\tsyncBone(delta, map.rightLeg, \"rightLeg\", \"rightKnee\", sideHips, \"-x\") \n\t\t\t\t\n\t\t\t}\n\t\t}\n\t}\n}\n ","import {\n\tDrawingUtils,\n HandLandmarker,\n\tHandLandmarkerOptions,\n\tNormalizedLandmark,\n} from \"@mediapipe/tasks-vision\";\nimport * as THREE from \"three/webgpu\";\nimport { lookAt, LookAtPoleAxis } from \"./util/lookAt\";\nimport { Tracker } from \"./Tracker\";\nimport { rootPosition } from \"./util/getRootPosition\";\nimport { getBoneByName } from \"./util/getBoneByName\";\nimport { BoneMap } from \"./BoneMapping\";\n\nexport type HandsTrackerConfig = {\n\tleftWrist: ()=>NormalizedLandmark;\n\trightWrist: ()=>NormalizedLandmark;\n\tmodelPath?:string\n} & Partial<HandLandmarkerOptions>;\n\nconst A = new THREE.Vector2();\nconst B = new THREE.Vector2();\n\nexport async function loadHandTracker(vision: any, config:HandsTrackerConfig ) {\n const landmarker = await HandLandmarker.createFromOptions(vision, {\n baseOptions: {\n modelAssetPath: config.modelPath ?? \"hand_landmarker.task\",\n //modelAssetPath: `https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task`,\n delegate: \"GPU\",\n },\n runningMode: \"VIDEO\",\n numHands: 2,\n });\n\n\tconst isMyWrist = ( myWrist:()=>NormalizedLandmark, otherWrist:()=>NormalizedLandmark, handWrist:NormalizedLandmark ) => {\n\t\tA.copy(myWrist());\n\t\tB.copy(otherWrist());\n\t\treturn A.distanceTo(handWrist) < B.distanceTo(handWrist);\n\t}\n\n return {\n\t\tleft:new HandsTracker(landmarker, \"Left\", isMyWrist.bind(null, config.leftWrist, config.rightWrist) ),\n\t\tright:new HandsTracker(landmarker, \"Right\", isMyWrist.bind(null, config.rightWrist, config.leftWrist) )\n\t};\n}\n\nconst handMarks = {\n wrist: 0,\n\tpalm: [9,13],\n\n thumb1: 1,\n thumb2: 2,\n thumb3: 3,\n thumb4: 4,\n\n index1: 5,\n index2: 6,\n index3: 7,\n index4: 8,\n\n middle1: 9,\n middle2: 10,\n middle3: 11,\n middle4: 12,\n\n ring1: 13,\n ring2: 14,\n ring3: 15,\n ring4: 16,\n\n pinky1: 17,\n pinky2: 18,\n pinky3: 19,\n pinky4: 20,\n};\n\nexport type HandMarkName = keyof typeof handMarks;\n\nconst fingerKeys = {\n\tthumb: [\"thumb1\",\"thumb2\",\"thumb3\",\"thumb4\"],\n\tindex: [\"index1\",\"index2\",\"index3\",\"index4\"],\n\tmiddle: [\"middle1\",\"middle2\",\"middle3\",\"middle4\"],\n\tring: [\"ring1\",\"ring2\",\"ring3\",\"ring4\"],\n\tpinky: [\"pinky1\",\"pinky2\",\"pinky3\",\"pinky4\"]\n} as { [key:string]: HandMarkName[]} ;\n\n\ntype HandSide = \"Left\" | \"Right\"\nexport type Mark2Bone = Partial<{ [key in HandMarkName]: THREE.Object3D }>;\n\nconst v1 = new THREE.Vector3();\nconst v2 = new THREE.Vector3();\nconst v3 = new THREE.Vector3();\nconst v4 = new THREE.Vector3();\nconst v5 = new THREE.Vector3();\nconst v6 = new THREE.Vector3();\n\nconst currNormal = new THREE.Vector3();\nconst currForward = new THREE.Vector3();\nconst currSide = new THREE.Vector3();\nconst HALF_PI = Math.PI/2\nconst DOWN = new THREE.Vector3(0,-1,0);\n\nclass HandsTracker extends Tracker<typeof handMarks> {\n\tprivate readonly sign:number;\n\tprivate readonly isLeft:boolean;\n\t/**\n\t * the axis used to look at the pole\n\t */\n\tprivate readonly lookAtPoleAxis:LookAtPoleAxis;\n\n\tconstructor(private readonly handLandmarker:HandLandmarker, private readonly side:HandSide, private readonly isMyWrist:( handWrist:NormalizedLandmark )=>boolean ){\n\t\tsuper(handMarks, HandLandmarker.HAND_CONNECTIONS)\n\n\t\tthis.sign = this.side==\"Left\" ? -1 : 1;\n\t\tthis.isLeft = this.side==\"Left\";\n\t\tthis.lookAtPoleAxis = this.sign<0? \"+x\" : \"-x\";\n\t\tthis.root.scale.setScalar(2)\n\t\tthis.root.scale.y *= -1\n\t\tthis.root.scale.z *= -1\n\t}\n\n\toverride predict( source:TexImageSource, drawingUtils:DrawingUtils ){\n\t\tconst result = this.handLandmarker.detectForVideo(source, performance.now());\n\n\t\tif( result.landmarks.length )\n\t\t{\n\t\t\t//console.log(`DETECTED ${result.landmarks.length} hands`, result.handedness)\n\n\n\t\t\tfor(let i=0; i<result.landmarks.length; i++){\n\t\t\t\tconst hand = result.landmarks[i];\n\t\t\t\tconst wrist = hand[this.points.wrist];\n\t\t\t\tconst isMyWrist = this.isMyWrist(wrist);\n\t\t\t\tif( isMyWrist ){\n\t\t\t\t\tthis.updateLandmarks( result.worldLandmarks[i] );\n\n\t\t\t\t\tdrawingUtils.drawConnectors(hand, HandLandmarker.HAND_CONNECTIONS, {\n\t\t\t\t\t\tcolor: this.side==\"Left\" ? \"#00FF00\" : \"#0000FF\",\n\t\t\t\t\t\tlineWidth: 4\n\t\t\t\t\t});\n\t\t\t\t\tdrawingUtils.drawLandmarks(hand, { color: this.side==\"Left\" ? \"#00FF00\" : \"#0000FF\", lineWidth: 3, radius: 1 }); \n\n\t\t\t\t\t\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} \n \n \n\t\t} \n\t}\n\n\toverride sync ( delta:number, objects: [THREE.Object3D, HandMarkName, HandMarkName, LookAtPoleAxis][] ) {\n\n\t\tthrow new Error(\"Not used. Use syncHandBones instead\");\n\t}\n\t\t\n\t/**\n\t * \n\t * @param delta time since last frame\n\t * @param landmark2bones Array the same size as the umber of hand landmarks, and on each positionthe bone that belongs to that point.\n\t * @see https://ai.google.dev/edge/mediapipe/solutions/vision/hand_landmarker\n\t */\n\tsyncHandBones( delta:number, markToBone:Mark2Bone, rig:THREE.Object3D )\n\t{ \n\t\tconst palmNormal = v1.crossVectors(\n\t\t\tv2.copy(this.marks.index1.worldPosition).sub(this.marks.wrist.worldPosition),\n\t\t\tv3.copy(this.marks.pinky1.worldPosition).sub(this.marks.wrist.worldPosition)\n\t\t).normalize();\n\n\t\tconst parlmDir = v2.copy(this.marks.palm.worldPosition).sub(this.marks.wrist.worldPosition).normalize();\n\t\tconst palmSide = v3.copy(this.marks.pinky1.worldPosition).sub(this.marks.index1.worldPosition).normalize();\n\t\t \n\t\tif( parlmDir.dot(DOWN)>0.8 )\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tif( markToBone.wrist )\n\t\t{\n\t\t\tconst palmLookAt = rootPosition(v4, markToBone.wrist, rig ).add( parlmDir ).applyMatrix4(rig.matrixWorld) //markToBone.wrist.getWorldPosition(v4).add( parlmDir );\n\t\t\tconst polPosition = rootPosition(v5, markToBone.wrist, rig ).sub( palmSide ).applyMatrix4(rig.matrixWorld) //markToBone.wrist.getWorldPosition(v5).sub( palmSide );\n\n\t\t\tconst palmGhost = this.getGhost(markToBone.wrist)\n\n\t\t\tlookAt( palmGhost, palmLookAt, polPosition, \"-y\" );\n\t\t\tpalmGhost.rotateX( HALF_PI ) ; \n\n\t\t\tpalmGhost.lerp(markToBone.wrist, delta)\n\t\t}\n\t\t\n\n\t\t// palmLookAtOffset.normalize();\n\n\t\t \n\t\t// const palmSide = v3.crossVectors(palmNormal, palmLookAtOffset).normalize();\n \n\t\tthis.syncFinger( delta, rig, palmNormal, parlmDir, palmSide, markToBone, fingerKeys.index, \"middle1\" )\n\t\tthis.syncFinger( delta, rig, palmNormal, parlmDir, palmSide, markToBone, fingerKeys.middle, \"ring1\" )\n\t\tthis.syncFinger( delta, rig, palmNormal, parlmDir, palmSide, markToBone, fingerKeys.ring, \"pinky1\" )\n\t\tthis.syncFinger( delta, rig, palmNormal, parlmDir, palmSide, markToBone, fingerKeys.pinky, \"ring1\", true )\n\n\t\t// //thumb...\n\t\tthis.syncFinger( delta, rig, palmNormal, parlmDir, palmSide, markToBone, fingerKeys.thumb, \"index1\" )\n\n\t\t\n\t}\n\n\tprivate syncFinger( delta:number, rig:THREE.Object3D, palmNormal:THREE.Vector3, palmForward:THREE.Vector3, palmSide:THREE.Vector3, markToBone:Mark2Bone, fingerKeys:HandMarkName[], sideGoal:HandMarkName, negateSideGoal:boolean=false ){\n\t \n\t\tlet signMult = 1;\n\n\t\tfor(let i=0; i<fingerKeys.length-1;i++) { \n\t\t\t\n\t\t\tconst bone = markToBone[fingerKeys[i]];\n\t\t\t//const bonePole = markToBone[sideGoal];\n\n\t\t\tif(!bone ) continue;\n\n\t\t\tconst myDir = v4.copy( this.marks[fingerKeys[i+1]].worldPosition ).sub( this.marks[fingerKeys[i]].worldPosition).normalize(); \n\t\t\t\n\t\t\tconst bonePos = rootPosition(v5, bone, rig) //bone.getWorldPosition(v5);\n\t\t\tconst poleOffset = v6.copy(bonePos).add(palmSide) //rootPosition(v6, bonePole, rig).sub( bonePos );//bonePole.getWorldPosition(v6).sub( bonePos );\n\n\t\t\tif( negateSideGoal ) poleOffset.negate();\n\n\t\t\tconst fingerGhost = this.getGhost(bone)\n\n\n\t\t\tif( i==0 )\n\t\t\t{ \n\n\t\t\t\tcurrSide.copy(poleOffset);\n\n\t\t\t\t\n\t\t\t\tlookAt( fingerGhost, \n\t\t\t\t\tmyDir.add( bonePos ).applyMatrix4(rig.matrixWorld), \n\t\t\t\t\tpoleOffset.add(bonePos).applyMatrix4(rig.matrixWorld), \n\t\t\t\t\tthis.lookAtPoleAxis );\n\n\t\t\t\t\n\t\t\t}\n\t\t\telse \n\t\t\t{ \n\t\t\t\tpoleOffset.copy( currSide );\n\t\t\t\tlookAt( fingerGhost, \n\t\t\t\t\tmyDir.add( bonePos ).applyMatrix4(rig.matrixWorld), \n\t\t\t\t\tpoleOffset.add(bonePos).applyMatrix4(rig.matrixWorld), \n\t\t\t\t\tthis.lookAtPoleAxis );\n\t\t\t} \n\n\t\t\tfingerGhost.rotateX( HALF_PI ); \n\n\t\t\tfingerGhost.lerp(bone, delta)\n\n\t\t}\n\n \n\t}\n \n\tbind( rig:THREE.Object3D, magging:BoneMap ){\n\n\t\tconst map:Mark2Bone = {\n\t\t\t\n\t\t}\t \n\n\t\tconst addBind = ( boneName:string, markName:HandMarkName ) => {\n\t\t\t//const bone = rig.getObjectByName( cleanBoneName( boneName.replace(\"X\", this.sign<0 ? \"L\" : \"R\") ));\n\n\t\t\tconst bone = getBoneByName(rig, boneName );\n\n\t\t\tif( bone ){\n\t\t\t\tmap[markName] = bone;\n\t\t\t}\n\t\t}\n\n\t\taddBind( this.isLeft ? magging.handL : magging.handR, \"wrist\" )\n\t\taddBind( this.isLeft ? magging.index1L : magging.index1R, \"index1\" )\n\t\taddBind( this.isLeft ? magging.index2L : magging.index2R, \"index2\" )\n\t\taddBind( this.isLeft ? magging.index3L : magging.index3R, \"index3\" ) \n\n\t\taddBind( this.isLeft ? magging.middle1L : magging.middle1R, \"middle1\" )\n\t\taddBind( this.isLeft ? magging.middle2L : magging.middle2R, \"middle2\" )\n\t\taddBind( this.isLeft ? magging.middle3L : magging.middle3R, \"middle3\" ) \n\n\t\taddBind( this.isLeft ? magging.ring1L : magging.ring1R, \"ring1\" )\n\t\taddBind( this.isLeft ? magging.ring2L : magging.ring2R, \"ring2\" )\n\t\taddBind( this.isLeft ? magging.ring3L : magging.ring3R, \"ring3\" ) \n\n\t\taddBind( this.isLeft ? magging.pinky1L : magging.pinky1R, \"pinky1\" )\n\t\taddBind( this.isLeft ? magging.pinky2L : magging.pinky2R, \"pinky2\" )\n\t\taddBind( this.isLeft ? magging.pinky3L : magging.pinky3R, \"pinky3\" ) \n\n\t\taddBind( this.isLeft ? magging.thumb1L : magging.thumb1R, \"thumb1\" )\n\t\taddBind( this.isLeft ? magging.thumb2L : magging.thumb2R, \"thumb2\" )\n\t\taddBind( this.isLeft ? magging.thumb3L : magging.thumb3R, \"thumb3\" ) \n\n\t\treturn {\n\t\t\tupdate: ( delta:number )=> { \n\t\t\t\tthis.syncHandBones(delta, map, rig);\n\t\t\t}\n\t\t}\t\n\t}\n}\n","import {\n Category,\n DrawingUtils,\n FaceLandmarker\n} from \"@mediapipe/tasks-vision\";\nimport { Mesh, Object3D, Vector3 } from \"three/webgpu\";\nimport { Tracker } from \"./Tracker\";\nimport { rootPosition } from \"./util/getRootPosition\";\nimport { getBoneByName } from \"./util/getBoneByName\";\nimport { lookAt } from \"./util/lookAt\";\n\nexport async function loadFaceTracker(vision: any, cfg?: { modelPath?: string }) {\n const faceLandmarker = await FaceLandmarker.createFromOptions(vision, {\n baseOptions: {\n modelAssetPath: cfg?.modelPath ?? \"face_landmarker.task\",\n\t\t\tdelegate: \"GPU\", \n },\n\t\toutputFaceBlendshapes: true,\n runningMode: \"VIDEO\",\n\t\tnumFaces: 1,\n });\n\n\treturn new FaceTracker(faceLandmarker);\n}\n\n/**\n * @see https://storage.googleapis.com/mediapipe-assets/documentation/mediapipe_face_landmark_fullsize.png\n */\nconst faceMarks = {\n\teyeL: 473,\n\teyeR: 468,\n\teyeStartL: 463,\n\teyeStartR: 243,\n\teyeEndL: 263,\n\teyeEndR: 33, \n\n\tearL: 454,\n\tearR: 234,\n\tnoseTip: 4,\n\tnoseBone:6,\n\tchin:152,\n\tforehead: 10\n\n}\n\ntype MarkKey = keyof typeof faceMarks;\nconst v = new Vector3();\nconst v2 = new Vector3();\nconst v3 = new Vector3();\nconst v4 = new Vector3();\nconst v5 = new Vector3();\nconst v6 = new Vector3();\n\nclass FaceTracker extends Tracker<typeof faceMarks> {\n\tprivate blendshapeCategories: Category[] | undefined;\n\tprivate blendshapeMap: Map<string, number> = new Map();\n\tprivate smoothed: Record<string, number> = {};\n\tprivate smoothing =.0003; // lower = smoother but more lag, higher = more responsive\n\n\tconstructor(private faceLandmarker: FaceLandmarker) {\n\t\tsuper(faceMarks, FaceLandmarker.FACE_LANDMARKS_TESSELATION)\n\n\t\tthis.root.scale.y*=-1\n\t\tthis.root.scale.z*=-1\n\t\tthis.root.scale.multiplyScalar(3)\n\t}\n\n\toverride predict(frame: TexImageSource, drawingUtils: DrawingUtils) {\n\t\tconst result = this.faceLandmarker.detectForVideo(frame, performance.now());\n\t\tif (result.faceLandmarks[0]) {\n\t\t\tdrawingUtils.drawConnectors(result.faceLandmarks[0], FaceLandmarker.FACE_LANDMARKS_TESSELATION, { color: \"#00fff2ff\", lineWidth: .1 });\n\t\t\tdrawingUtils.drawLandmarks(result.faceLandmarks[0], { color: \"#00ff00\", lineWidth: .1, radius: .4 });\t\n\n\t\t\tthis.updateLandmarks(result.faceLandmarks[0], result.faceLandmarks[0] );\n\t\t}\n\n\t\tthis.blendshapeCategories = result.faceBlendshapes?.[0]?.categories; \n\n\t\tthis.blendshapeCategories?.forEach((category) => {\n\t\t\tthis.blendshapeMap.set(category.categoryName, category.score);\n\t\t});\n\t\t\n\t}\n\n\tbindShapeKeys(mesh: Mesh) {\n\t\tconst meshKeys = mesh.morphTargetDictionary; \n\n\t\treturn {\n\t\t\tupdate: (delta: number) => {\n\t\t\t\tthis.blendshapeCategories?.forEach((category) => {\n\t\t\t\t\tconst { categoryName, score } = category;\n\n\t\t\t\t\tif (!meshKeys?.hasOwnProperty(categoryName)) return;\n\n\t\t\t\t\t// Initialize if first time seeing this key\n\t\t\t\t\tif (this.smoothed[categoryName] === undefined)\n\t\t\t\t\t\tthis.smoothed[categoryName] = score;\n\n\t\t\t\t\t// Lerp toward target score\n\t\t\t\t\tconst factor = 1 - Math.pow(this.smoothing, delta);\n\t\t\t\t\tthis.smoothed[categoryName] += (score - this.smoothed[categoryName]) * factor;\n\n\t\t\t\t\tmesh.morphTargetInfluences![meshKeys[categoryName]] = this.smoothed[categoryName];\n\t\t\t\t});\n\n\t\t\t\t//eyes\n\t\t\t}\n\t\t}\n\t}\n\n\tbind( rig:Object3D ) {\n\n\t\tconst eyeL = new EyeRig(rig, \"L\");\n\t\tconst eyeR = new EyeRig(rig, \"R\");\n\t\tconst headBone = getBoneByName(rig, \"head\") ;\n \n\t\treturn {\n\t\t\tupdate: ( delta:number )=> {\n\t\t\t\t \n\t\t\t\teyeL.update(delta, this.blendshapeMap);\n\t\t\t\teyeR.update(delta, this.blendshapeMap); \n\t\t\t\t\n\t\t\t\tif(!headBone) return;\n\n\t\t\t\t//\n\t\t\t\tconst markEarL = v.copy( this.marks.earL.worldPosition );\n\t\t\t\tconst markEarR = v2.copy( this.marks.earR.worldPosition );\n\t\t\t\tconst headcenter = v3.subVectors(markEarL, markEarR).multiplyScalar(.5).add(markEarR);\n\t\t\t\tconst headForward = v4.subVectors(this.marks.noseTip.worldPosition, headcenter) ;\n\t\t\t\tconst headSideNormal = markEarL.sub(markEarR) ;\n\n\t\t\t\t\n\t\t\t\tconst headPosition = rootPosition( v5, headBone, rig); \n\n\t\t\t\tconst poleLookAt = headSideNormal.add( headPosition ).applyMatrix4(rig.matrixWorld);\n\t\t\t\tconst faceLookAt = headForward.add( headPosition ).applyMatrix4(rig.matrixWorld);\n\n\t\t\t\tlookAt( headBone, faceLookAt, poleLookAt,\"+x\" );\n\t\t\t\t \n\n\t\t\t\t// headLookAtPos.applyMatrix4(rig.matrixWorld);\n\t\t\t\t//headBone.lookAt( headLookAtPos );\n\t\t\t\t// \n\t\t\t}\n\t\t}\n\t\t\n\t}\n}\n\nclass EyeRig {\n\tprivate eyeBone:Object3D|undefined; \n\n\tprivate eyeLookOut:string;\n\tprivate eyeLookIn:string;\n\tprivate eyeLookUp:string;\n\tprivate eyeLookDown:string;\n\tprivate sign = 1;\n\t\n\tconstructor( readonly rig:Object3D, readonly side:\"L\"|\"R\" ) {\n\t\tthis.eyeBone = rig.getObjectByName(`eye${side}`) as Object3D; \n\n\t\tconst sideName = side == \"L\" ? \"Left\" : \"Right\";\n\t\tthis.eyeLookOut = `eyeLookOut${sideName}`;\n\t\tthis.eyeLookIn = `eyeLookIn${sideName}`;\n\t\tthis.eyeLookUp = `eyeLookUp${sideName}`;\n\t\tthis.eyeLookDown = `eyeLookDown${sideName}`;\n\n\t\tthis.sign = side == \"L\" ? -1 : 1;\n\t}\n\n\tupdate( delta:number, blendshapes: Map<string, number> ) {\n\t\tif( !this.eyeBone ) return; \n \n\t\tconst eye = rootPosition(v3, this.eyeBone, this.rig); \n\n\t\t\n\t\t\n\t\t// From MediaPipe blendshapes\n\t\tconst lookLeft = blendshapes.get(this.eyeLookOut) ?? 0; // or eyeLookInRight\n\t\tconst lookRight = blendshapes.get(this.eyeLookIn) ?? 0; // or eyeLookOutRight\n\t\tconst lookUp = blendshapes.get(this.eyeLookUp) ?? 0;\n\t\tconst lookDown = blendshapes.get(this.eyeLookDown) ?? 0;\n\n\t\t\n\t\t// Map to a -1..1 range\n\t\tconst sideMovement = lookRight - lookLeft // horizontal\n\t\tconst verticalMovement = lookDown - lookUp // vertical\n\n\t\tconsole.log(\"EYE: \", sideMovement, verticalMovement)\n\n\t\tthis.eyeBone.rotation.y =( sideMovement * this.sign) / 2; \n\t\tthis.eyeBone.rotation.x = verticalMovement / 2; \n\t\t// // Then drive your rig bone with a target offset\n\t\t// const lookAtPos = eyeCenter\n\t\t// .add(eyeHorizontalDir ) // -sideMovement * eyeRange)\n\t\t// //.addScaledVector(eyeVerticalDir, verticalMovement * eyeRange/3)\n\t\t// .applyMatrix4(this.rig.matrixWorld);\n\n\t\t// this.eyeBone.lookAt(lookAtPos);\n\t\t// this.eyeBone.rotateX(Math.PI/2)\n\t}\n}","/**\n * The bone mapping to use for the rig.\n */\nexport type BoneMap = {\n\tfaceMesh:string\n\thead: string;\n\thips:string\n\tneck:string\n\ttorso:string\n\tarmL:string\n\tforearmL:string\n\n\tarmR:string\n\tforearmR:string\n\n\tthighL:string\n\tshinL:string\n\tfootL:string\n\n\tthighR:string\n\tshinR:string\n\tfootR:string\n\t \n\t\n\thandL:string\n\tindex1L:string\n\tindex2L:string\n\tindex3L:string\n\n\tmiddle1L:string\n\tmiddle2L:string\n\tmiddle3L:string\n\n\tring1L:string\n\tring2L:string\n\tring3L:string\n\n\tpinky1L:string\n\tpinky2L:string\n\tpinky3L:string\n\n\tthumb1L:string\n\tthumb2L:string\n\tthumb3L:string\n\n\thandR:string\n\tindex1R:string\n\tindex2R:string\n\tindex3R:string\n\n\tmiddle1R:string\n\tmiddle2R:string\n\tmiddle3R:string\n\n\tring1R:string\n\tring2R:string\n\tring3R:string\n\n\tpinky1R:string\n\tpinky2R:string\n\tpinky3R:string\n\n\tthumb1R:string\n\tthumb2R:string\n\tthumb3R:string\n \n}\n\nexport const defaultBoneMap:BoneMap = {\n\tfaceMesh:\"face\",\n\t\n\thead: \"head\",\n\thips:\"hips\",\n\tneck:\"neck\",\n\ttorso:\"torso\",\n\n\tarmL:\"upper_armL\",\n\tforearmL:\"forearmL\",\n\n\tarmR:\"upper_armR\",\n\tforearmR:\"forearmR\",\n\n\tthighL:\"thighL\",\n\tshinL:\"shinL\",\n\tfootL:\"footL\",\n\n\tthighR:\"thighR\",\n\tshinR:\"shinR\",\n\tfootR:\"footR\",\n\t \n\t\n\thandL:\"handL\",\n\tindex1L:\"index1L\",\n\tindex2L:\"index2L\",\n\tindex3L:\"index3L\",\n\n\tmiddle1L:\"middle1L\",\n\tmiddle2L:\"middle2L\",\n\tmiddle3L:\"middle3L\",\n\n\tring1L:\"ring1L\",\n\tring2L:\"ring2L\",\n\tring3L:\"ring3L\",\n\n\tpinky1L:\"pinky1L\",\n\tpinky2L:\"pinky2L\",\n\tpinky3L:\"pinky3L\",\n\n\tthumb1L:\"thumb1L\",\n\tthumb2L:\"thumb2L\",\n\tthumb3L:\"thumb3L\",\n\n\thandR:\"handR\",\n\tindex1R:\"index1R\",\n\tindex2R:\"index2R\",\n\tindex3R:\"index3R\",\n\n\tmiddle1R:\"middle1R\",\n\tmiddle2R:\"middle2R\",\n\tmiddle3R:\"middle3R\",\n\n\tring1R:\"ring1R\",\n\tring2R:\"ring2R\",\n\tring3R:\"ring3R\",\n\n\tpinky1R:\"pinky1R\",\n\tpinky2R:\"pinky2R\",\n\tpinky3R:\"pinky3R\",\n\n\tthumb1R:\"thumb1R\",\n\tthumb2R:\"thumb2R\",\n\tthumb3R:\"thumb3R\",\n \n}","import {\n DrawingUtils,\n FilesetResolver,\n HandLandmarkerOptions,\n PoseLandmarker,\n} from \"@mediapipe/tasks-vision\";\nimport * as THREE from \"three/webgpu\";\nimport { loadPoseTracker } from \"./PoseTracker\";\nimport { loadHandTracker } from \"./HandTracker\"; \nimport { loadFaceTracker } from \"./FaceTracker\";\nimport { BoneMap, defaultBoneMap } from \"./BoneMapping\";\n\nexport type TrackerConfig = {\n /**\n * Use an image file. Useful to test a particular pose.\n */\n debugFrame?: string;\n\n /**\n * Scale of the video display\n */\n displayScale: number;\n\n /**\n * If the body pose should ignore the legs\n */\n ignoreLegs: boolean;\n\n /**\n * Use a video file instead of the webcam\n */\n debugVideo?: string;\n\n /**\n * Don't track the face\n */\n ignoreFace: boolean;\n\n /**\n * @see https://ai.google.dev/edge/mediapipe/solutions/vision/hand_landmarker/web_js#configuration_options\n */\n handsTrackerOptions: HandLandmarkerOptions | undefined;\n\n\tmodelPaths?: {\n\t\tvision?:string;\n\t\tpose?: string;\n\t\thand?: string;\n\t\tface?: string;\n\t}\n};\n\nexport interface BindingHandler {\n update: (delta: number) => void;\n}\n\n// Check if webcam access is supported.\nconst hasGetUserMedia = () => !!navigator.mediaDevices?.getUserMedia;\n\nexport async function setupTracker(config?: Partial<TrackerConfig>) {\n const $cfg = {\n debugFrame: undefined,\n displayScale: 1,\n ignoreLegs: false,\n debugVideo: undefined,\n ignoreFace: false,\n\t\tmodelPaths: {\n\t\t\tvision: \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3/wasm\",\n\t\t\tpose: \"https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task\",\n\t\t\thand: \"https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task\",\n\t\t\tface: \"https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task\",\n\t\t},\n ...config,\n };\n let video: HTMLVideoElement | undefined;\n const vision = await FilesetResolver.forVisionTasks( $cfg.modelPaths.vision ?? \"/wasm\" );\n const poseTracker = await loadPoseTracker(vision, {\n ignoreLegs: $cfg.ignoreLegs,\n\t\tmodelPath: $cfg.modelPaths.pose!,\n });\n const handsTracker = await loadHandTracker(vision, {\n leftWrist: () => poseTracker.leftWristNormalizedPosition,\n rightWrist: () => poseTracker.rightWristNormalizedPosition,\n\t\tmodelPath: $cfg.modelPaths.hand!,\n ...config?.handsTrackerOptions,\n });\n const faceTracker = $cfg.ignoreFace\n ? undefined\n : await loadFaceTracker(vision, { modelPath: $cfg.modelPaths.face! });\n\n //#region setup Camera and Canvas...\n\tconst viewport = document.createElement(\"div\");\n\tviewport.style.position = \"absolute\";\n\tviewport.style.top = \"0px\";\n\tviewport.style.left = \"0px\"; \n\tviewport.style.zIndex = \"21\";\n\tviewport.classList.add(\"three-mediapipe-rig\")\n\tdocument.body.appendChild(viewport);\n\n const canvasElement = document.createElement(\"canvas\");\n const canvasCtx = canvasElement.getContext(\"2d\")!;\n const drawingUtils = new DrawingUtils(canvasCtx);\n\n canvasElement.style.zIndex = \"22\";\n canvasElement.style.position = \"absolute\";\n canvasElement.style.top = \"0px\";\n canvasElement.style.left = \"0px\";\n canvasElement.style.pointerEvents = \"none\";\n viewport.appendChild(canvasElement);\n\n function predict(source: TexImageSource) {\n canvasCtx.save();\n canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);\n poseTracker?.predict(source, drawingUtils);\n handsTracker?.left.predict(source, drawingUtils);\n handsTracker?.right.predict(source, drawingUtils);\n faceTracker?.predict(source, drawingUtils);\n canvasCtx.restore();\n }\n\n function initializeVideo() {\n video = document.createElement(\"video\");\n viewport.appendChild(video);\n\n let lastVideoTime = -1;\n\n video.style.zIndex = \"21\";\n video.style.position = \"absolute\";\n video.style.top = \"0px\";\n video.style.left = \"0px\";\n\n if ($cfg.debugVideo) {\n video.src = $cfg.debugVideo;\n video.controls = true;\n video.loop = true;\n video.muted = true;\n video.controls = true;\n video.play();\n }\n\n function predictWebcam() {\n if (lastVideoTime !== video!.currentTime) {\n predict(video!);\n lastVideoTime = video!.currentTime;\n }\n window.requestAnimationFrame(predictWebcam);\n }\n\n video.addEventListener(\"loadeddata\", () => {\n video!.width = video!.videoWidth * $cfg.displayScale;\n video!.height = video!.videoHeight * $cfg.displayScale;\n canvasElement.width = video!.videoWidth;\n canvasElement.height = video!.videoHeight;\n canvasElement.style.height = video!.height + \"px\";\n canvasElement.style.width = video!.width + \"px\";\n\n window.requestAnimationFrame(predictWebcam);\n });\n }\n\n if ($cfg.debugFrame) {\n //#region Debug Frame mode — use a static image\n const img = document.createElement(\"img\");\n img.src = $cfg.debugFrame;\n img.style.zIndex = \"21\";\n img.style.position = \"absolute\";\n img.style.top = \"0px\";\n img.style.left = \"0px\";\n document.body.appendChild(img);\n\n img.addEventListener(\"load\", () => {\n img.width = img.naturalWidth * $cfg.displayScale;\n img.height = img.naturalHeight * $cfg.displayScale;\n canvasElement.width = img.naturalWidth;\n canvasElement.height = img.naturalWidth;\n canvasElement.style.width = img.width + \"px\";\n canvasElement.style.height = img.height + \"px\";\n\n function predictFrame() {\n predict(img);\n }\n\n window.requestAnimationFrame(predictFrame);\n });\n //#endregion\n } else if( $cfg.debugVideo ) {\n //#region Video mode\n initializeVideo();\n //#endregion\n } \n\n return {\n poseTracker,\n handsTracker,\n faceTracker,\n video,\n\n\t\t/**\n\t\t * A div that contains the video and canvas used to display the landmarks stacked on top of each other.\n\t\t */\n\t\tdomElement: viewport,\n\n\t\t/**\n\t\t * Start the webcam feed. This must be initiated by a user triggered event ( a click on a button ) due to security reasons. \n\t\t */\n start: async () => {\n\t\t\tlet stopped = false;\n\n if (!hasGetUserMedia()) {\n throw new Error(\"Webcam not supported\");\n }\n\n if (!video) {\n initializeVideo();\n }\n\n let stream: Awaited<MediaStream> | undefined;\n\n\t\t\tfunction onTrackEnded(video: HTMLVideoElement): void {\n\t\t\t\tconsole.warn('Camera track ended, attempting recovery...');\n\t\t\t\tstopCamera(video);\n\t\t\t\tretryWithBackoff(video);\n\t\t\t}\n\n\t\t\tfunction stopCamera(video: HTMLVideoElement): void {\n\t\t\t\tstream?.getTracks().forEach(t => t.stop());\n\t\t\t\tstream = undefined;\n\t\t\t\tvideo.srcObject = null;\n\t\t\t}\n\n\t\t\tasync function retryWithBackoff(video: HTMLVideoElement, attempt = 0): Promise<void> {\n\t\t\t const MAX_ATTEMPTS = 5;\n\t\t\t const delay = Math.min(1000 * 2 ** attempt, 16000); // 1s, 2s, 4s, 8s, 16s\n\n\t\t\t if (attempt >= MAX_ATTEMPTS) { \n\t\t\t throw new Error('Camera recovery failed after max attempts');\n\t\t\t }\n\n\t\t\t await new Promise(res => setTimeout(res, delay)); \n\n\t\t\t if(stopped) return;\n\n\t\t\t try {\n\t\t\t await startCamera(video);\n\t\t\t console.log('Camera recovered successfully');\n\t\t\t } catch {\n\t\t\t retryWithBackoff(video, attempt + 1);\n\t\t\t }\n\t\t\t}\n\n\t\t\tasync function startCamera(video: HTMLVideoElement): Promise<void> {\n\t\t\t try {\n\t\t\t stream = await navigator.mediaDevices.getUserMedia({ video: true });\n\t\t\t video.srcObject = stream;\n\t\t\t await video.play();\n\n\t\t\t // Listen for track ending (camera disconnected / permission revoked)\n\t\t\t stream.getVideoTracks().forEach(track => {\n\t\t\t track.addEventListener('ended', () => onTrackEnded(video));\n\t\t\t });\n\n\t\t\t } catch (err) {\n\t\t\t handleCameraError(err, video);\n\t\t\t }\n\t\t\t}\n\n\t\t\tfunction handleCameraError(err: unknown, video: HTMLVideoElement): void {\n\t\t\t if (err instanceof DOMException) {\n\t\t\t switch (err.name) {\n\t\t\t case 'NotAllowedError':\n\t\t\t throw new Error('Permission denied — prompt user to allow camera');\n\t\t\t break;\n\t\t\t case 'NotFoundError':\n\t\t\t console.error('No camera found — retry when device is connected');\n\t\t\t retryWithBackoff(video); // device might be plugged in later\n\t\t\t break;\n\t\t\t case 'NotReadableError':\n\t\t\t console.error('Camera in use by another app');\n\t\t\t retryWithBackoff(video);\n\t\t\t break;\n\t\t\t default:\n\t\t\t console.error('Camera error:', err.message);\n\t\t\t retryWithBackoff(video);\n\t\t\t }\n\t\t\t }\n\t\t\t} \n\n await startCamera(video!);\n\n\t\t\treturn {\n\t\t\t\tstop:()=>{\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tstopCamera(video!);\n\t\t\t\t}\n\t\t\t}\n },\n\n /**\n * Binds the bones of the rig to the landmarks provided by media pipe.\n * @param rig The rig that contains all the bones and skinned meshes of your character.\n\t\t * @param magging The bone mapping to use for the rig.\n */\n bind: ( rig: THREE.Object3D, magging?:BoneMap ) => {\n\n\t\t\tmagging = magging || defaultBoneMap;\n\n const bodyBindin = poseTracker.bind(rig, magging);\n const leftHandBinding = handsTracker.left.bind(rig, magging);\n const rightHandBinding = handsTracker.right.bind(rig, magging);\n let faceKeys: BindingHandler | undefined;\n const faceRig = faceTracker?.bind(rig);\n\n rig.traverse((child) => {\n if (\n child instanceof THREE.Mesh &&\n child.name.indexOf( magging.faceMesh ) === 0\n ) {\n child.frustumCulled = false;\n faceKeys = faceTracker?.bindShapeKeys(child);\n }\n });\n\n return {\n update: (delta: number) => {\n bodyBindin.update(delta);\n leftHandBinding.update(delta);\n rightHandBinding.update(delta);\n faceKeys?.update(delta);\n faceRig?.update(delta);\n },\n } as BindingHandler;\n },\n };\n}\n"],"names":["poleDir","Vector3","objectPosition","XAxis","XAxisNeg","YAxis","YAxisNeg","ZAxis","pole","lookDir","v","correction","Quaternion","worldQuat","lookAt","object","target","poleTarget","poleAxis","axis","currentPole","lookAxisDir","desiredPoleDir","cross","angle","THREE","A","B","Tracker","points","debugConnections","__publicField","key","Mark","landmarks","debugLandmarks","debugDrawer","point","mark","o","Ghost","_a","source","drawingUtils","delta","objects","normal","root","offset","objectLookAtGoal","polePosition","ghost","rig","name","speed","rootPosition","out","cleanBoneName","getBoneByName","bone","Bone","loadPoseTracker","vision","config","poseLandmarker","PoseLandmarker","PoseTracker","poseMarks","C","D","E","lookGoal","poleGoal","result","magging","map","v2","syncBone","from","to","sideAxis","hipsDir","sideHips","sideShoulders","sideHead","loadHandTracker","landmarker","HandLandmarker","isMyWrist","myWrist","otherWrist","handWrist","HandsTracker","handMarks","fingerKeys","v1","v3","v4","v5","v6","currSide","HALF_PI","DOWN","handLandmarker","side","hand","wrist","markToBone","palmNormal","parlmDir","palmSide","palmLookAt","polPosition","palmGhost","palmForward","sideGoal","negateSideGoal","i","myDir","bonePos","poleOffset","fingerGhost","addBind","boneName","markName","loadFaceTracker","cfg","faceLandmarker","FaceLandmarker","FaceTracker","faceMarks","frame","_b","_c","category","mesh","meshKeys","categoryName","score","factor","eyeL","EyeRig","eyeR","headBone","markEarL","markEarR","headcenter","headForward","headSideNormal","headPosition","poleLookAt","faceLookAt","sideName","blendshapes","lookLeft","lookRight","lookUp","lookDown","sideMovement","verticalMovement","defaultBoneMap","hasGetUserMedia","setupTracker","$cfg","video","FilesetResolver","poseTracker","handsTracker","faceTracker","viewport","canvasElement","canvasCtx","DrawingUtils","predict","initializeVideo","lastVideoTime","predictWebcam","img","predictFrame","stopped","stream","onTrackEnded","stopCamera","retryWithBackoff","t","attempt","delay","res","startCamera","track","err","handleCameraError","bodyBindin","leftHandBinding","rightHandBinding","faceKeys","faceRig","child"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bone mapping to use for the rig.
|
|
3
|
+
*/
|
|
4
|
+
export type BoneMap = {
|
|
5
|
+
faceMesh: string;
|
|
6
|
+
head: string;
|
|
7
|
+
hips: string;
|
|
8
|
+
neck: string;
|
|
9
|
+
torso: string;
|
|
10
|
+
armL: string;
|
|
11
|
+
forearmL: string;
|
|
12
|
+
armR: string;
|
|
13
|
+
forearmR: string;
|
|
14
|
+
thighL: string;
|
|
15
|
+
shinL: string;
|
|
16
|
+
footL: string;
|
|
17
|
+
thighR: string;
|
|
18
|
+
shinR: string;
|
|
19
|
+
footR: string;
|
|
20
|
+
handL: string;
|
|
21
|
+
index1L: string;
|
|
22
|
+
index2L: string;
|
|
23
|
+
index3L: string;
|
|
24
|
+
middle1L: string;
|
|
25
|
+
middle2L: string;
|
|
26
|
+
middle3L: string;
|
|
27
|
+
ring1L: string;
|
|
28
|
+
ring2L: string;
|
|
29
|
+
ring3L: string;
|
|
30
|
+
pinky1L: string;
|
|
31
|
+
pinky2L: string;
|
|
32
|
+
pinky3L: string;
|
|
33
|
+
thumb1L: string;
|
|
34
|
+
thumb2L: string;
|
|
35
|
+
thumb3L: string;
|
|
36
|
+
handR: string;
|
|
37
|
+
index1R: string;
|
|
38
|
+
index2R: string;
|
|
39
|
+
index3R: string;
|
|
40
|
+
middle1R: string;
|
|
41
|
+
middle2R: string;
|
|
42
|
+
middle3R: string;
|
|
43
|
+
ring1R: string;
|
|
44
|
+
ring2R: string;
|
|
45
|
+
ring3R: string;
|
|
46
|
+
pinky1R: string;
|
|
47
|
+
pinky2R: string;
|
|
48
|
+
pinky3R: string;
|
|
49
|
+
thumb1R: string;
|
|
50
|
+
thumb2R: string;
|
|
51
|
+
thumb3R: string;
|
|
52
|
+
};
|
|
53
|
+
export declare const defaultBoneMap: BoneMap;
|
|
54
|
+
//# sourceMappingURL=BoneMapping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BoneMapping.d.ts","sourceRoot":"","sources":["../../src/tracking/BoneMapping.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACrB,QAAQ,EAAC,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAC,MAAM,CAAA;IACX,IAAI,EAAC,MAAM,CAAA;IACX,KAAK,EAAC,MAAM,CAAA;IACZ,IAAI,EAAC,MAAM,CAAA;IACX,QAAQ,EAAC,MAAM,CAAA;IAEf,IAAI,EAAC,MAAM,CAAA;IACX,QAAQ,EAAC,MAAM,CAAA;IAEf,MAAM,EAAC,MAAM,CAAA;IACb,KAAK,EAAC,MAAM,CAAA;IACZ,KAAK,EAAC,MAAM,CAAA;IAEZ,MAAM,EAAC,MAAM,CAAA;IACb,KAAK,EAAC,MAAM,CAAA;IACZ,KAAK,EAAC,MAAM,CAAA;IAGZ,KAAK,EAAC,MAAM,CAAA;IACZ,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IAEd,QAAQ,EAAC,MAAM,CAAA;IACf,QAAQ,EAAC,MAAM,CAAA;IACf,QAAQ,EAAC,MAAM,CAAA;IAEf,MAAM,EAAC,MAAM,CAAA;IACb,MAAM,EAAC,MAAM,CAAA;IACb,MAAM,EAAC,MAAM,CAAA;IAEb,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IAEd,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IAEd,KAAK,EAAC,MAAM,CAAA;IACZ,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IAEd,QAAQ,EAAC,MAAM,CAAA;IACf,QAAQ,EAAC,MAAM,CAAA;IACf,QAAQ,EAAC,MAAM,CAAA;IAEf,MAAM,EAAC,MAAM,CAAA;IACb,MAAM,EAAC,MAAM,CAAA;IACb,MAAM,EAAC,MAAM,CAAA;IAEb,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IAEd,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;IACd,OAAO,EAAC,MAAM,CAAA;CAEd,CAAA;AAED,eAAO,MAAM,cAAc,EAAC,OAiE3B,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DrawingUtils, FaceLandmarker } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { Mesh, Object3D } from 'three/webgpu';
|
|
3
|
+
import { Tracker } from './Tracker';
|
|
4
|
+
export declare function loadFaceTracker(vision: any, cfg?: {
|
|
5
|
+
modelPath?: string;
|
|
6
|
+
}): Promise<FaceTracker>;
|
|
7
|
+
/**
|
|
8
|
+
* @see https://storage.googleapis.com/mediapipe-assets/documentation/mediapipe_face_landmark_fullsize.png
|
|
9
|
+
*/
|
|
10
|
+
declare const faceMarks: {
|
|
11
|
+
eyeL: number;
|
|
12
|
+
eyeR: number;
|
|
13
|
+
eyeStartL: number;
|
|
14
|
+
eyeStartR: number;
|
|
15
|
+
eyeEndL: number;
|
|
16
|
+
eyeEndR: number;
|
|
17
|
+
earL: number;
|
|
18
|
+
earR: number;
|
|
19
|
+
noseTip: number;
|
|
20
|
+
noseBone: number;
|
|
21
|
+
chin: number;
|
|
22
|
+
forehead: number;
|
|
23
|
+
};
|
|
24
|
+
declare class FaceTracker extends Tracker<typeof faceMarks> {
|
|
25
|
+
private faceLandmarker;
|
|
26
|
+
private blendshapeCategories;
|
|
27
|
+
private blendshapeMap;
|
|
28
|
+
private smoothed;
|
|
29
|
+
private smoothing;
|
|
30
|
+
constructor(faceLandmarker: FaceLandmarker);
|
|
31
|
+
predict(frame: TexImageSource, drawingUtils: DrawingUtils): void;
|
|
32
|
+
bindShapeKeys(mesh: Mesh): {
|
|
33
|
+
update: (delta: number) => void;
|
|
34
|
+
};
|
|
35
|
+
bind(rig: Object3D): {
|
|
36
|
+
update: (delta: number) => void;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=FaceTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FaceTracker.d.ts","sourceRoot":"","sources":["../../src/tracking/FaceTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,YAAY,EACZ,cAAc,EACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAW,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAsB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,wBAY9E;AAED;;GAEG;AACH,QAAA,MAAM,SAAS;;;;;;;;;;;;;CAed,CAAA;AAUD,cAAM,WAAY,SAAQ,OAAO,CAAC,OAAO,SAAS,CAAC;IAMtC,OAAO,CAAC,cAAc;IALlC,OAAO,CAAC,oBAAoB,CAAyB;IACrD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,SAAS,CAAQ;gBAEL,cAAc,EAAE,cAAc;IAQzC,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY;IAiBlE,aAAa,CAAC,IAAI,EAAE,IAAI;wBAIN,MAAM;;IAsBxB,IAAI,CAAE,GAAG,EAAC,QAAQ;wBAOA,MAAM;;CA8BxB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { DrawingUtils, HandLandmarker, HandLandmarkerOptions, NormalizedLandmark } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { LookAtPoleAxis } from './util/lookAt';
|
|
3
|
+
import { Tracker } from './Tracker';
|
|
4
|
+
import { BoneMap } from './BoneMapping';
|
|
5
|
+
import * as THREE from "three/webgpu";
|
|
6
|
+
export type HandsTrackerConfig = {
|
|
7
|
+
leftWrist: () => NormalizedLandmark;
|
|
8
|
+
rightWrist: () => NormalizedLandmark;
|
|
9
|
+
modelPath?: string;
|
|
10
|
+
} & Partial<HandLandmarkerOptions>;
|
|
11
|
+
export declare function loadHandTracker(vision: any, config: HandsTrackerConfig): Promise<{
|
|
12
|
+
left: HandsTracker;
|
|
13
|
+
right: HandsTracker;
|
|
14
|
+
}>;
|
|
15
|
+
declare const handMarks: {
|
|
16
|
+
wrist: number;
|
|
17
|
+
palm: number[];
|
|
18
|
+
thumb1: number;
|
|
19
|
+
thumb2: number;
|
|
20
|
+
thumb3: number;
|
|
21
|
+
thumb4: number;
|
|
22
|
+
index1: number;
|
|
23
|
+
index2: number;
|
|
24
|
+
index3: number;
|
|
25
|
+
index4: number;
|
|
26
|
+
middle1: number;
|
|
27
|
+
middle2: number;
|
|
28
|
+
middle3: number;
|
|
29
|
+
middle4: number;
|
|
30
|
+
ring1: number;
|
|
31
|
+
ring2: number;
|
|
32
|
+
ring3: number;
|
|
33
|
+
ring4: number;
|
|
34
|
+
pinky1: number;
|
|
35
|
+
pinky2: number;
|
|
36
|
+
pinky3: number;
|
|
37
|
+
pinky4: number;
|
|
38
|
+
};
|
|
39
|
+
export type HandMarkName = keyof typeof handMarks;
|
|
40
|
+
type HandSide = "Left" | "Right";
|
|
41
|
+
export type Mark2Bone = Partial<{
|
|
42
|
+
[key in HandMarkName]: THREE.Object3D;
|
|
43
|
+
}>;
|
|
44
|
+
declare class HandsTracker extends Tracker<typeof handMarks> {
|
|
45
|
+
private readonly handLandmarker;
|
|
46
|
+
private readonly side;
|
|
47
|
+
private readonly isMyWrist;
|
|
48
|
+
private readonly sign;
|
|
49
|
+
private readonly isLeft;
|
|
50
|
+
/**
|
|
51
|
+
* the axis used to look at the pole
|
|
52
|
+
*/
|
|
53
|
+
private readonly lookAtPoleAxis;
|
|
54
|
+
constructor(handLandmarker: HandLandmarker, side: HandSide, isMyWrist: (handWrist: NormalizedLandmark) => boolean);
|
|
55
|
+
predict(source: TexImageSource, drawingUtils: DrawingUtils): void;
|
|
56
|
+
sync(delta: number, objects: [THREE.Object3D, HandMarkName, HandMarkName, LookAtPoleAxis][]): void;
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
* @param delta time since last frame
|
|
60
|
+
* @param landmark2bones Array the same size as the umber of hand landmarks, and on each positionthe bone that belongs to that point.
|
|
61
|
+
* @see https://ai.google.dev/edge/mediapipe/solutions/vision/hand_landmarker
|
|
62
|
+
*/
|
|
63
|
+
syncHandBones(delta: number, markToBone: Mark2Bone, rig: THREE.Object3D): void;
|
|
64
|
+
private syncFinger;
|
|
65
|
+
bind(rig: THREE.Object3D, magging: BoneMap): {
|
|
66
|
+
update: (delta: number) => void;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=HandTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HandTracker.d.ts","sourceRoot":"","sources":["../../src/tracking/HandTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACT,cAAc,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAU,cAAc,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,MAAM,MAAM,kBAAkB,GAAG;IAChC,SAAS,EAAE,MAAI,kBAAkB,CAAC;IAClC,UAAU,EAAE,MAAI,kBAAkB,CAAC;IACnC,SAAS,CAAC,EAAC,MAAM,CAAA;CACjB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAKnC,wBAAsB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAC,kBAAkB;;;GAqB3E;AAED,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;CA4Bd,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,SAAS,CAAC;AAWlD,KAAK,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;AAChC,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC;KAAG,GAAG,IAAI,YAAY,GAAG,KAAK,CAAC,QAAQ;CAAE,CAAC,CAAC;AAe3E,cAAM,YAAa,SAAQ,OAAO,CAAC,OAAO,SAAS,CAAC;IAQvC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAAiB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAW,OAAO,CAAC,QAAQ,CAAC,SAAS;IAPtH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;gBAElB,cAAc,EAAC,cAAc,EAAmB,IAAI,EAAC,QAAQ,EAAmB,SAAS,EAAC,CAAE,SAAS,EAAC,kBAAkB,KAAI,OAAO;IAWvJ,OAAO,CAAE,MAAM,EAAC,cAAc,EAAE,YAAY,EAAC,YAAY;IA8BzD,IAAI,CAAG,KAAK,EAAC,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE;IAKrG;;;;;OAKG;IACH,aAAa,CAAE,KAAK,EAAC,MAAM,EAAE,UAAU,EAAC,SAAS,EAAE,GAAG,EAAC,KAAK,CAAC,QAAQ;IA6CrE,OAAO,CAAC,UAAU;IAoDlB,IAAI,CAAE,GAAG,EAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAC,OAAO;wBAsCvB,MAAM;;CAKxB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DrawingUtils, NormalizedLandmark, PoseLandmarker } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { Tracker } from './Tracker';
|
|
3
|
+
import { BoneMap } from './BoneMapping';
|
|
4
|
+
import * as THREE from "three/webgpu";
|
|
5
|
+
export declare function loadPoseTracker(vision: any, config?: Partial<PoseTrackerConfig>): Promise<PoseTracker>;
|
|
6
|
+
/**
|
|
7
|
+
* Points derived from https://ai.google.dev/static/mediapipe/images/solutions/pose_landmarks_index.png
|
|
8
|
+
* If the array has 2 elements, the point is between those 2 landmarks.
|
|
9
|
+
* If it has 4, the point is at the center of those 4 landmarks.
|
|
10
|
+
*/
|
|
11
|
+
declare const poseMarks: {
|
|
12
|
+
hips: number[];
|
|
13
|
+
neck: number[];
|
|
14
|
+
leftLeg: number;
|
|
15
|
+
leftKnee: number;
|
|
16
|
+
leftArm: number;
|
|
17
|
+
leftElbow: number;
|
|
18
|
+
leftWrist: number;
|
|
19
|
+
rightLeg: number;
|
|
20
|
+
rightKnee: number;
|
|
21
|
+
rightArm: number;
|
|
22
|
+
rightElbow: number;
|
|
23
|
+
rightWrist: number;
|
|
24
|
+
head: number[];
|
|
25
|
+
mouth: number[];
|
|
26
|
+
torso: number[];
|
|
27
|
+
leftEar: number;
|
|
28
|
+
rightEar: number;
|
|
29
|
+
};
|
|
30
|
+
type PoseTrackerConfig = {
|
|
31
|
+
ignoreLegs: boolean;
|
|
32
|
+
modelPath: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* @see https://ai.google.dev/edge/mediapipe/solutions/vision/pose_landmarker
|
|
36
|
+
*/
|
|
37
|
+
declare class PoseTracker extends Tracker<typeof poseMarks> {
|
|
38
|
+
private readonly poseLandmarker;
|
|
39
|
+
private readonly config?;
|
|
40
|
+
private _leftWristNormalizedPosition;
|
|
41
|
+
private _rightWristNormalizedPosition;
|
|
42
|
+
/**
|
|
43
|
+
* Position of the left wrist in normalized coordinates (0..1)
|
|
44
|
+
*/
|
|
45
|
+
get leftWristNormalizedPosition(): NormalizedLandmark;
|
|
46
|
+
/**
|
|
47
|
+
* Position of the right wrist in normalized coordinates (0..1)
|
|
48
|
+
*/
|
|
49
|
+
get rightWristNormalizedPosition(): NormalizedLandmark;
|
|
50
|
+
constructor(poseLandmarker: PoseLandmarker, config?: Partial<PoseTrackerConfig> | undefined);
|
|
51
|
+
predict(source: TexImageSource, drawingUtils: DrawingUtils): void;
|
|
52
|
+
bind(rig: THREE.Object3D, magging: BoneMap): {
|
|
53
|
+
update: (delta: number) => void;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=PoseTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoseTracker.d.ts","sourceRoot":"","sources":["../../src/tracking/PoseTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,wBAAsB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,EAAC,OAAO,CAAC,iBAAiB,CAAC,wBAapF;AAED;;;;GAIG;AACH,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;CAkBZ,CAAE;AAcL,KAAK,iBAAiB,GAAG;IACxB,UAAU,EAAC,OAAO,CAAA;IAClB,SAAS,EAAC,MAAM,CAAA;CAChB,CAAA;AAED;;GAEG;AACH,cAAM,WAAY,SAAQ,OAAO,CAAC,OAAO,SAAS,CAAC;IActC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAAiB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAbpF,OAAO,CAAC,4BAA4B,CAAqB;IACzD,OAAO,CAAC,6BAA6B,CAAqB;IAE1D;;OAEG;IACH,IAAI,2BAA2B,uBAAgD;IAE/E;;OAEG;IACH,IAAI,4BAA4B,uBAAiD;gBAEpD,cAAc,EAAC,cAAc,EAAmB,MAAM,CAAC,EAAC,OAAO,CAAC,iBAAiB,CAAC,YAAA;IAStG,OAAO,CAAE,MAAM,EAAC,cAAc,EAAE,YAAY,EAAC,YAAY;IA8BlE,IAAI,CAAE,GAAG,EAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAC,OAAO;wBAiDxB,MAAM;;CAsBvB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Landmark, NormalizedLandmark, DrawingUtils } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { LookAtPoleAxis } from './util/lookAt';
|
|
3
|
+
import * as THREE from "three/webgpu";
|
|
4
|
+
export declare class Tracker<T extends Record<string, number | number[]>> {
|
|
5
|
+
protected readonly points: T;
|
|
6
|
+
private readonly debugConnections?;
|
|
7
|
+
private objectGhost;
|
|
8
|
+
readonly root: THREE.Object3D;
|
|
9
|
+
/**
|
|
10
|
+
* per landmark index, it points to it's object3D equivalent.
|
|
11
|
+
*/
|
|
12
|
+
protected marks: {
|
|
13
|
+
[name in keyof T]: Mark;
|
|
14
|
+
};
|
|
15
|
+
constructor(points: T, debugConnections?: {
|
|
16
|
+
start: number;
|
|
17
|
+
end: number;
|
|
18
|
+
}[] | undefined);
|
|
19
|
+
protected updateLandmarks(landmarks: Landmark[], debugLandmarks?: NormalizedLandmark[], debugDrawer?: DrawingUtils): void;
|
|
20
|
+
protected getGhost(object: THREE.Object3D): Ghost;
|
|
21
|
+
predict(source: TexImageSource, drawingUtils: DrawingUtils): void;
|
|
22
|
+
sync(delta: number, objects: [THREE.Object3D, keyof T, keyof T, LookAtPoleAxis][]): void;
|
|
23
|
+
test(key: keyof T): void;
|
|
24
|
+
protected syncObjects(objects: [THREE.Object3D, keyof T, keyof T, LookAtPoleAxis][], delta: number, normal: THREE.Vector3): void;
|
|
25
|
+
protected getBone(rig: THREE.Object3D, name: string): THREE.Object3D<THREE.Object3DEventMap> | undefined;
|
|
26
|
+
}
|
|
27
|
+
declare class Mark extends THREE.Mesh {
|
|
28
|
+
private _worldPosition;
|
|
29
|
+
constructor();
|
|
30
|
+
get worldPosition(): THREE.Vector3;
|
|
31
|
+
}
|
|
32
|
+
declare class Ghost extends THREE.Object3D {
|
|
33
|
+
lerp(target: THREE.Object3D, delta: number, speed?: number): void;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=Tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tracker.d.ts","sourceRoot":"","sources":["../../src/tracking/Tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EACH,QAAQ,EACR,kBAAkB,EACrB,YAAY,EACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAU,cAAc,EAAE,MAAM,eAAe,CAAC;AASvD,qBAAa,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC;IAShD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAC,CAAC;IAAE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAR5E,OAAO,CAAC,WAAW,CAA+B;IAClD,QAAQ,CAAC,IAAI,EAAC,KAAK,CAAC,QAAQ,CAAC;IAE7B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE;SAAG,IAAI,IAAI,MAAM,CAAC,GAAG,IAAI;KAAE,CAAqC;gBAEjD,MAAM,EAAC,CAAC,EAAmB,gBAAgB,CAAC,EAAC;QAAC,KAAK,EAAC,MAAM,CAAC;QAAA,GAAG,EAAC,MAAM,CAAA;KAAC,EAAE,YAAA;IAYxG,SAAS,CAAC,eAAe,CAAE,SAAS,EAAC,QAAQ,EAAE,EAAE,cAAc,CAAC,EAAC,kBAAkB,EAAE,EAAE,WAAW,CAAC,EAAC,YAAY;IAkDhH,SAAS,CAAC,QAAQ,CAAE,MAAM,EAAC,KAAK,CAAC,QAAQ;IAczC,OAAO,CAAE,MAAM,EAAC,cAAc,EAAE,YAAY,EAAC,YAAY;IAIzD,IAAI,CAAG,KAAK,EAAC,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,cAAc,CAAC,EAAE;IAIlF,IAAI,CAAE,GAAG,EAAC,MAAM,CAAC;IAIjB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAC,cAAc,CAAC,EAAE,EAAE,KAAK,EAAC,MAAM,EAAE,MAAM,EAAC,KAAK,CAAC,OAAO;IA2CtH,SAAS,CAAC,OAAO,CAAE,GAAG,EAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAC,MAAM;CAGlD;AAQD,cAAM,IAAK,SAAQ,KAAK,CAAC,IAAI;IAC5B,OAAO,CAAC,cAAc,CAAuB;;IAM7C,IAAI,aAAa,kBAGhB;CACD;AAED,cAAM,KAAM,SAAQ,KAAK,CAAC,QAAQ;IACjC,IAAI,CAAE,MAAM,EAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,EAAE,KAAK,SAAI;CAKpD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanBoneName.d.ts","sourceRoot":"","sources":["../../../src/tracking/util/cleanBoneName.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,IAAI,EAAC,MAAM,UAExC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getBoneByName.d.ts","sourceRoot":"","sources":["../../../src/tracking/util/getBoneByName.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGvC,wBAAgB,aAAa,CAAC,GAAG,EAAC,QAAQ,EAAE,IAAI,EAAC,MAAM,sDAWtD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Object3D, Vector3 } from 'three/webgpu';
|
|
2
|
+
/**
|
|
3
|
+
* Gets the position of `object` relative to `root`.
|
|
4
|
+
* @param out
|
|
5
|
+
* @param object
|
|
6
|
+
* @param root
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export declare function rootPosition(out: Vector3, object: Object3D, root: Object3D): Vector3;
|
|
10
|
+
//# sourceMappingURL=getRootPosition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRootPosition.d.ts","sourceRoot":"","sources":["../../../src/tracking/util/getRootPosition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGjD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAE,GAAG,EAAC,OAAO,EAAE,MAAM,EAAC,QAAQ,EAAE,IAAI,EAAC,QAAQ,WAKxE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Object3D, Vector3 } from 'three/webgpu';
|
|
2
|
+
export type LookAtPoleAxis = "+x" | "+y" | "-x" | "-y";
|
|
3
|
+
/**
|
|
4
|
+
* Will point the Z axis of object at target and the X or Y axis in the general direction of the pole target
|
|
5
|
+
* @param object The object to rotate
|
|
6
|
+
* @param target The point to look at ( in world coord )
|
|
7
|
+
* @param poleTarget The goal of the pole axis ( in world coord )
|
|
8
|
+
* @param poleAxis The axis to use as the pole axis ( z is the one pointing at the target )
|
|
9
|
+
*/
|
|
10
|
+
export declare function lookAt(object: Object3D, target: Vector3, poleTarget: Vector3, poleAxis?: LookAtPoleAxis): void;
|
|
11
|
+
//# sourceMappingURL=lookAt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookAt.d.ts","sourceRoot":"","sources":["../../../src/tracking/util/lookAt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAc,OAAO,EAAE,MAAM,cAAc,CAAC;AAmB7D,MAAM,MAAM,cAAc,GAAG,IAAI,GAAC,IAAI,GAAC,IAAI,GAAC,IAAI,CAAA;AAEhD;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAE,MAAM,EAAC,QAAQ,EAAE,MAAM,EAAC,OAAO,EAAE,UAAU,EAAC,OAAO,EAAE,QAAQ,GAAC,cAAqB,QAiC1G"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Vector3 } from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the signed orientation of `vector` around `forward`,
|
|
4
|
+
* using `sideNormal` as the reference axis.
|
|
5
|
+
*
|
|
6
|
+
* > 0 if (forward × vector) points in the same direction as sideNormal
|
|
7
|
+
* < 0 if it points in the opposite direction
|
|
8
|
+
* 0 if vectors are collinear or degenerate
|
|
9
|
+
*
|
|
10
|
+
* All vectors must be in the same coordinate space.
|
|
11
|
+
*/
|
|
12
|
+
export declare function vectorSign(forward: Vector3, vector: Vector3, sideNormal: Vector3): number;
|
|
13
|
+
/**
|
|
14
|
+
* Gets the angle [-π, +π] between from and to. Using "from" as angle 0.
|
|
15
|
+
*
|
|
16
|
+
* > 0 if (from × to) points in the same direction as rotationAxis
|
|
17
|
+
* < 0 if it points in the opposite direction
|
|
18
|
+
* 0 if vectors are collinear or degenerate
|
|
19
|
+
* @param from Normalized origin vector
|
|
20
|
+
* @param to Normalized target vector
|
|
21
|
+
* @param rotationAxis Normalized vector that defines the rotation axis
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
24
|
+
export declare function signedAngleTo(from: Vector3, to: Vector3, rotationAxis: Vector3): number;
|
|
25
|
+
//# sourceMappingURL=vectorSign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vectorSign.d.ts","sourceRoot":"","sources":["../../../src/tracking/util/vectorSign.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIhC;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACtB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,OAAO,UAGtB;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CACzB,IAAI,EAAE,OAAO,EACb,EAAE,EAAE,OAAO,EACX,YAAY,EAAE,OAAO,GACtB,MAAM,CAIR"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "three-mediapipe-rig",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Easy setup of a skeletal rig that responds to the motion tracker provided by google's mediapipe webwam feed.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/bandinopla/three-mediapipe-rig.git"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/three-mediapipe-rig.js",
|
|
11
|
+
"module": "./dist/three-mediapipe-rig.js",
|
|
12
|
+
"types": "./dist/module.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/three-mediapipe-rig.js",
|
|
16
|
+
"types": "./dist/module.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"dev": "vite --config vite.dev.config.ts",
|
|
24
|
+
"build": "vite build --config vite.lib.config.ts",
|
|
25
|
+
"build:web": "vite build --config vite.dev.config.ts",
|
|
26
|
+
"preview": "vite preview --config vite.dev.config.ts"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^25.3.3",
|
|
30
|
+
"path": "^0.12.7",
|
|
31
|
+
"typescript": "~5.7.2",
|
|
32
|
+
"vite": "^6.1.0",
|
|
33
|
+
"vite-plugin-dts": "^4.5.4",
|
|
34
|
+
"@types/three": "^0.183.1"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"three": "^0.183.1",
|
|
38
|
+
"@mediapipe/tasks-vision": "^0.10.32"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"packageManager": "pnpm@9.0.0"
|
|
42
|
+
}
|