{"_id":"@anhldh/gltf-animation-pointer-extensions","_rev":"2-c4feeabc611a6cc89b2d6b6a5751d0de","name":"@anhldh/gltf-animation-pointer-extensions","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@anhldh/gltf-animation-pointer-extensions","version":"0.1.0","keywords":["gltf","glb","three","threejs","gltf-transform","KHR_animation_pointer","animation"],"author":{"name":"anhldh"},"license":"MIT","_id":"@anhldh/gltf-animation-pointer-extensions@0.1.0","maintainers":[{"name":"aldh","email":"ledinhhoanganh10@gmail.com"}],"homepage":"https://github.com/anhldh/gltf-animation-pointer-extensions#readme","bugs":{"url":"https://github.com/anhldh/gltf-animation-pointer-extensions/issues"},"dist":{"shasum":"54be224427dde336d0ced57b3322e234f4a468b9","tarball":"https://registry.npmjs.org/@anhldh/gltf-animation-pointer-extensions/-/gltf-animation-pointer-extensions-0.1.0.tgz","fileCount":8,"integrity":"sha512-Z3zXurBUkTTjHC0XDEEy9tw6ZKL2k3iF7Vpxig+eIlb+kOFrJdMsKZtXJzYdg531LDoqE0Mszz89rw3CfP8+nQ==","signatures":[{"sig":"MEUCIAjVLGFRclx8GsrOtkq2tmCJEmXcFCJsWhACy3BQGMVHAiEA1DbLxA3zSn6EpWLSGWNej+HTmI3/USGqmoY2U3mbJPk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53438},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"495758155f8cb9027f1da362600aa13d5e2a932a","scripts":{"dev":"vite","lint":"eslint .","build":"tsc -b && vite build","preview":"vite preview","build:lib":"vite build --config vite.lib.config.ts"},"_npmUser":{"name":"aldh","email":"ledinhhoanganh10@gmail.com"},"repository":{"url":"git+https://github.com/anhldh/gltf-animation-pointer-extensions.git","type":"git"},"_npmVersion":"11.6.2","description":"KHR_animation_pointer support for three.js (GLTFLoader) and gltf-transform.","directories":{},"sideEffects":false,"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.1.1","react":"^19.2.7","three":"^0.185.1","eslint":"^10.6.0","globals":"^17.7.0","react-dom":"^19.2.7","@eslint/js":"^10.0.1","typescript":"~6.0.2","@babel/core":"^7.29.7","@types/node":"^24.13.2","r3f-monitor":"^2.1.0","@types/react":"^19.2.17","@types/three":"^0.185.0","vite-plugin-dts":"^5.0.3","@types/react-dom":"^19.2.3","@react-three/drei":"^10.7.7","typescript-eslint":"^8.62.0","@react-three/fiber":"^9.6.1","@types/babel__core":"^7.20.5","@gltf-transform/core":"^4.4.1","@vitejs/plugin-react":"^6.0.3","@rolldown/plugin-babel":"^0.2.3","eslint-plugin-react-hooks":"^7.1.1","babel-plugin-react-compiler":"^1.0.0","eslint-plugin-react-refresh":"^0.5.3"},"peerDependencies":{"three":">=0.150.0","@gltf-transform/core":">=4.0.0"},"peerDependenciesMeta":{"three":{"optional":true},"@gltf-transform/core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/gltf-animation-pointer-extensions_0.1.0_1783063458629_0.522809974981369","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@anhldh/gltf-animation-pointer-extensions","version":"0.1.1","description":"KHR_animation_pointer support for three.js (GLTFLoader) and gltf-transform.","keywords":["gltf","glb","three","threejs","gltf-transform","KHR_animation_pointer","animation"],"license":"MIT","author":{"name":"anhldh"},"homepage":"https://github.com/anhldh/gltf-animation-pointer-extensions#readme","repository":{"type":"git","url":"git+https://github.com/anhldh/gltf-animation-pointer-extensions.git"},"bugs":{"url":"https://github.com/anhldh/gltf-animation-pointer-extensions/issues"},"type":"module","sideEffects":false,"publishConfig":{"access":"public"},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./transform":{"types":"./dist/transform.d.ts","import":"./dist/transform.js","require":"./dist/transform.cjs"}},"scripts":{"dev":"vite","build":"tsc -b && vite build","build:lib":"vite build --config vite.lib.config.ts","lint":"eslint .","preview":"vite preview"},"peerDependencies":{"three":">=0.150.0","@gltf-transform/core":">=4.0.0"},"peerDependenciesMeta":{"three":{"optional":true},"@gltf-transform/core":{"optional":true}},"devDependencies":{"@babel/core":"^7.29.7","@eslint/js":"^10.0.1","@gltf-transform/core":"^4.4.1","@react-three/drei":"^10.7.7","@react-three/fiber":"^9.6.1","@rolldown/plugin-babel":"^0.2.3","@types/babel__core":"^7.20.5","@types/node":"^24.13.2","@types/react":"^19.2.17","@types/react-dom":"^19.2.3","@types/three":"^0.185.0","@vitejs/plugin-react":"^6.0.3","babel-plugin-react-compiler":"^1.0.0","eslint":"^10.6.0","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-react-refresh":"^0.5.3","globals":"^17.7.0","r3f-monitor":"^2.1.0","react":"^19.2.7","react-dom":"^19.2.7","three":"^0.185.1","typescript":"~6.0.2","typescript-eslint":"^8.62.0","vite":"^8.1.1","vite-plugin-dts":"^5.0.3"},"gitHead":"fee5c2f7edc9ccccd2bdb716a9927b943f36bdb6","_id":"@anhldh/gltf-animation-pointer-extensions@0.1.1","_nodeVersion":"22.23.1","_npmVersion":"11.18.0","dist":{"integrity":"sha512-U7Yuz9FYjJ2CCAtqxhkyapr09RGROH04h3haLAJtEpmLNSfcZFXDOFrHay1ZTLZHbP8+csNHr2RLvbEqIpFWoQ==","shasum":"5840ff9e88452b20cb1c9130d63af9a81d3c5c84","tarball":"https://registry.npmjs.org/@anhldh/gltf-animation-pointer-extensions/-/gltf-animation-pointer-extensions-0.1.1.tgz","fileCount":11,"unpackedSize":53847,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@anhldh%2fgltf-animation-pointer-extensions@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCbVFelJwWFfP2XXRIAmyldFeONuLNbnJOFsmX65ETl3wIhANaqmIki0Fr4KMedKF8GqlFThzppOzOu0pp8w/VtHTgb"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f8f389f2-3309-4ffc-afde-a915f7fd71ff"}},"directories":{},"maintainers":[{"name":"aldh","email":"ledinhhoanganh10@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/gltf-animation-pointer-extensions_0.1.1_1783068097429_0.8655904048393299"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-03T07:24:18.482Z","modified":"2026-07-03T08:41:37.855Z","0.1.0":"2026-07-03T07:24:18.853Z","0.1.1":"2026-07-03T08:41:37.550Z"},"bugs":{"url":"https://github.com/anhldh/gltf-animation-pointer-extensions/issues"},"author":{"name":"anhldh"},"license":"MIT","homepage":"https://github.com/anhldh/gltf-animation-pointer-extensions#readme","keywords":["gltf","glb","three","threejs","gltf-transform","KHR_animation_pointer","animation"],"repository":{"type":"git","url":"git+https://github.com/anhldh/gltf-animation-pointer-extensions.git"},"description":"KHR_animation_pointer support for three.js (GLTFLoader) and gltf-transform.","maintainers":[{"name":"aldh","email":"ledinhhoanganh10@gmail.com"}],"readme":"# @anhldh/gltf-animation-pointer-extensions\n\nSupport for the glTF [`KHR_animation_pointer`](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_animation_pointer/README.md) extension on **both sides** of the pipeline:\n\n- **Runtime (three.js)** — load models that use `KHR_animation_pointer` with `GLTFLoader` (and drei's `useGLTF`). three.js does **not** support it by default, so those animations simply don't play.\n- **Build-time (gltf-transform)** — **preserve** `KHR_animation_pointer` channels while processing/optimizing a model. gltf-transform **drops** them by default.\n\n## What is `KHR_animation_pointer`?\n\nThe extension lets an animation target almost any property of a model via a JSON pointer — not just node transforms, but material factors / texture transforms, light parameters (`KHR_lights_punctual`), cameras, morph weights, visibility, and more. Because it lives outside \"classic\" animation, both three.js and gltf-transform ignore it unless a dedicated extension handles it.\n\n## Installation\n\n```bash\npnpm add @anhldh/gltf-animation-pointer-extensions\n```\n\nPeer dependencies are **optional** — install only the side you use:\n\n```bash\n# runtime (three.js)\npnpm add three\n\n# build-time (gltf-transform)\npnpm add @gltf-transform/core @gltf-transform/extensions\n```\n\n## Usage — three.js\n\n### Plain GLTFLoader\n\n```ts\nimport { GLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\nimport { GLTFAnimationPointerExtension } from \"@anhldh/gltf-animation-pointer-extensions\";\n\nconst loader = new GLTFLoader();\nloader.register((p) => new GLTFAnimationPointerExtension(p));\n\nconst gltf = await loader.loadAsync(\"model.glb\");\n// gltf.animations now contains tracks generated from KHR_animation_pointer\n```\n\n### React Three Fiber (drei `useGLTF`)\n\nThe 4th argument of `useGLTF` is `extendLoader` — where you register the extension:\n\n```tsx\nimport { useGLTF } from \"@react-three/drei\";\nimport type {\n  GLTFLoader,\n  GLTFParser,\n} from \"three/examples/jsm/loaders/GLTFLoader.js\";\nimport { GLTFAnimationPointerExtension } from \"@anhldh/gltf-animation-pointer-extensions\";\n\nconst gltf = useGLTF(url, true, true, (loader) => {\n  // drei uses the three-stdlib GLTFLoader -> cast to three/examples.\n  const l = loader as unknown as GLTFLoader;\n  l.register((p: GLTFParser) => new GLTFAnimationPointerExtension(p));\n});\n```\n\n> `useGLTF` caches by URL, so `extendLoader` only runs on the first load of each URL.\n\n## Usage — gltf-transform\n\nWhen you run a gltf-transform pipeline (`weld`, `dedup`, `draco`, `resample`, `prune`, ...), `KHR_animation_pointer` channels are dropped by default. Register `KHRAnimationPointer` to read and write them back correctly — it automatically **remaps pointers to the new node/material indices** after transforms.\n\n```ts\nimport { WebIO } from \"@gltf-transform/core\";\nimport { ALL_EXTENSIONS } from \"@gltf-transform/extensions\";\nimport { KHRAnimationPointer } from \"@anhldh/gltf-animation-pointer-extensions/transform\";\n\nconst io = new WebIO().registerExtensions([\n  ...ALL_EXTENSIONS,\n  KHRAnimationPointer,\n]);\n\nconst doc = await io.read(url); // preread: maps pointer -> Node/Material\n// ...doc.transform(...)...        // pointers follow Node/Material, stay correct\nconst glb = await io.writeBinary(doc); // write: emits pointer with new indices\n```\n\nOn Node, use `NodeIO` instead of `WebIO`:\n\n```ts\nimport { NodeIO } from \"@gltf-transform/core\";\nimport { ALL_EXTENSIONS } from \"@gltf-transform/extensions\";\nimport { KHRAnimationPointer } from \"@anhldh/gltf-animation-pointer-extensions/transform\";\n\nconst io = new NodeIO().registerExtensions([\n  ...ALL_EXTENSIONS,\n  KHRAnimationPointer,\n]);\n\nconst doc = await io.read(\"in.glb\");\nawait io.write(\"out.glb\", doc);\n```\n\n## API\n\n**three.js side** — from `@anhldh/gltf-animation-pointer-extensions`\n\n- `GLTFAnimationPointerExtension` — plugin registered via `GLTFLoader.register(...)`.\n- `.setAnimationPointerResolver(resolver)` — customize how a pointer path maps to a three.js property.\n- `invalidateMaterialCache(root)` — clear the material cache when materials are swapped/cloned at runtime.\n- type `AnimationPointerResolver`.\n\n**gltf-transform side** — from `@anhldh/gltf-animation-pointer-extensions/transform`\n\n- `KHRAnimationPointer` — `Extension` registered on the IO (`WebIO` / `NodeIO`).\n- `AnimationPointer` — `ExtensionProperty` attached to an `AnimationChannel`.\n- `KHR_ANIMATION_POINTER` — the extension-name constant (`\"KHR_animation_pointer\"`).\n\n## Notes\n\n- The three.js side patches `PropertyBinding.findNode` (global, once, guarded) so pointers can bind to material / texture / light / camera. Textures shared across materials are cloned before binding to avoid animating the wrong one.\n- If an animation fails, the extension returns an empty clip instead of breaking the whole model — the model still loads, only that animation is lost.\n- Published builds are **minified**; read the source on [GitHub](https://github.com/anhldh/gltf-animation-pointer-extensions).\n- The two sides are separate entry points — `.` (three.js) and `/transform` (gltf-transform). Importing one never loads the other's peer dependency, so you only need the peer dep of the side you actually import.\n\n## License\n\n[MIT](https://github.com/anhldh/gltf-animation-pointer-extensions)\n","readmeFilename":"README.md"}